Serial I/O buffer #2
All checks were successful
Check / Build ISO (nightly-2025-04-27) (push) Successful in 42s

This commit is contained in:
Masato Imai
2025-08-24 12:24:53 +00:00
parent a0188056f0
commit 1606184551
2 changed files with 52 additions and 1 deletions

View File

@@ -56,6 +56,18 @@ pub fn write_byte(byte: u8) {
});
}
#[inline(always)]
pub fn write_bytes(bytes: &[u8]) {
use x86_64::instructions::interrupts;
interrupts::without_interrupts(|| {
let mut serial = SERIAL1.lock();
for &b in bytes {
serial.send(b);
}
});
}
#[macro_export]
macro_rules! print {
($($arg:tt)*) => {

View File

@@ -61,6 +61,7 @@ pub struct Pic {
pub primary_read_sel: ReadSel,
pub secondary_read_sel: ReadSel,
pub serial: Serial,
pub serial_buffer: SerialBuffer,
}
impl Pic {
@@ -79,6 +80,7 @@ impl Pic {
primary_read_sel: ReadSel::Irr,
secondary_read_sel: ReadSel::Irr,
serial: Serial::default(),
serial_buffer: SerialBuffer::default(),
}
}
@@ -235,7 +237,17 @@ impl Pic {
fn handle_serial_out(&mut self, regs: &mut GuestRegisters, qual: QualIo) {
match qual.port() {
0x3F8 => serial::write_byte(regs.rax as u8),
0x3F8 => {
let byte = regs.rax as u8;
if self.serial_buffer.end < self.serial_buffer.buffer.len() {
self.serial_buffer.buffer[self.serial_buffer.end] = byte;
self.serial_buffer.end += 1;
}
if byte == b'\n' || self.serial_buffer.end == self.serial_buffer.buffer.len() {
self.serial_buffer.flush();
}
}
0x3F9 => self.serial.ier = regs.rax as u8,
0x3FA => {}
0x3FB => {}
@@ -406,3 +418,30 @@ impl IOBitmap {
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct SerialBuffer {
pub buffer: [u8; 1024],
pub end: usize,
}
impl SerialBuffer {
pub fn flush(&mut self) {
if self.end == 0 {
return;
}
serial::write_bytes(&self.buffer[..self.end]);
self.end = 0;
}
}
impl Default for SerialBuffer {
fn default() -> Self {
Self {
buffer: [0; 1024],
end: 0,
}
}
}