[rtems commit] riscv: Optimize context switch and interrupts

Sebastian Huber sebh at rtems.org
Fri Jun 29 10:00:39 UTC 2018


Module:    rtems
Branch:    master
Commit:    e43994dfbb2c0ce9012c33c64f14533acc230366
Changeset: http://git.rtems.org/rtems/commit/?id=e43994dfbb2c0ce9012c33c64f14533acc230366

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed Jun 27 10:05:50 2018 +0200

riscv: Optimize context switch and interrupts

Save/restore non-volatile registers in _CPU_Context_switch().

Save/restore volatile registers in _ISR_Handler().

Update #3433.

---

 cpukit/score/cpu/riscv/cpu.c                       |  50 ++++++++
 cpukit/score/cpu/riscv/include/rtems/score/cpu.h   |  26 +++-
 .../score/cpu/riscv/include/rtems/score/cpuimpl.h  | 114 +++++++++++++++--
 cpukit/score/cpu/riscv/riscv-context-initialize.c  |   8 +-
 cpukit/score/cpu/riscv/riscv-context-switch.S      |  91 +++++---------
 cpukit/score/cpu/riscv/riscv-exception-handler.S   | 140 ++++++++-------------
 6 files changed, 255 insertions(+), 174 deletions(-)

diff --git a/cpukit/score/cpu/riscv/cpu.c b/cpukit/score/cpu/riscv/cpu.c
index c5d309a..87e61f1 100644
--- a/cpukit/score/cpu/riscv/cpu.c
+++ b/cpukit/score/cpu/riscv/cpu.c
@@ -40,6 +40,56 @@
   )
 
 RISCV_ASSERT_CONTEXT_OFFSET( isr_dispatch_disable, ISR_DISPATCH_DISABLE );
+#ifdef RTEMS_SMP
+RISCV_ASSERT_CONTEXT_OFFSET( is_executing, IS_EXECUTING );
+#endif
+RISCV_ASSERT_CONTEXT_OFFSET( ra, RA );
+RISCV_ASSERT_CONTEXT_OFFSET( sp, SP );
+RISCV_ASSERT_CONTEXT_OFFSET( tp, TP );
+RISCV_ASSERT_CONTEXT_OFFSET( s0, S0 );
+RISCV_ASSERT_CONTEXT_OFFSET( s1, S1 );
+RISCV_ASSERT_CONTEXT_OFFSET( s2, S2 );
+RISCV_ASSERT_CONTEXT_OFFSET( s3, S3 );
+RISCV_ASSERT_CONTEXT_OFFSET( s4, S4 );
+RISCV_ASSERT_CONTEXT_OFFSET( s5, S5 );
+RISCV_ASSERT_CONTEXT_OFFSET( s6, S6 );
+RISCV_ASSERT_CONTEXT_OFFSET( s7, S7 );
+RISCV_ASSERT_CONTEXT_OFFSET( s8, S8 );
+RISCV_ASSERT_CONTEXT_OFFSET( s9, S9 );
+RISCV_ASSERT_CONTEXT_OFFSET( s10, S10 );
+RISCV_ASSERT_CONTEXT_OFFSET( s11, S11 );
+
+#define RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( field, off ) \
+  RTEMS_STATIC_ASSERT( \
+    offsetof( CPU_Interrupt_frame, field) == RISCV_INTERRUPT_FRAME_ ## off, \
+    riscv_interrupt_frame_offset_ ## field \
+  )
+
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( mstatus, MSTATUS );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( mepc, MEPC );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a2, A2 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( s0, S0 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( s1, S1 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( ra, RA );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a3, A3 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a4, A4 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a5, A5 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a6, A6 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a7, A7 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( t0, T0 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( t1, T1 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( t2, T2 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( t3, T3 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( t4, T4 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( t5, T5 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( t6, T6 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a0, A0 );
+RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a1, A1 );
+
+RTEMS_STATIC_ASSERT(
+  sizeof( CPU_Interrupt_frame ) % CPU_STACK_ALIGNMENT == 0,
+  riscv_interrupt_frame_size
+);
 
 /* bsp_start_vector_table_begin is the start address of the vector table
  * containing addresses to ISR Handlers. It's defined at the BSP linkcmds
diff --git a/cpukit/score/cpu/riscv/include/rtems/score/cpu.h b/cpukit/score/cpu/riscv/include/rtems/score/cpu.h
index 61d3ffa..888de27 100644
--- a/cpukit/score/cpu/riscv/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/riscv/include/rtems/score/cpu.h
@@ -105,17 +105,31 @@ extern "C" {
 #ifndef ASM
 
 typedef struct {
-  /* riscv has 32 xlen-bit (where xlen can be 32 or 64) general purpose registers (x0-x31)*/
-  unsigned long x[32];
-
-  uint32_t isr_dispatch_disable;
 #ifdef RTEMS_SMP
-  volatile bool is_executing;
+  volatile uint32_t is_executing;
+#else
+  uint32_t reserved;
 #endif
+  uint32_t isr_dispatch_disable;
+  uintptr_t ra;
+  uintptr_t sp;
+  uintptr_t tp;
+  uintptr_t s0;
+  uintptr_t s1;
+  uintptr_t s2;
+  uintptr_t s3;
+  uintptr_t s4;
+  uintptr_t s5;
+  uintptr_t s6;
+  uintptr_t s7;
+  uintptr_t s8;
+  uintptr_t s9;
+  uintptr_t s10;
+  uintptr_t s11;
 } Context_Control;
 
 #define _CPU_Context_Get_SP( _context ) \
-  (_context)->x[2]
+  (_context)->sp
 
 typedef struct {
   /** TODO FPU registers are listed here */
diff --git a/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h
index 4952e29..c56e1ac 100644
--- a/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h
@@ -36,17 +36,93 @@
 
 #define CPU_PER_CPU_CONTROL_SIZE 0
 
-#if __riscv_xlen == 32
+#ifdef RTEMS_SMP
+#define RISCV_CONTEXT_IS_EXECUTING 0
+#endif
 
-#define RISCV_CONTEXT_ISR_DISPATCH_DISABLE 128
+#define RISCV_CONTEXT_ISR_DISPATCH_DISABLE 4
 
-#define CPU_INTERRUPT_FRAME_SIZE 140
+#if __riscv_xlen == 32
 
-#elif __riscv_xlen == 64
+#define RISCV_CONTEXT_RA 8
+#define RISCV_CONTEXT_SP 12
+#define RISCV_CONTEXT_TP 16
+#define RISCV_CONTEXT_S0 20
+#define RISCV_CONTEXT_S1 24
+#define RISCV_CONTEXT_S2 28
+#define RISCV_CONTEXT_S3 32
+#define RISCV_CONTEXT_S4 36
+#define RISCV_CONTEXT_S5 40
+#define RISCV_CONTEXT_S6 44
+#define RISCV_CONTEXT_S7 48
+#define RISCV_CONTEXT_S8 52
+#define RISCV_CONTEXT_S9 56
+#define RISCV_CONTEXT_S10 60
+#define RISCV_CONTEXT_S11 64
+
+#define RISCV_INTERRUPT_FRAME_MSTATUS 0
+#define RISCV_INTERRUPT_FRAME_MEPC 4
+#define RISCV_INTERRUPT_FRAME_A2 8
+#define RISCV_INTERRUPT_FRAME_S0 12
+#define RISCV_INTERRUPT_FRAME_S1 16
+#define RISCV_INTERRUPT_FRAME_RA 20
+#define RISCV_INTERRUPT_FRAME_A3 24
+#define RISCV_INTERRUPT_FRAME_A4 28
+#define RISCV_INTERRUPT_FRAME_A5 32
+#define RISCV_INTERRUPT_FRAME_A6 36
+#define RISCV_INTERRUPT_FRAME_A7 40
+#define RISCV_INTERRUPT_FRAME_T0 44
+#define RISCV_INTERRUPT_FRAME_T1 48
+#define RISCV_INTERRUPT_FRAME_T2 52
+#define RISCV_INTERRUPT_FRAME_T3 56
+#define RISCV_INTERRUPT_FRAME_T4 60
+#define RISCV_INTERRUPT_FRAME_T5 64
+#define RISCV_INTERRUPT_FRAME_T6 68
+#define RISCV_INTERRUPT_FRAME_A0 72
+#define RISCV_INTERRUPT_FRAME_A1 76
+
+#define CPU_INTERRUPT_FRAME_SIZE 80
 
-#define RISCV_CONTEXT_ISR_DISPATCH_DISABLE 256
+#elif __riscv_xlen == 64
 
-#define CPU_INTERRUPT_FRAME_SIZE 280
+#define RISCV_CONTEXT_RA 8
+#define RISCV_CONTEXT_SP 16
+#define RISCV_CONTEXT_TP 24
+#define RISCV_CONTEXT_S0 32
+#define RISCV_CONTEXT_S1 40
+#define RISCV_CONTEXT_S2 48
+#define RISCV_CONTEXT_S3 56
+#define RISCV_CONTEXT_S4 64
+#define RISCV_CONTEXT_S5 72
+#define RISCV_CONTEXT_S6 80
+#define RISCV_CONTEXT_S7 88
+#define RISCV_CONTEXT_S8 96
+#define RISCV_CONTEXT_S9 104
+#define RISCV_CONTEXT_S10 112
+#define RISCV_CONTEXT_S11 120
+
+#define RISCV_INTERRUPT_FRAME_MSTATUS 0
+#define RISCV_INTERRUPT_FRAME_MEPC 8
+#define RISCV_INTERRUPT_FRAME_A2 16
+#define RISCV_INTERRUPT_FRAME_S0 24
+#define RISCV_INTERRUPT_FRAME_S1 32
+#define RISCV_INTERRUPT_FRAME_RA 40
+#define RISCV_INTERRUPT_FRAME_A3 48
+#define RISCV_INTERRUPT_FRAME_A4 56
+#define RISCV_INTERRUPT_FRAME_A5 64
+#define RISCV_INTERRUPT_FRAME_A6 72
+#define RISCV_INTERRUPT_FRAME_A7 80
+#define RISCV_INTERRUPT_FRAME_T0 88
+#define RISCV_INTERRUPT_FRAME_T1 96
+#define RISCV_INTERRUPT_FRAME_T2 104
+#define RISCV_INTERRUPT_FRAME_T3 112
+#define RISCV_INTERRUPT_FRAME_T4 120
+#define RISCV_INTERRUPT_FRAME_T5 128
+#define RISCV_INTERRUPT_FRAME_T6 136
+#define RISCV_INTERRUPT_FRAME_A0 144
+#define RISCV_INTERRUPT_FRAME_A1 152
+
+#define CPU_INTERRUPT_FRAME_SIZE 160
 
 #endif /* __riscv_xlen */
 
@@ -57,11 +133,27 @@ extern "C" {
 #endif
 
 typedef struct {
-  unsigned long x[32];
-  unsigned long mstatus;
-  unsigned long mcause;
-  unsigned long mepc;
-} CPU_Interrupt_frame;
+  uintptr_t mstatus;
+  uintptr_t mepc;
+  uintptr_t a2;
+  uintptr_t s0;
+  uintptr_t s1;
+  uintptr_t ra;
+  uintptr_t a3;
+  uintptr_t a4;
+  uintptr_t a5;
+  uintptr_t a6;
+  uintptr_t a7;
+  uintptr_t t0;
+  uintptr_t t1;
+  uintptr_t t2;
+  uintptr_t t3;
+  uintptr_t t4;
+  uintptr_t t5;
+  uintptr_t t6;
+  uintptr_t a0;
+  uintptr_t a1;
+} RTEMS_ALIGNED( CPU_STACK_ALIGNMENT ) CPU_Interrupt_frame;
 
 #ifdef RTEMS_SMP
 
diff --git a/cpukit/score/cpu/riscv/riscv-context-initialize.c b/cpukit/score/cpu/riscv/riscv-context-initialize.c
index 9180c92..d293e24 100644
--- a/cpukit/score/cpu/riscv/riscv-context-initialize.c
+++ b/cpukit/score/cpu/riscv/riscv-context-initialize.c
@@ -51,11 +51,7 @@ void _CPU_Context_Initialize(
   stack = _Addresses_Add_offset( stack_area_begin, stack_area_size );
   stack = _Addresses_Align_down( stack, CPU_STACK_ALIGNMENT );
 
-  /* Stack Pointer - sp/x2 */
-  context->x[2] = (uintptr_t) stack;
-
-  /* Return Address - ra/x1 */
-  context->x[1] = (uintptr_t) entry_point;
-
+  context->ra = (uintptr_t) entry_point;
+  context->sp = (uintptr_t) stack;
   context->isr_dispatch_disable = 0;
 }
diff --git a/cpukit/score/cpu/riscv/riscv-context-switch.S b/cpukit/score/cpu/riscv/riscv-context-switch.S
index b6de9e6..1b82e2a 100644
--- a/cpukit/score/cpu/riscv/riscv-context-switch.S
+++ b/cpukit/score/cpu/riscv/riscv-context-switch.S
@@ -45,75 +45,42 @@ SYM(_CPU_Context_switch):
 	GET_SELF_CPU_CONTROL	a2
 	lw	a3, PER_CPU_ISR_DISPATCH_DISABLE(a2)
 
-	SREG	x1, (1 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x2, (2 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x4, (4 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x5, (5 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x6, (6 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x7, (7 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x8, (8 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x9, (9 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x10, (10 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x11, (11 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x12, (12 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x13, (13 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x14, (14 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x15, (15 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x16, (16 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x17, (17 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x18, (18 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x19, (19 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x20, (20 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x21, (21 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x22, (22 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x23, (23 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x24, (24 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x25, (25 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x26, (26 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x27, (27 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x28, (28 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x29, (28 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x30, (30 * CPU_SIZEOF_POINTER)(a0)
-	SREG	x31, (31 * CPU_SIZEOF_POINTER)(a0)
+	SREG	ra, RISCV_CONTEXT_RA(a0)
+	SREG	sp, RISCV_CONTEXT_SP(a0)
+	SREG	s0, RISCV_CONTEXT_S0(a0)
+	SREG	s1, RISCV_CONTEXT_S1(a0)
+	SREG	s2, RISCV_CONTEXT_S2(a0)
+	SREG	s3, RISCV_CONTEXT_S3(a0)
+	SREG	s4, RISCV_CONTEXT_S4(a0)
+	SREG	s5, RISCV_CONTEXT_S5(a0)
+	SREG	s6, RISCV_CONTEXT_S6(a0)
+	SREG	s7, RISCV_CONTEXT_S7(a0)
+	SREG	s8, RISCV_CONTEXT_S8(a0)
+	SREG	s9, RISCV_CONTEXT_S9(a0)
+	SREG	s10, RISCV_CONTEXT_S10(a0)
+	SREG	s11, RISCV_CONTEXT_S11(a0)
 
 	sw	a3, RISCV_CONTEXT_ISR_DISPATCH_DISABLE(a0)
 
 .Lrestore:
 	lw	a3, RISCV_CONTEXT_ISR_DISPATCH_DISABLE(a1)
 
-	sw	a3, PER_CPU_ISR_DISPATCH_DISABLE(a2)
-
-	LREG	x1, (1 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x2, (2 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x4, (4 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x5, (5 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x6, (6 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x7, (7 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x8, (8 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x9, (9 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x10, (10 * CPU_SIZEOF_POINTER)(a1)
-	/* Skip a1/x11 */
-	LREG	x12, (12 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x13, (13 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x14, (14 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x15, (15 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x16, (16 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x17, (17 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x18, (18 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x19, (19 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x20, (20 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x21, (21 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x22, (22 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x23, (23 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x24, (24 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x25, (25 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x26, (26 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x27, (27 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x28, (28 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x29, (29 * CPU_SIZEOF_POINTER)(a1)
-	LREG	x30, (30 * CPU_SIZEOF_POINTER)(a1)
+	LREG	ra, RISCV_CONTEXT_RA(a1)
+	LREG	sp, RISCV_CONTEXT_SP(a1)
+	LREG	s0, RISCV_CONTEXT_S0(a1)
+	LREG	s1, RISCV_CONTEXT_S1(a1)
+	LREG	s2, RISCV_CONTEXT_S2(a1)
+	LREG	s3, RISCV_CONTEXT_S3(a1)
+	LREG	s4, RISCV_CONTEXT_S4(a1)
+	LREG	s5, RISCV_CONTEXT_S5(a1)
+	LREG	s6, RISCV_CONTEXT_S6(a1)
+	LREG	s7, RISCV_CONTEXT_S7(a1)
+	LREG	s8, RISCV_CONTEXT_S8(a1)
+	LREG	s9, RISCV_CONTEXT_S9(a1)
+	LREG	s10, RISCV_CONTEXT_S10(a1)
+	LREG	s11, RISCV_CONTEXT_S11(a1)
 
-	LREG	x11, (11 * CPU_SIZEOF_POINTER)(a1)
+	sw	a3, PER_CPU_ISR_DISPATCH_DISABLE(a2)
 
 	ret
 
diff --git a/cpukit/score/cpu/riscv/riscv-exception-handler.S b/cpukit/score/cpu/riscv/riscv-exception-handler.S
index cc47bbb..844d417 100644
--- a/cpukit/score/cpu/riscv/riscv-exception-handler.S
+++ b/cpukit/score/cpu/riscv/riscv-exception-handler.S
@@ -50,54 +50,37 @@ PUBLIC(ISR_Handler)
 
 TYPE_FUNC(ISR_Handler)
 SYM(ISR_Handler):
-	addi	sp, sp, -1 * 36 * CPU_SIZEOF_POINTER
-
-	SREG	x1, (1 * CPU_SIZEOF_POINTER)(sp)
-	/* Skip x2/sp */
-	SREG	x3, (3 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x4, (4 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x5, (5 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x6, (6 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x7, (7 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x8, (8 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x9, (9 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x10, (10 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x11, (11 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x12, (12 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x13, (13 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x14, (14 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x15, (15 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x16, (16 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x17, (17 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x18, (18 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x19, (19 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x20, (20 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x21, (21 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x22, (22 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x23, (23 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x24, (24 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x25, (25 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x26, (26 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x27, (27 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x28, (28 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x29, (29 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x30, (30 * CPU_SIZEOF_POINTER)(sp)
-	SREG	x31, (31 * CPU_SIZEOF_POINTER)(sp)
-
-	/* Exception level related registers */
-	csrr	a0, mstatus
-	SREG	a0, (32 * CPU_SIZEOF_POINTER)(sp)
+	addi	sp, sp, -CPU_INTERRUPT_FRAME_SIZE
+
+	/* Save */
+	SREG	a0, RISCV_INTERRUPT_FRAME_A0(sp)
+	SREG	a1, RISCV_INTERRUPT_FRAME_A1(sp)
+	SREG	a2, RISCV_INTERRUPT_FRAME_A2(sp)
+	SREG	s0, RISCV_INTERRUPT_FRAME_S0(sp)
 	csrr	a0, mcause
-	SREG	a0, (33 * CPU_SIZEOF_POINTER)(sp)
-	csrr	a1, mepc
-	SREG	a1, (34 * CPU_SIZEOF_POINTER)(sp)
+	csrr	a1, mstatus
+	csrr	a2, mepc
+	GET_SELF_CPU_CONTROL	s0
+	SREG	s1, RISCV_INTERRUPT_FRAME_S1(sp)
+	SREG	ra, RISCV_INTERRUPT_FRAME_RA(sp)
+	SREG	a3, RISCV_INTERRUPT_FRAME_A3(sp)
+	SREG	a4, RISCV_INTERRUPT_FRAME_A4(sp)
+	SREG	a5, RISCV_INTERRUPT_FRAME_A5(sp)
+	SREG	a6, RISCV_INTERRUPT_FRAME_A6(sp)
+	SREG	a7, RISCV_INTERRUPT_FRAME_A7(sp)
+	SREG	t0, RISCV_INTERRUPT_FRAME_T0(sp)
+	SREG	t1, RISCV_INTERRUPT_FRAME_T1(sp)
+	SREG	t2, RISCV_INTERRUPT_FRAME_T2(sp)
+	SREG	t3, RISCV_INTERRUPT_FRAME_T3(sp)
+	SREG	t4, RISCV_INTERRUPT_FRAME_T4(sp)
+	SREG	t5, RISCV_INTERRUPT_FRAME_T5(sp)
+	SREG	t6, RISCV_INTERRUPT_FRAME_T6(sp)
+	SREG	a1, RISCV_INTERRUPT_FRAME_MSTATUS(sp)
+	SREG	a2, RISCV_INTERRUPT_FRAME_MEPC(sp)
 
 	/* FIXME Only handle interrupts for now (MSB = 1) */
 	andi	a0, a0, 0xf
 
-	/* Get per-CPU control of current processor */
-	GET_SELF_CPU_CONTROL	s0
-
 	/* Increment interrupt nest and thread dispatch disable level */
 	lw	t0, PER_CPU_ISR_NEST_LEVEL(s0)
 	lw	t1, PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL(s0)
@@ -106,10 +89,6 @@ SYM(ISR_Handler):
 	sw	t2, PER_CPU_ISR_NEST_LEVEL(s0)
 	sw	t1, PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL(s0)
 
-	/* Save interrupted task stack pointer */
-	addi	t4, sp, 36 * CPU_SIZEOF_POINTER
-	SREG	t4, (2 * CPU_SIZEOF_POINTER)(sp)
-
 	/* Keep sp (Exception frame address) in s1 */
 	mv	s1, sp
 
@@ -191,47 +170,30 @@ SYM(ISR_Handler):
 
 .Lthread_dispatch_done:
 
-	LREG	x1, (1 * CPU_SIZEOF_POINTER)(sp)
-	/* Skip sp/x2 */
-	LREG	x3, (3 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x4, (4 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x5, (5 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x6, (6 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x7, (7 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x8, (8 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x9, (9 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x10, (10 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x11, (11 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x12, (12 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x13, (13 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x14, (14 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x15, (15 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x16, (16 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x17, (17 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x18, (18 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x19, (19 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x20, (20 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x21, (21 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x22, (22 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x23, (23 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x24, (24 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x25, (25 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x26, (26 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x27, (27 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x28, (28 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x29, (29 * CPU_SIZEOF_POINTER)(sp)
-	LREG	x30, (30 * CPU_SIZEOF_POINTER)(sp)
-
-	/* Load mstatus */
-	LREG	x31, (32 * CPU_SIZEOF_POINTER)(sp)
-	csrw	mstatus, x31
-	/* Load mepc */
-	LREG	x31, (34 * CPU_SIZEOF_POINTER)(sp)
-	csrw	mepc, x31
-
-	LREG	x31, (31 * CPU_SIZEOF_POINTER)(sp)
-
-	/* Unwind exception frame */
-	addi	sp, sp, 36 * CPU_SIZEOF_POINTER
+	/* Restore */
+	LREG	a0, RISCV_INTERRUPT_FRAME_MSTATUS(sp)
+	LREG	a1, RISCV_INTERRUPT_FRAME_MEPC(sp)
+	LREG	a2, RISCV_INTERRUPT_FRAME_A2(sp)
+	LREG	s0, RISCV_INTERRUPT_FRAME_S0(sp)
+	LREG	s1, RISCV_INTERRUPT_FRAME_S1(sp)
+	LREG	ra, RISCV_INTERRUPT_FRAME_RA(sp)
+	LREG	a3, RISCV_INTERRUPT_FRAME_A3(sp)
+	LREG	a4, RISCV_INTERRUPT_FRAME_A4(sp)
+	LREG	a5, RISCV_INTERRUPT_FRAME_A5(sp)
+	LREG	a6, RISCV_INTERRUPT_FRAME_A6(sp)
+	LREG	a7, RISCV_INTERRUPT_FRAME_A7(sp)
+	LREG	t0, RISCV_INTERRUPT_FRAME_T0(sp)
+	LREG	t1, RISCV_INTERRUPT_FRAME_T1(sp)
+	LREG	t2, RISCV_INTERRUPT_FRAME_T2(sp)
+	LREG	t3, RISCV_INTERRUPT_FRAME_T3(sp)
+	LREG	t4, RISCV_INTERRUPT_FRAME_T4(sp)
+	LREG	t5, RISCV_INTERRUPT_FRAME_T5(sp)
+	LREG	t6, RISCV_INTERRUPT_FRAME_T6(sp)
+	csrw	mstatus, a0
+	csrw	mepc, a1
+	LREG	a0, RISCV_INTERRUPT_FRAME_A0(sp)
+	LREG	a1, RISCV_INTERRUPT_FRAME_A1(sp)
+
+	addi	sp, sp, CPU_INTERRUPT_FRAME_SIZE
 
 	mret



More information about the vc mailing list