diff options
Diffstat (limited to 'ports/risc-v64/gnu/example_build/erbium/trap.c')
| -rw-r--r-- | ports/risc-v64/gnu/example_build/erbium/trap.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/ports/risc-v64/gnu/example_build/erbium/trap.c b/ports/risc-v64/gnu/example_build/erbium/trap.c new file mode 100644 index 00000000..d839e6ea --- /dev/null +++ b/ports/risc-v64/gnu/example_build/erbium/trap.c @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5.5). + * The AI-generated portions may be considered public domain (CC0-1.0) + * and not subject to the project's licence. The human contributor has + * reviewed and verified that the code is correct. + * + * SPDX-License-Identifier: MIT and CC0-1.0 + **************************************************************************/ + +/* Machine-mode trap dispatcher for the Erbium example. */ + +#include "csr.h" +#include "uart.h" +#include "hwtimer.h" +#include "plic.h" +#include <stdint.h> +#include <tx_api.h> + +#define MCAUSE_INT_BIT ((uintptr_t)1 << (__riscv_xlen - 1)) +#define MCAUSE_M_TIMER (MCAUSE_INT_BIT | 7u) +#define MCAUSE_M_EXTERNAL (MCAUSE_INT_BIT | 11u) + +extern void _tx_timer_interrupt(void); + +static void print_hex(uintptr_t val) +{ + const char digits[] = "0123456789ABCDEF"; + + uart_putc('0'); + uart_putc('x'); + for (int i = (int)(sizeof(uintptr_t) * 2) - 1; i >= 0; i--) + uart_putc(digits[(val >> (i * 4)) & 0xFu]); + uart_putc('\r'); + uart_putc('\n'); +} + +static void trap_halt(const char *reason, uintptr_t mcause, uintptr_t mepc, uintptr_t mtval) +{ + uart_puts(reason); + uart_puts("mcause:"); + print_hex(mcause); + uart_puts("mepc:"); + print_hex(mepc); + uart_puts("mtval:"); + print_hex(mtval); + + /* Spin rather than WFI, as everywhere else in this example. */ + while (1) + ; +} + +void trap_handler(uintptr_t mcause, uintptr_t mepc, uintptr_t mtval) +{ + if (mcause == MCAUSE_M_TIMER) + { + hwtimer_handler(); + _tx_timer_interrupt(); + } + else if (mcause == MCAUSE_M_EXTERNAL) + { + if (plic_irq_intr() != 0) + trap_halt("[INTERRUPT]: external interrupt not handled, halting", mcause, mepc, mtval); + } + else if ((mcause & MCAUSE_INT_BIT) != 0u) + { + trap_halt("[INTERRUPT]: unexpected interrupt, halting", mcause, mepc, mtval); + } + else + { + trap_halt("[EXCEPTION]: unhandled exception, halting", mcause, mepc, mtval); + } +} |
