From a7dab8de222660826c87d55ec388161a609f4e80 Mon Sep 17 00:00:00 2001 From: luojia65 Date: Sun, 25 Apr 2021 13:30:11 +0800 Subject: [PATCH] Use syscall instead of SBI call in shared scheduler --- shared-scheduler/src/console.rs | 10 +---- shared-scheduler/src/main.rs | 17 ++++++--- shared-scheduler/src/sbi.rs | 41 -------------------- shared-scheduler/src/syscall.rs | 67 +++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 54 deletions(-) delete mode 100644 shared-scheduler/src/sbi.rs create mode 100644 shared-scheduler/src/syscall.rs diff --git a/shared-scheduler/src/console.rs b/shared-scheduler/src/console.rs index 0e6987f..74ce35d 100644 --- a/shared-scheduler/src/console.rs +++ b/shared-scheduler/src/console.rs @@ -1,4 +1,4 @@ -use crate::sbi::*; +use crate::syscall; use core::fmt::{self, Write}; struct Stdout; @@ -8,18 +8,12 @@ static STDOUT_LOCK: spin::Mutex<()> = spin::Mutex::new(()); impl Write for Stdout { fn write_str(&mut self, s: &str) -> fmt::Result { - let mut buffer = [0u8; 4]; STDOUT_LOCK.lock(); - for c in s.chars() { - for code_point in c.encode_utf8(&mut buffer).as_bytes().iter() { - console_putchar(*code_point as usize); - } - } + syscall::sys_test_write(s.as_bytes()); Ok(()) } } - pub fn print(args: fmt::Arguments) { Stdout.write_fmt(args).unwrap(); } diff --git a/shared-scheduler/src/main.rs b/shared-scheduler/src/main.rs index 467df71..5130928 100644 --- a/shared-scheduler/src/main.rs +++ b/shared-scheduler/src/main.rs @@ -12,12 +12,12 @@ extern crate alloc; -mod sbi; #[macro_use] mod console; mod algorithm; mod task; mod mm; +mod syscall; use buddy_system_allocator::LockedHeap; use core::{mem::MaybeUninit, ptr::NonNull}; @@ -35,14 +35,21 @@ static HEAP_MEMORY: MaybeUninit<[u8; HEAP_SIZE]> = core::mem::MaybeUninit::unini #[cfg_attr(not(test), panic_handler)] pub fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! { - println!("[shared scheduler] panic: {:?}", panic_info); - sbi::shutdown() + let err = panic_info.message().unwrap().as_str(); + if let Some(location) = panic_info.location() { + syscall::sys_panic(Some(location.file()), location.line(), location.column(), err); + } else { + syscall::sys_panic(None, 0, 0, err); + } + unreachable!() } +// todo: 未来尽量使用有Allocator的new_in函数,这样能处理内存不足的问题 + #[cfg_attr(not(test), alloc_error_handler)] pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! { - println!("[shared scheduler] alloc panic: {:?}", layout); - sbi::shutdown() + println!("[shared scheduler] alloc error, layout = {:?}", layout); + panic!("shared scheduler alloc error: {:?}", layout) } /// 共享载荷虚函数表 diff --git a/shared-scheduler/src/sbi.rs b/shared-scheduler/src/sbi.rs deleted file mode 100644 index 0a69aa2..0000000 --- a/shared-scheduler/src/sbi.rs +++ /dev/null @@ -1,41 +0,0 @@ -#![allow(unused)] - -#[inline(always)] -fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize { - let ret; - unsafe { - llvm_asm!("ecall" - : "={x10}" (ret) - : "{x10}" (arg0), "{x11}" (arg1), "{x12}" (arg2), "{x17}" (which) - : "memory" - : "volatile"); - } - ret -} - -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; - -pub fn console_putchar(c: usize) { - sbi_call(SBI_CONSOLE_PUTCHAR, c, 0, 0); -} - -pub fn console_getchar() -> usize { - sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0) -} - -pub fn shutdown() -> ! { - sbi_call(SBI_SHUTDOWN, 0, 0, 0); - unreachable!() -} - -pub fn set_timer(time: usize) { - sbi_call(SBI_SET_TIMER, time, 0, 0); -} diff --git a/shared-scheduler/src/syscall.rs b/shared-scheduler/src/syscall.rs new file mode 100644 index 0000000..9ceaca3 --- /dev/null +++ b/shared-scheduler/src/syscall.rs @@ -0,0 +1,67 @@ +const MODULE_TEST_INTERFACE: usize = 0x233666; +const MODULE_PROCESS: usize = 0x114514; + +const FUNC_PROCESS_PANIC: usize = 0x11451419; + +const FUNC_TEST_WRITE: usize = 0x666233; + +pub fn sys_panic(file_name: Option<&str>, line: u32, col: u32, msg: Option<&str>) -> SyscallResult { + let (f_buf, f_len) = file_name.map(|s| (s.as_ptr() as usize, s.len())).unwrap_or((0, 0)); + let (m_buf, m_len) = msg.map(|s| (s.as_ptr() as usize, s.len())).unwrap_or((0, 0)); + syscall_6( + MODULE_PROCESS, FUNC_PROCESS_PANIC, + [line as usize, col as usize, f_buf, f_len, m_buf, m_len] + ) +} + +pub fn sys_test_write(buf: &[u8]) -> SyscallResult { + syscall_3(MODULE_TEST_INTERFACE, FUNC_TEST_WRITE, [0, buf.as_ptr() as usize, buf.len()]) +} + +pub struct SyscallResult { + pub code: usize, + pub extra: usize +} + +fn syscall_3(module: usize, func: usize, args: [usize; 3]) -> SyscallResult { + match () { + #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + () => { + let (code, extra); + unsafe { asm!( + "ecall", + in("a0") args[0], in("a1") args[1], in("a2") args[2], + in("a6") func, in("a7") module, + lateout("a0") code, lateout("a1") extra, + ) }; + SyscallResult { code, extra } + }, + #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))] + () => { + drop((module, func, args)); + unimplemented!("not RISC-V instruction set architecture") + } + } +} + +fn syscall_6(module: usize, func: usize, args: [usize; 6]) -> SyscallResult { + match () { + #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + () => { + let (code, extra); + unsafe { asm!( + "ecall", + in("a0") args[0], in("a1") args[1], in("a2") args[2], + in("a3") args[3], in("a4") args[4], in("a5") args[5], + in("a6") func, in("a7") module, + lateout("a0") code, lateout("a1") extra, + ) }; + SyscallResult { code, extra } + }, + #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))] + () => { + drop((module, func, args)); + unimplemented!("not RISC-V instruction set architecture") + } + } +}