1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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);
}
}
|