From 8db3f0e878b7f008ad05716f501220509662e2c4 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 19 Jul 2018 12:11:19 +0200 Subject: riscv: Rework exception handling Remove _CPU_ISR_install_raw_handler() and _CPU_ISR_install_vector() functions. Applications can install an exception handler via the fatal error handler to handle synchronous exceptions. Handle interrupt exceptions via _RISCV_Interrupt_dispatch() which must be provided by the BSP. Update #3433. --- cpukit/score/cpu/riscv/Makefile.am | 1 - cpukit/score/cpu/riscv/cpu.c | 46 ------------- cpukit/score/cpu/riscv/include/rtems/score/cpu.h | 30 --------- .../score/cpu/riscv/include/rtems/score/cpuimpl.h | 7 ++ cpukit/score/cpu/riscv/riscv-exception-default.c | 39 ----------- cpukit/score/cpu/riscv/riscv-exception-handler.S | 75 ++++++++++++++-------- 6 files changed, 54 insertions(+), 144 deletions(-) delete mode 100644 cpukit/score/cpu/riscv/riscv-exception-default.c (limited to 'cpukit/score/cpu/riscv') diff --git a/cpukit/score/cpu/riscv/Makefile.am b/cpukit/score/cpu/riscv/Makefile.am index 3630c038a7..40fcd1ff75 100644 --- a/cpukit/score/cpu/riscv/Makefile.am +++ b/cpukit/score/cpu/riscv/Makefile.am @@ -3,7 +3,6 @@ noinst_LIBRARIES = libscorecpu.a libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS) libscorecpu_a_SOURCES = cpu.c libscorecpu_a_SOURCES += riscv-exception-handler.S -libscorecpu_a_SOURCES += riscv-exception-default.c libscorecpu_a_SOURCES += riscv-exception-frame-print.c libscorecpu_a_SOURCES += riscv-context-switch.S libscorecpu_a_SOURCES += riscv-context-initialize.c diff --git a/cpukit/score/cpu/riscv/cpu.c b/cpukit/score/cpu/riscv/cpu.c index 6b29de2273..64eef969b7 100644 --- a/cpukit/score/cpu/riscv/cpu.c +++ b/cpukit/score/cpu/riscv/cpu.c @@ -173,12 +173,6 @@ RTEMS_STATIC_ASSERT( 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 - * and may differ from one BSP to another. - */ -extern char bsp_start_vector_table_begin[]; - void _init(void); void _fini(void); @@ -208,46 +202,6 @@ uint32_t _CPU_ISR_Get_level( void ) return 1; } -void _CPU_ISR_install_raw_handler( - uint32_t vector, - proc_ptr new_handler, - proc_ptr *old_handler -) -{ - /* Do nothing */ -} - -void _CPU_ISR_install_vector( - unsigned long vector, - proc_ptr new_handler, - proc_ptr *old_handler -) -{ - proc_ptr *table = - (proc_ptr *) bsp_start_vector_table_begin; - proc_ptr current_handler; - - ISR_Level level; - - _ISR_Local_disable( level ); - - current_handler = table [vector]; - - /* The current handler is now the old one */ - if (old_handler != NULL) { - *old_handler = (proc_ptr) current_handler; - } - - /* Write only if necessary to avoid writes to a maybe read-only - * memory */ - if (current_handler != new_handler) { - table [vector] = new_handler; - } - - _ISR_Local_enable( level ); - -} - void *_CPU_Thread_Idle_body( uintptr_t ignored ) { do { diff --git a/cpukit/score/cpu/riscv/include/rtems/score/cpu.h b/cpukit/score/cpu/riscv/include/rtems/score/cpu.h index 5553fa9d05..724385cd75 100644 --- a/cpukit/score/cpu/riscv/include/rtems/score/cpu.h +++ b/cpukit/score/cpu/riscv/include/rtems/score/cpu.h @@ -360,36 +360,6 @@ void _CPU_Initialize( void ); -/* - * _CPU_ISR_install_raw_handler - * - * This routine installs a "raw" interrupt handler directly into the - * processor's vector table. - * - */ - -void _CPU_ISR_install_raw_handler( - uint32_t vector, - proc_ptr new_handler, - proc_ptr *old_handler -); - -/* - * _CPU_ISR_install_vector - * - * This routine installs an interrupt vector. - * - * NO_CPU Specific Information: - * - * XXX document implementation including references if appropriate - */ - -void _CPU_ISR_install_vector( - unsigned long vector, - proc_ptr new_handler, - proc_ptr *old_handler -); - /* * _CPU_Thread_Idle_body * diff --git a/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h index cb60a528de..313b671da0 100644 --- a/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h @@ -289,6 +289,13 @@ typedef struct { } CPU_Per_CPU_control; #endif +struct Per_CPU_Control; + +void _RISCV_Interrupt_dispatch( + uintptr_t mcause, + struct Per_CPU_Control *cpu_self +); + static inline uint32_t _RISCV_Read_FCSR( void ) { uint32_t fcsr; diff --git a/cpukit/score/cpu/riscv/riscv-exception-default.c b/cpukit/score/cpu/riscv/riscv-exception-default.c deleted file mode 100644 index 62d0dd3803..0000000000 --- a/cpukit/score/cpu/riscv/riscv-exception-default.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2014 Hesham Almatary - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -void _RISCV_Exception_default(uint32_t vector, CPU_Exception_frame *frame); - -void _RISCV_Exception_default(uint32_t vector, CPU_Exception_frame *frame) -{ - rtems_fatal( RTEMS_FATAL_SOURCE_EXCEPTION, (rtems_fatal_code) frame ); -} diff --git a/cpukit/score/cpu/riscv/riscv-exception-handler.S b/cpukit/score/cpu/riscv/riscv-exception-handler.S index 875566cb23..897a15cd11 100644 --- a/cpukit/score/cpu/riscv/riscv-exception-handler.S +++ b/cpukit/score/cpu/riscv/riscv-exception-handler.S @@ -41,15 +41,13 @@ #include #include -EXTERN(bsp_start_vector_table_begin) -EXTERN(_Thread_Dispatch) -PUBLIC(ISR_Handler) +PUBLIC(_RISCV_Exception_handler) .section .text, "ax", @progbits .align 2 -TYPE_FUNC(ISR_Handler) -SYM(ISR_Handler): +TYPE_FUNC(_RISCV_Exception_handler) +SYM(_RISCV_Exception_handler): addi sp, sp, -CPU_INTERRUPT_FRAME_SIZE /* Save */ @@ -104,8 +102,8 @@ SYM(ISR_Handler): FSREG fa7, RISCV_INTERRUPT_FRAME_FA7(sp) #endif - /* FIXME Only handle interrupts for now (MSB = 1) */ - andi a0, a0, 0xf + /* Check if this is a synchronous or interrupt exception */ + bgez a0, .Lsynchronous_exception /* Increment interrupt nest and thread dispatch disable level */ lw t0, PER_CPU_ISR_NEST_LEVEL(s0) @@ -117,32 +115,17 @@ SYM(ISR_Handler): CLEAR_RESERVATIONS s0 - /* Keep sp (Exception frame address) in s1 */ + /* + * Remember current stack pointer in non-volatile register s1. Switch + * to interrupt stack if necessary. + */ mv s1, sp - - /* Call the exception handler from vector table */ - - /* First function arg for C handler is vector number, - * and the second is a pointer to exception frame. - * a0/mcause/vector number is already loaded above */ - mv a1, sp - - /* calculate the offset */ - LADDR t5, bsp_start_vector_table_begin -#if __riscv_xlen == 32 - slli t6, a0, 2 -#else /* xlen = 64 */ - slli t6, a0, 3 -#endif - add t5, t5, t6 - LREG t5, (t5) - - /* Switch to interrupt stack if necessary */ bnez t0, .Linterrupt_stack_switch_done LREG sp, PER_CPU_INTERRUPT_STACK_HIGH(s0) .Linterrupt_stack_switch_done: - jalr t5 + mv a1, s0 + call _RISCV_Interrupt_dispatch /* Load some per-CPU variables */ lw t0, PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL(s0) @@ -249,3 +232,39 @@ SYM(ISR_Handler): addi sp, sp, CPU_INTERRUPT_FRAME_SIZE mret + +.Lsynchronous_exception: + + SREG a0, RISCV_EXCEPTION_FRAME_MCAUSE(sp) + addi a0, sp, CPU_INTERRUPT_FRAME_SIZE + SREG a0, RISCV_EXCEPTION_FRAME_SP(sp) + SREG gp, RISCV_EXCEPTION_FRAME_GP(sp) + SREG tp, RISCV_EXCEPTION_FRAME_TP(sp) + SREG s2, RISCV_EXCEPTION_FRAME_S2(sp) + SREG s3, RISCV_EXCEPTION_FRAME_S3(sp) + SREG s4, RISCV_EXCEPTION_FRAME_S4(sp) + SREG s5, RISCV_EXCEPTION_FRAME_S5(sp) + SREG s6, RISCV_EXCEPTION_FRAME_S6(sp) + SREG s7, RISCV_EXCEPTION_FRAME_S7(sp) + SREG s8, RISCV_EXCEPTION_FRAME_S8(sp) + SREG s9, RISCV_EXCEPTION_FRAME_S9(sp) + SREG s10, RISCV_EXCEPTION_FRAME_S10(sp) + SREG s11, RISCV_EXCEPTION_FRAME_S11(sp) +#if __riscv_flen > 0 + FSREG fs0, RISCV_EXCEPTION_FRAME_FS0(sp) + FSREG fs1, RISCV_EXCEPTION_FRAME_FS1(sp) + FSREG fs2, RISCV_EXCEPTION_FRAME_FS2(sp) + FSREG fs3, RISCV_EXCEPTION_FRAME_FS3(sp) + FSREG fs4, RISCV_EXCEPTION_FRAME_FS4(sp) + FSREG fs5, RISCV_EXCEPTION_FRAME_FS5(sp) + FSREG fs6, RISCV_EXCEPTION_FRAME_FS6(sp) + FSREG fs7, RISCV_EXCEPTION_FRAME_FS7(sp) + FSREG fs8, RISCV_EXCEPTION_FRAME_FS8(sp) + FSREG fs9, RISCV_EXCEPTION_FRAME_FS9(sp) + FSREG fs10, RISCV_EXCEPTION_FRAME_FS10(sp) + FSREG fs11, RISCV_EXCEPTION_FRAME_FS11(sp) +#endif + + li a0, 9 + mv a1, sp + call _Terminate -- cgit v1.2.3