diff --git a/bootloader/rustsbi-qemu.bin b/bootloader/rustsbi-qemu.bin index 022c7f27..f9015b81 100755 Binary files a/bootloader/rustsbi-qemu.bin and b/bootloader/rustsbi-qemu.bin differ diff --git a/os/Cargo.toml b/os/Cargo.toml index 3ca8312c..5b740407 100644 --- a/os/Cargo.toml +++ b/os/Cargo.toml @@ -10,5 +10,7 @@ edition = "2021" riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] } lazy_static = { version = "1.4.0", features = ["spin_no_std"] } log = "0.4" +sbi-rt = { version = "0.0.2", features = ["legacy"] } + [profile.release] debug = true diff --git a/os/src/boards/qemu.rs b/os/src/boards/qemu.rs deleted file mode 100644 index 285be40f..00000000 --- a/os/src/boards/qemu.rs +++ /dev/null @@ -1,79 +0,0 @@ -//ref:: https://github.com/andre-richter/qemu-exit -use core::arch::asm; - -const EXIT_SUCCESS: u32 = 0x5555; // Equals `exit(0)`. qemu successful exit - -const EXIT_FAILURE_FLAG: u32 = 0x3333; -const EXIT_FAILURE: u32 = exit_code_encode(1); // Equals `exit(1)`. qemu failed exit -const EXIT_RESET: u32 = 0x7777; // qemu reset - -pub trait QEMUExit { - /// Exit with specified return code. - /// - /// Note: For `X86`, code is binary-OR'ed with `0x1` inside QEMU. - fn exit(&self, code: u32) -> !; - - /// Exit QEMU using `EXIT_SUCCESS`, aka `0`, if possible. - /// - /// Note: Not possible for `X86`. - fn exit_success(&self) -> !; - - /// Exit QEMU using `EXIT_FAILURE`, aka `1`. - fn exit_failure(&self) -> !; -} - -/// RISCV64 configuration -pub struct RISCV64 { - /// Address of the sifive_test mapped device. - addr: u64, -} - -/// Encode the exit code using EXIT_FAILURE_FLAG. -const fn exit_code_encode(code: u32) -> u32 { - (code << 16) | EXIT_FAILURE_FLAG -} - -impl RISCV64 { - /// Create an instance. - pub const fn new(addr: u64) -> Self { - RISCV64 { addr } - } -} - -impl QEMUExit for RISCV64 { - /// Exit qemu with specified exit code. - fn exit(&self, code: u32) -> ! { - // If code is not a special value, we need to encode it with EXIT_FAILURE_FLAG. - let code_new = match code { - EXIT_SUCCESS | EXIT_FAILURE | EXIT_RESET => code, - _ => exit_code_encode(code), - }; - - unsafe { - asm!( - "sw {0}, 0({1})", - in(reg)code_new, in(reg)self.addr - ); - - // For the case that the QEMU exit attempt did not work, transition into an infinite - // loop. Calling `panic!()` here is unfeasible, since there is a good chance - // this function here is the last expression in the `panic!()` handler - // itself. This prevents a possible infinite loop. - loop { - asm!("wfi", options(nomem, nostack)); - } - } - } - - fn exit_success(&self) -> ! { - self.exit(EXIT_SUCCESS); - } - - fn exit_failure(&self) -> ! { - self.exit(EXIT_FAILURE); - } -} - -const VIRT_TEST: u64 = 0x100000; - -pub const QEMU_EXIT_HANDLE: RISCV64 = RISCV64::new(VIRT_TEST); diff --git a/os/src/lang_items.rs b/os/src/lang_items.rs index db902c35..24ec29d1 100644 --- a/os/src/lang_items.rs +++ b/os/src/lang_items.rs @@ -15,5 +15,5 @@ fn panic(info: &PanicInfo) -> ! { } else { println!("[kernel] Panicked: {}", info.message().unwrap()); } - shutdown() + shutdown(true) } diff --git a/os/src/main.rs b/os/src/main.rs index 5b2135b4..2deec4ab 100644 --- a/os/src/main.rs +++ b/os/src/main.rs @@ -22,8 +22,6 @@ use core::arch::global_asm; -#[path = "boards/qemu.rs"] -mod board; use log::*; #[macro_use] mod console; diff --git a/os/src/sbi.rs b/os/src/sbi.rs index c0998794..62da527c 100644 --- a/os/src/sbi.rs +++ b/os/src/sbi.rs @@ -1,42 +1,25 @@ //! SBI call wrappers -use core::arch::asm; - -const SBI_CONSOLE_PUTCHAR: usize = 1; - -// const SBI_SET_TIMER: usize = 0; -// const SBI_CONSOLE_GETCHAR: usize = 2; -// const SBI_CLEAR_IPI: usize = 3; -// const SBI_SEND_IPI: usize = 4; -// const SBI_REMOTE_FENCE_I: usize = 5; -// const SBI_REMOTE_SFENCE_VMA: usize = 6; -// const SBI_REMOTE_SFENCE_VMA_ASID: usize = 7; -// const SBI_SHUTDOWN: usize = 8; - -/// handle SBI call with `which` SBI_id and other arguments -#[inline(always)] -fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize { - let mut ret; - unsafe { - asm!( - "li x16, 0", - "ecall", - inlateout("x10") arg0 => ret, - in("x11") arg1, - in("x12") arg2, - in("x17") which, - ); - } - ret -} - /// use sbi call to putchar in console (qemu uart handler) pub fn console_putchar(c: usize) { - sbi_call(SBI_CONSOLE_PUTCHAR, c, 0, 0); + #[allow(deprecated)] + sbi_rt::legacy::console_putchar(c); } -use crate::board::QEMUExit; -/// use sbi call to shutdown the kernel -pub fn shutdown() -> ! { - crate::board::QEMU_EXIT_HANDLE.exit_failure(); +/// use sbi call to getchar from console (qemu uart handler) +#[allow(unused)] +pub fn console_getchar() -> usize { + #[allow(deprecated)] + sbi_rt::legacy::console_getchar() +} + +/// use sbi call to shutdown the kernel +pub fn shutdown(failure: bool) -> ! { + use sbi_rt::{system_reset, NoReason, Shutdown, SystemFailure}; + if !failure { + system_reset(Shutdown, NoReason); + } else { + system_reset(Shutdown, SystemFailure); + } + unreachable!() }