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.
This commit is contained in:
Sebastian Huber
2018-07-25 10:07:43 +02:00
parent 5694b0cce4
commit 8db3f0e878
15 changed files with 120 additions and 170 deletions
+3 -1
View File
@@ -142,7 +142,9 @@ typedef enum {
/* RISC-V fatal codes */
RISCV_FATAL_NO_TIMEBASE_FREQUENCY_IN_DEVICE_TREE = BSP_FATAL_CODE_BLOCK(13),
RISCV_FATAL_NO_NS16550_REG_IN_DEVICE_TREE,
RISCV_FATAL_NO_NS16550_CLOCK_FREQUENCY_IN_DEVICE_TREE
RISCV_FATAL_NO_NS16550_CLOCK_FREQUENCY_IN_DEVICE_TREE,
RISCV_FATAL_UNEXPECTED_INTERRUPT_EXCEPTION,
RISCV_FATAL_CLOCK_IRQ_INSTALL
} bsp_fatal_code;
RTEMS_NO_RETURN static inline void
-4
View File
@@ -63,10 +63,6 @@ LINKER_SYMBOL(bsp_vector_table_begin)
LINKER_SYMBOL(bsp_vector_table_end)
LINKER_SYMBOL(bsp_vector_table_size)
LINKER_SYMBOL(bsp_start_vector_table_begin)
LINKER_SYMBOL(bsp_start_vector_table_end)
LINKER_SYMBOL(bsp_start_vector_table_size)
LINKER_SYMBOL(bsp_translation_table_base)
LINKER_SYMBOL(bsp_translation_table_end)
-2
View File
@@ -29,8 +29,6 @@
#include <rtems/btimer.h>
#include <rtems/score/riscv-utility.h>
extern char bsp_start_vector_table_begin[];
bool benchmark_timer_find_average_overhead;
static void benchmark_timer1_interrupt_handler(void)
+14 -5
View File
@@ -72,11 +72,20 @@ static void riscv_clock_at_tick(void)
#endif
}
static void riscv_clock_handler_install(proc_ptr new_isr)
static void riscv_clock_handler_install(void)
{
_CPU_ISR_install_vector(RISCV_MACHINE_TIMER_INTERRUPT,
new_isr,
NULL);
rtems_status_code sc;
sc = rtems_interrupt_handler_install(
RISCV_INTERRUPT_VECTOR_TIMER,
"Clock",
RTEMS_INTERRUPT_UNIQUE,
(rtems_interrupt_handler) Clock_isr,
NULL
);
if (sc != RTEMS_SUCCESSFUL) {
bsp_fatal(RISCV_FATAL_CLOCK_IRQ_INSTALL);
}
}
static uint32_t riscv_clock_get_timecount(struct timecounter *tc)
@@ -136,6 +145,6 @@ uint32_t _CPU_Counter_frequency( void )
#define Clock_driver_support_initialize_hardware() riscv_clock_initialize()
#define Clock_driver_support_install_isr(isr) \
riscv_clock_handler_install(isr)
riscv_clock_handler_install()
#include "../../../shared/dev/clock/clockimpl.h"
+12 -3
View File
@@ -7,6 +7,7 @@
*/
/*
* Copyright (c) 2018 embedded brains GmbH
*
* Copyright (c) 2015 University of York.
* Hesham Almatary <hesham@alumni.york.ac.uk>
@@ -38,12 +39,20 @@
#ifndef ASM
#include <rtems.h>
#include <bsp.h>
#include <rtems/irq.h>
#include <rtems/irq-extension.h>
#define BSP_INTERRUPT_VECTOR_MIN 0x0
#define BSP_INTERRUPT_VECTOR_MAX 0x24
#define RISCV_INTERRUPT_VECTOR_SOFTWARE 0
#define RISCV_INTERRUPT_VECTOR_TIMER 1
#define RISCV_INTERRUPT_VECTOR_EXTERNAL(x) ((x) + 2)
#define BSP_INTERRUPT_VECTOR_MIN 0
#define BSP_INTERRUPT_VECTOR_MAX RISCV_INTERRUPT_VECTOR_EXTERNAL(RISCV_MAXIMUM_EXTERNAL_INTERRUPTS - 1)
#endif /* ASM */
#endif /* LIBBSP_GENERIC_RISCV_IRQ_H */
+25 -3
View File
@@ -7,7 +7,7 @@
*/
/*
* RISCV CPU Dependent Source
* Copyright (c) 2018 embedded brains GmbH
*
* Copyright (c) 2015 University of York.
* Hesham Almatary <hesham@alumni.york.ac.uk>
@@ -35,11 +35,33 @@
*/
#include <bsp/irq.h>
#include <bsp/fatal.h>
#include <bsp/irq-generic.h>
rtems_status_code bsp_interrupt_facility_initialize()
#include <rtems/score/percpu.h>
void _RISCV_Interrupt_dispatch(uintptr_t mcause, Per_CPU_Control *cpu_self)
{
return RTEMS_NOT_IMPLEMENTED;
/*
* Get rid of the most significant bit which indicates if the exception was
* caused by an interrupt or not.
*/
mcause <<= 1;
if (mcause == (RISCV_INTERRUPT_TIMER_MACHINE << 1)) {
bsp_interrupt_handler_dispatch(RISCV_INTERRUPT_VECTOR_TIMER);
} else if (mcause == (RISCV_INTERRUPT_EXTERNAL_MACHINE << 1)) {
/* TODO: Handle PLIC interrupt */
} else if (mcause == (RISCV_INTERRUPT_SOFTWARE_MACHINE << 1)) {
bsp_interrupt_handler_dispatch(RISCV_INTERRUPT_VECTOR_SOFTWARE);
} else {
bsp_fatal(RISCV_FATAL_UNEXPECTED_INTERRUPT_EXCEPTION);
}
}
rtems_status_code bsp_interrupt_facility_initialize(void)
{
return RTEMS_SUCCESSFUL;
}
void bsp_interrupt_vector_enable(rtems_vector_number vector)
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 Hesham Almatary <heshamelmatary@gmail.com>
* Copyright (c) 2018 embedded brains GmbH
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,17 +23,10 @@
* SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <bsp/bootcard.h>
#include <bsp/irq-generic.h>
#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)
void bsp_start(void)
{
rtems_fatal( RTEMS_FATAL_SOURCE_EXCEPTION, (rtems_fatal_code) frame );
bsp_interrupt_initialize();
}
+3 -34
View File
@@ -1,4 +1,6 @@
/*
* Copyright (c) 2018 embedded brains GmbH
* Copyright (c) 2015 University of York.
* Hesham Almatary <hesham@alumni.york.ac.uk>
*
@@ -33,13 +35,6 @@
#include <bsp/linker-symbols.h>
#include <bspopts.h>
EXTERN(bsp_section_bss_begin)
EXTERN(bsp_section_bss_end)
EXTERN(ISR_Handler)
EXTERN(bsp_section_stack_begin)
PUBLIC(bsp_start_vector_table_begin)
PUBLIC(bsp_start_vector_table_end)
PUBLIC(_start)
.section .bsp_start_text, "wax", @progbits
@@ -70,7 +65,7 @@ SYM(_start):
call bsp_fdt_copy
#endif
LADDR t0, ISR_Handler
LADDR t0, _RISCV_Exception_handler
csrw mtvec, t0
/* Clear .bss */
@@ -107,29 +102,3 @@ SYM(_start):
.Lsecondary_processor_go:
.word 0xdeadbeef
#endif
#if __riscv_xlen == 32
#define ADDR .word
#elif __riscv_xlen == 64
#define ADDR .quad
#endif
.align 4
bsp_start_vector_table_begin:
ADDR _RISCV_Exception_default /* User int */
ADDR _RISCV_Exception_default /* Supervisor int */
ADDR _RISCV_Exception_default /* Reserved */
ADDR _RISCV_Exception_default /* Machine int */
ADDR _RISCV_Exception_default /* User timer int */
ADDR _RISCV_Exception_default /* Supervisor Timer int */
ADDR _RISCV_Exception_default /* Reserved */
ADDR _RISCV_Exception_default /* Machine Timer int */
ADDR _RISCV_Exception_default /* User external int */
ADDR _RISCV_Exception_default /* Supervisor external int */
ADDR _RISCV_Exception_default /* Reserved */
ADDR _RISCV_Exception_default /* Machine external int */
ADDR _RISCV_Exception_default
ADDR _RISCV_Exception_default
ADDR _RISCV_Exception_default
ADDR _RISCV_Exception_default
bsp_start_vector_table_end:
+1 -1
View File
@@ -33,7 +33,7 @@ project_lib_LIBRARIES = librtemsbsp.a
# Startup
librtemsbsp_a_SOURCES = ../../../../../../bsps/shared/start/bspreset-empty.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspstart-empty.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/riscv/riscv/start/bspstart.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/riscv/riscv/start/bsp_fatal_halt.c
# Shared
@@ -30,6 +30,9 @@ RTEMS_BSPOPTS_HELP([BSP_FDT_BLOB_COPY_TO_READ_ONLY_LOAD_AREA],[copy the FDT blob
RTEMS_BSPOPTS_SET([BSP_CONSOLE_BAUD],[*],[115200])
RTEMS_BSPOPTS_HELP([BSP_CONSOLE_BAUD],[default baud for console driver devices (default 115200)])
RTEMS_BSPOPTS_SET([RISCV_MAXIMUM_EXTERNAL_INTERRUPTS],[*],[64])
RTEMS_BSPOPTS_HELP([RISCV_MAXIMUM_EXTERNAL_INTERRUPTS],[maximum number of external interrupts supported by the BSP (default 64)])
RTEMS_BSPOPTS_SET([RISCV_ENABLE_HTIF_SUPPORT],[*],[1])
RTEMS_BSPOPTS_HELP([RISCV_ENABLE_HTIF_SUPPORT],[enables the HTIF support if defined to a non-zero value, otherwise it is disabled (enabled by default)])
-1
View File
@@ -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
-46
View File
@@ -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 {
@@ -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
*
@@ -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;
@@ -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