drivers: support graphic console output

This commit is contained in:
Yuekai Jia 2021-10-05 04:50:30 +08:00
parent dd835e5af7
commit d8e6aca2f9
27 changed files with 362 additions and 158 deletions

View File

@ -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 }

View File

@ -1 +1 @@
pub use crate::scheme::display::{ColorDepth, ColorFormat, DisplayInfo};
pub use crate::scheme::display::{ColorFormat, DisplayInfo, RgbColor};

View File

@ -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 {

View File

@ -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)
}

View File

@ -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<Window>,
event_pump: EventPump,
info: DisplayInfo,
display: Arc<dyn DisplayScheme>,
}
impl SdlWindow {
pub fn new(title: &str, info: DisplayInfo) -> Self {
assert_eq!(info.format, ColorFormat::RGBA8888);
pub fn new(title: &str, display: Arc<dyn DisplayScheme>) -> 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<ColorFormat> 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,
}
}
}

View File

@ -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<Self, &'static str> {
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;
}
}
}

View File

@ -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<dyn DisplayScheme>);
pub struct GraphicConsole {
inner: ConsoleOnGraphic<DisplayWrapper>,
}
impl GraphicConsole {
pub fn new(display: Arc<dyn DisplayScheme>) -> Self {
Self {
inner: Console::on_frame_buffer(DisplayWrapper(display)),
}
}
}
impl DrawTarget for DisplayWrapper {
type Color = Rgb888;
type Error = Infallible;
fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
where
I: IntoIterator<Item = Pixel<Self::Color>>,
{
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<DisplayWrapper>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl DerefMut for GraphicConsole {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}

View File

@ -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;

View File

@ -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]

View File

@ -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);
}

View File

@ -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};

View File

@ -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<Mutex<GraphicConsole>> = InitOnce::new();
#[allow(dead_code)]
pub(crate) fn init_graphic_console(display: Arc<dyn DisplayScheme>) {
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
}

View File

@ -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],
}

View File

@ -10,5 +10,5 @@ pub(super) mod vdso;
pub(super) mod vm;
pub mod addr;
pub mod serial;
pub mod console;
pub mod user;

View File

@ -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
}

View File

@ -87,8 +87,8 @@ hal_fn_def! {
pub fn msi_register_handler(block: Range<usize>, 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 {

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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")] {

View File

@ -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));
}
}

View File

@ -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);
}

View File

@ -132,7 +132,7 @@ impl INode for Stdout {
fn write_at(&self, _offset: usize, buf: &[u8]) -> Result<usize> {
// 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<PollStatus> {

View File

@ -22,7 +22,7 @@ impl Syscall<'_> {
&mut self,
mut ufds: UserInOutPtr<PollFd>,
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<PollFd>,
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<TimeSpec>,
) -> 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
}
}

View File

@ -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 => {

View File

@ -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;

View File

@ -6,7 +6,7 @@ impl Syscall<'_> {
pub fn sys_debug_write(&self, buf: UserInPtr<u8>, 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::<Resource>(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(())

View File

@ -54,9 +54,9 @@ impl Syscall<'_> {
let dlog = proc.get_object_with_rights::<DebugLog>(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(())
}