soc/intel/*: Use SSDT to pass A4GB and A4GS

GNVS is more fragile as you need to keep struct elements in sync with
ASL code.

Change-Id: I2cd5e6b56e4a0dbbb11f4a0ac97e8f84d53b90ec
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/64216
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Reviewed-by: Subrata Banik <subratabanik@google.com>
diff --git a/src/soc/intel/alderlake/acpi.c b/src/soc/intel/alderlake/acpi.c
index 39897e7a..634f3f0 100644
--- a/src/soc/intel/alderlake/acpi.c
+++ b/src/soc/intel/alderlake/acpi.c
@@ -445,9 +445,6 @@
 	/* Set USB2/USB3 wake enable bitmaps. */
 	gnvs->u2we = config->usb2_wake_enable_bitmap;
 	gnvs->u3we = config->usb3_wake_enable_bitmap;
-
-	/* Fill in Above 4GB MMIO resource */
-	sa_fill_gnvs(gnvs);
 }
 
 int soc_madt_sci_irq_polarity(int sci)
diff --git a/src/soc/intel/alderlake/chip.c b/src/soc/intel/alderlake/chip.c
index 59f0066..6bb55ac 100644
--- a/src/soc/intel/alderlake/chip.c
+++ b/src/soc/intel/alderlake/chip.c
@@ -11,6 +11,7 @@
 #include <intelblocks/irq.h>
 #include <intelblocks/itss.h>
 #include <intelblocks/pcie_rp.h>
+#include <intelblocks/systemagent.h>
 #include <intelblocks/xdci.h>
 #include <soc/intel/common/vbt.h>
 #include <soc/itss.h>
@@ -188,6 +189,7 @@
 	.scan_bus         = &pci_domain_scan_bus,
 #if CONFIG(HAVE_ACPI_TABLES)
 	.acpi_name        = &soc_acpi_name,
+	.acpi_fill_ssdt   = ssdt_set_above_4g_pci,
 #endif
 };
 
diff --git a/src/soc/intel/apollolake/acpi.c b/src/soc/intel/apollolake/acpi.c
index 0e60771..e0e6163 100644
--- a/src/soc/intel/apollolake/acpi.c
+++ b/src/soc/intel/apollolake/acpi.c
@@ -86,9 +86,6 @@
 		gnvs->scdp = gpio_get_pad_portid(cfg->sdcard_cd_gpio);
 		gnvs->scdo = gpio_acpi_pin(cfg->sdcard_cd_gpio);
 	}
-
-	/* Fill in Above 4GB MMIO resource */
-	sa_fill_gnvs(gnvs);
 }
 
 int soc_madt_sci_irq_polarity(int sci)
diff --git a/src/soc/intel/apollolake/acpi/globalnvs.asl b/src/soc/intel/apollolake/acpi/globalnvs.asl
index 41f2409..a56d2e1 100644
--- a/src/soc/intel/apollolake/acpi/globalnvs.asl
+++ b/src/soc/intel/apollolake/acpi/globalnvs.asl
@@ -23,6 +23,4 @@
 	SCDP,	8,      // 0x29 - SD_CD GPIO portid
 	SCDO,	8,      // 0x2A - GPIO pad offset relative to the community
 	UIOR,	8,      // 0x2B - UART debug controller init on S3 resume
-	A4GB,	64,	// 0x2C - 0x33 Base of above 4GB MMIO Resource
-	A4GS,	64,	// 0x34 - 0x3B Length of above 4GB MMIO Resource
 }
diff --git a/src/soc/intel/apollolake/acpi/northbridge.asl b/src/soc/intel/apollolake/acpi/northbridge.asl
index b05dc56..f8023be 100644
--- a/src/soc/intel/apollolake/acpi/northbridge.asl
+++ b/src/soc/intel/apollolake/acpi/northbridge.asl
@@ -22,6 +22,9 @@
 	}
 }
 
+External (A4GS, IntObj)
+External (A4GB, IntObj)
+
 /* Current Resource Settings */
 Method (_CRS, 0, Serialized)
 {
diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c
index c98d1c4..0228cd2 100644
--- a/src/soc/intel/apollolake/chip.c
+++ b/src/soc/intel/apollolake/chip.c
@@ -22,6 +22,7 @@
 #include <intelblocks/gpio.h>
 #include <intelblocks/itss.h>
 #include <intelblocks/pmclib.h>
+#include <intelblocks/systemagent.h>
 #include <option.h>
 #include <soc/cpu.h>
 #include <soc/heci.h>
@@ -202,6 +203,7 @@
 	.set_resources = pci_domain_set_resources,
 	.scan_bus = pci_domain_scan_bus,
 	.acpi_name = &soc_acpi_name,
+	.acpi_fill_ssdt = ssdt_set_above_4g_pci,
 };
 
 static struct device_operations cpu_bus_ops = {
diff --git a/src/soc/intel/apollolake/include/soc/nvs.h b/src/soc/intel/apollolake/include/soc/nvs.h
index a9e0230..95d9ab4 100644
--- a/src/soc/intel/apollolake/include/soc/nvs.h
+++ b/src/soc/intel/apollolake/include/soc/nvs.h
@@ -28,8 +28,6 @@
 	uint8_t		scdo; /* 0x2A - GPIO pad offset relative to the community */
 	uint8_t		uior; /* 0x2B - UART debug controller init on S3
 					 resume */
-	uint64_t	a4gb; /* 0x2C - 0x33 Base of above 4GB MMIO Resource */
-	uint64_t	a4gs; /* 0x34 - 0x3B Length of above 4GB MMIO Resource */
 };
 
 #endif	/* _SOC_APOLLOLAKE_NVS_H_ */
diff --git a/src/soc/intel/cannonlake/acpi.c b/src/soc/intel/cannonlake/acpi.c
index d5a0a17..f6948b3 100644
--- a/src/soc/intel/cannonlake/acpi.c
+++ b/src/soc/intel/cannonlake/acpi.c
@@ -179,9 +179,6 @@
 	/* Set USB2/USB3 wake enable bitmaps. */
 	gnvs->u2we = config->usb2_wake_enable_bitmap;
 	gnvs->u3we = config->usb3_wake_enable_bitmap;
-
-	/* Fill in Above 4GB MMIO resource */
-	sa_fill_gnvs(gnvs);
 }
 
 int soc_madt_sci_irq_polarity(int sci)
diff --git a/src/soc/intel/cannonlake/chip.c b/src/soc/intel/cannonlake/chip.c
index c223211..c001e98 100644
--- a/src/soc/intel/cannonlake/chip.c
+++ b/src/soc/intel/cannonlake/chip.c
@@ -10,6 +10,7 @@
 #include <intelblocks/irq.h>
 #include <intelblocks/itss.h>
 #include <intelblocks/pcie_rp.h>
+#include <intelblocks/systemagent.h>
 #include <intelblocks/xdci.h>
 #include <soc/intel/common/vbt.h>
 #include <soc/pci_devs.h>
@@ -176,6 +177,7 @@
 	.scan_bus         = &pci_domain_scan_bus,
 #if CONFIG(HAVE_ACPI_TABLES)
 	.acpi_name        = &soc_acpi_name,
+	.acpi_fill_ssdt   = ssdt_set_above_4g_pci,
 #endif
 };
 
diff --git a/src/soc/intel/common/block/acpi/acpi/globalnvs.asl b/src/soc/intel/common/block/acpi/acpi/globalnvs.asl
index bb7ab0c..2c72b7d 100644
--- a/src/soc/intel/common/block/acpi/acpi/globalnvs.asl
+++ b/src/soc/intel/common/block/acpi/acpi/globalnvs.asl
@@ -22,7 +22,5 @@
 	U2WE,	16,	// 0x2b - 0x2c USB2 Wake Enable Bitmap
 	U3WE,	16,	// 0x2d - 0x2e USB3 Wake Enable Bitmap
 	UIOR,	8,	// 0x2f - UART debug controller init on S3 resume
-	A4GB,	64,	// 0x30 - 0x37 Base of above 4GB MMIO Resource
-	A4GS,	64,	// 0x38 - 0x3f Length of above 4GB MMIO Resource
-	,	64,	// 0x40 - 0x47 Hest log buffer (used in SMM, not ASL code)
+	,	64,	// 0x30 - 0x37 Hest log buffer (used in SMM, not ASL code)
 }
diff --git a/src/soc/intel/common/block/acpi/acpi/northbridge.asl b/src/soc/intel/common/block/acpi/acpi/northbridge.asl
index be14d18..28d38ed 100644
--- a/src/soc/intel/common/block/acpi/acpi/northbridge.asl
+++ b/src/soc/intel/common/block/acpi/acpi/northbridge.asl
@@ -45,6 +45,9 @@
 	}
 }
 
+External (A4GS, IntObj)
+External (A4GB, IntObj)
+
 Method (_CRS, 0, Serialized)
 {
 	Name (MCRS, ResourceTemplate ()
diff --git a/src/soc/intel/common/block/include/intelblocks/nvs.h b/src/soc/intel/common/block/include/intelblocks/nvs.h
index 5adbdb8..4fc5b4c 100644
--- a/src/soc/intel/common/block/include/intelblocks/nvs.h
+++ b/src/soc/intel/common/block/include/intelblocks/nvs.h
@@ -24,9 +24,7 @@
 	u16	u2we; /* 0x2b - 0x2c USB2 Wake Enable Bitmap */
 	u16	u3we; /* 0x2d - 0x2e USB3 Wake Enable Bitmap */
 	u8	uior; /* 0x2f - UART debug controller init on S3 resume */
-	u64	a4gb; /* 0x30 - 0x37 Base of above 4GB MMIO Resource */
-	u64	a4gs; /* 0x38 - 0x3f Length of above 4GB MMIO Resource */
-	u64	hest_log_addr; /* 0x40 - 47 err log addr (used in SMM, not ASL code) */
+	u64	hest_log_addr; /* 0x30 - 0x37 err log addr (used in SMM, not ASL code) */
 };
 
 #endif
diff --git a/src/soc/intel/common/block/include/intelblocks/systemagent.h b/src/soc/intel/common/block/include/intelblocks/systemagent.h
index f708fae..174c1a6 100644
--- a/src/soc/intel/common/block/include/intelblocks/systemagent.h
+++ b/src/soc/intel/common/block/include/intelblocks/systemagent.h
@@ -77,8 +77,6 @@
 uintptr_t sa_get_tseg_base(void);
 /* API to get TSEG size */
 size_t sa_get_tseg_size(void);
-/* Fill MMIO resource above 4GB into GNVS */
-void sa_fill_gnvs(struct global_nvs *gnvs);
 /* API to lock PAM registers */
 void sa_lock_pam(void);
 
@@ -104,4 +102,7 @@
 /* Returns the maximum supported capacity of a channel as encoded by DDRSZ in MiB */
 uint32_t soc_systemagent_max_chan_capacity_mib(u8 capid0_a_ddrsz);
 
+/* To be called in the acpi_fill_ssdt op of the domain */
+void ssdt_set_above_4g_pci(const struct device *dev);
+
 #endif	/* SOC_INTEL_COMMON_BLOCK_SA_H */
diff --git a/src/soc/intel/common/block/systemagent/systemagent.c b/src/soc/intel/common/block/systemagent/systemagent.c
index 07bcb0c..51fb0e5 100644
--- a/src/soc/intel/common/block/systemagent/systemagent.c
+++ b/src/soc/intel/common/block/systemagent/systemagent.c
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 
+#include <acpi/acpigen.h>
 #include <cbmem.h>
 #include <console/console.h>
 #include <cpu/cpu.h>
@@ -119,7 +120,7 @@
 };
 
 /* Read DRAM memory map register value through PCI configuration space */
-static void sa_read_map_entry(struct device *dev,
+static void sa_read_map_entry(const struct device *dev,
 		const struct sa_mem_map_descriptor *entry, uint64_t *result)
 {
 	uint64_t value = 0;
@@ -136,17 +137,6 @@
 	*result = value;
 }
 
-/* Fill MMIO resource above 4GB into GNVS */
-void sa_fill_gnvs(struct global_nvs *gnvs)
-{
-	struct device *sa_dev = pcidev_path_on_root(SA_DEVFN_ROOT);
-
-	sa_read_map_entry(sa_dev, &sa_memory_map[SA_TOUUD_REG], &gnvs->a4gb);
-	gnvs->a4gs = POWER_OF_2(cpu_phys_address_size()) - gnvs->a4gb;
-	printk(BIOS_DEBUG, "PCI space above 4GB MMIO is at 0x%llx, len = 0x%llx\n",
-	       gnvs->a4gb, gnvs->a4gs);
-}
-
 static void sa_get_mem_map(struct device *dev, uint64_t *values)
 {
 	int i;
@@ -315,6 +305,25 @@
 	pci_or_config8(dev, PAM0, PAM_LOCK);
 }
 
+void ssdt_set_above_4g_pci(const struct device *dev)
+{
+	if (dev->path.type != DEVICE_PATH_DOMAIN)
+		return;
+
+	uint64_t touud;
+	sa_read_map_entry(pcidev_path_on_root(SA_DEVFN_ROOT), &sa_memory_map[SA_TOUUD_REG],
+			  &touud);
+	const uint64_t len = POWER_OF_2(cpu_phys_address_size()) - touud;
+
+	const char *scope = acpi_device_path(dev);
+	acpigen_write_scope(scope);
+	acpigen_write_name_qword("A4GB", touud);
+	acpigen_write_name_qword("A4GS", len);
+	acpigen_pop_len();
+
+	printk(BIOS_DEBUG, "PCI space above 4GB MMIO is at 0x%llx, len = 0x%llx\n", touud, len);
+}
+
 static struct device_operations systemagent_ops = {
 	.read_resources   = systemagent_read_resources,
 	.set_resources    = pci_dev_set_resources,
diff --git a/src/soc/intel/elkhartlake/acpi.c b/src/soc/intel/elkhartlake/acpi.c
index 59a9adb..9f08acd 100644
--- a/src/soc/intel/elkhartlake/acpi.c
+++ b/src/soc/intel/elkhartlake/acpi.c
@@ -243,9 +243,6 @@
 	/* Set USB2/USB3 wake enable bitmaps. */
 	gnvs->u2we = config->usb2_wake_enable_bitmap;
 	gnvs->u3we = config->usb3_wake_enable_bitmap;
-
-	/* Fill in Above 4GB MMIO resource */
-	sa_fill_gnvs(gnvs);
 }
 
 int soc_madt_sci_irq_polarity(int sci)
diff --git a/src/soc/intel/elkhartlake/chip.c b/src/soc/intel/elkhartlake/chip.c
index c138a1fe..03f9cc9 100644
--- a/src/soc/intel/elkhartlake/chip.c
+++ b/src/soc/intel/elkhartlake/chip.c
@@ -9,6 +9,7 @@
 #include <intelblocks/gpio.h>
 #include <intelblocks/itss.h>
 #include <intelblocks/pcie_rp.h>
+#include <intelblocks/systemagent.h>
 #include <intelblocks/xdci.h>
 #include <soc/intel/common/vbt.h>
 #include <soc/itss.h>
@@ -134,6 +135,7 @@
 	.scan_bus         = &pci_domain_scan_bus,
 #if CONFIG(HAVE_ACPI_TABLES)
 	.acpi_name        = &soc_acpi_name,
+	.acpi_fill_ssdt   = ssdt_set_above_4g_pci,
 #endif
 };
 
diff --git a/src/soc/intel/icelake/acpi.c b/src/soc/intel/icelake/acpi.c
index 26c5aba..e2e8880 100644
--- a/src/soc/intel/icelake/acpi.c
+++ b/src/soc/intel/icelake/acpi.c
@@ -174,9 +174,6 @@
 	/* Set USB2/USB3 wake enable bitmaps. */
 	gnvs->u2we = config->usb2_wake_enable_bitmap;
 	gnvs->u3we = config->usb3_wake_enable_bitmap;
-
-	/* Fill in Above 4GB MMIO resource */
-	sa_fill_gnvs(gnvs);
 }
 
 int soc_madt_sci_irq_polarity(int sci)
diff --git a/src/soc/intel/icelake/chip.c b/src/soc/intel/icelake/chip.c
index 05f42b4..5010583 100644
--- a/src/soc/intel/icelake/chip.c
+++ b/src/soc/intel/icelake/chip.c
@@ -8,6 +8,7 @@
 #include <intelblocks/cfg.h>
 #include <intelblocks/gpio.h>
 #include <intelblocks/itss.h>
+#include <intelblocks/systemagent.h>
 #include <intelblocks/xdci.h>
 #include <soc/intel/common/vbt.h>
 #include <soc/itss.h>
@@ -124,9 +125,10 @@
 	.read_resources   = &pci_domain_read_resources,
 	.set_resources    = &pci_domain_set_resources,
 	.scan_bus         = &pci_domain_scan_bus,
-	#if CONFIG(HAVE_ACPI_TABLES)
+#if CONFIG(HAVE_ACPI_TABLES)
 	.acpi_name        = &soc_acpi_name,
-	#endif
+	.acpi_fill_ssdt   = ssdt_set_above_4g_pci,
+#endif
 };
 
 static struct device_operations cpu_bus_ops = {
diff --git a/src/soc/intel/jasperlake/acpi.c b/src/soc/intel/jasperlake/acpi.c
index a877e1a..f000648 100644
--- a/src/soc/intel/jasperlake/acpi.c
+++ b/src/soc/intel/jasperlake/acpi.c
@@ -254,9 +254,6 @@
 	/* Set USB2/USB3 wake enable bitmaps. */
 	gnvs->u2we = config->usb2_wake_enable_bitmap;
 	gnvs->u3we = config->usb3_wake_enable_bitmap;
-
-	/* Fill in Above 4GB MMIO resource */
-	sa_fill_gnvs(gnvs);
 }
 
 int soc_madt_sci_irq_polarity(int sci)
diff --git a/src/soc/intel/jasperlake/chip.c b/src/soc/intel/jasperlake/chip.c
index 7f325c4..3464399 100644
--- a/src/soc/intel/jasperlake/chip.c
+++ b/src/soc/intel/jasperlake/chip.c
@@ -9,6 +9,7 @@
 #include <intelblocks/gpio.h>
 #include <intelblocks/itss.h>
 #include <intelblocks/pcie_rp.h>
+#include <intelblocks/systemagent.h>
 #include <intelblocks/xdci.h>
 #include <soc/intel/common/vbt.h>
 #include <soc/itss.h>
@@ -138,6 +139,7 @@
 	.scan_bus         = &pci_domain_scan_bus,
 #if CONFIG(HAVE_ACPI_TABLES)
 	.acpi_name        = &soc_acpi_name,
+	.acpi_fill_ssdt   = ssdt_set_above_4g_pci,
 #endif
 };
 
diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c
index b7cd5c9..9ae0bb6 100644
--- a/src/soc/intel/skylake/acpi.c
+++ b/src/soc/intel/skylake/acpi.c
@@ -176,9 +176,6 @@
 	/* Set USB2/USB3 wake enable bitmaps. */
 	gnvs->u2we = config->usb2_wake_enable_bitmap;
 	gnvs->u3we = config->usb3_wake_enable_bitmap;
-
-	/* Fill in Above 4GB MMIO resource */
-	sa_fill_gnvs(gnvs);
 }
 
 static unsigned long soc_fill_dmar(unsigned long current)
diff --git a/src/soc/intel/skylake/acpi/systemagent.asl b/src/soc/intel/skylake/acpi/systemagent.asl
index 1ca6232..f9b8f2d 100644
--- a/src/soc/intel/skylake/acpi/systemagent.asl
+++ b/src/soc/intel/skylake/acpi/systemagent.asl
@@ -48,6 +48,9 @@
 	}
 }
 
+External (A4GS, IntObj)
+External (A4GB, IntObj)
+
 Method (_CRS, 0, Serialized)
 {
 	Name (MCRS, ResourceTemplate ()
diff --git a/src/soc/intel/skylake/chip.c b/src/soc/intel/skylake/chip.c
index f59b4c3..a1a311a 100644
--- a/src/soc/intel/skylake/chip.c
+++ b/src/soc/intel/skylake/chip.c
@@ -17,6 +17,7 @@
 #include <intelblocks/power_limit.h>
 #include <intelblocks/xdci.h>
 #include <intelblocks/p2sb.h>
+#include <intelblocks/systemagent.h>
 #include <intelpch/lockdown.h>
 #include <soc/intel/common/vbt.h>
 #include <soc/interrupt.h>
@@ -190,7 +191,8 @@
 	.set_resources    = &pci_domain_set_resources,
 	.scan_bus         = &pci_domain_scan_bus,
 #if CONFIG(HAVE_ACPI_TABLES)
-	.acpi_name		= &soc_acpi_name,
+	.acpi_name        = &soc_acpi_name,
+	.acpi_fill_ssdt   = ssdt_set_above_4g_pci,
 #endif
 };
 
diff --git a/src/soc/intel/tigerlake/acpi.c b/src/soc/intel/tigerlake/acpi.c
index 6314d1c..6e13aba 100644
--- a/src/soc/intel/tigerlake/acpi.c
+++ b/src/soc/intel/tigerlake/acpi.c
@@ -269,9 +269,6 @@
 	/* Set USB2/USB3 wake enable bitmaps. */
 	gnvs->u2we = config->usb2_wake_enable_bitmap;
 	gnvs->u3we = config->usb3_wake_enable_bitmap;
-
-	/* Fill in Above 4GB MMIO resource */
-	sa_fill_gnvs(gnvs);
 }
 
 int soc_madt_sci_irq_polarity(int sci)
diff --git a/src/soc/intel/tigerlake/chip.c b/src/soc/intel/tigerlake/chip.c
index 9343ecf..867e410 100644
--- a/src/soc/intel/tigerlake/chip.c
+++ b/src/soc/intel/tigerlake/chip.c
@@ -10,6 +10,7 @@
 #include <intelblocks/irq.h>
 #include <intelblocks/itss.h>
 #include <intelblocks/pcie_rp.h>
+#include <intelblocks/systemagent.h>
 #include <intelblocks/xdci.h>
 #include <soc/intel/common/vbt.h>
 #include <soc/itss.h>
@@ -180,6 +181,7 @@
 	.scan_bus         = &pci_domain_scan_bus,
 #if CONFIG(HAVE_ACPI_TABLES)
 	.acpi_name        = &soc_acpi_name,
+	.acpi_fill_ssdt   = ssdt_set_above_4g_pci,
 #endif
 };