diff options
Diffstat (limited to 'arch/powerpc/kernel/exceptions-64s.S')
-rw-r--r-- | arch/powerpc/kernel/exceptions-64s.S | 97 |
1 files changed, 59 insertions, 38 deletions
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index eb898112e57..1808876edcc 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -12,6 +12,8 @@ | |||
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <asm/exception-64s.h> | ||
16 | |||
15 | /* | 17 | /* |
16 | * We layout physical memory as follows: | 18 | * We layout physical memory as follows: |
17 | * 0x0000 - 0x00ff : Secondary processor spin code | 19 | * 0x0000 - 0x00ff : Secondary processor spin code |
@@ -22,18 +24,6 @@ | |||
22 | * 0x8000 - : Early init and support code | 24 | * 0x8000 - : Early init and support code |
23 | */ | 25 | */ |
24 | 26 | ||
25 | |||
26 | /* | ||
27 | * SPRG Usage | ||
28 | * | ||
29 | * Register Definition | ||
30 | * | ||
31 | * SPRG0 reserved for hypervisor | ||
32 | * SPRG1 temp - used to save gpr | ||
33 | * SPRG2 temp - used to save gpr | ||
34 | * SPRG3 virt addr of paca | ||
35 | */ | ||
36 | |||
37 | /* | 27 | /* |
38 | * This is the start of the interrupt handlers for pSeries | 28 | * This is the start of the interrupt handlers for pSeries |
39 | * This code runs with relocation off. | 29 | * This code runs with relocation off. |
@@ -51,34 +41,44 @@ __start_interrupts: | |||
51 | . = 0x200 | 41 | . = 0x200 |
52 | _machine_check_pSeries: | 42 | _machine_check_pSeries: |
53 | HMT_MEDIUM | 43 | HMT_MEDIUM |
54 | mtspr SPRN_SPRG1,r13 /* save r13 */ | 44 | mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */ |
55 | EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) | 45 | EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) |
56 | 46 | ||
57 | . = 0x300 | 47 | . = 0x300 |
58 | .globl data_access_pSeries | 48 | .globl data_access_pSeries |
59 | data_access_pSeries: | 49 | data_access_pSeries: |
60 | HMT_MEDIUM | 50 | HMT_MEDIUM |
61 | mtspr SPRN_SPRG1,r13 | 51 | mtspr SPRN_SPRG_SCRATCH0,r13 |
62 | BEGIN_FTR_SECTION | 52 | BEGIN_FTR_SECTION |
63 | mtspr SPRN_SPRG2,r12 | 53 | mfspr r13,SPRN_SPRG_PACA |
64 | mfspr r13,SPRN_DAR | 54 | std r9,PACA_EXSLB+EX_R9(r13) |
65 | mfspr r12,SPRN_DSISR | 55 | std r10,PACA_EXSLB+EX_R10(r13) |
66 | srdi r13,r13,60 | 56 | mfspr r10,SPRN_DAR |
67 | rlwimi r13,r12,16,0x20 | 57 | mfspr r9,SPRN_DSISR |
68 | mfcr r12 | 58 | srdi r10,r10,60 |
69 | cmpwi r13,0x2c | 59 | rlwimi r10,r9,16,0x20 |
60 | mfcr r9 | ||
61 | cmpwi r10,0x2c | ||
70 | beq do_stab_bolted_pSeries | 62 | beq do_stab_bolted_pSeries |
71 | mtcrf 0x80,r12 | 63 | ld r10,PACA_EXSLB+EX_R10(r13) |
72 | mfspr r12,SPRN_SPRG2 | 64 | std r11,PACA_EXGEN+EX_R11(r13) |
73 | END_FTR_SECTION_IFCLR(CPU_FTR_SLB) | 65 | ld r11,PACA_EXSLB+EX_R9(r13) |
66 | std r12,PACA_EXGEN+EX_R12(r13) | ||
67 | mfspr r12,SPRN_SPRG_SCRATCH0 | ||
68 | std r10,PACA_EXGEN+EX_R10(r13) | ||
69 | std r11,PACA_EXGEN+EX_R9(r13) | ||
70 | std r12,PACA_EXGEN+EX_R13(r13) | ||
71 | EXCEPTION_PROLOG_PSERIES_1(data_access_common) | ||
72 | FTR_SECTION_ELSE | ||
74 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common) | 73 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common) |
74 | ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB) | ||
75 | 75 | ||
76 | . = 0x380 | 76 | . = 0x380 |
77 | .globl data_access_slb_pSeries | 77 | .globl data_access_slb_pSeries |
78 | data_access_slb_pSeries: | 78 | data_access_slb_pSeries: |
79 | HMT_MEDIUM | 79 | HMT_MEDIUM |
80 | mtspr SPRN_SPRG1,r13 | 80 | mtspr SPRN_SPRG_SCRATCH0,r13 |
81 | mfspr r13,SPRN_SPRG3 /* get paca address into r13 */ | 81 | mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */ |
82 | std r3,PACA_EXSLB+EX_R3(r13) | 82 | std r3,PACA_EXSLB+EX_R3(r13) |
83 | mfspr r3,SPRN_DAR | 83 | mfspr r3,SPRN_DAR |
84 | std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ | 84 | std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ |
@@ -91,7 +91,7 @@ data_access_slb_pSeries: | |||
91 | std r10,PACA_EXSLB+EX_R10(r13) | 91 | std r10,PACA_EXSLB+EX_R10(r13) |
92 | std r11,PACA_EXSLB+EX_R11(r13) | 92 | std r11,PACA_EXSLB+EX_R11(r13) |
93 | std r12,PACA_EXSLB+EX_R12(r13) | 93 | std r12,PACA_EXSLB+EX_R12(r13) |
94 | mfspr r10,SPRN_SPRG1 | 94 | mfspr r10,SPRN_SPRG_SCRATCH0 |
95 | std r10,PACA_EXSLB+EX_R13(r13) | 95 | std r10,PACA_EXSLB+EX_R13(r13) |
96 | mfspr r12,SPRN_SRR1 /* and SRR1 */ | 96 | mfspr r12,SPRN_SRR1 /* and SRR1 */ |
97 | #ifndef CONFIG_RELOCATABLE | 97 | #ifndef CONFIG_RELOCATABLE |
@@ -115,8 +115,8 @@ data_access_slb_pSeries: | |||
115 | .globl instruction_access_slb_pSeries | 115 | .globl instruction_access_slb_pSeries |
116 | instruction_access_slb_pSeries: | 116 | instruction_access_slb_pSeries: |
117 | HMT_MEDIUM | 117 | HMT_MEDIUM |
118 | mtspr SPRN_SPRG1,r13 | 118 | mtspr SPRN_SPRG_SCRATCH0,r13 |
119 | mfspr r13,SPRN_SPRG3 /* get paca address into r13 */ | 119 | mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */ |
120 | std r3,PACA_EXSLB+EX_R3(r13) | 120 | std r3,PACA_EXSLB+EX_R3(r13) |
121 | mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ | 121 | mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ |
122 | std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ | 122 | std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ |
@@ -129,7 +129,7 @@ instruction_access_slb_pSeries: | |||
129 | std r10,PACA_EXSLB+EX_R10(r13) | 129 | std r10,PACA_EXSLB+EX_R10(r13) |
130 | std r11,PACA_EXSLB+EX_R11(r13) | 130 | std r11,PACA_EXSLB+EX_R11(r13) |
131 | std r12,PACA_EXSLB+EX_R12(r13) | 131 | std r12,PACA_EXSLB+EX_R12(r13) |
132 | mfspr r10,SPRN_SPRG1 | 132 | mfspr r10,SPRN_SPRG_SCRATCH0 |
133 | std r10,PACA_EXSLB+EX_R13(r13) | 133 | std r10,PACA_EXSLB+EX_R13(r13) |
134 | mfspr r12,SPRN_SRR1 /* and SRR1 */ | 134 | mfspr r12,SPRN_SRR1 /* and SRR1 */ |
135 | #ifndef CONFIG_RELOCATABLE | 135 | #ifndef CONFIG_RELOCATABLE |
@@ -159,7 +159,7 @@ BEGIN_FTR_SECTION | |||
159 | beq- 1f | 159 | beq- 1f |
160 | END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) | 160 | END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) |
161 | mr r9,r13 | 161 | mr r9,r13 |
162 | mfspr r13,SPRN_SPRG3 | 162 | mfspr r13,SPRN_SPRG_PACA |
163 | mfspr r11,SPRN_SRR0 | 163 | mfspr r11,SPRN_SRR0 |
164 | ld r12,PACAKBASE(r13) | 164 | ld r12,PACAKBASE(r13) |
165 | ld r10,PACAKMSR(r13) | 165 | ld r10,PACAKMSR(r13) |
@@ -228,15 +228,17 @@ masked_interrupt: | |||
228 | rotldi r10,r10,16 | 228 | rotldi r10,r10,16 |
229 | mtspr SPRN_SRR1,r10 | 229 | mtspr SPRN_SRR1,r10 |
230 | ld r10,PACA_EXGEN+EX_R10(r13) | 230 | ld r10,PACA_EXGEN+EX_R10(r13) |
231 | mfspr r13,SPRN_SPRG1 | 231 | mfspr r13,SPRN_SPRG_SCRATCH0 |
232 | rfid | 232 | rfid |
233 | b . | 233 | b . |
234 | 234 | ||
235 | .align 7 | 235 | .align 7 |
236 | do_stab_bolted_pSeries: | 236 | do_stab_bolted_pSeries: |
237 | mtcrf 0x80,r12 | 237 | std r11,PACA_EXSLB+EX_R11(r13) |
238 | mfspr r12,SPRN_SPRG2 | 238 | std r12,PACA_EXSLB+EX_R12(r13) |
239 | EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) | 239 | mfspr r10,SPRN_SPRG_SCRATCH0 |
240 | std r10,PACA_EXSLB+EX_R13(r13) | ||
241 | EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted) | ||
240 | 242 | ||
241 | #ifdef CONFIG_PPC_PSERIES | 243 | #ifdef CONFIG_PPC_PSERIES |
242 | /* | 244 | /* |
@@ -246,14 +248,14 @@ do_stab_bolted_pSeries: | |||
246 | .align 7 | 248 | .align 7 |
247 | system_reset_fwnmi: | 249 | system_reset_fwnmi: |
248 | HMT_MEDIUM | 250 | HMT_MEDIUM |
249 | mtspr SPRN_SPRG1,r13 /* save r13 */ | 251 | mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */ |
250 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) | 252 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) |
251 | 253 | ||
252 | .globl machine_check_fwnmi | 254 | .globl machine_check_fwnmi |
253 | .align 7 | 255 | .align 7 |
254 | machine_check_fwnmi: | 256 | machine_check_fwnmi: |
255 | HMT_MEDIUM | 257 | HMT_MEDIUM |
256 | mtspr SPRN_SPRG1,r13 /* save r13 */ | 258 | mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */ |
257 | EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) | 259 | EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) |
258 | 260 | ||
259 | #endif /* CONFIG_PPC_PSERIES */ | 261 | #endif /* CONFIG_PPC_PSERIES */ |
@@ -268,7 +270,7 @@ slb_miss_user_pseries: | |||
268 | std r10,PACA_EXGEN+EX_R10(r13) | 270 | std r10,PACA_EXGEN+EX_R10(r13) |
269 | std r11,PACA_EXGEN+EX_R11(r13) | 271 | std r11,PACA_EXGEN+EX_R11(r13) |
270 | std r12,PACA_EXGEN+EX_R12(r13) | 272 | std r12,PACA_EXGEN+EX_R12(r13) |
271 | mfspr r10,SPRG1 | 273 | mfspr r10,SPRG_SCRATCH0 |
272 | ld r11,PACA_EXSLB+EX_R9(r13) | 274 | ld r11,PACA_EXSLB+EX_R9(r13) |
273 | ld r12,PACA_EXSLB+EX_R3(r13) | 275 | ld r12,PACA_EXSLB+EX_R3(r13) |
274 | std r10,PACA_EXGEN+EX_R13(r13) | 276 | std r10,PACA_EXGEN+EX_R13(r13) |
@@ -729,6 +731,11 @@ BEGIN_FTR_SECTION | |||
729 | bne- do_ste_alloc /* If so handle it */ | 731 | bne- do_ste_alloc /* If so handle it */ |
730 | END_FTR_SECTION_IFCLR(CPU_FTR_SLB) | 732 | END_FTR_SECTION_IFCLR(CPU_FTR_SLB) |
731 | 733 | ||
734 | clrrdi r11,r1,THREAD_SHIFT | ||
735 | lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */ | ||
736 | andis. r0,r0,NMI_MASK@h /* (i.e. an irq when soft-disabled) */ | ||
737 | bne 77f /* then don't call hash_page now */ | ||
738 | |||
732 | /* | 739 | /* |
733 | * On iSeries, we soft-disable interrupts here, then | 740 | * On iSeries, we soft-disable interrupts here, then |
734 | * hard-enable interrupts so that the hash_page code can spin on | 741 | * hard-enable interrupts so that the hash_page code can spin on |
@@ -833,6 +840,20 @@ handle_page_fault: | |||
833 | bl .low_hash_fault | 840 | bl .low_hash_fault |
834 | b .ret_from_except | 841 | b .ret_from_except |
835 | 842 | ||
843 | /* | ||
844 | * We come here as a result of a DSI at a point where we don't want | ||
845 | * to call hash_page, such as when we are accessing memory (possibly | ||
846 | * user memory) inside a PMU interrupt that occurred while interrupts | ||
847 | * were soft-disabled. We want to invoke the exception handler for | ||
848 | * the access, or panic if there isn't a handler. | ||
849 | */ | ||
850 | 77: bl .save_nvgprs | ||
851 | mr r4,r3 | ||
852 | addi r3,r1,STACK_FRAME_OVERHEAD | ||
853 | li r5,SIGSEGV | ||
854 | bl .bad_page_fault | ||
855 | b .ret_from_except | ||
856 | |||
836 | /* here we have a segment miss */ | 857 | /* here we have a segment miss */ |
837 | do_ste_alloc: | 858 | do_ste_alloc: |
838 | bl .ste_allocate /* try to insert stab entry */ | 859 | bl .ste_allocate /* try to insert stab entry */ |