aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/exception-64s.h37
-rw-r--r--arch/powerpc/include/asm/feature-fixups.h2
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S92
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; \
156label##_pSeries: \ 156label##_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; \
165label##_pSeries: \ 165label##_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; \
201label##_pSeries: \
202 _MASKABLE_EXCEPTION_PSERIES(vec, label, EXC_STD)
203
204#define MASKABLE_EXCEPTION_HV(loc, vec, label) \
205 . = loc; \
206 .globl label##_hv; \
207label##_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;
152hardware_interrupt_pSeries: 156hardware_interrupt_pSeries:
157hardware_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)
165decrementer_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 */
207performance_monitor_pSeries_1: 223performance_monitor_pSeries_1:
208 . = 0xf00 224 . = 0xf00
209 DO_KVM 0xf00
210 b performance_monitor_pSeries 225 b performance_monitor_pSeries
211 226
212altivec_unavailable_pSeries_1: 227altivec_unavailable_pSeries_1:
213 . = 0xf20 228 . = 0xf20
214 DO_KVM 0xf20
215 b altivec_unavailable_pSeries 229 b altivec_unavailable_pSeries
216 230
217vsx_unavailable_pSeries_1: 231vsx_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
471h_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
450instruction_access_common: 484instruction_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