forked from Imagelibrary/rtems
sparc: Save/restore only non-volatile context
The _CPU_Context_switch() is a normal function call. The following registers are volatile (the caller must assume that the register contents are destroyed by the callee) according to "SYSTEM V APPLICATION BINARY INTERFACE - SPARC Processor Supplement", Third Edition: g1, o0, o1, o2, o3, o4, o5. Drop these registers from the context. Ensure that offset defines match the structure offsets.
This commit is contained in:
@@ -52,9 +52,7 @@
|
|||||||
.align 4
|
.align 4
|
||||||
PUBLIC(_CPU_Context_switch)
|
PUBLIC(_CPU_Context_switch)
|
||||||
SYM(_CPU_Context_switch):
|
SYM(_CPU_Context_switch):
|
||||||
! skip g0
|
std %g2, [%o0 + G2_OFFSET] ! save the global registers
|
||||||
st %g1, [%o0 + G1_OFFSET] ! save the global registers
|
|
||||||
std %g2, [%o0 + G2_OFFSET]
|
|
||||||
std %g4, [%o0 + G4_OFFSET]
|
std %g4, [%o0 + G4_OFFSET]
|
||||||
std %g6, [%o0 + G6_OFFSET]
|
std %g6, [%o0 + G6_OFFSET]
|
||||||
|
|
||||||
@@ -68,10 +66,7 @@ SYM(_CPU_Context_switch):
|
|||||||
std %i4, [%o0 + I4_OFFSET]
|
std %i4, [%o0 + I4_OFFSET]
|
||||||
std %i6, [%o0 + I6_FP_OFFSET]
|
std %i6, [%o0 + I6_FP_OFFSET]
|
||||||
|
|
||||||
std %o0, [%o0 + O0_OFFSET] ! save the output registers
|
std %o6, [%o0 + O6_SP_OFFSET] ! save the output registers
|
||||||
std %o2, [%o0 + O2_OFFSET]
|
|
||||||
std %o4, [%o0 + O4_OFFSET]
|
|
||||||
std %o6, [%o0 + O6_SP_OFFSET]
|
|
||||||
|
|
||||||
! o3 = self per-CPU control
|
! o3 = self per-CPU control
|
||||||
GET_SELF_CPU_CONTROL %o3, %o4
|
GET_SELF_CPU_CONTROL %o3, %o4
|
||||||
@@ -190,9 +185,7 @@ done_flushing:
|
|||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
|
|
||||||
! skip g0
|
ldd [%o1 + G2_OFFSET], %g2 ! restore the global registers
|
||||||
ld [%o1 + G1_OFFSET], %g1 ! restore the global registers
|
|
||||||
ldd [%o1 + G2_OFFSET], %g2
|
|
||||||
ldd [%o1 + G4_OFFSET], %g4
|
ldd [%o1 + G4_OFFSET], %g4
|
||||||
ldd [%o1 + G6_OFFSET], %g6
|
ldd [%o1 + G6_OFFSET], %g6
|
||||||
|
|
||||||
@@ -213,11 +206,7 @@ done_flushing:
|
|||||||
ldd [%o1 + I4_OFFSET], %i4
|
ldd [%o1 + I4_OFFSET], %i4
|
||||||
ldd [%o1 + I6_FP_OFFSET], %i6
|
ldd [%o1 + I6_FP_OFFSET], %i6
|
||||||
|
|
||||||
ldd [%o1 + O2_OFFSET], %o2 ! restore the output registers
|
ldd [%o1 + O6_SP_OFFSET], %o6 ! restore the output registers
|
||||||
ldd [%o1 + O4_OFFSET], %o4
|
|
||||||
ldd [%o1 + O6_SP_OFFSET], %o6
|
|
||||||
! do o0/o1 last to avoid destroying heir context pointer
|
|
||||||
ldd [%o1 + O0_OFFSET], %o0 ! overwrite heir pointer
|
|
||||||
|
|
||||||
jmp %o7 + 8 ! return
|
jmp %o7 + 8 ! return
|
||||||
nop ! delay slot
|
nop ! delay slot
|
||||||
|
|||||||
@@ -29,6 +29,44 @@ RTEMS_STATIC_ASSERT(
|
|||||||
SPARC_PER_CPU_ISR_DISPATCH_DISABLE
|
SPARC_PER_CPU_ISR_DISPATCH_DISABLE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#define SPARC_ASSERT_OFFSET(field, off) \
|
||||||
|
RTEMS_STATIC_ASSERT( \
|
||||||
|
offsetof(Context_Control, field) == off ## _OFFSET, \
|
||||||
|
Context_Control_offset_ ## field \
|
||||||
|
)
|
||||||
|
|
||||||
|
SPARC_ASSERT_OFFSET(g2_g3, G2);
|
||||||
|
SPARC_ASSERT_OFFSET(g4, G4);
|
||||||
|
SPARC_ASSERT_OFFSET(g5, G5);
|
||||||
|
SPARC_ASSERT_OFFSET(g6, G6);
|
||||||
|
SPARC_ASSERT_OFFSET(g7, G7);
|
||||||
|
SPARC_ASSERT_OFFSET(l0, L0);
|
||||||
|
SPARC_ASSERT_OFFSET(l1, L1);
|
||||||
|
SPARC_ASSERT_OFFSET(l2, L2);
|
||||||
|
SPARC_ASSERT_OFFSET(l3, L3);
|
||||||
|
SPARC_ASSERT_OFFSET(l4, L4);
|
||||||
|
SPARC_ASSERT_OFFSET(l5, L5);
|
||||||
|
SPARC_ASSERT_OFFSET(l6, L6);
|
||||||
|
SPARC_ASSERT_OFFSET(l7, L7);
|
||||||
|
SPARC_ASSERT_OFFSET(i0, I0);
|
||||||
|
SPARC_ASSERT_OFFSET(i1, I1);
|
||||||
|
SPARC_ASSERT_OFFSET(i2, I2);
|
||||||
|
SPARC_ASSERT_OFFSET(i3, I3);
|
||||||
|
SPARC_ASSERT_OFFSET(i4, I4);
|
||||||
|
SPARC_ASSERT_OFFSET(i5, I5);
|
||||||
|
SPARC_ASSERT_OFFSET(i6_fp, I6_FP);
|
||||||
|
SPARC_ASSERT_OFFSET(i7, I7);
|
||||||
|
SPARC_ASSERT_OFFSET(o6_sp, O6_SP);
|
||||||
|
SPARC_ASSERT_OFFSET(o7, O7);
|
||||||
|
SPARC_ASSERT_OFFSET(psr, PSR);
|
||||||
|
SPARC_ASSERT_OFFSET(isr_dispatch_disable, ISR_DISPATCH_DISABLE_STACK);
|
||||||
|
|
||||||
|
RTEMS_STATIC_ASSERT(
|
||||||
|
(offsetof(Context_Control, g2_g3)
|
||||||
|
+ offsetof(Context_Control, g4)) / 2 == G3_OFFSET,
|
||||||
|
Context_Control_offset_G3
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This initializes the set of opcodes placed in each trap
|
* This initializes the set of opcodes placed in each trap
|
||||||
* table entry. The routine which installs a handler is responsible
|
* table entry. The routine which installs a handler is responsible
|
||||||
|
|||||||
@@ -401,20 +401,17 @@ typedef struct {
|
|||||||
/**
|
/**
|
||||||
* @brief SPARC basic context.
|
* @brief SPARC basic context.
|
||||||
*
|
*
|
||||||
* This structure defines the basic integer and processor state context
|
* This structure defines the non-volatile integer and processor state context
|
||||||
* for the SPARC architecture.
|
* for the SPARC architecture according to "SYSTEM V APPLICATION BINARY
|
||||||
|
* INTERFACE - SPARC Processor Supplement", Third Edition.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/**
|
/**
|
||||||
* Using a double g0_g1 will put everything in this structure on a
|
* Using a double g2_g3 will put everything in this structure on a
|
||||||
* double word boundary which allows us to use double word loads
|
* double word boundary which allows us to use double word loads
|
||||||
* and stores safely in the context switch.
|
* and stores safely in the context switch.
|
||||||
*/
|
*/
|
||||||
double g0_g1;
|
double g2_g3;
|
||||||
/** This will contain the contents of the g2 register. */
|
|
||||||
uint32_t g2;
|
|
||||||
/** This will contain the contents of the g3 register. */
|
|
||||||
uint32_t g3;
|
|
||||||
/** This will contain the contents of the g4 register. */
|
/** This will contain the contents of the g4 register. */
|
||||||
uint32_t g4;
|
uint32_t g4;
|
||||||
/** This will contain the contents of the g5 register. */
|
/** This will contain the contents of the g5 register. */
|
||||||
@@ -458,21 +455,12 @@ typedef struct {
|
|||||||
/** This will contain the contents of the i7 register. */
|
/** This will contain the contents of the i7 register. */
|
||||||
uint32_t i7;
|
uint32_t i7;
|
||||||
|
|
||||||
/** This will contain the contents of the o0 register. */
|
|
||||||
uint32_t o0;
|
|
||||||
/** This will contain the contents of the o1 register. */
|
|
||||||
uint32_t o1;
|
|
||||||
/** This will contain the contents of the o2 register. */
|
|
||||||
uint32_t o2;
|
|
||||||
/** This will contain the contents of the o3 register. */
|
|
||||||
uint32_t o3;
|
|
||||||
/** This will contain the contents of the o4 register. */
|
|
||||||
uint32_t o4;
|
|
||||||
/** This will contain the contents of the o5 register. */
|
|
||||||
uint32_t o5;
|
|
||||||
/** This will contain the contents of the o6 (e.g. frame pointer) register. */
|
/** This will contain the contents of the o6 (e.g. frame pointer) register. */
|
||||||
uint32_t o6_sp;
|
uint32_t o6_sp;
|
||||||
/** This will contain the contents of the o7 register. */
|
/**
|
||||||
|
* This will contain the contents of the o7 (e.g. address of CALL
|
||||||
|
* instruction) register.
|
||||||
|
*/
|
||||||
uint32_t o7;
|
uint32_t o7;
|
||||||
|
|
||||||
/** This will contain the contents of the processor status register. */
|
/** This will contain the contents of the processor status register. */
|
||||||
@@ -500,80 +488,64 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define G0_OFFSET 0x00
|
#define G2_OFFSET 0x00
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define G1_OFFSET 0x04
|
#define G3_OFFSET 0x04
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define G2_OFFSET 0x08
|
#define G4_OFFSET 0x08
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define G3_OFFSET 0x0C
|
#define G5_OFFSET 0x0C
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define G4_OFFSET 0x10
|
#define G6_OFFSET 0x10
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define G5_OFFSET 0x14
|
#define G7_OFFSET 0x14
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
|
||||||
#define G6_OFFSET 0x18
|
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
|
||||||
#define G7_OFFSET 0x1C
|
|
||||||
|
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define L0_OFFSET 0x20
|
#define L0_OFFSET 0x18
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define L1_OFFSET 0x24
|
#define L1_OFFSET 0x1C
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define L2_OFFSET 0x28
|
#define L2_OFFSET 0x20
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define L3_OFFSET 0x2C
|
#define L3_OFFSET 0x24
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define L4_OFFSET 0x30
|
#define L4_OFFSET 0x28
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define L5_OFFSET 0x34
|
#define L5_OFFSET 0x2C
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define L6_OFFSET 0x38
|
#define L6_OFFSET 0x30
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define L7_OFFSET 0x3C
|
#define L7_OFFSET 0x34
|
||||||
|
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define I0_OFFSET 0x40
|
#define I0_OFFSET 0x38
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define I1_OFFSET 0x44
|
#define I1_OFFSET 0x3C
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define I2_OFFSET 0x48
|
#define I2_OFFSET 0x40
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define I3_OFFSET 0x4C
|
#define I3_OFFSET 0x44
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define I4_OFFSET 0x50
|
#define I4_OFFSET 0x48
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define I5_OFFSET 0x54
|
#define I5_OFFSET 0x4C
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define I6_FP_OFFSET 0x58
|
#define I6_FP_OFFSET 0x50
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define I7_OFFSET 0x5C
|
#define I7_OFFSET 0x54
|
||||||
|
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define O0_OFFSET 0x60
|
#define O6_SP_OFFSET 0x58
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define O1_OFFSET 0x64
|
#define O7_OFFSET 0x5C
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
|
||||||
#define O2_OFFSET 0x68
|
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
|
||||||
#define O3_OFFSET 0x6C
|
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
|
||||||
#define O4_OFFSET 0x70
|
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
|
||||||
#define O5_OFFSET 0x74
|
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
|
||||||
#define O6_SP_OFFSET 0x78
|
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
|
||||||
#define O7_OFFSET 0x7C
|
|
||||||
|
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define PSR_OFFSET 0x80
|
#define PSR_OFFSET 0x60
|
||||||
/** This macro defines an offset into the context for use in assembly. */
|
/** This macro defines an offset into the context for use in assembly. */
|
||||||
#define ISR_DISPATCH_DISABLE_STACK_OFFSET 0x84
|
#define ISR_DISPATCH_DISABLE_STACK_OFFSET 0x64
|
||||||
|
|
||||||
/** This defines the size of the context area for use in assembly. */
|
/** This defines the size of the context area for use in assembly. */
|
||||||
#define CONTEXT_CONTROL_SIZE 0x88
|
#define CONTEXT_CONTROL_SIZE 0x68
|
||||||
|
|
||||||
#ifndef ASM
|
#ifndef ASM
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user