]> 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)
commitd696dfe1d2741a8e1a19597e60da0ccdc238ce22
tree564c05a2a4ec3aa9499d58d7cb5b7f7be9ea3ffd
parent5027c8fec901a8da84d64251bbfb70392de36e07
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]