Wait until serial tx buffer is empty
All checks were successful
Continuous Integration / Check (push) Successful in 1m9s
Continuous Integration / Clippy (push) Successful in 1m12s

This commit is contained in:
August 2025-11-04 16:32:03 -05:00
parent b02c34fd1d
commit 07136397d0
Signed by: shibedrill
GPG Key ID: 5FE0CB25945EFAA2

View File

@ -9,6 +9,8 @@ use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use x86_64::instructions::port::Port;
use crate::arch::asm::nop;
/// Represents an x86 port-mapped serial port.
pub struct SerialPort {
base_port: Port<u8>,
@ -21,6 +23,7 @@ pub struct SerialPort {
scratch: Port<u8>,
fifo_register: u8,
pub crlf: Crlf,
pub wait_tx_clear: bool,
}
#[derive(PartialEq, Eq)]
@ -123,7 +126,6 @@ pub enum ModemStatus {
DataCarrierDetect = 0b10000000,
}
// TODO: Ensure we don't clobber the tx buffer and prevent some data from getting printed
impl SerialPort {
pub fn log_write(&mut self, msg: &str) {
if self.crlf == Crlf::Crlf {
@ -140,10 +142,18 @@ impl SerialPort {
}
}
/// Get whether the transmit buffer is empty.
pub fn is_transmit_empty(&mut self) -> bool {
self.get_interrupt_state() != InterruptState::TransmitterEmpty
self.get_line_status().contains(LineStatus::TransmitterEmpty)
}
fn block_until_transmit_empty(&mut self) {
while !self.is_transmit_empty() {
nop();
}
}
/// Write a message with a newline appended to the serial port.
pub fn log_writeln(&mut self, msg: &str) {
self.log_write(msg);
self.log_write("\n");
@ -162,6 +172,7 @@ impl SerialPort {
scratch: Port::new(port_addr + 7),
fifo_register: 0,
crlf: Crlf::Crlf,
wait_tx_clear: true,
};
// ensure this is false
port.set_dlab(false);
@ -190,6 +201,10 @@ impl SerialPort {
}
/// Write a single character to the TX buffer.
pub fn write_char(&mut self, c: char) {
// Wait for the TX Buffer to be empty
if self.wait_tx_clear {
self.block_until_transmit_empty();
}
unsafe { self.base_port.write(c as u8) };
}