From 02fb65711ed94679690edfa2955dc64b535aba76 Mon Sep 17 00:00:00 2001 From: Yifan Wu Date: Tue, 28 Mar 2023 00:03:29 +0800 Subject: [PATCH] Using sbi-rt instead of asm && update rustsbi-qemu to latest rustsbi-qemu version: a4f0bbe44d9f2f1069a9e5becd09f291e542852c --- bootloader/rustsbi-qemu.bin | Bin 38920 -> 32328 bytes os/Cargo.toml | 2 + os/src/boards/qemu.rs | 81 ------------------------------------ os/src/lang_items.rs | 2 +- os/src/sbi.rs | 59 +++++++++----------------- 5 files changed, 23 insertions(+), 121 deletions(-) diff --git a/bootloader/rustsbi-qemu.bin b/bootloader/rustsbi-qemu.bin index 022c7f27b18efadbfa80301fb467421c52f7cd5e..f9015b81a17ef461aec196971b2dec52957bf51f 100755 GIT binary patch literal 32328 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 M-#fkiADfr|19gLOQUCw| literal 38920 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 diff --git a/os/Cargo.toml b/os/Cargo.toml index fbcff883..51fc1e88 100644 --- a/os/Cargo.toml +++ b/os/Cargo.toml @@ -19,6 +19,8 @@ lose-net-stack = { git = "https://github.com/yfblock/lose-net-stack", rev = "3f4 easy-fs = { path = "../easy-fs" } embedded-graphics = "0.7.1" tinybmp = "0.3.1" +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 index ffb88539..ad9cf096 100644 --- a/os/src/boards/qemu.rs +++ b/os/src/boards/qemu.rs @@ -103,84 +103,3 @@ pub unsafe extern "C" fn timervec() -> ! { options(noreturn) ); } - - -//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 a33943a1..68d736ec 100644 --- a/os/src/lang_items.rs +++ b/os/src/lang_items.rs @@ -18,7 +18,7 @@ fn panic(info: &PanicInfo) -> ! { unsafe { backtrace(); } - shutdown(255) + shutdown(true) } unsafe fn backtrace() { diff --git a/os/src/sbi.rs b/os/src/sbi.rs index 5113c901..326f4d63 100644 --- a/os/src/sbi.rs +++ b/os/src/sbi.rs @@ -1,46 +1,27 @@ -#![allow(unused)] - -use core::arch::asm; - -const SBI_SET_TIMER: usize = 0; -const SBI_CONSOLE_PUTCHAR: usize = 1; -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; - -#[inline(always)] -fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize { - let mut ret; - unsafe { - core::arch::asm!( - "li x16, 0", - "ecall", - inlateout("x10") arg0 => ret, - in("x11") arg1, - in("x12") arg2, - in("x17") which, - ); - } - ret -} - -pub fn set_timer(timer: usize) { - sbi_call(SBI_SET_TIMER, timer, 0, 0); -} - +/// 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 sbi call to getchar from console (qemu uart handler) pub fn console_getchar() -> usize { - sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0) + #[allow(deprecated)] + sbi_rt::legacy::console_getchar() } -use crate::board::QEMUExit; -pub fn shutdown(exit_code: usize) -> ! { - crate::board::QEMU_EXIT_HANDLE.exit_failure() +/// use sbi call to set timer +pub fn set_timer(timer: usize) { + sbi_rt::set_timer(timer as _); +} + +/// 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!() }