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
|
||||
PUBLIC(_CPU_Context_switch)
|
||||
SYM(_CPU_Context_switch):
|
||||
! skip g0
|
||||
st %g1, [%o0 + G1_OFFSET] ! save the global registers
|
||||
std %g2, [%o0 + G2_OFFSET]
|
||||
std %g2, [%o0 + G2_OFFSET] ! save the global registers
|
||||
std %g4, [%o0 + G4_OFFSET]
|
||||
std %g6, [%o0 + G6_OFFSET]
|
||||
|
||||
@@ -68,10 +66,7 @@ SYM(_CPU_Context_switch):
|
||||
std %i4, [%o0 + I4_OFFSET]
|
||||
std %i6, [%o0 + I6_FP_OFFSET]
|
||||
|
||||
std %o0, [%o0 + O0_OFFSET] ! save the output registers
|
||||
std %o2, [%o0 + O2_OFFSET]
|
||||
std %o4, [%o0 + O4_OFFSET]
|
||||
std %o6, [%o0 + O6_SP_OFFSET]
|
||||
std %o6, [%o0 + O6_SP_OFFSET] ! save the output registers
|
||||
|
||||
! o3 = self per-CPU control
|
||||
GET_SELF_CPU_CONTROL %o3, %o4
|
||||
@@ -190,9 +185,7 @@ done_flushing:
|
||||
nop
|
||||
nop
|
||||
|
||||
! skip g0
|
||||
ld [%o1 + G1_OFFSET], %g1 ! restore the global registers
|
||||
ldd [%o1 + G2_OFFSET], %g2
|
||||
ldd [%o1 + G2_OFFSET], %g2 ! restore the global registers
|
||||
ldd [%o1 + G4_OFFSET], %g4
|
||||
ldd [%o1 + G6_OFFSET], %g6
|
||||
|
||||
@@ -213,11 +206,7 @@ done_flushing:
|
||||
ldd [%o1 + I4_OFFSET], %i4
|
||||
ldd [%o1 + I6_FP_OFFSET], %i6
|
||||
|
||||
ldd [%o1 + O2_OFFSET], %o2 ! 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
|
||||
ldd [%o1 + O6_SP_OFFSET], %o6 ! restore the output registers
|
||||
|
||||
jmp %o7 + 8 ! return
|
||||
nop ! delay slot
|
||||
|
||||
@@ -29,6 +29,44 @@ RTEMS_STATIC_ASSERT(
|
||||
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
|
||||
* table entry. The routine which installs a handler is responsible
|
||||
|
||||
@@ -401,20 +401,17 @@ typedef struct {
|
||||
/**
|
||||
* @brief SPARC basic context.
|
||||
*
|
||||
* This structure defines the basic integer and processor state context
|
||||
* for the SPARC architecture.
|
||||
* This structure defines the non-volatile integer and processor state context
|
||||
* for the SPARC architecture according to "SYSTEM V APPLICATION BINARY
|
||||
* INTERFACE - SPARC Processor Supplement", Third Edition.
|
||||
*/
|
||||
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
|
||||
* and stores safely in the context switch.
|
||||
*/
|
||||
double g0_g1;
|
||||
/** This will contain the contents of the g2 register. */
|
||||
uint32_t g2;
|
||||
/** This will contain the contents of the g3 register. */
|
||||
uint32_t g3;
|
||||
double g2_g3;
|
||||
/** This will contain the contents of the g4 register. */
|
||||
uint32_t g4;
|
||||
/** This will contain the contents of the g5 register. */
|
||||
@@ -458,21 +455,12 @@ typedef struct {
|
||||
/** This will contain the contents of the i7 register. */
|
||||
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. */
|
||||
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;
|
||||
|
||||
/** 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. */
|
||||
#define G0_OFFSET 0x00
|
||||
#define G2_OFFSET 0x00
|
||||
/** 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. */
|
||||
#define G2_OFFSET 0x08
|
||||
#define G4_OFFSET 0x08
|
||||
/** 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. */
|
||||
#define G4_OFFSET 0x10
|
||||
#define G6_OFFSET 0x10
|
||||
/** This macro defines an offset into the context for use in assembly. */
|
||||
#define G5_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
|
||||
#define G7_OFFSET 0x14
|
||||
|
||||
/** 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. */
|
||||
#define L1_OFFSET 0x24
|
||||
#define L1_OFFSET 0x1C
|
||||
/** 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. */
|
||||
#define L3_OFFSET 0x2C
|
||||
#define L3_OFFSET 0x24
|
||||
/** 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. */
|
||||
#define L5_OFFSET 0x34
|
||||
#define L5_OFFSET 0x2C
|
||||
/** 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. */
|
||||
#define L7_OFFSET 0x3C
|
||||
#define L7_OFFSET 0x34
|
||||
|
||||
/** 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. */
|
||||
#define I1_OFFSET 0x44
|
||||
#define I1_OFFSET 0x3C
|
||||
/** 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. */
|
||||
#define I3_OFFSET 0x4C
|
||||
#define I3_OFFSET 0x44
|
||||
/** 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. */
|
||||
#define I5_OFFSET 0x54
|
||||
#define I5_OFFSET 0x4C
|
||||
/** 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. */
|
||||
#define I7_OFFSET 0x5C
|
||||
#define I7_OFFSET 0x54
|
||||
|
||||
/** 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. */
|
||||
#define O1_OFFSET 0x64
|
||||
/** 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
|
||||
#define O7_OFFSET 0x5C
|
||||
|
||||
/** 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. */
|
||||
#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. */
|
||||
#define CONTEXT_CONTROL_SIZE 0x88
|
||||
#define CONTEXT_CONTROL_SIZE 0x68
|
||||
|
||||
#ifndef ASM
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user