File: traps.S

package info (click to toggle)
mol 0.9.61-6
  • links: PTS
  • area: contrib
  • in suites: woody
  • size: 6,140 kB
  • ctags: 8,491
  • sloc: ansic: 50,560; asm: 2,826; sh: 458; makefile: 373; perl: 165; lex: 135; yacc: 131
file content (422 lines) | stat: -rw-r--r-- 11,287 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
/* 
 *   Creation Date: <2001/01/27 16:25:14 samuel>
 *   Time-stamp: <2001/06/24 13:32:31 samuel>
 *   
 *	<traps.S>
 *	
 *	
 *   
 *   Copyright (C) 2000, 2001 Samuel Rydh (samuel@ibrium.se)
 *   
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   as published by the Free Software Foundation
 *   
 */

#include "compat.h"
#include "processor.h"		/* avoid <asm/processor.h> (bogus SPRN_TBWU/L) */
#include "asm_offsets.h"
#include "asmdefs.h"
#include "molasm.h"
#include "reloc.h"
#include "rvec.h"
#include "constants.h"
#include "mac_registers.h"
#include "mmu.h"		/* for kSplitModeXXX */
#include "os_interface.h"
#include "kernel_vars.h"

/************************************************************************/
/*	DEBUG Settings							*/
/************************************************************************/

//#define DISABLE_DEC			// Disable DEC code
//#define DISABLE_DEC_REG		// Disable mtdec/mfdec
//#define DBG_TRACE			// Enable Tracing

#ifdef DBG_TRACE
#define TRACE( a,b )	TRACE_VAL a,b
#else
#define TRACE( a,b )
#endif

/************************************************************************/
/*	Exception Vector Definitions					*/
/************************************************************************/

	.data
	ACTION_SYMBOL( Action_LI_PHYS, ACTION_LI_PHYS )
	ACTION_SYMBOL( k_session_table, ACTION_KVARS_TABLE )
	ACTION_SYMBOL( k_session_table_virt, ACTION_KVARS_TABLE_VIRT )
	ACTION_SYMBOL( Action_RELOC_HOOK, ACTION_RELOC_HOOK )
	ACTION_SYMBOL( Action_VRET, ACTION_VRET )
	ACTION_SYMBOL( Action_HOOK_FUNCTION, ACTION_HOOK_FUNCTION )	
	ACTION_SYMBOL( Action_FRET, ACTION_FRET )
	
	.text
GLOBAL_SYMBOL(r__reloctable_start):

.macro EXCEPTION_PREAMBLE
	// SPRG1 = r1, SPRG0 = r3, r3=CR, r1=MOL_STACK
	stw	r3,xCR(r1)
	mfsprg1	r3			// SPRG1 = r1
	stw	r2,xGPR2(r1)
	stw	r0,xGPR0(r1)
	mfsprg0	r2			// SPRG0 = r3	
	stw	r4,xGPR4(r1)
	lwz	r0,xFLAG_BITS(r1)
	mflr	r4
	stw	r3,xGPR1(r1)
	stw	r5,xGPR5(r1)
	mtcr	r0
	stw	r2,xGPR3(r1)
	stw	r4,xLINK(r1)

	// saved: r0-r5, cr, lr
	// r1 = stack, cr5-7=flag_bits
.endm

save_middle_regs:			// save r6-r12 (r13-r31 should always be in regs)
	stw	r6,xGPR6(r1)
	stw	r7,xGPR7(r1)
	stw	r8,xGPR8(r1)
	mfctr	r6
	stw	r9,xGPR9(r1)
	stw	r10,xGPR10(r1)
	mfxer	r7
	stw	r11,xGPR11(r1)
	stw	r12,xGPR12(r1)
	mfsrr0	r8
	stw	r6,xCTR(r1)
	stw	r7,xXER(r1)
	stw	r8,xNIP(r1)
	blr

.macro RESTORE_MIDDLE_REGS		// In the unlikely case we need to reverse save_middle_regs...
	lwz	r11,xCTR(r1)			// Restore registers
	lwz	r12,xXER(r1)
	lwz	r6,xGPR6(r1)
	lwz	r7,xGPR7(r1)
	mtctr	r11
	lwz	r8,xGPR8(r1)
	lwz	r9,xGPR9(r1)
	lwz	r10,xGPR10(r1)
	mtxer	r12
	lwz	r11,xGPR11(r1)
	lwz	r12,xGPR12(r1)
.endm

#define EXCEPTION_SAVE_ALL				\
	EXCEPTION_PREAMBLE				;\
	bl save_middle_regs				;
	
#define VECTOR_KERNEL( v, dummy_name, secint )		\
	VECTOR( v, dummy_name, secint )			;\
	EXCEPTION_SAVE_ALL				;\
	TAKE_EXCEPTION					;

#define VECTOR_RESERVED( v, dummy_name, secint )	\
	VECTOR( v, dummy_name, secint )			;\
	DEBUGGER_SAVE( v )				;

#define MAC_EXIT( rvec_code ) 				\
	li	r3,rvec_code				;\
	b	mac_exit				;

#define MAC_EXIT_SAVE( rvec_code )			\
	bl	save_middle_regs			;\
	li	r3,rvec_code				;\
	b	mac_exit				;

#define MAC_TRAP( trap_num )				\
	li	r2,trap_num				;\
	b	mac_trap				;

#define DEBUGGER(n)		li r4,n ; MAC_EXIT( RVEC_DEBUGGER );
#define DEBUGGER_SAVE(n)	li r4,n ; MAC_EXIT_SAVE( RVEC_DEBUGGER );
	
/************************************************************************/
/*	Reserved / Kernel Vectors					*/
/************************************************************************/

VECTOR_KERNEL( 0x100, "System Reset", secint_bad )
VECTOR_KERNEL( 0x500, "External Interrupt", secint_bad )
VECTOR_KERNEL( 0x1400, "System Management Interrupt", secint_bad )
VECTOR_KERNEL( 0x1700, "Thermal Management Interrupt", secint_bad )

VECTOR_RESERVED( 0x200, "Machine Check", secint_bad )
VECTOR_RESERVED( 0xa00, "Reserved", secint_bad )
VECTOR_RESERVED( 0xb00, "Reserved", secint_bad )
VECTOR_RESERVED( 0xe00, "FPU Assist", secint_bad )
VECTOR_RESERVED( 0xf00, "Performance Monitor Interrupt", secint_bad )
//VECTOR_RESERVED( 0x1000, "InstructionTLBMiss-603", secint_bad )
//VECTOR_RESERVED( 0x1100, "DataLoadTLBMiss-603", secint_bad )
//VECTOR_RESERVED( 0x1200, "DataLoadTLBMiss-603", secint_bad )


/************************************************************************/
/*	DSI Exceptions							*/
/************************************************************************/
	
VECTOR( 0x300, "DSI", secint_lr_call )
	EXCEPTION_PREAMBLE
	TRACE(0x300, "DSI")

	mfsrr0	r4
	bl	_get_instr_opcode	// m: r0,r2-r3, ret: r4=opcode
	stw	r4,xINST_OPCODE(r1)
	bl	check_pthash_hit	// m: r0,r2-r5
	bl	splitmode_dsi		// Handle splitmode DSI exceptions
	bl	save_middle_regs
	bl	check_io_page

dsi_cont:
	LI_VIRT( r3, dsi_exception )
	mfdar	r4			// We might need to do this earlier
	mfdsisr	r5			// when the splitmode code is activated...
	b	call_kernel
	

/************************************************************************/
/*	ISI Exceptions							*/
/************************************************************************/

VECTOR( 0x400, "ISI", secint_bad )
	EXCEPTION_PREAMBLE
	TRACE(0x400, "ISI")
	
	bl	split_sr_no_execute
	bl	save_middle_regs

	LI_VIRT( r3, isi_exception )
	mfsrr0	r4
	mfsrr1	r5
	b	call_kernel


/************************************************************************/
/*	Alignement Exception						*/
/************************************************************************/

VECTOR( 0x600, "Alignment", secint_lr_call )
	EXCEPTION_SAVE_ALL
	TRACE(0x400, "Alignment")

alignment_cont:
	mfdar	r4
	mfdsisr	r5
	MAC_EXIT( RVEC_ALIGNMENT_TRAP )


/************************************************************************/
/*	Program Exception						*/
/************************************************************************/

VECTOR_( 0x700, "Program", secint_bad, mac_entry_test )
	EXCEPTION_PREAMBLE
	TRACE(0x700, "Program")
	b	emulate_instr


/************************************************************************/
/*	FPU Unavailable	Exception					*/
/************************************************************************/

	// FPU_STATE_IN_USE	- we own the fpu and its ready for use
	// FPU_STATE_DIRTY	- fr13 & fpscr are not loaded (everything else is).
	// FPU_STATE_HALF_SAVED	- fr14-fr31 are loaded.
	// FPU_STATE_SAVED	- fr14-fr31 are loaded (but also saved in mregs).
	//
	// FPU_STATE_DIRTY in the *emulator* means that all floating point 
	// registers *EXCEPT* fr13 and fpscr are valid.
	
VECTOR( 0x800, "FPU Unavailable", secint_lr_call )
	EXCEPTION_PREAMBLE
	TRACE(0x800, "FPU Unavailable")
fpu_cont:

	lwz	r2,xMSR(r1)
	andi.	r4,r2,MSR_FP
	beq-	mac_fpu_unavailable

	lwz	r4,xFPU_STATE(r1)
	cmpwi	r4,FPU_STATE_IN_USE		// We are currently the owner of the FPU
	beq	22f
	
	lwz	r3,K_EMULATOR_MSR(r1)
	andi.	r4,r3,MSR_FP
	bne+	enable_fpu
	MAC_EXIT_SAVE( RVEC_ENABLE_FPU )

mac_fpu_unavailable:
	li	r5,0				// r5 = srr1 bits
	MAC_TRAP( 0x800 )
	
enable_fpu:		
	ENABLE_MSR_FP /**/ r4			// Enable kernel FPU

	// flag the fpu dirty
	lwz	r3,xFPU_STATE(r1)
	lfd	fr13,xFPSCR-4(r1)		// fp13 and fpscr are *ALWAYS* saved
	cmpwi	r3,FPU_STATE_HALF_SAVED
	mtfsf	0xff,fr13
	li	r4,FPU_STATE_IN_USE
	lfd	fr13,xFPR13(r1)
	bne	1f
	xLOAD_LOW_FPU	r1			// load fr0-fr12
1:	
	stw	r4,xFPU_STATE(r1)		//
22:	lwz	r3,x_MSR(r1)			// Enable MSR_FP
	ori	r3,r3,MSR_FP
	mtsrr1	r3				// Update both srr1 and x_MSR
	stw	r3,x_MSR(r1)
	b	exception_return

	
/************************************************************************/
/*	Decrementer Exception						*/
/************************************************************************/

// The 0x900 decrementer vector is in dec.S

/************************************************************************/
/*	System Call Exception						*/
/************************************************************************/

VECTOR( 0xc00, "System Call", secint_bad )
	EXCEPTION_PREAMBLE
	TRACE( 0xc00, "System Call")
	
	lwz	r3,xGPR3(r1)
	LOADI	r5,OSI_SC_MAGIC_R3
	lwz	r4,xGPR4(r1)
	LOADI	r2,OSI_SC_MAGIC_R4
	cmpw	cr1,r3,r5
	cmpw	cr0,r4,r2
	crand	eq,eq,cr1*4+eq
	beq+	2f
	li	r5,0				// r5=srr1 bits
	MAC_TRAP(0xc00)
2:	
	MAC_EXIT_SAVE( RVEC_OSI_SYSCALL )


/************************************************************************/
/*	Trace Exception							*/
/************************************************************************/

VECTOR( 0xd00, "Trace", secint_bad )
trace_vector:
	EXCEPTION_PREAMBLE
	TRACE(0xd00, "Trace")

	MAC_EXIT_SAVE( RVEC_TRACE_TRAP );


/************************************************************************/
/*	AltiVec Exception						*/
/************************************************************************/

VECTOR( 0xf20, "AltiVec", secint_lr_call )
	EXCEPTION_PREAMBLE
	TRACE(0xf20, "AltiVec")
altivec_cont:

	lwz	r4,xNO_ALTIVEC(r1)		// AltiVec support disabled?
	cmpwi	r4,0
	bne-	mac_altivec_unavailable
	
	lwz	r2,xMSR(r1)
	rlwinm.	r4,r2,0,6,6			// bit 6 = MSR_VEC
	beq-	mac_altivec_unavailable
	
	lwz	r3,K_EMULATOR_MSR(r1)
	rlwinm.	r4,r3,0,6,6			// bit 6 = MSR_VEC
	bne+	enable_altivec
	MAC_EXIT_SAVE( RVEC_ENABLE_ALTIVEC )

mac_altivec_unavailable:
	MAC_EXIT_SAVE( RVEC_ALTIVEC_UNAVAIL_TRAP )
	
enable_altivec:
	// We don't need to load any registers since the emulator
	// won't touch the altivec unit (at least for now).
	
	lwz	r3,x_MSR(r1)
	oris	r3,r3,MSR_VEC@h
	mtsrr1	r3
	stw	r3,x_MSR(r1)
	b	exception_return

	
VECTOR( 0x1600, "AltiVec Assist", secint_bad )
	EXCEPTION_SAVE_ALL
	TRACE(0x1600, "AltiVec Assist")

	mfsrr1	r4
	MAC_EXIT( RVEC_ALTIVEC_ASSIST )		// r4 = srr1
	
	
/************************************************************************/
/*	Instruction Breakpoint						*/
/************************************************************************/
	
VECTOR( 0x1300, "Instruction Breakpoint", secint_bad )
	EXCEPTION_SAVE_ALL
	TRACE(0x1300, "IABR")
		
	DEBUGGER(0x1300)


/************************************************************************/
/*	RunMode-601 (trace)						*/
/************************************************************************/
	
VECTOR( 0x2000, "RunMode-601", secint_bad )
	b	trace_vector


/************************************************************************/
/*	Secondary Interrupt Handlers					*/
/************************************************************************/

	//////////////////////////////////////////////////////////////////////
	// secint_xxx
	//
	//	r1:		stack (sprg1 = old r1)
	//	r3:		vector addr (sprg0 = old r3)
	//	srr0/srr1:	kernel nip/msr
	//
	// secint_lr_call:
	//	lr		secondary interrupt handler

secint_bad:
	TRACE(0xbad, "secint_bad")
	mr	r4,r3
	MAC_EXIT( RVEC_INTERNAL_ERROR )

secint_lr_call:
	blrl
	li	r4,0x6666
	MAC_EXIT( RVEC_INTERNAL_ERROR )

			
/**************************************************************
*  Includes
**************************************************************/

// We need to be sure this code is contiguous, the simplest/safest
// method is using only a single file. This will also effectively
// reduce the size of the relocation table.

#include "entry.S"
#include "dec.S"
#include "603.S"
#include "emulation.S"
#include "iopage.S"
#include "splitmode.S"
#include "linux.S"
#include "ptintercept.S"
	
GLOBAL_SYMBOL(r__reloctable_end):