diff --git a/os/src/console.rs b/os/src/console.rs index 31614c64..5c8daaf7 100644 --- a/os/src/console.rs +++ b/os/src/console.rs @@ -1,4 +1,8 @@ -use crate::drivers::chardev::{CharDevice, UART}; +use crate::drivers::chardev::CharDevice; +#[cfg(feature = "board_qemu")] +use crate::drivers::chardev::UART; +#[cfg(feature = "board_k210")] +use crate::sbi::console_putchar; use core::fmt::{self, Write}; struct Stdout; @@ -6,7 +10,10 @@ struct Stdout; impl Write for Stdout { fn write_str(&mut self, s: &str) -> fmt::Result { for c in s.chars() { + #[cfg(feature = "board_qemu")] UART.write(c as u8); + #[cfg(feature = "board_k210")] + console_putchar(c as usize); } Ok(()) } diff --git a/os/src/drivers/chardev/mod.rs b/os/src/drivers/chardev/mod.rs index 28665769..2a04f8ed 100644 --- a/os/src/drivers/chardev/mod.rs +++ b/os/src/drivers/chardev/mod.rs @@ -1,17 +1,17 @@ mod ns16550a; -pub use ns16550a::NS16550a; - +#[cfg(feature = "board_qemu")] use crate::board::CharDeviceImpl; use alloc::sync::Arc; use lazy_static::*; +pub use ns16550a::NS16550a; pub trait CharDevice { fn read(&self) -> u8; fn write(&self, ch: u8); fn handle_irq(&self); } - +#[cfg(feature = "board_qemu")] lazy_static! { pub static ref UART: Arc = Arc::new(CharDeviceImpl::new()); } diff --git a/os/src/drivers/mod.rs b/os/src/drivers/mod.rs index 337c76d9..4ecf8a9d 100644 --- a/os/src/drivers/mod.rs +++ b/os/src/drivers/mod.rs @@ -1,9 +1,14 @@ pub mod block; pub mod chardev; +#[cfg(feature = "board_qemu")] pub mod gpu; +#[cfg(feature = "board_qemu")] pub mod input; pub mod plic; pub use block::BLOCK_DEVICE; +#[cfg(feature = "board_qemu")] pub use chardev::UART; +#[cfg(feature = "board_qemu")] pub use gpu::*; +#[cfg(feature = "board_qemu")] pub use input::*; diff --git a/os/src/fs/stdio.rs b/os/src/fs/stdio.rs index 7326822d..33af6033 100644 --- a/os/src/fs/stdio.rs +++ b/os/src/fs/stdio.rs @@ -1,6 +1,12 @@ use super::File; -use crate::drivers::chardev::{CharDevice, UART}; +use crate::drivers::chardev::CharDevice; +#[cfg(feature = "board_qemu")] +use crate::drivers::chardev::UART; use crate::mm::UserBuffer; +#[cfg(feature = "board_k210")] +use crate::sbi::console_getchar; +#[cfg(feature = "board_k210")] +use crate::task::suspend_current_and_run_next; pub struct Stdin; pub struct Stdout; @@ -12,6 +18,7 @@ impl File for Stdin { fn writable(&self) -> bool { false } + #[cfg(feature = "board_qemu")] fn read(&self, mut user_buf: UserBuffer) -> usize { assert_eq!(user_buf.len(), 1); //println!("before UART.read() in Stdin::read()"); @@ -21,6 +28,27 @@ impl File for Stdin { } 1 } + #[cfg(feature = "board_k210")] + fn read(&self, mut user_buf: UserBuffer) -> usize { + assert_eq!(user_buf.len(), 1); + // busy loop + let mut c: usize; + loop { + c = console_getchar(); + if c == 0 { + suspend_current_and_run_next(); + continue; + } else { + break; + } + } + let ch = c as u8; + unsafe { + user_buf.buffers[0].as_mut_ptr().write_volatile(ch); + } + 1 + } + fn write(&self, _user_buf: UserBuffer) -> usize { panic!("Cannot write to stdin!"); } diff --git a/os/src/main.rs b/os/src/main.rs index 3b84c24d..014b0299 100644 --- a/os/src/main.rs +++ b/os/src/main.rs @@ -2,7 +2,7 @@ #![no_main] #![feature(panic_info_message)] #![feature(alloc_error_handler)] - +#[cfg(feature = "board_qemu")] use crate::drivers::{GPU_DEVICE, KEYBOARD_DEVICE, MOUSE_DEVICE}; extern crate alloc; @@ -22,6 +22,7 @@ mod console; mod config; mod drivers; mod fs; +#[cfg(feature = "board_qemu")] mod gui; mod lang_items; mod mm; @@ -60,10 +61,13 @@ pub fn rust_main() -> ! { clear_bss(); mm::init(); println!("KERN: init gpu"); + #[cfg(feature = "board_qemu")] GPU_DEVICE.clone(); println!("KERN: init keyboard"); + #[cfg(feature = "board_qemu")] KEYBOARD_DEVICE.clone(); println!("KERN: init mouse"); + #[cfg(feature = "board_qemu")] MOUSE_DEVICE.clone(); println!("KERN: init trap"); trap::init(); diff --git a/os/src/sbi.rs b/os/src/sbi.rs index 50fcd975..a218ec8b 100644 --- a/os/src/sbi.rs +++ b/os/src/sbi.rs @@ -40,9 +40,13 @@ pub fn console_getchar() -> usize { sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0) } +#[cfg(feature = "board_qemu")] use crate::board::QEMUExit; pub fn shutdown(exit_code: usize) -> ! { - //sbi_call(SBI_SHUTDOWN, exit_code, 0, 0); + #[cfg(feature = "board_k210")] + sbi_call(SBI_SHUTDOWN, exit_code, 0, 0); + #[cfg(feature = "board_qemu")] crate::board::QEMU_EXIT_HANDLE.exit_failure(); + #[cfg(feature = "board_k210")] panic!("It should shutdown!"); } diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index 5d8660f9..70a1f167 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -27,18 +27,22 @@ const SYSCALL_CONDVAR_SIGNAL: usize = 1031; const SYSCALL_CONDVAR_WAIT: usize = 1032; const SYSCALL_CREATE_DESKTOP: usize = 2000; mod fs; +#[cfg(feature = "board_qemu")] mod gui; mod process; mod sync; mod thread; - +#[cfg(feature = "board_qemu")] pub use self::gui::create_desktop; use fs::*; + +#[cfg(feature = "board_qemu")] pub use gui::PAD; use process::*; use sync::*; use thread::*; +#[cfg(feature = "board_qemu")] pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { match syscall_id { SYSCALL_DUP => sys_dup(args[0]), @@ -72,3 +76,37 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { _ => panic!("Unsupported syscall_id: {}", syscall_id), } } + +#[cfg(feature = "board_k210")] +pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { + match syscall_id { + SYSCALL_DUP => sys_dup(args[0]), + SYSCALL_OPEN => sys_open(args[0] as *const u8, args[1] as u32), + SYSCALL_CLOSE => sys_close(args[0]), + SYSCALL_PIPE => sys_pipe(args[0] as *mut usize), + SYSCALL_READ => sys_read(args[0], args[1] as *const u8, args[2]), + SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]), + SYSCALL_EXIT => sys_exit(args[0] as i32), + SYSCALL_SLEEP => sys_sleep(args[0]), + SYSCALL_YIELD => sys_yield(), + SYSCALL_KILL => sys_kill(args[0], args[1] as u32), + SYSCALL_GET_TIME => sys_get_time(), + SYSCALL_GETPID => sys_getpid(), + SYSCALL_FORK => sys_fork(), + SYSCALL_EXEC => sys_exec(args[0] as *const u8, args[1] as *const usize), + SYSCALL_WAITPID => sys_waitpid(args[0] as isize, args[1] as *mut i32), + SYSCALL_THREAD_CREATE => sys_thread_create(args[0], args[1]), + SYSCALL_GETTID => sys_gettid(), + SYSCALL_WAITTID => sys_waittid(args[0]) as isize, + SYSCALL_MUTEX_CREATE => sys_mutex_create(args[0] == 1), + SYSCALL_MUTEX_LOCK => sys_mutex_lock(args[0]), + SYSCALL_MUTEX_UNLOCK => sys_mutex_unlock(args[0]), + SYSCALL_SEMAPHORE_CREATE => sys_semaphore_create(args[0]), + SYSCALL_SEMAPHORE_UP => sys_semaphore_up(args[0]), + SYSCALL_SEMAPHORE_DOWN => sys_semaphore_down(args[0]), + SYSCALL_CONDVAR_CREATE => sys_condvar_create(args[0]), + SYSCALL_CONDVAR_SIGNAL => sys_condvar_signal(args[0]), + SYSCALL_CONDVAR_WAIT => sys_condvar_wait(args[0], args[1]), + _ => panic!("Unsupported syscall_id: {}", syscall_id), + } +} diff --git a/os/src/task/mod.rs b/os/src/task/mod.rs index 3c762b77..31c792c9 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -56,7 +56,7 @@ pub fn block_current_and_run_next() { let task_cx_ptr = block_current_task(); schedule(task_cx_ptr); } - +#[cfg(feature = "board_qemu")] use crate::board::QEMUExit; pub fn exit_current_and_run_next(exit_code: i32) { @@ -75,6 +75,7 @@ pub fn exit_current_and_run_next(exit_code: i32) { // the process should terminate at once if tid == 0 { let pid = process.getpid(); + #[cfg(feature = "board_qemu")] if pid == IDLE_PID { println!( "[kernel] Idle process exit with exit_code {} ...",