From 2252edf22816f27a934bca50c2c8b1b302c3178f Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Fri, 15 Sep 2023 16:49:55 +0800 Subject: [PATCH] feat: implement Reader on RawConsole --- src/arch/io.rs | 10 ++++++---- src/arch/riscv/board/virt/mod.rs | 2 ++ src/arch/riscv/board/virt/printer.rs | 6 ++++++ src/arch/riscv/board/virt/reader.rs | 11 +++++++++++ src/arch/riscv/io.rs | 16 +++++++++++++++- src/lib.rs | 1 + 6 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 src/arch/riscv/board/virt/reader.rs diff --git a/src/arch/io.rs b/src/arch/io.rs index caa84a5..40288a3 100644 --- a/src/arch/io.rs +++ b/src/arch/io.rs @@ -1,8 +1,6 @@ -use core::fmt::Write; - pub struct RawConsole; -pub trait Printer: Write { +pub trait Printer: core::fmt::Write { fn put_char(c: char); #[inline] @@ -64,7 +62,11 @@ pub trait Printer: Write { } } -impl Write for RawConsole { +pub trait Reader { + fn get_char() -> char; +} + +impl core::fmt::Write for RawConsole { fn write_str(&mut self, s: &str) -> core::fmt::Result { Self::put_str(s); Ok(()) diff --git a/src/arch/riscv/board/virt/mod.rs b/src/arch/riscv/board/virt/mod.rs index 545cbe0..7cd41af 100644 --- a/src/arch/riscv/board/virt/mod.rs +++ b/src/arch/riscv/board/virt/mod.rs @@ -1,3 +1,5 @@ pub const UART0_BASE: usize = 0x1000_0000; +pub const UART0_LSR: usize = 0x1000_0005; pub mod printer; +pub mod reader; diff --git a/src/arch/riscv/board/virt/printer.rs b/src/arch/riscv/board/virt/printer.rs index 8b98120..611427b 100644 --- a/src/arch/riscv/board/virt/printer.rs +++ b/src/arch/riscv/board/virt/printer.rs @@ -1,5 +1,11 @@ use crate::arch::io::{Printer, RawConsole}; +/* + Theoretically, we should wait until + "THR Empty" bit (1<<5 in LSR) is set + before writing to UART. +*/ + impl Printer for RawConsole { #[inline] fn put_char(c: char) { diff --git a/src/arch/riscv/board/virt/reader.rs b/src/arch/riscv/board/virt/reader.rs new file mode 100644 index 0000000..d2b07cb --- /dev/null +++ b/src/arch/riscv/board/virt/reader.rs @@ -0,0 +1,11 @@ +use crate::arch::io::{RawConsole, Reader}; + +impl Reader for RawConsole { + #[inline] + fn get_char() -> char { + let uart = super::UART0_BASE as *mut char; + let line_sts = super::UART0_LSR as *mut u8; + while unsafe { line_sts.read_volatile() } & 0x01 == 0 {} + unsafe { uart.read_volatile() } + } +} diff --git a/src/arch/riscv/io.rs b/src/arch/riscv/io.rs index 41f1697..bcb6486 100644 --- a/src/arch/riscv/io.rs +++ b/src/arch/riscv/io.rs @@ -1,5 +1,5 @@ #[allow(unused_imports)] -use crate::arch::io::{Printer, RawConsole}; +use crate::arch::io::{Printer, RawConsole, Reader}; #[cfg(feature = "board_default")] impl Printer for RawConsole { @@ -8,3 +8,17 @@ impl Printer for RawConsole { sbi_rt::legacy::console_putchar(c as usize); } } + +#[cfg(feature = "board_default")] +impl Reader for RawConsole { + fn get_char() -> char { + loop { + #[allow(deprecated)] + let ch = sbi_rt::legacy::console_getchar(); + if ch == usize::MAX { + continue; + } + return ch as u8 as char; + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 72ce742..c3ae463 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ #![feature(naked_functions)] #![feature(panic_info_message)] #![feature(fmt_internals)] +#![feature(stmt_expr_attributes)] // arch pub mod arch;