From 74d7a213823eca265733630e2656ce502a3b5bfd Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Wed, 15 Oct 2025 09:12:05 -0500 Subject: [PATCH] nb/intel/haswell/acpi: Add missing MMIO window below 4GB For Broadwell SoC boards (which use Haswell's northbridge ACPI), coreboot's resource allocator identifies and uses two MMIO windows below 4GB, but currently only one is declared in the ACPI _CRS. Normally this isn't a problem, as coreboot is usually able to allocate resources entirely in the (declared) lower MMIO window. But, this is problematic when using top-down allocation, since coreboot assigns resources to devices starting in the (undeclared) upper MMIO window, which the OS does not consider a valid space. Linux will mostly handle this gracefully, and reassign BARs in the lower MMIO address space. Windows does not, and will simply mark any devices in the upper window as invalid or malfunctioning. To resolve this, add the dynamically-sized PM02 PCI MMIO window above MMCONF to match the region used by coreboot's allocator. With this change, both MMIO windows are properly reported via _CRS, allowing the OS to use coreboot's resource allocations properly. coreboot allocator: [INFO ] * Base: 80000000, Size: 70000000, Tag: 200 [Window 1: 1.75GB] [INFO ] * Base: f4000000, Size: a000000, Tag: 200 [Window 2: 160MB] kernel before: [mem 0x80000000-0xefffffff window] [PM01: 1.75GB] [mem 0xf4000000-0xfed44fff window] [TPM] kernel after: [mem 0x80000000-0xefffffff window] [PM01: 1.75GB] [mem 0xf4000000-0xfebfffff window] [PM02: 172MB] [mem 0xfed40000-0xfed44fff window] [TPM] BUG=https://ticket.coreboot.org/issues/611 TEST=Build/boot google/lulu with top-down allocation enabled. Verify kernel sees both MMIO windows and devices keep their coreboot- assigned BARs. Verify Windows boots with functional i2c devices. Change-Id: I83fa8ca7f9edfd7d185895f8bbff15ee9895d1ff Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/89588 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Angel Pons --- .../intel/haswell/acpi/hostbridge.asl | 46 ++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/northbridge/intel/haswell/acpi/hostbridge.asl b/src/northbridge/intel/haswell/acpi/hostbridge.asl index 3ecc5b3b36..509595b3b1 100644 --- a/src/northbridge/intel/haswell/acpi/hostbridge.asl +++ b/src/northbridge/intel/haswell/acpi/hostbridge.asl @@ -14,6 +14,12 @@ Device (MCHC) OperationRegion (MCHP, PCI_Config, 0x00, 0x100) Field (MCHP, DWordAcc, NoLock, Preserve) { + Offset (0x60), // PCIEXBAR + PXEN, 1, // Enable + PXSZ, 2, // PCIEXBAR size + , 23, + PXBR, 10, // PCIEXBAR base + Offset (0x70), // ME Base Address MEBA, 64, Offset (0xa0), // Top of Used Memory @@ -125,12 +131,18 @@ Name (MCRS, ResourceTemplate() 0x00000000, 0x000f0000, 0x000fffff, 0x00000000, 0x00010000,,, FSEG) - // PCI Memory Region (Top of memory-CONFIG_ECAM_MMCONF_BASE_ADDRESS) + // PCI Memory Region below MMCONF (TOLUD) DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,,, PM01) - +#if CONFIG(SOC_INTEL_BROADWELL) + // PCI Memory Region above MMCONF (dynamic, based on ECAM size) + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000,,, PM02) +#endif // TPM Area (0xfed40000-0xfed44fff) DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, @@ -164,6 +176,36 @@ Method (_CRS, 0, Serialized) PMAX = CONFIG_ECAM_MMCONF_BASE_ADDRESS - 1 PLEN = (PMAX - PMIN) + 1 +#if CONFIG(SOC_INTEL_BROADWELL) + // Set up PM02 region (MMCONF end to 0xFEBFFFFF) + CreateDwordField (MCRS, ^PM02._MIN, PM2B) + CreateDwordField (MCRS, ^PM02._MAX, PM2M) + CreateDwordField (MCRS, ^PM02._LEN, PM2L) + + // Calculate ECAM/MMCONF end address based on size bits in PCIEXBAR + // Bits [2:1] encode size: 00=256MB, 01=128MB, 10=64MB, 11=reserved + Local2 = ^MCHC.PXSZ + + // Populate based on ECAM size + If (Local2 == 0) { + // 256MB ECAM - no space for PM02 (would extend to 4GB boundary) + PM2L = 0 + } Else { + // 128MB or 64MB ECAM - there's space for PM02 + Local3 = CONFIG_ECAM_MMCONF_BASE_ADDRESS + If (Local2 == 1) { + // 128MB ECAM - ends at base + 0x08000000 + Local3 += 0x08000000 + } Else { + // 64MB ECAM (or reserved=3) - ends at base + 0x04000000 + Local3 += 0x04000000 + } + + PM2B = Local3 + PM2M = 0xFEBFFFFF // Just before chipset reserved (IOAPIC at 0xFEC00000) + PM2L = PM2M - PM2B + 1 + } +#endif Return (MCRS) }