From f1492729d2d3aac99a0753f839d6817d3880cbd7 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 7 Sep 2025 20:36:05 -0600 Subject: [PATCH] riscv64: support snps,dw-apb-uart serial --- src/arch/riscv64/device/serial.rs | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/arch/riscv64/device/serial.rs b/src/arch/riscv64/device/serial.rs index b74e1a5094..c379ab9289 100644 --- a/src/arch/riscv64/device/serial.rs +++ b/src/arch/riscv64/device/serial.rs @@ -53,26 +53,37 @@ pub unsafe fn init_early(dtb: &Fdt) { return; } - if let Some((phys, _, _, _, compatible)) = diag_uart_range(dtb) { + if let Some((phys, size, skip_init, _cts, compatible)) = diag_uart_range(dtb) { let virt = crate::PHYS_OFFSET + phys; - let port = if compatible == "ns16550a" { + let serial_opt = if compatible.contains("ns16550a") || compatible.contains("snps,dw-apb-uart") { + //TODO: get actual register size from device tree let serial_port = uart_16550::SerialPort::>::new(virt); - serial_port.init(); + if !skip_init { + serial_port.init(); + } Some(SerialPort { inner: serial_port }) } else { None }; - match port { - Some(port) => { - *COM1.lock() = Some(port); + match serial_opt { + Some(serial) => { + info!("UART {:?} at {:#X} size {:#X}", compatible, virt, size); + *COM1.lock() = Some(serial); + } + None => { + log::warn!( + "UART {:?} at {:#X} size {:#X}: no driver found", + compatible, + virt, + size + ); } - None => {} } } } pub unsafe fn init(fdt: &Fdt) -> Option<()> { - if let Some(node) = fdt.find_compatible(&["ns16550a"]) { + if let Some(node) = fdt.find_compatible(&["ns16550a", "snps,dw-apb-uart"]) { let intr = get_interrupt(fdt, &node, 0).unwrap(); let interrupt_parent = interrupt_parent(fdt, &node)?; let phandle = interrupt_parent.property("phandle")?.as_usize()? as u32;