All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] hw/arm/bcm2838_pcie: make PCI device enumeration work
@ 2026-07-25 12:42 Marcelo Manzo
  2026-07-25 12:42 ` [PATCH 1/2] hw/arm/bcm2838_pcie: make PCI device enumeration actually work Marcelo Manzo
  2026-07-25 12:42 ` [PATCH 2/2] tests/functional/aarch64: add raspi4b PCIe enumeration test Marcelo Manzo
  0 siblings, 2 replies; 3+ messages in thread
From: Marcelo Manzo @ 2026-07-25 12:42 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-arm, Peter Maydell, Philippe Mathieu-Daudé,
	Marcelo Manzo

Follow-up to "hw/arm/raspi4b: working PCIe and GENET (real
networking)" [1]. That series got the PCIe Root Complex link up and
GENET (a plain sysbus device, not PCI) working, but nothing in it
actually required a guest to enumerate a device *on* the PCIe bus --
so a real gap went unnoticed until now: attach anything to
raspi4b's PCIe port and "lspci"/"/sys/bus/pci/devices/" come back
completely empty, even though the link itself is up.

Root causes, all on the same host-bridge config-space path in
hw/arm/bcm2838_pcie.c:

 1. bcm2838_pcie_host_read/write computed
    "offset - PCIE_CONFIG_SPACE_SIZE" on an unsigned hwaddr, which
    underflows for every offset below 4KB -- i.e. the root port's own
    config space, including vendor/device ID at offset 0. Every such
    access fell into the "out of range" branch and read back as
    all-ones ("no device present"), so the guest's PCI core gave up
    immediately.

 2. pcie_host_mmcfg_init() was never called, even though both
    accessors dereference the MemoryRegion it sets up to service
    EXT_CFG_DATA. Fixing (1) let the guest reach that path for the
    first time, which then dereferenced an uninitialised region.

 3. The root port overrode PCIDeviceClass::config_read/config_write
    with plain pci_default_*_config(), bypassing
    pci_bridge_write_config(). Bridge memory windows were therefore
    never actually programmed, so BARs behind the root port stayed
    unreachable however the guest wrote them.

 4. PCIE_MMIO_OFFSET (0xc0000000) was defined in
    hw/arm/bcm2838_peripherals.c for exactly this purpose and never
    used -- grep count of 1, the definition itself. The PCI MMIO
    window was mapped straight onto the ARM address with no
    translation, even though the DTB declares CPU 0x600000000 as
    mapping to PCI 0xc0000000. The guest ended up reading PCI address
    0 where a device's BAR should have been.

Patch 1 fixes all four. I want to flag why they're one patch rather
than four: I tried splitting them during development, and every
subset short of all four either changes nothing (dormant bug) or
produces a kernel panic that doesn't happen on unfixed master (wrong
BAR content, alignment fault in a driver's MMIO access) -- worse
than the current silent "no devices enumerated". None of the four
are a coherent, independently-safe change on their own.

With all four, a PCIe device is enumerated and its driver binds:

  xhci_hcd 0000:01:00.0: xHCI Host Controller
  xhci_hcd 0000:01:00.0: new USB bus registered, assigned bus number 1
  xhci_hcd 0000:01:00.0: Host supports USB 3.0 SuperSpeed

This is not a complete PCIe implementation. The BCM2711's own MSI
controller is not implemented -- the guest driver programs it
correctly (visible as BRCM STB PCIe MSI vectors in
/proc/interrupts, permanently at 0 count) but QEMU never delivers
anything, so a device that only signals via MSI/MSI-X never actually
gets its interrupt. INTx works. Patch 1 documents this in
docs/system/arm/raspi.rst; patch 2's functional test attaches its
xHCI controller with "msi=off,msix=off" for the same reason. I
plan to look at the MSI controller separately; wanted this
enumeration fix to stand on its own rather than block on it, since it
already turns "no PCI device is usable at all" into "PCI devices
using INTx work".

Tested against real hardware, not just the emulated xHCI: with a USB
serial device passed through to the guest via QEMU's usb-serial
device pointed at the real /dev/cu.usbmodem* port, a real serial
peripheral connected to my Mac was reachable from inside the guest,
byte-for-byte identical to reading it directly on the host.

checkpatch.pl is clean (0 errors, 0 warnings) across both patches.
All 4 tests in tests/functional/aarch64/test_raspi4.py pass,
including the 3 pre-existing ones (no regression) and the new one
added here.

[1] https://patchwork.kernel.org/project/qemu-devel/cover/20260725004219.66222-1-marcelomanzo@gmail.com/

Marcelo Manzo (2):
  hw/arm/bcm2838_pcie: make PCI device enumeration actually work
  tests/functional/aarch64: add raspi4b PCIe enumeration test

 docs/system/arm/raspi.rst               |  2 ++
 hw/arm/bcm2838_pcie.c                   | 45 +++++++++++++++----------
 hw/arm/bcm2838_peripherals.c            | 16 +++++++--
 include/hw/arm/bcm2838_peripherals.h    |  1 +
 tests/functional/aarch64/test_raspi4.py | 37 ++++++++++++++++++++
 5 files changed, 82 insertions(+), 19 deletions(-)

-- 
2.47.1



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-07-25 12:43 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-25 12:42 [PATCH 0/2] hw/arm/bcm2838_pcie: make PCI device enumeration work Marcelo Manzo
2026-07-25 12:42 ` [PATCH 1/2] hw/arm/bcm2838_pcie: make PCI device enumeration actually work Marcelo Manzo
2026-07-25 12:42 ` [PATCH 2/2] tests/functional/aarch64: add raspi4b PCIe enumeration test Marcelo Manzo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.