diff options
author | Scott Wood <scottwood@freescale.com> | 2011-12-20 10:34:40 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2012-04-08 05:51:17 -0400 |
commit | cfac57847a67c4903f34a77e971521531bbc7c77 (patch) | |
tree | 1803ecce9ff975e7602b3c47ae53f8111cfb1184 /arch/powerpc/kernel/head_booke.h | |
parent | ab9fc4056af338248640ddb18497be386360363d (diff) |
powerpc/booke: Provide exception macros with interrupt name
DO_KVM will need to identify the particular exception type.
There is an existing set of arbitrary numbers that Linux passes,
but it's an undocumented mess that sort of corresponds to server/classic
exception vectors but not really.
Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/powerpc/kernel/head_booke.h')
-rw-r--r-- | arch/powerpc/kernel/head_booke.h | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index 0e4175388f47..51fd0724e095 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h | |||
@@ -2,6 +2,8 @@ | |||
2 | #define __HEAD_BOOKE_H__ | 2 | #define __HEAD_BOOKE_H__ |
3 | 3 | ||
4 | #include <asm/ptrace.h> /* for STACK_FRAME_REGS_MARKER */ | 4 | #include <asm/ptrace.h> /* for STACK_FRAME_REGS_MARKER */ |
5 | #include <asm/kvm_asm.h> | ||
6 | |||
5 | /* | 7 | /* |
6 | * Macros used for common Book-e exception handling | 8 | * Macros used for common Book-e exception handling |
7 | */ | 9 | */ |
@@ -28,7 +30,7 @@ | |||
28 | */ | 30 | */ |
29 | #define THREAD_NORMSAVE(offset) (THREAD_NORMSAVES + (offset * 4)) | 31 | #define THREAD_NORMSAVE(offset) (THREAD_NORMSAVES + (offset * 4)) |
30 | 32 | ||
31 | #define NORMAL_EXCEPTION_PROLOG \ | 33 | #define NORMAL_EXCEPTION_PROLOG(intno) \ |
32 | mtspr SPRN_SPRG_WSCRATCH0, r10; /* save one register */ \ | 34 | mtspr SPRN_SPRG_WSCRATCH0, r10; /* save one register */ \ |
33 | mfspr r10, SPRN_SPRG_THREAD; \ | 35 | mfspr r10, SPRN_SPRG_THREAD; \ |
34 | stw r11, THREAD_NORMSAVE(0)(r10); \ | 36 | stw r11, THREAD_NORMSAVE(0)(r10); \ |
@@ -113,7 +115,7 @@ | |||
113 | * registers as the normal prolog above. Instead we use a portion of the | 115 | * registers as the normal prolog above. Instead we use a portion of the |
114 | * critical/machine check exception stack at low physical addresses. | 116 | * critical/machine check exception stack at low physical addresses. |
115 | */ | 117 | */ |
116 | #define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \ | 118 | #define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, intno, exc_level_srr0, exc_level_srr1) \ |
117 | mtspr SPRN_SPRG_WSCRATCH_##exc_level,r8; \ | 119 | mtspr SPRN_SPRG_WSCRATCH_##exc_level,r8; \ |
118 | BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \ | 120 | BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \ |
119 | stw r9,GPR9(r8); /* save various registers */\ | 121 | stw r9,GPR9(r8); /* save various registers */\ |
@@ -162,12 +164,13 @@ | |||
162 | SAVE_4GPRS(3, r11); \ | 164 | SAVE_4GPRS(3, r11); \ |
163 | SAVE_2GPRS(7, r11) | 165 | SAVE_2GPRS(7, r11) |
164 | 166 | ||
165 | #define CRITICAL_EXCEPTION_PROLOG \ | 167 | #define CRITICAL_EXCEPTION_PROLOG(intno) \ |
166 | EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1) | 168 | EXC_LEVEL_EXCEPTION_PROLOG(CRIT, intno, SPRN_CSRR0, SPRN_CSRR1) |
167 | #define DEBUG_EXCEPTION_PROLOG \ | 169 | #define DEBUG_EXCEPTION_PROLOG \ |
168 | EXC_LEVEL_EXCEPTION_PROLOG(DBG, SPRN_DSRR0, SPRN_DSRR1) | 170 | EXC_LEVEL_EXCEPTION_PROLOG(DBG, DEBUG, SPRN_DSRR0, SPRN_DSRR1) |
169 | #define MCHECK_EXCEPTION_PROLOG \ | 171 | #define MCHECK_EXCEPTION_PROLOG \ |
170 | EXC_LEVEL_EXCEPTION_PROLOG(MC, SPRN_MCSRR0, SPRN_MCSRR1) | 172 | EXC_LEVEL_EXCEPTION_PROLOG(MC, MACHINE_CHECK, \ |
173 | SPRN_MCSRR0, SPRN_MCSRR1) | ||
171 | 174 | ||
172 | /* | 175 | /* |
173 | * Exception vectors. | 176 | * Exception vectors. |
@@ -181,16 +184,16 @@ label: | |||
181 | .long func; \ | 184 | .long func; \ |
182 | .long ret_from_except_full | 185 | .long ret_from_except_full |
183 | 186 | ||
184 | #define EXCEPTION(n, label, hdlr, xfer) \ | 187 | #define EXCEPTION(n, intno, label, hdlr, xfer) \ |
185 | START_EXCEPTION(label); \ | 188 | START_EXCEPTION(label); \ |
186 | NORMAL_EXCEPTION_PROLOG; \ | 189 | NORMAL_EXCEPTION_PROLOG(intno); \ |
187 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 190 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
188 | xfer(n, hdlr) | 191 | xfer(n, hdlr) |
189 | 192 | ||
190 | #define CRITICAL_EXCEPTION(n, label, hdlr) \ | 193 | #define CRITICAL_EXCEPTION(n, intno, label, hdlr) \ |
191 | START_EXCEPTION(label); \ | 194 | START_EXCEPTION(label); \ |
192 | CRITICAL_EXCEPTION_PROLOG; \ | 195 | CRITICAL_EXCEPTION_PROLOG(intno); \ |
193 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 196 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
194 | EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ | 197 | EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ |
195 | NOCOPY, crit_transfer_to_handler, \ | 198 | NOCOPY, crit_transfer_to_handler, \ |
196 | ret_from_crit_exc) | 199 | ret_from_crit_exc) |
@@ -302,7 +305,7 @@ label: | |||
302 | 305 | ||
303 | #define DEBUG_CRIT_EXCEPTION \ | 306 | #define DEBUG_CRIT_EXCEPTION \ |
304 | START_EXCEPTION(DebugCrit); \ | 307 | START_EXCEPTION(DebugCrit); \ |
305 | CRITICAL_EXCEPTION_PROLOG; \ | 308 | CRITICAL_EXCEPTION_PROLOG(DEBUG); \ |
306 | \ | 309 | \ |
307 | /* \ | 310 | /* \ |
308 | * If there is a single step or branch-taken exception in an \ | 311 | * If there is a single step or branch-taken exception in an \ |
@@ -355,7 +358,7 @@ label: | |||
355 | 358 | ||
356 | #define DATA_STORAGE_EXCEPTION \ | 359 | #define DATA_STORAGE_EXCEPTION \ |
357 | START_EXCEPTION(DataStorage) \ | 360 | START_EXCEPTION(DataStorage) \ |
358 | NORMAL_EXCEPTION_PROLOG; \ | 361 | NORMAL_EXCEPTION_PROLOG(DATA_STORAGE); \ |
359 | mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \ | 362 | mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \ |
360 | stw r5,_ESR(r11); \ | 363 | stw r5,_ESR(r11); \ |
361 | mfspr r4,SPRN_DEAR; /* Grab the DEAR */ \ | 364 | mfspr r4,SPRN_DEAR; /* Grab the DEAR */ \ |
@@ -363,7 +366,7 @@ label: | |||
363 | 366 | ||
364 | #define INSTRUCTION_STORAGE_EXCEPTION \ | 367 | #define INSTRUCTION_STORAGE_EXCEPTION \ |
365 | START_EXCEPTION(InstructionStorage) \ | 368 | START_EXCEPTION(InstructionStorage) \ |
366 | NORMAL_EXCEPTION_PROLOG; \ | 369 | NORMAL_EXCEPTION_PROLOG(INST_STORAGE); \ |
367 | mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \ | 370 | mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \ |
368 | stw r5,_ESR(r11); \ | 371 | stw r5,_ESR(r11); \ |
369 | mr r4,r12; /* Pass SRR0 as arg2 */ \ | 372 | mr r4,r12; /* Pass SRR0 as arg2 */ \ |
@@ -372,7 +375,7 @@ label: | |||
372 | 375 | ||
373 | #define ALIGNMENT_EXCEPTION \ | 376 | #define ALIGNMENT_EXCEPTION \ |
374 | START_EXCEPTION(Alignment) \ | 377 | START_EXCEPTION(Alignment) \ |
375 | NORMAL_EXCEPTION_PROLOG; \ | 378 | NORMAL_EXCEPTION_PROLOG(ALIGNMENT); \ |
376 | mfspr r4,SPRN_DEAR; /* Grab the DEAR and save it */ \ | 379 | mfspr r4,SPRN_DEAR; /* Grab the DEAR and save it */ \ |
377 | stw r4,_DEAR(r11); \ | 380 | stw r4,_DEAR(r11); \ |
378 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 381 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
@@ -380,7 +383,7 @@ label: | |||
380 | 383 | ||
381 | #define PROGRAM_EXCEPTION \ | 384 | #define PROGRAM_EXCEPTION \ |
382 | START_EXCEPTION(Program) \ | 385 | START_EXCEPTION(Program) \ |
383 | NORMAL_EXCEPTION_PROLOG; \ | 386 | NORMAL_EXCEPTION_PROLOG(PROGRAM); \ |
384 | mfspr r4,SPRN_ESR; /* Grab the ESR and save it */ \ | 387 | mfspr r4,SPRN_ESR; /* Grab the ESR and save it */ \ |
385 | stw r4,_ESR(r11); \ | 388 | stw r4,_ESR(r11); \ |
386 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 389 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
@@ -388,7 +391,7 @@ label: | |||
388 | 391 | ||
389 | #define DECREMENTER_EXCEPTION \ | 392 | #define DECREMENTER_EXCEPTION \ |
390 | START_EXCEPTION(Decrementer) \ | 393 | START_EXCEPTION(Decrementer) \ |
391 | NORMAL_EXCEPTION_PROLOG; \ | 394 | NORMAL_EXCEPTION_PROLOG(DECREMENTER); \ |
392 | lis r0,TSR_DIS@h; /* Setup the DEC interrupt mask */ \ | 395 | lis r0,TSR_DIS@h; /* Setup the DEC interrupt mask */ \ |
393 | mtspr SPRN_TSR,r0; /* Clear the DEC interrupt */ \ | 396 | mtspr SPRN_TSR,r0; /* Clear the DEC interrupt */ \ |
394 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 397 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
@@ -396,7 +399,7 @@ label: | |||
396 | 399 | ||
397 | #define FP_UNAVAILABLE_EXCEPTION \ | 400 | #define FP_UNAVAILABLE_EXCEPTION \ |
398 | START_EXCEPTION(FloatingPointUnavailable) \ | 401 | START_EXCEPTION(FloatingPointUnavailable) \ |
399 | NORMAL_EXCEPTION_PROLOG; \ | 402 | NORMAL_EXCEPTION_PROLOG(FP_UNAVAIL); \ |
400 | beq 1f; \ | 403 | beq 1f; \ |
401 | bl load_up_fpu; /* if from user, just load it up */ \ | 404 | bl load_up_fpu; /* if from user, just load it up */ \ |
402 | b fast_exception_return; \ | 405 | b fast_exception_return; \ |