summary refs log tree commit diff stats
path: root/hw/char/sifive_uart.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2025-10-03 04:57:12 -0700
committerRichard Henderson <richard.henderson@linaro.org>2025-10-03 04:57:12 -0700
commit91f80dda70aeedeb78979b07ad2a0e5503f7dd47 (patch)
tree3ec229eb07158e34798e389d56506894d11e97ea /hw/char/sifive_uart.c
parent517e9b4862cc9798b7a24b1935d94c2f96787f12 (diff)
parentad2a0aa2824b1dac9f61bac33980e866e9a88856 (diff)
downloadfocaccia-qemu-91f80dda70aeedeb78979b07ad2a0e5503f7dd47.tar.gz
focaccia-qemu-91f80dda70aeedeb78979b07ad2a0e5503f7dd47.zip
Merge tag 'pull-riscv-to-apply-20251003-3' of https://github.com/alistair23/qemu into staging
First RISC-V PR for 10.2

* Fix MSI table size limit
* Add riscv64 to FirmwareArchitecture
* Sync RISC-V hwprobe with Linux
* Implement MonitorDef HMP API
* Update OpenSBI to v1.7
* Fix SiFive UART character drop issue and minor refactors
* Fix RISC-V timer migration issues
* Use riscv_cpu_is_32bit() when handling SBI_DBCN reg
* Use riscv_csrr in riscv_csr_read
* Align memory allocations to 2M on RISC-V
* Do not use translator_ldl in opcode_at
* Minor fixes of RISC-V CFI
* Modify minimum VLEN rule
* Fix vslide1[up|down].vx unexpected result when XLEN=32 and SEW=64
* Fixup IOMMU PDT Nested Walk
* Fix endianness swap on compressed instructions
* Update status of IOMMU kernel support

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCgAdFiEEaukCtqfKh31tZZKWr3yVEwxTgBMFAmjfQhoACgkQr3yVEwxT
# gBPnTg//eQ9GMFTLcW4kFMsVYeY8TbkmQN9Wnk+XubG92siGkzuNmfy36yo7oeib
# dB6/h5JLjycjttOfgyx73/TKUucyZs+ZYkVVWWQCSU+sqPTA370MmGNM8CSmPms/
# lFuNIixd+sSUDIOod9zQHzxv+f3ZN2bjEAyzJAEhSXgTO+1xnOeJHHjxB5O2Z/a1
# ccd3Po1wR6nm2T4x88LcHDHj8svLsfG0G1RRkU+yeLu7J6Qpp0d/lOZI7if+AQqb
# Nmz65n2uSuUEuNNQIxYaQp/nbkF3DSxi3mg3+hCQjF+hMjXL4hAhSEPril3MQjGi
# 802nEaqG8Qdzec+bZiKt0c3e0f4SrnpDXDnz7NrtfSO6vXAvqqZuC8kTdZy8dsPU
# 1D809ksZoNDIB87z89MQPsQ7k1Bs2Iq9pNpB9huD3mzY4DHqYhkzysAwc8Qhvimv
# pBaeSDV66OrI/al5c0FqSN0LiLHvlRcwqiATiQwIdCV+PUe+cVPwIKq6ABQiYpVu
# mvnzgEJ4r7iO92hOoAGM+eRC7krafF1/gbe3SDI3RLUTDPM6hcTRcluvBlpBdNDj
# lIYXs89f0jBh0I4IRGm8ftqD9xPDP56mZVEIIjSWDRTT6mfZLxWWMmXC/OK63U7/
# bpJKohFOKy8P6SSvTACcLSOQlP3r+FRrmBOXs7S24U+Hr9xUep0=
# =DGkt
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 02 Oct 2025 08:25:14 PM PDT
# gpg:                using RSA key 6AE902B6A7CA877D6D659296AF7C95130C538013
# gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 6AE9 02B6 A7CA 877D 6D65  9296 AF7C 9513 0C53 8013

* tag 'pull-riscv-to-apply-20251003-3' of https://github.com/alistair23/qemu: (26 commits)
  docs: riscv-iommu: Update status of kernel support
  target/riscv: Fix endianness swap on compressed instructions
  hw/riscv/riscv-iommu: Fixup PDT Nested Walk
  target/riscv: rvv: Fix vslide1[up|down].vx unexpected result when XLEN=32 and SEW=64
  target/riscv: rvv: Modify minimum VLEN according to enabled vector extensions
  target/riscv: rvv: Replace checking V by checking Zve32x
  target/riscv: Fix ssamoswap error handling
  target/riscv: Fix SSP CSR error handling in VU/VS mode
  target/riscv: Fix the mepc when sspopchk triggers the exception
  target/riscv: do not use translator_ldl in opcode_at
  qemu/osdep: align memory allocations to 2M on RISC-V
  target/riscv: use riscv_csrr in riscv_csr_read
  target/riscv/kvm: Use riscv_cpu_is_32bit() when handling SBI_DBCN reg
  target/riscv: Save stimer and vstimer in CPU vmstate
  hw/intc: Save timers array in RISC-V mtimer VMState
  migration: Add support for a variable-length array of UINT32 pointers
  hw/intc: Save time_delta in RISC-V mtimer VMState
  hw/char: sifive_uart: Add newline to error message
  hw/char: sifive_uart: Remove outdated comment about Tx FIFO
  hw/char: sifive_uart: Avoid pushing Tx FIFO when size is zero
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw/char/sifive_uart.c')
-rw-r--r--hw/char/sifive_uart.c36
1 files changed, 16 insertions, 20 deletions
diff --git a/hw/char/sifive_uart.c b/hw/char/sifive_uart.c
index 9bc697a67b..e7357d585a 100644
--- a/hw/char/sifive_uart.c
+++ b/hw/char/sifive_uart.c
@@ -28,23 +28,18 @@
 
 #define TX_INTERRUPT_TRIGGER_DELAY_NS 100
 
-/*
- * Not yet implemented:
- *
- * Transmit FIFO using "qemu/fifo8.h"
- */
-
 /* Returns the state of the IP (interrupt pending) register */
-static uint64_t sifive_uart_ip(SiFiveUARTState *s)
+static uint32_t sifive_uart_ip(SiFiveUARTState *s)
 {
-    uint64_t ret = 0;
+    uint32_t ret = 0;
 
-    uint64_t txcnt = SIFIVE_UART_GET_TXCNT(s->txctrl);
-    uint64_t rxcnt = SIFIVE_UART_GET_RXCNT(s->rxctrl);
+    uint32_t txcnt = SIFIVE_UART_GET_TXCNT(s->txctrl);
+    uint32_t rxcnt = SIFIVE_UART_GET_RXCNT(s->rxctrl);
 
-    if (txcnt != 0) {
+    if (fifo8_num_used(&s->tx_fifo) < txcnt) {
         ret |= SIFIVE_UART_IP_TXWM;
     }
+
     if (s->rx_fifo_len > rxcnt) {
         ret |= SIFIVE_UART_IP_RXWM;
     }
@@ -55,15 +50,14 @@ static uint64_t sifive_uart_ip(SiFiveUARTState *s)
 static void sifive_uart_update_irq(SiFiveUARTState *s)
 {
     int cond = 0;
-    if ((s->ie & SIFIVE_UART_IE_TXWM) ||
-        ((s->ie & SIFIVE_UART_IE_RXWM) && s->rx_fifo_len)) {
+    uint32_t ip = sifive_uart_ip(s);
+
+    if (((ip & SIFIVE_UART_IP_TXWM) && (s->ie & SIFIVE_UART_IE_TXWM)) ||
+        ((ip & SIFIVE_UART_IP_RXWM) && (s->ie & SIFIVE_UART_IE_RXWM))) {
         cond = 1;
     }
-    if (cond) {
-        qemu_irq_raise(s->irq);
-    } else {
-        qemu_irq_lower(s->irq);
-    }
+
+    qemu_set_irq(s->irq, cond);
 }
 
 static gboolean sifive_uart_xmit(void *do_not_use, GIOCondition cond,
@@ -119,10 +113,12 @@ static void sifive_uart_write_tx_fifo(SiFiveUARTState *s, const uint8_t *buf,
 
     if (size > fifo8_num_free(&s->tx_fifo)) {
         size = fifo8_num_free(&s->tx_fifo);
-        qemu_log_mask(LOG_GUEST_ERROR, "sifive_uart: TX FIFO overflow");
+        qemu_log_mask(LOG_GUEST_ERROR, "sifive_uart: TX FIFO overflow.\n");
     }
 
-    fifo8_push_all(&s->tx_fifo, buf, size);
+    if (size > 0) {
+        fifo8_push_all(&s->tx_fifo, buf, size);
+    }
 
     if (fifo8_is_full(&s->tx_fifo)) {
         s->txfifo |= SIFIVE_UART_TXFIFO_FULL;