Commit ee43eb78 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt
Browse files

powerpc: Use names rather than numbers for SPRGs (v2)



The kernel uses SPRG registers for various purposes, typically in
low level assembly code as scratch registers or to hold per-cpu
global infos such as the PACA or the current thread_info pointer.

We want to be able to easily shuffle the usage of those registers
as some implementations have specific constraints realted to some
of them, for example, some have userspace readable aliases, etc..
and the current choice isn't always the best.

This patch should not change any code generation, and replaces the
usage of SPRN_SPRGn everywhere in the kernel with a named replacement
and adds documentation next to the definition of the names as to
what those are used for on each processor family.

The only parts that still use the original numbers are bits of KVM
or suspend/resume code that just blindly needs to save/restore all
the SPRGs.

Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 8aa34ab8
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -57,12 +57,12 @@
	addi	reg,reg,(label)-_stext;	/* virt addr of handler ... */

#define EXCEPTION_PROLOG_1(area)				\
	mfspr	r13,SPRN_SPRG3;		/* get paca address into r13 */	\
	mfspr	r13,SPRN_SPRG_PACA;	/* get paca address into 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_SPRG1;						\
	mfspr	r9,SPRN_SPRG_SCRATCH0;					\
	std	r9,area+EX_R13(r13);					\
	mfcr	r9

@@ -144,7 +144,7 @@
	.globl label##_pSeries;				\
label##_pSeries:					\
	HMT_MEDIUM;					\
	mtspr	SPRN_SPRG1,r13;		/* save r13 */	\
	mtspr	SPRN_SPRG_SCRATCH0,r13;		/* save r13 */	\
	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)

#define HSTD_EXCEPTION_PSERIES(n, label)		\
@@ -152,13 +152,13 @@ label##_pSeries: \
	.globl label##_pSeries;				\
label##_pSeries:					\
	HMT_MEDIUM;					\
	mtspr	SPRN_SPRG1,r20;		/* save r20 */	\
	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_SPRG1;		/* restore r20 */ \
	mtspr	SPRN_SPRG1,r13;		/* save r13 */	\
	mfspr	r20,SPRN_SPRG_SCRATCH0;	/* restore r20 */ \
	mtspr	SPRN_SPRG_SCRATCH0,r13;		/* save r13 */	\
	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)


@@ -167,15 +167,15 @@ label##_pSeries: \
	.globl label##_pSeries;						\
label##_pSeries:							\
	HMT_MEDIUM;							\
	mtspr	SPRN_SPRG1,r13;		/* save r13 */			\
	mfspr	r13,SPRN_SPRG3;		/* get paca address into r13 */	\
	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
	mfspr	r13,SPRN_SPRG_PACA;	/* get paca address into 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_SPRG1;						\
	mfspr	r10,SPRN_SPRG_SCRATCH0;					\
	std	r10,PACA_EXGEN+EX_R13(r13);				\
	std	r11,PACA_EXGEN+EX_R11(r13);				\
	std	r12,PACA_EXGEN+EX_R12(r13);				\
+113 −0
Original line number Diff line number Diff line
@@ -645,6 +645,119 @@
#define MMCR0_PMC2_LOADMISSTIME	0x5
#endif

/*
 * SPRG usage:
 *
 * All 64-bit:
 *	- SPRG3 stores PACA pointer
 *
 * 64-bit server:
 *	- SPRG0 unused (reserved for HV on Power4)
 *	- SPRG1 scratch for exception vectors
 *	- SPRG2 scratch for exception vectors
 *
 * All 32-bit:
 *	- SPRG3 current thread_info pointer
 *        (virtual on BookE, physical on others)
 *
 * 32-bit classic:
 *	- SPRG0 scratch for exception vectors
 *	- SPRG1 scratch for exception vectors
 *	- SPRG2 indicator that we are in RTAS
 *	- SPRG4 (603 only) pseudo TLB LRU data
 *
 * 32-bit 40x:
 *	- SPRG0 scratch for exception vectors
 *	- SPRG1 scratch for exception vectors
 *	- SPRG2 scratch for exception vectors
 *	- SPRG4 scratch for exception vectors (not 403)
 *	- SPRG5 scratch for exception vectors (not 403)
 *	- SPRG6 scratch for exception vectors (not 403)
 *	- SPRG7 scratch for exception vectors (not 403)
 *
 * 32-bit 440 and FSL BookE:
 *	- SPRG0 scratch for exception vectors
 *	- SPRG1 scratch for exception vectors (*)
 *	- SPRG2 scratch for crit interrupts handler
 *	- SPRG4 scratch for exception vectors
 *	- SPRG5 scratch for exception vectors
 *	- SPRG6 scratch for machine check handler
 *	- SPRG7 scratch for exception vectors
 *	- SPRG9 scratch for debug vectors (e500 only)
 *
 *      Additionally, BookE separates "read" and "write"
 *      of those registers. That allows to use the userspace
 *      readable variant for reads, which can avoid a fault
 *      with KVM type virtualization.
 *
 *      (*) Under KVM, the host SPRG1 is used to point to
 *      the current VCPU data structure
 *
 * 32-bit 8xx:
 *	- SPRG0 scratch for exception vectors
 *	- SPRG1 scratch for exception vectors
 *	- SPRG2 apparently unused but initialized
 *
 */
#ifdef CONFIG_PPC64
#define SPRN_SPRG_PACA 		SPRN_SPRG3
#else
#define SPRN_SPRG_THREAD 	SPRN_SPRG3
#endif

#ifdef CONFIG_PPC_BOOK3S_64
#define SPRN_SPRG_SCRATCH0	SPRN_SPRG1
#define SPRN_SPRG_SCRATCH1	SPRN_SPRG2
#endif

#ifdef CONFIG_PPC_BOOK3S_32
#define SPRN_SPRG_SCRATCH0	SPRN_SPRG0
#define SPRN_SPRG_SCRATCH1	SPRN_SPRG1
#define SPRN_SPRG_RTAS		SPRN_SPRG2
#define SPRN_SPRG_603_LRU	SPRN_SPRG4
#endif

#ifdef CONFIG_40x
#define SPRN_SPRG_SCRATCH0	SPRN_SPRG0
#define SPRN_SPRG_SCRATCH1	SPRN_SPRG1
#define SPRN_SPRG_SCRATCH2	SPRN_SPRG2
#define SPRN_SPRG_SCRATCH3	SPRN_SPRG4
#define SPRN_SPRG_SCRATCH4	SPRN_SPRG5
#define SPRN_SPRG_SCRATCH5	SPRN_SPRG6
#define SPRN_SPRG_SCRATCH6	SPRN_SPRG7
#endif

#ifdef CONFIG_BOOKE
#define SPRN_SPRG_RSCRATCH0	SPRN_SPRG0
#define SPRN_SPRG_WSCRATCH0	SPRN_SPRG0
#define SPRN_SPRG_RSCRATCH1	SPRN_SPRG1
#define SPRN_SPRG_WSCRATCH1	SPRN_SPRG1
#define SPRN_SPRG_RSCRATCH_CRIT	SPRN_SPRG2
#define SPRN_SPRG_WSCRATCH_CRIT	SPRN_SPRG2
#define SPRN_SPRG_RSCRATCH2	SPRN_SPRG4R
#define SPRN_SPRG_WSCRATCH2	SPRN_SPRG4W
#define SPRN_SPRG_RSCRATCH3	SPRN_SPRG5R
#define SPRN_SPRG_WSCRATCH3	SPRN_SPRG5W
#define SPRN_SPRG_RSCRATCH_MC	SPRN_SPRG6R
#define SPRN_SPRG_WSCRATCH_MC	SPRN_SPRG6W
#define SPRN_SPRG_RSCRATCH4	SPRN_SPRG7R
#define SPRN_SPRG_WSCRATCH4	SPRN_SPRG7W
#ifdef CONFIG_E200
#define SPRN_SPRG_RSCRATCH_DBG	SPRN_SPRG6R
#define SPRN_SPRG_WSCRATCH_DBG	SPRN_SPRG6W
#else
#define SPRN_SPRG_RSCRATCH_DBG	SPRN_SPRG9
#define SPRN_SPRG_WSCRATCH_DBG	SPRN_SPRG9
#endif
#define SPRN_SPRG_RVCPU		SPRN_SPRG1
#define SPRN_SPRG_WVCPU		SPRN_SPRG1
#endif

#ifdef CONFIG_8xx
#define SPRN_SPRG_SCRATCH0	SPRN_SPRG0
#define SPRN_SPRG_SCRATCH1	SPRN_SPRG1
#endif

/*
 * An mtfsf instruction with the L bit set. On CPUs that support this a
 * full 64bits of FPSCR is restored and on other CPUs the L bit is ignored.
+1 −1
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ _GLOBAL(__setup_cpu_603)
	mflr	r4
BEGIN_MMU_FTR_SECTION
	li	r10,0
	mtspr	SPRN_SPRG4,r10		/* init SW LRU tracking */
	mtspr	SPRN_SPRG_603_LRU,r10		/* init SW LRU tracking */
END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
BEGIN_FTR_SECTION
	bl	__init_fpu_registers
+10 −10
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@ crit_transfer_to_handler:
	mfspr	r0,SPRN_SRR1
	stw	r0,_SRR1(r11)

	mfspr	r8,SPRN_SPRG3
	mfspr	r8,SPRN_SPRG_THREAD
	lwz	r0,KSP_LIMIT(r8)
	stw	r0,SAVED_KSP_LIMIT(r11)
	rlwimi	r0,r1,0,0,(31-THREAD_SHIFT)
@@ -108,7 +108,7 @@ crit_transfer_to_handler:
	mfspr	r0,SPRN_SRR1
	stw	r0,crit_srr1@l(0)

	mfspr	r8,SPRN_SPRG3
	mfspr	r8,SPRN_SPRG_THREAD
	lwz	r0,KSP_LIMIT(r8)
	stw	r0,saved_ksp_limit@l(0)
	rlwimi	r0,r1,0,0,(31-THREAD_SHIFT)
@@ -138,7 +138,7 @@ transfer_to_handler:
	mfspr	r2,SPRN_XER
	stw	r12,_CTR(r11)
	stw	r2,_XER(r11)
	mfspr	r12,SPRN_SPRG3
	mfspr	r12,SPRN_SPRG_THREAD
	addi	r2,r12,-THREAD
	tovirt(r2,r2)			/* set r2 to current */
	beq	2f			/* if from user, fix up THREAD.regs */
@@ -680,7 +680,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPE)

	tophys(r0,r4)
	CLR_TOP32(r0)
	mtspr	SPRN_SPRG3,r0	/* Update current THREAD phys addr */
	mtspr	SPRN_SPRG_THREAD,r0	/* Update current THREAD phys addr */
	lwz	r1,KSP(r4)	/* Load new stack pointer */

	/* save the old current 'last' for return value */
@@ -1057,7 +1057,7 @@ exc_exit_restart_end:
#ifdef CONFIG_40x
	.globl	ret_from_crit_exc
ret_from_crit_exc:
	mfspr	r9,SPRN_SPRG3
	mfspr	r9,SPRN_SPRG_THREAD
	lis	r10,saved_ksp_limit@ha;
	lwz	r10,saved_ksp_limit@l(r10);
	tovirt(r9,r9);
@@ -1074,7 +1074,7 @@ ret_from_crit_exc:
#ifdef CONFIG_BOOKE
	.globl	ret_from_crit_exc
ret_from_crit_exc:
	mfspr	r9,SPRN_SPRG3
	mfspr	r9,SPRN_SPRG_THREAD
	lwz	r10,SAVED_KSP_LIMIT(r1)
	stw	r10,KSP_LIMIT(r9)
	RESTORE_xSRR(SRR0,SRR1);
@@ -1083,7 +1083,7 @@ ret_from_crit_exc:

	.globl	ret_from_debug_exc
ret_from_debug_exc:
	mfspr	r9,SPRN_SPRG3
	mfspr	r9,SPRN_SPRG_THREAD
	lwz	r10,SAVED_KSP_LIMIT(r1)
	stw	r10,KSP_LIMIT(r9)
	lwz	r9,THREAD_INFO-THREAD(r9)
@@ -1097,7 +1097,7 @@ ret_from_debug_exc:

	.globl	ret_from_mcheck_exc
ret_from_mcheck_exc:
	mfspr	r9,SPRN_SPRG3
	mfspr	r9,SPRN_SPRG_THREAD
	lwz	r10,SAVED_KSP_LIMIT(r1)
	stw	r10,KSP_LIMIT(r9)
	RESTORE_xSRR(SRR0,SRR1);
@@ -1255,7 +1255,7 @@ _GLOBAL(enter_rtas)
	MTMSRD(r0)		/* don't get trashed */
	li	r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
	mtlr	r6
	mtspr	SPRN_SPRG2,r7
	mtspr	SPRN_SPRG_RTAS,r7
	mtspr	SPRN_SRR0,r8
	mtspr	SPRN_SRR1,r9
	RFI
@@ -1265,7 +1265,7 @@ _GLOBAL(enter_rtas)
	FIX_SRR1(r9,r0)
	addi	r1,r1,INT_FRAME_SIZE
	li	r0,0
	mtspr	SPRN_SPRG2,r0
	mtspr	SPRN_SPRG_RTAS,r0
	mtspr	SPRN_SRR0,r8
	mtspr	SPRN_SRR1,r9
	RFI			/* return to caller */
+2 −2
Original line number Diff line number Diff line
@@ -762,7 +762,7 @@ _GLOBAL(enter_rtas)

_STATIC(rtas_return_loc)
	/* relocation is off at this point */
	mfspr	r4,SPRN_SPRG3	        /* Get PACA */
	mfspr	r4,SPRN_SPRG_PACA	/* Get PACA */
	clrldi	r4,r4,2			/* convert to realmode address */

	bcl	20,31,$+4
@@ -793,7 +793,7 @@ _STATIC(rtas_restore_regs)
	REST_8GPRS(14, r1)		/* Restore the non-volatiles */
	REST_10GPRS(22, r1)		/* ditto */

	mfspr	r13,SPRN_SPRG3
	mfspr	r13,SPRN_SPRG_PACA

	ld	r4,_CCR(r1)
	mtcr	r4
Loading