Skip to content

Commit fc4f314

Browse files
committed
Add vector table
1 parent db6c2f9 commit fc4f314

File tree

5 files changed

+111
-77
lines changed

5 files changed

+111
-77
lines changed

riscv-pac/macros/src/lib.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,42 @@ impl PacEnumItem {
192192
vectors
193193
}
194194

195+
fn vector_table(&self) -> TokenStream2 {
196+
let mut asm = String::from(
197+
r#"
198+
core::arch::global_asm!("
199+
.section .trap, \"ax\"
200+
.global _vector_table
201+
.type _vector_table, @function
202+
203+
.option push
204+
.balign 0x4 // TODO check if this is the correct alignment
205+
.option norelax
206+
.option norvc
207+
208+
_vector_table:
209+
j _start_trap // Interrupt 0 is used for exceptions
210+
"#,
211+
);
212+
213+
for i in 1..=self.max_number {
214+
if let Some(ident) = self.numbers.get(&i) {
215+
asm.push_str(&format!(" j _start_{ident}_trap\n"));
216+
} else {
217+
asm.push_str(&format!(
218+
" j _start_DefaultHandler_trap // Interrupt {i} is reserved\n"
219+
));
220+
}
221+
}
222+
223+
asm.push_str(
224+
r#" .option pop"
225+
);"#,
226+
);
227+
228+
TokenStream2::from_str(&asm).unwrap()
229+
}
230+
195231
/// Returns a vector of token streams representing the trait implementations for
196232
/// the enum. If the trait is an interrupt trait, the implementation also includes
197233
/// the interrupt handler functions and the interrupt array.
@@ -269,6 +305,10 @@ impl PacEnumItem {
269305
}
270306
}
271307
});
308+
309+
if let InterruptType::Core = interrupt_type {
310+
res.push(self.vector_table());
311+
}
272312
}
273313

274314
res

riscv-rt/src/asm.rs

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -287,38 +287,6 @@ riscv_rt_macros::vectored_interrupt_trap_riscv32!();
287287
#[cfg(all(riscv64, feature = "v-trap"))]
288288
riscv_rt_macros::vectored_interrupt_trap_riscv64!();
289289

290-
#[cfg(feature = "v-trap")]
291-
cfg_global_asm!(
292-
// Set the vector mode to vectored.
293-
r#".section .trap, "ax"
294-
.weak _vector_table
295-
.type _vector_table, @function
296-
297-
.option push
298-
.balign 0x4 // TODO check if this is the correct alignment
299-
.option norelax
300-
.option norvc
301-
302-
_vector_table:
303-
j _start_trap // Interrupt 0 is used for exceptions
304-
j _start_SupervisorSoft_trap
305-
j _start_DefaultHandler_trap // Interrupt 2 is reserved
306-
j _start_MachineSoft_trap
307-
j _start_DefaultHandler_trap // Interrupt 4 is reserved
308-
j _start_SupervisorTimer_trap
309-
j _start_DefaultHandler_trap // Interrupt 6 is reserved
310-
j _start_MachineTimer_trap
311-
j _start_DefaultHandler_trap // Interrupt 8 is reserved
312-
j _start_SupervisorExternal_trap
313-
j _start_DefaultHandler_trap // Interrupt 10 is reserved
314-
j _start_MachineExternal_trap
315-
316-
// default table does not include the remaining interrupts.
317-
// Targets with extra interrupts should override this table.
318-
319-
.option pop"#,
320-
);
321-
322290
#[rustfmt::skip]
323291
global_asm!(
324292
".section .text.abort

riscv-rt/src/interrupt.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
extern "C" {
2+
fn SupervisorSoft();
3+
fn MachineSoft();
4+
fn SupervisorTimer();
5+
fn MachineTimer();
6+
fn SupervisorExternal();
7+
fn MachineExternal();
8+
fn DefaultHandler();
9+
}
10+
11+
#[doc(hidden)]
12+
#[no_mangle]
13+
pub static __CORE_INTERRUPTS: [Option<unsafe extern "C" fn()>; 12] = [
14+
None,
15+
Some(SupervisorSoft),
16+
None,
17+
Some(MachineSoft),
18+
None,
19+
Some(SupervisorTimer),
20+
None,
21+
Some(MachineTimer),
22+
None,
23+
Some(SupervisorExternal),
24+
None,
25+
Some(MachineExternal),
26+
];
27+
28+
#[export_name = "_dispatch_core_interrupt"]
29+
unsafe extern "C" fn dispatch_core_interrupt(code: usize) {
30+
if code < __CORE_INTERRUPTS.len() {
31+
let h = &__CORE_INTERRUPTS[code];
32+
if let Some(handler) = h {
33+
handler();
34+
} else {
35+
DefaultHandler();
36+
}
37+
} else {
38+
DefaultHandler();
39+
}
40+
}
41+
42+
#[cfg(all(riscv, feature = "v-trap"))]
43+
core::arch::global_asm!(
44+
r#" .section .trap, "ax"
45+
.weak _vector_table
46+
.type _vector_table, @function
47+
48+
.option push
49+
.balign 0x4 // TODO check if this is the correct alignment
50+
.option norelax
51+
.option norvc
52+
53+
_vector_table:
54+
j _start_trap // Interrupt 0 is used for exceptions
55+
j _start_SupervisorSoft_trap
56+
j _start_DefaultHandler_trap // Interrupt 2 is reserved
57+
j _start_MachineSoft_trap
58+
j _start_DefaultHandler_trap // Interrupt 4 is reserved
59+
j _start_SupervisorTimer_trap
60+
j _start_DefaultHandler_trap // Interrupt 6 is reserved
61+
j _start_MachineTimer_trap
62+
j _start_DefaultHandler_trap // Interrupt 8 is reserved
63+
j _start_SupervisorExternal_trap
64+
j _start_DefaultHandler_trap // Interrupt 10 is reserved
65+
j _start_MachineExternal_trap
66+
67+
.option pop"#
68+
);

riscv-rt/src/lib.rs

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,8 @@
460460
#[cfg(riscv)]
461461
mod asm;
462462

463+
mod interrupt;
464+
463465
#[cfg(feature = "s-mode")]
464466
use riscv::register::scause as xcause;
465467

@@ -578,47 +580,3 @@ pub static __EXCEPTIONS: [Option<unsafe extern "C" fn(&TrapFrame)>; 16] = [
578580
None,
579581
Some(StorePageFault),
580582
];
581-
582-
#[export_name = "_dispatch_core_interrupt"]
583-
unsafe extern "C" fn dispatch_core_interrupt(code: usize) {
584-
extern "C" {
585-
fn DefaultHandler();
586-
}
587-
588-
if code < __INTERRUPTS.len() {
589-
let h = &__INTERRUPTS[code];
590-
if let Some(handler) = h {
591-
handler();
592-
} else {
593-
DefaultHandler();
594-
}
595-
} else {
596-
DefaultHandler();
597-
}
598-
}
599-
600-
extern "C" {
601-
fn SupervisorSoft();
602-
fn MachineSoft();
603-
fn SupervisorTimer();
604-
fn MachineTimer();
605-
fn SupervisorExternal();
606-
fn MachineExternal();
607-
}
608-
609-
#[doc(hidden)]
610-
#[no_mangle]
611-
pub static __INTERRUPTS: [Option<unsafe extern "C" fn()>; 12] = [
612-
None,
613-
Some(SupervisorSoft),
614-
None,
615-
Some(MachineSoft),
616-
None,
617-
Some(SupervisorTimer),
618-
None,
619-
Some(MachineTimer),
620-
None,
621-
Some(SupervisorExternal),
622-
None,
623-
Some(MachineExternal),
624-
];

riscv/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This project is developed and maintained by the [RISC-V team][team].
1111

1212
## Minimum Supported Rust Version (MSRV)
1313

14-
This crate is guaranteed to compile on stable Rust 1.60 and up. It *might*
14+
This crate is guaranteed to compile on stable Rust 1.61 and up. It *might*
1515
compile with older versions but that may change in any new patch release.
1616

1717
## License

0 commit comments

Comments
 (0)