diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-02-05 11:36:05 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-02-12 09:18:00 +0100 |
commit | 97cf623d4ada641b0a59321f0e75a6b323ecf193 (patch) | |
tree | 995ca3143804849f95c778e38c21c33cf2421faa /c | |
parent | bsps/sparc: Fix ambapp_find_by_idx() (diff) | |
download | rtems-97cf623d4ada641b0a59321f0e75a6b323ecf193.tar.bz2 |
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.
Diffstat (limited to '')
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/irq_asm.S | 19 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/cpu.c | 38 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/rtems/score/cpu.h | 100 |
3 files changed, 78 insertions, 79 deletions
diff --git a/c/src/lib/libbsp/sparc/shared/irq_asm.S b/c/src/lib/libbsp/sparc/shared/irq_asm.S index dbf4af93bd..684e7835cb 100644 --- a/c/src/lib/libbsp/sparc/shared/irq_asm.S +++ b/c/src/lib/libbsp/sparc/shared/irq_asm.S @@ -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 diff --git a/cpukit/score/cpu/sparc/cpu.c b/cpukit/score/cpu/sparc/cpu.c index 11e31f9d10..3e08c26af7 100644 --- a/cpukit/score/cpu/sparc/cpu.c +++ b/cpukit/score/cpu/sparc/cpu.c @@ -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 diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h index ad0cbd2928..9706e45668 100644 --- a/cpukit/score/cpu/sparc/rtems/score/cpu.h +++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h @@ -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 -/** This macro defines an offset into the context for use in assembly. */ -#define G1_OFFSET 0x04 +#define G2_OFFSET 0x00 /** This macro defines an offset into the context for use in assembly. */ -#define G2_OFFSET 0x08 +#define G3_OFFSET 0x04 /** This macro defines an offset into the context for use in assembly. */ -#define G3_OFFSET 0x0C +#define G4_OFFSET 0x08 /** This macro defines an offset into the context for use in assembly. */ -#define G4_OFFSET 0x10 +#define G5_OFFSET 0x0C /** This macro defines an offset into the context for use in assembly. */ -#define G5_OFFSET 0x14 +#define G6_OFFSET 0x10 /** 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 -/** 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 +#define O6_SP_OFFSET 0x58 /** 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 /** |