diff options
-rw-r--r-- | bsps/include/bsp/fatal.h | 4 | ||||
-rw-r--r-- | bsps/riscv/include/bsp/linker-symbols.h | 4 | ||||
-rw-r--r-- | bsps/riscv/riscv/btimer/btimer.c | 2 | ||||
-rw-r--r-- | bsps/riscv/riscv/clock/clockdrv.c | 19 | ||||
-rw-r--r-- | bsps/riscv/riscv/include/bsp/irq.h | 15 | ||||
-rw-r--r-- | bsps/riscv/riscv/irq/irq.c | 28 | ||||
-rw-r--r-- | bsps/riscv/riscv/start/bspstart.c (renamed from cpukit/score/cpu/riscv/riscv-exception-default.c) | 17 | ||||
-rw-r--r-- | bsps/riscv/riscv/start/start.S | 37 | ||||
-rw-r--r-- | c/src/lib/libbsp/riscv/riscv/Makefile.am | 2 | ||||
-rw-r--r-- | c/src/lib/libbsp/riscv/riscv/configure.ac | 3 | ||||
-rw-r--r-- | cpukit/score/cpu/riscv/Makefile.am | 1 | ||||
-rw-r--r-- | cpukit/score/cpu/riscv/cpu.c | 46 | ||||
-rw-r--r-- | cpukit/score/cpu/riscv/include/rtems/score/cpu.h | 30 | ||||
-rw-r--r-- | cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h | 7 | ||||
-rw-r--r-- | cpukit/score/cpu/riscv/riscv-exception-handler.S | 75 |
15 files changed, 120 insertions, 170 deletions
diff --git a/bsps/include/bsp/fatal.h b/bsps/include/bsp/fatal.h index 77c056601c..92ab55fbb4 100644 --- a/bsps/include/bsp/fatal.h +++ b/bsps/include/bsp/fatal.h @@ -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 diff --git a/bsps/riscv/include/bsp/linker-symbols.h b/bsps/riscv/include/bsp/linker-symbols.h index 34bf4873ba..426b17451f 100644 --- a/bsps/riscv/include/bsp/linker-symbols.h +++ b/bsps/riscv/include/bsp/linker-symbols.h @@ -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) diff --git a/bsps/riscv/riscv/btimer/btimer.c b/bsps/riscv/riscv/btimer/btimer.c index 4dd3193685..796979fbb2 100644 --- a/bsps/riscv/riscv/btimer/btimer.c +++ b/bsps/riscv/riscv/btimer/btimer.c @@ -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) diff --git a/bsps/riscv/riscv/clock/clockdrv.c b/bsps/riscv/riscv/clock/clockdrv.c index d2d7a406a0..52fb441ce1 100644 --- a/bsps/riscv/riscv/clock/clockdrv.c +++ b/bsps/riscv/riscv/clock/clockdrv.c @@ -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" diff --git a/bsps/riscv/riscv/include/bsp/irq.h b/bsps/riscv/riscv/include/bsp/irq.h index d7ee45b378..353005fadf 100644 --- a/bsps/riscv/riscv/include/bsp/irq.h +++ b/bsps/riscv/riscv/include/bsp/irq.h @@ -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 */ diff --git a/bsps/riscv/riscv/irq/irq.c b/bsps/riscv/riscv/irq/irq.c index ac4f1ca115..61cf13153b 100644 --- a/bsps/riscv/riscv/irq/irq.c +++ b/bsps/riscv/riscv/irq/irq.c @@ -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) +{ + /* + * 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_NOT_IMPLEMENTED; + return RTEMS_SUCCESSFUL; } void bsp_interrupt_vector_enable(rtems_vector_number vector) diff --git a/cpukit/score/cpu/riscv/riscv-exception-default.c b/bsps/riscv/riscv/start/bspstart.c index 62d0dd3803..217e6f23a6 100644 --- a/cpukit/score/cpu/riscv/riscv-exception-default.c +++ b/bsps/riscv/riscv/start/bspstart.c @@ -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(); } diff --git a/bsps/riscv/riscv/start/start.S b/bsps/riscv/riscv/start/start.S index 0dad170c3c..83926a9272 100644 --- a/bsps/riscv/riscv/start/start.S +++ b/bsps/riscv/riscv/start/start.S @@ -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: diff --git a/c/src/lib/libbsp/riscv/riscv/Makefile.am b/c/src/lib/libbsp/riscv/riscv/Makefile.am index c8299f3e72..159b4fe2c9 100644 --- a/c/src/lib/libbsp/riscv/riscv/Makefile.am +++ b/c/src/lib/libbsp/riscv/riscv/Makefile.am @@ -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 diff --git a/c/src/lib/libbsp/riscv/riscv/configure.ac b/c/src/lib/libbsp/riscv/riscv/configure.ac index 17f4eb8d88..478e255844 100644 --- a/c/src/lib/libbsp/riscv/riscv/configure.ac +++ b/c/src/lib/libbsp/riscv/riscv/configure.ac @@ -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)]) 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-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 |