#![no_std]
extern "C" {
#[allow(dead_code)]
fn rivet_main() -> !;
}
#[cfg(target_arch = "riscv32")]
mod riscv {
#[no_mangle]
static __rivet_max_harts: u32 = rivet::config::MAX_HARTS as u32;
core::arch::global_asm!(
".section .text._start",
".global _start",
"_start:",
" csrr t0, mhartid",
" bnez t0, secondary_entry",
" la sp, __stack_top",
" la t0, __data_start",
" la t1, __data_end",
" la t2, __data_load",
"3:",
" bgeu t0, t1, 4f",
" lw t3, 0(t2)",
" sw t3, 0(t0)",
" addi t0, t0, 4",
" addi t2, t2, 4",
" j 3b",
"4:",
" la t0, __bss_start",
" la t1, __bss_end",
"1:",
" bgeu t0, t1, 2f",
" sw zero, 0(t0)",
" addi t0, t0, 4",
" j 1b",
"2:",
" call rivet_main",
" j park_hart",
"secondary_entry:",
" la t1, __rivet_max_harts",
" lw t1, 0(t1)",
" bgeu t0, t1, park_hart",
" la t2, __secondary_stacks_top",
" slli t3, t0, 9", " sub sp, t2, t3",
" call rivet_secondary_main",
" j park_hart",
"park_hart:",
" wfi",
" j park_hart",
);
#[no_mangle]
unsafe extern "C" fn rivet_secondary_main() -> ! {
while !rivet::kernel_ready() {
core::hint::spin_loop();
}
rivet::run_secondary_hart();
}
}
#[cfg(target_arch = "arm")]
mod cortex_m {
extern "C" {
static __data_load: u8;
static __data_start: u8;
static __data_end: u8;
static __bss_start: u8;
static __bss_end: u8;
}
#[no_mangle]
pub unsafe extern "C" fn Reset() -> ! {
unsafe {
let data_load = core::ptr::addr_of!(__data_load);
let data_start = core::ptr::addr_of!(__data_start);
let data_end = core::ptr::addr_of!(__data_end);
let count = data_end as usize - data_start as usize;
for i in 0..count {
core::ptr::write(
(data_start as *mut u8).add(i),
core::ptr::read(data_load.add(i)),
);
}
let bss_start = core::ptr::addr_of!(__bss_start);
let bss_end = core::ptr::addr_of!(__bss_end);
let bss_count = bss_end as usize - bss_start as usize;
for i in 0..bss_count {
core::ptr::write((bss_start as *mut u8).add(i), 0);
}
super::rivet_main()
}
}
#[no_mangle]
pub extern "C" fn DefaultHandler() {
rivet::console::write_str("HARD_FAULT\n");
rivet::console::flush_sync();
loop {
core::hint::spin_loop();
}
}
}
#[cfg(target_arch = "xtensa")]
mod xtensa {
#[no_mangle]
pub extern "C" fn main() -> ! {
unsafe { super::rivet_main() }
}
#[no_mangle]
pub extern "C" fn DefaultHandler() {
rivet::console::write_str("UNHANDLED_INTERRUPT\n");
loop {
core::hint::spin_loop();
}
}
}
#[cfg(feature = "panic-handler")]
mod panic {
use core::fmt::Write;
use core::panic::PanicInfo;
struct ConsoleWriter;
impl Write for ConsoleWriter {
fn write_str(&mut self, s: &str) -> core::fmt::Result {
rivet::console::write_str(s);
Ok(())
}
}
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
rivet::console::write_str("PANIC: ");
if let Some(loc) = info.location() {
let _ = write!(ConsoleWriter, "{}:{}", loc.file(), loc.line());
} else {
rivet::console::write_str("(no location)");
}
rivet::console::write_str(": ");
let _ = write!(ConsoleWriter, "{}", info.message());
rivet::console::write_str("\n");
rivet::exit_failure(0xFF);
}
}