diff --git a/CHANGELOG.md b/CHANGELOG.md index 61d9a21..6de1f23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Xtask will now print error when system does not have qemu installed - Fix dtb parsing for qemu 7.2 +## [0.1.0] - 2022-02-13 + +### Added + +- Adapts to RustSBI version 0.2.0 +- Implement SBI non-retentive resume procedure +- PMP updates, use stabilized core::arch::asm! macro, thanks to @wyfcyx +- Fixes on usage of CLINT peripheral, thanks to @duskmoon314 +- Numerous fixes to HSM module implementation, more documents + ## [0.1.1] - 2022-03-23 ### Added @@ -45,15 +55,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Use Rust Edition 2021 - Modify test kernel message -## [0.1.0] - 2022-02-13 +## [0.1.2] - 2025-05-16 -### Added +### Modified -- Adapts to RustSBI version 0.2.0 -- Implement SBI non-retentive resume procedure -- PMP updates, use stabilized core::arch::asm! macro, thanks to @wyfcyx -- Fixes on usage of CLINT peripheral, thanks to @duskmoon314 -- Numerous fixes to HSM module implementation, more documents +- Bump fast-trap version to 0.1.0 +- Bump aclint version to 0.1.0 + +### Fixed + +- Reorder date for CHANGELOG.md +- Replace #[naked] with #[unsafe(naked)] across all relevant functions. +- Remove `#![feature(naked_functions, asm_const)]` as they are no longer needed. +- Switche to the `naked_asm!` macro to comply with new naked function requirements. +- Remove `options(noreturn)`, which is not allowed in `naked_asm!`. +- Fix warning `creating a mutable/shared reference to mutable static` in multiple files. [Unreleased]: https://github.com/rustsbi/rustsbi-qemu/compare/v0.1.1...HEAD [0.1.1]: https://github.com/rustsbi/rustsbi-qemu/compare/v0.1.0...v0.1.1 diff --git a/Cargo.lock b/Cargo.lock index 8b01ae2..b903dce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "aclint" -version = "0.0.0" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a01ba40421eca6c4f1afcedd8465fba6d9e5ef8e0e13060d0141e4cded4ab4a" +checksum = "8cc30f3f60fd3106787fa9b540e64372dd4793813c400ba12d113506e94dcb8c" [[package]] name = "anstream" @@ -154,9 +154,9 @@ checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" [[package]] name = "fast-trap" -version = "0.0.1" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fbe69badc2e0dc98ad2787648fa140b5772d24b49e9a6b180a67e1348f7544c" +checksum = "46da95e6fcc7619a12d05594693e48591c0b574aef6fe5d7a7e765e6763a2cb2" [[package]] name = "heck" diff --git a/bench-kernel/src/main.rs b/bench-kernel/src/main.rs index 572dbf3..d5feb48 100644 --- a/bench-kernel/src/main.rs +++ b/bench-kernel/src/main.rs @@ -1,6 +1,5 @@ #![no_std] #![no_main] -#![feature(naked_functions, asm_const)] #![deny(warnings)] use rcore_console::log; @@ -8,7 +7,7 @@ use riscv::register::*; use sbi_rt::*; use uart16550::Uart16550; -#[naked] +#[unsafe(naked)] #[no_mangle] #[link_section = ".text.entry"] unsafe extern "C" fn _start(hartid: usize, device_tree_paddr: usize) -> ! { @@ -17,13 +16,12 @@ unsafe extern "C" fn _start(hartid: usize, device_tree_paddr: usize) -> ! { #[link_section = ".bss.uninit"] static mut STACK: [u8; STACK_SIZE] = [0u8; STACK_SIZE]; - core::arch::asm!( + core::arch::naked_asm!( "la sp, {stack} + {stack_size}", "j {main}", stack_size = const STACK_SIZE, stack = sym STACK, main = sym rust_main, - options(noreturn), ) } @@ -127,11 +125,17 @@ impl Uart16550Map { impl rcore_console::Console for Console { #[inline] fn put_char(&self, c: u8) { - unsafe { UART.get().write(core::slice::from_ref(&c)) }; + unsafe { + let mut_ref_uart = (*(&raw mut UART)).get(); + mut_ref_uart.write(core::slice::from_ref(&c)); + } } #[inline] fn put_str(&self, s: &str) { - unsafe { UART.get().write(s.as_bytes()) }; + unsafe { + let mut_ref_uart = (*(&raw mut UART)).get(); + mut_ref_uart.write(s.as_bytes()); + } } } diff --git a/rustsbi-qemu/Cargo.toml b/rustsbi-qemu/Cargo.toml index db3113b..afdd74d 100644 --- a/rustsbi-qemu/Cargo.toml +++ b/rustsbi-qemu/Cargo.toml @@ -22,10 +22,10 @@ sbi-spec = { version = "0.0.7", features = ["legacy"] } riscv = "0.10.1" spin = "0.9" rcore-console = "0.0.0" -aclint = "0.0.0" +aclint = "0.1.0" sifive-test-device = "0.0.0" dtb-walker = "=0.2.0-alpha.3" uart16550 = "0.0.1" hsm-cell = { path = "../hsm-cell" } -fast-trap = { version = "=0.0.1", features = ["riscv-m"] } +fast-trap = { version = "=0.1.0", features = ["riscv-m"] } diff --git a/rustsbi-qemu/src/main.rs b/rustsbi-qemu/src/main.rs index faa8472..840aa65 100644 --- a/rustsbi-qemu/src/main.rs +++ b/rustsbi-qemu/src/main.rs @@ -1,6 +1,5 @@ #![no_std] #![no_main] -#![feature(naked_functions, asm_const)] #![deny(warnings)] mod clint; @@ -27,15 +26,13 @@ extern crate rcore_console; use constants::*; use core::{ - arch::asm, - mem::MaybeUninit, - sync::atomic::{AtomicBool, Ordering}, + arch::{asm, naked_asm}, mem::MaybeUninit, sync::atomic::{AtomicBool, Ordering} }; use device_tree::BoardInfo; use fast_trap::{FastContext, FastResult}; use riscv_spec::*; use rustsbi::{RustSBI, SbiRet}; -use spin::Once; +use spin::{Mutex, Once}; use trap_stack::{local_hsm, local_remote_hsm, remote_hsm}; use trap_vec::trap_vec; @@ -44,11 +41,11 @@ use trap_vec::trap_vec; /// # Safety /// /// 裸函数。 -#[naked] +#[unsafe(naked)] #[no_mangle] #[link_section = ".text.entry"] unsafe extern "C" fn _start() -> ! { - asm!( + naked_asm!( " call {locate_stack} call {rust_main} j {trap} @@ -56,7 +53,6 @@ unsafe extern "C" fn _start() -> ! { locate_stack = sym trap_stack::locate, rust_main = sym rust_main, trap = sym trap_vec, - options(noreturn), ) } @@ -112,13 +108,14 @@ extern "C" fn rust_main(hartid: usize, opaque: usize) { firmware = _start as usize, ); // 初始化 SBI + let sbi = SBI.lock().as_mut_ptr(); unsafe { - SBI = MaybeUninit::new(FixedRustSBI { + *sbi = FixedRustSBI { clint: &clint::Clint, hsm: Hsm, reset: qemu_test::get(), dbcn: dbcn::get(), - }); + }; } // 设置并打印 pmp set_pmp(board_info); @@ -222,11 +219,14 @@ extern "C" fn fast_handler( // SBI call T::Exception(E::SupervisorEnvCall) => { use sbi_spec::{base, hsm, legacy}; - let mut ret = unsafe { SBI.assume_init_mut() }.handle_ecall( - a7, - a6, - [ctx.a0(), a1, a2, a3, a4, a5], - ); + let mut ret = unsafe { + let sbi = SBI.lock().as_mut_ptr(); + (*sbi).handle_ecall( + a7, + a6, + [ctx.a0(), a1, a2, a3, a4, a5], + ) + }; if ret.is_ok() { match (a7, a6) { // 关闭 @@ -337,7 +337,7 @@ impl rcore_console::Console for Console { } } -static mut SBI: MaybeUninit = MaybeUninit::uninit(); +static SBI: Mutex> = Mutex::new(MaybeUninit::uninit()); #[derive(RustSBI)] struct FixedRustSBI<'a> { diff --git a/rustsbi-qemu/src/trap_stack.rs b/rustsbi-qemu/src/trap_stack.rs index e8b3b3e..80f0628 100644 --- a/rustsbi-qemu/src/trap_stack.rs +++ b/rustsbi-qemu/src/trap_stack.rs @@ -1,16 +1,24 @@ use crate::{fast_handler, hart_id, Supervisor, LEN_STACK_PER_HART, NUM_HART_MAX}; -use core::{mem::forget, ptr::NonNull}; +use core::{cell::UnsafeCell, mem::forget, ptr::NonNull}; use fast_trap::{FlowContext, FreeTrapStack}; use hsm_cell::{HsmCell, LocalHsmCell, RemoteHsmCell}; +#[repr(transparent)] +struct HartLocal(UnsafeCell); + +unsafe impl Sync for HartLocal {} + /// 栈空间。 #[link_section = ".bss.uninit"] -static mut ROOT_STACK: [Stack; NUM_HART_MAX] = [Stack::ZERO; NUM_HART_MAX]; +static ROOT_STACK: [HartLocal; NUM_HART_MAX] = { + const INIT: HartLocal = HartLocal(UnsafeCell::new(Stack::ZERO)); + [INIT; NUM_HART_MAX] +}; /// 定位每个 hart 的栈。 -#[naked] +#[unsafe(naked)] pub(crate) unsafe extern "C" fn locate() { - core::arch::asm!( + core::arch::naked_asm!( " la sp, {stack} li t0, {per_hart_stack_size} csrr t1, mhartid @@ -24,43 +32,40 @@ pub(crate) unsafe extern "C" fn locate() { per_hart_stack_size = const LEN_STACK_PER_HART, stack = sym ROOT_STACK, move_stack = sym fast_trap::reuse_stack_for_trap, - options(noreturn), ) } /// 预备陷入栈。 pub(crate) fn prepare_for_trap() { - unsafe { ROOT_STACK.get_unchecked_mut(hart_id()).load_as_stack() }; + unsafe { + let stack = &mut *ROOT_STACK.get_unchecked(hart_id()).0.get(); + stack.load_as_stack() + }; } /// 获取此 hart 的 local hsm 对象。 pub(crate) fn local_hsm() -> LocalHsmCell<'static, Supervisor> { unsafe { - ROOT_STACK - .get_unchecked_mut(hart_id()) - .hart_context() - .hsm - .local() + let stack = &mut *ROOT_STACK.get_unchecked(hart_id()).0.get(); + stack.hart_context().hsm.local() } } /// 获取此 hart 的 remote hsm 对象。 pub(crate) fn local_remote_hsm() -> RemoteHsmCell<'static, Supervisor> { unsafe { - ROOT_STACK - .get_unchecked_mut(hart_id()) - .hart_context() - .hsm - .remote() + let stack = &mut *ROOT_STACK.get_unchecked(hart_id()).0.get(); + stack.hart_context().hsm.remote() } } /// 获取任意 hart 的 remote hsm 对象。 pub(crate) fn remote_hsm(hart_id: usize) -> Option> { unsafe { - ROOT_STACK - .get_mut(hart_id) - .map(|x| x.hart_context().hsm.remote()) + ROOT_STACK.get(hart_id).map(|cell| { + let stack = &mut *cell.0.get(); + stack.hart_context().hsm.remote() + }) } } diff --git a/rustsbi-qemu/src/trap_vec.rs b/rustsbi-qemu/src/trap_vec.rs index 7092edb..028c58f 100644 --- a/rustsbi-qemu/src/trap_vec.rs +++ b/rustsbi-qemu/src/trap_vec.rs @@ -1,6 +1,6 @@ use crate::clint::CLINT; use aclint::SifiveClint as Clint; -use core::arch::asm; +use core::arch::naked_asm; use fast_trap::trap_entry; /// 中断向量表 @@ -8,9 +8,9 @@ use fast_trap::trap_entry; /// # Safety /// /// 裸函数。 -#[naked] +#[unsafe(naked)] pub(crate) unsafe extern "C" fn trap_vec() { - asm!( + naked_asm!( ".align 2", ".option push", ".option norvc", @@ -30,7 +30,6 @@ pub(crate) unsafe extern "C" fn trap_vec() { default = sym trap_entry, mtimer = sym mtimer, msoft = sym msoft, - options(noreturn) ) } @@ -39,9 +38,9 @@ pub(crate) unsafe extern "C" fn trap_vec() { /// # Safety /// /// 裸函数。 -#[naked] +#[unsafe(naked)] unsafe extern "C" fn mtimer() { - asm!( + naked_asm!( // 换栈: // sp : M sp // mscratch: S sp @@ -81,7 +80,6 @@ unsafe extern "C" fn mtimer() { clint_ptr = sym CLINT, // Clint::write_mtimecmp_naked(&self, hart_idx, val) set_mtimecmp = sym Clint::write_mtimecmp_naked, - options(noreturn) ) } @@ -90,9 +88,9 @@ unsafe extern "C" fn mtimer() { /// # Safety /// /// 裸函数。 -#[naked] +#[unsafe(naked)] unsafe extern "C" fn msoft() { - asm!( + naked_asm!( // 换栈: // sp : M sp // mscratch: S sp @@ -125,6 +123,5 @@ unsafe extern "C" fn msoft() { clint_ptr = sym CLINT, // Clint::clear_msip_naked(&self, hart_idx) clear_msip = sym Clint::clear_msip_naked, - options(noreturn) ) } diff --git a/test-kernel/src/main.rs b/test-kernel/src/main.rs index 91743c7..2fd5e18 100644 --- a/test-kernel/src/main.rs +++ b/test-kernel/src/main.rs @@ -1,12 +1,11 @@ #![no_std] #![no_main] -#![feature(naked_functions, asm_const)] #![deny(warnings)] #[macro_use] extern crate rcore_console; -use core::{arch::asm, ptr::null}; +use core::{arch::{asm, naked_asm}, ptr::null}; use sbi_testing::sbi; use uart16550::Uart16550; @@ -15,7 +14,7 @@ use uart16550::Uart16550; /// # Safety /// /// 裸函数。 -#[naked] +#[unsafe(naked)] #[no_mangle] #[link_section = ".text.entry"] unsafe extern "C" fn _start(hartid: usize, device_tree_paddr: usize) -> ! { @@ -24,13 +23,12 @@ unsafe extern "C" fn _start(hartid: usize, device_tree_paddr: usize) -> ! { #[link_section = ".bss.uninit"] static mut STACK: [u8; STACK_SIZE] = [0u8; STACK_SIZE]; - asm!( + naked_asm!( "la sp, {stack} + {stack_size}", "j {main}", stack_size = const STACK_SIZE, stack = sym STACK, main = sym rust_main, - options(noreturn), ) } @@ -170,11 +168,17 @@ impl Uart16550Map { impl rcore_console::Console for Console { #[inline] fn put_char(&self, c: u8) { - unsafe { UART.get().write(core::slice::from_ref(&c)) }; + unsafe { + let mut_ref_uart = (*(&raw mut UART)).get(); + mut_ref_uart.write(core::slice::from_ref(&c)) + }; } #[inline] fn put_str(&self, s: &str) { - unsafe { UART.get().write(s.as_bytes()) }; + unsafe { + let mut_ref_uart = (*(&raw mut UART)).get(); + mut_ref_uart.write(s.as_bytes()) + }; } }