From: Marcelo Manzo <marcelomanzo@gmail.com>
To: qemu-devel@nongnu.org, qemu-arm@nongnu.org
Cc: "Peter Maydell" <peter.maydell@linaro.org>,
"Philippe Mathieu-Daudé" <philmd@oss.qualcomm.com>,
"Marcelo Manzo" <marcelomanzo@gmail.com>,
"Philippe Mathieu-Daudé" <philmd@mailo.com>
Subject: [PATCH v2 03/19] hw/arm/bcm2838: enable BCM2838 PCIe host bridge
Date: Tue, 11 Aug 2026 10:35:40 -0400 [thread overview]
Message-ID: <20260811143557.7862-4-marcelomanzo@gmail.com> (raw)
In-Reply-To: <20260811143557.7862-1-marcelomanzo@gmail.com>
Wire the BCM2838 PCIe host bridge into the SoC's peripheral block:
instantiate it, map its RC registers and MMIO window.
Per Peter Maydell's review of a later follow-up series, fold in the
remaining defect from what was originally a separate bugfix here,
since this device isn't in upstream git yet: the PCI MMIO window was
mapped at the ARM base address with no address translation, even
though PCIE_MMIO_OFFSET was defined for exactly that purpose (and
otherwise unused). The DTB declares CPU 0x600000000 as mapping to PCI
0xc0000000, so a guest would read PCI address 0 where it expected a
device BAR. Map an alias at the correct PCI offset instead.
Signed-off-by: Marcelo Manzo <marcelomanzo@gmail.com>
---
hw/arm/bcm2838.c | 9 +++++++
hw/arm/bcm2838_peripherals.c | 35 ++++++++++++++++++++++++++++
hw/arm/raspi4b.c | 1 -
include/hw/arm/bcm2838_peripherals.h | 3 +++
4 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/hw/arm/bcm2838.c b/hw/arm/bcm2838.c
index 089af412a3..fc56f87934 100644
--- a/hw/arm/bcm2838.c
+++ b/hw/arm/bcm2838.c
@@ -230,6 +230,15 @@ static void bcm2838_realize(DeviceState *dev, Error **errp)
qdev_connect_gpio_out(dma_9_10_irq_orgate, 0,
qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_DMA_9_10));
+ /* Connect PCIe host bridge to the interrupt controller */
+ for (int n = 0; n < BCM2838_PCIE_NUM_IRQS; n++) {
+ int int_n = GIC_SPI_INTERRUPT_PCI_INT_A + n;
+ sysbus_connect_irq(SYS_BUS_DEVICE(&ps->pcie_host), n,
+ qdev_get_gpio_in(gicdev, int_n));
+ bcm2838_pcie_host_set_irq_num(BCM2838_PCIE_HOST(&ps->pcie_host), n,
+ int_n);
+ }
+
/* Pass through inbound GPIO lines to the GIC */
qdev_init_gpio_in(dev, bcm2838_gic_set_irq, GIC_NUM_IRQS);
diff --git a/hw/arm/bcm2838_peripherals.c b/hw/arm/bcm2838_peripherals.c
index 812b5b8480..d923ba968a 100644
--- a/hw/arm/bcm2838_peripherals.c
+++ b/hw/arm/bcm2838_peripherals.c
@@ -15,6 +15,11 @@
#define CLOCK_ISP_OFFSET 0xc11000
#define CLOCK_ISP_SIZE 0x100
+#define PCIE_RC_OFFSET 0x1500000
+#define PCIE_MMIO_OFFSET 0xc0000000
+#define PCIE_MMIO_ARM_OFFSET 0x600000000
+#define PCIE_MMIO_SIZE 0x40000000
+
/* Lower peripheral base address on the VC (GPU) system bus */
#define BCM2838_VC_PERI_LOW_BASE 0x7c000000
@@ -35,6 +40,10 @@ static void bcm2838_peripherals_init(Object *obj)
/* Extended Mass Media Controller 2 */
object_initialize_child(obj, "emmc2", &s->emmc2, TYPE_SYSBUS_SDHCI);
+ /* PCIe Host Bridge */
+ object_initialize_child(obj, "pcie-host", &s->pcie_host,
+ TYPE_BCM2838_PCIE_HOST);
+
/* GPIO */
object_initialize_child(obj, "gpio", &s->gpio, TYPE_BCM2838_GPIO);
@@ -67,6 +76,8 @@ static void bcm2838_peripherals_realize(DeviceState *dev, Error **errp)
MemoryRegion *mphi_mr;
BCM2838PeripheralState *s = BCM2838_PERIPHERALS(dev);
BCMSocPeripheralBaseState *s_base = BCM_SOC_PERIPHERALS_BASE(dev);
+ MemoryRegion *regs_mr;
+ MemoryRegion *mmio_mr;
int n;
bcm_soc_peripherals_common_realize(dev, errp);
@@ -182,6 +193,30 @@ static void bcm2838_peripherals_realize(DeviceState *dev, Error **errp)
create_unimp(s_base, &s->clkisp, "bcm2835-clkisp", CLOCK_ISP_OFFSET,
CLOCK_ISP_SIZE);
+ /* PCIe Root Complex */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->pcie_host), errp)) {
+ return;
+ }
+ /* RC registers region */
+ regs_mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pcie_host), 0);
+ memory_region_add_subregion(&s->peri_low_mr, PCIE_RC_OFFSET, regs_mr);
+ /*
+ * MMIO region.
+ *
+ * The BCM2711 PCIe controller translates addresses between the ARM and
+ * PCI address spaces: the DTB declares CPU 0x600000000 as mapping to PCI
+ * 0xc0000000. Map an alias of the PCI window starting at that PCI offset
+ * so accesses land on the right addresses; mapping the window directly
+ * would expose PCI address 0 at the ARM base instead, and every BAR
+ * behind the root port would be read at the wrong address.
+ */
+ mmio_mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pcie_host), 1);
+ memory_region_init_alias(&s->pcie_mmio_alias, OBJECT(s),
+ "bcm2838_pcie_mmio_alias", mmio_mr,
+ PCIE_MMIO_OFFSET, PCIE_MMIO_SIZE);
+ memory_region_add_subregion(get_system_memory(), PCIE_MMIO_ARM_OFFSET,
+ &s->pcie_mmio_alias);
+
/* GPIO */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
return;
diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c
index 06aeb8db01..038eefb234 100644
--- a/hw/arm/raspi4b.c
+++ b/hw/arm/raspi4b.c
@@ -64,7 +64,6 @@ static void raspi4_modify_dtb(const struct arm_boot_info *info, void *fdt)
/* Temporarily disable following devices until they are implemented */
const char *nodes_to_remove[] = {
- "brcm,bcm2711-pcie",
"brcm,bcm2711-rng200",
"brcm,bcm2711-thermal",
"brcm,bcm2711-genet-v5",
diff --git a/include/hw/arm/bcm2838_peripherals.h b/include/hw/arm/bcm2838_peripherals.h
index 0be97e67c7..7fe92789e8 100644
--- a/include/hw/arm/bcm2838_peripherals.h
+++ b/include/hw/arm/bcm2838_peripherals.h
@@ -10,6 +10,7 @@
#define BCM2838_PERIPHERALS_H
#include "hw/arm/bcm2835_peripherals.h"
+#include "hw/arm/bcm2838_pcie.h"
#include "hw/sd/sdhci.h"
#include "hw/gpio/bcm2838_gpio.h"
@@ -65,6 +66,8 @@ struct BCM2838PeripheralState {
MemoryRegion mphi_mr_alias;
SDHCIState emmc2;
+ MemoryRegion pcie_mmio_alias;
+ BCM2838PcieHostState pcie_host;
BCM2838GpioState gpio;
OrIRQState mmc_irq_orgate;
--
2.47.1
next prev parent reply other threads:[~2026-08-11 14:36 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-11 14:35 [PATCH v2 00/19] hw/arm/raspi4b: working PCIe and GENET (real networking) Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 01/19] hw/arm/bcm2838_pcie: add BCM2838 PCIe Root Complex Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 02/19] hw/arm/bcm2838_pcie: add BCM2838 PCIe host Marcelo Manzo
2026-08-11 14:35 ` Marcelo Manzo [this message]
2026-08-11 14:35 ` [PATCH v2 04/19] hw/net/bcm2838_genet: add GENET stub device Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 05/19] hw/net/bcm2838_genet: add GENET register structs, part 1/4 Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 06/19] hw/net/bcm2838_genet: add GENET register structs, part 2/4 Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 07/19] hw/net/bcm2838_genet: add GENET register structs, part 3/4 Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 08/19] hw/net/bcm2838_genet: add GENET register structs, part 4/4 Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 09/19] hw/net/bcm2838_genet: add GENET register access macros Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 10/19] hw/net/bcm2838_genet: implement GENET register ops Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 11/19] hw/net/bcm2838_genet: implement GENET MDIO Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 12/19] hw/net/bcm2838_genet: implement GENET TX path Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 13/19] hw/net/bcm2838_genet: implement GENET RX path Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 14/19] hw/arm/bcm2838: enable BCM2838 GENET controller Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 15/19] hw/net/bcm2838_genet: fix PHY autonegotiation-restart deadlock Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 16/19] hw/net/bcm2838_genet: fix bogus RX checksum reporting Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 17/19] hw/net/bcm2838_genet: fix TX ring activation check Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 18/19] docs/system/arm/raspi: move PCIe/GENET from missing to implemented Marcelo Manzo
2026-08-11 14:35 ` [PATCH v2 19/19] tests/functional/aarch64: add raspi4b GENET networking test Marcelo Manzo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260811143557.7862-4-marcelomanzo@gmail.com \
--to=marcelomanzo@gmail.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@mailo.com \
--cc=philmd@oss.qualcomm.com \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox