diff --git a/drivers/Cargo.toml b/drivers/Cargo.toml index 515ae210..6d661d37 100644 --- a/drivers/Cargo.toml +++ b/drivers/Cargo.toml @@ -8,7 +8,7 @@ description = "Device drivers of zCore" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -graphic = [] +graphic = ["rcore-console"] mock = ["async-std", "sdl2"] virtio = ["virtio-drivers"] @@ -21,6 +21,7 @@ lazy_static = "1.4" device_tree = { git = "https://github.com/rcore-os/device_tree-rs", rev = "4e8144b" } bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator", rev = "b3f9f51" } virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "2b3c6cf", optional = true } +rcore-console = { git = "https://github.com/rcore-os/rcore-console", default-features = false, rev = "ee95abd", optional = true } [target.'cfg(not(target_os = "none"))'.dependencies] async-std = { version = "1.10", optional = true } diff --git a/drivers/src/display/mod.rs b/drivers/src/display/mod.rs index 304c0a65..3718dfda 100644 --- a/drivers/src/display/mod.rs +++ b/drivers/src/display/mod.rs @@ -1 +1 @@ -pub use crate::scheme::display::{ColorDepth, ColorFormat, DisplayInfo}; +pub use crate::scheme::display::{ColorFormat, DisplayInfo, RgbColor}; diff --git a/drivers/src/lib.rs b/drivers/src/lib.rs index 377aebd5..0a99dbc6 100644 --- a/drivers/src/lib.rs +++ b/drivers/src/lib.rs @@ -9,8 +9,6 @@ extern crate log; use alloc::sync::Arc; use core::fmt; -mod utils; - #[cfg(feature = "mock")] pub mod mock; @@ -23,6 +21,7 @@ pub mod io; pub mod irq; pub mod scheme; pub mod uart; +pub mod utils; #[derive(Debug)] pub enum DeviceError { diff --git a/drivers/src/mock/display/mod.rs b/drivers/src/mock/display/mod.rs index 0889a2c7..745ae56b 100644 --- a/drivers/src/mock/display/mod.rs +++ b/drivers/src/mock/display/mod.rs @@ -2,7 +2,7 @@ pub mod sdl; use alloc::vec::Vec; -use crate::display::{ColorDepth, ColorFormat, DisplayInfo}; +use crate::display::{ColorFormat, DisplayInfo}; use crate::scheme::{DisplayScheme, Scheme}; pub struct MockDisplay { @@ -12,15 +12,13 @@ pub struct MockDisplay { impl MockDisplay { pub fn new(width: u32, height: u32) -> Self { - let depth = ColorDepth::ColorDepth32; - let format = ColorFormat::RGBA8888; - let fb_size = (width * height * depth.bytes() as u32) as usize; + let format = ColorFormat::RGB888; + let fb_size = (width * height * format.bytes() as u32) as usize; let info = DisplayInfo { width, height, - fb_size, - depth, format, + fb_size, }; let fb = vec![0; fb_size]; Self { info, fb } @@ -34,10 +32,12 @@ impl Scheme for MockDisplay { } impl DisplayScheme for MockDisplay { + #[inline] fn info(&self) -> DisplayInfo { self.info } + #[inline] unsafe fn raw_fb(&self) -> &mut [u8] { core::slice::from_raw_parts_mut(self.fb.as_ptr() as _, self.info.fb_size) } diff --git a/drivers/src/mock/display/sdl.rs b/drivers/src/mock/display/sdl.rs index f5e7ad6f..d54feb2f 100644 --- a/drivers/src/mock/display/sdl.rs +++ b/drivers/src/mock/display/sdl.rs @@ -1,47 +1,48 @@ +use alloc::sync::Arc; + use sdl2::{event::Event, keyboard::Keycode, EventPump}; use sdl2::{pixels::PixelFormatEnum, render::Canvas, video::Window}; -use crate::display::{ColorFormat, DisplayInfo}; +use crate::display::ColorFormat; use crate::scheme::DisplayScheme; pub struct SdlWindow { canvas: Canvas, event_pump: EventPump, - info: DisplayInfo, + display: Arc, } impl SdlWindow { - pub fn new(title: &str, info: DisplayInfo) -> Self { - assert_eq!(info.format, ColorFormat::RGBA8888); + pub fn new(title: &str, display: Arc) -> Self { let sdl_context = sdl2::init().unwrap(); let video_subsystem = sdl_context.video().unwrap(); let window = video_subsystem - .window(title, info.width, info.height) + .window(title, display.info().width, display.info().height) .position_centered() .build() .unwrap(); let event_pump = sdl_context.event_pump().unwrap(); - let mut canvas = window.into_canvas().build().unwrap(); - canvas.clear(); - canvas.present(); - Self { - info, + let canvas = window.into_canvas().build().unwrap(); + let mut ret = Self { + display, canvas, event_pump, - } + }; + ret.flush(); + ret } - pub fn flush(&mut self, display: &dyn DisplayScheme) { + pub fn flush(&mut self) { + let info = self.display.info(); let texture_creator = self.canvas.texture_creator(); + let format: PixelFormatEnum = info.format.into(); let mut texture = texture_creator - .create_texture_streaming(PixelFormatEnum::RGBA8888, self.info.width, self.info.height) + .create_texture_streaming(format, info.width, info.height) .unwrap(); - let buf = unsafe { display.raw_fb() }; - texture - .update(None, buf, display.info().width as usize * 4) - .unwrap(); + let buf = unsafe { self.display.raw_fb() }; + texture.update(None, buf, info.pitch() as usize).unwrap(); self.canvas.copy(&texture, None, None).unwrap(); self.canvas.present(); } @@ -60,3 +61,15 @@ impl SdlWindow { false } } + +impl core::convert::From for PixelFormatEnum { + fn from(format: ColorFormat) -> Self { + match format { + ColorFormat::RGB332 => Self::RGB332, + ColorFormat::RGB565 => Self::RGB565, + ColorFormat::RGB888 => Self::BGR24, // notice: BGR24 means R at the highest address, B at the lowest address. + ColorFormat::RGBA8888 => Self::RGBA8888, + ColorFormat::BGRA8888 => Self::BGRA8888, + } + } +} diff --git a/drivers/src/scheme/display.rs b/drivers/src/scheme/display.rs index 775f366d..5b836ca6 100644 --- a/drivers/src/scheme/display.rs +++ b/drivers/src/scheme/display.rs @@ -1,21 +1,65 @@ use super::Scheme; +use crate::{DeviceError, DeviceResult}; -#[repr(u8)] +#[repr(transparent)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum ColorDepth { - ColorDepth8 = 8, - ColorDepth16 = 16, - ColorDepth24 = 24, - ColorDepth32 = 32, +pub struct RgbColor(u32); + +impl RgbColor { + #[inline] + pub const fn new(r: u8, g: u8, b: u8) -> Self { + Self(((r as u32) << 16) | ((g as u32) << 8) | b as u32) + } + + #[inline] + pub const fn r(self) -> u8 { + (self.0 >> 16) as u8 + } + + #[inline] + pub const fn g(self) -> u8 { + (self.0 >> 8) as u8 + } + + #[inline] + pub const fn b(self) -> u8 { + self.0 as u8 + } + + #[inline] + pub const fn raw_value(self) -> u32 { + self.0 + } } +/// Color format for one pixel. `RGB888` means R in bits 16-23, G in bits 8-15 and B in bits 0-7. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ColorFormat { RGB332, RGB565, + RGB888, RGBA8888, // QEMU and low version RPi use RGBA BGRA8888, // RPi3 B+ uses BGRA - VgaPalette, +} + +impl ColorFormat { + /// Number of bits per pixel. + #[inline] + pub const fn depth(self) -> u8 { + match self { + Self::RGB332 => 8, + Self::RGB565 => 16, + Self::RGB888 => 24, + Self::RGBA8888 => 32, + Self::BGRA8888 => 32, + } + } + + /// Number of bytes per pixel. + #[inline] + pub const fn bytes(self) -> u8 { + self.depth() / 8 + } } #[derive(Debug, Clone, Copy)] @@ -24,28 +68,17 @@ pub struct DisplayInfo { pub width: u32, /// visible height pub height: u32, - /// frame buffer size - pub fb_size: usize, - - /// bits per pixel - pub depth: ColorDepth, /// color encoding format of RGBA pub format: ColorFormat, + /// frame buffer size + pub fb_size: usize, } -impl ColorDepth { - pub fn try_from(depth: u8) -> Result { - match depth { - 8 => Ok(Self::ColorDepth8), - 16 => Ok(Self::ColorDepth16), - 24 => Ok(Self::ColorDepth24), - 32 => Ok(Self::ColorDepth32), - _ => Err("unsupported color depth"), - } - } - - pub fn bytes(self) -> u8 { - self as u8 / 8 +impl DisplayInfo { + /// Number of bytes between each row of the frame buffer. + #[inline] + pub const fn pitch(self) -> u32 { + self.width * self.format.bytes() as u32 } } @@ -53,5 +86,51 @@ pub trait DisplayScheme: Scheme { fn info(&self) -> DisplayInfo; #[allow(clippy::mut_from_ref)] + /// Returns the raw framebuffer. + /// + /// # Safety + /// + /// This function is unsafe because it returns the raw pointer of the framebuffer. unsafe fn raw_fb(&self) -> &mut [u8]; + + #[inline] + fn write_pixel(&self, x: u32, y: u32, color: RgbColor) -> DeviceResult { + let info = self.info(); + let fb = unsafe { self.raw_fb() }; + let offset = (x + y * info.width) as usize * info.format.bytes() as usize; + if offset >= info.fb_size { + return Err(DeviceError::InvalidParam); + } + unsafe { write_color(&mut fb[offset as usize] as _, color, info.format) }; + Ok(()) + } +} + +const fn pack_channel(r_val: u8, _r_bits: u8, g_val: u8, g_bits: u8, b_val: u8, b_bits: u8) -> u32 { + ((r_val as u32) << (g_bits + b_bits)) | ((g_val as u32) << b_bits) | b_val as u32 +} + +unsafe fn write_color(ptr: *mut u8, color: RgbColor, format: ColorFormat) { + let (r, g, b) = (color.r(), color.g(), color.b()); + let dst = core::slice::from_raw_parts_mut(ptr, 4); + match format { + ColorFormat::RGB332 => { + *ptr = pack_channel(r >> (8 - 3), 3, g >> (8 - 3), 3, b >> (8 - 2), 2) as u8 + } + ColorFormat::RGB565 => { + *(ptr as *mut u16) = + pack_channel(r >> (8 - 5), 5, g >> (8 - 6), 6, b >> (8 - 5), 5) as u16 + } + ColorFormat::RGB888 => { + dst[2] = r; + dst[1] = g; + dst[0] = b; + } + ColorFormat::RGBA8888 => *(ptr as *mut u32) = color.raw_value() << 8, + ColorFormat::BGRA8888 => { + dst[3] = b; + dst[2] = g; + dst[1] = r; + } + } } diff --git a/drivers/src/utils/graphic_console.rs b/drivers/src/utils/graphic_console.rs new file mode 100644 index 00000000..f88c3879 --- /dev/null +++ b/drivers/src/utils/graphic_console.rs @@ -0,0 +1,60 @@ +use alloc::sync::Arc; +use core::convert::Infallible; +use core::ops::{Deref, DerefMut}; + +use rcore_console::{Console, ConsoleOnGraphic, DrawTarget, OriginDimensions, Pixel, Rgb888, Size}; + +use crate::scheme::DisplayScheme; + +pub struct DisplayWrapper(Arc); + +pub struct GraphicConsole { + inner: ConsoleOnGraphic, +} + +impl GraphicConsole { + pub fn new(display: Arc) -> Self { + Self { + inner: Console::on_frame_buffer(DisplayWrapper(display)), + } + } +} + +impl DrawTarget for DisplayWrapper { + type Color = Rgb888; + type Error = Infallible; + + fn draw_iter(&mut self, pixels: I) -> Result<(), Self::Error> + where + I: IntoIterator>, + { + for p in pixels { + let color = unsafe { core::mem::transmute(p.1) }; + self.0 + .write_pixel(p.0.x as u32, p.0.y as u32, color) + .unwrap(); + } + Ok(()) + } +} + +impl OriginDimensions for DisplayWrapper { + fn size(&self) -> Size { + let info = self.0.info(); + Size::new(info.width, info.height) + } +} + +impl Deref for GraphicConsole { + type Target = ConsoleOnGraphic; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl DerefMut for GraphicConsole { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} diff --git a/drivers/src/utils/mod.rs b/drivers/src/utils/mod.rs index 70f76d7e..26efbd4a 100644 --- a/drivers/src/utils/mod.rs +++ b/drivers/src/utils/mod.rs @@ -2,6 +2,13 @@ mod event_listener; mod id_allocator; mod irq_manager; -pub(super) use event_listener::EventListener; +#[cfg(feature = "graphic")] +mod graphic_console; + pub(super) use id_allocator::IdAllocator; pub(super) use irq_manager::IrqManager; + +pub use event_listener::EventListener; + +#[cfg(feature = "graphic")] +pub use graphic_console::GraphicConsole; diff --git a/kernel-hal/Cargo.toml b/kernel-hal/Cargo.toml index 870cc255..8ef332f3 100644 --- a/kernel-hal/Cargo.toml +++ b/kernel-hal/Cargo.toml @@ -33,7 +33,6 @@ async-std = { version = "1.10", optional = true } executor = { git = "https://github.com/rcore-os/executor.git", rev = "a2d02ee9" } naive-timer = "0.2.0" lazy_static = { version = "1.4", features = ["spin_no_std"] } -bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator", rev = "b3f9f51" } # Bare-metal mode on x86_64 [target.'cfg(all(target_os = "none", target_arch = "x86_64"))'.dependencies] diff --git a/kernel-hal/src/bare/arch/riscv/sbi.rs b/kernel-hal/src/bare/arch/riscv/sbi.rs index 06ce66e2..bd636662 100644 --- a/kernel-hal/src/bare/arch/riscv/sbi.rs +++ b/kernel-hal/src/bare/arch/riscv/sbi.rs @@ -48,8 +48,8 @@ pub fn send_ipi(sipi_value: usize) { } hal_fn_impl! { - impl mod crate::hal_fn::serial { - fn serial_write_early(s: &str) { + impl mod crate::hal_fn::console { + fn console_write_early(s: &str) { for c in s.bytes() { console_putchar(c as usize); } diff --git a/kernel-hal/src/bare/arch/x86_64/mod.rs b/kernel-hal/src/bare/arch/x86_64/mod.rs index 501afac8..3d95c220 100644 --- a/kernel-hal/src/bare/arch/x86_64/mod.rs +++ b/kernel-hal/src/bare/arch/x86_64/mod.rs @@ -10,7 +10,7 @@ pub mod special; pub mod timer; pub mod vm; -hal_fn_impl_default!(crate::hal_fn::serial); +hal_fn_impl_default!(crate::hal_fn::console); use x86_64::registers::control::{Cr4, Cr4Flags}; diff --git a/kernel-hal/src/common/console.rs b/kernel-hal/src/common/console.rs new file mode 100644 index 00000000..4f3736bc --- /dev/null +++ b/kernel-hal/src/common/console.rs @@ -0,0 +1,77 @@ +use core::fmt::{Arguments, Result, Write}; + +use crate::drivers; + +struct SerialWriter; + +impl Write for SerialWriter { + fn write_str(&mut self, s: &str) -> Result { + if let Some(uart) = drivers::uart::first() { + uart.write_str(s).unwrap(); + } else { + crate::hal_fn::console::console_write_early(s); + } + Ok(()) + } +} + +cfg_if! { + if #[cfg(feature = "graphic")] { + use crate::utils::init_once::InitOnce; + use alloc::sync::Arc; + use spin::Mutex; + use zcore_drivers::{scheme::DisplayScheme, utils::GraphicConsole}; + + static GRAPHIC_CONSOLE: InitOnce> = InitOnce::new(); + + #[allow(dead_code)] + pub(crate) fn init_graphic_console(display: Arc) { + GRAPHIC_CONSOLE.init_once_by(Mutex::new(GraphicConsole::new(display))); + } + } +} + +/// Print format string and its arguments to serial. +pub fn serial_write_fmt(fmt: Arguments) { + SerialWriter.write_fmt(fmt).unwrap(); +} + +/// Print format string and its arguments to serial. +pub fn serial_write(s: &str) { + SerialWriter.write_str(s).unwrap(); +} + +/// Print format string and its arguments to graphic console. +#[allow(unused_variables)] +pub fn graphic_console_write_fmt(fmt: Arguments) { + #[cfg(feature = "graphic")] + if let Some(cons) = GRAPHIC_CONSOLE.try_get() { + cons.lock().write_fmt(fmt).unwrap(); + } +} + +/// Print format string and its arguments to graphic console. +#[allow(unused_variables)] +pub fn graphic_console_write(s: &str) { + #[cfg(feature = "graphic")] + if let Some(cons) = GRAPHIC_CONSOLE.try_get() { + cons.lock().write_str(s).unwrap(); + } +} + +/// Print format string and its arguments to serial and graphic console (if exists). +pub fn console_write_fmt(fmt: Arguments) { + serial_write_fmt(fmt); + graphic_console_write_fmt(fmt); +} + +/// Print a string to serial and graphic console (if exists). +pub fn console_write(s: &str) { + serial_write(s); + graphic_console_write(s); +} + +/// Read buffer data from console (serial). +pub async fn console_read(buf: &mut [u8]) -> usize { + super::future::SerialReadFuture::new(buf).await +} diff --git a/kernel-hal/src/common/future.rs b/kernel-hal/src/common/future.rs index 24364bfe..09413045 100644 --- a/kernel-hal/src/common/future.rs +++ b/kernel-hal/src/common/future.rs @@ -49,7 +49,7 @@ impl Future for SleepFuture { } } -#[must_use = "`serial_read()` does nothing unless polled/`await`-ed"] +#[must_use = "`console_read()` does nothing unless polled/`await`-ed"] pub(super) struct SerialReadFuture<'a> { buf: &'a mut [u8], } diff --git a/kernel-hal/src/common/mod.rs b/kernel-hal/src/common/mod.rs index 6c85aa96..e76c9ac6 100644 --- a/kernel-hal/src/common/mod.rs +++ b/kernel-hal/src/common/mod.rs @@ -10,5 +10,5 @@ pub(super) mod vdso; pub(super) mod vm; pub mod addr; -pub mod serial; +pub mod console; pub mod user; diff --git a/kernel-hal/src/common/serial.rs b/kernel-hal/src/common/serial.rs deleted file mode 100644 index 07703195..00000000 --- a/kernel-hal/src/common/serial.rs +++ /dev/null @@ -1,31 +0,0 @@ -use core::fmt::{Arguments, Result, Write}; - -use crate::drivers; - -struct SerialWriter; - -impl Write for SerialWriter { - fn write_str(&mut self, s: &str) -> Result { - if let Some(uart) = drivers::uart::first() { - uart.write_str(s).unwrap(); - } else { - crate::hal_fn::serial::serial_write_early(s); - } - Ok(()) - } -} - -/// Print format string and its arguments to serial. -pub fn serial_write_fmt(fmt: Arguments) { - SerialWriter.write_fmt(fmt).unwrap(); -} - -/// Print a string to serial. -pub fn serial_write(s: &str) { - serial_write_fmt(format_args!("{}", s)); -} - -/// Read buffer data from serial. -pub async fn serial_read(buf: &mut [u8]) -> usize { - super::future::SerialReadFuture::new(buf).await -} diff --git a/kernel-hal/src/hal_fn.rs b/kernel-hal/src/hal_fn.rs index e1a3bd03..993c8140 100644 --- a/kernel-hal/src/hal_fn.rs +++ b/kernel-hal/src/hal_fn.rs @@ -87,8 +87,8 @@ hal_fn_def! { pub fn msi_register_handler(block: Range, msi_id: usize, handler: IrqHandler) -> HalResult; } - pub(crate) mod serial { - pub(crate) fn serial_write_early(_s: &str) {} + pub(crate) mod console { + pub(crate) fn console_write_early(_s: &str) {} } pub mod context: common::context { diff --git a/kernel-hal/src/lib.rs b/kernel-hal/src/lib.rs index 9338dc3f..97634117 100644 --- a/kernel-hal/src/lib.rs +++ b/kernel-hal/src/lib.rs @@ -36,7 +36,7 @@ cfg_if! { pub(crate) use config::KCONFIG; pub(crate) use kernel_handler::KHANDLER; -pub use common::{addr, defs::*, serial, user}; +pub use common::{addr, console, defs::*, user}; pub use config::KernelConfig; pub use imp::*; pub use kernel_handler::KernelHandler; diff --git a/kernel-hal/src/libos/drivers.rs b/kernel-hal/src/libos/drivers.rs index 7fe48a85..8027fc45 100644 --- a/kernel-hal/src/libos/drivers.rs +++ b/kernel-hal/src/libos/drivers.rs @@ -3,17 +3,16 @@ use alloc::sync::Arc; use zcore_drivers::mock::uart::MockUart; use zcore_drivers::{scheme::Scheme, Device}; -use crate::drivers; - pub(super) fn init() { let uart = Arc::new(MockUart::new()); - drivers::add_device(Device::Uart(uart.clone())); + crate::drivers::add_device(Device::Uart(uart.clone())); MockUart::start_irq_serve(move || uart.handle_irq(0)); #[cfg(feature = "graphic")] { use zcore_drivers::mock::display::MockDisplay; - let display = Arc::new(MockDisplay::new(800, 600)); - drivers::add_device(Device::Display(display)); + let display = Arc::new(MockDisplay::new(1280, 720)); + crate::drivers::add_device(Device::Display(display.clone())); + crate::console::init_graphic_console(display); } } diff --git a/kernel-hal/src/libos/mod.rs b/kernel-hal/src/libos/mod.rs index 4b25a62f..67ad4cfe 100644 --- a/kernel-hal/src/libos/mod.rs +++ b/kernel-hal/src/libos/mod.rs @@ -14,7 +14,7 @@ pub mod libos; pub use super::hal_fn::{context, cpu, interrupt, rand}; -hal_fn_impl_default!(context, cpu, interrupt, rand, super::hal_fn::serial); +hal_fn_impl_default!(context, cpu, interrupt, rand, super::hal_fn::console); cfg_if! { if #[cfg(target_os = "linux")] { diff --git a/kernel-hal/src/libos/special.rs b/kernel-hal/src/libos/special.rs index 55ffffe3..c7aeffab 100644 --- a/kernel-hal/src/libos/special.rs +++ b/kernel-hal/src/libos/special.rs @@ -3,9 +3,9 @@ pub fn run_display_serve() { use zcore_drivers::mock::display::sdl::SdlWindow; let display = crate::drivers::display::first_unwrap(); - let mut window = SdlWindow::new("zcore-libos", display.info()); + let mut window = SdlWindow::new("zcore-libos", display.clone()); while !window.is_quit() { - window.flush(display.as_ref()); + window.flush(); std::thread::sleep(std::time::Duration::from_millis(10)); } } diff --git a/linux-loader/src/main.rs b/linux-loader/src/main.rs index ce905723..7cf01b62 100644 --- a/linux-loader/src/main.rs +++ b/linux-loader/src/main.rs @@ -28,24 +28,26 @@ async fn main() { ); } - // run first process let args: Vec<_> = std::env::args().skip(1).collect(); let proc_name = args.join(" "); let envs = vec!["PATH=/usr/sbin:/usr/bin:/sbin:/bin:/usr/x86_64-alpine-linux-musl/bin".into()]; - let hostfs = HostFS::new("rootfs"); - let proc = run(args, envs, hostfs); - - let wait_for_exit = async move { proc.wait_for_exit().await }; + // Run the first process. + let run_proc = async move { + let hostfs = HostFS::new("rootfs"); + let proc = run(args, envs, hostfs); + proc.wait_for_exit().await + }; + // If the graphic mode is on, run the process in another thread. #[cfg(feature = "graphic")] - let wait_for_exit = { - let handle = async_std::task::spawn(wait_for_exit); + let run_proc = { + let handle = async_std::task::spawn(run_proc); kernel_hal::libos::run_display_serve(); handle }; - let code = wait_for_exit.await; + let code = run_proc.await; log::info!("process {:?} exited with {}", proc_name, code); std::process::exit(code as i32); } diff --git a/linux-object/src/fs/stdio.rs b/linux-object/src/fs/stdio.rs index 8a3af366..7d27bb6f 100644 --- a/linux-object/src/fs/stdio.rs +++ b/linux-object/src/fs/stdio.rs @@ -132,7 +132,7 @@ impl INode for Stdout { fn write_at(&self, _offset: usize, buf: &[u8]) -> Result { // we do not care the utf-8 things, we just want to print it! let s = unsafe { core::str::from_utf8_unchecked(buf) }; - kernel_hal::serial::serial_write(s); + kernel_hal::console::console_write(s); Ok(buf.len()) } fn poll(&self) -> Result { diff --git a/linux-syscall/src/file/poll.rs b/linux-syscall/src/file/poll.rs index 66be5f31..6748a0bb 100644 --- a/linux-syscall/src/file/poll.rs +++ b/linux-syscall/src/file/poll.rs @@ -22,7 +22,7 @@ impl Syscall<'_> { &mut self, mut ufds: UserInOutPtr, nfds: usize, - timeout_msecs: usize, + timeout_msecs: isize, ) -> SysResult { let mut polls = ufds.read_array(nfds)?; info!( @@ -32,7 +32,7 @@ impl Syscall<'_> { #[must_use = "future does nothing unless polled/`await`-ed"] struct PollFuture<'a> { polls: &'a mut Vec, - timeout_msecs: usize, + timeout_msecs: isize, begin_time_ms: usize, syscall: &'a Syscall<'a>, } @@ -79,23 +79,23 @@ impl Syscall<'_> { return Poll::Ready(Ok(events)); } - if self.timeout_msecs == 0 { + match self.timeout_msecs { // no timeout, return now; - return Poll::Ready(Ok(0)); - } else { - let waker = cx.waker().clone(); - timer::timer_set( - timer::deadline_after(Duration::from_millis(self.timeout_msecs as u64)), - Box::new(move |_| waker.wake()), - ); - } - - let current_time_ms = TimeVal::now().to_msec(); - // infinity check - if self.timeout_msecs < (1 << 31) - && current_time_ms - self.begin_time_ms >= self.timeout_msecs as usize - { - return Poll::Ready(Ok(0)); + 0 => return Poll::Ready(Ok(0)), + 1.. => { + let current_time_ms = TimeVal::now().to_msec(); + let deadline = self.begin_time_ms + self.timeout_msecs as usize; + if current_time_ms >= deadline { + return Poll::Ready(Ok(0)); + } else { + let waker = cx.waker().clone(); + timer::timer_set( + Duration::from_millis(deadline as u64), + Box::new(move |_| waker.wake()), + ); + } + } + _ => {} } Poll::Pending @@ -122,13 +122,13 @@ impl Syscall<'_> { timeout: UserInPtr, ) -> SysResult { let timeout_msecs = if timeout.is_null() { - 1 << 31 // infinity + -1 } else { let timeout = timeout.read().unwrap(); - timeout.to_msec() + timeout.to_msec() as isize }; - self.sys_poll(ufds, nfds, timeout_msecs as usize).await + self.sys_poll(ufds, nfds, timeout_msecs).await } /// similar to select, but have sigmask argument @@ -169,10 +169,10 @@ impl Syscall<'_> { let timeout_msecs = if !timeout.is_null() { let timeout = timeout.read()?; - timeout.to_msec() + timeout.to_msec() as isize } else { // infinity - 1 << 31 + -1 }; let begin_time_ms = TimeVal::now().to_msec(); @@ -181,7 +181,7 @@ impl Syscall<'_> { read_fds: &'a mut FdSet, write_fds: &'a mut FdSet, err_fds: &'a mut FdSet, - timeout_msecs: usize, + timeout_msecs: isize, begin_time_ms: usize, syscall: &'a Syscall<'a>, } @@ -225,25 +225,24 @@ impl Syscall<'_> { return Poll::Ready(Ok(events)); } - if self.timeout_msecs == 0 { + match self.timeout_msecs { // no timeout, return now; - return Poll::Ready(Ok(0)); - } else { - let waker = cx.waker().clone(); - timer::timer_set( - timer::deadline_after(Duration::from_millis(self.timeout_msecs as u64)), - Box::new(move |_| waker.wake()), - ); + 0 => return Poll::Ready(Ok(0)), + 1.. => { + let current_time_ms = TimeVal::now().to_msec(); + let deadline = self.begin_time_ms + self.timeout_msecs as usize; + if current_time_ms >= deadline { + return Poll::Ready(Ok(0)); + } else { + let waker = cx.waker().clone(); + timer::timer_set( + Duration::from_millis(deadline as u64), + Box::new(move |_| waker.wake()), + ); + } + } + _ => {} } - - let current_time_ms = TimeVal::now().to_msec(); - // infinity check - if self.timeout_msecs < (1 << 31) - && current_time_ms - self.begin_time_ms >= self.timeout_msecs as usize - { - return Poll::Ready(Ok(0)); - } - Poll::Pending } } diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index 8671fcab..474b17ff 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -269,7 +269,7 @@ impl Syscall<'_> { Sys::OPEN => self.sys_open(a0.into(), a1, a2), Sys::STAT => self.sys_stat(a0.into(), a1.into()), Sys::LSTAT => self.sys_lstat(a0.into(), a1.into()), - Sys::POLL => self.sys_poll(a0.into(), a1, a2).await, + Sys::POLL => self.sys_poll(a0.into(), a1, a2 as _).await, Sys::ACCESS => self.sys_access(a0.into(), a1), Sys::PIPE => self.sys_pipe(a0.into()), Sys::SELECT => { diff --git a/zCore/src/logging.rs b/zCore/src/logging.rs index 6a038a0c..5670d618 100644 --- a/zCore/src/logging.rs +++ b/zCore/src/logging.rs @@ -37,12 +37,12 @@ macro_rules! with_color { } fn print_in_color(args: fmt::Arguments, color_code: u8) { - kernel_hal::serial::serial_write_fmt(with_color!(args, color_code)); + kernel_hal::console::console_write_fmt(with_color!(args, color_code)); } #[allow(dead_code)] pub fn print(args: fmt::Arguments) { - kernel_hal::serial::serial_write_fmt(args); + kernel_hal::console::console_write_fmt(args); } struct SimpleLogger; diff --git a/zircon-syscall/src/debug.rs b/zircon-syscall/src/debug.rs index 83d588ef..1f5b866d 100644 --- a/zircon-syscall/src/debug.rs +++ b/zircon-syscall/src/debug.rs @@ -6,7 +6,7 @@ impl Syscall<'_> { pub fn sys_debug_write(&self, buf: UserInPtr, len: usize) -> ZxResult { info!("debug.write: buf=({:?}; {:#x})", buf, len); let data = buf.read_array(len)?; - kernel_hal::serial::serial_write(core::str::from_utf8(&data).unwrap()); + kernel_hal::console::console_write(core::str::from_utf8(&data).unwrap()); Ok(()) } @@ -26,7 +26,7 @@ impl Syscall<'_> { proc.get_object::(handle)? .validate(ResourceKind::ROOT)?; let mut vec = vec![0u8; buf_size as usize]; - let len = kernel_hal::serial::serial_read(&mut vec).await; + let len = kernel_hal::console::console_read(&mut vec).await; buf.write_array(&vec[..len])?; actual.write(len as u32)?; Ok(()) diff --git a/zircon-syscall/src/debuglog.rs b/zircon-syscall/src/debuglog.rs index 2baa1833..5583a889 100644 --- a/zircon-syscall/src/debuglog.rs +++ b/zircon-syscall/src/debuglog.rs @@ -54,9 +54,9 @@ impl Syscall<'_> { let dlog = proc.get_object_with_rights::(handle_value, Rights::WRITE)?; dlog.write(Severity::Info, options, self.thread.id(), proc.id(), &data); // print to kernel console - kernel_hal::serial::serial_write(&data); + kernel_hal::console::console_write(&data); if data.as_bytes().last() != Some(&b'\n') { - kernel_hal::serial::serial_write("\n"); + kernel_hal::console::console_write("\n"); } Ok(()) }