summaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
authorNathaniel Graff2018-12-14 01:19:12 +0100
committerPalmer Dabbelt2018-12-20 21:08:43 +0100
commit40061ac0bc5bdfcfa1234dbf8e2a880fd9fc4c2e (patch)
tree3c7115f4b802338996e5925858f2fc8d145abe4c /hw
parentRISC-V: Enable second UART on sifive_e and sifive_u (diff)
downloadqemu-40061ac0bc5bdfcfa1234dbf8e2a880fd9fc4c2e.tar.gz
qemu-40061ac0bc5bdfcfa1234dbf8e2a880fd9fc4c2e.tar.xz
qemu-40061ac0bc5bdfcfa1234dbf8e2a880fd9fc4c2e.zip
sifive_uart: Implement interrupt pending register
The watermark bits are set in the interrupt pending register according to the configuration of txcnt and rxcnt in the txctrl and rxctrl registers. Since the UART TX does not implement a FIFO, the txwm bit is set as long as the TX watermark level is greater than zero. Signed-off-by: Nathaniel Graff <nathaniel.graff@sifive.com> Reviewed-by: Michael Clark <mjc@sifive.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
Diffstat (limited to 'hw')
-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: