drivers: add mock drivers for libos

And use a unified serial driver in kernel-hal
This commit is contained in:
Yuekai Jia 2021-09-16 23:11:19 +08:00
parent 8b6be6a876
commit 994f8b80f2
43 changed files with 395 additions and 243 deletions

View File

@ -8,9 +8,12 @@ description = "Device drivers of zCore"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
mock = []
virtio = ["virtio-drivers"]
[dependencies]
log = "0.4"
spin = "0.9"
cfg-if = "1.0"
bitflags = "1.3"
virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "2b3c6cf", optional = true }

View File

@ -1,4 +0,0 @@
#[cfg(feature = "virtio")]
mod virtio_blk;
#[cfg(feature = "virtio")]
pub use virtio_blk::VirtIoBlk;

View File

@ -9,6 +9,9 @@ pub struct Mmio<T> {
}
impl<T> Mmio<T> {
/// # Safety
///
/// This function is unsafe because `base_addr` may be an arbitrary address.
pub unsafe fn from_base<'a, R>(base_addr: usize) -> &'a mut R {
&mut *(base_addr as *mut R)
}

View File

@ -25,7 +25,7 @@ pub struct ReadOnly<I> {
impl<I> ReadOnly<I> {
pub const fn new(inner: I) -> ReadOnly<I> {
ReadOnly { inner: inner }
ReadOnly { inner }
}
}
@ -43,7 +43,7 @@ pub struct WriteOnly<I> {
impl<I> WriteOnly<I> {
pub const fn new(inner: I) -> WriteOnly<I> {
WriteOnly { inner: inner }
WriteOnly { inner }
}
}

View File

@ -13,7 +13,7 @@ impl<T> Pio<T> {
/// Create a PIO from a given port
pub const fn new(port: u16) -> Self {
Pio::<T> {
port: port,
port,
_phantom: PhantomData,
}
}

View File

@ -1,12 +1,14 @@
#![no_std]
#![cfg_attr(not(feature = "mock"), no_std)]
#![feature(asm)]
extern crate alloc;
#[cfg(feature = "virtio")]
mod virtio;
#[cfg(feature = "mock")]
pub mod mock;
#[cfg(feature = "virtio")]
pub mod virtio;
pub mod block;
pub mod io;
pub mod scheme;
pub mod uart;

3
drivers/src/mock/mod.rs Normal file
View File

@ -0,0 +1,3 @@
mod uart;
pub use uart::MockUart;

75
drivers/src/mock/uart.rs Normal file
View File

@ -0,0 +1,75 @@
use std::io::{self, Read};
use std::sync::mpsc::{self, Receiver};
use std::sync::Mutex;
use crate::scheme::{Scheme, UartScheme};
use crate::DeviceResult;
pub struct MockUart {
stdin_channel: Mutex<Receiver<u8>>,
}
impl MockUart {
pub fn new() -> Self {
let (tx, rx) = mpsc::channel();
std::thread::spawn(move || loop {
let mut buf = [0];
io::stdin().read_exact(&mut buf).unwrap();
if tx.send(buf[0]).is_err() {
break;
}
core::hint::spin_loop();
});
Self {
stdin_channel: Mutex::new(rx),
}
}
}
impl Default for MockUart {
fn default() -> Self {
Self::new()
}
}
impl Scheme for MockUart {}
impl UartScheme for MockUart {
fn try_recv(&self) -> DeviceResult<Option<u8>> {
match self.stdin_channel.lock().unwrap().try_recv() {
Ok(ch) => Ok(Some(ch)),
_ => Ok(None),
}
}
fn send(&self, ch: u8) -> DeviceResult {
eprint!("{}", ch as char);
Ok(())
}
fn write_str(&self, s: &str) -> DeviceResult {
eprint!("{}", s);
Ok(())
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_mock_uart() {
let uart = MockUart::new();
uart.write_str("Hello, World!\n").unwrap();
uart.write_str(format!("{} + {} = {}\n", 1, 2, 1 + 2).as_str())
.unwrap();
std::thread::sleep(std::time::Duration::from_millis(100));
if let Some(ch) = uart.try_recv().unwrap() {
uart.write_str(format!("received data: {:?}({:#x})\n", ch as char, ch).as_str())
.unwrap();
} else {
uart.write_str("no data to receive\n").unwrap();
}
}
}

View File

@ -2,7 +2,7 @@ use super::Scheme;
use crate::DeviceResult;
pub trait BlockScheme: Scheme {
fn read_block(&mut self, block_id: usize, buf: &mut [u8]) -> DeviceResult;
fn write_block(&mut self, block_id: usize, buf: &[u8]) -> DeviceResult;
fn flush(&mut self) -> DeviceResult;
fn read_block(&self, block_id: usize, buf: &mut [u8]) -> DeviceResult;
fn write_block(&self, block_id: usize, buf: &[u8]) -> DeviceResult;
fn flush(&self) -> DeviceResult;
}

View File

@ -10,8 +10,6 @@ pub use input::InputScheme;
pub use net::NetScheme;
pub use uart::UartScheme;
pub trait Scheme {
fn init(&mut self) -> crate::DeviceResult {
Ok(())
}
pub trait Scheme: Send + Sync {
fn handle_irq(&self, _irq_num: u32) {}
}

View File

@ -2,6 +2,6 @@ use super::Scheme;
use crate::DeviceResult;
pub trait NetScheme: Scheme {
fn recv(&mut self, buf: &mut [u8]) -> DeviceResult<usize>;
fn send(&mut self, buf: &[u8]) -> DeviceResult<usize>;
fn recv(&self, buf: &mut [u8]) -> DeviceResult<usize>;
fn send(&self, buf: &[u8]) -> DeviceResult<usize>;
}

View File

@ -2,6 +2,12 @@ use super::Scheme;
use crate::DeviceResult;
pub trait UartScheme: Scheme {
fn try_recv(&mut self) -> DeviceResult<Option<u8>>;
fn send(&mut self, ch: u8) -> DeviceResult;
fn try_recv(&self) -> DeviceResult<Option<u8>>;
fn send(&self, ch: u8) -> DeviceResult;
fn write_str(&self, s: &str) -> DeviceResult {
for c in s.bytes() {
self.send(c)?;
}
Ok(())
}
}

View File

@ -1,7 +1,5 @@
mod uart_16550;
pub use uart_16550::Uart16550;
pub use uart_16550::Uart16550Mmio;
#[cfg(feature = "virtio")]
mod virtio_console;
#[cfg(feature = "virtio")]
pub use virtio_console::VirtIoConsole;
#[cfg(target_arch = "x86_64")]
pub use uart_16550::Uart16550Pio;

View File

@ -1,6 +1,8 @@
use core::{convert::TryInto, fmt};
use core::convert::TryInto;
use core::ops::{BitAnd, BitOr, Not};
use bitflags::bitflags;
use spin::Mutex;
use crate::io::{Io, Mmio, ReadOnly};
use crate::scheme::{Scheme, UartScheme};
@ -28,7 +30,7 @@ bitflags! {
}
#[repr(C)]
pub struct Uart16550<T: Io> {
struct Uart16550Inner<T: Io> {
/// Data register, read to receive, write to send
data: T,
/// Interrupt enable
@ -45,50 +47,11 @@ pub struct Uart16550<T: Io> {
modem_sts: ReadOnly<T>,
}
#[cfg(target_arch = "x86_64")]
impl Uart16550<crate::io::Pio<u8>> {
pub const fn new(base: u16) -> Self {
use crate::io::Pio;
Self {
data: Pio::new(base),
int_en: Pio::new(base + 1),
fifo_ctrl: Pio::new(base + 2),
line_ctrl: Pio::new(base + 3),
modem_ctrl: Pio::new(base + 4),
line_sts: ReadOnly::new(Pio::new(base + 5)),
modem_sts: ReadOnly::new(Pio::new(base + 6)),
}
}
}
impl Uart16550<Mmio<u8>> {
pub unsafe fn new(base: usize) -> &'static mut Self {
Mmio::<u8>::from_base(base)
}
}
impl Uart16550<Mmio<u32>> {
pub unsafe fn new(base: usize) -> &'static mut Self {
Mmio::<u32>::from_base(base)
}
}
impl<T: Io> Uart16550<T>
impl<T: Io> Uart16550Inner<T>
where
T::Value: From<u8> + TryInto<u8>,
{
fn line_sts(&self) -> LineStsFlags {
LineStsFlags::from_bits_truncate(
(self.line_sts.read() & 0xFF.into()).try_into().unwrap_or(0),
)
}
}
impl<T: Io> Scheme for Uart16550<T>
where
T::Value: From<u8> + TryInto<u8>,
{
fn init(&mut self) -> DeviceResult {
fn init(&mut self) {
// Disable interrupts
self.int_en.write(0x00.into());
@ -112,15 +75,14 @@ where
// Enable interrupts
self.int_en.write(0x01.into());
Ok(())
}
}
impl<T: Io> UartScheme for Uart16550<T>
where
T::Value: From<u8> + TryInto<u8>,
{
fn line_sts(&self) -> LineStsFlags {
LineStsFlags::from_bits_truncate(
(self.line_sts.read() & 0xFF.into()).try_into().unwrap_or(0),
)
}
fn try_recv(&mut self) -> DeviceResult<Option<u8>> {
if self.line_sts().contains(LineStsFlags::INPUT_FULL) {
Ok(Some(
@ -136,29 +98,132 @@ where
self.data.write(ch.into());
Ok(())
}
}
impl<T: Io> fmt::Write for Uart16550<T>
where
T::Value: From<u8> + TryInto<u8>,
{
fn write_str(&mut self, s: &str) -> fmt::Result {
fn write_str(&mut self, s: &str) -> DeviceResult {
for b in s.bytes() {
match b {
8 | 0x7F => {
self.send(8).unwrap();
self.send(b' ').unwrap();
self.send(8).unwrap();
self.send(8)?;
self.send(b' ')?;
self.send(8)?;
}
b'\n' => {
self.send(b'\r').unwrap();
self.send(b'\n').unwrap();
self.send(b'\r')?;
self.send(b'\n')?;
}
_ => {
self.send(b).unwrap();
self.send(b)?;
}
}
}
Ok(())
}
}
pub struct Uart16550Mmio<V: 'static>
where
V: Copy + BitAnd<Output = V> + BitOr<Output = V> + Not<Output = V>,
{
inner: Mutex<&'static mut Uart16550Inner<Mmio<V>>>,
}
impl<V> Scheme for Uart16550Mmio<V> where
V: Copy + BitAnd<Output = V> + BitOr<Output = V> + Not<Output = V> + Send
{
}
impl<V> UartScheme for Uart16550Mmio<V>
where
V: Copy
+ BitAnd<Output = V>
+ BitOr<Output = V>
+ Not<Output = V>
+ From<u8>
+ TryInto<u8>
+ Send,
{
fn try_recv(&self) -> DeviceResult<Option<u8>> {
self.inner.lock().try_recv()
}
fn send(&self, ch: u8) -> DeviceResult {
self.inner.lock().send(ch)
}
fn write_str(&self, s: &str) -> DeviceResult {
self.inner.lock().write_str(s)
}
}
impl Uart16550Mmio<u8> {
/// # Safety
///
/// This function is unsafe because `base_addr` may be an arbitrary address.
pub unsafe fn new(base: usize) -> Self {
let uart: &mut Uart16550Inner<Mmio<u8>> = Mmio::<u8>::from_base(base);
uart.init();
Self {
inner: Mutex::new(uart),
}
}
}
impl Uart16550Mmio<u32> {
/// # Safety
///
/// This function is unsafe because `base_addr` may be an arbitrary address.
pub unsafe fn new(base: usize) -> Self {
let uart: &mut Uart16550Inner<Mmio<u32>> = Mmio::<u32>::from_base(base);
uart.init();
Self {
inner: Mutex::new(uart),
}
}
}
#[cfg(target_arch = "x86_64")]
mod pio {
use super::*;
use crate::io::Pio;
pub struct Uart16550Pio {
inner: Mutex<Uart16550Inner<Pio<u8>>>,
}
impl Scheme for Uart16550Pio {}
impl UartScheme for Uart16550Pio {
fn try_recv(&self) -> DeviceResult<Option<u8>> {
self.inner.lock().try_recv()
}
fn send(&self, ch: u8) -> DeviceResult {
self.inner.lock().send(ch)
}
fn write_str(&self, s: &str) -> DeviceResult {
self.inner.lock().write_str(s)
}
}
impl Uart16550Pio {
pub fn new(base: u16) -> Self {
let mut uart = Uart16550Inner::<Pio<u8>> {
data: Pio::new(base),
int_en: Pio::new(base + 1),
fifo_ctrl: Pio::new(base + 2),
line_ctrl: Pio::new(base + 3),
modem_ctrl: Pio::new(base + 4),
line_sts: ReadOnly::new(Pio::new(base + 5)),
modem_sts: ReadOnly::new(Pio::new(base + 6)),
};
uart.init();
Self {
inner: Mutex::new(uart),
}
}
}
}
#[cfg(target_arch = "x86_64")]
pub use pio::Uart16550Pio;

View File

@ -1,29 +0,0 @@
use crate::scheme::{Scheme, UartScheme};
use crate::DeviceResult;
use virtio_drivers::{VirtIOConsole as InnerDriver, VirtIOHeader};
pub struct VirtIoConsole<'a> {
inner: InnerDriver<'a>,
}
impl<'a> VirtIoConsole<'a> {
pub fn new(header: &'static mut VirtIOHeader) -> DeviceResult<Self> {
Ok(Self {
inner: InnerDriver::new(header)?,
})
}
}
impl<'a> Scheme for VirtIoConsole<'a> {}
impl<'a> UartScheme for VirtIoConsole<'a> {
fn try_recv(&mut self) -> DeviceResult<Option<u8>> {
Ok(self.inner.recv(true)?)
}
fn send(&mut self, ch: u8) -> DeviceResult {
self.inner.send(ch)?;
Ok(())
}
}

View File

@ -1,16 +1,17 @@
use spin::Mutex;
use virtio_drivers::{VirtIOBlk as InnerDriver, VirtIOHeader};
use crate::scheme::{BlockScheme, Scheme};
use crate::DeviceResult;
use virtio_drivers::{VirtIOBlk as InnerDriver, VirtIOHeader};
pub struct VirtIoBlk<'a> {
inner: InnerDriver<'a>,
inner: Mutex<InnerDriver<'a>>,
}
impl<'a> VirtIoBlk<'a> {
pub fn new(header: &'static mut VirtIOHeader) -> DeviceResult<Self> {
Ok(Self {
inner: InnerDriver::new(header)?,
inner: Mutex::new(InnerDriver::new(header)?),
})
}
}
@ -18,17 +19,17 @@ impl<'a> VirtIoBlk<'a> {
impl<'a> Scheme for VirtIoBlk<'a> {}
impl<'a> BlockScheme for VirtIoBlk<'a> {
fn read_block(&mut self, block_id: usize, buf: &mut [u8]) -> DeviceResult {
self.inner.read_block(block_id, buf)?;
fn read_block(&self, block_id: usize, buf: &mut [u8]) -> DeviceResult {
self.inner.lock().read_block(block_id, buf)?;
Ok(())
}
fn write_block(&mut self, block_id: usize, buf: &[u8]) -> DeviceResult {
self.inner.write_block(block_id, buf)?;
fn write_block(&self, block_id: usize, buf: &[u8]) -> DeviceResult {
self.inner.lock().write_block(block_id, buf)?;
Ok(())
}
fn flush(&mut self) -> DeviceResult {
fn flush(&self) -> DeviceResult {
Ok(())
}
}

View File

@ -0,0 +1,41 @@
use core::fmt::{Result, Write};
use spin::Mutex;
use virtio_drivers::{VirtIOConsole as InnerDriver, VirtIOHeader};
use crate::scheme::{Scheme, UartScheme};
use crate::DeviceResult;
pub struct VirtIoConsole<'a> {
inner: Mutex<InnerDriver<'a>>,
}
impl<'a> VirtIoConsole<'a> {
pub fn new(header: &'static mut VirtIOHeader) -> DeviceResult<Self> {
Ok(Self {
inner: Mutex::new(InnerDriver::new(header)?),
})
}
}
impl<'a> Scheme for VirtIoConsole<'a> {}
impl<'a> UartScheme for VirtIoConsole<'a> {
fn try_recv(&self) -> DeviceResult<Option<u8>> {
Ok(self.inner.lock().recv(true)?)
}
fn send(&self, ch: u8) -> DeviceResult {
self.inner.lock().send(ch)?;
Ok(())
}
}
impl<'a> Write for VirtIoConsole<'a> {
fn write_str(&mut self, s: &str) -> Result {
for b in s.bytes() {
self.send(b).unwrap()
}
Ok(())
}
}

View File

@ -1,3 +1,9 @@
mod blk;
mod console;
pub use blk::VirtIoBlk;
pub use console::VirtIoConsole;
use crate::DeviceError;
use core::convert::From;
use virtio_drivers::Error;

View File

@ -8,7 +8,7 @@ description = "Kernel HAL interface definations."
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
libos = ["async-std"]
libos = ["async-std", "zcore-drivers/mock"]
board_qemu = []
board_d1 = []
@ -17,10 +17,11 @@ log = "0.4"
bitflags = "1.3"
trapframe = "0.8.0"
numeric-enum-macro = "0.2"
spin = "0.7"
spin = "0.9"
git-version = "0.3"
cfg-if = "1.0"
acpi = "1.1"
zcore-drivers = { path = "../drivers" }
# LibOS mode
[target.'cfg(not(target_os = "none"))'.dependencies]
@ -31,7 +32,6 @@ async-std = { version = "1.9", optional = true }
# Bare-metal mode
[target.'cfg(target_os = "none")'.dependencies]
zcore-drivers = { path = "../drivers" }
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"] }

View File

@ -0,0 +1,11 @@
use alloc::boxed::Box;
use zcore_drivers::uart::Uart16550Mmio;
use crate::{drivers::UART, mem::phys_to_virt};
pub(super) fn init() {
UART.init_by(Box::new(unsafe {
Uart16550Mmio::<u8>::new(phys_to_virt(super::consts::UART_BASE))
}));
}

View File

@ -1,6 +1,7 @@
#![allow(dead_code)]
mod consts;
mod drivers;
mod plic;
mod sbi;
mod trap;
@ -10,7 +11,6 @@ pub mod context;
pub mod cpu;
pub mod interrupt;
pub mod mem;
pub mod serial;
pub mod special;
pub mod timer;
pub mod vm;
@ -19,7 +19,7 @@ pub fn init() {
vm::remap_the_kernel().unwrap();
interrupt::init();
timer::init();
serial::init();
drivers::init();
#[cfg(feature = "board_qemu")]
{

View File

@ -88,7 +88,7 @@ pub(super) fn handle_interrupt() {
}
UART0_INT_NUM => {
//UART中断ID是10
super::serial::handle_irq();
crate::serial::handle_irq();
//换用sbi的方式获取字符
//interrupt::try_process_serial();

View File

@ -1,48 +0,0 @@
use core::fmt::{Arguments, Result, Write};
use spin::Mutex;
use zcore_drivers::scheme::{Scheme, UartScheme};
use zcore_drivers::{io::Mmio, uart::Uart16550};
use crate::{mem::phys_to_virt, utils::init_once::InitOnce};
pub(super) static UART: InitOnce<Mutex<&'static mut Uart16550<Mmio<u8>>>> = InitOnce::new();
pub(super) fn init() {
UART.init(|| {
let uart = unsafe { Uart16550::<Mmio<u8>>::new(phys_to_virt(super::consts::UART_BASE)) };
uart.init().unwrap();
Mutex::new(uart)
});
}
pub(super) fn handle_irq() {
if let Some(uart) = UART.try_get() {
if let Some(c) = uart.lock().try_recv().unwrap() {
crate::serial::serial_put(c);
}
}
}
struct SbiWriter;
impl Write for SbiWriter {
fn write_str(&mut self, s: &str) -> Result {
for ch in s.chars() {
super::sbi::console_putchar(ch as usize);
}
Ok(())
}
}
hal_fn_impl! {
impl mod crate::hal_fn::serial {
fn serial_write_fmt(fmt: Arguments) {
if let Some(uart) = UART.try_get() {
uart.lock().write_fmt(fmt).unwrap();
} else {
SbiWriter.write_fmt(fmt).unwrap();
}
}
}
}

View File

@ -0,0 +1,9 @@
use alloc::boxed::Box;
use zcore_drivers::uart::Uart16550Pio;
use crate::drivers::UART;
pub(super) fn init() {
UART.init_by(Box::new(Uart16550Pio::new(0x3F8)));
}

View File

@ -240,7 +240,7 @@ fn timer() {
}
fn com1() {
super::serial::handle_irq();
crate::serial::handle_irq();
}
/*

View File

@ -1,5 +1,6 @@
mod acpi_table;
mod apic;
mod drivers;
mod trap;
pub mod config;
@ -7,7 +8,6 @@ pub mod context;
pub mod cpu;
pub mod interrupt;
pub mod mem;
pub mod serial;
pub mod special;
pub mod timer;
pub mod vm;
@ -16,8 +16,8 @@ use x86_64::registers::control::{Cr4, Cr4Flags};
pub fn init() {
apic::init();
drivers::init();
interrupt::init();
serial::init();
fn ap_main() {
info!("processor {} started", cpu::cpu_id());

View File

@ -1,25 +0,0 @@
use core::fmt::{Arguments, Write};
use spin::Mutex;
use zcore_drivers::scheme::{Scheme, UartScheme};
use zcore_drivers::{io::Pio, uart::Uart16550};
pub(super) static COM1: Mutex<Uart16550<Pio<u8>>> = Mutex::new(Uart16550::<Pio<u8>>::new(0x3F8));
pub(super) fn init() {
COM1.lock().init().unwrap();
}
pub(super) fn handle_irq() {
if let Some(c) = COM1.lock().try_recv().unwrap() {
crate::serial::serial_put(c);
}
}
hal_fn_impl! {
impl mod crate::hal_fn::serial {
fn serial_write_fmt(fmt: Arguments) {
COM1.lock().write_fmt(fmt).unwrap();
}
}
}

View File

@ -14,7 +14,7 @@ pub mod mem;
pub mod thread;
pub mod timer;
pub use self::arch::{config, context, cpu, interrupt, serial, vm};
pub use self::arch::{config, context, cpu, interrupt, vm};
pub use super::hal_fn::{dev, rand, vdso};
hal_fn_impl_default!(rand, vdso, dev::fb, dev::input);

View File

@ -0,0 +1,7 @@
use alloc::boxed::Box;
use zcore_drivers::scheme::UartScheme;
use crate::utils::init_once::InitOnce;
pub static UART: InitOnce<Box<dyn UartScheme>> = InitOnce::new();

View File

@ -3,6 +3,7 @@ pub(super) mod fb;
pub mod addr;
pub mod context;
pub mod drivers;
pub mod future;
pub mod mem;
pub mod serial;

View File

@ -1,18 +1,35 @@
use alloc::{boxed::Box, collections::VecDeque, vec::Vec};
use core::fmt::{Arguments, Result, Write};
use spin::Mutex;
use crate::drivers::UART;
lazy_static::lazy_static! {
static ref STDIN: Mutex<VecDeque<u8>> = Mutex::new(VecDeque::new());
static ref STDIN_CALLBACK: Mutex<Vec<Box<dyn Fn() -> bool + Send + Sync>>> =
Mutex::new(Vec::new());
}
/// Put a char to serial buffer.
pub fn serial_put(x: u8) {
let x = if x == b'\r' { b'\n' } else { x };
STDIN.lock().push_back(x);
STDIN_CALLBACK.lock().retain(|f| !f());
struct SerialWriter;
impl Write for SerialWriter {
fn write_str(&mut self, s: &str) -> Result {
if let Some(uart) = UART.try_get() {
uart.write_str(s).unwrap();
}
Ok(())
}
}
pub(crate) fn handle_irq() {
if let Some(uart) = UART.try_get() {
if let Some(c) = uart.try_recv().unwrap() {
let c = if c == b'\r' { b'\n' } else { c };
STDIN.lock().push_back(c);
STDIN_CALLBACK.lock().retain(|f| !f());
}
}
}
/// Register a callback of serial readable event.
@ -30,7 +47,12 @@ pub fn serial_read(buf: &mut [u8]) -> usize {
len
}
/// 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) {
crate::serial::serial_write_fmt(format_args!("{}", s));
serial_write_fmt(format_args!("{}", s));
}

View File

@ -1,5 +1,5 @@
use alloc::boxed::Box;
use core::{fmt::Arguments, future::Future, ops::Range, pin::Pin, time::Duration};
use core::{future::Future, ops::Range, pin::Pin, time::Duration};
use crate::{common, HalResult, MMUFlags, PhysAddr, VirtAddr};
@ -125,11 +125,6 @@ hal_fn_def! {
pub(crate) fn timer_tick();
}
pub mod serial: common::serial {
/// Print format string and its arguments to serial.
pub fn serial_write_fmt(fmt: Arguments);
}
pub mod rand {
/// Fill random bytes to the buffer
#[allow(unused_variables)]

View File

@ -31,7 +31,7 @@ cfg_if! {
}
}
pub use common::{addr, defs::*, future, user};
pub use common::{addr, defs::*, drivers, future, serial, user};
pub use config::*;
pub use imp::*;
pub use kernel_handler::*;

View File

@ -0,0 +1,9 @@
use alloc::boxed::Box;
use zcore_drivers::mock::MockUart;
use crate::drivers::UART;
pub(super) fn init() {
UART.init_by(Box::new(MockUart::new()));
}

View File

@ -1,10 +1,10 @@
mod drivers;
mod mem_common;
pub(super) mod dummy;
pub mod config;
pub mod mem;
pub mod serial;
pub mod thread;
pub mod timer;
pub mod vdso;
@ -32,16 +32,16 @@ include!("macos.rs");
pub fn init() {
crate::KHANDLER.init_by(&crate::DummyKernelHandler);
drivers::init();
#[cfg(target_os = "macos")]
unsafe {
register_sigsegv_handler();
}
// spawn a thread to read stdin
// TODO: raw mode
use std::io::Read;
std::thread::spawn(|| {
for i in std::io::stdin().bytes() {
serial::serial_put(i.unwrap());
}
std::thread::spawn(|| loop {
crate::serial::handle_irq();
core::hint::spin_loop();
});
}

View File

@ -1,7 +0,0 @@
hal_fn_impl! {
impl mod crate::hal_fn::serial {
fn serial_write_fmt(fmt: core::fmt::Arguments) {
eprint!("{}", fmt);
}
}
}

View File

@ -16,7 +16,6 @@ hal_fn_impl! {
pub struct PageTable;
impl PageTable {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Self
}
@ -30,6 +29,12 @@ impl PageTable {
}
}
impl Default for PageTable {
fn default() -> Self {
Self::new()
}
}
impl GenericPageTable for PageTable {
fn table_phys(&self) -> PhysAddr {
0

View File

@ -176,7 +176,6 @@ impl<L: PageTableLevel, PTE: GenericPTE> PageTableImpl<L, PTE> {
/// Public implementation.
impl<L: PageTableLevel, PTE: GenericPTE> PageTableImpl<L, PTE> {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
let root = PhysFrame::new_zero().expect("failed to alloc frame");
Self {
@ -198,6 +197,12 @@ impl<L: PageTableLevel, PTE: GenericPTE> PageTableImpl<L, PTE> {
}
}
impl<L: PageTableLevel, PTE: GenericPTE> Default for PageTableImpl<L, PTE> {
fn default() -> Self {
Self::new()
}
}
impl<L: PageTableLevel, PTE: GenericPTE> GenericPageTable for PageTableImpl<L, PTE> {
fn table_phys(&self) -> PhysAddr {
self.root.paddr()

View File

@ -13,7 +13,7 @@ graphic = []
[dependencies]
async-trait = "0.1"
log = "0.4"
spin = "0.7"
spin = "0.9"
xmas-elf = "0.7"
bitflags = "1.3"
hashbrown = "0.9"

View File

@ -9,7 +9,7 @@ description = "Linux syscalls implementation"
[dependencies]
log = "0.4"
spin = "0.7"
spin = "0.9"
bitflags = "1.3"
numeric-enum-macro = "0.2"
zircon-object = { path = "../zircon-object" }

View File

@ -20,7 +20,7 @@ lto = true
[dependencies]
log = "0.4"
spin = "0.7"
spin = "0.9"
cfg-if = "1.0"
buddy_system_allocator = "0.7"
kernel-hal = { path = "../kernel-hal" }

View File

@ -14,7 +14,7 @@ elf = ["xmas-elf"]
[dependencies]
bitflags = "1.3"
spin = "0.7"
spin = "0.9"
log = "0.4"
hashbrown = "0.9"
downcast-rs = { version = "1.2", default-features = false }

View File

@ -16,7 +16,7 @@ std = ["deny-page-fault"]
[dependencies]
log = "0.4"
spin = "0.7"
spin = "0.9"
bitflags = "1.3"
numeric-enum-macro = "0.2"
zircon-object = { path = "../zircon-object" }