diff options
author | Alistair Francis <alistair.francis@wdc.com> | 2024-08-15 10:57:28 +1000 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2024-10-30 11:22:08 +1000 |
commit | 53c1557b230986ab6320a58e1b2c26216ecd86d5 (patch) | |
tree | 9121bd92b12914638f9d03d7aab4cbba8d52429f /include/hw | |
parent | 4a0e8ca322d2a5ec9bdd9409cb02d4c08a07bef6 (diff) | |
download | qemu-53c1557b230986ab6320a58e1b2c26216ecd86d5.zip qemu-53c1557b230986ab6320a58e1b2c26216ecd86d5.tar.gz qemu-53c1557b230986ab6320a58e1b2c26216ecd86d5.tar.bz2 |
hw/char: sifive_uart: Print uart characters async
The current approach of using qemu_chr_fe_write() and ignoring the
return values results in dropped characters [1].
Let's update the SiFive UART to use a async sifive_uart_xmit() function
to transmit the characters and apply back pressure to the guest with
the SIFIVE_UART_TXFIFO_FULL status.
This should avoid dropped characters and more realisticly model the
hardware.
1: https://gitlab.com/qemu-project/qemu/-/issues/2114
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240910045419.1252277-3-alistair.francis@wdc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'include/hw')
-rw-r--r-- | include/hw/char/sifive_uart.h | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/include/hw/char/sifive_uart.h b/include/hw/char/sifive_uart.h index 7f6c79f..0846cf6 100644 --- a/include/hw/char/sifive_uart.h +++ b/include/hw/char/sifive_uart.h @@ -24,6 +24,7 @@ #include "hw/qdev-properties.h" #include "hw/sysbus.h" #include "qom/object.h" +#include "qemu/fifo8.h" enum { SIFIVE_UART_TXFIFO = 0, @@ -48,9 +49,13 @@ enum { SIFIVE_UART_IP_RXWM = 2 /* Receive watermark interrupt pending */ }; +#define SIFIVE_UART_TXFIFO_FULL 0x80000000 + #define SIFIVE_UART_GET_TXCNT(txctrl) ((txctrl >> 16) & 0x7) #define SIFIVE_UART_GET_RXCNT(rxctrl) ((rxctrl >> 16) & 0x7) + #define SIFIVE_UART_RX_FIFO_SIZE 8 +#define SIFIVE_UART_TX_FIFO_SIZE 8 #define TYPE_SIFIVE_UART "riscv.sifive.uart" OBJECT_DECLARE_SIMPLE_TYPE(SiFiveUARTState, SIFIVE_UART) @@ -63,13 +68,20 @@ struct SiFiveUARTState { qemu_irq irq; MemoryRegion mmio; CharBackend chr; - uint8_t rx_fifo[SIFIVE_UART_RX_FIFO_SIZE]; - uint8_t rx_fifo_len; + + uint32_t txfifo; uint32_t ie; uint32_t ip; uint32_t txctrl; uint32_t rxctrl; uint32_t div; + + uint8_t rx_fifo[SIFIVE_UART_RX_FIFO_SIZE]; + uint8_t rx_fifo_len; + + Fifo8 tx_fifo; + + QEMUTimer *fifo_trigger_handle; }; SiFiveUARTState *sifive_uart_create(MemoryRegion *address_space, hwaddr base, |