diff --git a/src/arch/aarch64/device/serial.rs b/src/arch/aarch64/device/serial.rs index a81287f0fb..f172cd8e5c 100644 --- a/src/arch/aarch64/device/serial.rs +++ b/src/arch/aarch64/device/serial.rs @@ -101,8 +101,8 @@ pub unsafe fn init_early(dtb: &Fdt) { }; match serial_opt { Some(serial) => { - info!("UART {:?} at {:#X} size {:#X}", compatible, virt, size); *COM1.lock() = Some(serial); + info!("UART {:?} at {:#X} size {:#X}", compatible, virt, size); } None => { log::warn!( diff --git a/src/arch/riscv64/device/serial.rs b/src/arch/riscv64/device/serial.rs index c379ab9289..5fc366d12e 100644 --- a/src/arch/riscv64/device/serial.rs +++ b/src/arch/riscv64/device/serial.rs @@ -16,18 +16,35 @@ use crate::{ }, }; -pub struct SerialPort { - inner: &'static mut uart_16550::SerialPort>, +pub enum SerialPort { + Ns16550u8(&'static mut uart_16550::SerialPort>), + Ns16550u32(&'static mut uart_16550::SerialPort>), } + impl SerialPort { - pub fn write(&mut self, buf: &[u8]) { - self.inner.write(buf) - } pub fn receive(&mut self) { - while let Some(c) = self.inner.receive() { - debug_input(c); + //TODO: make PL011 receive work the same way as NS16550 + match self { + Self::Ns16550u8(inner) => { + while let Some(c) = inner.receive() { + debug_input(c); + } + debug_notify(); + } + Self::Ns16550u32(inner) => { + while let Some(c) = inner.receive() { + debug_input(c); + } + debug_notify(); + } + } + } + + pub fn write(&mut self, buf: &[u8]) { + match self { + Self::Ns16550u8(inner) => inner.write(buf), + Self::Ns16550u32(inner) => inner.write(buf), } - debug_notify(); } } @@ -55,20 +72,28 @@ pub unsafe fn init_early(dtb: &Fdt) { if let Some((phys, size, skip_init, _cts, compatible)) = diag_uart_range(dtb) { let virt = crate::PHYS_OFFSET + phys; - let serial_opt = if compatible.contains("ns16550a") || compatible.contains("snps,dw-apb-uart") { + let serial_opt = + if compatible.contains("ns16550a") { //TODO: get actual register size from device tree let serial_port = uart_16550::SerialPort::>::new(virt); if !skip_init { serial_port.init(); } - Some(SerialPort { inner: serial_port }) + Some(SerialPort::Ns16550u8(serial_port)) + } else if compatible.contains("snps,dw-apb-uart") { + //TODO: get actual register size from device tree + let serial_port = uart_16550::SerialPort::>::new(virt); + if !skip_init { + serial_port.init(); + } + Some(SerialPort::Ns16550u32(serial_port)) } else { None }; match serial_opt { Some(serial) => { - info!("UART {:?} at {:#X} size {:#X}", compatible, virt, size); *COM1.lock() = Some(serial); + info!("UART {:?} at {:#X} size {:#X}", compatible, virt, size); } None => { log::warn!(