/*************************************************************************** * 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 #include #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); } }