summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu/riscv
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-07-19 12:11:19 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-07-25 10:07:43 +0200
commit8db3f0e878b7f008ad05716f501220509662e2c4 (patch)
treed55db59defa95096a3ef156427822a9f8744ab58 /cpukit/score/cpu/riscv
parentriscv: New CPU_Exception_frame (diff)
downloadrtems-8db3f0e878b7f008ad05716f501220509662e2c4.tar.bz2
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.
Diffstat (limited to 'cpukit/score/cpu/riscv')
-rw-r--r--cpukit/score/cpu/riscv/Makefile.am1
-rw-r--r--cpukit/score/cpu/riscv/cpu.c46
-rw-r--r--cpukit/score/cpu/riscv/include/rtems/score/cpu.h30
-rw-r--r--cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h7
-rw-r--r--cpukit/score/cpu/riscv/riscv-exception-default.c39
-rw-r--r--cpukit/score/cpu/riscv/riscv-exception-handler.S75
6 files changed, 54 insertions, 144 deletions
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
@@ -361,36 +361,6 @@ void _CPU_Initialize(
);
/*
- * _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
*
* This routine is the CPU dependent IDLE thread 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 <heshamelmatary@gmail.com>
- *
- * 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 <rtems/score/cpu.h>
-#include <rtems/fatal.h>
-#include <stdio.h>
-
-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 <rtems/asm.h>
#include <rtems/score/percpu.h>
-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