Skip to content

Commit

Permalink
Use environment variables for finding out the base ISA on riscv_rt_ma…
Browse files Browse the repository at this point in the history
…cros
  • Loading branch information
romancardenas committed Nov 27, 2024
1 parent 1e71338 commit 0dda7f8
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 109 deletions.
18 changes: 16 additions & 2 deletions riscv-rt/build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// NOTE: Adapted from cortex-m/build.rs

use riscv_target_parser::RiscvTarget;
use riscv_target_parser::{Extension, RiscvTarget, Width};
use std::{env, fs, io, path::PathBuf};

fn add_linker_script(arch_width: u32) -> io::Result<()> {
Expand Down Expand Up @@ -28,11 +28,25 @@ fn main() {
let cargo_flags = env::var("CARGO_ENCODED_RUSTFLAGS").unwrap();

if let Ok(target) = RiscvTarget::build(&target, &cargo_flags) {
let width = target.width();
let base = target.base_extension().expect("No base extension found");

// set environmet variable RISCV_RT_BASE_ISA to the width of the target
// this is used in riscv_rt_macros to determine the base ISA
let env_var = match (width, base) {
(Width::W32, Extension::I) => "rv32i",
(Width::W32, Extension::E) => "rv32e",
(Width::W64, Extension::I) => "rv64i",
(Width::W64, Extension::E) => "rv64e",
_ => panic!("Unsupported target"),
};
println!("cargo:rustc-env=RISCV_RT_BASE_ISA={env_var}");

for flag in target.rustc_flags() {
// Required until target_feature risc-v is stable and in-use
println!("cargo:rustc-check-cfg=cfg({flag})");
println!("cargo:rustc-cfg={flag}");
}
add_linker_script(target.width().into()).unwrap();
add_linker_script(width.into()).unwrap();
}
}
107 changes: 14 additions & 93 deletions riscv-rt/macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
#![deny(warnings)]

extern crate core;
extern crate proc_macro;
extern crate proc_macro2;
extern crate quote;
extern crate syn;

use std::vec;

use proc_macro::TokenStream;
use proc_macro2::{Span, TokenStream as TokenStream2};
use quote::quote;
use syn::{
Expand All @@ -18,8 +11,6 @@ use syn::{
FnArg, ItemFn, LitInt, LitStr, PatType, Path, ReturnType, Token, Type, Visibility,
};

use proc_macro::TokenStream;

/// Attribute to declare the entry point of the program
///
/// **IMPORTANT**: This attribute must appear exactly *once* in the dependency graph. Also, if you
Expand Down Expand Up @@ -381,6 +372,17 @@ impl syn::parse::Parse for RiscvArch {
}

impl RiscvArch {
fn try_from_env() -> Option<Self> {
let arch = std::env::var("RISCV_RT_BASE_ISA").ok()?;
match arch.as_str() {
"rv32i" => Some(Self::Rv32I),
"rv32e" => Some(Self::Rv32E),
"rv64i" => Some(Self::Rv64I),
"rv64e" => Some(Self::Rv64E),
_ => None,
}
}

fn width(&self) -> usize {
match self {
Self::Rv32I | Self::Rv32E => 4,
Expand Down Expand Up @@ -643,94 +645,14 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
/// loop{};
/// }
/// ```
pub fn core_interrupt_rv32i(args: TokenStream, input: TokenStream) -> TokenStream {
pub fn core_interrupt(args: TokenStream, input: TokenStream) -> TokenStream {
let arch = match () {
#[cfg(feature = "v-trap")]
() => Some(RiscvArch::Rv32I),
#[cfg(not(feature = "v-trap"))]
() => None,
};
trap(args, input, RiscvPacItem::CoreInterrupt, arch)
}

#[proc_macro_attribute]
/// Attribute to declare a core interrupt handler.
///
/// The function must have the signature `[unsafe] fn() [-> !]`.
///
/// The argument of the macro must be a path to a variant of an enum that implements the `riscv_rt::CoreInterruptNumber` trait.
///
/// If the `v-trap` feature is enabled, this macro generates the corresponding interrupt trap handler in assembly.
///
/// # Example
///
/// ``` ignore,no_run
/// #[riscv_rt::core_interrupt(riscv::interrupt::Interrupt::SupervisorSoft)]
/// fn supervisor_soft() -> ! {
/// loop{};
/// }
/// ```
pub fn core_interrupt_rv32e(args: TokenStream, input: TokenStream) -> TokenStream {
let arch = match () {
#[cfg(feature = "v-trap")]
() => Some(RiscvArch::Rv32E),
#[cfg(not(feature = "v-trap"))]
() => None,
};
trap(args, input, RiscvPacItem::CoreInterrupt, arch)
}

#[proc_macro_attribute]
/// Attribute to declare a core interrupt handler.
///
/// The function must have the signature `[unsafe] fn() [-> !]`.
///
/// The argument of the macro must be a path to a variant of an enum that implements the `riscv_rt::CoreInterruptNumber` trait.
///
/// If the `v-trap` feature is enabled, this macro generates the corresponding interrupt trap handler in assembly.
///
/// # Example
///
/// ``` ignore,no_run
/// #[riscv_rt::core_interrupt(riscv::interrupt::Interrupt::SupervisorSoft)]
/// fn supervisor_soft() -> ! {
/// loop{};
/// }
/// ```
pub fn core_interrupt_rv64i(args: TokenStream, input: TokenStream) -> TokenStream {
let arch = match () {
#[cfg(feature = "v-trap")]
() => Some(RiscvArch::Rv64I),
#[cfg(not(feature = "v-trap"))]
() => None,
() => RiscvArch::try_from_env(),
};
trap(args, input, RiscvPacItem::CoreInterrupt, arch)
}

#[proc_macro_attribute]
/// Attribute to declare a core interrupt handler.
///
/// The function must have the signature `[unsafe] fn() [-> !]`.
///
/// The argument of the macro must be a path to a variant of an enum that implements the `riscv_rt::CoreInterruptNumber` trait.
///
/// If the `v-trap` feature is enabled, this macro generates the corresponding interrupt trap handler in assembly.
///
/// # Example
///
/// ``` ignore,no_run
/// #[riscv_rt::core_interrupt(riscv::interrupt::Interrupt::SupervisorSoft)]
/// fn supervisor_soft() -> ! {
/// loop{};
/// }
/// ```
pub fn core_interrupt_rv64e(args: TokenStream, input: TokenStream) -> TokenStream {
let arch = match () {
#[cfg(feature = "v-trap")]
() => Some(RiscvArch::Rv64E),
#[cfg(not(feature = "v-trap"))]
() => None,
};
trap(args, input, RiscvPacItem::CoreInterrupt, arch)
}

Expand Down Expand Up @@ -790,7 +712,6 @@ fn trap(
Some(arch) => {
let trap = start_interrupt_trap(int_ident, arch);
quote! {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
#trap
}
}
Expand Down
15 changes: 1 addition & 14 deletions riscv-rt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,21 +547,8 @@ use riscv::register::scause as xcause;
#[cfg(not(feature = "s-mode"))]
use riscv::register::mcause as xcause;

pub use riscv_rt_macros::{entry, exception, external_interrupt, pre_init};

pub use riscv_pac::*;

#[cfg(all(target_arch = "riscv32", riscve))]
pub use riscv_rt_macros::core_interrupt_rv32e as core_interrupt;
#[cfg(all(target_arch = "riscv32", riscvi))]
pub use riscv_rt_macros::core_interrupt_rv32i as core_interrupt;
#[cfg(all(target_arch = "riscv64", riscve))]
pub use riscv_rt_macros::core_interrupt_rv64e as core_interrupt;
#[cfg(any(
all(target_arch = "riscv64", riscvi),
not(any(target_arch = "riscv32", target_arch = "riscv64"))
))]
pub use riscv_rt_macros::core_interrupt_rv64i as core_interrupt;
pub use riscv_rt_macros::{core_interrupt, entry, exception, external_interrupt, pre_init};

/// We export this static with an informative name so that if an application attempts to link
/// two copies of riscv-rt together, linking will fail. We also declare a links key in
Expand Down

0 comments on commit 0dda7f8

Please sign in to comment.