diff --git a/CHANGELOG.md b/CHANGELOG.md index 9de16384..3d26f66b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/). - Adapt RISC-V specific codegen for `riscv-peripheral` v0.3.0 rework - Include `riscv-peripheral` peripherals in `Peripherals` struct - Ensure `__INTERRUPTS` are `#[no_mangle]` on Xtensa. +- Add `base_isa` field to `riscv_config` to allow the `riscv_rt::core_interrupt` + macro to properly generate start trap assembly routines in vectored mode. ## [v0.36.1] - 2025-04-04 diff --git a/src/config/riscv.rs b/src/config/riscv.rs index 477c5848..de8a6146 100644 --- a/src/config/riscv.rs +++ b/src/config/riscv.rs @@ -1,3 +1,4 @@ +use log::warn; use proc_macro2::TokenStream; use quote::quote; @@ -11,21 +12,38 @@ pub struct RiscvConfig { pub harts: Vec, pub clint: Option, pub plic: Option, + pub base_isa: Option, pub mtvec_align: Option, } impl RiscvConfig { pub fn extra_build(&self) -> Option { - self.mtvec_align.map(|align| { - quote! { + let mut res = vec![]; + if let Some(base_isa) = self.base_isa.as_ref() { + let base_isa = base_isa.to_lowercase(); + let rustcv_env = format!("cargo:rustc-env=RISCV_RT_BASE_ISA={base_isa}"); + res.push(quote! { + // set environment variable RISCV_BASE_ISA to enforce correct base ISA. + println!(#rustcv_env); + println!("cargo:rerun-if-env-changed=RISCV_RT_BASE_ISA"); + }); + } else { + warn!("No base RISC-V ISA specified in settings file."); + warn!("If your target supports vectored mode, you must specify the base ISA."); + warn!("Otherwise, `riscv-rt` macros will not provide start trap routines to core interrupt handlers"); + } + if let Some(align) = self.mtvec_align { + let rustcv_env = format!("cargo:rustc-env=RISCV_MTVEC_ALIGN={align}"); + res.push(quote! { // set environment variable RISCV_MTVEC_ALIGN enfoce correct byte alignment of interrupt vector. - println!( - "cargo:rustc-env=RISCV_MTVEC_ALIGN={}", - #align - ); + println!(#rustcv_env); println!("cargo:rerun-if-env-changed=RISCV_MTVEC_ALIGN"); - } - }) + }); + } + match res.is_empty() { + true => None, + false => Some(quote! { #(#res)* }), + } } } @@ -66,3 +84,15 @@ pub struct RiscvPlicConfig { pub core_interrupt: Option, pub hart_id: Option, } + +#[cfg_attr(feature = "serde", derive(serde::Deserialize))] +pub enum RiscvBaseIsa { + #[cfg_attr(feature = "serde", serde(rename = "rv32i"))] + Rv32I, + #[cfg_attr(feature = "serde", serde(rename = "rv32e"))] + Rv32E, + #[cfg_attr(feature = "serde", serde(rename = "rv64i"))] + Rv64I, + #[cfg_attr(feature = "serde", serde(rename = "rv64e"))] + Rv64E, +}