summaryrefslogtreecommitdiff
path: root/src/soc
diff options
context:
space:
mode:
authorFelix Held <felix-coreboot@felixheld.de>2023-01-31 02:24:27 +0100
committerFelix Held <felix-coreboot@felixheld.de>2023-06-07 00:15:17 +0000
commit784c9c693fd2398e4283bdcd8051a027268238e0 (patch)
tree96a3916b2db3d9a031df3d3ca108432d2bb14862 /src/soc
parent7a5dd781d147d1f119290f258f6897fffba417dd (diff)
soc/amd/picasso/chip: use common data fabric domain resource code
Use amd_pci_domain_read_resources function that gets the configured MMIO regions for the PCI root domain from the data fabric's MMIO decode registers instead of using pci_domain_read_resources. This results in the same IO port range being used by the allocator, but makes sure that the allocator will only allocate non-fixed MMIO resources in the address ranges that get decoded to the PCI root complex. In order for the PCI0 _CRS ACPI resource template to match the decoded PCI root domain MMIO windows, use amd_pci_domain_fill_ssdt to generate the _CRS ACPI code instead of having a mostly hard-coded _CRS method in the DSDT. This makes sure that the OS will know about the MMIO regions it is allowed to used. Before this patch, only the region from TOM1 to right below CONFIG_ECAM_MMCONF_BASE_ADDRESS was advertised as usable PCI MMIO in the PCI0 _CRS method. Also the resource allocator didn't get any constraint on which address ranges it can use to put the non-fixed MMIO resources. This approach worked until now, since all address range from 0 up to right below TOM1 was filled with either usable or reserved memory and the allocator was allocating beginning right from TOM1, since it was using the bottom-up allocation approach and everything below TOM1 was already in use. The MMIO region from TOM1 to right below CONFIG_ECAM_MMCONF_BASE_ADDRESS also matched the MMIO decode window configured in the data fabric's MMIO decode registers, so everything seemed to work fine. However, when either selecting RESOURCE_ALLOCATION_TOP_DOWN or enabling above 4GB MMIO, things broke badly. This was partially due to the allocator putting non-fixed MMIO resources in regions that weren't decoded to the PCI root, since AMD family 17h and 19h silicon doesn't subtractively decode PCI MMIO and the wrong ranges the allocator used also weren't advertised in ACPI. TEST=Even when selecting RESOURCE_ALLOCATION_TOP_DOWN that usually ends up with a non-working system when the MMIO ranges aren't reported correctly to the resource allocator due to the reasons descried above, Ubuntu 22.04 LTS still boots on Mandolin both with SeaBIOS and EDK2 payload and Windows 10 boots with EDK payload. There's however an EDK2 bug that results the MMCONFIG region not being advertised in the e820 table, which causes Linux to not use the MMCONFIG and fall back to the legacy PCI config access method. This only happens with EDK2 payload and everything works fine when using SeaBIOS as payload. That e820 issue is unaffected by this patch. At the end of the data_fabric_set_mmio_np call, this is the data fabric MMIO register configuration: === Data Fabric MMIO configuration registers === idx base limit control R W NP F-ID 0 fc000000 febfffff 93 x x 9 1 10000000000 ffffffffffff 93 x x 9 2 d0000000 f7ffffff 93 x x 9 3 fed00000 fedfffff 1093 x x x 9 4 0 ffff 90 9 5 0 ffff 90 9 6 0 ffff 90 9 7 0 ffff 90 9 The limit of the data fabric MMIO decode register 1 is configured as 0xffffffffffff although this is way beyond the addressable memory space. add_data_fabric_mmio_regions fixes this up, so the range that gets passed to the allocator in that case is 0x7fcffffffff which takes both the reserved most significant address bits used for the memory encryption and the 12GB reserved data fabric MMIO at the top of the usable address space into account. This results in the following domain ranges passed to the resource allocator: DOMAIN: 0000 io: base: 0 size: 0 align: 0 gran: 0 limit: ffff done DOMAIN: 0000 mem: base: fc000000 size: 0 align: 0 gran: 0 limit: febfffff DOMAIN: 0000 mem: base: 10000000000 size: 0 align: 0 gran: 0 limit: 7fcffffffff DOMAIN: 0000 mem: base: d0000000 size: 0 align: 0 gran: 0 limit: f7ffffff The IO resource producer region is split into two parts to not cover the PCI config IO region resource consumer. This results in these resources being added to the PCI0 _CRS resource template: amd_pci_domain_fill_ssdt ACPI scope: '\_SB.PCI0' PCI0 _CRS: adding busses [0-3f] PCI0 _CRS: adding IO range [0-cf7] PCI0 _CRS: adding IO range [d00-ffff] PCI0 _CRS: adding MMIO range [fc000000-febfffff] PCI0 _CRS: adding MMIO range [10000000000-7fcffffffff] PCI0 _CRS: adding MMIO range [d0000000-f7ffffff] PCI0 _CRS: adding VGA resource Kernel version 5.15.0-43 from Ubuntu 2022.4 LTS prints this in dmesg: PCI host bridge to bus 0000:00 pci_bus 0000:00: root bus resource [bus 00-3f] pci_bus 0000:00: root bus resource [io 0x0000-0x0cf7 window] pci_bus 0000:00: root bus resource [io 0x0d00-0xffff window] pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff window] pci_bus 0000:00: root bus resource [mem 0xd0000000-0xf7ffffff window] pci_bus 0000:00: root bus resource [mem 0xfc000000-0xfebfffff window] pci_bus 0000:00: root bus resource [mem 0x10000000000-0x7fcffffffff window] Another noteworthy thing I wasn't aware of at first when testing ACPI changes on Windows 10 is that a normal Windows shutdown and boot cycle won't result in it processing the changed ACPI tables; you have to tell it to reboot to do a proper full boot where it will process the updated ACPI tables (and fail if it dislikes something about the ACPI tables and bytecode). Signed-off-by: Felix Held <felix-coreboot@felixheld.de> Change-Id: Ia24930ec2a9962dd15e874e9defea441cffae9f2 Reviewed-on: https://review.coreboot.org/c/coreboot/+/74712 Reviewed-by: Raul Rangel <rrangel@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Diffstat (limited to 'src/soc')
-rw-r--r--src/soc/amd/picasso/Kconfig1
-rw-r--r--src/soc/amd/picasso/acpi/northbridge.asl2
-rw-r--r--src/soc/amd/picasso/acpi/sb_pci0_fch.asl73
-rw-r--r--src/soc/amd/picasso/chip.c9
-rw-r--r--src/soc/amd/picasso/root_complex.c1
5 files changed, 6 insertions, 80 deletions
diff --git a/src/soc/amd/picasso/Kconfig b/src/soc/amd/picasso/Kconfig
index 11410ae91f..9738d19149 100644
--- a/src/soc/amd/picasso/Kconfig
+++ b/src/soc/amd/picasso/Kconfig
@@ -38,6 +38,7 @@ config SOC_AMD_PICASSO
select SOC_AMD_COMMON_BLOCK_BANKED_GPIOS
select SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM17H_19H
select SOC_AMD_COMMON_BLOCK_DATA_FABRIC
+ select SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN
select SOC_AMD_COMMON_BLOCK_GRAPHICS
select SOC_AMD_COMMON_BLOCK_HAS_ESPI
select SOC_AMD_COMMON_BLOCK_HDA
diff --git a/src/soc/amd/picasso/acpi/northbridge.asl b/src/soc/amd/picasso/acpi/northbridge.asl
index 99d04b5ba6..688f138123 100644
--- a/src/soc/amd/picasso/acpi/northbridge.asl
+++ b/src/soc/amd/picasso/acpi/northbridge.asl
@@ -1,8 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Note: Only need HID on Primary Bus */
-External (TOM1)
-External (TOM2)
Name(_HID, EISAID("PNP0A08")) /* PCI Express Root Bridge */
Name(_CID, EISAID("PNP0A03")) /* PCI Root Bridge */
diff --git a/src/soc/amd/picasso/acpi/sb_pci0_fch.asl b/src/soc/amd/picasso/acpi/sb_pci0_fch.asl
index 1f2c0d9310..898914cddf 100644
--- a/src/soc/amd/picasso/acpi/sb_pci0_fch.asl
+++ b/src/soc/amd/picasso/acpi/sb_pci0_fch.asl
@@ -1,7 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-#include <arch/ioapic.h>
-
/* System Bus */
/* _SB.PCI0 */
@@ -23,74 +21,3 @@ Method(_OSC,4)
/* 0:14.3 - LPC */
#include <soc/amd/common/acpi/lpc.asl>
#include <soc/amd/common/acpi/platform.asl>
-
-Name(CRES, ResourceTemplate() {
- /* Set the Bus number and Secondary Bus number for the PCI0 device
- * The Secondary bus range for PCI0 lets the system
- * know what bus values are allowed on the downstream
- * side of this PCI bus if there is a PCI-PCI bridge.
- * PCI buses can have 256 secondary buses which
- * range from [0-0xFF] but they do not need to be
- * sequential.
- */
- WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
- 0x0000, /* address granularity */
- 0x0000, /* range minimum */
- 0x00ff, /* range maximum */
- 0x0000, /* translation */
- 0x0100, /* length */
- ,, PSB0) /* ResourceSourceIndex, ResourceSource, DescriptorName */
-
- IO(Decode16, 0x0cf8, 0x0cf8, 1, 8)
-
- WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
- 0x0000, /* address granularity */
- 0x0000, /* range minimum */
- 0x0cf7, /* range maximum */
- 0x0000, /* translation */
- 0x0cf8 /* length */
- )
-
- WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
- 0x0000, /* address granularity */
- 0x0d00, /* range minimum */
- 0xffff, /* range maximum */
- 0x0000, /* translation */
- 0xf300 /* length */
- )
-
- /* VGA memory (0xa0000-0xbffff) */
- DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
- Cacheable, ReadWrite,
- 0x00000000, 0x000a0000, 0x000bffff, 0x00000000,
- 0x00020000)
- DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
- Cacheable, ReadOnly,
- 0x00000000, 0x000c0000, 0x000dffff, 0x00000000,
- 0x00020000)
-
- /* memory space for PCI BARs below 4GB */
- DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
- NonCacheable, ReadWrite,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000,,, PM01)
-}) /* End Name(_SB.PCI0.CRES) */
-
-Method(_CRS, 0) {
- /* Find PCI resource area in CRES */
- CreateDwordField (CRES, ^PM01._MIN, P1MN)
- CreateDwordField (CRES, ^PM01._MAX, P1MX)
- CreateDwordField (CRES, ^PM01._LEN, P1LN)
-
- /* Declare memory between TOM1 and MMCONF as available for PCI MMIO. */
- P1MN = TOM1
- P1MX = CONFIG_ECAM_MMCONF_BASE_ADDRESS - 1
- P1LN = P1MX - P1MN + 1
-
- CreateWordField(CRES, ^PSB0._MAX, BMAX)
- CreateWordField(CRES, ^PSB0._LEN, BLEN)
- BMAX = CONFIG_ECAM_MMCONF_BUS_NUMBER - 1
- BLEN = CONFIG_ECAM_MMCONF_BUS_NUMBER
-
- Return(CRES) /* note to change the Name buffer */
-} /* end of Method(_SB.PCI0._CRS) */
diff --git a/src/soc/amd/picasso/chip.c b/src/soc/amd/picasso/chip.c
index 782c1c3a6e..067c4a0734 100644
--- a/src/soc/amd/picasso/chip.c
+++ b/src/soc/amd/picasso/chip.c
@@ -27,10 +27,11 @@ static const char *soc_acpi_name(const struct device *dev)
};
struct device_operations picasso_pci_domain_ops = {
- .read_resources = pci_domain_read_resources,
- .set_resources = pci_domain_set_resources,
- .scan_bus = pci_domain_scan_bus,
- .acpi_name = soc_acpi_name,
+ .read_resources = amd_pci_domain_read_resources,
+ .set_resources = pci_domain_set_resources,
+ .scan_bus = amd_pci_domain_scan_bus,
+ .acpi_name = soc_acpi_name,
+ .acpi_fill_ssdt = amd_pci_domain_fill_ssdt,
};
static void soc_init(void *chip_info)
diff --git a/src/soc/amd/picasso/root_complex.c b/src/soc/amd/picasso/root_complex.c
index 65021a3f55..7a83197f51 100644
--- a/src/soc/amd/picasso/root_complex.c
+++ b/src/soc/amd/picasso/root_complex.c
@@ -196,7 +196,6 @@ static void acipgen_dptci(void)
static void root_complex_fill_ssdt(const struct device *device)
{
- acpi_fill_root_complex_tom(device);
if (CONFIG(SOC_AMD_COMMON_BLOCK_ACPI_DPTC))
acipgen_dptci();
}