summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/src/init.rs2
-rw-r--r--kernel/src/init/acpi.rs0
-rw-r--r--kernel/src/init/earlyprintk.rs24
-rw-r--r--kernel/src/io/output/serial/uart_16550.rs82
-rw-r--r--kernel/src/main.rs14
5 files changed, 116 insertions, 6 deletions
diff --git a/kernel/src/init.rs b/kernel/src/init.rs
new file mode 100644
index 0000000..ef51b1f
--- /dev/null
+++ b/kernel/src/init.rs
@@ -0,0 +1,2 @@
+pub mod acpi;
+pub mod earlyprintk;
diff --git a/kernel/src/init/acpi.rs b/kernel/src/init/acpi.rs
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/kernel/src/init/acpi.rs
diff --git a/kernel/src/init/earlyprintk.rs b/kernel/src/init/earlyprintk.rs
new file mode 100644
index 0000000..01c50fa
--- /dev/null
+++ b/kernel/src/init/earlyprintk.rs
@@ -0,0 +1,24 @@
+use spin::{lazylock::LazyLock, mutex::Mutex};
+
+use crate::io::output::serial::uart_16550::{SerialPortBitMask, 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() })
+});
+
+#[macro_export]
+macro_rules! printk {
+ ($($arg:tt)*) => ({
+ use ::core::fmt::Write;
+ write!($crate::init::earlyprintk::EARLY_PRINTK_SERIAL.lock().coms[0].as_mut().unwrap(), $($arg)*)
+ });
+}
+
+#[macro_export]
+macro_rules! printkln {
+ ($($arg:tt)*) => ({
+ use ::core::fmt::Write;
+ writeln!($crate::init::earlyprintk::EARLY_PRINTK_SERIAL.lock().coms[0].as_mut().unwrap(), $($arg)*)
+ });
+}
diff --git a/kernel/src/io/output/serial/uart_16550.rs b/kernel/src/io/output/serial/uart_16550.rs
index 984854a..65ba4e9 100644
--- a/kernel/src/io/output/serial/uart_16550.rs
+++ b/kernel/src/io/output/serial/uart_16550.rs
@@ -1,15 +1,87 @@
+use bitflags::bitflags;
+use uart_16550::{
+ Config, Uart16550Tty, Uart16550TtyError,
+ backend::{PioBackend, PortIoAddress},
+};
+
+#[repr(u16)]
+// TODO: parse & validate via acpi alors scratch
pub enum SerialPortAddress {
- Com1 = 0x3F8,
+ COM1 = 0x3F8,
Com2 = 0x2F8,
Com3 = 0x3E8,
Com4 = 0x2E8,
}
-#[derive(Default)]
-pub struct Uart16550 {}
+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
+ }
+}
+
+pub struct Uart16550 {
+ pub coms: [Option<Uart16550Tty<PioBackend>>; 4],
+}
impl Uart16550 {
- pub fn new() -> Self {
- Self {}
+ /// # Safety
+ ///
+ /// Callers must ensure that the base port is valid and safe to use
+ /// for the **whole lifetime** of the device(exclusively). Further, all
+ /// [`NUM_REGISTERS`] registers must be safely reachable from the base
+ /// address.
+ ///
+ /// [`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
+ },
+ ],
+ })
+ }
}
}
diff --git a/kernel/src/main.rs b/kernel/src/main.rs
index bfa20e6..87f590d 100644
--- a/kernel/src/main.rs
+++ b/kernel/src/main.rs
@@ -5,11 +5,23 @@
// extern crate alloc;
use bootloader_api::{BootInfo, BootloaderConfig, entry_point};
-use kernel::pm::hcf;
+use core::fmt::Write;
+use kernel::{io::output::serial::uart_16550::Uart16550, pm::hcf, printk};
const CONFIG: BootloaderConfig = BootloaderConfig::new_default();
fn kmain(boot_info: &'static mut BootInfo) -> ! {
+ // let mut a = unsafe { Uart16550::init(Default::default()) }.unwrap().com1;
+ // write!(a, "test").unwrap();
+ printk!("test").unwrap();
+ printk!("test").unwrap();
+ printk!("test").unwrap();
+ printk!("test").unwrap();
+ printk!("test").unwrap();
+ printk!("test").unwrap();
+ printk!("test").unwrap();
+ printk!("test").unwrap();
+ printk!("test").unwrap();
hcf()
}