Skip to content
This repository was archived by the owner on Nov 28, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ license = "ISC"
[dependencies]
r0 = "1.0.0"
riscv = "0.8"
riscv-rt-macros = { path = "macros", version = "0.1.6" }
riscv-rt-macros = { path = "macros", version = "0.2.0" }

[dev-dependencies]
panic-halt = "0.2.0"
Expand Down
18 changes: 8 additions & 10 deletions asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ _abs_start:
li x7, 0
li x8, 0
li x9, 0
li x10,0
li x11,0
li x12,0
// a0..a2 (x10..x12) skipped
li x13,0
li x14,0
li x15,0
Expand All @@ -87,23 +85,23 @@ _abs_start:
.option pop

// Check hart id
csrr a2, mhartid
csrr t2, mhartid
lui t0, %hi(_max_hart_id)
add t0, t0, %lo(_max_hart_id)
bgtu a2, t0, abort
bgtu t2, t0, abort

// Allocate stacks
la sp, _stack_start
lui t0, %hi(_hart_stack_size)
add t0, t0, %lo(_hart_stack_size)
#ifdef __riscv_mul
mul t0, a2, t0
mul t0, t2, t0
#else
beqz a2, 2f // Jump if single-hart
mv t1, a2
mv t2, t0
beqz t2, 2f // Jump if single-hart
mv t1, t2
mv t3, t0
1:
add t0, t0, t2
add t0, t0, t3
addi t1, t1, -1
bnez t1, 1b
2:
Expand Down
Binary file modified bin/riscv32i-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv32ic-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv32if-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv32ifc-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv32ifd-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv32ifdc-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv32im-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv32imc-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv32imf-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv32imfc-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv32imfd-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv32imfdc-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv64i-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv64ic-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv64if-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv64ifc-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv64ifd-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv64ifdc-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv64im-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv64imc-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv64imf-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv64imfc-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv64imfd-unknown-none-elf.a
Binary file not shown.
Binary file modified bin/riscv64imfdc-unknown-none-elf.a
Binary file not shown.
2 changes: 1 addition & 1 deletion macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ keywords = ["riscv", "runtime", "startup"]
license = "MIT OR Apache-2.0"
name = "riscv-rt-macros"
repository = "https://github.com/rust-embedded/riscv-rt"
version = "0.1.6"
version = "0.2.0"

[lib]
proc-macro = true
Expand Down
52 changes: 44 additions & 8 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ extern crate proc_macro2;
extern crate syn;

use proc_macro2::Span;
use syn::{parse, spanned::Spanned, ItemFn, ReturnType, Type, Visibility};
use syn::{parse, spanned::Spanned, FnArg, ItemFn, PathArguments, ReturnType, Type, Visibility};

use proc_macro::TokenStream;

Expand Down Expand Up @@ -48,27 +48,49 @@ use proc_macro::TokenStream;
pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
let f = parse_macro_input!(input as ItemFn);

// check the function arguments
if f.sig.inputs.len() > 3 {
return parse::Error::new(
f.sig.inputs.last().unwrap().span(),
"`#[entry]` function has too many arguments",
)
.to_compile_error()
.into();
}
for arg in &f.sig.inputs {
match arg {
FnArg::Receiver(_) => {
return parse::Error::new(arg.span(), "invalid argument")
.to_compile_error()
.into();
}
FnArg::Typed(t) => {
if !is_simple_type(&t.ty, "usize") {
return parse::Error::new(t.ty.span(), "argument type must be usize")
.to_compile_error()
.into();
}
}
}
}

// check the function signature
let valid_signature = f.sig.constness.is_none()
&& f.sig.asyncness.is_none()
&& f.vis == Visibility::Inherited
&& f.sig.abi.is_none()
&& f.sig.inputs.is_empty()
&& f.sig.generics.params.is_empty()
&& f.sig.generics.where_clause.is_none()
&& f.sig.variadic.is_none()
&& match f.sig.output {
ReturnType::Default => false,
ReturnType::Type(_, ref ty) => match **ty {
Type::Never(_) => true,
_ => false,
},
ReturnType::Type(_, ref ty) => matches!(**ty, Type::Never(_)),
};

if !valid_signature {
return parse::Error::new(
f.span(),
"`#[entry]` function must have signature `[unsafe] fn() -> !`",
"`#[entry]` function must have signature `[unsafe] fn([arg0: usize, ...]) -> !`",
)
.to_compile_error()
.into();
Expand All @@ -83,18 +105,32 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
// XXX should we blacklist other attributes?
let attrs = f.attrs;
let unsafety = f.sig.unsafety;
let args = f.sig.inputs;
let stmts = f.block.stmts;

quote!(
#[export_name = "main"]
#(#attrs)*
pub #unsafety fn __risc_v_rt__main() -> ! {
pub #unsafety fn __risc_v_rt__main(#args) -> ! {
#(#stmts)*
}
)
.into()
}

#[allow(unused)]
fn is_simple_type(ty: &Type, name: &str) -> bool {
if let Type::Path(p) = ty {
if p.qself.is_none() && p.path.leading_colon.is_none() && p.path.segments.len() == 1 {
let segment = p.path.segments.first().unwrap();
if segment.ident == name && segment.arguments == PathArguments::None {
return true;
}
}
}
false
}

/// Attribute to mark which function will be called at the beginning of the reset handler.
///
/// **IMPORTANT**: This attribute can appear at most *once* in the dependency graph. Also, if you
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,11 +361,11 @@ extern "C" {
/// never returns.
#[link_section = ".init.rust"]
#[export_name = "_start_rust"]
pub unsafe extern "C" fn start_rust() -> ! {
pub unsafe extern "C" fn start_rust(a0: usize, a1: usize, a2: usize) -> ! {
#[rustfmt::skip]
extern "Rust" {
// This symbol will be provided by the user via `#[entry]`
fn main() -> !;
fn main(a0: usize, a1: usize, a2: usize) -> !;

// This symbol will be provided by the user via `#[pre_init]`
fn __pre_init();
Expand All @@ -386,7 +386,7 @@ pub unsafe extern "C" fn start_rust() -> ! {

_setup_interrupts();

main();
main(a0, a1, a2);
}

/// Registers saved in trap handler
Expand Down