diff options
-rw-r--r-- | arch/powerpc/include/asm/exception-64s.h | 37 | ||||
-rw-r--r-- | arch/powerpc/include/asm/feature-fixups.h | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/exceptions-64s.S | 92 |
3 files changed, 89 insertions, 42 deletions
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 1d98e05be511..fb5b0af30fcf 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h | |||
@@ -150,28 +150,27 @@ | |||
150 | /* | 150 | /* |
151 | * Exception vectors. | 151 | * Exception vectors. |
152 | */ | 152 | */ |
153 | #define STD_EXCEPTION_PSERIES(n, label) \ | 153 | #define STD_EXCEPTION_PSERIES(loc, vec, label) \ |
154 | . = n; \ | 154 | . = loc; \ |
155 | .globl label##_pSeries; \ | 155 | .globl label##_pSeries; \ |
156 | label##_pSeries: \ | 156 | label##_pSeries: \ |
157 | HMT_MEDIUM; \ | 157 | HMT_MEDIUM; \ |
158 | DO_KVM n; \ | 158 | DO_KVM vec; \ |
159 | mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \ | 159 | mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \ |
160 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_STD) | 160 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_STD) |
161 | 161 | ||
162 | #define HSTD_EXCEPTION_PSERIES(n, label) \ | 162 | #define STD_EXCEPTION_HV(loc, vec, label) \ |
163 | . = n; \ | 163 | . = loc; \ |
164 | .globl label##_pSeries; \ | 164 | .globl label##_hv; \ |
165 | label##_pSeries: \ | 165 | label##_hv: \ |
166 | HMT_MEDIUM; \ | 166 | HMT_MEDIUM; \ |
167 | DO_KVM n; \ | 167 | DO_KVM vec; \ |
168 | mtspr SPRN_SPRG_HSCRATCH0,r13;/* save r13 */ \ | 168 | mtspr SPRN_SPRG_HSCRATCH0,r13;/* save r13 */ \ |
169 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_HV) | 169 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_HV) |
170 | 170 | ||
171 | 171 | #define __MASKABLE_EXCEPTION_PSERIES(vec, label, h) \ | |
172 | #define __MASKABLE_EXCEPTION_PSERIES(n, label, h) \ | ||
173 | HMT_MEDIUM; \ | 172 | HMT_MEDIUM; \ |
174 | DO_KVM n; \ | 173 | DO_KVM vec; \ |
175 | mtspr SPRN_SPRG_##h##SCRATCH0,r13; /* save r13 */ \ | 174 | mtspr SPRN_SPRG_##h##SCRATCH0,r13; /* save r13 */ \ |
176 | GET_PACA(r13); \ | 175 | GET_PACA(r13); \ |
177 | std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \ | 176 | std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \ |
@@ -193,8 +192,20 @@ label##_pSeries: \ | |||
193 | mtspr SPRN_##h##SRR1,r10; \ | 192 | mtspr SPRN_##h##SRR1,r10; \ |
194 | h##rfid; \ | 193 | h##rfid; \ |
195 | b . /* prevent speculative execution */ | 194 | b . /* prevent speculative execution */ |
196 | #define MASKABLE_EXCEPTION_PSERIES(n, label, h) \ | 195 | #define _MASKABLE_EXCEPTION_PSERIES(vec, label, h) \ |
197 | __MASKABLE_EXCEPTION_PSERIES(n, label, h) | 196 | __MASKABLE_EXCEPTION_PSERIES(vec, label, h) |
197 | |||
198 | #define MASKABLE_EXCEPTION_PSERIES(loc, vec, label) \ | ||
199 | . = loc; \ | ||
200 | .globl label##_pSeries; \ | ||
201 | label##_pSeries: \ | ||
202 | _MASKABLE_EXCEPTION_PSERIES(vec, label, EXC_STD) | ||
203 | |||
204 | #define MASKABLE_EXCEPTION_HV(loc, vec, label) \ | ||
205 | . = loc; \ | ||
206 | .globl label##_hv; \ | ||
207 | label##_hv: \ | ||
208 | _MASKABLE_EXCEPTION_PSERIES(vec, label, EXC_HV) | ||
198 | 209 | ||
199 | #ifdef CONFIG_PPC_ISERIES | 210 | #ifdef CONFIG_PPC_ISERIES |
200 | #define DISABLE_INTS \ | 211 | #define DISABLE_INTS \ |
diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h index 921a8470e18a..bdc0d6877bce 100644 --- a/arch/powerpc/include/asm/feature-fixups.h +++ b/arch/powerpc/include/asm/feature-fixups.h | |||
@@ -49,7 +49,7 @@ label##5: \ | |||
49 | FTR_ENTRY_OFFSET label##2b-label##5b; \ | 49 | FTR_ENTRY_OFFSET label##2b-label##5b; \ |
50 | FTR_ENTRY_OFFSET label##3b-label##5b; \ | 50 | FTR_ENTRY_OFFSET label##3b-label##5b; \ |
51 | FTR_ENTRY_OFFSET label##4b-label##5b; \ | 51 | FTR_ENTRY_OFFSET label##4b-label##5b; \ |
52 | .ifgt (label##4b-label##3b)-(label##2b-label##1b); \ | 52 | .ifgt (label##4b- label##3b)-(label##2b- label##1b); \ |
53 | .error "Feature section else case larger than body"; \ | 53 | .error "Feature section else case larger than body"; \ |
54 | .endif; \ | 54 | .endif; \ |
55 | .popsection; | 55 | .popsection; |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 17f1d6670635..805e20657868 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -37,7 +37,7 @@ | |||
37 | .globl __start_interrupts | 37 | .globl __start_interrupts |
38 | __start_interrupts: | 38 | __start_interrupts: |
39 | 39 | ||
40 | STD_EXCEPTION_PSERIES(0x100, system_reset) | 40 | STD_EXCEPTION_PSERIES(0x100, 0x100, system_reset) |
41 | 41 | ||
42 | . = 0x200 | 42 | . = 0x200 |
43 | _machine_check_pSeries: | 43 | _machine_check_pSeries: |
@@ -113,7 +113,7 @@ data_access_slb_pSeries: | |||
113 | bctr | 113 | bctr |
114 | #endif | 114 | #endif |
115 | 115 | ||
116 | STD_EXCEPTION_PSERIES(0x400, instruction_access) | 116 | STD_EXCEPTION_PSERIES(0x400, 0x400, instruction_access) |
117 | 117 | ||
118 | . = 0x480 | 118 | . = 0x480 |
119 | .globl instruction_access_slb_pSeries | 119 | .globl instruction_access_slb_pSeries |
@@ -147,26 +147,29 @@ instruction_access_slb_pSeries: | |||
147 | bctr | 147 | bctr |
148 | #endif | 148 | #endif |
149 | 149 | ||
150 | /* We open code these as we can't have a ". = x" (even with | ||
151 | * x = "." within a feature section | ||
152 | */ | ||
150 | . = 0x500; | 153 | . = 0x500; |
151 | .globl hardware_interrupt_pSeries | 154 | .globl hardware_interrupt_pSeries; |
155 | .globl hardware_interrupt_hv; | ||
152 | hardware_interrupt_pSeries: | 156 | hardware_interrupt_pSeries: |
157 | hardware_interrupt_hv: | ||
153 | BEGIN_FTR_SECTION | 158 | BEGIN_FTR_SECTION |
154 | MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt, EXC_STD) | 159 | _MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt, EXC_STD) |
155 | FTR_SECTION_ELSE | 160 | FTR_SECTION_ELSE |
156 | MASKABLE_EXCEPTION_PSERIES(0x502, hardware_interrupt, EXC_HV) | 161 | _MASKABLE_EXCEPTION_PSERIES(0x502, hardware_interrupt, EXC_HV) |
157 | ALT_FTR_SECTION_END_IFCLR(CPU_FTR_HVMODE_206) | 162 | ALT_FTR_SECTION_END_IFCLR(CPU_FTR_HVMODE_206) |
158 | 163 | ||
159 | STD_EXCEPTION_PSERIES(0x600, alignment) | 164 | STD_EXCEPTION_PSERIES(0x600, 0x600, alignment) |
160 | STD_EXCEPTION_PSERIES(0x700, program_check) | 165 | STD_EXCEPTION_PSERIES(0x700, 0x700, program_check) |
161 | STD_EXCEPTION_PSERIES(0x800, fp_unavailable) | 166 | STD_EXCEPTION_PSERIES(0x800, 0x800, fp_unavailable) |
162 | 167 | ||
163 | . = 0x900; | 168 | MASKABLE_EXCEPTION_PSERIES(0x900, 0x900, decrementer) |
164 | .globl decrementer_pSeries | 169 | MASKABLE_EXCEPTION_HV(0x980, 0x980, decrementer) |
165 | decrementer_pSeries: | ||
166 | MASKABLE_EXCEPTION_PSERIES(0x900, decrementer, EXC_STD) | ||
167 | 170 | ||
168 | STD_EXCEPTION_PSERIES(0xa00, trap_0a) | 171 | STD_EXCEPTION_PSERIES(0xa00, 0xa00, trap_0a) |
169 | STD_EXCEPTION_PSERIES(0xb00, trap_0b) | 172 | STD_EXCEPTION_PSERIES(0xb00, 0xb00, trap_0b) |
170 | 173 | ||
171 | . = 0xc00 | 174 | . = 0xc00 |
172 | .globl system_call_pSeries | 175 | .globl system_call_pSeries |
@@ -196,8 +199,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) | |||
196 | rfid /* return to userspace */ | 199 | rfid /* return to userspace */ |
197 | b . | 200 | b . |
198 | 201 | ||
199 | STD_EXCEPTION_PSERIES(0xd00, single_step) | 202 | STD_EXCEPTION_PSERIES(0xd00, 0xd00, single_step) |
200 | STD_EXCEPTION_PSERIES(0xe00, trap_0e) | 203 | |
204 | /* At 0xe??? we have a bunch of hypervisor exceptions, we branch | ||
205 | * out of line to handle them | ||
206 | */ | ||
207 | . = 0xe00 | ||
208 | b h_data_storage_hv | ||
209 | . = 0xe20 | ||
210 | b h_instr_storage_hv | ||
211 | . = 0xe40 | ||
212 | b emulation_assist_hv | ||
213 | . = 0xe50 | ||
214 | b hmi_exception_hv | ||
215 | . = 0xe60 | ||
216 | b hmi_exception_hv | ||
201 | 217 | ||
202 | /* We need to deal with the Altivec unavailable exception | 218 | /* We need to deal with the Altivec unavailable exception |
203 | * here which is at 0xf20, thus in the middle of the | 219 | * here which is at 0xf20, thus in the middle of the |
@@ -206,39 +222,42 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) | |||
206 | */ | 222 | */ |
207 | performance_monitor_pSeries_1: | 223 | performance_monitor_pSeries_1: |
208 | . = 0xf00 | 224 | . = 0xf00 |
209 | DO_KVM 0xf00 | ||
210 | b performance_monitor_pSeries | 225 | b performance_monitor_pSeries |
211 | 226 | ||
212 | altivec_unavailable_pSeries_1: | 227 | altivec_unavailable_pSeries_1: |
213 | . = 0xf20 | 228 | . = 0xf20 |
214 | DO_KVM 0xf20 | ||
215 | b altivec_unavailable_pSeries | 229 | b altivec_unavailable_pSeries |
216 | 230 | ||
217 | vsx_unavailable_pSeries_1: | 231 | vsx_unavailable_pSeries_1: |
218 | . = 0xf40 | 232 | . = 0xf40 |
219 | DO_KVM 0xf40 | ||
220 | b vsx_unavailable_pSeries | 233 | b vsx_unavailable_pSeries |
221 | 234 | ||
222 | #ifdef CONFIG_CBE_RAS | 235 | #ifdef CONFIG_CBE_RAS |
223 | HSTD_EXCEPTION_PSERIES(0x1202, cbe_system_error) | 236 | STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error) |
224 | #endif /* CONFIG_CBE_RAS */ | 237 | #endif /* CONFIG_CBE_RAS */ |
225 | STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint) | 238 | STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint) |
226 | #ifdef CONFIG_CBE_RAS | 239 | #ifdef CONFIG_CBE_RAS |
227 | HSTD_EXCEPTION_PSERIES(0x1602, cbe_maintenance) | 240 | STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance) |
228 | #endif /* CONFIG_CBE_RAS */ | 241 | #endif /* CONFIG_CBE_RAS */ |
229 | STD_EXCEPTION_PSERIES(0x1700, altivec_assist) | 242 | STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist) |
230 | #ifdef CONFIG_CBE_RAS | 243 | #ifdef CONFIG_CBE_RAS |
231 | HSTD_EXCEPTION_PSERIES(0x1802, cbe_thermal) | 244 | STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal) |
232 | #endif /* CONFIG_CBE_RAS */ | 245 | #endif /* CONFIG_CBE_RAS */ |
233 | 246 | ||
234 | . = 0x3000 | 247 | . = 0x3000 |
235 | 248 | ||
236 | /*** pSeries interrupt support ***/ | 249 | /*** Out of line interrupts support ***/ |
250 | |||
251 | /* moved from 0xe00 */ | ||
252 | STD_EXCEPTION_HV(., 0xe00, h_data_storage) | ||
253 | STD_EXCEPTION_HV(., 0xe20, h_instr_storage) | ||
254 | STD_EXCEPTION_HV(., 0xe40, emulation_assist) | ||
255 | STD_EXCEPTION_HV(., 0xe60, hmi_exception) /* need to flush cache ? */ | ||
237 | 256 | ||
238 | /* moved from 0xf00 */ | 257 | /* moved from 0xf00 */ |
239 | STD_EXCEPTION_PSERIES(., performance_monitor) | 258 | STD_EXCEPTION_PSERIES(., 0xf00, performance_monitor) |
240 | STD_EXCEPTION_PSERIES(., altivec_unavailable) | 259 | STD_EXCEPTION_PSERIES(., 0xf20, altivec_unavailable) |
241 | STD_EXCEPTION_PSERIES(., vsx_unavailable) | 260 | STD_EXCEPTION_PSERIES(., 0xf40, vsx_unavailable) |
242 | 261 | ||
243 | /* | 262 | /* |
244 | * An interrupt came in while soft-disabled; clear EE in SRR1, | 263 | * An interrupt came in while soft-disabled; clear EE in SRR1, |
@@ -368,6 +387,8 @@ machine_check_common: | |||
368 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) | 387 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) |
369 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) | 388 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) |
370 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) | 389 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) |
390 | STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception) | ||
391 | STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception) | ||
371 | STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception) | 392 | STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception) |
372 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) | 393 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) |
373 | #ifdef CONFIG_ALTIVEC | 394 | #ifdef CONFIG_ALTIVEC |
@@ -445,6 +466,19 @@ data_access_common: | |||
445 | li r5,0x300 | 466 | li r5,0x300 |
446 | b .do_hash_page /* Try to handle as hpte fault */ | 467 | b .do_hash_page /* Try to handle as hpte fault */ |
447 | 468 | ||
469 | .align 7 | ||
470 | .globl h_data_storage_common | ||
471 | h_data_storage_common: | ||
472 | mfspr r10,SPRN_HDAR | ||
473 | std r10,PACA_EXGEN+EX_DAR(r13) | ||
474 | mfspr r10,SPRN_HDSISR | ||
475 | stw r10,PACA_EXGEN+EX_DSISR(r13) | ||
476 | EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN) | ||
477 | bl .save_nvgprs | ||
478 | addi r3,r1,STACK_FRAME_OVERHEAD | ||
479 | bl .unknown_exception | ||
480 | b .ret_from_except | ||
481 | |||
448 | .align 7 | 482 | .align 7 |
449 | .globl instruction_access_common | 483 | .globl instruction_access_common |
450 | instruction_access_common: | 484 | instruction_access_common: |
@@ -454,6 +488,8 @@ instruction_access_common: | |||
454 | li r5,0x400 | 488 | li r5,0x400 |
455 | b .do_hash_page /* Try to handle as hpte fault */ | 489 | b .do_hash_page /* Try to handle as hpte fault */ |
456 | 490 | ||
491 | STD_EXCEPTION_COMMON(0xe20, h_instr_storage, .unknown_exception) | ||
492 | |||
457 | /* | 493 | /* |
458 | * Here is the common SLB miss user that is used when going to virtual | 494 | * Here is the common SLB miss user that is used when going to virtual |
459 | * mode for SLB misses, that is currently not used | 495 | * mode for SLB misses, that is currently not used |