kernel/arch/x86_64/drivers/tty/
uart.rs1use crate::drivers::tty::uart::{UartError, UartOps, UartResult};
7use core::sync::atomic::{AtomicU8, Ordering};
8use x86_64::instructions::port::Port;
9
10pub struct Uart {
12 state: AtomicU8,
13 base_addr: u16
14}
15
16impl Uart {
17 const INIT_CALLED: u8 = 1 << 0;
18 const USABLE: u8 = 1 << 1;
19
20 pub fn new(base_addr: u16) -> Self {
22 Self {
23 state: AtomicU8::default(),
24 base_addr,
25 }
26 }
27
28 pub fn com1() -> Self {
30 Self::new(0x3F8)
31 }
32 pub fn com2() -> Self {
34 Self::new(0x2F8)
35 }
36 pub fn com3() -> Self {
38 Self::new(0x3E8)
39 }
40 pub fn com4() -> Self {
42 Self::new(0x2E8)
43 }
44
45 fn reg(&self, offset: u16) -> Port<u8> {
47 Port::new(self.base_addr + offset)
48 }
49
50 #[inline(always)]
52 fn is_usable(&self) -> bool {
53 self.state.load(Ordering::Acquire) & Self::USABLE == Self::USABLE
54 }
55}
56
57impl UartOps for Uart {
58 fn init(&mut self) -> UartResult<()> {
59 let prev = self.state.fetch_or(Self::INIT_CALLED, Ordering::AcqRel);
60
61 if prev & Self::INIT_CALLED != 0 {
62 core::hint::cold_path();
63 return Err(UartError::AlreadyInitialized);
64 }
65
66 unsafe {
70 self.reg(1).write(0x00); self.reg(3).write(0x80); self.reg(0).write(0x01); self.reg(1).write(0x00); self.reg(3).write(0x03); self.reg(2).write(0xC7); self.reg(4).write(0x0B); }
78
79 self.state.fetch_or(Self::USABLE, Ordering::AcqRel);
80 Ok(())
81 }
82
83 fn read_byte(&mut self) -> UartResult<u8> {
84 if !self.is_usable() {
85 core::hint::cold_path();
86 return Err(UartError::NotInitialized);
87 }
88
89 unsafe {
91 while self.reg(5).read() & 0x01 == 0 {
92 core::hint::spin_loop();
93 }
94 Ok(self.reg(0).read())
95 }
96 }
97
98 fn write_byte(&mut self, byte: u8) -> UartResult<()> {
99 if !self.is_usable() {
100 core::hint::cold_path();
101 return Err(UartError::NotInitialized);
102 }
103
104 unsafe {
106 while self.reg(5).read() & 0x20 == 0 {
107 core::hint::spin_loop();
108 }
109 self.reg(0).write(byte);
110 }
111
112 Ok(())
113 }
114}