From 3dfec89f160af260e91766170e6784ff74fbcccb Mon Sep 17 00:00:00 2001 From: Alex Jones Date: Mon, 1 Sep 2025 23:00:51 +0100 Subject: [PATCH] [ot] hw/opentitan: ot_uart: Report RX idle high in `VAL` reg The UART's `VAL` register is currently not implemented, but since we assume that the UART is always reporting `STATUS.RXIDLE`, it makes sense that the `VAL.RX` field should always report sampling idle (high) bits instead of 0. This will help with booting ROM_EXT, which detects an incoming break condition on the UART via the VAL regsiter to determine when to enter Rescue mode via the Rescue 1.0 mechanism. Signed-off-by: Alex Jones --- hw/opentitan/ot_uart.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/hw/opentitan/ot_uart.c b/hw/opentitan/ot_uart.c index cdf35ffe1bf3c..bc47d9789a198 100644 --- a/hw/opentitan/ot_uart.c +++ b/hw/opentitan/ot_uart.c @@ -465,8 +465,23 @@ static uint64_t ot_uart_read(void *opaque, hwaddr addr, unsigned size) val32 |= (fifo8_num_used(&s->tx_fifo) & 0xffu) << R_FIFO_STATUS_TXLVL_SHIFT; break; - case R_OVRD: case R_VAL: + /* + * This is not trivially implemented due to the QEMU UART + * interface. There is no way to reliably sample or oversample + * given our emulated interface, but some software might poll the + * value of this register to determine break conditions. + * + * As such, and given that we always support RXIDLE, default + * to reporting 16 idle high samples (i.e. 0xFFFF) instead. + * This is still not ideal, but at least defaults to showing + * nothing (similar to SW waiting too long before polling) rather + * than essentially showing a break condition. + */ + val32 = R_VAL_RX_MASK; + qemu_log_mask(LOG_UNIMP, "%s: UART VAL always shows idle\n", __func__); + break; + case R_OVRD: case R_TIMEOUT_CTRL: val32 = s->regs[reg]; qemu_log_mask(LOG_UNIMP, "%s: %s is not supported\n", __func__,