Go to the documentation of this file. 1 #ifndef __HEAD_BOOKE_H__
2 #define __HEAD_BOOKE_H__
4 #include <asm/ptrace.h>
12 #define SET_IVOR(vector_number, vector_label) \
13 li r26,vector_label@l; \
14 mtspr SPRN_IVOR##vector_number,r26; \
17 #if (THREAD_SHIFT < 15)
18 #define ALLOC_STACK_FRAME(reg, val) \
21 #define ALLOC_STACK_FRAME(reg, val) \
22 addis reg,reg,val@ha; \
32 #define THREAD_NORMSAVE(offset) (THREAD_NORMSAVES + (offset * 4))
34 #define NORMAL_EXCEPTION_PROLOG(intno) \
35 mtspr SPRN_SPRG_WSCRATCH0, r10; \
36 mfspr r10, SPRN_SPRG_THREAD; \
37 stw r11, THREAD_NORMSAVE(0)(r10); \
38 stw r13, THREAD_NORMSAVE(2)(r10); \
40 mfspr r11, SPRN_SRR1; \
41 DO_KVM BOOKE_INTERRUPT_##intno SPRN_SRR1; \
42 andi. r11, r11, MSR_PR; \
46 lwz r11, THREAD_INFO-THREAD(r10); \
47 ALLOC_STACK_FRAME(r11, THREAD_SIZE); \
48 1 : subi r11, r11, INT_FRAME_SIZE; \
52 mfspr r13, SPRN_SPRG_RSCRATCH0; \
53 stw r13, GPR10(r11); \
54 lwz r12, THREAD_NORMSAVE(0)(r10); \
56 lwz r13, THREAD_NORMSAVE(2)(r10); \
59 mfspr r12,SPRN_SRR0; \
64 rlwinm r9,r9,0,14,12; \
66 lis r10, STACK_FRAME_REGS_MARKER@ha; \
67 addi r10, r10, STACK_FRAME_REGS_MARKER@l; \
90 #define MC_STACK_BASE mcheckirq_ctx
91 #define CRIT_STACK_BASE critirq_ctx
94 #define DBG_STACK_BASE dbgirq_ctx
96 #define EXC_LVL_FRAME_OVERHEAD (THREAD_SIZE - INT_FRAME_SIZE - EXC_LVL_SIZE)
99 #define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
102 addis r8,r8,level##_STACK_BASE@ha; \
103 lwz r8,level##_STACK_BASE@l(r8); \
104 addi r8,r8,EXC_LVL_FRAME_OVERHEAD;
106 #define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
107 lis r8,level##_STACK_BASE@ha; \
108 lwz r8,level##_STACK_BASE@l(r8); \
109 addi r8,r8,EXC_LVL_FRAME_OVERHEAD;
120 #define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, intno, exc_level_srr0, exc_level_srr1) \
121 mtspr SPRN_SPRG_WSCRATCH_##exc_level,r8; \
122 BOOKE_LOAD_EXC_LEVEL_STACK(exc_level); \
128 mfspr r11,exc_level_srr1; \
129 DO_KVM BOOKE_INTERRUPT_##intno exc_level_srr1; \
130 andi. r11,r11,MSR_PR; \
131 mfspr r11,SPRN_SPRG_THREAD; \
132 lwz r11,THREAD_INFO-THREAD(r11); \
133 addi r11,r11,EXC_LVL_FRAME_OVERHEAD; \
139 stw r10,GPR10(r11); \
142 stw r10,GPR11(r11); \
145 1: lwz r9,TI_FLAGS-EXC_LVL_FRAME_OVERHEAD(r11); \
146 lwz r10,TI_PREEMPT-EXC_LVL_FRAME_OVERHEAD(r11); \
147 stw r9,TI_FLAGS-EXC_LVL_FRAME_OVERHEAD(r8); \
148 stw r10,TI_PREEMPT-EXC_LVL_FRAME_OVERHEAD(r8); \
149 lwz r9,TI_TASK-EXC_LVL_FRAME_OVERHEAD(r11); \
150 stw r9,TI_TASK-EXC_LVL_FRAME_OVERHEAD(r8); \
152 2: mfspr r8,SPRN_SPRG_RSCRATCH_##exc_level; \
153 stw r12,GPR12(r11); \
155 stw r10,_LINK(r11); \
156 mfspr r12,SPRN_DEAR; \
157 stw r12,_DEAR(r11); \
160 mfspr r12,exc_level_srr0; \
162 mfspr r9,exc_level_srr1; \
165 rlwinm r9,r9,0,14,12; \
167 SAVE_4GPRS(3, r11); \
170 #define CRITICAL_EXCEPTION_PROLOG(intno) \
171 EXC_LEVEL_EXCEPTION_PROLOG(CRIT, intno, SPRN_CSRR0, SPRN_CSRR1)
172 #define DEBUG_EXCEPTION_PROLOG \
173 EXC_LEVEL_EXCEPTION_PROLOG(DBG, DEBUG, SPRN_DSRR0, SPRN_DSRR1)
174 #define MCHECK_EXCEPTION_PROLOG \
175 EXC_LEVEL_EXCEPTION_PROLOG(MC, MACHINE_CHECK, \
176 SPRN_MCSRR0, SPRN_MCSRR1)
184 #define GUEST_DOORBELL_EXCEPTION \
185 START_EXCEPTION(GuestDoorbell); \
186 mtspr SPRN_SPRG_WSCRATCH0, r10; \
187 mfspr r10, SPRN_SPRG_THREAD; \
188 stw r11, THREAD_NORMSAVE(0)(r10); \
189 mfspr r11, SPRN_SRR1; \
190 stw r13, THREAD_NORMSAVE(2)(r10); \
192 DO_KVM BOOKE_INTERRUPT_GUEST_DBELL SPRN_GSRR1; \
198 #define START_EXCEPTION(label) \
202 #define FINISH_EXCEPTION(func) \
203 bl transfer_to_handler_full; \
205 .long ret_from_except_full
207 #define EXCEPTION(n, intno, label, hdlr, xfer) \
208 START_EXCEPTION(label); \
209 NORMAL_EXCEPTION_PROLOG(intno); \
210 addi r3,r1,STACK_FRAME_OVERHEAD; \
213 #define CRITICAL_EXCEPTION(n, intno, label, hdlr) \
214 START_EXCEPTION(label); \
215 CRITICAL_EXCEPTION_PROLOG(intno); \
216 addi r3,r1,STACK_FRAME_OVERHEAD; \
217 EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
218 NOCOPY, crit_transfer_to_handler, \
221 #define MCHECK_EXCEPTION(n, label, hdlr) \
222 START_EXCEPTION(label); \
223 MCHECK_EXCEPTION_PROLOG; \
226 addi r3,r1,STACK_FRAME_OVERHEAD; \
227 EXC_XFER_TEMPLATE(hdlr, n+4, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
228 NOCOPY, mcheck_transfer_to_handler, \
231 #define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret) \
233 stw r10,_TRAP(r11); \
241 #define COPY_EE(d, s) rlwimi d,s,0,16,16
244 #define EXC_XFER_STD(n, hdlr) \
245 EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \
246 ret_from_except_full)
248 #define EXC_XFER_LITE(n, hdlr) \
249 EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \
252 #define EXC_XFER_EE(n, hdlr) \
253 EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \
254 ret_from_except_full)
256 #define EXC_XFER_EE_LITE(n, hdlr) \
257 EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \
273 #define DEBUG_DEBUG_EXCEPTION \
274 START_EXCEPTION(DebugDebug); \
275 DEBUG_EXCEPTION_PROLOG; \
285 mfspr r10,SPRN_DBSR; \
286 andis. r10,r10,(DBSR_IC|DBSR_BT)@h; \
289 lis r10,KERNELBASE@h; \
290 ori r10,r10,KERNELBASE@l; \
294 lis r10,DebugDebug@h; \
295 ori r10,r10,DebugDebug@l; \
300 1: rlwinm r9,r9,0,~MSR_DE; \
301 lis r10,(DBSR_IC|DBSR_BT)@h; \
302 mtspr SPRN_DBSR,r10; \
308 mtspr SPRN_DSRR0,r12; \
309 mtspr SPRN_DSRR1,r9; \
311 lwz r12,GPR12(r11); \
312 mtspr SPRN_SPRG_WSCRATCH_DBG,r8; \
313 BOOKE_LOAD_EXC_LEVEL_STACK(DBG); \
316 mfspr r8,SPRN_SPRG_RSCRATCH_DBG; \
322 2: mfspr r4,SPRN_DBSR; \
323 addi r3,r1,STACK_FRAME_OVERHEAD; \
324 EXC_XFER_TEMPLATE(DebugException, 0x2008, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, debug_transfer_to_handler, ret_from_debug_exc)
326 #define DEBUG_CRIT_EXCEPTION \
327 START_EXCEPTION(DebugCrit); \
328 CRITICAL_EXCEPTION_PROLOG(DEBUG); \
338 mfspr r10,SPRN_DBSR; \
339 andis. r10,r10,(DBSR_IC|DBSR_BT)@h; \
342 lis r10,KERNELBASE@h; \
343 ori r10,r10,KERNELBASE@l; \
347 lis r10,DebugCrit@h; \
348 ori r10,r10,DebugCrit@l; \
353 1: rlwinm r9,r9,0,~MSR_DE; \
354 lis r10,(DBSR_IC|DBSR_BT)@h; \
355 mtspr SPRN_DBSR,r10; \
361 mtspr SPRN_CSRR0,r12; \
362 mtspr SPRN_CSRR1,r9; \
364 lwz r12,GPR12(r11); \
365 mtspr SPRN_SPRG_WSCRATCH_CRIT,r8; \
366 BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); \
369 mfspr r8,SPRN_SPRG_RSCRATCH_CRIT; \
375 2: mfspr r4,SPRN_DBSR; \
376 addi r3,r1,STACK_FRAME_OVERHEAD; \
377 EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, crit_transfer_to_handler, ret_from_crit_exc)
379 #define DATA_STORAGE_EXCEPTION \
380 START_EXCEPTION(DataStorage) \
381 NORMAL_EXCEPTION_PROLOG(DATA_STORAGE); \
384 mfspr r4,SPRN_DEAR; \
385 EXC_XFER_LITE(0x0300, handle_page_fault)
387 #define INSTRUCTION_STORAGE_EXCEPTION \
388 START_EXCEPTION(InstructionStorage) \
389 NORMAL_EXCEPTION_PROLOG(INST_STORAGE); \
394 EXC_XFER_LITE(0x0400, handle_page_fault)
396 #define ALIGNMENT_EXCEPTION \
397 START_EXCEPTION(Alignment) \
398 NORMAL_EXCEPTION_PROLOG(ALIGNMENT); \
399 mfspr r4,SPRN_DEAR; \
401 addi r3,r1,STACK_FRAME_OVERHEAD; \
402 EXC_XFER_EE(0x0600, alignment_exception)
404 #define PROGRAM_EXCEPTION \
405 START_EXCEPTION(Program) \
406 NORMAL_EXCEPTION_PROLOG(PROGRAM); \
409 addi r3,r1,STACK_FRAME_OVERHEAD; \
410 EXC_XFER_STD(0x0700, program_check_exception)
412 #define DECREMENTER_EXCEPTION \
413 START_EXCEPTION(Decrementer) \
414 NORMAL_EXCEPTION_PROLOG(DECREMENTER); \
417 addi r3,r1,STACK_FRAME_OVERHEAD; \
418 EXC_XFER_LITE(0x0900, timer_interrupt)
420 #define FP_UNAVAILABLE_EXCEPTION \
421 START_EXCEPTION(FloatingPointUnavailable) \
422 NORMAL_EXCEPTION_PROLOG(FP_UNAVAIL); \
425 b fast_exception_return; \
426 1: addi r3,r1,STACK_FRAME_OVERHEAD; \
427 EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception)
447 #define STACK_EXC_LVL_FRAME_SIZE _ALIGN_UP(sizeof (struct exception_regs), 16)