blob: 8829b1095f7fe45105e11d49b7155fed28fb1ccb [file] [log] [blame]
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +00001/*
2 * This file contains the 64-bit "server" PowerPC variant
3 * of the low level exception handling including exception
4 * vectors, exception return, part of the slb and stab
5 * handling and other fixed offset specific things.
6 *
7 * This file is meant to be #included from head_64.S due to
Lucas De Marchi25985ed2011-03-30 22:57:33 -03008 * position dependent assembly.
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +00009 *
10 * Most of this originates from head_64.S and thus has the same
11 * copyright history.
12 *
13 */
14
Benjamin Herrenschmidt7230c562012-03-06 18:27:59 +110015#include <asm/hw_irq.h>
Benjamin Herrenschmidt8aa34ab2009-07-14 20:52:52 +000016#include <asm/exception-64s.h>
Stephen Rothwell46f52212010-11-18 15:06:17 +000017#include <asm/ptrace.h>
Benjamin Herrenschmidt8aa34ab2009-07-14 20:52:52 +000018
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +000019/*
20 * We layout physical memory as follows:
21 * 0x0000 - 0x00ff : Secondary processor spin code
22 * 0x0100 - 0x2fff : pSeries Interrupt prologs
Benjamin Herrenschmidt4f8cf362012-02-28 13:44:58 +110023 * 0x3000 - 0x5fff : interrupt support common interrupt prologs
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +000024 * 0x6000 - 0x6fff : Initial (CPU0) segment table
25 * 0x7000 - 0x7fff : FWNMI data area
26 * 0x8000 - : Early init and support code
27 */
28
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +000029/*
30 * This is the start of the interrupt handlers for pSeries
31 * This code runs with relocation off.
32 * Code from here to __end_interrupts gets copied down to real
33 * address 0x100 when we are running a relocatable kernel.
34 * Therefore any relative branches in this section must only
35 * branch to labels in this section.
36 */
37 . = 0x100
38 .globl __start_interrupts
39__start_interrupts:
40
Benjamin Herrenschmidt948cf672011-01-24 18:42:41 +110041 .globl system_reset_pSeries;
42system_reset_pSeries:
43 HMT_MEDIUM;
Benjamin Herrenschmidt948cf672011-01-24 18:42:41 +110044 SET_SCRATCH0(r13)
45#ifdef CONFIG_PPC_P7_NAP
46BEGIN_FTR_SECTION
47 /* Running native on arch 2.06 or later, check if we are
48 * waking up from nap. We only handle no state loss and
49 * supervisor state loss. We do -not- handle hypervisor
50 * state loss at this time.
51 */
52 mfspr r13,SPRN_SRR1
Paul Mackerras371fefd2011-06-29 00:23:08 +000053 rlwinm. r13,r13,47-31,30,31
54 beq 9f
55
56 /* waking up from powersave (nap) state */
57 cmpwi cr1,r13,2
Benjamin Herrenschmidt948cf672011-01-24 18:42:41 +110058 /* Total loss of HV state is fatal, we could try to use the
59 * PIR to locate a PACA, then use an emergency stack etc...
60 * but for now, let's just stay stuck here
61 */
Paul Mackerras371fefd2011-06-29 00:23:08 +000062 bgt cr1,.
63 GET_PACA(r13)
64
65#ifdef CONFIG_KVM_BOOK3S_64_HV
Paul Mackerrasf0888f72012-02-03 00:54:17 +000066 li r0,KVM_HWTHREAD_IN_KERNEL
67 stb r0,HSTATE_HWTHREAD_STATE(r13)
68 /* Order setting hwthread_state vs. testing hwthread_req */
69 sync
70 lbz r0,HSTATE_HWTHREAD_REQ(r13)
71 cmpwi r0,0
72 beq 1f
Paul Mackerras371fefd2011-06-29 00:23:08 +000073 b kvm_start_guest
741:
75#endif
76
77 beq cr1,2f
78 b .power7_wakeup_noloss
792: b .power7_wakeup_loss
809:
Paul Mackerras969391c2011-06-29 00:26:11 +000081END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
Benjamin Herrenschmidt948cf672011-01-24 18:42:41 +110082#endif /* CONFIG_PPC_P7_NAP */
Paul Mackerrasb01c8b52011-06-29 00:18:26 +000083 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
84 NOTEST, 0x100)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +000085
86 . = 0x200
Paul Mackerrasb01c8b52011-06-29 00:18:26 +000087machine_check_pSeries_1:
88 /* This is moved out of line as it can be patched by FW, but
89 * some code path might still want to branch into the original
90 * vector
91 */
92 b machine_check_pSeries
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +000093
94 . = 0x300
95 .globl data_access_pSeries
96data_access_pSeries:
97 HMT_MEDIUM
Paul Mackerras673b1892011-04-05 13:59:58 +100098 SET_SCRATCH0(r13)
Paul Mackerrasb01c8b52011-06-29 00:18:26 +000099#ifndef CONFIG_POWER4_ONLY
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000100BEGIN_FTR_SECTION
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000101 b data_access_check_stab
102data_access_not_stab:
103END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB)
104#endif
105 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common, EXC_STD,
Paul Mackerras697d3892011-12-12 12:36:37 +0000106 KVMTEST, 0x300)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000107
108 . = 0x380
109 .globl data_access_slb_pSeries
110data_access_slb_pSeries:
111 HMT_MEDIUM
Paul Mackerras673b1892011-04-05 13:59:58 +1000112 SET_SCRATCH0(r13)
Paul Mackerras697d3892011-12-12 12:36:37 +0000113 EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x380)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000114 std r3,PACA_EXSLB+EX_R3(r13)
115 mfspr r3,SPRN_DAR
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000116#ifdef __DISABLED__
117 /* Keep that around for when we re-implement dynamic VSIDs */
118 cmpdi r3,0
119 bge slb_miss_user_pseries
120#endif /* __DISABLED__ */
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000121 mfspr r12,SPRN_SRR1
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000122#ifndef CONFIG_RELOCATABLE
123 b .slb_miss_realmode
124#else
125 /*
126 * We can't just use a direct branch to .slb_miss_realmode
127 * because the distance from here to there depends on where
128 * the kernel ends up being put.
129 */
130 mfctr r11
131 ld r10,PACAKBASE(r13)
132 LOAD_HANDLER(r10, .slb_miss_realmode)
133 mtctr r10
134 bctr
135#endif
136
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000137 STD_EXCEPTION_PSERIES(0x400, 0x400, instruction_access)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000138
139 . = 0x480
140 .globl instruction_access_slb_pSeries
141instruction_access_slb_pSeries:
142 HMT_MEDIUM
Paul Mackerras673b1892011-04-05 13:59:58 +1000143 SET_SCRATCH0(r13)
Paul Mackerrasde56a942011-06-29 00:21:34 +0000144 EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000145 std r3,PACA_EXSLB+EX_R3(r13)
146 mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000147#ifdef __DISABLED__
148 /* Keep that around for when we re-implement dynamic VSIDs */
149 cmpdi r3,0
150 bge slb_miss_user_pseries
151#endif /* __DISABLED__ */
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000152 mfspr r12,SPRN_SRR1
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000153#ifndef CONFIG_RELOCATABLE
154 b .slb_miss_realmode
155#else
156 mfctr r11
157 ld r10,PACAKBASE(r13)
158 LOAD_HANDLER(r10, .slb_miss_realmode)
159 mtctr r10
160 bctr
161#endif
162
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000163 /* We open code these as we can't have a ". = x" (even with
164 * x = "." within a feature section
165 */
Benjamin Herrenschmidta5d4f3a2011-04-05 14:20:31 +1000166 . = 0x500;
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000167 .globl hardware_interrupt_pSeries;
168 .globl hardware_interrupt_hv;
Benjamin Herrenschmidta5d4f3a2011-04-05 14:20:31 +1000169hardware_interrupt_pSeries:
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000170hardware_interrupt_hv:
Benjamin Herrenschmidta5d4f3a2011-04-05 14:20:31 +1000171 BEGIN_FTR_SECTION
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000172 _MASKABLE_EXCEPTION_PSERIES(0x502, hardware_interrupt,
173 EXC_HV, SOFTEN_TEST_HV)
174 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x502)
Paul Mackerrasde56a942011-06-29 00:21:34 +0000175 FTR_SECTION_ELSE
176 _MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt,
Paul Mackerras9e368f22011-06-29 00:40:08 +0000177 EXC_STD, SOFTEN_TEST_HV_201)
Paul Mackerrasde56a942011-06-29 00:21:34 +0000178 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x500)
Paul Mackerras969391c2011-06-29 00:26:11 +0000179 ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
Benjamin Herrenschmidta5d4f3a2011-04-05 14:20:31 +1000180
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000181 STD_EXCEPTION_PSERIES(0x600, 0x600, alignment)
Paul Mackerrasde56a942011-06-29 00:21:34 +0000182 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x600)
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000183
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000184 STD_EXCEPTION_PSERIES(0x700, 0x700, program_check)
Paul Mackerrasde56a942011-06-29 00:21:34 +0000185 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x700)
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000186
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000187 STD_EXCEPTION_PSERIES(0x800, 0x800, fp_unavailable)
Paul Mackerrasde56a942011-06-29 00:21:34 +0000188 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x800)
Benjamin Herrenschmidta5d4f3a2011-04-05 14:20:31 +1000189
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000190 MASKABLE_EXCEPTION_PSERIES(0x900, 0x900, decrementer)
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000191 MASKABLE_EXCEPTION_HV(0x980, 0x982, decrementer)
Benjamin Herrenschmidta5d4f3a2011-04-05 14:20:31 +1000192
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000193 STD_EXCEPTION_PSERIES(0xa00, 0xa00, trap_0a)
Paul Mackerrasde56a942011-06-29 00:21:34 +0000194 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xa00)
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000195
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000196 STD_EXCEPTION_PSERIES(0xb00, 0xb00, trap_0b)
Paul Mackerrasde56a942011-06-29 00:21:34 +0000197 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xb00)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000198
199 . = 0xc00
200 .globl system_call_pSeries
201system_call_pSeries:
202 HMT_MEDIUM
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000203#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
204 SET_SCRATCH0(r13)
205 GET_PACA(r13)
206 std r9,PACA_EXGEN+EX_R9(r13)
207 std r10,PACA_EXGEN+EX_R10(r13)
208 mfcr r9
209 KVMTEST(0xc00)
210 GET_SCRATCH0(r13)
211#endif
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000212BEGIN_FTR_SECTION
213 cmpdi r0,0x1ebe
214 beq- 1f
215END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
216 mr r9,r13
Benjamin Herrenschmidt2dd60d72011-01-20 17:50:21 +1100217 GET_PACA(r13)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000218 mfspr r11,SPRN_SRR0
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000219 mfspr r12,SPRN_SRR1
Anton Blanchardf5f03072011-05-08 21:36:44 +0000220 ld r10,PACAKBASE(r13)
221 LOAD_HANDLER(r10, system_call_entry)
222 mtspr SPRN_SRR0,r10
223 ld r10,PACAKMSR(r13)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000224 mtspr SPRN_SRR1,r10
225 rfid
226 b . /* prevent speculative execution */
227
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000228 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00)
229
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000230/* Fast LE/BE switch system call */
2311: mfspr r12,SPRN_SRR1
232 xori r12,r12,MSR_LE
233 mtspr SPRN_SRR1,r12
234 rfid /* return to userspace */
235 b .
236
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000237 STD_EXCEPTION_PSERIES(0xd00, 0xd00, single_step)
Paul Mackerrasde56a942011-06-29 00:21:34 +0000238 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xd00)
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000239
240 /* At 0xe??? we have a bunch of hypervisor exceptions, we branch
241 * out of line to handle them
242 */
243 . = 0xe00
244 b h_data_storage_hv
245 . = 0xe20
246 b h_instr_storage_hv
247 . = 0xe40
248 b emulation_assist_hv
249 . = 0xe50
250 b hmi_exception_hv
251 . = 0xe60
252 b hmi_exception_hv
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000253
254 /* We need to deal with the Altivec unavailable exception
255 * here which is at 0xf20, thus in the middle of the
256 * prolog code of the PerformanceMonitor one. A little
257 * trickery is thus necessary
258 */
Anton Blanchardc86e2ea2009-10-18 01:24:06 +0000259performance_monitor_pSeries_1:
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000260 . = 0xf00
261 b performance_monitor_pSeries
262
Anton Blanchardc86e2ea2009-10-18 01:24:06 +0000263altivec_unavailable_pSeries_1:
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000264 . = 0xf20
265 b altivec_unavailable_pSeries
266
Anton Blanchardc86e2ea2009-10-18 01:24:06 +0000267vsx_unavailable_pSeries_1:
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000268 . = 0xf40
269 b vsx_unavailable_pSeries
270
271#ifdef CONFIG_CBE_RAS
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000272 STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error)
Alexander Graf5ccf55d2011-09-13 04:15:31 +0000273 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000274#endif /* CONFIG_CBE_RAS */
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000275
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000276 STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint)
Paul Mackerrasde56a942011-06-29 00:21:34 +0000277 KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_STD, 0x1300)
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000278
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000279#ifdef CONFIG_CBE_RAS
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000280 STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance)
Alexander Graf5ccf55d2011-09-13 04:15:31 +0000281 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1602)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000282#endif /* CONFIG_CBE_RAS */
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000283
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000284 STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist)
Paul Mackerrasde56a942011-06-29 00:21:34 +0000285 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x1700)
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000286
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000287#ifdef CONFIG_CBE_RAS
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000288 STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal)
Alexander Graf5ccf55d2011-09-13 04:15:31 +0000289 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1802)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000290#endif /* CONFIG_CBE_RAS */
291
292 . = 0x3000
293
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000294/*** Out of line interrupts support ***/
295
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000296 /* moved from 0x200 */
297machine_check_pSeries:
298 .globl machine_check_fwnmi
299machine_check_fwnmi:
300 HMT_MEDIUM
301 SET_SCRATCH0(r13) /* save r13 */
302 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common,
303 EXC_STD, KVMTEST, 0x200)
304 KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200)
305
306#ifndef CONFIG_POWER4_ONLY
307 /* moved from 0x300 */
308data_access_check_stab:
309 GET_PACA(r13)
310 std r9,PACA_EXSLB+EX_R9(r13)
311 std r10,PACA_EXSLB+EX_R10(r13)
312 mfspr r10,SPRN_DAR
313 mfspr r9,SPRN_DSISR
314 srdi r10,r10,60
315 rlwimi r10,r9,16,0x20
Paul Mackerrasde56a942011-06-29 00:21:34 +0000316#ifdef CONFIG_KVM_BOOK3S_PR
Paul Mackerras3c42bf82011-06-29 00:20:58 +0000317 lbz r9,HSTATE_IN_GUEST(r13)
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000318 rlwimi r10,r9,8,0x300
319#endif
320 mfcr r9
321 cmpwi r10,0x2c
322 beq do_stab_bolted_pSeries
323 mtcrf 0x80,r9
324 ld r9,PACA_EXSLB+EX_R9(r13)
325 ld r10,PACA_EXSLB+EX_R10(r13)
326 b data_access_not_stab
327do_stab_bolted_pSeries:
328 std r11,PACA_EXSLB+EX_R11(r13)
329 std r12,PACA_EXSLB+EX_R12(r13)
330 GET_SCRATCH0(r10)
331 std r10,PACA_EXSLB+EX_R13(r13)
332 EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD)
333#endif /* CONFIG_POWER4_ONLY */
334
Paul Mackerras697d3892011-12-12 12:36:37 +0000335 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300)
336 KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380)
Paul Mackerrasde56a942011-06-29 00:21:34 +0000337 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x400)
338 KVM_HANDLER_PR(PACA_EXSLB, EXC_STD, 0x480)
339 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x900)
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000340 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x982)
341
342 .align 7
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000343 /* moved from 0xe00 */
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000344 STD_EXCEPTION_HV(., 0xe02, h_data_storage)
345 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0xe02)
346 STD_EXCEPTION_HV(., 0xe22, h_instr_storage)
347 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe22)
348 STD_EXCEPTION_HV(., 0xe42, emulation_assist)
349 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe42)
350 STD_EXCEPTION_HV(., 0xe62, hmi_exception) /* need to flush cache ? */
351 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe62)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000352
353 /* moved from 0xf00 */
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000354 STD_EXCEPTION_PSERIES(., 0xf00, performance_monitor)
Paul Mackerrasde56a942011-06-29 00:21:34 +0000355 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf00)
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000356 STD_EXCEPTION_PSERIES(., 0xf20, altivec_unavailable)
Paul Mackerrasde56a942011-06-29 00:21:34 +0000357 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf20)
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000358 STD_EXCEPTION_PSERIES(., 0xf40, vsx_unavailable)
Paul Mackerrasde56a942011-06-29 00:21:34 +0000359 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf40)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000360
361/*
Benjamin Herrenschmidt7230c562012-03-06 18:27:59 +1100362 * An interrupt came in while soft-disabled. We set paca->irq_happened,
363 * then, if it was a decrementer interrupt, we bump the dec to max and
364 * and return, else we hard disable and return. This is called with
365 * r10 containing the value to OR to the paca field.
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000366 */
Benjamin Herrenschmidt7230c562012-03-06 18:27:59 +1100367#define MASKED_INTERRUPT(_H) \
368masked_##_H##interrupt: \
369 std r11,PACA_EXGEN+EX_R11(r13); \
370 lbz r11,PACAIRQHAPPENED(r13); \
371 or r11,r11,r10; \
372 stb r11,PACAIRQHAPPENED(r13); \
373 andi. r10,r10,PACA_IRQ_DEC; \
374 beq 1f; \
375 lis r10,0x7fff; \
376 ori r10,r10,0xffff; \
377 mtspr SPRN_DEC,r10; \
378 b 2f; \
3791: mfspr r10,SPRN_##_H##SRR1; \
380 rldicl r10,r10,48,1; /* clear MSR_EE */ \
381 rotldi r10,r10,16; \
382 mtspr SPRN_##_H##SRR1,r10; \
3832: mtcrf 0x80,r9; \
384 ld r9,PACA_EXGEN+EX_R9(r13); \
385 ld r10,PACA_EXGEN+EX_R10(r13); \
386 ld r11,PACA_EXGEN+EX_R11(r13); \
387 GET_SCRATCH0(r13); \
388 ##_H##rfid; \
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000389 b .
Benjamin Herrenschmidt7230c562012-03-06 18:27:59 +1100390
391 MASKED_INTERRUPT()
392 MASKED_INTERRUPT(H)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000393
Benjamin Herrenschmidt7230c562012-03-06 18:27:59 +1100394/*
395 * Called from arch_local_irq_enable when an interrupt needs
396 * to be resent. r3 contains 0x500 or 0x900 to indicate which
397 * kind of interrupt. MSR:EE is already off. We generate a
398 * stackframe like if a real interrupt had happened.
399 *
400 * Note: While MSR:EE is off, we need to make sure that _MSR
401 * in the generated frame has EE set to 1 or the exception
402 * handler will not properly re-enable them.
403 */
404_GLOBAL(__replay_interrupt)
405 /* We are going to jump to the exception common code which
406 * will retrieve various register values from the PACA which
407 * we don't give a damn about, so we don't bother storing them.
408 */
409 mfmsr r12
410 mflr r11
411 mfcr r9
412 ori r12,r12,MSR_EE
413 andi. r3,r3,0x0800
414 bne decrementer_common
415 b hardware_interrupt_common
Benjamin Herrenschmidta5d4f3a2011-04-05 14:20:31 +1000416
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000417#ifdef CONFIG_PPC_PSERIES
418/*
419 * Vectors for the FWNMI option. Share common code.
420 */
421 .globl system_reset_fwnmi
422 .align 7
423system_reset_fwnmi:
424 HMT_MEDIUM
Paul Mackerras673b1892011-04-05 13:59:58 +1000425 SET_SCRATCH0(r13) /* save r13 */
Paul Mackerrasb01c8b52011-06-29 00:18:26 +0000426 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
427 NOTEST, 0x100)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000428
429#endif /* CONFIG_PPC_PSERIES */
430
431#ifdef __DISABLED__
432/*
433 * This is used for when the SLB miss handler has to go virtual,
434 * which doesn't happen for now anymore but will once we re-implement
435 * dynamic VSIDs for shared page tables
436 */
437slb_miss_user_pseries:
438 std r10,PACA_EXGEN+EX_R10(r13)
439 std r11,PACA_EXGEN+EX_R11(r13)
440 std r12,PACA_EXGEN+EX_R12(r13)
Paul Mackerras673b1892011-04-05 13:59:58 +1000441 GET_SCRATCH0(r10)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000442 ld r11,PACA_EXSLB+EX_R9(r13)
443 ld r12,PACA_EXSLB+EX_R3(r13)
444 std r10,PACA_EXGEN+EX_R13(r13)
445 std r11,PACA_EXGEN+EX_R9(r13)
446 std r12,PACA_EXGEN+EX_R3(r13)
447 clrrdi r12,r13,32
448 mfmsr r10
449 mfspr r11,SRR0 /* save SRR0 */
450 ori r12,r12,slb_miss_user_common@l /* virt addr of handler */
451 ori r10,r10,MSR_IR|MSR_DR|MSR_RI
452 mtspr SRR0,r12
453 mfspr r12,SRR1 /* and SRR1 */
454 mtspr SRR1,r10
455 rfid
456 b . /* prevent spec. execution */
457#endif /* __DISABLED__ */
458
459 .align 7
460 .globl __end_interrupts
461__end_interrupts:
462
463/*
464 * Code from here down to __end_handlers is invoked from the
465 * exception prologs above. Because the prologs assemble the
466 * addresses of these handlers using the LOAD_HANDLER macro,
467 * which uses an addi instruction, these handlers must be in
468 * the first 32k of the kernel image.
469 */
470
471/*** Common interrupt handlers ***/
472
473 STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
474
475 /*
476 * Machine check is different because we use a different
477 * save area: PACA_EXMC instead of PACA_EXGEN.
478 */
479 .align 7
480 .globl machine_check_common
481machine_check_common:
482 EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
483 FINISH_NAP
484 DISABLE_INTS
485 bl .save_nvgprs
486 addi r3,r1,STACK_FRAME_OVERHEAD
487 bl .machine_check_exception
488 b .ret_from_except
489
Benjamin Herrenschmidt7450f6f2012-03-01 10:52:01 +1100490 STD_EXCEPTION_COMMON_ASYNC(0x500, hardware_interrupt, do_IRQ)
491 STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, .timer_interrupt)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000492 STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
493 STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
494 STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
495 STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000496 STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception)
497 STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
Benjamin Herrenschmidt7450f6f2012-03-01 10:52:01 +1100498 STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, .performance_monitor_exception)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000499 STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
500#ifdef CONFIG_ALTIVEC
501 STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
502#else
503 STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception)
504#endif
505#ifdef CONFIG_CBE_RAS
506 STD_EXCEPTION_COMMON(0x1200, cbe_system_error, .cbe_system_error_exception)
507 STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, .cbe_maintenance_exception)
508 STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception)
509#endif /* CONFIG_CBE_RAS */
510
511 .align 7
512system_call_entry:
513 b system_call_common
514
Benjamin Herrenschmidtfe1952f2012-03-01 12:45:27 +1100515ppc64_runlatch_on_trampoline:
516 b .__ppc64_runlatch_on
517
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000518/*
519 * Here we have detected that the kernel stack pointer is bad.
520 * R9 contains the saved CR, r13 points to the paca,
521 * r10 contains the (bad) kernel stack pointer,
522 * r11 and r12 contain the saved SRR0 and SRR1.
523 * We switch to using an emergency stack, save the registers there,
524 * and call kernel_bad_stack(), which panics.
525 */
526bad_stack:
527 ld r1,PACAEMERGSP(r13)
528 subi r1,r1,64+INT_FRAME_SIZE
529 std r9,_CCR(r1)
530 std r10,GPR1(r1)
531 std r11,_NIP(r1)
532 std r12,_MSR(r1)
533 mfspr r11,SPRN_DAR
534 mfspr r12,SPRN_DSISR
535 std r11,_DAR(r1)
536 std r12,_DSISR(r1)
537 mflr r10
538 mfctr r11
539 mfxer r12
540 std r10,_LINK(r1)
541 std r11,_CTR(r1)
542 std r12,_XER(r1)
543 SAVE_GPR(0,r1)
544 SAVE_GPR(2,r1)
Paul Mackerras1977b502011-05-01 19:46:44 +0000545 ld r10,EX_R3(r3)
546 std r10,GPR3(r1)
547 SAVE_GPR(4,r1)
548 SAVE_4GPRS(5,r1)
549 ld r9,EX_R9(r3)
550 ld r10,EX_R10(r3)
551 SAVE_2GPRS(9,r1)
552 ld r9,EX_R11(r3)
553 ld r10,EX_R12(r3)
554 ld r11,EX_R13(r3)
555 std r9,GPR11(r1)
556 std r10,GPR12(r1)
557 std r11,GPR13(r1)
Paul Mackerras48404f22011-05-01 19:48:20 +0000558BEGIN_FTR_SECTION
559 ld r10,EX_CFAR(r3)
560 std r10,ORIG_GPR3(r1)
561END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
Paul Mackerras1977b502011-05-01 19:46:44 +0000562 SAVE_8GPRS(14,r1)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000563 SAVE_10GPRS(22,r1)
564 lhz r12,PACA_TRAP_SAVE(r13)
565 std r12,_TRAP(r1)
566 addi r11,r1,INT_FRAME_SIZE
567 std r11,0(r1)
568 li r12,0
569 std r12,0(r11)
570 ld r2,PACATOC(r13)
Paul Mackerras1977b502011-05-01 19:46:44 +0000571 ld r11,exception_marker@toc(r2)
572 std r12,RESULT(r1)
573 std r11,STACK_FRAME_OVERHEAD-16(r1)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +00005741: addi r3,r1,STACK_FRAME_OVERHEAD
575 bl .kernel_bad_stack
576 b 1b
577
578/*
579 * Here r13 points to the paca, r9 contains the saved CR,
580 * SRR0 and SRR1 are saved in r11 and r12,
581 * r9 - r13 are saved in paca->exgen.
582 */
583 .align 7
584 .globl data_access_common
585data_access_common:
586 mfspr r10,SPRN_DAR
587 std r10,PACA_EXGEN+EX_DAR(r13)
588 mfspr r10,SPRN_DSISR
589 stw r10,PACA_EXGEN+EX_DSISR(r13)
590 EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
Benjamin Herrenschmidta5464982012-03-07 16:48:45 +1100591 DISABLE_INTS
592 ld r12,_MSR(r1)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000593 ld r3,PACA_EXGEN+EX_DAR(r13)
594 lwz r4,PACA_EXGEN+EX_DSISR(r13)
595 li r5,0x300
596 b .do_hash_page /* Try to handle as hpte fault */
597
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000598 .align 7
599 .globl h_data_storage_common
600h_data_storage_common:
601 mfspr r10,SPRN_HDAR
602 std r10,PACA_EXGEN+EX_DAR(r13)
603 mfspr r10,SPRN_HDSISR
604 stw r10,PACA_EXGEN+EX_DSISR(r13)
605 EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN)
606 bl .save_nvgprs
Benjamin Herrenschmidta5464982012-03-07 16:48:45 +1100607 DISABLE_INTS
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000608 addi r3,r1,STACK_FRAME_OVERHEAD
609 bl .unknown_exception
610 b .ret_from_except
611
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000612 .align 7
613 .globl instruction_access_common
614instruction_access_common:
615 EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
Benjamin Herrenschmidta5464982012-03-07 16:48:45 +1100616 DISABLE_INTS
617 ld r12,_MSR(r1)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000618 ld r3,_NIP(r1)
619 andis. r4,r12,0x5820
620 li r5,0x400
621 b .do_hash_page /* Try to handle as hpte fault */
622
Benjamin Herrenschmidtb3e6b5d2011-04-05 14:27:11 +1000623 STD_EXCEPTION_COMMON(0xe20, h_instr_storage, .unknown_exception)
624
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000625/*
626 * Here is the common SLB miss user that is used when going to virtual
627 * mode for SLB misses, that is currently not used
628 */
629#ifdef __DISABLED__
630 .align 7
631 .globl slb_miss_user_common
632slb_miss_user_common:
633 mflr r10
634 std r3,PACA_EXGEN+EX_DAR(r13)
635 stw r9,PACA_EXGEN+EX_CCR(r13)
636 std r10,PACA_EXGEN+EX_LR(r13)
637 std r11,PACA_EXGEN+EX_SRR0(r13)
638 bl .slb_allocate_user
639
640 ld r10,PACA_EXGEN+EX_LR(r13)
641 ld r3,PACA_EXGEN+EX_R3(r13)
642 lwz r9,PACA_EXGEN+EX_CCR(r13)
643 ld r11,PACA_EXGEN+EX_SRR0(r13)
644 mtlr r10
645 beq- slb_miss_fault
646
647 andi. r10,r12,MSR_RI /* check for unrecoverable exception */
648 beq- unrecov_user_slb
649 mfmsr r10
650
651.machine push
652.machine "power4"
653 mtcrf 0x80,r9
654.machine pop
655
656 clrrdi r10,r10,2 /* clear RI before setting SRR0/1 */
657 mtmsrd r10,1
658
659 mtspr SRR0,r11
660 mtspr SRR1,r12
661
662 ld r9,PACA_EXGEN+EX_R9(r13)
663 ld r10,PACA_EXGEN+EX_R10(r13)
664 ld r11,PACA_EXGEN+EX_R11(r13)
665 ld r12,PACA_EXGEN+EX_R12(r13)
666 ld r13,PACA_EXGEN+EX_R13(r13)
667 rfid
668 b .
669
670slb_miss_fault:
671 EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
672 ld r4,PACA_EXGEN+EX_DAR(r13)
673 li r5,0
674 std r4,_DAR(r1)
675 std r5,_DSISR(r1)
676 b handle_page_fault
677
678unrecov_user_slb:
679 EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
680 DISABLE_INTS
681 bl .save_nvgprs
6821: addi r3,r1,STACK_FRAME_OVERHEAD
683 bl .unrecoverable_exception
684 b 1b
685
686#endif /* __DISABLED__ */
687
688
689/*
690 * r13 points to the PACA, r9 contains the saved CR,
691 * r12 contain the saved SRR1, SRR0 is still ready for return
692 * r3 has the faulting address
693 * r9 - r13 are saved in paca->exslb.
694 * r3 is saved in paca->slb_r3
695 * We assume we aren't going to take any exceptions during this procedure.
696 */
697_GLOBAL(slb_miss_realmode)
698 mflr r10
699#ifdef CONFIG_RELOCATABLE
700 mtctr r11
701#endif
702
703 stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
704 std r10,PACA_EXSLB+EX_LR(r13) /* save LR */
705
706 bl .slb_allocate_realmode
707
708 /* All done -- return from exception. */
709
710 ld r10,PACA_EXSLB+EX_LR(r13)
711 ld r3,PACA_EXSLB+EX_R3(r13)
712 lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000713
714 mtlr r10
715
716 andi. r10,r12,MSR_RI /* check for unrecoverable exception */
717 beq- 2f
718
719.machine push
720.machine "power4"
721 mtcrf 0x80,r9
722 mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
723.machine pop
724
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000725 ld r9,PACA_EXSLB+EX_R9(r13)
726 ld r10,PACA_EXSLB+EX_R10(r13)
727 ld r11,PACA_EXSLB+EX_R11(r13)
728 ld r12,PACA_EXSLB+EX_R12(r13)
729 ld r13,PACA_EXSLB+EX_R13(r13)
730 rfid
731 b . /* prevent speculative execution */
732
Benjamin Herrenschmidt4f8cf362012-02-28 13:44:58 +11007332: mfspr r11,SPRN_SRR0
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000734 ld r10,PACAKBASE(r13)
735 LOAD_HANDLER(r10,unrecov_slb)
736 mtspr SPRN_SRR0,r10
737 ld r10,PACAKMSR(r13)
738 mtspr SPRN_SRR1,r10
739 rfid
740 b .
741
742unrecov_slb:
743 EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
744 DISABLE_INTS
745 bl .save_nvgprs
7461: addi r3,r1,STACK_FRAME_OVERHEAD
747 bl .unrecoverable_exception
748 b 1b
749
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000750
751#ifdef CONFIG_PPC_970_NAP
752power4_fixup_nap:
753 andc r9,r9,r10
754 std r9,TI_LOCAL_FLAGS(r11)
755 ld r10,_LINK(r1) /* make idle task do the */
756 std r10,_NIP(r1) /* equivalent of a blr */
757 blr
758#endif
759
760 .align 7
761 .globl alignment_common
762alignment_common:
763 mfspr r10,SPRN_DAR
764 std r10,PACA_EXGEN+EX_DAR(r13)
765 mfspr r10,SPRN_DSISR
766 stw r10,PACA_EXGEN+EX_DSISR(r13)
767 EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
768 ld r3,PACA_EXGEN+EX_DAR(r13)
769 lwz r4,PACA_EXGEN+EX_DSISR(r13)
770 std r3,_DAR(r1)
771 std r4,_DSISR(r1)
772 bl .save_nvgprs
773 addi r3,r1,STACK_FRAME_OVERHEAD
774 ENABLE_INTS
775 bl .alignment_exception
776 b .ret_from_except
777
778 .align 7
779 .globl program_check_common
780program_check_common:
781 EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
782 bl .save_nvgprs
Benjamin Herrenschmidt54321242012-02-13 20:42:18 +0000783 DISABLE_INTS
Michael Ellerman922b9f82012-02-20 21:32:30 +0000784 addi r3,r1,STACK_FRAME_OVERHEAD
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000785 bl .program_check_exception
786 b .ret_from_except
787
788 .align 7
789 .globl fp_unavailable_common
790fp_unavailable_common:
791 EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
792 bne 1f /* if from user, just load it up */
793 bl .save_nvgprs
Benjamin Herrenschmidt9f2f79e2012-03-01 15:47:44 +1100794 DISABLE_INTS
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000795 addi r3,r1,STACK_FRAME_OVERHEAD
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000796 bl .kernel_fp_unavailable_exception
797 BUG_OPCODE
7981: bl .load_up_fpu
799 b fast_exception_return
800
801 .align 7
802 .globl altivec_unavailable_common
803altivec_unavailable_common:
804 EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
805#ifdef CONFIG_ALTIVEC
806BEGIN_FTR_SECTION
807 beq 1f
808 bl .load_up_altivec
809 b fast_exception_return
8101:
811END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
812#endif
813 bl .save_nvgprs
Benjamin Herrenschmidt9f2f79e2012-03-01 15:47:44 +1100814 DISABLE_INTS
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000815 addi r3,r1,STACK_FRAME_OVERHEAD
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000816 bl .altivec_unavailable_exception
817 b .ret_from_except
818
819 .align 7
820 .globl vsx_unavailable_common
821vsx_unavailable_common:
822 EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN)
823#ifdef CONFIG_VSX
824BEGIN_FTR_SECTION
Benjamin Herrenschmidt7230c562012-03-06 18:27:59 +1100825 beq 1f
826 b .load_up_vsx
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +00008271:
828END_FTR_SECTION_IFSET(CPU_FTR_VSX)
829#endif
830 bl .save_nvgprs
Benjamin Herrenschmidt9f2f79e2012-03-01 15:47:44 +1100831 DISABLE_INTS
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000832 addi r3,r1,STACK_FRAME_OVERHEAD
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000833 bl .vsx_unavailable_exception
834 b .ret_from_except
835
836 .align 7
837 .globl __end_handlers
838__end_handlers:
839
840/*
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000841 * Hash table stuff
842 */
843 .align 7
844_STATIC(do_hash_page)
845 std r3,_DAR(r1)
846 std r4,_DSISR(r1)
847
K.Prasad9c7cc232010-03-29 23:59:25 +0000848 andis. r0,r4,0xa410 /* weird error? */
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000849 bne- handle_page_fault /* if not, try to insert a HPTE */
K.Prasad9c7cc232010-03-29 23:59:25 +0000850 andis. r0,r4,DSISR_DABRMATCH@h
851 bne- handle_dabr_fault
852
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000853BEGIN_FTR_SECTION
854 andis. r0,r4,0x0020 /* Is it a segment table fault? */
855 bne- do_ste_alloc /* If so handle it */
Matt Evans44ae3ab2011-04-06 19:48:50 +0000856END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000857
Paul Mackerras9c1e1052009-08-17 15:17:54 +1000858 clrrdi r11,r1,THREAD_SHIFT
859 lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */
860 andis. r0,r0,NMI_MASK@h /* (i.e. an irq when soft-disabled) */
861 bne 77f /* then don't call hash_page now */
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000862 /*
863 * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
864 * accessing a userspace segment (even from the kernel). We assume
865 * kernel addresses always have the high bit set.
866 */
867 rlwinm r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */
868 rotldi r0,r3,15 /* Move high bit into MSR_PR posn */
869 orc r0,r12,r0 /* MSR_PR | ~high_bit */
870 rlwimi r4,r0,32-13,30,30 /* becomes _PAGE_USER access bit */
871 ori r4,r4,1 /* add _PAGE_PRESENT */
872 rlwimi r4,r5,22+2,31-2,31-2 /* Set _PAGE_EXEC if trap is 0x400 */
873
874 /*
875 * r3 contains the faulting address
876 * r4 contains the required access permissions
877 * r5 contains the trap number
878 *
Benjamin Herrenschmidt7230c562012-03-06 18:27:59 +1100879 * at return r3 = 0 for success, 1 for page fault, negative for error
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000880 */
881 bl .hash_page /* build HPTE if possible */
882 cmpdi r3,0 /* see if hash_page succeeded */
883
Benjamin Herrenschmidt7230c562012-03-06 18:27:59 +1100884 /* Success */
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000885 beq fast_exc_return_irq /* Return from exception on success */
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000886
Benjamin Herrenschmidt7230c562012-03-06 18:27:59 +1100887 /* Error */
888 blt- 13f
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000889
Benjamin Herrenschmidta5464982012-03-07 16:48:45 +1100890/* Here we have a page fault that hash_page can't handle. */
891handle_page_fault:
89211: ld r4,_DAR(r1)
893 ld r5,_DSISR(r1)
894 addi r3,r1,STACK_FRAME_OVERHEAD
895 bl .do_page_fault
896 cmpdi r3,0
897 beq+ 12f
898 bl .save_nvgprs
899 mr r5,r3
900 addi r3,r1,STACK_FRAME_OVERHEAD
901 lwz r4,_DAR(r1)
902 bl .bad_page_fault
903 b .ret_from_except
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000904
K.Prasad9c7cc232010-03-29 23:59:25 +0000905/* We have a data breakpoint exception - handle it */
906handle_dabr_fault:
K.Prasad5aae8a52010-06-15 11:35:19 +0530907 bl .save_nvgprs
K.Prasad9c7cc232010-03-29 23:59:25 +0000908 ld r4,_DAR(r1)
909 ld r5,_DSISR(r1)
910 addi r3,r1,STACK_FRAME_OVERHEAD
911 bl .do_dabr
Benjamin Herrenschmidta5464982012-03-07 16:48:45 +110091212: b .ret_from_except_lite
K.Prasad9c7cc232010-03-29 23:59:25 +0000913
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000914
915/* We have a page fault that hash_page could handle but HV refused
916 * the PTE insertion
917 */
Benjamin Herrenschmidta5464982012-03-07 16:48:45 +110091813: bl .save_nvgprs
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000919 mr r5,r3
920 addi r3,r1,STACK_FRAME_OVERHEAD
921 ld r4,_DAR(r1)
922 bl .low_hash_fault
923 b .ret_from_except
924
Paul Mackerras9c1e1052009-08-17 15:17:54 +1000925/*
926 * We come here as a result of a DSI at a point where we don't want
927 * to call hash_page, such as when we are accessing memory (possibly
928 * user memory) inside a PMU interrupt that occurred while interrupts
929 * were soft-disabled. We want to invoke the exception handler for
930 * the access, or panic if there isn't a handler.
931 */
93277: bl .save_nvgprs
933 mr r4,r3
934 addi r3,r1,STACK_FRAME_OVERHEAD
935 li r5,SIGSEGV
936 bl .bad_page_fault
937 b .ret_from_except
938
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +0000939 /* here we have a segment miss */
940do_ste_alloc:
941 bl .ste_allocate /* try to insert stab entry */
942 cmpdi r3,0
943 bne- handle_page_fault
944 b fast_exception_return
945
946/*
947 * r13 points to the PACA, r9 contains the saved CR,
948 * r11 and r12 contain the saved SRR0 and SRR1.
949 * r9 - r13 are saved in paca->exslb.
950 * We assume we aren't going to take any exceptions during this procedure.
951 * We assume (DAR >> 60) == 0xc.
952 */
953 .align 7
954_GLOBAL(do_stab_bolted)
955 stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
956 std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */
957
958 /* Hash to the primary group */
959 ld r10,PACASTABVIRT(r13)
960 mfspr r11,SPRN_DAR
961 srdi r11,r11,28
962 rldimi r10,r11,7,52 /* r10 = first ste of the group */
963
964 /* Calculate VSID */
965 /* This is a kernel address, so protovsid = ESID */
966 ASM_VSID_SCRAMBLE(r11, r9, 256M)
967 rldic r9,r11,12,16 /* r9 = vsid << 12 */
968
969 /* Search the primary group for a free entry */
9701: ld r11,0(r10) /* Test valid bit of the current ste */
971 andi. r11,r11,0x80
972 beq 2f
973 addi r10,r10,16
974 andi. r11,r10,0x70
975 bne 1b
976
977 /* Stick for only searching the primary group for now. */
978 /* At least for now, we use a very simple random castout scheme */
979 /* Use the TB as a random number ; OR in 1 to avoid entry 0 */
980 mftb r11
981 rldic r11,r11,4,57 /* r11 = (r11 << 4) & 0x70 */
982 ori r11,r11,0x10
983
984 /* r10 currently points to an ste one past the group of interest */
985 /* make it point to the randomly selected entry */
986 subi r10,r10,128
987 or r10,r10,r11 /* r10 is the entry to invalidate */
988
989 isync /* mark the entry invalid */
990 ld r11,0(r10)
991 rldicl r11,r11,56,1 /* clear the valid bit */
992 rotldi r11,r11,8
993 std r11,0(r10)
994 sync
995
996 clrrdi r11,r11,28 /* Get the esid part of the ste */
997 slbie r11
998
9992: std r9,8(r10) /* Store the vsid part of the ste */
1000 eieio
1001
1002 mfspr r11,SPRN_DAR /* Get the new esid */
1003 clrrdi r11,r11,28 /* Permits a full 32b of ESID */
1004 ori r11,r11,0x90 /* Turn on valid and kp */
1005 std r11,0(r10) /* Put new entry back into the stab */
1006
1007 sync
1008
1009 /* All done -- return from exception. */
1010 lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
1011 ld r11,PACA_EXSLB+EX_SRR0(r13) /* get saved SRR0 */
1012
1013 andi. r10,r12,MSR_RI
1014 beq- unrecov_slb
1015
1016 mtcrf 0x80,r9 /* restore CR */
1017
1018 mfmsr r10
1019 clrrdi r10,r10,2
1020 mtmsrd r10,1
1021
1022 mtspr SPRN_SRR0,r11
1023 mtspr SPRN_SRR1,r12
1024 ld r9,PACA_EXSLB+EX_R9(r13)
1025 ld r10,PACA_EXSLB+EX_R10(r13)
1026 ld r11,PACA_EXSLB+EX_R11(r13)
1027 ld r12,PACA_EXSLB+EX_R12(r13)
1028 ld r13,PACA_EXSLB+EX_R13(r13)
1029 rfid
1030 b . /* prevent speculative execution */
1031
Benjamin Herrenschmidted79ba92011-09-19 17:45:04 +00001032#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +00001033/*
1034 * Data area reserved for FWNMI option.
1035 * This address (0x7000) is fixed by the RPA.
1036 */
1037 .= 0x7000
1038 .globl fwnmi_data_area
1039fwnmi_data_area:
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +00001040
Benjamin Herrenschmidted79ba92011-09-19 17:45:04 +00001041 /* pseries and powernv need to keep the whole page from
1042 * 0x7000 to 0x8000 free for use by the firmware
1043 */
Benjamin Herrenschmidt0ebc4cd2009-06-02 21:17:38 +00001044 . = 0x8000
Benjamin Herrenschmidted79ba92011-09-19 17:45:04 +00001045#endif /* defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
Benjamin Herrenschmidt84493802011-03-06 18:09:07 +00001046
Benjamin Herrenschmidt4f8cf362012-02-28 13:44:58 +11001047/* Space for CPU0's segment table */
1048 .balign 4096
Benjamin Herrenschmidt84493802011-03-06 18:09:07 +00001049 .globl initial_stab
1050initial_stab:
1051 .space 4096
Benjamin Herrenschmidt4f8cf362012-02-28 13:44:58 +11001052
Benjamin Herrenschmidted79ba92011-09-19 17:45:04 +00001053#ifdef CONFIG_PPC_POWERNV
1054_GLOBAL(opal_mc_secondary_handler)
1055 HMT_MEDIUM
1056 SET_SCRATCH0(r13)
1057 GET_PACA(r13)
1058 clrldi r3,r3,2
1059 tovirt(r3,r3)
1060 std r3,PACA_OPAL_MC_EVT(r13)
1061 ld r13,OPAL_MC_SRR0(r3)
1062 mtspr SPRN_SRR0,r13
1063 ld r13,OPAL_MC_SRR1(r3)
1064 mtspr SPRN_SRR1,r13
1065 ld r3,OPAL_MC_GPR3(r3)
1066 GET_SCRATCH0(r13)
1067 b machine_check_pSeries
1068#endif /* CONFIG_PPC_POWERNV */