xref: /linux/arch/powerpc/kernel/exceptions-64s.S (revision 0869b6fd209bda402576a9a559120ddd4f61198e)
10ebc4cdaSBenjamin Herrenschmidt/*
20ebc4cdaSBenjamin Herrenschmidt * This file contains the 64-bit "server" PowerPC variant
30ebc4cdaSBenjamin Herrenschmidt * of the low level exception handling including exception
40ebc4cdaSBenjamin Herrenschmidt * vectors, exception return, part of the slb and stab
50ebc4cdaSBenjamin Herrenschmidt * handling and other fixed offset specific things.
60ebc4cdaSBenjamin Herrenschmidt *
70ebc4cdaSBenjamin Herrenschmidt * This file is meant to be #included from head_64.S due to
825985edcSLucas De Marchi * position dependent assembly.
90ebc4cdaSBenjamin Herrenschmidt *
100ebc4cdaSBenjamin Herrenschmidt * Most of this originates from head_64.S and thus has the same
110ebc4cdaSBenjamin Herrenschmidt * copyright history.
120ebc4cdaSBenjamin Herrenschmidt *
130ebc4cdaSBenjamin Herrenschmidt */
140ebc4cdaSBenjamin Herrenschmidt
157230c564SBenjamin Herrenschmidt#include <asm/hw_irq.h>
168aa34ab8SBenjamin Herrenschmidt#include <asm/exception-64s.h>
1746f52210SStephen Rothwell#include <asm/ptrace.h>
188aa34ab8SBenjamin Herrenschmidt
190ebc4cdaSBenjamin Herrenschmidt/*
200ebc4cdaSBenjamin Herrenschmidt * We layout physical memory as follows:
210ebc4cdaSBenjamin Herrenschmidt * 0x0000 - 0x00ff : Secondary processor spin code
22c1fb6816SMichael Neuling * 0x0100 - 0x17ff : pSeries Interrupt prologs
23c1fb6816SMichael Neuling * 0x1800 - 0x4000 : interrupt support common interrupt prologs
24c1fb6816SMichael Neuling * 0x4000 - 0x5fff : pSeries interrupts with IR=1,DR=1
25c1fb6816SMichael Neuling * 0x6000 - 0x6fff : more interrupt support including for IR=1,DR=1
260ebc4cdaSBenjamin Herrenschmidt * 0x7000 - 0x7fff : FWNMI data area
27c1fb6816SMichael Neuling * 0x8000 - 0x8fff : Initial (CPU0) segment table
28c1fb6816SMichael Neuling * 0x9000 -        : Early init and support code
290ebc4cdaSBenjamin Herrenschmidt */
30742415d6SMichael Neuling	/* Syscall routine is used twice, in reloc-off and reloc-on paths */
31742415d6SMichael Neuling#define SYSCALL_PSERIES_1 					\
32742415d6SMichael NeulingBEGIN_FTR_SECTION						\
33742415d6SMichael Neuling	cmpdi	r0,0x1ebe ; 					\
34742415d6SMichael Neuling	beq-	1f ;						\
35742415d6SMichael NeulingEND_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)				\
36742415d6SMichael Neuling	mr	r9,r13 ;					\
37742415d6SMichael Neuling	GET_PACA(r13) ;						\
38742415d6SMichael Neuling	mfspr	r11,SPRN_SRR0 ;					\
39742415d6SMichael Neuling0:
40742415d6SMichael Neuling
41742415d6SMichael Neuling#define SYSCALL_PSERIES_2_RFID 					\
42742415d6SMichael Neuling	mfspr	r12,SPRN_SRR1 ;					\
43742415d6SMichael Neuling	ld	r10,PACAKBASE(r13) ; 				\
44742415d6SMichael Neuling	LOAD_HANDLER(r10, system_call_entry) ; 			\
45742415d6SMichael Neuling	mtspr	SPRN_SRR0,r10 ; 				\
46742415d6SMichael Neuling	ld	r10,PACAKMSR(r13) ;				\
47742415d6SMichael Neuling	mtspr	SPRN_SRR1,r10 ; 				\
48742415d6SMichael Neuling	rfid ; 							\
49742415d6SMichael Neuling	b	. ;	/* prevent speculative execution */
50742415d6SMichael Neuling
51742415d6SMichael Neuling#define SYSCALL_PSERIES_3					\
52742415d6SMichael Neuling	/* Fast LE/BE switch system call */			\
53742415d6SMichael Neuling1:	mfspr	r12,SPRN_SRR1 ;					\
54742415d6SMichael Neuling	xori	r12,r12,MSR_LE ;				\
55742415d6SMichael Neuling	mtspr	SPRN_SRR1,r12 ;					\
56742415d6SMichael Neuling	rfid ;		/* return to userspace */		\
57742415d6SMichael Neuling	b	. ;	/* prevent speculative execution */
58742415d6SMichael Neuling
594700dfafSMichael Neuling#if defined(CONFIG_RELOCATABLE)
604700dfafSMichael Neuling	/*
614700dfafSMichael Neuling	 * We can't branch directly; in the direct case we use LR
624700dfafSMichael Neuling	 * and system_call_entry restores LR.  (We thus need to move
634700dfafSMichael Neuling	 * LR to r10 in the RFID case too.)
644700dfafSMichael Neuling	 */
654700dfafSMichael Neuling#define SYSCALL_PSERIES_2_DIRECT				\
664700dfafSMichael Neuling	mflr	r10 ;						\
674700dfafSMichael Neuling	ld	r12,PACAKBASE(r13) ; 				\
684700dfafSMichael Neuling	LOAD_HANDLER(r12, system_call_entry_direct) ;		\
696a404806SMichael Neuling	mtctr	r12 ;						\
704700dfafSMichael Neuling	mfspr	r12,SPRN_SRR1 ;					\
714700dfafSMichael Neuling	/* Re-use of r13... No spare regs to do this */	\
724700dfafSMichael Neuling	li	r13,MSR_RI ;					\
734700dfafSMichael Neuling	mtmsrd 	r13,1 ;						\
744700dfafSMichael Neuling	GET_PACA(r13) ;	/* get r13 back */			\
756a404806SMichael Neuling	bctr ;
764700dfafSMichael Neuling#else
774700dfafSMichael Neuling	/* We can branch directly */
784700dfafSMichael Neuling#define SYSCALL_PSERIES_2_DIRECT				\
794700dfafSMichael Neuling	mfspr	r12,SPRN_SRR1 ;					\
804700dfafSMichael Neuling	li	r10,MSR_RI ;					\
814700dfafSMichael Neuling	mtmsrd 	r10,1 ;			/* Set RI (EE=0) */	\
824700dfafSMichael Neuling	b	system_call_entry_direct ;
834700dfafSMichael Neuling#endif
840ebc4cdaSBenjamin Herrenschmidt
850ebc4cdaSBenjamin Herrenschmidt/*
860ebc4cdaSBenjamin Herrenschmidt * This is the start of the interrupt handlers for pSeries
870ebc4cdaSBenjamin Herrenschmidt * This code runs with relocation off.
880ebc4cdaSBenjamin Herrenschmidt * Code from here to __end_interrupts gets copied down to real
890ebc4cdaSBenjamin Herrenschmidt * address 0x100 when we are running a relocatable kernel.
900ebc4cdaSBenjamin Herrenschmidt * Therefore any relative branches in this section must only
910ebc4cdaSBenjamin Herrenschmidt * branch to labels in this section.
920ebc4cdaSBenjamin Herrenschmidt */
930ebc4cdaSBenjamin Herrenschmidt	. = 0x100
940ebc4cdaSBenjamin Herrenschmidt	.globl __start_interrupts
950ebc4cdaSBenjamin Herrenschmidt__start_interrupts:
960ebc4cdaSBenjamin Herrenschmidt
97948cf67cSBenjamin Herrenschmidt	.globl system_reset_pSeries;
98948cf67cSBenjamin Herrenschmidtsystem_reset_pSeries:
9944e9309fSHaren Myneni	HMT_MEDIUM_PPR_DISCARD
100948cf67cSBenjamin Herrenschmidt	SET_SCRATCH0(r13)
101948cf67cSBenjamin Herrenschmidt#ifdef CONFIG_PPC_P7_NAP
102948cf67cSBenjamin HerrenschmidtBEGIN_FTR_SECTION
103948cf67cSBenjamin Herrenschmidt	/* Running native on arch 2.06 or later, check if we are
104948cf67cSBenjamin Herrenschmidt	 * waking up from nap. We only handle no state loss and
105948cf67cSBenjamin Herrenschmidt	 * supervisor state loss. We do -not- handle hypervisor
106948cf67cSBenjamin Herrenschmidt	 * state loss at this time.
107948cf67cSBenjamin Herrenschmidt	 */
108948cf67cSBenjamin Herrenschmidt	mfspr	r13,SPRN_SRR1
109371fefd6SPaul Mackerras	rlwinm.	r13,r13,47-31,30,31
110371fefd6SPaul Mackerras	beq	9f
111371fefd6SPaul Mackerras
112371fefd6SPaul Mackerras	/* waking up from powersave (nap) state */
113371fefd6SPaul Mackerras	cmpwi	cr1,r13,2
114948cf67cSBenjamin Herrenschmidt	/* Total loss of HV state is fatal, we could try to use the
115948cf67cSBenjamin Herrenschmidt	 * PIR to locate a PACA, then use an emergency stack etc...
116aca79d2bSVaidyanathan Srinivasan	 * OPAL v3 based powernv platforms have new idle states
117aca79d2bSVaidyanathan Srinivasan	 * which fall in this catagory.
118948cf67cSBenjamin Herrenschmidt	 */
119aca79d2bSVaidyanathan Srinivasan	bgt	cr1,8f
120371fefd6SPaul Mackerras	GET_PACA(r13)
121371fefd6SPaul Mackerras
1223a167beaSAneesh Kumar K.V#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
123f0888f70SPaul Mackerras	li	r0,KVM_HWTHREAD_IN_KERNEL
124f0888f70SPaul Mackerras	stb	r0,HSTATE_HWTHREAD_STATE(r13)
125f0888f70SPaul Mackerras	/* Order setting hwthread_state vs. testing hwthread_req */
126f0888f70SPaul Mackerras	sync
127f0888f70SPaul Mackerras	lbz	r0,HSTATE_HWTHREAD_REQ(r13)
128f0888f70SPaul Mackerras	cmpwi	r0,0
129f0888f70SPaul Mackerras	beq	1f
130371fefd6SPaul Mackerras	b	kvm_start_guest
131371fefd6SPaul Mackerras1:
132371fefd6SPaul Mackerras#endif
133371fefd6SPaul Mackerras
134371fefd6SPaul Mackerras	beq	cr1,2f
135b1576fecSAnton Blanchard	b	power7_wakeup_noloss
136b1576fecSAnton Blanchard2:	b	power7_wakeup_loss
137aca79d2bSVaidyanathan Srinivasan
138aca79d2bSVaidyanathan Srinivasan	/* Fast Sleep wakeup on PowerNV */
139aca79d2bSVaidyanathan Srinivasan8:	GET_PACA(r13)
140b1576fecSAnton Blanchard	b 	power7_wakeup_tb_loss
141aca79d2bSVaidyanathan Srinivasan
142371fefd6SPaul Mackerras9:
143969391c5SPaul MackerrasEND_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
144948cf67cSBenjamin Herrenschmidt#endif /* CONFIG_PPC_P7_NAP */
145b01c8b54SPaul Mackerras	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
146b01c8b54SPaul Mackerras				 NOTEST, 0x100)
1470ebc4cdaSBenjamin Herrenschmidt
1480ebc4cdaSBenjamin Herrenschmidt	. = 0x200
149b01c8b54SPaul Mackerrasmachine_check_pSeries_1:
150b01c8b54SPaul Mackerras	/* This is moved out of line as it can be patched by FW, but
151b01c8b54SPaul Mackerras	 * some code path might still want to branch into the original
152b01c8b54SPaul Mackerras	 * vector
153b01c8b54SPaul Mackerras	 */
1541707dd16SPaul Mackerras	HMT_MEDIUM_PPR_DISCARD
1551707dd16SPaul Mackerras	SET_SCRATCH0(r13)		/* save r13 */
1561c51089fSMahesh Salgaonkar#ifdef CONFIG_PPC_P7_NAP
1571c51089fSMahesh SalgaonkarBEGIN_FTR_SECTION
1581c51089fSMahesh Salgaonkar	/* Running native on arch 2.06 or later, check if we are
1591c51089fSMahesh Salgaonkar	 * waking up from nap. We only handle no state loss and
1601c51089fSMahesh Salgaonkar	 * supervisor state loss. We do -not- handle hypervisor
1611c51089fSMahesh Salgaonkar	 * state loss at this time.
1621c51089fSMahesh Salgaonkar	 */
1631c51089fSMahesh Salgaonkar	mfspr	r13,SPRN_SRR1
1641c51089fSMahesh Salgaonkar	rlwinm.	r13,r13,47-31,30,31
165d410ae21SMahesh Salgaonkar	OPT_GET_SPR(r13, SPRN_CFAR, CPU_FTR_CFAR)
1661c51089fSMahesh Salgaonkar	beq	9f
1671c51089fSMahesh Salgaonkar
168d410ae21SMahesh Salgaonkar	mfspr	r13,SPRN_SRR1
169d410ae21SMahesh Salgaonkar	rlwinm.	r13,r13,47-31,30,31
1701c51089fSMahesh Salgaonkar	/* waking up from powersave (nap) state */
1711c51089fSMahesh Salgaonkar	cmpwi	cr1,r13,2
1721c51089fSMahesh Salgaonkar	/* Total loss of HV state is fatal. let's just stay stuck here */
173d410ae21SMahesh Salgaonkar	OPT_GET_SPR(r13, SPRN_CFAR, CPU_FTR_CFAR)
1741c51089fSMahesh Salgaonkar	bgt	cr1,.
1751c51089fSMahesh Salgaonkar9:
176d410ae21SMahesh Salgaonkar	OPT_SET_SPR(r13, SPRN_CFAR, CPU_FTR_CFAR)
1771c51089fSMahesh SalgaonkarEND_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
1781c51089fSMahesh Salgaonkar#endif /* CONFIG_PPC_P7_NAP */
1791707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXMC)
1801e9b4507SMahesh SalgaonkarBEGIN_FTR_SECTION
1811e9b4507SMahesh Salgaonkar	b	machine_check_pSeries_early
1821e9b4507SMahesh SalgaonkarFTR_SECTION_ELSE
1831707dd16SPaul Mackerras	b	machine_check_pSeries_0
1841e9b4507SMahesh SalgaonkarALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
1850ebc4cdaSBenjamin Herrenschmidt
1860ebc4cdaSBenjamin Herrenschmidt	. = 0x300
1870ebc4cdaSBenjamin Herrenschmidt	.globl data_access_pSeries
1880ebc4cdaSBenjamin Herrenschmidtdata_access_pSeries:
18944e9309fSHaren Myneni	HMT_MEDIUM_PPR_DISCARD
190673b189aSPaul Mackerras	SET_SCRATCH0(r13)
191b01c8b54SPaul Mackerras	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common, EXC_STD,
192697d3899SPaul Mackerras				 KVMTEST, 0x300)
1930ebc4cdaSBenjamin Herrenschmidt
1940ebc4cdaSBenjamin Herrenschmidt	. = 0x380
1950ebc4cdaSBenjamin Herrenschmidt	.globl data_access_slb_pSeries
1960ebc4cdaSBenjamin Herrenschmidtdata_access_slb_pSeries:
19744e9309fSHaren Myneni	HMT_MEDIUM_PPR_DISCARD
198673b189aSPaul Mackerras	SET_SCRATCH0(r13)
1991707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXSLB)
200697d3899SPaul Mackerras	EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x380)
2010ebc4cdaSBenjamin Herrenschmidt	std	r3,PACA_EXSLB+EX_R3(r13)
2020ebc4cdaSBenjamin Herrenschmidt	mfspr	r3,SPRN_DAR
2030ebc4cdaSBenjamin Herrenschmidt#ifdef __DISABLED__
2040ebc4cdaSBenjamin Herrenschmidt	/* Keep that around for when we re-implement dynamic VSIDs */
2050ebc4cdaSBenjamin Herrenschmidt	cmpdi	r3,0
2060ebc4cdaSBenjamin Herrenschmidt	bge	slb_miss_user_pseries
2070ebc4cdaSBenjamin Herrenschmidt#endif /* __DISABLED__ */
208b01c8b54SPaul Mackerras	mfspr	r12,SPRN_SRR1
2090ebc4cdaSBenjamin Herrenschmidt#ifndef CONFIG_RELOCATABLE
210b1576fecSAnton Blanchard	b	slb_miss_realmode
2110ebc4cdaSBenjamin Herrenschmidt#else
2120ebc4cdaSBenjamin Herrenschmidt	/*
213ad0289e4SAnton Blanchard	 * We can't just use a direct branch to slb_miss_realmode
2140ebc4cdaSBenjamin Herrenschmidt	 * because the distance from here to there depends on where
2150ebc4cdaSBenjamin Herrenschmidt	 * the kernel ends up being put.
2160ebc4cdaSBenjamin Herrenschmidt	 */
2170ebc4cdaSBenjamin Herrenschmidt	mfctr	r11
2180ebc4cdaSBenjamin Herrenschmidt	ld	r10,PACAKBASE(r13)
219ad0289e4SAnton Blanchard	LOAD_HANDLER(r10, slb_miss_realmode)
2200ebc4cdaSBenjamin Herrenschmidt	mtctr	r10
2210ebc4cdaSBenjamin Herrenschmidt	bctr
2220ebc4cdaSBenjamin Herrenschmidt#endif
2230ebc4cdaSBenjamin Herrenschmidt
224b3e6b5dfSBenjamin Herrenschmidt	STD_EXCEPTION_PSERIES(0x400, 0x400, instruction_access)
2250ebc4cdaSBenjamin Herrenschmidt
2260ebc4cdaSBenjamin Herrenschmidt	. = 0x480
2270ebc4cdaSBenjamin Herrenschmidt	.globl instruction_access_slb_pSeries
2280ebc4cdaSBenjamin Herrenschmidtinstruction_access_slb_pSeries:
22944e9309fSHaren Myneni	HMT_MEDIUM_PPR_DISCARD
230673b189aSPaul Mackerras	SET_SCRATCH0(r13)
2311707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXSLB)
232de56a948SPaul Mackerras	EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480)
2330ebc4cdaSBenjamin Herrenschmidt	std	r3,PACA_EXSLB+EX_R3(r13)
2340ebc4cdaSBenjamin Herrenschmidt	mfspr	r3,SPRN_SRR0		/* SRR0 is faulting address */
2350ebc4cdaSBenjamin Herrenschmidt#ifdef __DISABLED__
2360ebc4cdaSBenjamin Herrenschmidt	/* Keep that around for when we re-implement dynamic VSIDs */
2370ebc4cdaSBenjamin Herrenschmidt	cmpdi	r3,0
2380ebc4cdaSBenjamin Herrenschmidt	bge	slb_miss_user_pseries
2390ebc4cdaSBenjamin Herrenschmidt#endif /* __DISABLED__ */
240b01c8b54SPaul Mackerras	mfspr	r12,SPRN_SRR1
2410ebc4cdaSBenjamin Herrenschmidt#ifndef CONFIG_RELOCATABLE
242b1576fecSAnton Blanchard	b	slb_miss_realmode
2430ebc4cdaSBenjamin Herrenschmidt#else
2440ebc4cdaSBenjamin Herrenschmidt	mfctr	r11
2450ebc4cdaSBenjamin Herrenschmidt	ld	r10,PACAKBASE(r13)
246ad0289e4SAnton Blanchard	LOAD_HANDLER(r10, slb_miss_realmode)
2470ebc4cdaSBenjamin Herrenschmidt	mtctr	r10
2480ebc4cdaSBenjamin Herrenschmidt	bctr
2490ebc4cdaSBenjamin Herrenschmidt#endif
2500ebc4cdaSBenjamin Herrenschmidt
251b3e6b5dfSBenjamin Herrenschmidt	/* We open code these as we can't have a ". = x" (even with
252b3e6b5dfSBenjamin Herrenschmidt	 * x = "." within a feature section
253b3e6b5dfSBenjamin Herrenschmidt	 */
254a5d4f3adSBenjamin Herrenschmidt	. = 0x500;
255b3e6b5dfSBenjamin Herrenschmidt	.globl hardware_interrupt_pSeries;
256b3e6b5dfSBenjamin Herrenschmidt	.globl hardware_interrupt_hv;
257a5d4f3adSBenjamin Herrenschmidthardware_interrupt_pSeries:
258b3e6b5dfSBenjamin Herrenschmidthardware_interrupt_hv:
259a485c709SPaul Mackerras	HMT_MEDIUM_PPR_DISCARD
260a5d4f3adSBenjamin Herrenschmidt	BEGIN_FTR_SECTION
261b01c8b54SPaul Mackerras		_MASKABLE_EXCEPTION_PSERIES(0x502, hardware_interrupt,
262b01c8b54SPaul Mackerras					    EXC_HV, SOFTEN_TEST_HV)
263b01c8b54SPaul Mackerras		KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x502)
264de56a948SPaul Mackerras	FTR_SECTION_ELSE
265de56a948SPaul Mackerras		_MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt,
2669e368f29SPaul Mackerras					    EXC_STD, SOFTEN_TEST_HV_201)
267de56a948SPaul Mackerras		KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x500)
268969391c5SPaul Mackerras	ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
269a5d4f3adSBenjamin Herrenschmidt
270b3e6b5dfSBenjamin Herrenschmidt	STD_EXCEPTION_PSERIES(0x600, 0x600, alignment)
271de56a948SPaul Mackerras	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x600)
272b01c8b54SPaul Mackerras
273b3e6b5dfSBenjamin Herrenschmidt	STD_EXCEPTION_PSERIES(0x700, 0x700, program_check)
274de56a948SPaul Mackerras	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x700)
275b01c8b54SPaul Mackerras
276b3e6b5dfSBenjamin Herrenschmidt	STD_EXCEPTION_PSERIES(0x800, 0x800, fp_unavailable)
277de56a948SPaul Mackerras	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x800)
278a5d4f3adSBenjamin Herrenschmidt
279a485c709SPaul Mackerras	. = 0x900
280a485c709SPaul Mackerras	.globl decrementer_pSeries
281a485c709SPaul Mackerrasdecrementer_pSeries:
282a485c709SPaul Mackerras	_MASKABLE_EXCEPTION_PSERIES(0x900, decrementer, EXC_STD, SOFTEN_TEST_PR)
283a485c709SPaul Mackerras
284dabe859eSPaul Mackerras	STD_EXCEPTION_HV(0x980, 0x982, hdecrementer)
285a5d4f3adSBenjamin Herrenschmidt
2861dbdafecSIan Munsie	MASKABLE_EXCEPTION_PSERIES(0xa00, 0xa00, doorbell_super)
287de56a948SPaul Mackerras	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xa00)
288b01c8b54SPaul Mackerras
289b3e6b5dfSBenjamin Herrenschmidt	STD_EXCEPTION_PSERIES(0xb00, 0xb00, trap_0b)
290de56a948SPaul Mackerras	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xb00)
2910ebc4cdaSBenjamin Herrenschmidt
2920ebc4cdaSBenjamin Herrenschmidt	. = 0xc00
2930ebc4cdaSBenjamin Herrenschmidt	.globl	system_call_pSeries
2940ebc4cdaSBenjamin Herrenschmidtsystem_call_pSeries:
2950ebc4cdaSBenjamin Herrenschmidt	HMT_MEDIUM
296b01c8b54SPaul Mackerras#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
297b01c8b54SPaul Mackerras	SET_SCRATCH0(r13)
298b01c8b54SPaul Mackerras	GET_PACA(r13)
299b01c8b54SPaul Mackerras	std	r9,PACA_EXGEN+EX_R9(r13)
300b01c8b54SPaul Mackerras	std	r10,PACA_EXGEN+EX_R10(r13)
301b01c8b54SPaul Mackerras	mfcr	r9
302b01c8b54SPaul Mackerras	KVMTEST(0xc00)
303b01c8b54SPaul Mackerras	GET_SCRATCH0(r13)
304b01c8b54SPaul Mackerras#endif
305742415d6SMichael Neuling	SYSCALL_PSERIES_1
306742415d6SMichael Neuling	SYSCALL_PSERIES_2_RFID
307742415d6SMichael Neuling	SYSCALL_PSERIES_3
308b01c8b54SPaul Mackerras	KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00)
309b01c8b54SPaul Mackerras
310b3e6b5dfSBenjamin Herrenschmidt	STD_EXCEPTION_PSERIES(0xd00, 0xd00, single_step)
311de56a948SPaul Mackerras	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xd00)
312b3e6b5dfSBenjamin Herrenschmidt
313b3e6b5dfSBenjamin Herrenschmidt	/* At 0xe??? we have a bunch of hypervisor exceptions, we branch
314b3e6b5dfSBenjamin Herrenschmidt	 * out of line to handle them
315b3e6b5dfSBenjamin Herrenschmidt	 */
316b3e6b5dfSBenjamin Herrenschmidt	. = 0xe00
317d671ddd6SMichael Ellermanhv_data_storage_trampoline:
3181707dd16SPaul Mackerras	SET_SCRATCH0(r13)
3191707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXGEN)
320b3e6b5dfSBenjamin Herrenschmidt	b	h_data_storage_hv
3211707dd16SPaul Mackerras
322b3e6b5dfSBenjamin Herrenschmidt	. = 0xe20
323d671ddd6SMichael Ellermanhv_instr_storage_trampoline:
3241707dd16SPaul Mackerras	SET_SCRATCH0(r13)
3251707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXGEN)
326b3e6b5dfSBenjamin Herrenschmidt	b	h_instr_storage_hv
3271707dd16SPaul Mackerras
328b3e6b5dfSBenjamin Herrenschmidt	. = 0xe40
329d671ddd6SMichael Ellermanemulation_assist_trampoline:
3301707dd16SPaul Mackerras	SET_SCRATCH0(r13)
3311707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXGEN)
332b3e6b5dfSBenjamin Herrenschmidt	b	emulation_assist_hv
3331707dd16SPaul Mackerras
334b3e6b5dfSBenjamin Herrenschmidt	. = 0xe60
335d671ddd6SMichael Ellermanhv_exception_trampoline:
3361707dd16SPaul Mackerras	SET_SCRATCH0(r13)
3371707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXGEN)
338*0869b6fdSMahesh Salgaonkar	b	hmi_exception_early
3391707dd16SPaul Mackerras
340655bb3f4SIan Munsie	. = 0xe80
341d671ddd6SMichael Ellermanhv_doorbell_trampoline:
3421707dd16SPaul Mackerras	SET_SCRATCH0(r13)
3431707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXGEN)
344655bb3f4SIan Munsie	b	h_doorbell_hv
3450ebc4cdaSBenjamin Herrenschmidt
3460ebc4cdaSBenjamin Herrenschmidt	/* We need to deal with the Altivec unavailable exception
3470ebc4cdaSBenjamin Herrenschmidt	 * here which is at 0xf20, thus in the middle of the
3480ebc4cdaSBenjamin Herrenschmidt	 * prolog code of the PerformanceMonitor one. A little
3490ebc4cdaSBenjamin Herrenschmidt	 * trickery is thus necessary
3500ebc4cdaSBenjamin Herrenschmidt	 */
3510ebc4cdaSBenjamin Herrenschmidt	. = 0xf00
352fa111f1fSMichael Ellermanperformance_monitor_pseries_trampoline:
3531707dd16SPaul Mackerras	SET_SCRATCH0(r13)
3541707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXGEN)
3550ebc4cdaSBenjamin Herrenschmidt	b	performance_monitor_pSeries
3560ebc4cdaSBenjamin Herrenschmidt
3570ebc4cdaSBenjamin Herrenschmidt	. = 0xf20
358fa111f1fSMichael Ellermanaltivec_unavailable_pseries_trampoline:
3591707dd16SPaul Mackerras	SET_SCRATCH0(r13)
3601707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXGEN)
3610ebc4cdaSBenjamin Herrenschmidt	b	altivec_unavailable_pSeries
3620ebc4cdaSBenjamin Herrenschmidt
3630ebc4cdaSBenjamin Herrenschmidt	. = 0xf40
364fa111f1fSMichael Ellermanvsx_unavailable_pseries_trampoline:
3651707dd16SPaul Mackerras	SET_SCRATCH0(r13)
3661707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXGEN)
3670ebc4cdaSBenjamin Herrenschmidt	b	vsx_unavailable_pSeries
3680ebc4cdaSBenjamin Herrenschmidt
369d0c0c9a1SMichael Neuling	. = 0xf60
370fa111f1fSMichael Ellermanfacility_unavailable_trampoline:
371d0c0c9a1SMichael Neuling	SET_SCRATCH0(r13)
372d0c0c9a1SMichael Neuling	EXCEPTION_PROLOG_0(PACA_EXGEN)
373021424a1SMichael Ellerman	b	facility_unavailable_pSeries
374d0c0c9a1SMichael Neuling
375b14b6260SMichael Ellerman	. = 0xf80
376fa111f1fSMichael Ellermanhv_facility_unavailable_trampoline:
377b14b6260SMichael Ellerman	SET_SCRATCH0(r13)
378b14b6260SMichael Ellerman	EXCEPTION_PROLOG_0(PACA_EXGEN)
379b14b6260SMichael Ellerman	b	facility_unavailable_hv
380b14b6260SMichael Ellerman
3810ebc4cdaSBenjamin Herrenschmidt#ifdef CONFIG_CBE_RAS
382b3e6b5dfSBenjamin Herrenschmidt	STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error)
3835ccf55ddSAlexander Graf	KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202)
3840ebc4cdaSBenjamin Herrenschmidt#endif /* CONFIG_CBE_RAS */
385b01c8b54SPaul Mackerras
386b3e6b5dfSBenjamin Herrenschmidt	STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint)
387de56a948SPaul Mackerras	KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_STD, 0x1300)
388b01c8b54SPaul Mackerras
389b92a66a6SMichael Neuling	. = 0x1500
39051cf2b30SMichael Neuling	.global denorm_exception_hv
391b92a66a6SMichael Neulingdenorm_exception_hv:
39244e9309fSHaren Myneni	HMT_MEDIUM_PPR_DISCARD
393b92a66a6SMichael Neuling	mtspr	SPRN_SPRG_HSCRATCH0,r13
3941707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXGEN)
395630573c1SPaul Mackerras	EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0x1500)
396b92a66a6SMichael Neuling
397b92a66a6SMichael Neuling#ifdef CONFIG_PPC_DENORMALISATION
398b92a66a6SMichael Neuling	mfspr	r10,SPRN_HSRR1
399b92a66a6SMichael Neuling	mfspr	r11,SPRN_HSRR0		/* save HSRR0 */
400b92a66a6SMichael Neuling	andis.	r10,r10,(HSRR1_DENORM)@h /* denorm? */
401b92a66a6SMichael Neuling	addi	r11,r11,-4		/* HSRR0 is next instruction */
402b92a66a6SMichael Neuling	bne+	denorm_assist
403b92a66a6SMichael Neuling#endif
404b92a66a6SMichael Neuling
405630573c1SPaul Mackerras	KVMTEST(0x1500)
406b92a66a6SMichael Neuling	EXCEPTION_PROLOG_PSERIES_1(denorm_common, EXC_HV)
407b92a66a6SMichael Neuling	KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x1500)
408b92a66a6SMichael Neuling
4090ebc4cdaSBenjamin Herrenschmidt#ifdef CONFIG_CBE_RAS
410b3e6b5dfSBenjamin Herrenschmidt	STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance)
4115ccf55ddSAlexander Graf	KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1602)
4120ebc4cdaSBenjamin Herrenschmidt#endif /* CONFIG_CBE_RAS */
413b01c8b54SPaul Mackerras
414b3e6b5dfSBenjamin Herrenschmidt	STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist)
415de56a948SPaul Mackerras	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x1700)
416b01c8b54SPaul Mackerras
4170ebc4cdaSBenjamin Herrenschmidt#ifdef CONFIG_CBE_RAS
418b3e6b5dfSBenjamin Herrenschmidt	STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal)
4195ccf55ddSAlexander Graf	KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1802)
420faab4dd2SMichael Neuling#else
421faab4dd2SMichael Neuling	. = 0x1800
4220ebc4cdaSBenjamin Herrenschmidt#endif /* CONFIG_CBE_RAS */
4230ebc4cdaSBenjamin Herrenschmidt
4240ebc4cdaSBenjamin Herrenschmidt
425b3e6b5dfSBenjamin Herrenschmidt/*** Out of line interrupts support ***/
426b3e6b5dfSBenjamin Herrenschmidt
427faab4dd2SMichael Neuling	.align	7
428b01c8b54SPaul Mackerras	/* moved from 0x200 */
4291e9b4507SMahesh Salgaonkarmachine_check_pSeries_early:
4301e9b4507SMahesh SalgaonkarBEGIN_FTR_SECTION
4311e9b4507SMahesh Salgaonkar	EXCEPTION_PROLOG_1(PACA_EXMC, NOTEST, 0x200)
4321e9b4507SMahesh Salgaonkar	/*
4331e9b4507SMahesh Salgaonkar	 * Register contents:
4341e9b4507SMahesh Salgaonkar	 * R13		= PACA
4351e9b4507SMahesh Salgaonkar	 * R9		= CR
4361e9b4507SMahesh Salgaonkar	 * Original R9 to R13 is saved on PACA_EXMC
4371e9b4507SMahesh Salgaonkar	 *
438e75ad93aSMahesh Salgaonkar	 * Switch to mc_emergency stack and handle re-entrancy (we limit
439e75ad93aSMahesh Salgaonkar	 * the nested MCE upto level 4 to avoid stack overflow).
440e75ad93aSMahesh Salgaonkar	 * Save MCE registers srr1, srr0, dar and dsisr and then set ME=1
4411e9b4507SMahesh Salgaonkar	 *
4421e9b4507SMahesh Salgaonkar	 * We use paca->in_mce to check whether this is the first entry or
4431e9b4507SMahesh Salgaonkar	 * nested machine check. We increment paca->in_mce to track nested
4441e9b4507SMahesh Salgaonkar	 * machine checks.
4451e9b4507SMahesh Salgaonkar	 *
4461e9b4507SMahesh Salgaonkar	 * If this is the first entry then set stack pointer to
4471e9b4507SMahesh Salgaonkar	 * paca->mc_emergency_sp, otherwise r1 is already pointing to
4481e9b4507SMahesh Salgaonkar	 * stack frame on mc_emergency stack.
4491e9b4507SMahesh Salgaonkar	 *
4501e9b4507SMahesh Salgaonkar	 * NOTE: We are here with MSR_ME=0 (off), which means we risk a
4511e9b4507SMahesh Salgaonkar	 * checkstop if we get another machine check exception before we do
4521e9b4507SMahesh Salgaonkar	 * rfid with MSR_ME=1.
4531e9b4507SMahesh Salgaonkar	 */
4541e9b4507SMahesh Salgaonkar	mr	r11,r1			/* Save r1 */
4551e9b4507SMahesh Salgaonkar	lhz	r10,PACA_IN_MCE(r13)
4561e9b4507SMahesh Salgaonkar	cmpwi	r10,0			/* Are we in nested machine check */
4571e9b4507SMahesh Salgaonkar	bne	0f			/* Yes, we are. */
4581e9b4507SMahesh Salgaonkar	/* First machine check entry */
4591e9b4507SMahesh Salgaonkar	ld	r1,PACAMCEMERGSP(r13)	/* Use MC emergency stack */
4601e9b4507SMahesh Salgaonkar0:	subi	r1,r1,INT_FRAME_SIZE	/* alloc stack frame */
4611e9b4507SMahesh Salgaonkar	addi	r10,r10,1		/* increment paca->in_mce */
4621e9b4507SMahesh Salgaonkar	sth	r10,PACA_IN_MCE(r13)
463e75ad93aSMahesh Salgaonkar	/* Limit nested MCE to level 4 to avoid stack overflow */
464e75ad93aSMahesh Salgaonkar	cmpwi	r10,4
465e75ad93aSMahesh Salgaonkar	bgt	2f			/* Check if we hit limit of 4 */
4661e9b4507SMahesh Salgaonkar	std	r11,GPR1(r1)		/* Save r1 on the stack. */
4671e9b4507SMahesh Salgaonkar	std	r11,0(r1)		/* make stack chain pointer */
4681e9b4507SMahesh Salgaonkar	mfspr	r11,SPRN_SRR0		/* Save SRR0 */
4691e9b4507SMahesh Salgaonkar	std	r11,_NIP(r1)
4701e9b4507SMahesh Salgaonkar	mfspr	r11,SPRN_SRR1		/* Save SRR1 */
4711e9b4507SMahesh Salgaonkar	std	r11,_MSR(r1)
4721e9b4507SMahesh Salgaonkar	mfspr	r11,SPRN_DAR		/* Save DAR */
4731e9b4507SMahesh Salgaonkar	std	r11,_DAR(r1)
4741e9b4507SMahesh Salgaonkar	mfspr	r11,SPRN_DSISR		/* Save DSISR */
4751e9b4507SMahesh Salgaonkar	std	r11,_DSISR(r1)
4761e9b4507SMahesh Salgaonkar	std	r9,_CCR(r1)		/* Save CR in stackframe */
4771e9b4507SMahesh Salgaonkar	/* Save r9 through r13 from EXMC save area to stack frame. */
4781e9b4507SMahesh Salgaonkar	EXCEPTION_PROLOG_COMMON_2(PACA_EXMC)
4791e9b4507SMahesh Salgaonkar	mfmsr	r11			/* get MSR value */
4801e9b4507SMahesh Salgaonkar	ori	r11,r11,MSR_ME		/* turn on ME bit */
4811e9b4507SMahesh Salgaonkar	ori	r11,r11,MSR_RI		/* turn on RI bit */
4821e9b4507SMahesh Salgaonkar	ld	r12,PACAKBASE(r13)	/* get high part of &label */
4831e9b4507SMahesh Salgaonkar	LOAD_HANDLER(r12, machine_check_handle_early)
484e75ad93aSMahesh Salgaonkar1:	mtspr	SPRN_SRR0,r12
4851e9b4507SMahesh Salgaonkar	mtspr	SPRN_SRR1,r11
4861e9b4507SMahesh Salgaonkar	rfid
4871e9b4507SMahesh Salgaonkar	b	.	/* prevent speculative execution */
488e75ad93aSMahesh Salgaonkar2:
489e75ad93aSMahesh Salgaonkar	/* Stack overflow. Stay on emergency stack and panic.
490e75ad93aSMahesh Salgaonkar	 * Keep the ME bit off while panic-ing, so that if we hit
491e75ad93aSMahesh Salgaonkar	 * another machine check we checkstop.
492e75ad93aSMahesh Salgaonkar	 */
493e75ad93aSMahesh Salgaonkar	addi	r1,r1,INT_FRAME_SIZE	/* go back to previous stack frame */
494e75ad93aSMahesh Salgaonkar	ld	r11,PACAKMSR(r13)
495e75ad93aSMahesh Salgaonkar	ld	r12,PACAKBASE(r13)
496e75ad93aSMahesh Salgaonkar	LOAD_HANDLER(r12, unrecover_mce)
497e75ad93aSMahesh Salgaonkar	li	r10,MSR_ME
498e75ad93aSMahesh Salgaonkar	andc	r11,r11,r10		/* Turn off MSR_ME */
499e75ad93aSMahesh Salgaonkar	b	1b
500e75ad93aSMahesh Salgaonkar	b	.	/* prevent speculative execution */
5011e9b4507SMahesh SalgaonkarEND_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
5021e9b4507SMahesh Salgaonkar
503b01c8b54SPaul Mackerrasmachine_check_pSeries:
504b01c8b54SPaul Mackerras	.globl machine_check_fwnmi
505b01c8b54SPaul Mackerrasmachine_check_fwnmi:
50644e9309fSHaren Myneni	HMT_MEDIUM_PPR_DISCARD
507b01c8b54SPaul Mackerras	SET_SCRATCH0(r13)		/* save r13 */
5081707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXMC)
5091707dd16SPaul Mackerrasmachine_check_pSeries_0:
5101707dd16SPaul Mackerras	EXCEPTION_PROLOG_1(PACA_EXMC, KVMTEST, 0x200)
5111707dd16SPaul Mackerras	EXCEPTION_PROLOG_PSERIES_1(machine_check_common, EXC_STD)
512b01c8b54SPaul Mackerras	KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200)
513697d3899SPaul Mackerras	KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300)
514697d3899SPaul Mackerras	KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380)
515de56a948SPaul Mackerras	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x400)
516de56a948SPaul Mackerras	KVM_HANDLER_PR(PACA_EXSLB, EXC_STD, 0x480)
517de56a948SPaul Mackerras	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x900)
518b01c8b54SPaul Mackerras	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x982)
519b01c8b54SPaul Mackerras
520b92a66a6SMichael Neuling#ifdef CONFIG_PPC_DENORMALISATION
521b92a66a6SMichael Neulingdenorm_assist:
522b92a66a6SMichael NeulingBEGIN_FTR_SECTION
523b92a66a6SMichael Neuling/*
524b92a66a6SMichael Neuling * To denormalise we need to move a copy of the register to itself.
525b92a66a6SMichael Neuling * For POWER6 do that here for all FP regs.
526b92a66a6SMichael Neuling */
527b92a66a6SMichael Neuling	mfmsr	r10
528b92a66a6SMichael Neuling	ori	r10,r10,(MSR_FP|MSR_FE0|MSR_FE1)
529b92a66a6SMichael Neuling	xori	r10,r10,(MSR_FE0|MSR_FE1)
530b92a66a6SMichael Neuling	mtmsrd	r10
531b92a66a6SMichael Neuling	sync
532d7c67fb1SMichael Neuling
533d7c67fb1SMichael Neuling#define FMR2(n)  fmr (n), (n) ; fmr n+1, n+1
534d7c67fb1SMichael Neuling#define FMR4(n)  FMR2(n) ; FMR2(n+2)
535d7c67fb1SMichael Neuling#define FMR8(n)  FMR4(n) ; FMR4(n+4)
536d7c67fb1SMichael Neuling#define FMR16(n) FMR8(n) ; FMR8(n+8)
537d7c67fb1SMichael Neuling#define FMR32(n) FMR16(n) ; FMR16(n+16)
538d7c67fb1SMichael Neuling	FMR32(0)
539d7c67fb1SMichael Neuling
540b92a66a6SMichael NeulingFTR_SECTION_ELSE
541b92a66a6SMichael Neuling/*
542b92a66a6SMichael Neuling * To denormalise we need to move a copy of the register to itself.
543b92a66a6SMichael Neuling * For POWER7 do that here for the first 32 VSX registers only.
544b92a66a6SMichael Neuling */
545b92a66a6SMichael Neuling	mfmsr	r10
546b92a66a6SMichael Neuling	oris	r10,r10,MSR_VSX@h
547b92a66a6SMichael Neuling	mtmsrd	r10
548b92a66a6SMichael Neuling	sync
549d7c67fb1SMichael Neuling
550d7c67fb1SMichael Neuling#define XVCPSGNDP2(n) XVCPSGNDP(n,n,n) ; XVCPSGNDP(n+1,n+1,n+1)
551d7c67fb1SMichael Neuling#define XVCPSGNDP4(n) XVCPSGNDP2(n) ; XVCPSGNDP2(n+2)
552d7c67fb1SMichael Neuling#define XVCPSGNDP8(n) XVCPSGNDP4(n) ; XVCPSGNDP4(n+4)
553d7c67fb1SMichael Neuling#define XVCPSGNDP16(n) XVCPSGNDP8(n) ; XVCPSGNDP8(n+8)
554d7c67fb1SMichael Neuling#define XVCPSGNDP32(n) XVCPSGNDP16(n) ; XVCPSGNDP16(n+16)
555d7c67fb1SMichael Neuling	XVCPSGNDP32(0)
556d7c67fb1SMichael Neuling
557b92a66a6SMichael NeulingALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
558fb0fce3eSMichael Neuling
559fb0fce3eSMichael NeulingBEGIN_FTR_SECTION
560fb0fce3eSMichael Neuling	b	denorm_done
561fb0fce3eSMichael NeulingEND_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
562fb0fce3eSMichael Neuling/*
563fb0fce3eSMichael Neuling * To denormalise we need to move a copy of the register to itself.
564fb0fce3eSMichael Neuling * For POWER8 we need to do that for all 64 VSX registers
565fb0fce3eSMichael Neuling */
566fb0fce3eSMichael Neuling	XVCPSGNDP32(32)
567fb0fce3eSMichael Neulingdenorm_done:
568b92a66a6SMichael Neuling	mtspr	SPRN_HSRR0,r11
569b92a66a6SMichael Neuling	mtcrf	0x80,r9
570b92a66a6SMichael Neuling	ld	r9,PACA_EXGEN+EX_R9(r13)
57144e9309fSHaren Myneni	RESTORE_PPR_PACA(PACA_EXGEN, r10)
572630573c1SPaul MackerrasBEGIN_FTR_SECTION
573630573c1SPaul Mackerras	ld	r10,PACA_EXGEN+EX_CFAR(r13)
574630573c1SPaul Mackerras	mtspr	SPRN_CFAR,r10
575630573c1SPaul MackerrasEND_FTR_SECTION_IFSET(CPU_FTR_CFAR)
576b92a66a6SMichael Neuling	ld	r10,PACA_EXGEN+EX_R10(r13)
577b92a66a6SMichael Neuling	ld	r11,PACA_EXGEN+EX_R11(r13)
578b92a66a6SMichael Neuling	ld	r12,PACA_EXGEN+EX_R12(r13)
579b92a66a6SMichael Neuling	ld	r13,PACA_EXGEN+EX_R13(r13)
580b92a66a6SMichael Neuling	HRFID
581b92a66a6SMichael Neuling	b	.
582b92a66a6SMichael Neuling#endif
583b92a66a6SMichael Neuling
584b01c8b54SPaul Mackerras	.align	7
585b3e6b5dfSBenjamin Herrenschmidt	/* moved from 0xe00 */
5861707dd16SPaul Mackerras	STD_EXCEPTION_HV_OOL(0xe02, h_data_storage)
587b01c8b54SPaul Mackerras	KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0xe02)
5881707dd16SPaul Mackerras	STD_EXCEPTION_HV_OOL(0xe22, h_instr_storage)
589b01c8b54SPaul Mackerras	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe22)
5901707dd16SPaul Mackerras	STD_EXCEPTION_HV_OOL(0xe42, emulation_assist)
591b01c8b54SPaul Mackerras	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe42)
592*0869b6fdSMahesh Salgaonkar	MASKABLE_EXCEPTION_HV_OOL(0xe62, hmi_exception)
593b01c8b54SPaul Mackerras	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe62)
594*0869b6fdSMahesh Salgaonkar
595*0869b6fdSMahesh Salgaonkar	.globl hmi_exception_early
596*0869b6fdSMahesh Salgaonkarhmi_exception_early:
597*0869b6fdSMahesh Salgaonkar	EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0xe60)
598*0869b6fdSMahesh Salgaonkar	mr	r10,r1			/* Save r1			*/
599*0869b6fdSMahesh Salgaonkar	ld	r1,PACAEMERGSP(r13)	/* Use emergency stack		*/
600*0869b6fdSMahesh Salgaonkar	subi	r1,r1,INT_FRAME_SIZE	/* alloc stack frame		*/
601*0869b6fdSMahesh Salgaonkar	std	r9,_CCR(r1)		/* save CR in stackframe	*/
602*0869b6fdSMahesh Salgaonkar	mfspr	r11,SPRN_HSRR0		/* Save HSRR0 */
603*0869b6fdSMahesh Salgaonkar	std	r11,_NIP(r1)		/* save HSRR0 in stackframe	*/
604*0869b6fdSMahesh Salgaonkar	mfspr	r12,SPRN_HSRR1		/* Save SRR1 */
605*0869b6fdSMahesh Salgaonkar	std	r12,_MSR(r1)		/* save SRR1 in stackframe	*/
606*0869b6fdSMahesh Salgaonkar	std	r10,0(r1)		/* make stack chain pointer	*/
607*0869b6fdSMahesh Salgaonkar	std	r0,GPR0(r1)		/* save r0 in stackframe	*/
608*0869b6fdSMahesh Salgaonkar	std	r10,GPR1(r1)		/* save r1 in stackframe	*/
609*0869b6fdSMahesh Salgaonkar	EXCEPTION_PROLOG_COMMON_2(PACA_EXGEN)
610*0869b6fdSMahesh Salgaonkar	EXCEPTION_PROLOG_COMMON_3(0xe60)
611*0869b6fdSMahesh Salgaonkar	addi	r3,r1,STACK_FRAME_OVERHEAD
612*0869b6fdSMahesh Salgaonkar	bl	hmi_exception_realmode
613*0869b6fdSMahesh Salgaonkar	/* Windup the stack. */
614*0869b6fdSMahesh Salgaonkar	/* Clear MSR_RI before setting SRR0 and SRR1. */
615*0869b6fdSMahesh Salgaonkar	li	r0,MSR_RI
616*0869b6fdSMahesh Salgaonkar	mfmsr	r9			/* get MSR value */
617*0869b6fdSMahesh Salgaonkar	andc	r9,r9,r0
618*0869b6fdSMahesh Salgaonkar	mtmsrd	r9,1			/* Clear MSR_RI */
619*0869b6fdSMahesh Salgaonkar	/* Move original HSRR0 and HSRR1 into the respective regs */
620*0869b6fdSMahesh Salgaonkar	ld	r9,_MSR(r1)
621*0869b6fdSMahesh Salgaonkar	mtspr	SPRN_HSRR1,r9
622*0869b6fdSMahesh Salgaonkar	ld	r3,_NIP(r1)
623*0869b6fdSMahesh Salgaonkar	mtspr	SPRN_HSRR0,r3
624*0869b6fdSMahesh Salgaonkar	ld	r9,_CTR(r1)
625*0869b6fdSMahesh Salgaonkar	mtctr	r9
626*0869b6fdSMahesh Salgaonkar	ld	r9,_XER(r1)
627*0869b6fdSMahesh Salgaonkar	mtxer	r9
628*0869b6fdSMahesh Salgaonkar	ld	r9,_LINK(r1)
629*0869b6fdSMahesh Salgaonkar	mtlr	r9
630*0869b6fdSMahesh Salgaonkar	REST_GPR(0, r1)
631*0869b6fdSMahesh Salgaonkar	REST_8GPRS(2, r1)
632*0869b6fdSMahesh Salgaonkar	REST_GPR(10, r1)
633*0869b6fdSMahesh Salgaonkar	ld	r11,_CCR(r1)
634*0869b6fdSMahesh Salgaonkar	mtcr	r11
635*0869b6fdSMahesh Salgaonkar	REST_GPR(11, r1)
636*0869b6fdSMahesh Salgaonkar	REST_2GPRS(12, r1)
637*0869b6fdSMahesh Salgaonkar	/* restore original r1. */
638*0869b6fdSMahesh Salgaonkar	ld	r1,GPR1(r1)
639*0869b6fdSMahesh Salgaonkar
640*0869b6fdSMahesh Salgaonkar	/*
641*0869b6fdSMahesh Salgaonkar	 * Go to virtual mode and pull the HMI event information from
642*0869b6fdSMahesh Salgaonkar	 * firmware.
643*0869b6fdSMahesh Salgaonkar	 */
644*0869b6fdSMahesh Salgaonkar	.globl hmi_exception_after_realmode
645*0869b6fdSMahesh Salgaonkarhmi_exception_after_realmode:
646*0869b6fdSMahesh Salgaonkar	SET_SCRATCH0(r13)
647*0869b6fdSMahesh Salgaonkar	EXCEPTION_PROLOG_0(PACA_EXGEN)
648*0869b6fdSMahesh Salgaonkar	b	hmi_exception_hv
649*0869b6fdSMahesh Salgaonkar
6501707dd16SPaul Mackerras	MASKABLE_EXCEPTION_HV_OOL(0xe82, h_doorbell)
651655bb3f4SIan Munsie	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe82)
6520ebc4cdaSBenjamin Herrenschmidt
6530ebc4cdaSBenjamin Herrenschmidt	/* moved from 0xf00 */
6541707dd16SPaul Mackerras	STD_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor)
655de56a948SPaul Mackerras	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf00)
6561707dd16SPaul Mackerras	STD_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable)
657de56a948SPaul Mackerras	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf20)
6581707dd16SPaul Mackerras	STD_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable)
659de56a948SPaul Mackerras	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf40)
660021424a1SMichael Ellerman	STD_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable)
661d0c0c9a1SMichael Neuling	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf60)
662b14b6260SMichael Ellerman	STD_EXCEPTION_HV_OOL(0xf82, facility_unavailable)
663b14b6260SMichael Ellerman	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xf82)
6640ebc4cdaSBenjamin Herrenschmidt
6650ebc4cdaSBenjamin Herrenschmidt/*
666fe9e1d54SIan Munsie * An interrupt came in while soft-disabled. We set paca->irq_happened, then:
667fe9e1d54SIan Munsie * - If it was a decrementer interrupt, we bump the dec to max and and return.
668fe9e1d54SIan Munsie * - If it was a doorbell we return immediately since doorbells are edge
669fe9e1d54SIan Munsie *   triggered and won't automatically refire.
670*0869b6fdSMahesh Salgaonkar * - If it was a HMI we return immediately since we handled it in realmode
671*0869b6fdSMahesh Salgaonkar *   and it won't refire.
672fe9e1d54SIan Munsie * - else we hard disable and return.
673fe9e1d54SIan Munsie * This is called with r10 containing the value to OR to the paca field.
6740ebc4cdaSBenjamin Herrenschmidt */
6757230c564SBenjamin Herrenschmidt#define MASKED_INTERRUPT(_H)				\
6767230c564SBenjamin Herrenschmidtmasked_##_H##interrupt:					\
6777230c564SBenjamin Herrenschmidt	std	r11,PACA_EXGEN+EX_R11(r13);		\
6787230c564SBenjamin Herrenschmidt	lbz	r11,PACAIRQHAPPENED(r13);		\
6797230c564SBenjamin Herrenschmidt	or	r11,r11,r10;				\
6807230c564SBenjamin Herrenschmidt	stb	r11,PACAIRQHAPPENED(r13);		\
681fe9e1d54SIan Munsie	cmpwi	r10,PACA_IRQ_DEC;			\
682fe9e1d54SIan Munsie	bne	1f;					\
6837230c564SBenjamin Herrenschmidt	lis	r10,0x7fff;				\
6847230c564SBenjamin Herrenschmidt	ori	r10,r10,0xffff;				\
6857230c564SBenjamin Herrenschmidt	mtspr	SPRN_DEC,r10;				\
6867230c564SBenjamin Herrenschmidt	b	2f;					\
687fe9e1d54SIan Munsie1:	cmpwi	r10,PACA_IRQ_DBELL;			\
688fe9e1d54SIan Munsie	beq	2f;					\
689*0869b6fdSMahesh Salgaonkar	cmpwi	r10,PACA_IRQ_HMI;			\
690*0869b6fdSMahesh Salgaonkar	beq	2f;					\
691fe9e1d54SIan Munsie	mfspr	r10,SPRN_##_H##SRR1;			\
6927230c564SBenjamin Herrenschmidt	rldicl	r10,r10,48,1; /* clear MSR_EE */	\
6937230c564SBenjamin Herrenschmidt	rotldi	r10,r10,16;				\
6947230c564SBenjamin Herrenschmidt	mtspr	SPRN_##_H##SRR1,r10;			\
6957230c564SBenjamin Herrenschmidt2:	mtcrf	0x80,r9;				\
6967230c564SBenjamin Herrenschmidt	ld	r9,PACA_EXGEN+EX_R9(r13);		\
6977230c564SBenjamin Herrenschmidt	ld	r10,PACA_EXGEN+EX_R10(r13);		\
6987230c564SBenjamin Herrenschmidt	ld	r11,PACA_EXGEN+EX_R11(r13);		\
6997230c564SBenjamin Herrenschmidt	GET_SCRATCH0(r13);				\
7007230c564SBenjamin Herrenschmidt	##_H##rfid;					\
7010ebc4cdaSBenjamin Herrenschmidt	b	.
7020ebc4cdaSBenjamin Herrenschmidt
7037230c564SBenjamin Herrenschmidt	MASKED_INTERRUPT()
7047230c564SBenjamin Herrenschmidt	MASKED_INTERRUPT(H)
7057230c564SBenjamin Herrenschmidt
7067230c564SBenjamin Herrenschmidt/*
7077230c564SBenjamin Herrenschmidt * Called from arch_local_irq_enable when an interrupt needs
708fe9e1d54SIan Munsie * to be resent. r3 contains 0x500, 0x900, 0xa00 or 0xe80 to indicate
709fe9e1d54SIan Munsie * which kind of interrupt. MSR:EE is already off. We generate a
7107230c564SBenjamin Herrenschmidt * stackframe like if a real interrupt had happened.
7117230c564SBenjamin Herrenschmidt *
7127230c564SBenjamin Herrenschmidt * Note: While MSR:EE is off, we need to make sure that _MSR
7137230c564SBenjamin Herrenschmidt * in the generated frame has EE set to 1 or the exception
7147230c564SBenjamin Herrenschmidt * handler will not properly re-enable them.
7157230c564SBenjamin Herrenschmidt */
7167230c564SBenjamin Herrenschmidt_GLOBAL(__replay_interrupt)
7177230c564SBenjamin Herrenschmidt	/* We are going to jump to the exception common code which
7187230c564SBenjamin Herrenschmidt	 * will retrieve various register values from the PACA which
7197230c564SBenjamin Herrenschmidt	 * we don't give a damn about, so we don't bother storing them.
7207230c564SBenjamin Herrenschmidt	 */
7217230c564SBenjamin Herrenschmidt	mfmsr	r12
7227230c564SBenjamin Herrenschmidt	mflr	r11
7237230c564SBenjamin Herrenschmidt	mfcr	r9
7247230c564SBenjamin Herrenschmidt	ori	r12,r12,MSR_EE
725fe9e1d54SIan Munsie	cmpwi	r3,0x900
726fe9e1d54SIan Munsie	beq	decrementer_common
727fe9e1d54SIan Munsie	cmpwi	r3,0x500
728fe9e1d54SIan Munsie	beq	hardware_interrupt_common
729fe9e1d54SIan MunsieBEGIN_FTR_SECTION
730fe9e1d54SIan Munsie	cmpwi	r3,0xe80
731fe9e1d54SIan Munsie	beq	h_doorbell_common
732fe9e1d54SIan MunsieFTR_SECTION_ELSE
733fe9e1d54SIan Munsie	cmpwi	r3,0xa00
734fe9e1d54SIan Munsie	beq	doorbell_super_common
735fe9e1d54SIan MunsieALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
736fe9e1d54SIan Munsie	blr
737a5d4f3adSBenjamin Herrenschmidt
7380ebc4cdaSBenjamin Herrenschmidt#ifdef CONFIG_PPC_PSERIES
7390ebc4cdaSBenjamin Herrenschmidt/*
7400ebc4cdaSBenjamin Herrenschmidt * Vectors for the FWNMI option.  Share common code.
7410ebc4cdaSBenjamin Herrenschmidt */
7420ebc4cdaSBenjamin Herrenschmidt	.globl system_reset_fwnmi
7430ebc4cdaSBenjamin Herrenschmidt      .align 7
7440ebc4cdaSBenjamin Herrenschmidtsystem_reset_fwnmi:
74544e9309fSHaren Myneni	HMT_MEDIUM_PPR_DISCARD
746673b189aSPaul Mackerras	SET_SCRATCH0(r13)		/* save r13 */
747b01c8b54SPaul Mackerras	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
748b01c8b54SPaul Mackerras				 NOTEST, 0x100)
7490ebc4cdaSBenjamin Herrenschmidt
7500ebc4cdaSBenjamin Herrenschmidt#endif /* CONFIG_PPC_PSERIES */
7510ebc4cdaSBenjamin Herrenschmidt
7520ebc4cdaSBenjamin Herrenschmidt#ifdef __DISABLED__
7530ebc4cdaSBenjamin Herrenschmidt/*
7540ebc4cdaSBenjamin Herrenschmidt * This is used for when the SLB miss handler has to go virtual,
7550ebc4cdaSBenjamin Herrenschmidt * which doesn't happen for now anymore but will once we re-implement
7560ebc4cdaSBenjamin Herrenschmidt * dynamic VSIDs for shared page tables
7570ebc4cdaSBenjamin Herrenschmidt */
7580ebc4cdaSBenjamin Herrenschmidtslb_miss_user_pseries:
7590ebc4cdaSBenjamin Herrenschmidt	std	r10,PACA_EXGEN+EX_R10(r13)
7600ebc4cdaSBenjamin Herrenschmidt	std	r11,PACA_EXGEN+EX_R11(r13)
7610ebc4cdaSBenjamin Herrenschmidt	std	r12,PACA_EXGEN+EX_R12(r13)
762673b189aSPaul Mackerras	GET_SCRATCH0(r10)
7630ebc4cdaSBenjamin Herrenschmidt	ld	r11,PACA_EXSLB+EX_R9(r13)
7640ebc4cdaSBenjamin Herrenschmidt	ld	r12,PACA_EXSLB+EX_R3(r13)
7650ebc4cdaSBenjamin Herrenschmidt	std	r10,PACA_EXGEN+EX_R13(r13)
7660ebc4cdaSBenjamin Herrenschmidt	std	r11,PACA_EXGEN+EX_R9(r13)
7670ebc4cdaSBenjamin Herrenschmidt	std	r12,PACA_EXGEN+EX_R3(r13)
7680ebc4cdaSBenjamin Herrenschmidt	clrrdi	r12,r13,32
7690ebc4cdaSBenjamin Herrenschmidt	mfmsr	r10
7700ebc4cdaSBenjamin Herrenschmidt	mfspr	r11,SRR0			/* save SRR0 */
7710ebc4cdaSBenjamin Herrenschmidt	ori	r12,r12,slb_miss_user_common@l	/* virt addr of handler */
7720ebc4cdaSBenjamin Herrenschmidt	ori	r10,r10,MSR_IR|MSR_DR|MSR_RI
7730ebc4cdaSBenjamin Herrenschmidt	mtspr	SRR0,r12
7740ebc4cdaSBenjamin Herrenschmidt	mfspr	r12,SRR1			/* and SRR1 */
7750ebc4cdaSBenjamin Herrenschmidt	mtspr	SRR1,r10
7760ebc4cdaSBenjamin Herrenschmidt	rfid
7770ebc4cdaSBenjamin Herrenschmidt	b	.				/* prevent spec. execution */
7780ebc4cdaSBenjamin Herrenschmidt#endif /* __DISABLED__ */
7790ebc4cdaSBenjamin Herrenschmidt
7804f6c11dbSPaul Mackerras#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
7814f6c11dbSPaul Mackerraskvmppc_skip_interrupt:
7824f6c11dbSPaul Mackerras	/*
7834f6c11dbSPaul Mackerras	 * Here all GPRs are unchanged from when the interrupt happened
7844f6c11dbSPaul Mackerras	 * except for r13, which is saved in SPRG_SCRATCH0.
7854f6c11dbSPaul Mackerras	 */
7864f6c11dbSPaul Mackerras	mfspr	r13, SPRN_SRR0
7874f6c11dbSPaul Mackerras	addi	r13, r13, 4
7884f6c11dbSPaul Mackerras	mtspr	SPRN_SRR0, r13
7894f6c11dbSPaul Mackerras	GET_SCRATCH0(r13)
7904f6c11dbSPaul Mackerras	rfid
7914f6c11dbSPaul Mackerras	b	.
7924f6c11dbSPaul Mackerras
7934f6c11dbSPaul Mackerraskvmppc_skip_Hinterrupt:
7944f6c11dbSPaul Mackerras	/*
7954f6c11dbSPaul Mackerras	 * Here all GPRs are unchanged from when the interrupt happened
7964f6c11dbSPaul Mackerras	 * except for r13, which is saved in SPRG_SCRATCH0.
7974f6c11dbSPaul Mackerras	 */
7984f6c11dbSPaul Mackerras	mfspr	r13, SPRN_HSRR0
7994f6c11dbSPaul Mackerras	addi	r13, r13, 4
8004f6c11dbSPaul Mackerras	mtspr	SPRN_HSRR0, r13
8014f6c11dbSPaul Mackerras	GET_SCRATCH0(r13)
8024f6c11dbSPaul Mackerras	hrfid
8034f6c11dbSPaul Mackerras	b	.
8044f6c11dbSPaul Mackerras#endif
8054f6c11dbSPaul Mackerras
8060ebc4cdaSBenjamin Herrenschmidt/*
8070ebc4cdaSBenjamin Herrenschmidt * Code from here down to __end_handlers is invoked from the
8080ebc4cdaSBenjamin Herrenschmidt * exception prologs above.  Because the prologs assemble the
8090ebc4cdaSBenjamin Herrenschmidt * addresses of these handlers using the LOAD_HANDLER macro,
81061e2390eSMichael Neuling * which uses an ori instruction, these handlers must be in
81161e2390eSMichael Neuling * the first 64k of the kernel image.
8120ebc4cdaSBenjamin Herrenschmidt */
8130ebc4cdaSBenjamin Herrenschmidt
8140ebc4cdaSBenjamin Herrenschmidt/*** Common interrupt handlers ***/
8150ebc4cdaSBenjamin Herrenschmidt
81635425501SAnton Blanchard	STD_EXCEPTION_COMMON(0x100, system_reset, system_reset_exception)
8170ebc4cdaSBenjamin Herrenschmidt
8187450f6f0SBenjamin Herrenschmidt	STD_EXCEPTION_COMMON_ASYNC(0x500, hardware_interrupt, do_IRQ)
81935425501SAnton Blanchard	STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, timer_interrupt)
82035425501SAnton Blanchard	STD_EXCEPTION_COMMON(0x980, hdecrementer, hdec_interrupt)
8211dbdafecSIan Munsie#ifdef CONFIG_PPC_DOORBELL
82235425501SAnton Blanchard	STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, doorbell_exception)
8231dbdafecSIan Munsie#else
82435425501SAnton Blanchard	STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, unknown_exception)
8251dbdafecSIan Munsie#endif
82635425501SAnton Blanchard	STD_EXCEPTION_COMMON(0xb00, trap_0b, unknown_exception)
82735425501SAnton Blanchard	STD_EXCEPTION_COMMON(0xd00, single_step, single_step_exception)
82835425501SAnton Blanchard	STD_EXCEPTION_COMMON(0xe00, trap_0e, unknown_exception)
82935425501SAnton Blanchard	STD_EXCEPTION_COMMON(0xe40, emulation_assist, emulation_assist_interrupt)
830*0869b6fdSMahesh Salgaonkar	STD_EXCEPTION_COMMON_ASYNC(0xe60, hmi_exception, handle_hmi_exception)
831655bb3f4SIan Munsie#ifdef CONFIG_PPC_DOORBELL
83235425501SAnton Blanchard	STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, doorbell_exception)
833655bb3f4SIan Munsie#else
83435425501SAnton Blanchard	STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, unknown_exception)
835655bb3f4SIan Munsie#endif
83635425501SAnton Blanchard	STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, performance_monitor_exception)
83735425501SAnton Blanchard	STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, instruction_breakpoint_exception)
83835425501SAnton Blanchard	STD_EXCEPTION_COMMON(0x1502, denorm, unknown_exception)
8390ebc4cdaSBenjamin Herrenschmidt#ifdef CONFIG_ALTIVEC
84035425501SAnton Blanchard	STD_EXCEPTION_COMMON(0x1700, altivec_assist, altivec_assist_exception)
8410ebc4cdaSBenjamin Herrenschmidt#else
84235425501SAnton Blanchard	STD_EXCEPTION_COMMON(0x1700, altivec_assist, unknown_exception)
8430ebc4cdaSBenjamin Herrenschmidt#endif
8440ebc4cdaSBenjamin Herrenschmidt#ifdef CONFIG_CBE_RAS
84535425501SAnton Blanchard	STD_EXCEPTION_COMMON(0x1200, cbe_system_error, cbe_system_error_exception)
84635425501SAnton Blanchard	STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, cbe_maintenance_exception)
84735425501SAnton Blanchard	STD_EXCEPTION_COMMON(0x1800, cbe_thermal, cbe_thermal_exception)
8480ebc4cdaSBenjamin Herrenschmidt#endif /* CONFIG_CBE_RAS */
8490ebc4cdaSBenjamin Herrenschmidt
850c1fb6816SMichael Neuling	/*
851c1fb6816SMichael Neuling	 * Relocation-on interrupts: A subset of the interrupts can be delivered
852c1fb6816SMichael Neuling	 * with IR=1/DR=1, if AIL==2 and MSR.HV won't be changed by delivering
853c1fb6816SMichael Neuling	 * it.  Addresses are the same as the original interrupt addresses, but
854c1fb6816SMichael Neuling	 * offset by 0xc000000000004000.
855c1fb6816SMichael Neuling	 * It's impossible to receive interrupts below 0x300 via this mechanism.
856c1fb6816SMichael Neuling	 * KVM: None of these traps are from the guest ; anything that escalated
857c1fb6816SMichael Neuling	 * to HV=1 from HV=0 is delivered via real mode handlers.
858c1fb6816SMichael Neuling	 */
859c1fb6816SMichael Neuling
860c1fb6816SMichael Neuling	/*
861c1fb6816SMichael Neuling	 * This uses the standard macro, since the original 0x300 vector
862c1fb6816SMichael Neuling	 * only has extra guff for STAB-based processors -- which never
863c1fb6816SMichael Neuling	 * come here.
864c1fb6816SMichael Neuling	 */
865c1fb6816SMichael Neuling	STD_RELON_EXCEPTION_PSERIES(0x4300, 0x300, data_access)
866c1fb6816SMichael Neuling	. = 0x4380
867c1fb6816SMichael Neuling	.globl data_access_slb_relon_pSeries
868c1fb6816SMichael Neulingdata_access_slb_relon_pSeries:
869c1fb6816SMichael Neuling	SET_SCRATCH0(r13)
8701707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXSLB)
871c1fb6816SMichael Neuling	EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x380)
872c1fb6816SMichael Neuling	std	r3,PACA_EXSLB+EX_R3(r13)
873c1fb6816SMichael Neuling	mfspr	r3,SPRN_DAR
874c1fb6816SMichael Neuling	mfspr	r12,SPRN_SRR1
875c1fb6816SMichael Neuling#ifndef CONFIG_RELOCATABLE
876b1576fecSAnton Blanchard	b	slb_miss_realmode
877c1fb6816SMichael Neuling#else
878c1fb6816SMichael Neuling	/*
879ad0289e4SAnton Blanchard	 * We can't just use a direct branch to slb_miss_realmode
880c1fb6816SMichael Neuling	 * because the distance from here to there depends on where
881c1fb6816SMichael Neuling	 * the kernel ends up being put.
882c1fb6816SMichael Neuling	 */
883c1fb6816SMichael Neuling	mfctr	r11
884c1fb6816SMichael Neuling	ld	r10,PACAKBASE(r13)
885ad0289e4SAnton Blanchard	LOAD_HANDLER(r10, slb_miss_realmode)
886c1fb6816SMichael Neuling	mtctr	r10
887c1fb6816SMichael Neuling	bctr
888c1fb6816SMichael Neuling#endif
889c1fb6816SMichael Neuling
890c1fb6816SMichael Neuling	STD_RELON_EXCEPTION_PSERIES(0x4400, 0x400, instruction_access)
891c1fb6816SMichael Neuling	. = 0x4480
892c1fb6816SMichael Neuling	.globl instruction_access_slb_relon_pSeries
893c1fb6816SMichael Neulinginstruction_access_slb_relon_pSeries:
894c1fb6816SMichael Neuling	SET_SCRATCH0(r13)
8951707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXSLB)
896c1fb6816SMichael Neuling	EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x480)
897c1fb6816SMichael Neuling	std	r3,PACA_EXSLB+EX_R3(r13)
898c1fb6816SMichael Neuling	mfspr	r3,SPRN_SRR0		/* SRR0 is faulting address */
899c1fb6816SMichael Neuling	mfspr	r12,SPRN_SRR1
900c1fb6816SMichael Neuling#ifndef CONFIG_RELOCATABLE
901b1576fecSAnton Blanchard	b	slb_miss_realmode
902c1fb6816SMichael Neuling#else
903c1fb6816SMichael Neuling	mfctr	r11
904c1fb6816SMichael Neuling	ld	r10,PACAKBASE(r13)
905ad0289e4SAnton Blanchard	LOAD_HANDLER(r10, slb_miss_realmode)
906c1fb6816SMichael Neuling	mtctr	r10
907c1fb6816SMichael Neuling	bctr
908c1fb6816SMichael Neuling#endif
909c1fb6816SMichael Neuling
910c1fb6816SMichael Neuling	. = 0x4500
911c1fb6816SMichael Neuling	.globl hardware_interrupt_relon_pSeries;
912c1fb6816SMichael Neuling	.globl hardware_interrupt_relon_hv;
913c1fb6816SMichael Neulinghardware_interrupt_relon_pSeries:
914c1fb6816SMichael Neulinghardware_interrupt_relon_hv:
915c1fb6816SMichael Neuling	BEGIN_FTR_SECTION
916c1fb6816SMichael Neuling		_MASKABLE_RELON_EXCEPTION_PSERIES(0x502, hardware_interrupt, EXC_HV, SOFTEN_TEST_HV)
917c1fb6816SMichael Neuling	FTR_SECTION_ELSE
918c1fb6816SMichael Neuling		_MASKABLE_RELON_EXCEPTION_PSERIES(0x500, hardware_interrupt, EXC_STD, SOFTEN_TEST_PR)
9193e96ca7fSMichael Neuling	ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
920c1fb6816SMichael Neuling	STD_RELON_EXCEPTION_PSERIES(0x4600, 0x600, alignment)
921c1fb6816SMichael Neuling	STD_RELON_EXCEPTION_PSERIES(0x4700, 0x700, program_check)
922c1fb6816SMichael Neuling	STD_RELON_EXCEPTION_PSERIES(0x4800, 0x800, fp_unavailable)
923c1fb6816SMichael Neuling	MASKABLE_RELON_EXCEPTION_PSERIES(0x4900, 0x900, decrementer)
924c1fb6816SMichael Neuling	STD_RELON_EXCEPTION_HV(0x4980, 0x982, hdecrementer)
9251dbdafecSIan Munsie	MASKABLE_RELON_EXCEPTION_PSERIES(0x4a00, 0xa00, doorbell_super)
926c1fb6816SMichael Neuling	STD_RELON_EXCEPTION_PSERIES(0x4b00, 0xb00, trap_0b)
927c1fb6816SMichael Neuling
928c1fb6816SMichael Neuling	. = 0x4c00
929c1fb6816SMichael Neuling	.globl system_call_relon_pSeries
930c1fb6816SMichael Neulingsystem_call_relon_pSeries:
931c1fb6816SMichael Neuling	HMT_MEDIUM
932c1fb6816SMichael Neuling	SYSCALL_PSERIES_1
933c1fb6816SMichael Neuling	SYSCALL_PSERIES_2_DIRECT
934c1fb6816SMichael Neuling	SYSCALL_PSERIES_3
935c1fb6816SMichael Neuling
936c1fb6816SMichael Neuling	STD_RELON_EXCEPTION_PSERIES(0x4d00, 0xd00, single_step)
937c1fb6816SMichael Neuling
938c1fb6816SMichael Neuling	. = 0x4e00
9391d567cb4SMichael Ellerman	b	.	/* Can't happen, see v2.07 Book III-S section 6.5 */
940c1fb6816SMichael Neuling
941c1fb6816SMichael Neuling	. = 0x4e20
9421d567cb4SMichael Ellerman	b	.	/* Can't happen, see v2.07 Book III-S section 6.5 */
943c1fb6816SMichael Neuling
944c1fb6816SMichael Neuling	. = 0x4e40
945d671ddd6SMichael Ellermanemulation_assist_relon_trampoline:
9461707dd16SPaul Mackerras	SET_SCRATCH0(r13)
9471707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXGEN)
948c1fb6816SMichael Neuling	b	emulation_assist_relon_hv
949c1fb6816SMichael Neuling
950c1fb6816SMichael Neuling	. = 0x4e60
9511d567cb4SMichael Ellerman	b	.	/* Can't happen, see v2.07 Book III-S section 6.5 */
952c1fb6816SMichael Neuling
953655bb3f4SIan Munsie	. = 0x4e80
954d671ddd6SMichael Ellermanh_doorbell_relon_trampoline:
9551707dd16SPaul Mackerras	SET_SCRATCH0(r13)
9561707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXGEN)
957655bb3f4SIan Munsie	b	h_doorbell_relon_hv
958c1fb6816SMichael Neuling
959c1fb6816SMichael Neuling	. = 0x4f00
960fa111f1fSMichael Ellermanperformance_monitor_relon_pseries_trampoline:
9611707dd16SPaul Mackerras	SET_SCRATCH0(r13)
9621707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXGEN)
963c1fb6816SMichael Neuling	b	performance_monitor_relon_pSeries
964c1fb6816SMichael Neuling
965c1fb6816SMichael Neuling	. = 0x4f20
966fa111f1fSMichael Ellermanaltivec_unavailable_relon_pseries_trampoline:
9671707dd16SPaul Mackerras	SET_SCRATCH0(r13)
9681707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXGEN)
969c1fb6816SMichael Neuling	b	altivec_unavailable_relon_pSeries
970c1fb6816SMichael Neuling
971c1fb6816SMichael Neuling	. = 0x4f40
972fa111f1fSMichael Ellermanvsx_unavailable_relon_pseries_trampoline:
9731707dd16SPaul Mackerras	SET_SCRATCH0(r13)
9741707dd16SPaul Mackerras	EXCEPTION_PROLOG_0(PACA_EXGEN)
975c1fb6816SMichael Neuling	b	vsx_unavailable_relon_pSeries
976c1fb6816SMichael Neuling
977d0c0c9a1SMichael Neuling	. = 0x4f60
978fa111f1fSMichael Ellermanfacility_unavailable_relon_trampoline:
979d0c0c9a1SMichael Neuling	SET_SCRATCH0(r13)
980d0c0c9a1SMichael Neuling	EXCEPTION_PROLOG_0(PACA_EXGEN)
981021424a1SMichael Ellerman	b	facility_unavailable_relon_pSeries
982d0c0c9a1SMichael Neuling
983b14b6260SMichael Ellerman	. = 0x4f80
984fa111f1fSMichael Ellermanhv_facility_unavailable_relon_trampoline:
985b14b6260SMichael Ellerman	SET_SCRATCH0(r13)
986b14b6260SMichael Ellerman	EXCEPTION_PROLOG_0(PACA_EXGEN)
98788f09412SMichael Neuling	b	hv_facility_unavailable_relon_hv
988b14b6260SMichael Ellerman
989c1fb6816SMichael Neuling	STD_RELON_EXCEPTION_PSERIES(0x5300, 0x1300, instruction_breakpoint)
990c1fb6816SMichael Neuling#ifdef CONFIG_PPC_DENORMALISATION
991c1fb6816SMichael Neuling	. = 0x5500
992c1fb6816SMichael Neuling	b	denorm_exception_hv
993c1fb6816SMichael Neuling#endif
994c1fb6816SMichael Neuling	STD_RELON_EXCEPTION_PSERIES(0x5700, 0x1700, altivec_assist)
995c1fb6816SMichael Neuling
996c1fb6816SMichael Neuling	/* Other future vectors */
9970ebc4cdaSBenjamin Herrenschmidt	.align	7
998c1fb6816SMichael Neuling	.globl	__end_interrupts
999c1fb6816SMichael Neuling__end_interrupts:
1000c1fb6816SMichael Neuling
1001c1fb6816SMichael Neuling	.align	7
1002c1fb6816SMichael Neulingsystem_call_entry_direct:
1003c1fb6816SMichael Neuling#if defined(CONFIG_RELOCATABLE)
1004c1fb6816SMichael Neuling	/* The first level prologue may have used LR to get here, saving
1005c1fb6816SMichael Neuling	 * orig in r10.  To save hacking/ifdeffing common code, restore here.
1006c1fb6816SMichael Neuling	 */
1007c1fb6816SMichael Neuling	mtlr	r10
1008c1fb6816SMichael Neuling#endif
10090ebc4cdaSBenjamin Herrenschmidtsystem_call_entry:
10100ebc4cdaSBenjamin Herrenschmidt	b	system_call_common
10110ebc4cdaSBenjamin Herrenschmidt
1012fe1952fcSBenjamin Herrenschmidtppc64_runlatch_on_trampoline:
1013b1576fecSAnton Blanchard	b	__ppc64_runlatch_on
1014fe1952fcSBenjamin Herrenschmidt
10150ebc4cdaSBenjamin Herrenschmidt/*
10160ebc4cdaSBenjamin Herrenschmidt * Here r13 points to the paca, r9 contains the saved CR,
10170ebc4cdaSBenjamin Herrenschmidt * SRR0 and SRR1 are saved in r11 and r12,
10180ebc4cdaSBenjamin Herrenschmidt * r9 - r13 are saved in paca->exgen.
10190ebc4cdaSBenjamin Herrenschmidt */
10200ebc4cdaSBenjamin Herrenschmidt	.align	7
10210ebc4cdaSBenjamin Herrenschmidt	.globl data_access_common
10220ebc4cdaSBenjamin Herrenschmidtdata_access_common:
10230ebc4cdaSBenjamin Herrenschmidt	mfspr	r10,SPRN_DAR
10240ebc4cdaSBenjamin Herrenschmidt	std	r10,PACA_EXGEN+EX_DAR(r13)
10250ebc4cdaSBenjamin Herrenschmidt	mfspr	r10,SPRN_DSISR
10260ebc4cdaSBenjamin Herrenschmidt	stw	r10,PACA_EXGEN+EX_DSISR(r13)
10270ebc4cdaSBenjamin Herrenschmidt	EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
10289daf112bSMichael Ellerman	RECONCILE_IRQ_STATE(r10, r11)
1029a546498fSBenjamin Herrenschmidt	ld	r12,_MSR(r1)
10300ebc4cdaSBenjamin Herrenschmidt	ld	r3,PACA_EXGEN+EX_DAR(r13)
10310ebc4cdaSBenjamin Herrenschmidt	lwz	r4,PACA_EXGEN+EX_DSISR(r13)
10320ebc4cdaSBenjamin Herrenschmidt	li	r5,0x300
1033b1576fecSAnton Blanchard	b	do_hash_page		/* Try to handle as hpte fault */
10340ebc4cdaSBenjamin Herrenschmidt
10350ebc4cdaSBenjamin Herrenschmidt	.align  7
1036b3e6b5dfSBenjamin Herrenschmidt	.globl  h_data_storage_common
1037b3e6b5dfSBenjamin Herrenschmidth_data_storage_common:
1038b3e6b5dfSBenjamin Herrenschmidt	mfspr   r10,SPRN_HDAR
1039b3e6b5dfSBenjamin Herrenschmidt	std     r10,PACA_EXGEN+EX_DAR(r13)
1040b3e6b5dfSBenjamin Herrenschmidt	mfspr   r10,SPRN_HDSISR
1041b3e6b5dfSBenjamin Herrenschmidt	stw     r10,PACA_EXGEN+EX_DSISR(r13)
1042b3e6b5dfSBenjamin Herrenschmidt	EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN)
1043b1576fecSAnton Blanchard	bl      save_nvgprs
10449daf112bSMichael Ellerman	RECONCILE_IRQ_STATE(r10, r11)
1045b3e6b5dfSBenjamin Herrenschmidt	addi    r3,r1,STACK_FRAME_OVERHEAD
1046b1576fecSAnton Blanchard	bl      unknown_exception
1047b1576fecSAnton Blanchard	b       ret_from_except
1048b3e6b5dfSBenjamin Herrenschmidt
1049b3e6b5dfSBenjamin Herrenschmidt	.align	7
10500ebc4cdaSBenjamin Herrenschmidt	.globl instruction_access_common
10510ebc4cdaSBenjamin Herrenschmidtinstruction_access_common:
10520ebc4cdaSBenjamin Herrenschmidt	EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
10539daf112bSMichael Ellerman	RECONCILE_IRQ_STATE(r10, r11)
1054a546498fSBenjamin Herrenschmidt	ld	r12,_MSR(r1)
10550ebc4cdaSBenjamin Herrenschmidt	ld	r3,_NIP(r1)
10560ebc4cdaSBenjamin Herrenschmidt	andis.	r4,r12,0x5820
10570ebc4cdaSBenjamin Herrenschmidt	li	r5,0x400
1058b1576fecSAnton Blanchard	b	do_hash_page		/* Try to handle as hpte fault */
10590ebc4cdaSBenjamin Herrenschmidt
106035425501SAnton Blanchard	STD_EXCEPTION_COMMON(0xe20, h_instr_storage, unknown_exception)
1061b3e6b5dfSBenjamin Herrenschmidt
10620ebc4cdaSBenjamin Herrenschmidt/*
10630ebc4cdaSBenjamin Herrenschmidt * Here is the common SLB miss user that is used when going to virtual
10640ebc4cdaSBenjamin Herrenschmidt * mode for SLB misses, that is currently not used
10650ebc4cdaSBenjamin Herrenschmidt */
10660ebc4cdaSBenjamin Herrenschmidt#ifdef __DISABLED__
10670ebc4cdaSBenjamin Herrenschmidt	.align	7
10680ebc4cdaSBenjamin Herrenschmidt	.globl	slb_miss_user_common
10690ebc4cdaSBenjamin Herrenschmidtslb_miss_user_common:
10700ebc4cdaSBenjamin Herrenschmidt	mflr	r10
10710ebc4cdaSBenjamin Herrenschmidt	std	r3,PACA_EXGEN+EX_DAR(r13)
10720ebc4cdaSBenjamin Herrenschmidt	stw	r9,PACA_EXGEN+EX_CCR(r13)
10730ebc4cdaSBenjamin Herrenschmidt	std	r10,PACA_EXGEN+EX_LR(r13)
10740ebc4cdaSBenjamin Herrenschmidt	std	r11,PACA_EXGEN+EX_SRR0(r13)
1075b1576fecSAnton Blanchard	bl	slb_allocate_user
10760ebc4cdaSBenjamin Herrenschmidt
10770ebc4cdaSBenjamin Herrenschmidt	ld	r10,PACA_EXGEN+EX_LR(r13)
10780ebc4cdaSBenjamin Herrenschmidt	ld	r3,PACA_EXGEN+EX_R3(r13)
10790ebc4cdaSBenjamin Herrenschmidt	lwz	r9,PACA_EXGEN+EX_CCR(r13)
10800ebc4cdaSBenjamin Herrenschmidt	ld	r11,PACA_EXGEN+EX_SRR0(r13)
10810ebc4cdaSBenjamin Herrenschmidt	mtlr	r10
10820ebc4cdaSBenjamin Herrenschmidt	beq-	slb_miss_fault
10830ebc4cdaSBenjamin Herrenschmidt
10840ebc4cdaSBenjamin Herrenschmidt	andi.	r10,r12,MSR_RI		/* check for unrecoverable exception */
10850ebc4cdaSBenjamin Herrenschmidt	beq-	unrecov_user_slb
10860ebc4cdaSBenjamin Herrenschmidt	mfmsr	r10
10870ebc4cdaSBenjamin Herrenschmidt
10880ebc4cdaSBenjamin Herrenschmidt.machine push
10890ebc4cdaSBenjamin Herrenschmidt.machine "power4"
10900ebc4cdaSBenjamin Herrenschmidt	mtcrf	0x80,r9
10910ebc4cdaSBenjamin Herrenschmidt.machine pop
10920ebc4cdaSBenjamin Herrenschmidt
10930ebc4cdaSBenjamin Herrenschmidt	clrrdi	r10,r10,2		/* clear RI before setting SRR0/1 */
10940ebc4cdaSBenjamin Herrenschmidt	mtmsrd	r10,1
10950ebc4cdaSBenjamin Herrenschmidt
10960ebc4cdaSBenjamin Herrenschmidt	mtspr	SRR0,r11
10970ebc4cdaSBenjamin Herrenschmidt	mtspr	SRR1,r12
10980ebc4cdaSBenjamin Herrenschmidt
10990ebc4cdaSBenjamin Herrenschmidt	ld	r9,PACA_EXGEN+EX_R9(r13)
11000ebc4cdaSBenjamin Herrenschmidt	ld	r10,PACA_EXGEN+EX_R10(r13)
11010ebc4cdaSBenjamin Herrenschmidt	ld	r11,PACA_EXGEN+EX_R11(r13)
11020ebc4cdaSBenjamin Herrenschmidt	ld	r12,PACA_EXGEN+EX_R12(r13)
11030ebc4cdaSBenjamin Herrenschmidt	ld	r13,PACA_EXGEN+EX_R13(r13)
11040ebc4cdaSBenjamin Herrenschmidt	rfid
11050ebc4cdaSBenjamin Herrenschmidt	b	.
11060ebc4cdaSBenjamin Herrenschmidt
11070ebc4cdaSBenjamin Herrenschmidtslb_miss_fault:
11080ebc4cdaSBenjamin Herrenschmidt	EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
11090ebc4cdaSBenjamin Herrenschmidt	ld	r4,PACA_EXGEN+EX_DAR(r13)
11100ebc4cdaSBenjamin Herrenschmidt	li	r5,0
11110ebc4cdaSBenjamin Herrenschmidt	std	r4,_DAR(r1)
11120ebc4cdaSBenjamin Herrenschmidt	std	r5,_DSISR(r1)
11130ebc4cdaSBenjamin Herrenschmidt	b	handle_page_fault
11140ebc4cdaSBenjamin Herrenschmidt
11150ebc4cdaSBenjamin Herrenschmidtunrecov_user_slb:
11160ebc4cdaSBenjamin Herrenschmidt	EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
11179daf112bSMichael Ellerman	RECONCILE_IRQ_STATE(r10, r11)
1118b1576fecSAnton Blanchard	bl	save_nvgprs
11190ebc4cdaSBenjamin Herrenschmidt1:	addi	r3,r1,STACK_FRAME_OVERHEAD
1120b1576fecSAnton Blanchard	bl	unrecoverable_exception
11210ebc4cdaSBenjamin Herrenschmidt	b	1b
11220ebc4cdaSBenjamin Herrenschmidt
11230ebc4cdaSBenjamin Herrenschmidt#endif /* __DISABLED__ */
11240ebc4cdaSBenjamin Herrenschmidt
11250ebc4cdaSBenjamin Herrenschmidt
11264e243b79SMahesh Salgaonkar	/*
11274e243b79SMahesh Salgaonkar	 * Machine check is different because we use a different
11284e243b79SMahesh Salgaonkar	 * save area: PACA_EXMC instead of PACA_EXGEN.
11294e243b79SMahesh Salgaonkar	 */
11304e243b79SMahesh Salgaonkar	.align	7
11314e243b79SMahesh Salgaonkar	.globl machine_check_common
11324e243b79SMahesh Salgaonkarmachine_check_common:
11334e243b79SMahesh Salgaonkar
11344e243b79SMahesh Salgaonkar	mfspr	r10,SPRN_DAR
11354e243b79SMahesh Salgaonkar	std	r10,PACA_EXGEN+EX_DAR(r13)
11364e243b79SMahesh Salgaonkar	mfspr	r10,SPRN_DSISR
11374e243b79SMahesh Salgaonkar	stw	r10,PACA_EXGEN+EX_DSISR(r13)
11384e243b79SMahesh Salgaonkar	EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
11394e243b79SMahesh Salgaonkar	FINISH_NAP
11409daf112bSMichael Ellerman	RECONCILE_IRQ_STATE(r10, r11)
11414e243b79SMahesh Salgaonkar	ld	r3,PACA_EXGEN+EX_DAR(r13)
11424e243b79SMahesh Salgaonkar	lwz	r4,PACA_EXGEN+EX_DSISR(r13)
11434e243b79SMahesh Salgaonkar	std	r3,_DAR(r1)
11444e243b79SMahesh Salgaonkar	std	r4,_DSISR(r1)
1145b1576fecSAnton Blanchard	bl	save_nvgprs
11464e243b79SMahesh Salgaonkar	addi	r3,r1,STACK_FRAME_OVERHEAD
1147b1576fecSAnton Blanchard	bl	machine_check_exception
1148b1576fecSAnton Blanchard	b	ret_from_except
11494e243b79SMahesh Salgaonkar
11500ebc4cdaSBenjamin Herrenschmidt	.align	7
11510ebc4cdaSBenjamin Herrenschmidt	.globl alignment_common
11520ebc4cdaSBenjamin Herrenschmidtalignment_common:
11530ebc4cdaSBenjamin Herrenschmidt	mfspr	r10,SPRN_DAR
11540ebc4cdaSBenjamin Herrenschmidt	std	r10,PACA_EXGEN+EX_DAR(r13)
11550ebc4cdaSBenjamin Herrenschmidt	mfspr	r10,SPRN_DSISR
11560ebc4cdaSBenjamin Herrenschmidt	stw	r10,PACA_EXGEN+EX_DSISR(r13)
11570ebc4cdaSBenjamin Herrenschmidt	EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
11580ebc4cdaSBenjamin Herrenschmidt	ld	r3,PACA_EXGEN+EX_DAR(r13)
11590ebc4cdaSBenjamin Herrenschmidt	lwz	r4,PACA_EXGEN+EX_DSISR(r13)
11600ebc4cdaSBenjamin Herrenschmidt	std	r3,_DAR(r1)
11610ebc4cdaSBenjamin Herrenschmidt	std	r4,_DSISR(r1)
1162b1576fecSAnton Blanchard	bl	save_nvgprs
11639daf112bSMichael Ellerman	RECONCILE_IRQ_STATE(r10, r11)
11640ebc4cdaSBenjamin Herrenschmidt	addi	r3,r1,STACK_FRAME_OVERHEAD
1165b1576fecSAnton Blanchard	bl	alignment_exception
1166b1576fecSAnton Blanchard	b	ret_from_except
11670ebc4cdaSBenjamin Herrenschmidt
11680ebc4cdaSBenjamin Herrenschmidt	.align	7
11690ebc4cdaSBenjamin Herrenschmidt	.globl program_check_common
11700ebc4cdaSBenjamin Herrenschmidtprogram_check_common:
11710ebc4cdaSBenjamin Herrenschmidt	EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
1172b1576fecSAnton Blanchard	bl	save_nvgprs
11739daf112bSMichael Ellerman	RECONCILE_IRQ_STATE(r10, r11)
1174922b9f86SMichael Ellerman	addi	r3,r1,STACK_FRAME_OVERHEAD
1175b1576fecSAnton Blanchard	bl	program_check_exception
1176b1576fecSAnton Blanchard	b	ret_from_except
11770ebc4cdaSBenjamin Herrenschmidt
11780ebc4cdaSBenjamin Herrenschmidt	.align	7
11790ebc4cdaSBenjamin Herrenschmidt	.globl fp_unavailable_common
11800ebc4cdaSBenjamin Herrenschmidtfp_unavailable_common:
11810ebc4cdaSBenjamin Herrenschmidt	EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
11820ebc4cdaSBenjamin Herrenschmidt	bne	1f			/* if from user, just load it up */
1183b1576fecSAnton Blanchard	bl	save_nvgprs
11849daf112bSMichael Ellerman	RECONCILE_IRQ_STATE(r10, r11)
11850ebc4cdaSBenjamin Herrenschmidt	addi	r3,r1,STACK_FRAME_OVERHEAD
1186b1576fecSAnton Blanchard	bl	kernel_fp_unavailable_exception
11870ebc4cdaSBenjamin Herrenschmidt	BUG_OPCODE
1188bc2a9408SMichael Neuling1:
1189bc2a9408SMichael Neuling#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1190bc2a9408SMichael NeulingBEGIN_FTR_SECTION
1191bc2a9408SMichael Neuling	/* Test if 2 TM state bits are zero.  If non-zero (ie. userspace was in
1192bc2a9408SMichael Neuling	 * transaction), go do TM stuff
1193bc2a9408SMichael Neuling	 */
1194bc2a9408SMichael Neuling	rldicl.	r0, r12, (64-MSR_TS_LG), (64-2)
1195bc2a9408SMichael Neuling	bne-	2f
1196bc2a9408SMichael NeulingEND_FTR_SECTION_IFSET(CPU_FTR_TM)
1197bc2a9408SMichael Neuling#endif
1198b1576fecSAnton Blanchard	bl	load_up_fpu
11990ebc4cdaSBenjamin Herrenschmidt	b	fast_exception_return
1200bc2a9408SMichael Neuling#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1201bc2a9408SMichael Neuling2:	/* User process was in a transaction */
1202b1576fecSAnton Blanchard	bl	save_nvgprs
12039daf112bSMichael Ellerman	RECONCILE_IRQ_STATE(r10, r11)
1204bc2a9408SMichael Neuling	addi	r3,r1,STACK_FRAME_OVERHEAD
1205b1576fecSAnton Blanchard	bl	fp_unavailable_tm
1206b1576fecSAnton Blanchard	b	ret_from_except
1207bc2a9408SMichael Neuling#endif
12080ebc4cdaSBenjamin Herrenschmidt	.align	7
12090ebc4cdaSBenjamin Herrenschmidt	.globl altivec_unavailable_common
12100ebc4cdaSBenjamin Herrenschmidtaltivec_unavailable_common:
12110ebc4cdaSBenjamin Herrenschmidt	EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
12120ebc4cdaSBenjamin Herrenschmidt#ifdef CONFIG_ALTIVEC
12130ebc4cdaSBenjamin HerrenschmidtBEGIN_FTR_SECTION
12140ebc4cdaSBenjamin Herrenschmidt	beq	1f
1215bc2a9408SMichael Neuling#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1216bc2a9408SMichael Neuling  BEGIN_FTR_SECTION_NESTED(69)
1217bc2a9408SMichael Neuling	/* Test if 2 TM state bits are zero.  If non-zero (ie. userspace was in
1218bc2a9408SMichael Neuling	 * transaction), go do TM stuff
1219bc2a9408SMichael Neuling	 */
1220bc2a9408SMichael Neuling	rldicl.	r0, r12, (64-MSR_TS_LG), (64-2)
1221bc2a9408SMichael Neuling	bne-	2f
1222bc2a9408SMichael Neuling  END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69)
1223bc2a9408SMichael Neuling#endif
1224b1576fecSAnton Blanchard	bl	load_up_altivec
12250ebc4cdaSBenjamin Herrenschmidt	b	fast_exception_return
1226bc2a9408SMichael Neuling#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1227bc2a9408SMichael Neuling2:	/* User process was in a transaction */
1228b1576fecSAnton Blanchard	bl	save_nvgprs
12299daf112bSMichael Ellerman	RECONCILE_IRQ_STATE(r10, r11)
1230bc2a9408SMichael Neuling	addi	r3,r1,STACK_FRAME_OVERHEAD
1231b1576fecSAnton Blanchard	bl	altivec_unavailable_tm
1232b1576fecSAnton Blanchard	b	ret_from_except
1233bc2a9408SMichael Neuling#endif
12340ebc4cdaSBenjamin Herrenschmidt1:
12350ebc4cdaSBenjamin HerrenschmidtEND_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
12360ebc4cdaSBenjamin Herrenschmidt#endif
1237b1576fecSAnton Blanchard	bl	save_nvgprs
12389daf112bSMichael Ellerman	RECONCILE_IRQ_STATE(r10, r11)
12390ebc4cdaSBenjamin Herrenschmidt	addi	r3,r1,STACK_FRAME_OVERHEAD
1240b1576fecSAnton Blanchard	bl	altivec_unavailable_exception
1241b1576fecSAnton Blanchard	b	ret_from_except
12420ebc4cdaSBenjamin Herrenschmidt
12430ebc4cdaSBenjamin Herrenschmidt	.align	7
12440ebc4cdaSBenjamin Herrenschmidt	.globl vsx_unavailable_common
12450ebc4cdaSBenjamin Herrenschmidtvsx_unavailable_common:
12460ebc4cdaSBenjamin Herrenschmidt	EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN)
12470ebc4cdaSBenjamin Herrenschmidt#ifdef CONFIG_VSX
12480ebc4cdaSBenjamin HerrenschmidtBEGIN_FTR_SECTION
12497230c564SBenjamin Herrenschmidt	beq	1f
1250bc2a9408SMichael Neuling#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1251bc2a9408SMichael Neuling  BEGIN_FTR_SECTION_NESTED(69)
1252bc2a9408SMichael Neuling	/* Test if 2 TM state bits are zero.  If non-zero (ie. userspace was in
1253bc2a9408SMichael Neuling	 * transaction), go do TM stuff
1254bc2a9408SMichael Neuling	 */
1255bc2a9408SMichael Neuling	rldicl.	r0, r12, (64-MSR_TS_LG), (64-2)
1256bc2a9408SMichael Neuling	bne-	2f
1257bc2a9408SMichael Neuling  END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69)
1258bc2a9408SMichael Neuling#endif
1259b1576fecSAnton Blanchard	b	load_up_vsx
1260bc2a9408SMichael Neuling#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1261bc2a9408SMichael Neuling2:	/* User process was in a transaction */
1262b1576fecSAnton Blanchard	bl	save_nvgprs
12639daf112bSMichael Ellerman	RECONCILE_IRQ_STATE(r10, r11)
1264bc2a9408SMichael Neuling	addi	r3,r1,STACK_FRAME_OVERHEAD
1265b1576fecSAnton Blanchard	bl	vsx_unavailable_tm
1266b1576fecSAnton Blanchard	b	ret_from_except
1267bc2a9408SMichael Neuling#endif
12680ebc4cdaSBenjamin Herrenschmidt1:
12690ebc4cdaSBenjamin HerrenschmidtEND_FTR_SECTION_IFSET(CPU_FTR_VSX)
12700ebc4cdaSBenjamin Herrenschmidt#endif
1271b1576fecSAnton Blanchard	bl	save_nvgprs
12729daf112bSMichael Ellerman	RECONCILE_IRQ_STATE(r10, r11)
12730ebc4cdaSBenjamin Herrenschmidt	addi	r3,r1,STACK_FRAME_OVERHEAD
1274b1576fecSAnton Blanchard	bl	vsx_unavailable_exception
1275b1576fecSAnton Blanchard	b	ret_from_except
12760ebc4cdaSBenjamin Herrenschmidt
127735425501SAnton Blanchard	STD_EXCEPTION_COMMON(0xf60, facility_unavailable, facility_unavailable_exception)
127835425501SAnton Blanchard	STD_EXCEPTION_COMMON(0xf80, hv_facility_unavailable, facility_unavailable_exception)
1279d0c0c9a1SMichael Neuling
1280d0c0c9a1SMichael Neuling	.align	7
12810ebc4cdaSBenjamin Herrenschmidt	.globl	__end_handlers
12820ebc4cdaSBenjamin Herrenschmidt__end_handlers:
12830ebc4cdaSBenjamin Herrenschmidt
128461383407SBenjamin Herrenschmidt	/* Equivalents to the above handlers for relocation-on interrupt vectors */
12851707dd16SPaul Mackerras	STD_RELON_EXCEPTION_HV_OOL(0xe40, emulation_assist)
12861707dd16SPaul Mackerras	MASKABLE_RELON_EXCEPTION_HV_OOL(0xe80, h_doorbell)
128761383407SBenjamin Herrenschmidt
12881707dd16SPaul Mackerras	STD_RELON_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor)
12891707dd16SPaul Mackerras	STD_RELON_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable)
12901707dd16SPaul Mackerras	STD_RELON_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable)
1291021424a1SMichael Ellerman	STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable)
129288f09412SMichael Neuling	STD_RELON_EXCEPTION_HV_OOL(0xf80, hv_facility_unavailable)
129361383407SBenjamin Herrenschmidt
129461383407SBenjamin Herrenschmidt#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
129561383407SBenjamin Herrenschmidt/*
129661383407SBenjamin Herrenschmidt * Data area reserved for FWNMI option.
129761383407SBenjamin Herrenschmidt * This address (0x7000) is fixed by the RPA.
129861383407SBenjamin Herrenschmidt */
129961383407SBenjamin Herrenschmidt	.= 0x7000
130061383407SBenjamin Herrenschmidt	.globl fwnmi_data_area
130161383407SBenjamin Herrenschmidtfwnmi_data_area:
130261383407SBenjamin Herrenschmidt
130361383407SBenjamin Herrenschmidt	/* pseries and powernv need to keep the whole page from
130461383407SBenjamin Herrenschmidt	 * 0x7000 to 0x8000 free for use by the firmware
130561383407SBenjamin Herrenschmidt	 */
130661383407SBenjamin Herrenschmidt	. = 0x8000
130761383407SBenjamin Herrenschmidt#endif /* defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
130861383407SBenjamin Herrenschmidt
130961383407SBenjamin Herrenschmidt#ifdef CONFIG_PPC_POWERNV
131061383407SBenjamin Herrenschmidt_GLOBAL(opal_mc_secondary_handler)
131161383407SBenjamin Herrenschmidt	HMT_MEDIUM_PPR_DISCARD
131261383407SBenjamin Herrenschmidt	SET_SCRATCH0(r13)
131361383407SBenjamin Herrenschmidt	GET_PACA(r13)
131461383407SBenjamin Herrenschmidt	clrldi	r3,r3,2
131561383407SBenjamin Herrenschmidt	tovirt(r3,r3)
131661383407SBenjamin Herrenschmidt	std	r3,PACA_OPAL_MC_EVT(r13)
131761383407SBenjamin Herrenschmidt	ld	r13,OPAL_MC_SRR0(r3)
131861383407SBenjamin Herrenschmidt	mtspr	SPRN_SRR0,r13
131961383407SBenjamin Herrenschmidt	ld	r13,OPAL_MC_SRR1(r3)
132061383407SBenjamin Herrenschmidt	mtspr	SPRN_SRR1,r13
132161383407SBenjamin Herrenschmidt	ld	r3,OPAL_MC_GPR3(r3)
132261383407SBenjamin Herrenschmidt	GET_SCRATCH0(r13)
132361383407SBenjamin Herrenschmidt	b	machine_check_pSeries
132461383407SBenjamin Herrenschmidt#endif /* CONFIG_PPC_POWERNV */
132561383407SBenjamin Herrenschmidt
132661383407SBenjamin Herrenschmidt
13274e243b79SMahesh Salgaonkar#define MACHINE_CHECK_HANDLER_WINDUP			\
13284e243b79SMahesh Salgaonkar	/* Clear MSR_RI before setting SRR0 and SRR1. */\
13294e243b79SMahesh Salgaonkar	li	r0,MSR_RI;				\
13304e243b79SMahesh Salgaonkar	mfmsr	r9;		/* get MSR value */	\
13314e243b79SMahesh Salgaonkar	andc	r9,r9,r0;				\
13324e243b79SMahesh Salgaonkar	mtmsrd	r9,1;		/* Clear MSR_RI */	\
13334e243b79SMahesh Salgaonkar	/* Move original SRR0 and SRR1 into the respective regs */	\
13344e243b79SMahesh Salgaonkar	ld	r9,_MSR(r1);				\
13354e243b79SMahesh Salgaonkar	mtspr	SPRN_SRR1,r9;				\
13364e243b79SMahesh Salgaonkar	ld	r3,_NIP(r1);				\
13374e243b79SMahesh Salgaonkar	mtspr	SPRN_SRR0,r3;				\
13384e243b79SMahesh Salgaonkar	ld	r9,_CTR(r1);				\
13394e243b79SMahesh Salgaonkar	mtctr	r9;					\
13404e243b79SMahesh Salgaonkar	ld	r9,_XER(r1);				\
13414e243b79SMahesh Salgaonkar	mtxer	r9;					\
13424e243b79SMahesh Salgaonkar	ld	r9,_LINK(r1);				\
13434e243b79SMahesh Salgaonkar	mtlr	r9;					\
13444e243b79SMahesh Salgaonkar	REST_GPR(0, r1);				\
13454e243b79SMahesh Salgaonkar	REST_8GPRS(2, r1);				\
13464e243b79SMahesh Salgaonkar	REST_GPR(10, r1);				\
13474e243b79SMahesh Salgaonkar	ld	r11,_CCR(r1);				\
13484e243b79SMahesh Salgaonkar	mtcr	r11;					\
13494e243b79SMahesh Salgaonkar	/* Decrement paca->in_mce. */			\
13504e243b79SMahesh Salgaonkar	lhz	r12,PACA_IN_MCE(r13);			\
13514e243b79SMahesh Salgaonkar	subi	r12,r12,1;				\
13524e243b79SMahesh Salgaonkar	sth	r12,PACA_IN_MCE(r13);			\
13534e243b79SMahesh Salgaonkar	REST_GPR(11, r1);				\
13544e243b79SMahesh Salgaonkar	REST_2GPRS(12, r1);				\
13554e243b79SMahesh Salgaonkar	/* restore original r1. */			\
13564e243b79SMahesh Salgaonkar	ld	r1,GPR1(r1)
13574e243b79SMahesh Salgaonkar
13584e243b79SMahesh Salgaonkar	/*
13594e243b79SMahesh Salgaonkar	 * Handle machine check early in real mode. We come here with
13604e243b79SMahesh Salgaonkar	 * ME=1, MMU (IR=0 and DR=0) off and using MC emergency stack.
13614e243b79SMahesh Salgaonkar	 */
13624e243b79SMahesh Salgaonkar	.align	7
13634e243b79SMahesh Salgaonkar	.globl machine_check_handle_early
13644e243b79SMahesh Salgaonkarmachine_check_handle_early:
13654e243b79SMahesh Salgaonkar	std	r0,GPR0(r1)	/* Save r0 */
13664e243b79SMahesh Salgaonkar	EXCEPTION_PROLOG_COMMON_3(0x200)
1367b1576fecSAnton Blanchard	bl	save_nvgprs
13684e243b79SMahesh Salgaonkar	addi	r3,r1,STACK_FRAME_OVERHEAD
1369b1576fecSAnton Blanchard	bl	machine_check_early
13702749a2f2SMahesh Salgaonkar	std	r3,RESULT(r1)	/* Save result */
13714e243b79SMahesh Salgaonkar	ld	r12,_MSR(r1)
13724e243b79SMahesh Salgaonkar#ifdef	CONFIG_PPC_P7_NAP
13734e243b79SMahesh Salgaonkar	/*
13744e243b79SMahesh Salgaonkar	 * Check if thread was in power saving mode. We come here when any
13754e243b79SMahesh Salgaonkar	 * of the following is true:
13764e243b79SMahesh Salgaonkar	 * a. thread wasn't in power saving mode
13774e243b79SMahesh Salgaonkar	 * b. thread was in power saving mode with no state loss or
13784e243b79SMahesh Salgaonkar	 *    supervisor state loss
13794e243b79SMahesh Salgaonkar	 *
13804e243b79SMahesh Salgaonkar	 * Go back to nap again if (b) is true.
13814e243b79SMahesh Salgaonkar	 */
13824e243b79SMahesh Salgaonkar	rlwinm.	r11,r12,47-31,30,31	/* Was it in power saving mode? */
13834e243b79SMahesh Salgaonkar	beq	4f			/* No, it wasn;t */
13844e243b79SMahesh Salgaonkar	/* Thread was in power saving mode. Go back to nap again. */
13854e243b79SMahesh Salgaonkar	cmpwi	r11,2
13864e243b79SMahesh Salgaonkar	bne	3f
13874e243b79SMahesh Salgaonkar	/* Supervisor state loss */
13884e243b79SMahesh Salgaonkar	li	r0,1
13894e243b79SMahesh Salgaonkar	stb	r0,PACA_NAPSTATELOST(r13)
1390b1576fecSAnton Blanchard3:	bl	machine_check_queue_event
13914e243b79SMahesh Salgaonkar	MACHINE_CHECK_HANDLER_WINDUP
13924e243b79SMahesh Salgaonkar	GET_PACA(r13)
13934e243b79SMahesh Salgaonkar	ld	r1,PACAR1(r13)
1394b1576fecSAnton Blanchard	b	power7_enter_nap_mode
13954e243b79SMahesh Salgaonkar4:
13964e243b79SMahesh Salgaonkar#endif
13974e243b79SMahesh Salgaonkar	/*
13984e243b79SMahesh Salgaonkar	 * Check if we are coming from hypervisor userspace. If yes then we
13994e243b79SMahesh Salgaonkar	 * continue in host kernel in V mode to deliver the MC event.
14004e243b79SMahesh Salgaonkar	 */
14014e243b79SMahesh Salgaonkar	rldicl.	r11,r12,4,63		/* See if MC hit while in HV mode. */
14024e243b79SMahesh Salgaonkar	beq	5f
14034e243b79SMahesh Salgaonkar	andi.	r11,r12,MSR_PR		/* See if coming from user. */
14044e243b79SMahesh Salgaonkar	bne	9f			/* continue in V mode if we are. */
14054e243b79SMahesh Salgaonkar
14064e243b79SMahesh Salgaonkar5:
14074e243b79SMahesh Salgaonkar#ifdef CONFIG_KVM_BOOK3S_64_HV
14084e243b79SMahesh Salgaonkar	/*
14094e243b79SMahesh Salgaonkar	 * We are coming from kernel context. Check if we are coming from
14104e243b79SMahesh Salgaonkar	 * guest. if yes, then we can continue. We will fall through
14114e243b79SMahesh Salgaonkar	 * do_kvm_200->kvmppc_interrupt to deliver the MC event to guest.
14124e243b79SMahesh Salgaonkar	 */
14134e243b79SMahesh Salgaonkar	lbz	r11,HSTATE_IN_GUEST(r13)
14144e243b79SMahesh Salgaonkar	cmpwi	r11,0			/* Check if coming from guest */
14154e243b79SMahesh Salgaonkar	bne	9f			/* continue if we are. */
14164e243b79SMahesh Salgaonkar#endif
14174e243b79SMahesh Salgaonkar	/*
14184e243b79SMahesh Salgaonkar	 * At this point we are not sure about what context we come from.
14194e243b79SMahesh Salgaonkar	 * Queue up the MCE event and return from the interrupt.
14204e243b79SMahesh Salgaonkar	 * But before that, check if this is an un-recoverable exception.
14214e243b79SMahesh Salgaonkar	 * If yes, then stay on emergency stack and panic.
14224e243b79SMahesh Salgaonkar	 */
14234e243b79SMahesh Salgaonkar	andi.	r11,r12,MSR_RI
14244e243b79SMahesh Salgaonkar	bne	2f
14252749a2f2SMahesh Salgaonkar1:	mfspr	r11,SPRN_SRR0
14262749a2f2SMahesh Salgaonkar	ld	r10,PACAKBASE(r13)
14272749a2f2SMahesh Salgaonkar	LOAD_HANDLER(r10,unrecover_mce)
14282749a2f2SMahesh Salgaonkar	mtspr	SPRN_SRR0,r10
14292749a2f2SMahesh Salgaonkar	ld	r10,PACAKMSR(r13)
14302749a2f2SMahesh Salgaonkar	/*
14312749a2f2SMahesh Salgaonkar	 * We are going down. But there are chances that we might get hit by
14322749a2f2SMahesh Salgaonkar	 * another MCE during panic path and we may run into unstable state
14332749a2f2SMahesh Salgaonkar	 * with no way out. Hence, turn ME bit off while going down, so that
14342749a2f2SMahesh Salgaonkar	 * when another MCE is hit during panic path, system will checkstop
14352749a2f2SMahesh Salgaonkar	 * and hypervisor will get restarted cleanly by SP.
14362749a2f2SMahesh Salgaonkar	 */
14372749a2f2SMahesh Salgaonkar	li	r3,MSR_ME
14382749a2f2SMahesh Salgaonkar	andc	r10,r10,r3		/* Turn off MSR_ME */
14392749a2f2SMahesh Salgaonkar	mtspr	SPRN_SRR1,r10
14402749a2f2SMahesh Salgaonkar	rfid
14412749a2f2SMahesh Salgaonkar	b	.
14424e243b79SMahesh Salgaonkar2:
14434e243b79SMahesh Salgaonkar	/*
14442749a2f2SMahesh Salgaonkar	 * Check if we have successfully handled/recovered from error, if not
14452749a2f2SMahesh Salgaonkar	 * then stay on emergency stack and panic.
14462749a2f2SMahesh Salgaonkar	 */
14472749a2f2SMahesh Salgaonkar	ld	r3,RESULT(r1)	/* Load result */
14482749a2f2SMahesh Salgaonkar	cmpdi	r3,0		/* see if we handled MCE successfully */
14492749a2f2SMahesh Salgaonkar
14502749a2f2SMahesh Salgaonkar	beq	1b		/* if !handled then panic */
14512749a2f2SMahesh Salgaonkar	/*
14524e243b79SMahesh Salgaonkar	 * Return from MC interrupt.
14534e243b79SMahesh Salgaonkar	 * Queue up the MCE event so that we can log it later, while
14544e243b79SMahesh Salgaonkar	 * returning from kernel or opal call.
14554e243b79SMahesh Salgaonkar	 */
1456b1576fecSAnton Blanchard	bl	machine_check_queue_event
14574e243b79SMahesh Salgaonkar	MACHINE_CHECK_HANDLER_WINDUP
14584e243b79SMahesh Salgaonkar	rfid
14594e243b79SMahesh Salgaonkar9:
14604e243b79SMahesh Salgaonkar	/* Deliver the machine check to host kernel in V mode. */
14614e243b79SMahesh Salgaonkar	MACHINE_CHECK_HANDLER_WINDUP
14624e243b79SMahesh Salgaonkar	b	machine_check_pSeries
14634e243b79SMahesh Salgaonkar
14642749a2f2SMahesh Salgaonkarunrecover_mce:
14652749a2f2SMahesh Salgaonkar	/* Invoke machine_check_exception to print MCE event and panic. */
14662749a2f2SMahesh Salgaonkar	addi	r3,r1,STACK_FRAME_OVERHEAD
1467ad718622SAnton Blanchard	bl	machine_check_exception
14682749a2f2SMahesh Salgaonkar	/*
14692749a2f2SMahesh Salgaonkar	 * We will not reach here. Even if we did, there is no way out. Call
14702749a2f2SMahesh Salgaonkar	 * unrecoverable_exception and die.
14712749a2f2SMahesh Salgaonkar	 */
14722749a2f2SMahesh Salgaonkar1:	addi	r3,r1,STACK_FRAME_OVERHEAD
1473ad718622SAnton Blanchard	bl	unrecoverable_exception
14742749a2f2SMahesh Salgaonkar	b	1b
14750ebc4cdaSBenjamin Herrenschmidt/*
1476087aa036SChen Gang * r13 points to the PACA, r9 contains the saved CR,
1477087aa036SChen Gang * r12 contain the saved SRR1, SRR0 is still ready for return
1478087aa036SChen Gang * r3 has the faulting address
1479087aa036SChen Gang * r9 - r13 are saved in paca->exslb.
1480087aa036SChen Gang * r3 is saved in paca->slb_r3
1481087aa036SChen Gang * We assume we aren't going to take any exceptions during this procedure.
1482087aa036SChen Gang */
1483ad0289e4SAnton Blanchardslb_miss_realmode:
1484087aa036SChen Gang	mflr	r10
1485087aa036SChen Gang#ifdef CONFIG_RELOCATABLE
1486087aa036SChen Gang	mtctr	r11
1487087aa036SChen Gang#endif
1488087aa036SChen Gang
1489087aa036SChen Gang	stw	r9,PACA_EXSLB+EX_CCR(r13)	/* save CR in exc. frame */
1490087aa036SChen Gang	std	r10,PACA_EXSLB+EX_LR(r13)	/* save LR */
1491087aa036SChen Gang
1492b1576fecSAnton Blanchard	bl	slb_allocate_realmode
1493087aa036SChen Gang
1494087aa036SChen Gang	/* All done -- return from exception. */
1495087aa036SChen Gang
1496087aa036SChen Gang	ld	r10,PACA_EXSLB+EX_LR(r13)
1497087aa036SChen Gang	ld	r3,PACA_EXSLB+EX_R3(r13)
1498087aa036SChen Gang	lwz	r9,PACA_EXSLB+EX_CCR(r13)	/* get saved CR */
1499087aa036SChen Gang
1500087aa036SChen Gang	mtlr	r10
1501087aa036SChen Gang
1502087aa036SChen Gang	andi.	r10,r12,MSR_RI	/* check for unrecoverable exception */
1503087aa036SChen Gang	beq-	2f
1504087aa036SChen Gang
1505087aa036SChen Gang.machine	push
1506087aa036SChen Gang.machine	"power4"
1507087aa036SChen Gang	mtcrf	0x80,r9
1508087aa036SChen Gang	mtcrf	0x01,r9		/* slb_allocate uses cr0 and cr7 */
1509087aa036SChen Gang.machine	pop
1510087aa036SChen Gang
1511087aa036SChen Gang	RESTORE_PPR_PACA(PACA_EXSLB, r9)
1512087aa036SChen Gang	ld	r9,PACA_EXSLB+EX_R9(r13)
1513087aa036SChen Gang	ld	r10,PACA_EXSLB+EX_R10(r13)
1514087aa036SChen Gang	ld	r11,PACA_EXSLB+EX_R11(r13)
1515087aa036SChen Gang	ld	r12,PACA_EXSLB+EX_R12(r13)
1516087aa036SChen Gang	ld	r13,PACA_EXSLB+EX_R13(r13)
1517087aa036SChen Gang	rfid
1518087aa036SChen Gang	b	.	/* prevent speculative execution */
1519087aa036SChen Gang
1520087aa036SChen Gang2:	mfspr	r11,SPRN_SRR0
1521087aa036SChen Gang	ld	r10,PACAKBASE(r13)
1522087aa036SChen Gang	LOAD_HANDLER(r10,unrecov_slb)
1523087aa036SChen Gang	mtspr	SPRN_SRR0,r10
1524087aa036SChen Gang	ld	r10,PACAKMSR(r13)
1525087aa036SChen Gang	mtspr	SPRN_SRR1,r10
1526087aa036SChen Gang	rfid
1527087aa036SChen Gang	b	.
1528087aa036SChen Gang
1529087aa036SChen Gangunrecov_slb:
1530087aa036SChen Gang	EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
15319daf112bSMichael Ellerman	RECONCILE_IRQ_STATE(r10, r11)
1532b1576fecSAnton Blanchard	bl	save_nvgprs
1533087aa036SChen Gang1:	addi	r3,r1,STACK_FRAME_OVERHEAD
1534b1576fecSAnton Blanchard	bl	unrecoverable_exception
1535087aa036SChen Gang	b	1b
1536087aa036SChen Gang
1537087aa036SChen Gang
1538087aa036SChen Gang#ifdef CONFIG_PPC_970_NAP
1539087aa036SChen Gangpower4_fixup_nap:
1540087aa036SChen Gang	andc	r9,r9,r10
1541087aa036SChen Gang	std	r9,TI_LOCAL_FLAGS(r11)
1542087aa036SChen Gang	ld	r10,_LINK(r1)		/* make idle task do the */
1543087aa036SChen Gang	std	r10,_NIP(r1)		/* equivalent of a blr */
1544087aa036SChen Gang	blr
1545087aa036SChen Gang#endif
1546087aa036SChen Gang
1547087aa036SChen Gang/*
15480ebc4cdaSBenjamin Herrenschmidt * Hash table stuff
15490ebc4cdaSBenjamin Herrenschmidt */
15500ebc4cdaSBenjamin Herrenschmidt	.align	7
15516a3bab90SAnton Blancharddo_hash_page:
15520ebc4cdaSBenjamin Herrenschmidt	std	r3,_DAR(r1)
15530ebc4cdaSBenjamin Herrenschmidt	std	r4,_DSISR(r1)
15540ebc4cdaSBenjamin Herrenschmidt
15559c7cc234SK.Prasad	andis.	r0,r4,0xa410		/* weird error? */
15560ebc4cdaSBenjamin Herrenschmidt	bne-	handle_page_fault	/* if not, try to insert a HPTE */
15579c7cc234SK.Prasad	andis.  r0,r4,DSISR_DABRMATCH@h
15589c7cc234SK.Prasad	bne-    handle_dabr_fault
15599778b696SStuart Yoder	CURRENT_THREAD_INFO(r11, r1)
15609c1e1052SPaul Mackerras	lwz	r0,TI_PREEMPT(r11)	/* If we're in an "NMI" */
15619c1e1052SPaul Mackerras	andis.	r0,r0,NMI_MASK@h	/* (i.e. an irq when soft-disabled) */
15629c1e1052SPaul Mackerras	bne	77f			/* then don't call hash_page now */
15630ebc4cdaSBenjamin Herrenschmidt	/*
15640ebc4cdaSBenjamin Herrenschmidt	 * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
15650ebc4cdaSBenjamin Herrenschmidt	 * accessing a userspace segment (even from the kernel). We assume
15660ebc4cdaSBenjamin Herrenschmidt	 * kernel addresses always have the high bit set.
15670ebc4cdaSBenjamin Herrenschmidt	 */
15680ebc4cdaSBenjamin Herrenschmidt	rlwinm	r4,r4,32-25+9,31-9,31-9	/* DSISR_STORE -> _PAGE_RW */
15690ebc4cdaSBenjamin Herrenschmidt	rotldi	r0,r3,15		/* Move high bit into MSR_PR posn */
15700ebc4cdaSBenjamin Herrenschmidt	orc	r0,r12,r0		/* MSR_PR | ~high_bit */
15710ebc4cdaSBenjamin Herrenschmidt	rlwimi	r4,r0,32-13,30,30	/* becomes _PAGE_USER access bit */
15720ebc4cdaSBenjamin Herrenschmidt	ori	r4,r4,1			/* add _PAGE_PRESENT */
15730ebc4cdaSBenjamin Herrenschmidt	rlwimi	r4,r5,22+2,31-2,31-2	/* Set _PAGE_EXEC if trap is 0x400 */
15740ebc4cdaSBenjamin Herrenschmidt
15750ebc4cdaSBenjamin Herrenschmidt	/*
15760ebc4cdaSBenjamin Herrenschmidt	 * r3 contains the faulting address
15770ebc4cdaSBenjamin Herrenschmidt	 * r4 contains the required access permissions
15780ebc4cdaSBenjamin Herrenschmidt	 * r5 contains the trap number
15790ebc4cdaSBenjamin Herrenschmidt	 *
15807230c564SBenjamin Herrenschmidt	 * at return r3 = 0 for success, 1 for page fault, negative for error
15810ebc4cdaSBenjamin Herrenschmidt	 */
1582b1576fecSAnton Blanchard	bl	hash_page		/* build HPTE if possible */
15830ebc4cdaSBenjamin Herrenschmidt	cmpdi	r3,0			/* see if hash_page succeeded */
15840ebc4cdaSBenjamin Herrenschmidt
15857230c564SBenjamin Herrenschmidt	/* Success */
15860ebc4cdaSBenjamin Herrenschmidt	beq	fast_exc_return_irq	/* Return from exception on success */
15870ebc4cdaSBenjamin Herrenschmidt
15887230c564SBenjamin Herrenschmidt	/* Error */
15897230c564SBenjamin Herrenschmidt	blt-	13f
15900ebc4cdaSBenjamin Herrenschmidt
1591a546498fSBenjamin Herrenschmidt/* Here we have a page fault that hash_page can't handle. */
1592a546498fSBenjamin Herrenschmidthandle_page_fault:
1593a546498fSBenjamin Herrenschmidt11:	ld	r4,_DAR(r1)
1594a546498fSBenjamin Herrenschmidt	ld	r5,_DSISR(r1)
1595a546498fSBenjamin Herrenschmidt	addi	r3,r1,STACK_FRAME_OVERHEAD
1596b1576fecSAnton Blanchard	bl	do_page_fault
1597a546498fSBenjamin Herrenschmidt	cmpdi	r3,0
1598a546498fSBenjamin Herrenschmidt	beq+	12f
1599b1576fecSAnton Blanchard	bl	save_nvgprs
1600a546498fSBenjamin Herrenschmidt	mr	r5,r3
1601a546498fSBenjamin Herrenschmidt	addi	r3,r1,STACK_FRAME_OVERHEAD
1602a546498fSBenjamin Herrenschmidt	lwz	r4,_DAR(r1)
1603b1576fecSAnton Blanchard	bl	bad_page_fault
1604b1576fecSAnton Blanchard	b	ret_from_except
16050ebc4cdaSBenjamin Herrenschmidt
16069c7cc234SK.Prasad/* We have a data breakpoint exception - handle it */
16079c7cc234SK.Prasadhandle_dabr_fault:
1608b1576fecSAnton Blanchard	bl	save_nvgprs
16099c7cc234SK.Prasad	ld      r4,_DAR(r1)
16109c7cc234SK.Prasad	ld      r5,_DSISR(r1)
16119c7cc234SK.Prasad	addi    r3,r1,STACK_FRAME_OVERHEAD
1612b1576fecSAnton Blanchard	bl      do_break
1613b1576fecSAnton Blanchard12:	b       ret_from_except_lite
16149c7cc234SK.Prasad
16150ebc4cdaSBenjamin Herrenschmidt
16160ebc4cdaSBenjamin Herrenschmidt/* We have a page fault that hash_page could handle but HV refused
16170ebc4cdaSBenjamin Herrenschmidt * the PTE insertion
16180ebc4cdaSBenjamin Herrenschmidt */
1619b1576fecSAnton Blanchard13:	bl	save_nvgprs
16200ebc4cdaSBenjamin Herrenschmidt	mr	r5,r3
16210ebc4cdaSBenjamin Herrenschmidt	addi	r3,r1,STACK_FRAME_OVERHEAD
16220ebc4cdaSBenjamin Herrenschmidt	ld	r4,_DAR(r1)
1623b1576fecSAnton Blanchard	bl	low_hash_fault
1624b1576fecSAnton Blanchard	b	ret_from_except
16250ebc4cdaSBenjamin Herrenschmidt
16269c1e1052SPaul Mackerras/*
16279c1e1052SPaul Mackerras * We come here as a result of a DSI at a point where we don't want
16289c1e1052SPaul Mackerras * to call hash_page, such as when we are accessing memory (possibly
16299c1e1052SPaul Mackerras * user memory) inside a PMU interrupt that occurred while interrupts
16309c1e1052SPaul Mackerras * were soft-disabled.  We want to invoke the exception handler for
16319c1e1052SPaul Mackerras * the access, or panic if there isn't a handler.
16329c1e1052SPaul Mackerras */
1633b1576fecSAnton Blanchard77:	bl	save_nvgprs
16349c1e1052SPaul Mackerras	mr	r4,r3
16359c1e1052SPaul Mackerras	addi	r3,r1,STACK_FRAME_OVERHEAD
16369c1e1052SPaul Mackerras	li	r5,SIGSEGV
1637b1576fecSAnton Blanchard	bl	bad_page_fault
1638b1576fecSAnton Blanchard	b	ret_from_except
16394e2bf01bSMichael Ellerman
16404e2bf01bSMichael Ellerman/*
16414e2bf01bSMichael Ellerman * Here we have detected that the kernel stack pointer is bad.
16424e2bf01bSMichael Ellerman * R9 contains the saved CR, r13 points to the paca,
16434e2bf01bSMichael Ellerman * r10 contains the (bad) kernel stack pointer,
16444e2bf01bSMichael Ellerman * r11 and r12 contain the saved SRR0 and SRR1.
16454e2bf01bSMichael Ellerman * We switch to using an emergency stack, save the registers there,
16464e2bf01bSMichael Ellerman * and call kernel_bad_stack(), which panics.
16474e2bf01bSMichael Ellerman */
16484e2bf01bSMichael Ellermanbad_stack:
16494e2bf01bSMichael Ellerman	ld	r1,PACAEMERGSP(r13)
16504e2bf01bSMichael Ellerman	subi	r1,r1,64+INT_FRAME_SIZE
16514e2bf01bSMichael Ellerman	std	r9,_CCR(r1)
16524e2bf01bSMichael Ellerman	std	r10,GPR1(r1)
16534e2bf01bSMichael Ellerman	std	r11,_NIP(r1)
16544e2bf01bSMichael Ellerman	std	r12,_MSR(r1)
16554e2bf01bSMichael Ellerman	mfspr	r11,SPRN_DAR
16564e2bf01bSMichael Ellerman	mfspr	r12,SPRN_DSISR
16574e2bf01bSMichael Ellerman	std	r11,_DAR(r1)
16584e2bf01bSMichael Ellerman	std	r12,_DSISR(r1)
16594e2bf01bSMichael Ellerman	mflr	r10
16604e2bf01bSMichael Ellerman	mfctr	r11
16614e2bf01bSMichael Ellerman	mfxer	r12
16624e2bf01bSMichael Ellerman	std	r10,_LINK(r1)
16634e2bf01bSMichael Ellerman	std	r11,_CTR(r1)
16644e2bf01bSMichael Ellerman	std	r12,_XER(r1)
16654e2bf01bSMichael Ellerman	SAVE_GPR(0,r1)
16664e2bf01bSMichael Ellerman	SAVE_GPR(2,r1)
16674e2bf01bSMichael Ellerman	ld	r10,EX_R3(r3)
16684e2bf01bSMichael Ellerman	std	r10,GPR3(r1)
16694e2bf01bSMichael Ellerman	SAVE_GPR(4,r1)
16704e2bf01bSMichael Ellerman	SAVE_4GPRS(5,r1)
16714e2bf01bSMichael Ellerman	ld	r9,EX_R9(r3)
16724e2bf01bSMichael Ellerman	ld	r10,EX_R10(r3)
16734e2bf01bSMichael Ellerman	SAVE_2GPRS(9,r1)
16744e2bf01bSMichael Ellerman	ld	r9,EX_R11(r3)
16754e2bf01bSMichael Ellerman	ld	r10,EX_R12(r3)
16764e2bf01bSMichael Ellerman	ld	r11,EX_R13(r3)
16774e2bf01bSMichael Ellerman	std	r9,GPR11(r1)
16784e2bf01bSMichael Ellerman	std	r10,GPR12(r1)
16794e2bf01bSMichael Ellerman	std	r11,GPR13(r1)
16804e2bf01bSMichael EllermanBEGIN_FTR_SECTION
16814e2bf01bSMichael Ellerman	ld	r10,EX_CFAR(r3)
16824e2bf01bSMichael Ellerman	std	r10,ORIG_GPR3(r1)
16834e2bf01bSMichael EllermanEND_FTR_SECTION_IFSET(CPU_FTR_CFAR)
16844e2bf01bSMichael Ellerman	SAVE_8GPRS(14,r1)
16854e2bf01bSMichael Ellerman	SAVE_10GPRS(22,r1)
16864e2bf01bSMichael Ellerman	lhz	r12,PACA_TRAP_SAVE(r13)
16874e2bf01bSMichael Ellerman	std	r12,_TRAP(r1)
16884e2bf01bSMichael Ellerman	addi	r11,r1,INT_FRAME_SIZE
16894e2bf01bSMichael Ellerman	std	r11,0(r1)
16904e2bf01bSMichael Ellerman	li	r12,0
16914e2bf01bSMichael Ellerman	std	r12,0(r11)
16924e2bf01bSMichael Ellerman	ld	r2,PACATOC(r13)
16934e2bf01bSMichael Ellerman	ld	r11,exception_marker@toc(r2)
16944e2bf01bSMichael Ellerman	std	r12,RESULT(r1)
16954e2bf01bSMichael Ellerman	std	r11,STACK_FRAME_OVERHEAD-16(r1)
16964e2bf01bSMichael Ellerman1:	addi	r3,r1,STACK_FRAME_OVERHEAD
16974e2bf01bSMichael Ellerman	bl	kernel_bad_stack
16984e2bf01bSMichael Ellerman	b	1b
1699