From e43994dfbb2c0ce9012c33c64f14533acc230366 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 27 Jun 2018 10:05:50 +0200 Subject: 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 c5d309a5d6..87e61f1ec9 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 61d3ffa3f7..888de27e8e 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 4952e29537..c56e1acab2 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 9180c92cd3..d293e24b00 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 b6de9e6f2b..1b82e2aa79 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 cc47bbb7c1..844d417738 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 -- cgit v1.2.3