This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 73e3fd8f3ce306393f81d67bb05963d71a29d7cd Author: Afonso Oliveira <[email protected]> AuthorDate: Thu Oct 8 22:05:47 2026 +0100 riscv/erbium: Stop dispatching ET-Minion exceptions as interrupts. ET-Minion raises exception codes above 15: 25 (instruction bus error), 26 (instruction ECC error), 27 and 28 (load and store split-page fault) and 30 (M-code emulation). Code 30 is raised by FDIV.S, FSQRT.S, FCVT.L.S, FCVT.LU.S, FCVT.S.L, FCVT.S.LU, FENCE.I, SFENCE.VMA and some ET packed instructions, which have no hardware implementation. riscv_dispatch_irq() uses the exception code as the IRQ number, and with the default RISCV_MAX_EXCEPTION of 15 these codes alias interrupt IRQ numbers. Code 30 ran the UART0 interrupt handler, which returned to the faulting instruction, so the task trapped again forever. A cast from float to int64_t, or a call to lroundf(), hung the system with no report. Set RISCV_MAX_EXCEPTION to 31, name the ET-Minion codes through RISCV_CUSTOM_EXCEPTION_REASONS and attach codes 16 to 31 to riscv_exception(), so that each is reported once as a fatal exception with its name, EPC and MTVAL. Interrupt IRQ numbers move up by 16, for example UART0 from 30 to 46. Also correct comments that said these instructions run in microcode. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Afonso Oliveira <[email protected]> --- arch/risc-v/include/erbium/irq.h | 36 +++++++++++++++++++++++ arch/risc-v/src/erbium/erbium_irq.c | 33 ++++++++++++++++++++- arch/risc-v/src/erbium/erbium_irq_dispatch.c | 18 ++++++++++-- arch/risc-v/src/erbium/erbium_start.c | 5 ++-- boards/risc-v/erbium/minion/cmake/Toolchain.cmake | 4 +-- boards/risc-v/erbium/minion/scripts/Make.defs | 4 +-- 6 files changed, 91 insertions(+), 9 deletions(-) diff --git a/arch/risc-v/include/erbium/irq.h b/arch/risc-v/include/erbium/irq.h index 50c13cc3b46..6a18d0f59af 100644 --- a/arch/risc-v/include/erbium/irq.h +++ b/arch/risc-v/include/erbium/irq.h @@ -27,6 +27,42 @@ * Pre-processor Definitions ****************************************************************************/ +/* ET-Minion reports a 5-bit exception code. Besides the standard codes it + * raises 25 (instruction bus error), 26 (instruction ECC error), 27 and 28 + * (load and store split-page fault) and 30 (M-code emulation: the + * instruction has no hardware implementation and traps to machine mode). + * Number all 32 codes as exceptions so that none of them is dispatched as + * an interrupt. Interrupt IRQ numbers therefore start at 32. + */ + +#define RISCV_MAX_EXCEPTION (31) + +#define ERBIUM_IRQ_IBUSERR (25) /* Instruction bus error */ +#define ERBIUM_IRQ_IECCERR (26) /* Instruction ECC error */ +#define ERBIUM_IRQ_LSPLITPF (27) /* Load split-page fault */ +#define ERBIUM_IRQ_SSPLITPF (28) /* Store split-page fault */ +#define ERBIUM_IRQ_MCODE (30) /* M-code emulation */ + +/* Reason strings for the codes after the common table. The common table + * names codes 16-19 itself when Machine ISA 1.13 support is enabled. + */ + +#ifdef CONFIG_ARCH_RV_MACHINE_ISA_1_13 +# define ERBIUM_FIRST_CUSTOM_EXCEPTION (20) +# define ERBIUM_EXCEPTION_REASONS_16_19 +#else +# define ERBIUM_FIRST_CUSTOM_EXCEPTION (16) +# define ERBIUM_EXCEPTION_REASONS_16_19 \ + "Reserved", "Reserved", "Reserved", "Reserved", +#endif + +#define RISCV_CUSTOM_EXCEPTION_REASONS \ + ERBIUM_EXCEPTION_REASONS_16_19 \ + "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", \ + "Instruction bus error", "Instruction ECC error", \ + "Load split-page fault", "Store split-page fault", \ + "Reserved", "M-code emulation", "Reserved", + #define ERBIUM_IRQ_UART0 (RISCV_IRQ_MEXT + 3) #define ERBIUM_IRQ_EXT_MAX (RISCV_IRQ_MEXT + 6) diff --git a/arch/risc-v/src/erbium/erbium_irq.c b/arch/risc-v/src/erbium/erbium_irq.c index da82ccba70a..097738a6a20 100644 --- a/arch/risc-v/src/erbium/erbium_irq.c +++ b/arch/risc-v/src/erbium/erbium_irq.c @@ -25,12 +25,32 @@ ****************************************************************************/ #include <nuttx/config.h> +#include <assert.h> #include <stdint.h> +#include <sys/param.h> #include <nuttx/irq.h> #include "chip.h" #include "riscv_internal.h" +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* riscv_exception() names an exception with g_reasons_str[code], which has + * RISCV_MAX_EXCEPTION + 1 entries. The chip's part of that table must name + * every code after the common part; this copy only checks its length. + */ + +static const char * const g_custom_reasons[] unused_data = +{ + RISCV_CUSTOM_EXCEPTION_REASONS +}; + +static_assert(nitems(g_custom_reasons) == + RISCV_MAX_EXCEPTION + 1 - ERBIUM_FIRST_CUSTOM_EXCEPTION, + "RISCV_CUSTOM_EXCEPTION_REASONS must end at code 31"); + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -40,7 +60,8 @@ * * Description: * Initialize hart 0 interrupt state and PLIC priorities, attach the - * common exception handlers, and enable interrupts unless suppressed. + * exception handlers, including those for the ET-specific exception + * codes, and enable interrupts unless suppressed. * * Input Parameters: * None. @@ -70,6 +91,16 @@ void up_irqinitialize(void) putreg32(0, ERBIUM_PLIC_THRESHOLD); riscv_exception_attach(); + /* riscv_exception_attach() covers codes 0-15 only. Report the other + * codes, among them the ET-specific ones and M-code instructions that + * are not emulated, as fatal exceptions. + */ + + for (id = RISCV_IRQ_RESERVED16; id <= RISCV_MAX_EXCEPTION; id++) + { + irq_attach(id, riscv_exception, NULL); + } + #ifndef CONFIG_SUPPRESS_INTERRUPTS up_irq_enable(); #endif diff --git a/arch/risc-v/src/erbium/erbium_irq_dispatch.c b/arch/risc-v/src/erbium/erbium_irq_dispatch.c index ecc6369cddf..c37fdb161cd 100644 --- a/arch/risc-v/src/erbium/erbium_irq_dispatch.c +++ b/arch/risc-v/src/erbium/erbium_irq_dispatch.c @@ -31,6 +31,18 @@ #include "hardware/erbium_plic.h" #include "riscv_internal.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* An exception is dispatched with its 5-bit cause code as the IRQ number, + * so every code must lie below the first interrupt IRQ number. + */ + +#if RISCV_IRQ_ASYNC < 32 +# error "ET-Minion exception codes would alias interrupt IRQ numbers" +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -39,8 +51,10 @@ * Name: riscv_dispatch_irq * * Description: - * Dispatch hart-local traps or claim, dispatch and complete a PLIC - * interrupt. Complete nonzero claims even if their source is unsupported. + * Dispatch an exception as IRQ <cause> (0-31) and a hart-local + * interrupt as IRQ RISCV_IRQ_ASYNC + <cause>, or claim, dispatch and + * complete a PLIC interrupt. Complete nonzero claims even if their + * source is unsupported. * * Input Parameters: * vector - Trap cause register value. diff --git a/arch/risc-v/src/erbium/erbium_start.c b/arch/risc-v/src/erbium/erbium_start.c index c5aac2e734c..dfc92f02cd0 100644 --- a/arch/risc-v/src/erbium/erbium_start.c +++ b/arch/risc-v/src/erbium/erbium_start.c @@ -63,8 +63,9 @@ void erbium_start(void) } #ifdef CONFIG_ARCH_FPU - /* Erbium traps FENCE.I to microcode. The ELF loader has already installed - * the image, so initialize the FPU without the common FENCE.I sequence. + /* FENCE.I raises exception 30 (M-code emulation) on ET-Minion. The ELF + * loader has already installed the image, so initialize the FPU without + * the common FENCE.I sequence. */ SET_CSR(CSR_STATUS, MSTATUS_FS_INIT); diff --git a/boards/risc-v/erbium/minion/cmake/Toolchain.cmake b/boards/risc-v/erbium/minion/cmake/Toolchain.cmake index 1b1b845af12..1fc89398af0 100644 --- a/boards/risc-v/erbium/minion/cmake/Toolchain.cmake +++ b/boards/risc-v/erbium/minion/cmake/Toolchain.cmake @@ -20,8 +20,8 @@ # # ############################################################################## -# Erbium executes floating-point divide and square root in microcode, which this -# image does not provide. Use software helpers for those operations. +# ET-Minion has no hardware for floating-point divide and square root; they +# raise exception 30 (M-code emulation). Use software helpers instead. if(CONFIG_ARCH_FPU) add_compile_options(-mno-fdiv) diff --git a/boards/risc-v/erbium/minion/scripts/Make.defs b/boards/risc-v/erbium/minion/scripts/Make.defs index c4d0b779062..766eb9f6ccb 100644 --- a/boards/risc-v/erbium/minion/scripts/Make.defs +++ b/boards/risc-v/erbium/minion/scripts/Make.defs @@ -24,8 +24,8 @@ include $(TOPDIR)/.config include $(TOPDIR)/tools/Config.mk include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs -# Erbium executes floating-point divide and square root in microcode, which -# this image does not provide. Use software helpers for those operations. +# ET-Minion has no hardware for floating-point divide and square root; they +# raise exception 30 (M-code emulation). Use software helpers instead. ifeq ($(CONFIG_ARCH_FPU),y) ARCHCPUFLAGS += -mno-fdiv
