aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/exceptions-64e.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/exceptions-64e.S')
-rw-r--r--arch/powerpc/kernel/exceptions-64e.S50
1 files changed, 46 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 24dcc0ecf24..5c43063d250 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); \
2281:
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
255interrupt_end_book3e: 278interrupt_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:
428kernel_dbg_exc: 454kernel_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)
563BAD_STACK_TRAMPOLINE(0xe00) 603BAD_STACK_TRAMPOLINE(0xe00)
564BAD_STACK_TRAMPOLINE(0xf00) 604BAD_STACK_TRAMPOLINE(0xf00)
565BAD_STACK_TRAMPOLINE(0xf20) 605BAD_STACK_TRAMPOLINE(0xf20)
606BAD_STACK_TRAMPOLINE(0x2070)
607BAD_STACK_TRAMPOLINE(0x2080)
566 608
567 .globl bad_stack_book3e 609 .globl bad_stack_book3e
568bad_stack_book3e: 610bad_stack_book3e: