Follow-up to "hw/arm/bcm2838_pcie: make PCI device enumeration actually
work" [1]. That series (plus the GENET/RNG200/thermal work before it)
got a real Raspberry Pi 4 SoC far enough to boot official, unmodified
Raspberry Pi OS releases end to end under raspi4b -- not just the
functional-test suite's minimal 2019-era kernel+initrd. Doing that
surfaced two further bugs that only show up with a modern distro's
systemd actually driving the hardware, both on paths the existing
tests don't exercise:
1. hw/misc/bcm2835_powermgt: the RSTC register's write-config bits
(0x30) being set to the "full reset" value (0x20) does not mean
"reset now" on real hardware -- it arms the watchdog so a reset
happens only if the WDOG countdown register is not refreshed
before it expires. QEMU's model treated any such RSTC write as an
immediate reset. This is dormant on lighter userspace, but
Debian 13/Trixie's systemd (257) writes to RSTC during routine
early-boot watchdog probing, causing an immediate spurious reset a
few seconds into boot. Combined with -no-reboot this looks exactly
like a QEMU crash from the outside: clean exit, no panic, no guest
reboot message, the last log line being the RSTC/WDOG write itself.
Fixed by actually implementing the watchdog as a QEMUTimer that
only fires -- and only then requests a reset/shutdown -- after the
real timeout computed from the WDOG register.
2. hw/net/bcm2838_genet: three related per-ring DMA bugs. RDMA_CTRL
writes never updated any per-ring status at all (only TDMA_CTRL
updated a single overall DISABLED bit); enabling a ring didn't
flush packets queued while it was disabled; and the RX fallback
path hardcoded the last/default ring with no check that it was
actually active. Bullseye and Bookworm's kernels default to that
last ring, so this was invisible with them, but Trixie's 6.18
kernel actively uses rings 0-4 and never enables the default ring,
so every unfiltered packet was silently dropped -- no DHCP lease,
no usable networking. Fixed by tracking a real per-ring enable
bitmask for both directions, flushing queued packets when a ring
is enabled, and falling back to scanning for the first actually-
active ring instead of assuming the last one.
Testing: rather than only the functional-test kernel, I booted three
official Raspberry Pi OS Lite arm64 releases end to end against the
patched raspi4b machine -- Bullseye (5.15.61-v8+), Bookworm
(6.12.25+rpt-rpi-v8), and Trixie (6.18.34+rpt-rpi-v8) -- each with a
clean boot (no crash/reboot loop), a DHCP lease obtained over GENET,
working SSH login, and an error log containing nothing beyond the
expected "hardware QEMU doesn't emulate" noise (VideoCore/VCHI,
camera/codec/audio probes, GPIO regulators, Bluetooth UART, EEPROM
check) on all three. Before patch 1, Trixie reset within seconds of
boot; before patch 2, Trixie booted but never got a network address.
Bullseye and Bookworm were unaffected either way, which is exactly
why these bugs went unnoticed until a newer kernel exercised these
specific paths.
I did not add a functional test for either fix: reliably triggering
them needs a real systemd doing real early-boot watchdog/network
setup, which the existing test kernel/initrd (a minimal 2019 busybox
environment) doesn't exercise, and downloading a full modern distro
image isn't practical for the functional-test asset infrastructure.
Happy to take suggestions on a lighter-weight way to cover this if
one exists.
checkpatch.pl is clean (0 errors, 0 warnings) on both patches, and the
series builds standalone from a clean worktree
(--target-list=aarch64-softmmu).
[1] https://patchwork.kernel.org/project/qemu-devel/cover/20260725124231.86233-1-marcelomanzo@gmail.com/
Marcelo Manzo (2):
hw/misc/bcm2835_powermgt: implement a real watchdog timer
hw/net/bcm2838_genet: fix per-ring DMA status and RX ring selection
hw/misc/bcm2835_powermgt.c | 49 +++++++++++++++++++++++-------
hw/net/bcm2838_genet.c | 24 +++++++++++++--
include/hw/misc/bcm2835_powermgt.h | 2 ++
include/hw/net/bcm2838_genet.h | 2 ++
4 files changed, 63 insertions(+), 14 deletions(-)
--
2.47.1