summaryrefslogtreecommitdiffstats
path: root/hw/riscv/sifive_uart.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/riscv/sifive_uart.c')
-rw-r--r--hw/riscv/sifive_uart.c24
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: