Hi Igor, Thanks for the review.
On Mon, 27 Jul 2026 11:06:15 +0200 Igor Mammedov <[email protected]> wrote: > I kind of dislike (basically riscv specific hack) in generic code. > well, correct way to tackle this is > 1: fix UEFI to perform required initialization. I agree this is not a clean solution, and I acknowledge the concern about putting riscv-specific behavior into the shared gpex code. I did try the "fix UEFI" direction first. With the current EDK2 (edk2-stable202602, the same FdtPciHostBridgeLib/PciBusDxe used by both aarch64 and riscv virt), I booted a riscv virt machine with pxb-cxl and dumped the ECAM config space after the firmware finished enumeration: - pxb-cxl (1b36:000b) on bus 0: class 0x0600 (host bridge), header type 0, memory/prefetchable window registers all zero; - cxl-rp on bus 12: memory window base > limit (empty, reset value); - cxl-type3 on bus 13: entire config space reads 0xffffffff, i.e. the firmware never enumerated behind the CXL host bridge. The root cause is that PciBusDxe only recurses into devices for which IS_PCI_BRIDGE() is true (header layout 1), while pxb-cxl presents header type 0 and class 0x0600, so the firmware neither assigns it a secondary bus number nor any MMIO window. FdtPciHostBridgeLib likewise only consumes the single "pci-host-ecam-generic" node describing PCI0 and has no knowledge of the expander bridge. As a result build_crs() genuinely returns an empty set on riscv today - this is not a timing artifact. > if you have to put a hack into QEMU, make it work with current build_crs() > and localize 'proper simulated initialization' in riscv codebase > (i.e. do not spread it to common codebase). But before doing it see (#1 not= e). Understood. Since #1 (a UEFI that performs the initialization) is not available on riscv at the moment, the static window is currently the only path that makes CXL host bridge _CRS usable here. For what it is worth, this is consistent with how CXL is being handled on the ARM side. The sbsa-ref enablement (Yuquan Wang, RFC up to v7, "hw/arm/sbsa-ref: Support CXL Host Bridge & CFMW" [1], plus the matching edk2-platforms RFC [2]) deliberately carves out exclusive static MMIO32/MMIO64 and bus-number ranges for the CXL host bridge and builds static ACPI tables, explicitly noting that it "doesn't need to communicate CXL contents via DT to edk2". Jonathan Cameron's arm/virt approach instead relies on EDK2 performing the enumeration and QEMU reading the result back via build_crs(), but that depends on a recent EDK2 with expander-bridge support that we do not have on riscv yet; his earlier DT-binding RFC for expander bridges [3] also notes that on the DT path QEMU has to allocate the windows itself. [1] https://lore.kernel.org/all/[email protected]/ [2] https://op-lists.linaro.org/archives/list/[email protected]/thread/EPPN4R6KLGKYLWPOZUBWJG5HCXAAO3SQ/ [3] https://lore.kernel.org/all/[email protected]/ Given that, my tentative plan for v3 is to keep the static-window approach for now but address your objection by localizing it: drop the cxl_mmio32 field and the is_cxl branch from the common gpex code, and instead simulate the initialization in riscv virt code so that the existing build_crs() path produces the correct _CRS (i.e. have riscv pre-populate the bridge window registers / range set the way a firmware would), keeping the common codebase untouched. Before I rework it that way, I would appreciate any suggestions you may have on this approach. Thanks, Pei
