diff options
Diffstat (limited to 'arch/powerpc/kernel/exceptions-64e.S')
-rw-r--r-- | arch/powerpc/kernel/exceptions-64e.S | 50 |
1 files changed, 46 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index 24dcc0ecf246..5c43063d2506 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S | |||
@@ -191,6 +191,12 @@ exc_##n##_bad_stack: \ | |||
191 | sth r1,PACA_TRAP_SAVE(r13); /* store trap */ \ | 191 | sth r1,PACA_TRAP_SAVE(r13); /* store trap */ \ |
192 | b bad_stack_book3e; /* bad stack error */ | 192 | b bad_stack_book3e; /* bad stack error */ |
193 | 193 | ||
194 | /* WARNING: If you change the layout of this stub, make sure you chcek | ||
195 | * the debug exception handler which handles single stepping | ||
196 | * into exceptions from userspace, and the MM code in | ||
197 | * arch/powerpc/mm/tlb_nohash.c which patches the branch here | ||
198 | * and would need to be updated if that branch is moved | ||
199 | */ | ||
194 | #define EXCEPTION_STUB(loc, label) \ | 200 | #define EXCEPTION_STUB(loc, label) \ |
195 | . = interrupt_base_book3e + loc; \ | 201 | . = interrupt_base_book3e + loc; \ |
196 | nop; /* To make debug interrupts happy */ \ | 202 | nop; /* To make debug interrupts happy */ \ |
@@ -204,11 +210,30 @@ exc_##n##_bad_stack: \ | |||
204 | lis r,TSR_FIS@h; \ | 210 | lis r,TSR_FIS@h; \ |
205 | mtspr SPRN_TSR,r | 211 | mtspr SPRN_TSR,r |
206 | 212 | ||
213 | /* Used by asynchronous interrupt that may happen in the idle loop. | ||
214 | * | ||
215 | * This check if the thread was in the idle loop, and if yes, returns | ||
216 | * to the caller rather than the PC. This is to avoid a race if | ||
217 | * interrupts happen before the wait instruction. | ||
218 | */ | ||
219 | #define CHECK_NAPPING() \ | ||
220 | clrrdi r11,r1,THREAD_SHIFT; \ | ||
221 | ld r10,TI_LOCAL_FLAGS(r11); \ | ||
222 | andi. r9,r10,_TLF_NAPPING; \ | ||
223 | beq+ 1f; \ | ||
224 | ld r8,_LINK(r1); \ | ||
225 | rlwinm r7,r10,0,~_TLF_NAPPING; \ | ||
226 | std r8,_NIP(r1); \ | ||
227 | std r7,TI_LOCAL_FLAGS(r11); \ | ||
228 | 1: | ||
229 | |||
230 | |||
207 | #define MASKABLE_EXCEPTION(trapnum, label, hdlr, ack) \ | 231 | #define MASKABLE_EXCEPTION(trapnum, label, hdlr, ack) \ |
208 | START_EXCEPTION(label); \ | 232 | START_EXCEPTION(label); \ |
209 | NORMAL_EXCEPTION_PROLOG(trapnum, PROLOG_ADDITION_MASKABLE) \ | 233 | NORMAL_EXCEPTION_PROLOG(trapnum, PROLOG_ADDITION_MASKABLE) \ |
210 | EXCEPTION_COMMON(trapnum, PACA_EXGEN, INTS_DISABLE_ALL) \ | 234 | EXCEPTION_COMMON(trapnum, PACA_EXGEN, INTS_DISABLE_ALL) \ |
211 | ack(r8); \ | 235 | ack(r8); \ |
236 | CHECK_NAPPING(); \ | ||
212 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 237 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
213 | bl hdlr; \ | 238 | bl hdlr; \ |
214 | b .ret_from_except_lite; | 239 | b .ret_from_except_lite; |
@@ -246,11 +271,9 @@ interrupt_base_book3e: /* fake trap */ | |||
246 | EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */ | 271 | EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */ |
247 | EXCEPTION_STUB(0x1c0, data_tlb_miss) | 272 | EXCEPTION_STUB(0x1c0, data_tlb_miss) |
248 | EXCEPTION_STUB(0x1e0, instruction_tlb_miss) | 273 | EXCEPTION_STUB(0x1e0, instruction_tlb_miss) |
274 | EXCEPTION_STUB(0x280, doorbell) | ||
275 | EXCEPTION_STUB(0x2a0, doorbell_crit) | ||
249 | 276 | ||
250 | #if 0 | ||
251 | EXCEPTION_STUB(0x280, processor_doorbell) | ||
252 | EXCEPTION_STUB(0x220, processor_doorbell_crit) | ||
253 | #endif | ||
254 | .globl interrupt_end_book3e | 277 | .globl interrupt_end_book3e |
255 | interrupt_end_book3e: | 278 | interrupt_end_book3e: |
256 | 279 | ||
@@ -259,6 +282,7 @@ interrupt_end_book3e: | |||
259 | CRIT_EXCEPTION_PROLOG(0x100, PROLOG_ADDITION_NONE) | 282 | CRIT_EXCEPTION_PROLOG(0x100, PROLOG_ADDITION_NONE) |
260 | // EXCEPTION_COMMON(0x100, PACA_EXCRIT, INTS_DISABLE_ALL) | 283 | // EXCEPTION_COMMON(0x100, PACA_EXCRIT, INTS_DISABLE_ALL) |
261 | // bl special_reg_save_crit | 284 | // bl special_reg_save_crit |
285 | // CHECK_NAPPING(); | ||
262 | // addi r3,r1,STACK_FRAME_OVERHEAD | 286 | // addi r3,r1,STACK_FRAME_OVERHEAD |
263 | // bl .critical_exception | 287 | // bl .critical_exception |
264 | // b ret_from_crit_except | 288 | // b ret_from_crit_except |
@@ -270,6 +294,7 @@ interrupt_end_book3e: | |||
270 | // EXCEPTION_COMMON(0x200, PACA_EXMC, INTS_DISABLE_ALL) | 294 | // EXCEPTION_COMMON(0x200, PACA_EXMC, INTS_DISABLE_ALL) |
271 | // bl special_reg_save_mc | 295 | // bl special_reg_save_mc |
272 | // addi r3,r1,STACK_FRAME_OVERHEAD | 296 | // addi r3,r1,STACK_FRAME_OVERHEAD |
297 | // CHECK_NAPPING(); | ||
273 | // bl .machine_check_exception | 298 | // bl .machine_check_exception |
274 | // b ret_from_mc_except | 299 | // b ret_from_mc_except |
275 | b . | 300 | b . |
@@ -340,6 +365,7 @@ interrupt_end_book3e: | |||
340 | CRIT_EXCEPTION_PROLOG(0x9f0, PROLOG_ADDITION_NONE) | 365 | CRIT_EXCEPTION_PROLOG(0x9f0, PROLOG_ADDITION_NONE) |
341 | // EXCEPTION_COMMON(0x9f0, PACA_EXCRIT, INTS_DISABLE_ALL) | 366 | // EXCEPTION_COMMON(0x9f0, PACA_EXCRIT, INTS_DISABLE_ALL) |
342 | // bl special_reg_save_crit | 367 | // bl special_reg_save_crit |
368 | // CHECK_NAPPING(); | ||
343 | // addi r3,r1,STACK_FRAME_OVERHEAD | 369 | // addi r3,r1,STACK_FRAME_OVERHEAD |
344 | // bl .unknown_exception | 370 | // bl .unknown_exception |
345 | // b ret_from_crit_except | 371 | // b ret_from_crit_except |
@@ -428,6 +454,20 @@ interrupt_end_book3e: | |||
428 | kernel_dbg_exc: | 454 | kernel_dbg_exc: |
429 | b . /* NYI */ | 455 | b . /* NYI */ |
430 | 456 | ||
457 | /* Doorbell interrupt */ | ||
458 | MASKABLE_EXCEPTION(0x2070, doorbell, .doorbell_exception, ACK_NONE) | ||
459 | |||
460 | /* Doorbell critical Interrupt */ | ||
461 | START_EXCEPTION(doorbell_crit); | ||
462 | CRIT_EXCEPTION_PROLOG(0x2080, PROLOG_ADDITION_NONE) | ||
463 | // EXCEPTION_COMMON(0x2080, PACA_EXCRIT, INTS_DISABLE_ALL) | ||
464 | // bl special_reg_save_crit | ||
465 | // CHECK_NAPPING(); | ||
466 | // addi r3,r1,STACK_FRAME_OVERHEAD | ||
467 | // bl .doorbell_critical_exception | ||
468 | // b ret_from_crit_except | ||
469 | b . | ||
470 | |||
431 | 471 | ||
432 | /* | 472 | /* |
433 | * An interrupt came in while soft-disabled; clear EE in SRR1, | 473 | * An interrupt came in while soft-disabled; clear EE in SRR1, |
@@ -563,6 +603,8 @@ BAD_STACK_TRAMPOLINE(0xd00) | |||
563 | BAD_STACK_TRAMPOLINE(0xe00) | 603 | BAD_STACK_TRAMPOLINE(0xe00) |
564 | BAD_STACK_TRAMPOLINE(0xf00) | 604 | BAD_STACK_TRAMPOLINE(0xf00) |
565 | BAD_STACK_TRAMPOLINE(0xf20) | 605 | BAD_STACK_TRAMPOLINE(0xf20) |
606 | BAD_STACK_TRAMPOLINE(0x2070) | ||
607 | BAD_STACK_TRAMPOLINE(0x2080) | ||
566 | 608 | ||
567 | .globl bad_stack_book3e | 609 | .globl bad_stack_book3e |
568 | bad_stack_book3e: | 610 | bad_stack_book3e: |