Skip to content

Commit 56a1f81

Browse files
committed
update interrupt module
1 parent 815b95e commit 56a1f81

File tree

3 files changed

+57
-42
lines changed

3 files changed

+57
-42
lines changed

Cargo.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,10 @@ html-escape = "0.2"
5858
url = { version = "2.5", features = ["serde"] }
5959

6060
[dependencies.svd-parser]
61-
git = "https://github.com/romancardenas/svd.git" # TODO use crates.io
62-
rev = "ddc3d99"
6361
features = ["expand"]
6462
version = "0.14.7"
6563

6664
[dependencies.svd-rs]
67-
git = "https://github.com/romancardenas/svd.git" # TODO use crates.io
68-
rev = "ddc3d99"
6965
features = ["serde"]
7066
version = "0.14.9"
7167

src/generate/riscv.rs

Lines changed: 57 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,10 @@ pub fn render(
1515
) -> Result<TokenStream> {
1616
let mut mod_items = TokenStream::new();
1717

18-
let external_interrupts = peripherals
19-
.iter()
20-
.flat_map(|p| p.interrupt.iter())
21-
.map(|i| (i.value, i))
22-
.collect::<HashMap<_, _>>();
23-
let mut external_interrupts = external_interrupts.into_values().collect::<Vec<_>>();
24-
external_interrupts.sort_by_key(|i| i.value);
25-
if !external_interrupts.is_empty() {
26-
writeln!(device_x, "/* External interrupt sources */")?;
27-
mod_items.extend(quote! { pub use riscv_pac::ExternalInterruptNumber; });
28-
18+
if !r.core_interrupts.is_empty() {
19+
writeln!(device_x, "/* Core interrupt sources and trap handlers */")?;
2920
let mut interrupts = vec![];
30-
for i in external_interrupts.iter() {
21+
for i in r.core_interrupts.iter() {
3122
let name = TokenStream::from_str(&i.name).unwrap();
3223
let value = TokenStream::from_str(&format!("{}", i.value)).unwrap();
3324
let description = format!(
@@ -42,29 +33,43 @@ pub fn render(
4233
);
4334

4435
writeln!(device_x, "PROVIDE({name} = DefaultHandler);")?;
36+
writeln!(
37+
device_x,
38+
"PROVIDE(_start_{name}_trap = _start_DefaultHandler_trap);"
39+
)?;
4540

4641
interrupts.push(quote! {
4742
#[doc = #description]
4843
#name = #value,
49-
})
44+
});
5045
}
5146
mod_items.extend(quote! {
52-
/// External interrupts. These interrupts are handled by the external peripherals.
53-
#[repr(usize)]
54-
#[riscv_pac::pac_enum(unsafe ExternalInterruptNumber)]
47+
/// Core interrupts. These interrupts are handled by the core itself.
48+
#[riscv::pac_enum(unsafe CoreInterruptNumber)]
5549
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56-
pub enum ExternalInterrupt {
50+
pub enum CoreInterrupt {
5751
#(#interrupts)*
5852
}
5953
});
54+
} else {
55+
// when no interrupts are defined, we re-export the standard riscv interrupts
56+
mod_items.extend(quote! {pub use riscv::interrupt::Interrupt as CoreInterrupt;});
6057
}
6158

62-
if !r.core_interrupts.is_empty() {
63-
writeln!(device_x, "/* Core interrupt sources and trap handlers */")?;
64-
mod_items.extend(quote! { pub use riscv_pac::CoreInterruptNumber; });
59+
// TODO something similar to core interrupts but for exceptions
60+
mod_items.extend(quote! { pub use riscv::interrupt::Exception; });
6561

62+
let external_interrupts = peripherals
63+
.iter()
64+
.flat_map(|p| p.interrupt.iter())
65+
.map(|i| (i.value, i))
66+
.collect::<HashMap<_, _>>();
67+
let mut external_interrupts = external_interrupts.into_values().collect::<Vec<_>>();
68+
external_interrupts.sort_by_key(|i| i.value);
69+
if !external_interrupts.is_empty() {
70+
writeln!(device_x, "/* External interrupt sources */")?;
6671
let mut interrupts = vec![];
67-
for i in r.core_interrupts.iter() {
72+
for i in external_interrupts.iter() {
6873
let name = TokenStream::from_str(&i.name).unwrap();
6974
let value = TokenStream::from_str(&format!("{}", i.value)).unwrap();
7075
let description = format!(
@@ -79,29 +84,23 @@ pub fn render(
7984
);
8085

8186
writeln!(device_x, "PROVIDE({name} = DefaultHandler);")?;
82-
writeln!(
83-
device_x,
84-
"PROVIDE(_start_{name}_trap = _start_DefaultHandler_trap);"
85-
)?;
8687

8788
interrupts.push(quote! {
8889
#[doc = #description]
8990
#name = #value,
90-
});
91+
})
9192
}
9293
mod_items.extend(quote! {
93-
/// Core interrupts. These interrupts are handled by the core itself.
94-
#[repr(usize)]
95-
#[riscv_pac::pac_enum(unsafe CoreInterruptNumber)]
94+
/// External interrupts. These interrupts are handled by the external peripherals.
95+
#[riscv::pac_enum(unsafe ExternalInterruptNumber)]
9696
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
97-
pub enum CoreInterrupt {
97+
pub enum ExternalInterrupt {
9898
#(#interrupts)*
9999
}
100100
});
101101
}
102102

103103
if !r.priorities.is_empty() {
104-
mod_items.extend(quote! { pub use riscv_pac::PriorityNumber; });
105104
let priorities = r.priorities.iter().map(|p| {
106105
let name = TokenStream::from_str(&p.name).unwrap();
107106
let value = TokenStream::from_str(&format!("{}", p.value)).unwrap();
@@ -123,8 +122,7 @@ pub fn render(
123122
});
124123
mod_items.extend(quote! {
125124
/// Priority levels in the device
126-
#[repr(u8)]
127-
#[riscv_pac::pac_enum(unsafe PriorityNumber)]
125+
#[riscv::pac_enum(unsafe PriorityNumber)]
128126
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
129127
pub enum Priority {
130128
#(#priorities)*
@@ -133,7 +131,6 @@ pub fn render(
133131
}
134132

135133
if !r.harts.is_empty() {
136-
mod_items.extend(quote! { pub use riscv_pac::HartIdNumber; });
137134
let harts = r.harts.iter().map(|h| {
138135
let name = TokenStream::from_str(&h.name).unwrap();
139136
let value = TokenStream::from_str(&format!("{}", h.value)).unwrap();
@@ -155,15 +152,39 @@ pub fn render(
155152
});
156153
mod_items.extend(quote! {
157154
/// HARTs in the device
158-
#[repr(u16)]
159-
#[riscv_pac::pac_enum(unsafe HartIdNumber)]
155+
#[riscv::pac_enum(unsafe HartIdNumber)]
160156
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
161157
pub enum Hart {
162158
#(#harts)*
163159
}
164160
});
165161
}
166162

163+
mod_items.extend(quote! {
164+
pub use riscv::{
165+
CoreInterruptNumber, ExceptionNumber, PriorityNumber, HartIdNumber,
166+
interrupt::{enable, disable, free, nested}
167+
};
168+
169+
pub type Trap = riscv::interrupt::Trap<CoreInterrupt, Exception>;
170+
171+
/// Retrieves the cause of a trap in the current hart.
172+
///
173+
/// If the raw cause is not a valid interrupt or exception for the target, it returns an error.
174+
#[inline]
175+
pub fn try_cause() -> riscv::result::Result<Trap> {
176+
riscv::interrupt::try_cause()
177+
}
178+
179+
/// Retrieves the cause of a trap in the current hart (machine mode).
180+
///
181+
/// If the raw cause is not a valid interrupt or exception for the target, it panics.
182+
#[inline]
183+
pub fn cause() -> Trap {
184+
try_cause().unwrap()
185+
}
186+
});
187+
167188
Ok(quote! {
168189
/// Interrupt numbers, priority levels, and HART IDs.
169190
pub mod interrupt {

src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@
150150
//!
151151
//! - [`critical-section`](https://crates.io/crates/critical-section) v1.x
152152
//! - [`riscv`](https://crates.io/crates/riscv) v0.9.x (if target is RISC-V) TODO update version
153-
//! - [`riscv-pac`](https://crates.io/crates/riscv-pac) v0.9.x (if target is RISC-V) TODO update version
154153
//! - [`riscv-peripheral`](https://crates.io/crates/riscv-peripheral) v0.9.x (if target is RISC-V and has standard peripherals) TODO update version
155154
//! - [`riscv-rt`](https://crates.io/crates/riscv-rt) v0.9.x (if target is RISC-V) TODO update version
156155
//! - [`vcell`](https://crates.io/crates/vcell) v0.1.x
@@ -163,7 +162,6 @@
163162
//! [dependencies]
164163
//! critical-section = { version = "1.0", optional = true }
165164
//! riscv = "0.9.0" // TODO update version
166-
//! riscv-pac = "0.9.0" // TODO update version
167165
//! riscv-peripheral = "0.9.0" // TODO update version
168166
//! riscv-rt = { version = "0.9.0", optional = true } // TODO update version
169167
//! vcell = "0.1.0"

0 commit comments

Comments
 (0)