summaryrefslogtreecommitdiff
path: root/kernel/src/io/output/serial
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2026-09-06 18:07:30 +0800
committerlittleblack111 <littleblack11111@gmail.com>2026-09-06 18:07:30 +0800
commit4820b2dd73543a6fbd5db547d009529d0fe11ccd (patch)
tree86243e91da43f575a807f43f1ff4c359cf72e159 /kernel/src/io/output/serial
parent9c887d5428043bab7af259386d9bda5dd1fd59f8 (diff)
new: earlyprintk
Diffstat (limited to 'kernel/src/io/output/serial')
-rw-r--r--kernel/src/io/output/serial/uart_16550.rs82
1 files changed, 77 insertions, 5 deletions
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
+ },
+ ],
+ })
+ }
}
}