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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
/***************************************************************************
* 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
**************************************************************************/
#include "csr.h"
#include "tx_port.h"
/* Erbium ignores mtvec base bits 11:1, so the trap vector must be 4 KiB
aligned. */
.section .text.trap, "ax", @progbits
.balign 4096
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* trap_entry RISC-V64/GNU */
/* */
/* DESCRIPTION */
/* */
/* This function is the machine-mode trap vector (direct mode). It */
/* saves the interrupted context, calls trap_handler with mcause, */
/* mepc and mtval, and leaves through the ThreadX context restore. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_context_save Save interrupted context */
/* trap_handler Dispatch the trap */
/* _tx_thread_context_restore Restore or schedule a thread */
/* */
/* CALLED BY */
/* */
/* Hardware trap */
/* */
/**************************************************************************/
.global trap_entry
.extern trap_handler
.extern _tx_thread_context_save
.extern _tx_thread_context_restore
trap_entry:
addi sp, sp, -TX_RISCV_TRAP_FRAME_SIZE // Interrupt frame from the port contract
sd x1, 28*8(sp) // Save RA before the call below overwrites it
call _tx_thread_context_save
csrr a0, mcause
csrr a1, mepc
csrr a2, mtval
addi sp, sp, -16 // 16 bytes keep sp 16-byte aligned at the call
sd ra, 0(sp)
call trap_handler
ld ra, 0(sp)
addi sp, sp, 16
call _tx_thread_context_restore
/* _tx_thread_context_restore does not return. */
_trap_entry_hang:
j _trap_entry_hang
.section .text
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_initialize_low_level RISC-V64/GNU */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for any low-level processor */
/* initialization, including setting up interrupt vectors, setting */
/* up a periodic timer interrupt source, saving the system stack */
/* pointer for use in ISR processing later, and finding the first */
/* available RAM memory address for tx_application_define. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* board_init Initialize the peripherals */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* */
/**************************************************************************/
/* VOID _tx_initialize_low_level(VOID)
{ */
.global _tx_initialize_low_level // Strong definition: must beat the port's weak default
.extern _end
.extern board_init
.extern _tx_thread_system_stack_ptr
.extern _tx_initialize_unused_memory
_tx_initialize_low_level:
la t0, _tx_thread_system_stack_ptr
sd sp, 0(t0) // Save system stack pointer
la t0, _end // Pickup first free address
la t1, _tx_initialize_unused_memory
sd t0, 0(t1) // Save unused memory address
li t0, MSTATUS_MIE
csrrc zero, mstatus, t0 // Keep interrupts off until the scheduler runs
li t0, (MSTATUS_MPP_M | MSTATUS_MPIE)
csrrs zero, mstatus, t0 // mret stays in M-mode with interrupts enabled
li t0, (MIE_MTIE | MIE_MEIE)
csrrs zero, mie, t0 // Enable timer and external interrupts
addi sp, sp, -16 // 16 bytes keep sp 16-byte aligned at the call
sd ra, 0(sp)
call board_init
ld ra, 0(sp)
addi sp, sp, 16
la t0, trap_entry
csrw mtvec, t0 // Direct mode: trap_entry is 4 KiB aligned
ret
/* } */
|