diff options
Diffstat (limited to 'arch/powerpc/include/asm/exception-64s.h')
| -rw-r--r-- | arch/powerpc/include/asm/exception-64s.h | 113 | 
1 files changed, 67 insertions, 46 deletions
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 7778d6f0c87..f5dfe3411f6 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -46,6 +46,7 @@  #define EX_CCR		60  #define EX_R3		64  #define EX_LR		72 +#define EX_CFAR		80  /*   * We're short on space and time in the exception prolog, so we can't @@ -56,30 +57,40 @@  #define LOAD_HANDLER(reg, label)					\  	addi	reg,reg,(label)-_stext;	/* virt addr of handler ... */ -#define EXCEPTION_PROLOG_1(area)				\ -	mfspr	r13,SPRN_SPRG_PACA;	/* get paca address into r13 */	\ +/* Exception register prefixes */ +#define EXC_HV	H +#define EXC_STD + +#define EXCEPTION_PROLOG_1(area)					\ +	GET_PACA(r13);							\  	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\  	std	r10,area+EX_R10(r13);					\  	std	r11,area+EX_R11(r13);					\  	std	r12,area+EX_R12(r13);					\ -	mfspr	r9,SPRN_SPRG_SCRATCH0;					\ +	BEGIN_FTR_SECTION_NESTED(66);					\ +	mfspr	r10,SPRN_CFAR;						\ +	std	r10,area+EX_CFAR(r13);					\ +	END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66);		\ +	GET_SCRATCH0(r9);						\  	std	r9,area+EX_R13(r13);					\  	mfcr	r9 -#define EXCEPTION_PROLOG_PSERIES_1(label)				\ +#define __EXCEPTION_PROLOG_PSERIES_1(label, h)				\  	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\  	ld	r10,PACAKMSR(r13);	/* get MSR value for kernel */	\ -	mfspr	r11,SPRN_SRR0;		/* save SRR0 */			\ +	mfspr	r11,SPRN_##h##SRR0;	/* save SRR0 */			\  	LOAD_HANDLER(r12,label)						\ -	mtspr	SPRN_SRR0,r12;						\ -	mfspr	r12,SPRN_SRR1;		/* and SRR1 */			\ -	mtspr	SPRN_SRR1,r10;						\ -	rfid;								\ +	mtspr	SPRN_##h##SRR0,r12;					\ +	mfspr	r12,SPRN_##h##SRR1;	/* and SRR1 */			\ +	mtspr	SPRN_##h##SRR1,r10;					\ +	h##rfid;							\  	b	.	/* prevent speculative execution */ +#define EXCEPTION_PROLOG_PSERIES_1(label, h) \ +	__EXCEPTION_PROLOG_PSERIES_1(label, h) -#define EXCEPTION_PROLOG_PSERIES(area, label)				\ +#define EXCEPTION_PROLOG_PSERIES(area, label, h)			\  	EXCEPTION_PROLOG_1(area);					\ -	EXCEPTION_PROLOG_PSERIES_1(label); +	EXCEPTION_PROLOG_PSERIES_1(label, h);  /*   * The common exception prolog is used for all except a few exceptions @@ -98,10 +109,11 @@  	beq-	1f;							   \  	ld	r1,PACAKSAVE(r13);	/* kernel stack to use		*/ \  1:	cmpdi	cr1,r1,0;		/* check if r1 is in userspace	*/ \ -	bge-	cr1,2f;			/* abort if it is		*/ \ -	b	3f;							   \ -2:	li	r1,(n);			/* will be reloaded later	*/ \ +	blt+	cr1,3f;			/* abort if it is		*/ \ +	li	r1,(n);			/* will be reloaded later	*/ \  	sth	r1,PACA_TRAP_SAVE(r13);					   \ +	std	r3,area+EX_R3(r13);					   \ +	addi	r3,r13,area;		/* r3 -> where regs are saved*/	   \  	b	bad_stack;						   \  3:	std	r9,_CCR(r1);		/* save CR in stackframe	*/ \  	std	r11,_NIP(r1);		/* save SRR0 in stackframe	*/ \ @@ -123,6 +135,10 @@  	std	r9,GPR11(r1);						   \  	std	r10,GPR12(r1);						   \  	std	r11,GPR13(r1);						   \ +	BEGIN_FTR_SECTION_NESTED(66);					   \ +	ld	r10,area+EX_CFAR(r13);					   \ +	std	r10,ORIG_GPR3(r1);					   \ +	END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66);		   \  	ld	r2,PACATOC(r13);	/* get kernel TOC into r2	*/ \  	mflr	r9;			/* save LR in stackframe	*/ \  	std	r9,_LINK(r1);						   \ @@ -143,57 +159,62 @@  /*   * Exception vectors.   */ -#define STD_EXCEPTION_PSERIES(n, label)			\ -	. = n;						\ +#define STD_EXCEPTION_PSERIES(loc, vec, label)		\ +	. = loc;					\  	.globl label##_pSeries;				\  label##_pSeries:					\  	HMT_MEDIUM;					\ -	DO_KVM	n;					\ -	mtspr	SPRN_SPRG_SCRATCH0,r13;		/* save r13 */	\ -	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) +	DO_KVM	vec;					\ +	SET_SCRATCH0(r13);		/* save r13 */		\ +	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_STD) -#define HSTD_EXCEPTION_PSERIES(n, label)		\ -	. = n;						\ -	.globl label##_pSeries;				\ -label##_pSeries:					\ +#define STD_EXCEPTION_HV(loc, vec, label)		\ +	. = loc;					\ +	.globl label##_hv;				\ +label##_hv:						\  	HMT_MEDIUM;					\ -	mtspr	SPRN_SPRG_SCRATCH0,r20;	/* save r20 */	\ -	mfspr	r20,SPRN_HSRR0;		/* copy HSRR0 to SRR0 */ \ -	mtspr	SPRN_SRR0,r20;				\ -	mfspr	r20,SPRN_HSRR1;		/* copy HSRR0 to SRR0 */ \ -	mtspr	SPRN_SRR1,r20;				\ -	mfspr	r20,SPRN_SPRG_SCRATCH0;	/* restore r20 */ \ -	mtspr	SPRN_SPRG_SCRATCH0,r13;		/* save r13 */	\ -	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) +	DO_KVM	vec;					\ +	SET_SCRATCH0(r13);	/* save r13 */		\ +	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_HV) - -#define MASKABLE_EXCEPTION_PSERIES(n, label)				\ -	. = n;								\ -	.globl label##_pSeries;						\ -label##_pSeries:							\ +#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h)			\  	HMT_MEDIUM;							\ -	DO_KVM	n;							\ -	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\ -	mfspr	r13,SPRN_SPRG_PACA;	/* get paca address into r13 */	\ +	DO_KVM	vec;							\ +	SET_SCRATCH0(r13);    /* save r13 */				\ +	GET_PACA(r13);							\  	std	r9,PACA_EXGEN+EX_R9(r13);	/* save r9, r10 */	\  	std	r10,PACA_EXGEN+EX_R10(r13);				\  	lbz	r10,PACASOFTIRQEN(r13);					\  	mfcr	r9;							\  	cmpwi	r10,0;							\ -	beq	masked_interrupt;					\ -	mfspr	r10,SPRN_SPRG_SCRATCH0;					\ +	beq	masked_##h##interrupt;					\ +	GET_SCRATCH0(r10);						\  	std	r10,PACA_EXGEN+EX_R13(r13);				\  	std	r11,PACA_EXGEN+EX_R11(r13);				\  	std	r12,PACA_EXGEN+EX_R12(r13);				\  	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\  	ld	r10,PACAKMSR(r13);	/* get MSR value for kernel */	\ -	mfspr	r11,SPRN_SRR0;		/* save SRR0 */			\ +	mfspr	r11,SPRN_##h##SRR0;	/* save SRR0 */			\  	LOAD_HANDLER(r12,label##_common)				\ -	mtspr	SPRN_SRR0,r12;						\ -	mfspr	r12,SPRN_SRR1;		/* and SRR1 */			\ -	mtspr	SPRN_SRR1,r10;						\ -	rfid;								\ +	mtspr	SPRN_##h##SRR0,r12;					\ +	mfspr	r12,SPRN_##h##SRR1;	/* and SRR1 */			\ +	mtspr	SPRN_##h##SRR1,r10;					\ +	h##rfid;							\  	b	.	/* prevent speculative execution */ +#define _MASKABLE_EXCEPTION_PSERIES(vec, label, h)			\ +	__MASKABLE_EXCEPTION_PSERIES(vec, label, h) + +#define MASKABLE_EXCEPTION_PSERIES(loc, vec, label)			\ +	. = loc;							\ +	.globl label##_pSeries;						\ +label##_pSeries:							\ +	_MASKABLE_EXCEPTION_PSERIES(vec, label, EXC_STD) + +#define MASKABLE_EXCEPTION_HV(loc, vec, label)				\ +	. = loc;							\ +	.globl label##_hv;						\ +label##_hv:								\ +	_MASKABLE_EXCEPTION_PSERIES(vec, label, EXC_HV)  #ifdef CONFIG_PPC_ISERIES  #define DISABLE_INTS				\  |