diff options
Diffstat (limited to 'hw/riscv/sifive_uart.c')
-rw-r--r-- | hw/riscv/sifive_uart.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/hw/riscv/sifive_uart.c b/hw/riscv/sifive_uart.c index b0c3798cf2..456a3d3697 100644 --- a/hw/riscv/sifive_uart.c +++ b/hw/riscv/sifive_uart.c @@ -28,12 +28,26 @@ * Not yet implemented: * * Transmit FIFO using "qemu/fifo8.h" - * SIFIVE_UART_IE_TXWM interrupts - * SIFIVE_UART_IE_RXWM interrupts must honor fifo watermark - * Rx FIFO watermark interrupt trigger threshold - * Tx FIFO watermark interrupt trigger threshold. */ +/* Returns the state of the IP (interrupt pending) register */ +static uint64_t uart_ip(SiFiveUARTState *s) +{ + uint64_t ret = 0; + + uint64_t txcnt = SIFIVE_UART_GET_TXCNT(s->txctrl); + uint64_t rxcnt = SIFIVE_UART_GET_RXCNT(s->rxctrl); + + if (txcnt != 0) { + ret |= SIFIVE_UART_IP_TXWM; + } + if (s->rx_fifo_len > rxcnt) { + ret |= SIFIVE_UART_IP_RXWM; + } + + return ret; +} + static void update_irq(SiFiveUARTState *s) { int cond = 0; @@ -69,7 +83,7 @@ uart_read(void *opaque, hwaddr addr, unsigned int size) case SIFIVE_UART_IE: return s->ie; case SIFIVE_UART_IP: - return s->rx_fifo_len ? SIFIVE_UART_IP_RXWM : 0; + return uart_ip(s); case SIFIVE_UART_TXCTRL: return s->txctrl; case SIFIVE_UART_RXCTRL: |