Skip to content

Commit

Permalink
powerpc: Use names rather than numbers for SPRGs (v2)
Browse files Browse the repository at this point in the history
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: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Benjamin Herrenschmidt committed Aug 20, 2009
1 parent 8aa34ab commit ee43eb7
Show file tree
Hide file tree
Showing 20 changed files with 356 additions and 264 deletions.
18 changes: 9 additions & 9 deletions arch/powerpc/include/asm/exception-64s.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -144,21 +144,21 @@
.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) \
. = n; \
.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)


Expand All @@ -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); \
Expand Down
113 changes: 113 additions & 0 deletions arch/powerpc/include/asm/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/kernel/cpu_setup_6xx.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 10 additions & 10 deletions arch/powerpc/kernel/entry_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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)
Expand All @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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 */
Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/kernel/entry_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit ee43eb7

Please sign in to comment.