resolve uart interrupts
diff --git a/target/ast10x0/backend/usart/src/lib.rs b/target/ast10x0/backend/usart/src/lib.rs index 5585a79..52c1cac 100644 --- a/target/ast10x0/backend/usart/src/lib.rs +++ b/target/ast10x0/backend/usart/src/lib.rs
@@ -27,8 +27,15 @@ // The peripheral driver's `Usart::new` enables every IER source. // Mask the ones the trait exposes so the server inherits a quiet // device and only the interrupts a client explicitly enables fire. - uart.clear_rx_data_available_interrupt(); - uart.clear_tx_idle_interrupt(); + // uart.clear_rx_data_available_interrupt(); + // uart.clear_tx_idle_interrupt(); + // ELSI and EDSSI were also left enabled. EDSSI fires immediately if + // the MSR delta bits (DCTS/DDSR/TERI/DDCD) are set at init — QEMU + // sets them — causing a continuous IRQ that the server acks and + // unmasks in a tight loop, starving the IPC dispatch path. + // Read MSR to clear the delta bits, then disable all four IER sources. + uart.drain_modem_status(); + uart.disable_all_interrupts(); Self { uart } }
diff --git a/target/ast10x0/peripherals/uart/mod.rs b/target/ast10x0/peripherals/uart/mod.rs index 0de7491..e8d039e 100644 --- a/target/ast10x0/peripherals/uart/mod.rs +++ b/target/ast10x0/peripherals/uart/mod.rs
@@ -461,4 +461,15 @@ pub fn clear_rx_data_available_interrupt(&self) { self.regs().uartier().modify(|_, w| w.erbfi().clear_bit()); } + + /// Disables all four IER interrupt sources at once. + pub fn disable_all_interrupts(&self) { + self.regs().uartier().write(|w| w); + } + + /// Reads and discards MSR to clear the delta bits (DCTS/DDSR/TERI/DDCD) + /// that would otherwise keep retriggering EDSSI after enable. + pub fn drain_modem_status(&self) { + let _ = self.regs().uartmsr().read().bits(); + } }