xref: /openbmc/linux/arch/powerpc/kernel/head_32.h (revision 1ae99b4b924ab10452da653baed29d3883705519)
18a23fdecSChristophe Leroy /* SPDX-License-Identifier: GPL-2.0 */
28a23fdecSChristophe Leroy #ifndef __HEAD_32_H__
38a23fdecSChristophe Leroy #define __HEAD_32_H__
48a23fdecSChristophe Leroy 
58a23fdecSChristophe Leroy #include <asm/ptrace.h>	/* for STACK_FRAME_REGS_MARKER */
68a23fdecSChristophe Leroy 
78a23fdecSChristophe Leroy /*
837737a2aSChristophe Leroy  * MSR_KERNEL is > 0x8000 on 4xx/Book-E since it include MSR_CE.
937737a2aSChristophe Leroy  */
1037737a2aSChristophe Leroy .macro __LOAD_MSR_KERNEL r, x
1137737a2aSChristophe Leroy .if \x >= 0x8000
1237737a2aSChristophe Leroy 	lis \r, (\x)@h
1337737a2aSChristophe Leroy 	ori \r, \r, (\x)@l
1437737a2aSChristophe Leroy .else
1537737a2aSChristophe Leroy 	li \r, (\x)
1637737a2aSChristophe Leroy .endif
1737737a2aSChristophe Leroy .endm
1837737a2aSChristophe Leroy #define LOAD_MSR_KERNEL(r, x) __LOAD_MSR_KERNEL r, x
1937737a2aSChristophe Leroy 
2037737a2aSChristophe Leroy /*
218a23fdecSChristophe Leroy  * Exception entry code.  This code runs with address translation
228a23fdecSChristophe Leroy  * turned off, i.e. using physical addresses.
238a23fdecSChristophe Leroy  * We assume sprg3 has the physical address of the current
248a23fdecSChristophe Leroy  * task's thread_struct.
258a23fdecSChristophe Leroy  */
268a23fdecSChristophe Leroy 
278a23fdecSChristophe Leroy .macro EXCEPTION_PROLOG
288a23fdecSChristophe Leroy 	mtspr	SPRN_SPRG_SCRATCH0,r10
298a23fdecSChristophe Leroy 	mtspr	SPRN_SPRG_SCRATCH1,r11
308a23fdecSChristophe Leroy 	mfcr	r10
318a23fdecSChristophe Leroy 	EXCEPTION_PROLOG_1
328a23fdecSChristophe Leroy 	EXCEPTION_PROLOG_2
338a23fdecSChristophe Leroy .endm
348a23fdecSChristophe Leroy 
358a23fdecSChristophe Leroy .macro EXCEPTION_PROLOG_1
368a23fdecSChristophe Leroy 	mfspr	r11,SPRN_SRR1		/* check whether user or kernel */
378a23fdecSChristophe Leroy 	andi.	r11,r11,MSR_PR
388a23fdecSChristophe Leroy 	tophys(r11,r1)			/* use tophys(r1) if kernel */
398a23fdecSChristophe Leroy 	beq	1f
408a23fdecSChristophe Leroy 	mfspr	r11,SPRN_SPRG_THREAD
418a23fdecSChristophe Leroy 	lwz	r11,TASK_STACK-THREAD(r11)
428a23fdecSChristophe Leroy 	addi	r11,r11,THREAD_SIZE
438a23fdecSChristophe Leroy 	tophys(r11,r11)
448a23fdecSChristophe Leroy 1:	subi	r11,r11,INT_FRAME_SIZE	/* alloc exc. frame */
458a23fdecSChristophe Leroy .endm
468a23fdecSChristophe Leroy 
478a23fdecSChristophe Leroy .macro EXCEPTION_PROLOG_2
488a23fdecSChristophe Leroy 	stw	r10,_CCR(r11)		/* save registers */
498a23fdecSChristophe Leroy 	stw	r12,GPR12(r11)
508a23fdecSChristophe Leroy 	stw	r9,GPR9(r11)
518a23fdecSChristophe Leroy 	mfspr	r10,SPRN_SPRG_SCRATCH0
528a23fdecSChristophe Leroy 	stw	r10,GPR10(r11)
538a23fdecSChristophe Leroy 	mfspr	r12,SPRN_SPRG_SCRATCH1
548a23fdecSChristophe Leroy 	stw	r12,GPR11(r11)
558a23fdecSChristophe Leroy 	mflr	r10
568a23fdecSChristophe Leroy 	stw	r10,_LINK(r11)
578a23fdecSChristophe Leroy 	mfspr	r12,SPRN_SRR0
588a23fdecSChristophe Leroy 	mfspr	r9,SPRN_SRR1
598a23fdecSChristophe Leroy 	stw	r1,GPR1(r11)
608a23fdecSChristophe Leroy 	stw	r1,0(r11)
618a23fdecSChristophe Leroy 	tovirt(r1,r11)			/* set new kernel sp */
6290f204b9SChristophe Leroy #ifdef CONFIG_40x
6390f204b9SChristophe Leroy 	rlwinm	r9,r9,0,14,12		/* clear MSR_WE (necessary?) */
6490f204b9SChristophe Leroy #else
658a23fdecSChristophe Leroy 	li	r10,MSR_KERNEL & ~(MSR_IR|MSR_DR) /* can take exceptions */
668a23fdecSChristophe Leroy 	MTMSRD(r10)			/* (except for mach check in rtas) */
6790f204b9SChristophe Leroy #endif
688a23fdecSChristophe Leroy 	stw	r0,GPR0(r11)
698a23fdecSChristophe Leroy 	lis	r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */
708a23fdecSChristophe Leroy 	addi	r10,r10,STACK_FRAME_REGS_MARKER@l
718a23fdecSChristophe Leroy 	stw	r10,8(r11)
728a23fdecSChristophe Leroy 	SAVE_4GPRS(3, r11)
738a23fdecSChristophe Leroy 	SAVE_2GPRS(7, r11)
748a23fdecSChristophe Leroy .endm
758a23fdecSChristophe Leroy 
768a23fdecSChristophe Leroy /*
778a23fdecSChristophe Leroy  * Note: code which follows this uses cr0.eq (set if from kernel),
788a23fdecSChristophe Leroy  * r11, r12 (SRR0), and r9 (SRR1).
798a23fdecSChristophe Leroy  *
808a23fdecSChristophe Leroy  * Note2: once we have set r1 we are in a position to take exceptions
818a23fdecSChristophe Leroy  * again, and we could thus set MSR:RI at that point.
828a23fdecSChristophe Leroy  */
838a23fdecSChristophe Leroy 
848a23fdecSChristophe Leroy /*
858a23fdecSChristophe Leroy  * Exception vectors.
868a23fdecSChristophe Leroy  */
878a23fdecSChristophe Leroy #ifdef CONFIG_PPC_BOOK3S
888a23fdecSChristophe Leroy #define	START_EXCEPTION(n, label)		\
898a23fdecSChristophe Leroy 	. = n;					\
908a23fdecSChristophe Leroy 	DO_KVM n;				\
918a23fdecSChristophe Leroy label:
928a23fdecSChristophe Leroy 
938a23fdecSChristophe Leroy #else
948a23fdecSChristophe Leroy #define	START_EXCEPTION(n, label)		\
958a23fdecSChristophe Leroy 	. = n;					\
968a23fdecSChristophe Leroy label:
978a23fdecSChristophe Leroy 
988a23fdecSChristophe Leroy #endif
998a23fdecSChristophe Leroy 
1008a23fdecSChristophe Leroy #define EXCEPTION(n, label, hdlr, xfer)		\
1018a23fdecSChristophe Leroy 	START_EXCEPTION(n, label)		\
1028a23fdecSChristophe Leroy 	EXCEPTION_PROLOG;			\
1038a23fdecSChristophe Leroy 	addi	r3,r1,STACK_FRAME_OVERHEAD;	\
1048a23fdecSChristophe Leroy 	xfer(n, hdlr)
1058a23fdecSChristophe Leroy 
106*1ae99b4bSChristophe Leroy #define EXC_XFER_TEMPLATE(hdlr, trap, msr, tfer, ret)		\
1078a23fdecSChristophe Leroy 	li	r10,trap;					\
1088a23fdecSChristophe Leroy 	stw	r10,_TRAP(r11);					\
1091d3034aeSChristophe Leroy 	LOAD_MSR_KERNEL(r10, msr);				\
1108a23fdecSChristophe Leroy 	bl	tfer;						\
1118a23fdecSChristophe Leroy 	.long	hdlr;						\
1128a23fdecSChristophe Leroy 	.long	ret
1138a23fdecSChristophe Leroy 
1148a23fdecSChristophe Leroy #define EXC_XFER_STD(n, hdlr)		\
115*1ae99b4bSChristophe Leroy 	EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, transfer_to_handler_full,	\
1168a23fdecSChristophe Leroy 			  ret_from_except_full)
1178a23fdecSChristophe Leroy 
1188a23fdecSChristophe Leroy #define EXC_XFER_LITE(n, hdlr)		\
119*1ae99b4bSChristophe Leroy 	EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, transfer_to_handler, \
1208a23fdecSChristophe Leroy 			  ret_from_except)
1218a23fdecSChristophe Leroy 
122f97dec21SChristophe Leroy #define EXC_XFER_SYS(n, hdlr)		\
123*1ae99b4bSChristophe Leroy 	EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL | MSR_EE, transfer_to_handler, \
124f97dec21SChristophe Leroy 			  ret_from_except)
125f97dec21SChristophe Leroy 
1268a23fdecSChristophe Leroy #endif /* __HEAD_32_H__ */
127