]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commit
fix: serial input blocking — timer-polled UART RX fallback
authorTulio A M Mendes <[email protected]>
Sat, 14 Feb 2026 22:27:14 +0000 (19:27 -0300)
committerTulio A M Mendes <[email protected]>
Sat, 14 Feb 2026 22:27:14 +0000 (19:27 -0300)
commitcef8b5224536c58168c35b22a70cc3ae7beaaeee
treea4c3401fe144d50e945c4bf450e621fdaf0fa23f
parent46adb42eb6bc6800c7a4ad8fe36cf544e08e4922
fix: serial input blocking — timer-polled UART RX fallback

Root cause: IOAPIC edge-triggered delivery for COM1 IRQ 4 never
fires in QEMU i440FX. The UART IRQ line state during the PIC→IOAPIC
transition is undefined — if the line is already HIGH when the
IOAPIC starts watching, no rising edge is ever detected, permanently
blocking serial input.

Attempted fixes that did NOT work:
- hal_uart_drain_rx() after IOAPIC routing (drain FIFO + IIR + MSR)
- FIFO trigger level 14→1 byte (eliminate character timeout dependency)
- IER disable→drain→re-enable sequencing around IOAPIC route

Fix: poll UART RX in the timer tick handler (100Hz). hal_uart_poll_rx()
checks LSR bit 0 and dispatches pending characters through the existing
rx_callback chain (tty_input_char). This gives ≤10ms latency for serial
input — imperceptible for interactive use.

The IRQ-driven path (uart_irq_handler at vector 36) remains active as
a fast path for platforms where IOAPIC edge detection works correctly.

Also adds tests/test_serial_input.exp: automated expect-based test that
boots /bin/sh with console=serial and verifies typed commands execute.

Tests: 20/20 smoke (8s), 16/16 battery, serial input PASS, cppcheck clean
include/hal/uart.h
src/drivers/timer.c
src/hal/arm/uart.c
src/hal/mips/uart.c
src/hal/riscv/uart.c
src/hal/x86/uart.c
tests/test_serial_input.exp [new file with mode: 0755]