Commit 91993c8c authored by Stefan Kristiansson's avatar Stefan Kristiansson Committed by Stafford Horne
Browse files

openrisc: use shadow registers to save regs on exception



Previously, the area between 0x0-0x100 have been used as a "scratch"
memory area to temporarily store regs during exception entry. In a
multi-core environment, this will not work.

This change is to use shadow registers for nested context.

Currently only the "critical" temp load/stores are covered, the
EMERGENCY_PRINT ones are left as is (when they are used, it's game over
anyway), they need to be handled as well in the future.

Signed-off-by: default avatarStefan Kristiansson <stefan.kristiansson@saunalahti.fi>
Signed-off-by: default avatarStafford Horne <shorne@gmail.com>
parent ddc92bec
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -124,6 +124,17 @@ config OPENRISC_NO_SPR_SR_DSX
	  Say N here if you know that your OpenRISC processor has
	  SPR_SR_DSX bit implemented. Say Y if you are unsure.

config OPENRISC_HAVE_SHADOW_GPRS
	bool "Support for shadow gpr files" if !SMP
	default y if SMP
	help
	  Say Y here if your OpenRISC processor features shadowed
	  register files. They will in such case be used as a
	  scratch reg storage on exception entry.

	  On SMP systems, this feature is mandatory.
	  On a unicore system it's safe to say N here if you are unsure.

config CMDLINE
        string "Default kernel command string"
        default ""
+69 −26
Original line number Diff line number Diff line
@@ -49,9 +49,31 @@

/* ============================================[ tmp store locations ]=== */

#define SPR_SHADOW_GPR(x)	((x) + SPR_GPR_BASE + 32)

/*
 * emergency_print temporary stores
 */
#ifdef CONFIG_OPENRISC_HAVE_SHADOW_GPRS
#define EMERGENCY_PRINT_STORE_GPR4	l.mtspr r0,r4,SPR_SHADOW_GPR(14)
#define EMERGENCY_PRINT_LOAD_GPR4	l.mfspr r4,r0,SPR_SHADOW_GPR(14)

#define EMERGENCY_PRINT_STORE_GPR5	l.mtspr r0,r5,SPR_SHADOW_GPR(15)
#define EMERGENCY_PRINT_LOAD_GPR5	l.mfspr r5,r0,SPR_SHADOW_GPR(15)

#define EMERGENCY_PRINT_STORE_GPR6	l.mtspr r0,r6,SPR_SHADOW_GPR(16)
#define EMERGENCY_PRINT_LOAD_GPR6	l.mfspr r6,r0,SPR_SHADOW_GPR(16)

#define EMERGENCY_PRINT_STORE_GPR7	l.mtspr r0,r7,SPR_SHADOW_GPR(7)
#define EMERGENCY_PRINT_LOAD_GPR7	l.mfspr r7,r0,SPR_SHADOW_GPR(7)

#define EMERGENCY_PRINT_STORE_GPR8	l.mtspr r0,r8,SPR_SHADOW_GPR(8)
#define EMERGENCY_PRINT_LOAD_GPR8	l.mfspr r8,r0,SPR_SHADOW_GPR(8)

#define EMERGENCY_PRINT_STORE_GPR9	l.mtspr r0,r9,SPR_SHADOW_GPR(9)
#define EMERGENCY_PRINT_LOAD_GPR9	l.mfspr r9,r0,SPR_SHADOW_GPR(9)

#else /* !CONFIG_OPENRISC_HAVE_SHADOW_GPRS */
#define EMERGENCY_PRINT_STORE_GPR4	l.sw    0x20(r0),r4
#define EMERGENCY_PRINT_LOAD_GPR4	l.lwz   r4,0x20(r0)

@@ -70,13 +92,28 @@
#define EMERGENCY_PRINT_STORE_GPR9	l.sw    0x34(r0),r9
#define EMERGENCY_PRINT_LOAD_GPR9	l.lwz   r9,0x34(r0)

#endif

/*
 * TLB miss handlers temorary stores
 */
#define EXCEPTION_STORE_GPR9		l.sw    0x10(r0),r9
#define EXCEPTION_LOAD_GPR9		l.lwz   r9,0x10(r0)
#ifdef CONFIG_OPENRISC_HAVE_SHADOW_GPRS
#define EXCEPTION_STORE_GPR2		l.mtspr r0,r2,SPR_SHADOW_GPR(2)
#define EXCEPTION_LOAD_GPR2		l.mfspr r2,r0,SPR_SHADOW_GPR(2)

#define EXCEPTION_STORE_GPR3		l.mtspr r0,r3,SPR_SHADOW_GPR(3)
#define EXCEPTION_LOAD_GPR3		l.mfspr r3,r0,SPR_SHADOW_GPR(3)

#define EXCEPTION_STORE_GPR4		l.mtspr r0,r4,SPR_SHADOW_GPR(4)
#define EXCEPTION_LOAD_GPR4		l.mfspr r4,r0,SPR_SHADOW_GPR(4)

#define EXCEPTION_STORE_GPR5		l.mtspr r0,r5,SPR_SHADOW_GPR(5)
#define EXCEPTION_LOAD_GPR5		l.mfspr r5,r0,SPR_SHADOW_GPR(5)

#define EXCEPTION_STORE_GPR6		l.mtspr r0,r6,SPR_SHADOW_GPR(6)
#define EXCEPTION_LOAD_GPR6		l.mfspr r6,r0,SPR_SHADOW_GPR(6)

#else /* !CONFIG_OPENRISC_HAVE_SHADOW_GPRS */
#define EXCEPTION_STORE_GPR2		l.sw    0x64(r0),r2
#define EXCEPTION_LOAD_GPR2		l.lwz   r2,0x64(r0)

@@ -92,11 +129,23 @@
#define EXCEPTION_STORE_GPR6		l.sw    0x74(r0),r6
#define EXCEPTION_LOAD_GPR6		l.lwz   r6,0x74(r0)

#endif

/*
 * EXCEPTION_HANDLE temporary stores
 */

#ifdef CONFIG_OPENRISC_HAVE_SHADOW_GPRS
#define EXCEPTION_T_STORE_GPR30		l.mtspr r0,r30,SPR_SHADOW_GPR(30)
#define EXCEPTION_T_LOAD_GPR30(reg)	l.mfspr reg,r0,SPR_SHADOW_GPR(30)

#define EXCEPTION_T_STORE_GPR10		l.mtspr r0,r10,SPR_SHADOW_GPR(10)
#define EXCEPTION_T_LOAD_GPR10(reg)	l.mfspr reg,r0,SPR_SHADOW_GPR(10)

#define EXCEPTION_T_STORE_SP		l.mtspr r0,r1,SPR_SHADOW_GPR(1)
#define EXCEPTION_T_LOAD_SP(reg)	l.mfspr reg,r0,SPR_SHADOW_GPR(1)

#else /* !CONFIG_OPENRISC_HAVE_SHADOW_GPRS */
#define EXCEPTION_T_STORE_GPR30		l.sw    0x78(r0),r30
#define EXCEPTION_T_LOAD_GPR30(reg)	l.lwz   reg,0x78(r0)

@@ -105,13 +154,7 @@

#define EXCEPTION_T_STORE_SP		l.sw    0x80(r0),r1
#define EXCEPTION_T_LOAD_SP(reg)	l.lwz   reg,0x80(r0)

/*
 * For UNHANLDED_EXCEPTION
 */

#define EXCEPTION_T_STORE_GPR31		l.sw    0x84(r0),r31
#define EXCEPTION_T_LOAD_GPR31(reg)	l.lwz   reg,0x84(r0)
#endif

/* =========================================================[ macros ]=== */

@@ -226,7 +269,7 @@
 *
 */
#define UNHANDLED_EXCEPTION(handler)				\
	EXCEPTION_T_STORE_GPR31					;\
	EXCEPTION_T_STORE_GPR30					;\
	EXCEPTION_T_STORE_GPR10					;\
	EXCEPTION_T_STORE_SP					;\
	/* temporary store r3, r9 into r1, r10 */		;\
@@ -255,35 +298,35 @@
	/* r1: KSP, r10: current, r31: __pa(KSP) */		;\
	/* r12:	temp, syscall indicator, r13 temp */		;\
	l.addi  r1,r1,-(INT_FRAME_SIZE)				;\
	/* r1 is KSP, r31 is __pa(KSP) */			;\
	tophys  (r31,r1)					;\
	l.sw    PT_GPR12(r31),r12					;\
	/* r1 is KSP, r30 is __pa(KSP) */			;\
	tophys  (r30,r1)					;\
	l.sw    PT_GPR12(r30),r12					;\
	l.mfspr r12,r0,SPR_EPCR_BASE				;\
	l.sw    PT_PC(r31),r12					;\
	l.sw    PT_PC(r30),r12					;\
	l.mfspr r12,r0,SPR_ESR_BASE				;\
	l.sw    PT_SR(r31),r12					;\
	l.sw    PT_SR(r30),r12					;\
	/* save r31 */						;\
	EXCEPTION_T_LOAD_GPR31(r12)				;\
	l.sw	PT_GPR31(r31),r12					;\
	EXCEPTION_T_LOAD_GPR30(r12)				;\
	l.sw	PT_GPR30(r30),r12					;\
	/* save r10 as was prior to exception */		;\
	EXCEPTION_T_LOAD_GPR10(r12)				;\
	l.sw	PT_GPR10(r31),r12					;\
	l.sw	PT_GPR10(r30),r12					;\
	/* save PT_SP as was prior to exception */			;\
	EXCEPTION_T_LOAD_SP(r12)				;\
	l.sw	PT_SP(r31),r12					;\
	l.sw    PT_GPR13(r31),r13					;\
	l.sw	PT_SP(r30),r12					;\
	l.sw    PT_GPR13(r30),r13					;\
	/* --> */						;\
	/* save exception r4, set r4 = EA */			;\
	l.sw	PT_GPR4(r31),r4					;\
	l.sw	PT_GPR4(r30),r4					;\
	l.mfspr r4,r0,SPR_EEAR_BASE				;\
	/* r12 == 1 if we come from syscall */			;\
	CLEAR_GPR(r12)						;\
	/* ----- play a MMU trick ----- */			;\
	l.ori	r31,r0,(EXCEPTION_SR)				;\
	l.mtspr	r0,r31,SPR_ESR_BASE				;\
	l.ori	r30,r0,(EXCEPTION_SR)				;\
	l.mtspr	r0,r30,SPR_ESR_BASE				;\
	/* r31:	EA address of handler */			;\
	LOAD_SYMBOL_2_GPR(r31,handler)				;\
	l.mtspr r0,r31,SPR_EPCR_BASE				;\
	LOAD_SYMBOL_2_GPR(r30,handler)				;\
	l.mtspr r0,r30,SPR_EPCR_BASE				;\
	l.rfe

/* =====================================================[ exceptions] === */