Skip to content

Commit 2e450c5

Browse files
committed
Add configuration for PLIC external interrupt handler
1 parent 787473f commit 2e450c5

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ default = ["bin", "json", "yaml"]
3535
bin = ["dep:clap", "dep:env_logger", "serde", "dep:irx-config"]
3636
json = ["dep:serde_json"]
3737
yaml = ["dep:serde_yaml"]
38-
unstable-riscv = ["svd-rs/unstable-riscv", "svd-parser/unstable-riscv"]
38+
unstable-riscv = []
3939

4040
[dependencies]
4141
clap = { version = "4.0", optional = true }

src/config.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ pub struct RiscvConfig {
325325
pub priorities: Option<Vec<RiscvEnumItem>>,
326326
pub harts: Option<Vec<RiscvEnumItem>>,
327327
pub clint: Option<RiscvClintConfig>,
328-
pub plic: Option<String>,
328+
pub plic: Option<RiscvPlicConfig>,
329329
}
330330

331331
#[cfg(feature = "unstable-riscv")]
@@ -358,3 +358,13 @@ pub struct RiscvClintConfig {
358358
pub freq: Option<usize>,
359359
pub async_delay: bool,
360360
}
361+
362+
#[cfg(feature = "unstable-riscv")]
363+
#[cfg_attr(feature = "serde", derive(serde::Deserialize), serde(default))]
364+
#[derive(Clone, PartialEq, Eq, Debug, Default)]
365+
#[non_exhaustive]
366+
pub struct RiscvPlicConfig {
367+
pub name: String,
368+
pub core_interrupt: Option<String>,
369+
pub hart_id: Option<String>,
370+
}

src/generate/riscv.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub fn is_riscv_peripheral(p: &Peripheral, c: &Config) -> bool {
1010
match &c.riscv_config {
1111
Some(c) => {
1212
c.clint.as_ref().is_some_and(|clint| clint.name == p.name)
13-
|| c.plic.as_ref().is_some_and(|plic| plic == &p.name)
13+
|| c.plic.as_ref().is_some_and(|plic| plic.name == p.name)
1414
}
1515
_ => false,
1616
}
@@ -253,7 +253,7 @@ pub fn render(
253253
});
254254
}
255255
if let Some(plic) = &c.plic {
256-
let p = peripherals.iter().find(|&p| &p.name == plic).unwrap();
256+
let p = peripherals.iter().find(|&p| p.name == plic.name).unwrap();
257257
let base = TokenStream::from_str(&format!("base 0x{:X},", p.base_address)).unwrap();
258258
let ctxs = harts
259259
.iter()
@@ -271,6 +271,27 @@ pub fn render(
271271
riscv_peripherals.extend(quote! {
272272
riscv_peripheral::plic_codegen!(#base #ctxs);
273273
});
274+
275+
if let Some(core_interrupt) = &plic.core_interrupt {
276+
let core_interrupt = TokenStream::from_str(core_interrupt).unwrap();
277+
let ctx = match &plic.hart_id {
278+
Some(hart_id) => {
279+
TokenStream::from_str(&format!("ctx(Hart::{hart_id})")).unwrap()
280+
}
281+
None => quote! { ctx_mhartid() },
282+
};
283+
mod_items.extend(quote! {
284+
#[cfg(feature = "rt")]
285+
#[riscv_rt::core_interrupt(CoreInterrupt::#core_interrupt)]
286+
fn plic_handler() {
287+
let claim = crate::PLIC::#ctx.claim();
288+
if let Some(s) = claim.claim::<CoreInterrupt>() {
289+
unsafe { _dispatch_core_interrupt(s.number()) }
290+
claim.complete(s);
291+
}
292+
}
293+
});
294+
}
274295
}
275296
}
276297

0 commit comments

Comments
 (0)