rust: pl011: Really use RX FIFO depth

While we model a 16-elements RX FIFO since the PL011 model was
introduced in commit cdbdb648b7 ("ARM Versatile Platform Baseboard
emulation"), we only read 1 char at a time!

Have can_receive() return how many elements are available, and use that
in receive().

This is the Rust version of commit 3e0f118f82 ("hw/char/pl011: Really
use RX FIFO depth"); but it also adds back a comment that is present
in commit f576e0733c ("hw/char/pl011: Add support for loopback") and
absent in the Rust code.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2025-05-08 10:29:43 +02:00
parent cc1f4b34d0
commit ac2c4d3aed
2 changed files with 14 additions and 7 deletions

View file

@ -119,7 +119,7 @@ QEMU includes four crates:
for the ``hw/char/pl011.c`` and ``hw/timer/hpet.c`` files. for the ``hw/char/pl011.c`` and ``hw/timer/hpet.c`` files.
.. [#issues] The ``pl011`` crate is synchronized with ``hw/char/pl011.c`` .. [#issues] The ``pl011`` crate is synchronized with ``hw/char/pl011.c``
as of commit 02b1f7f61928. The ``hpet`` crate is synchronized as of as of commit 3e0f118f82. The ``hpet`` crate is synchronized as of
commit 1433e38cc8. Both are lacking tracing functionality. commit 1433e38cc8. Both are lacking tracing functionality.
This section explains how to work with them. This section explains how to work with them.

View file

@ -580,19 +580,26 @@ impl PL011State {
fn can_receive(&self) -> u32 { fn can_receive(&self) -> u32 {
let regs = self.regs.borrow(); let regs = self.regs.borrow();
// trace_pl011_can_receive(s->lcr, s->read_count, r); // trace_pl011_can_receive(s->lcr, s->read_count, r);
u32::from(regs.read_count < regs.fifo_depth()) regs.fifo_depth() - regs.read_count
} }
fn receive(&self, buf: &[u8]) { fn receive(&self, buf: &[u8]) {
if buf.is_empty() { let mut regs = self.regs.borrow_mut();
if regs.loopback_enabled() {
// In loopback mode, the RX input signal is internally disconnected
// from the entire receiving logics; thus, all inputs are ignored,
// and BREAK detection on RX input signal is also not performed.
return; return;
} }
let mut regs = self.regs.borrow_mut();
let c: u32 = buf[0].into(); let mut update_irq = false;
let update_irq = !regs.loopback_enabled() && regs.fifo_rx_put(c.into()); for &c in buf {
let c: u32 = c.into();
update_irq |= regs.fifo_rx_put(c.into());
}
// Release the BqlRefCell before calling self.update() // Release the BqlRefCell before calling self.update()
drop(regs); drop(regs);
if update_irq { if update_irq {
self.update(); self.update();
} }