The diff below fixes an issue with using the rpi4 with newer RaspberryPi firmware in combination with the EDK2-based UEFI firmware. The problem is that the EDK2-based firmware programs the outbound mmio window in a way that is incompatible with the device tree. There are multiple ways to fix this, but the diff below simply reprograms the window with the values from the device tree.
ok? Index: dev/fdt/bcm2711_pcie.c =================================================================== RCS file: /cvs/src/sys/dev/fdt/bcm2711_pcie.c,v retrieving revision 1.3 diff -u -p -r1.3 bcm2711_pcie.c --- dev/fdt/bcm2711_pcie.c 14 Jul 2020 15:42:19 -0000 1.3 +++ dev/fdt/bcm2711_pcie.c 17 Jan 2021 18:02:09 -0000 @@ -28,12 +28,18 @@ #include <dev/pci/pcidevs.h> #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> +#include <dev/pci/ppbreg.h> #include <dev/ofw/openfirm.h> #include <dev/ofw/fdt.h> -#define PCIE_EXT_CFG_DATA 0x8000 -#define PCIE_EXT_CFG_INDEX 0x9000 +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO 0x400c +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI 0x4010 +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT 0x4070 +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI 0x4080 +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI 0x4084 +#define PCIE_EXT_CFG_DATA 0x8000 +#define PCIE_EXT_CFG_INDEX 0x9000 #define HREAD4(sc, reg) \ (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) @@ -174,6 +180,31 @@ bcmpcie_attach(struct device *parent, st } free(ranges, M_TEMP, rangeslen); + + /* + * Reprogram the outbound window to match the configuration in + * the device tree. This is necessary since the EDK2-based + * UEFI firmware reprograms the window. + */ + for (i = 0; i < sc->sc_nranges; i++) { + if ((sc->sc_ranges[i].flags & 0x03000000) == 0x02000000) { + uint64_t cpu_base = sc->sc_ranges[i].phys_base; + uint64_t cpu_limit = sc->sc_ranges[i].phys_base + + sc->sc_ranges[i].size - 1; + + HWRITE4(sc, PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO, + sc->sc_ranges[i].pci_base); + HWRITE4(sc, PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI, + sc->sc_ranges[i].pci_base >> 32); + HWRITE4(sc, PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT, + (cpu_base & PPB_MEM_MASK) >> PPB_MEM_SHIFT | + (cpu_limit & PPB_MEM_MASK)); + HWRITE4(sc, PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI, + cpu_base >> 32); + HWRITE4(sc, PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI, + cpu_limit >> 32); + } + } printf("\n");