summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/src/init/earlyprintk.rs24
-rw-r--r--kernel/src/io/output/serial/uart_16550.rs55
2 files changed, 30 insertions, 49 deletions
diff --git a/kernel/src/init/earlyprintk.rs b/kernel/src/init/earlyprintk.rs
index 01c50fa..a217a92 100644
--- a/kernel/src/init/earlyprintk.rs
+++ b/kernel/src/init/earlyprintk.rs
@@ -1,17 +1,26 @@
use spin::{lazylock::LazyLock, mutex::Mutex};
-use crate::io::output::serial::uart_16550::{SerialPortBitMask, Uart16550};
+use crate::io::output::serial::uart_16550::Uart16550;
// TODO: use linkme instead
-pub static EARLY_PRINTK_SERIAL: LazyLock<Mutex<Uart16550>> = LazyLock::new(|| {
- Mutex::new(unsafe { Uart16550::init(SerialPortBitMask::COM1, [const { None }; 4]).unwrap() })
-});
+pub static EARLY_PRINTK_SERIAL: LazyLock<Option<Mutex<Uart16550>>> =
+ LazyLock::new(|| match unsafe { Uart16550::init([const { None }; 4]) } {
+ Ok(o) => Some(Mutex::new(o)),
+ Err(_) => None,
+ });
#[macro_export]
+// TODO: configurable via option or arguments
+// or use a system similar to the drivers(`linkme`)
macro_rules! printk {
($($arg:tt)*) => ({
use ::core::fmt::Write;
- write!($crate::init::earlyprintk::EARLY_PRINTK_SERIAL.lock().coms[0].as_mut().unwrap(), $($arg)*)
+ match &*$crate::init::earlyprintk::EARLY_PRINTK_SERIAL {
+ // TODO: elim the unwrap
+ Some(m) => write!(m.lock().coms[0].as_mut().unwrap(), $($arg)*),
+ // TODO: if needed find a way to return an error here, but for now just ignore it
+ None => Ok(()),
+ }
});
}
@@ -19,6 +28,9 @@ macro_rules! printk {
macro_rules! printkln {
($($arg:tt)*) => ({
use ::core::fmt::Write;
- writeln!($crate::init::earlyprintk::EARLY_PRINTK_SERIAL.lock().coms[0].as_mut().unwrap(), $($arg)*)
+ match &*$crate::init::earlyprintk::EARLY_PRINTK_SERIAL {
+ Some(m) => writeln!(m.lock().coms[0].as_mut().unwrap(), $($arg)*),
+ None => Ok(()),
+ }
});
}
diff --git a/kernel/src/io/output/serial/uart_16550.rs b/kernel/src/io/output/serial/uart_16550.rs
index 65ba4e9..3ecce1b 100644
--- a/kernel/src/io/output/serial/uart_16550.rs
+++ b/kernel/src/io/output/serial/uart_16550.rs
@@ -1,4 +1,3 @@
-use bitflags::bitflags;
use uart_16550::{
Config, Uart16550Tty, Uart16550TtyError,
backend::{PioBackend, PortIoAddress},
@@ -13,15 +12,6 @@ pub enum SerialPortAddress {
Com4 = 0x2E8,
}
-bitflags! {
- pub struct SerialPortBitMask: u8 {
- const COM1 = 1 << 0;
- const COM2 = 1 << 1;
- const COM3 = 1 << 2;
- const COM4 = 1 << 3;
- }
-}
-
impl From<SerialPortAddress> for u16 {
fn from(value: SerialPortAddress) -> Self {
value as u16
@@ -32,6 +22,14 @@ pub struct Uart16550 {
pub coms: [Option<Uart16550Tty<PioBackend>>; 4],
}
+#[inline(always)]
+fn init_port(
+ cfg: &mut Option<Config>,
+ addr: SerialPortAddress,
+) -> Result<Option<Uart16550Tty<PioBackend>>, Uart16550TtyError<PortIoAddress>> {
+ cfg.take().map(|c| unsafe { Uart16550Tty::new_port(addr.into(), c) }).transpose()
+}
+
impl Uart16550 {
/// # Safety
///
@@ -42,44 +40,15 @@ impl Uart16550 {
///
/// [`NUM_REGISTERS`]: crate::spec::NUM_REGISTERS
pub unsafe fn init(
- coms_enabled: SerialPortBitMask,
mut config: [Option<Config>; 4],
) -> Result<Self, Uart16550TtyError<PortIoAddress>> {
unsafe {
Ok(Self {
coms: [
- if coms_enabled.contains(SerialPortBitMask::COM1) {
- Some(Uart16550Tty::new_port(
- SerialPortAddress::COM1.into(),
- config[0].take().unwrap_or_default(),
- )?)
- } else {
- None
- },
- if coms_enabled.contains(SerialPortBitMask::COM2) {
- Some(Uart16550Tty::new_port(
- SerialPortAddress::Com2.into(),
- config[1].take().unwrap_or_default(),
- )?)
- } else {
- None
- },
- if coms_enabled.contains(SerialPortBitMask::COM3) {
- Some(Uart16550Tty::new_port(
- SerialPortAddress::Com3.into(),
- config[2].take().unwrap_or_default(),
- )?)
- } else {
- None
- },
- if coms_enabled.contains(SerialPortBitMask::COM4) {
- Some(Uart16550Tty::new_port(
- SerialPortAddress::Com4.into(),
- config[3].take().unwrap_or_default(),
- )?)
- } else {
- None
- },
+ init_port(&mut config[0], SerialPortAddress::COM1)?,
+ init_port(&mut config[1], SerialPortAddress::Com2)?,
+ init_port(&mut config[2], SerialPortAddress::Com3)?,
+ init_port(&mut config[3], SerialPortAddress::Com4)?,
],
})
}