soc/amd/picasso: Assign IOAPIC IDs, GNB APIC base with FSP

Add Kconfig symbols for the FCH and GNB IOAPIC IDs, then pass
the info to FSP to keep it in sync with coreboot.  Do the same
for the northbridge's IOAPIC base address.

Use the new values where needed, and reserve the resources
consumed by the GNB IOAPIC.

BUG=b:167421913, b:166519072
TEST=Boot Morphius and verify settings
BRANCH=Zork

Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com>
Change-Id: I57d3d6b2ebd8b5d511dbcb4324ea065cc3111a2d
Reviewed-on: https://review.coreboot.org/c/coreboot/+/45115
Reviewed-by: Furquan Shaikh <furquan@google.com>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/soc/amd/picasso/Kconfig b/src/soc/amd/picasso/Kconfig
index ec5ff76..29ebc6d 100644
--- a/src/soc/amd/picasso/Kconfig
+++ b/src/soc/amd/picasso/Kconfig
@@ -243,6 +243,24 @@
 	hex
 	default 0xfef00000
 
+config PICASSO_FCH_IOAPIC_ID
+	hex
+	default 0x8
+	help
+	  The Picasso APU has two IOAPICs, one in the FCH and one in the
+	  northbridge.  Set this value for the intended ID to assign to the
+	  FCH IOAPIC.  The value should be >= MAX_CPUS and different from
+	  the GNB's IOAPIC_ID.
+
+config PICASSO_GNB_IOAPIC_ID
+	hex
+	default 0x9
+	help
+	  The Picasso APU has two IOAPICs, one in the FCH and one in the
+	  northbridge.  Set this value for the intended ID to assign to the
+	  GNB IOAPIC.  The value should be >= MAX_CPUS and different from
+	  the FCH's IOAPIC_ID.
+
 config SERIRQ_CONTINUOUS_MODE
 	bool
 	default n
diff --git a/src/soc/amd/picasso/acpi.c b/src/soc/amd/picasso/acpi.c
index 1b9c0ca..84be4bd 100644
--- a/src/soc/amd/picasso/acpi.c
+++ b/src/soc/amd/picasso/acpi.c
@@ -49,9 +49,9 @@
 	/* create all subtables for processors */
 	current = acpi_create_madt_lapics(current);
 
-	/* Write Kern IOAPIC, only one */
+	/* Write IOAPIC, only one */
 	current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current,
-			CONFIG_MAX_CPUS, IO_APIC_ADDR, 0);
+			CONFIG_PICASSO_FCH_IOAPIC_ID, IO_APIC_ADDR, 0);
 
 	/* 0: mean bus 0--->ISA */
 	/* 0: PIC 0 */
diff --git a/src/soc/amd/picasso/agesa_acpi.c b/src/soc/amd/picasso/agesa_acpi.c
index c76e943..c2ff81d 100644
--- a/src/soc/amd/picasso/agesa_acpi.c
+++ b/src/soc/amd/picasso/agesa_acpi.c
@@ -54,7 +54,7 @@
 	ivhd_ioapic->dte_setting = IVHD_DTE_LINT_1_PASS | IVHD_DTE_LINT_0_PASS |
 				   IVHD_DTE_SYS_MGT_NO_TRANS | IVHD_DTE_NMI_PASS |
 				   IVHD_DTE_EXT_INT_PASS | IVHD_DTE_INIT_PASS;
-	ivhd_ioapic->handle = CONFIG_MAX_CPUS; /* FCH IOAPIC ID */
+	ivhd_ioapic->handle = CONFIG_PICASSO_FCH_IOAPIC_ID;
 	ivhd_ioapic->source_dev_id = PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC);
 	ivhd_ioapic->variety = IVHD_SPECIAL_DEV_IOAPIC;
 	current += sizeof(ivrs_ivhd_special_t);
@@ -63,7 +63,7 @@
 	memset(ivhd_ioapic, 0, sizeof(*ivhd_ioapic));
 
 	ivhd_ioapic->type = IVHD_DEV_8_BYTE_EXT_SPECIAL_DEV;
-	ivhd_ioapic->handle = CONFIG_MAX_CPUS + 1; /* GNB IOAPIC ID */
+	ivhd_ioapic->handle = CONFIG_PICASSO_GNB_IOAPIC_ID;
 	ivhd_ioapic->source_dev_id = PCI_DEVFN(0, 1);
 	ivhd_ioapic->variety = IVHD_SPECIAL_DEV_IOAPIC;
 	current += sizeof(ivrs_ivhd_special_t);
diff --git a/src/soc/amd/picasso/fsp_params.c b/src/soc/amd/picasso/fsp_params.c
index 1dbb8e5..f7f23b5 100644
--- a/src/soc/amd/picasso/fsp_params.c
+++ b/src/soc/amd/picasso/fsp_params.c
@@ -2,6 +2,7 @@
 
 #include <assert.h>
 #include <device/pci.h>
+#include <soc/iomap.h>
 #include <soc/pci_devs.h>
 #include <soc/platform_descriptors.h>
 #include <fsp/api.h>
@@ -122,6 +123,20 @@
 	}
 }
 
+static void fsp_assign_ioapic_upds(FSP_S_CONFIG *scfg)
+{
+	_Static_assert(CONFIG_PICASSO_GNB_IOAPIC_ID >= CONFIG_MAX_CPUS,
+			"PICASSO_GNB_IOAPIC_ID should be >= CONFIG_MAX_CPUS!\n");
+	_Static_assert(CONFIG_PICASSO_FCH_IOAPIC_ID >= CONFIG_MAX_CPUS,
+			"PICASSO_FCH_IOAPIC_ID should be >= CONFIG_MAX_CPUS!\n");
+	_Static_assert(CONFIG_PICASSO_GNB_IOAPIC_ID != CONFIG_PICASSO_FCH_IOAPIC_ID,
+			"PICASSO_GNB_IOAPIC_ID should be != PICASSO_FCH_IOAPIC_ID!\n");
+
+	scfg->gnb_ioapic_base = GNB_IO_APIC_ADDR;
+	scfg->gnb_ioapic_id = CONFIG_PICASSO_GNB_IOAPIC_ID;
+	scfg->fch_ioapic_id = CONFIG_PICASSO_FCH_IOAPIC_ID;
+}
+
 void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd)
 {
 	const struct soc_amd_picasso_config *cfg;
@@ -130,5 +145,6 @@
 	cfg = config_of_soc();
 	fsps_update_emmc_config(scfg, cfg);
 	fsp_fill_pcie_ddi_descriptors(scfg);
+	fsp_assign_ioapic_upds(scfg);
 	fsp_usb_oem_customization(scfg, cfg);
 }
diff --git a/src/soc/amd/picasso/include/soc/iomap.h b/src/soc/amd/picasso/include/soc/iomap.h
index 8256836..890b1c3 100644
--- a/src/soc/amd/picasso/include/soc/iomap.h
+++ b/src/soc/amd/picasso/include/soc/iomap.h
@@ -5,6 +5,7 @@
 
 /* MMIO Ranges */
 /* IO_APIC_ADDR defined in arch/x86	0xfec00000 */
+#define GNB_IO_APIC_ADDR		0xfec01000
 #define SPI_BASE_ADDRESS		0xfec10000
 
 #if CONFIG(HPET_ADDRESS_OVERRIDE)
diff --git a/src/soc/amd/picasso/root_complex.c b/src/soc/amd/picasso/root_complex.c
index 1c06928..21af481 100644
--- a/src/soc/amd/picasso/root_complex.c
+++ b/src/soc/amd/picasso/root_complex.c
@@ -12,6 +12,7 @@
 #include <fsp/util.h>
 #include <stdint.h>
 #include <soc/memmap.h>
+#include <soc/iomap.h>
 
 /*
  *
@@ -72,6 +73,7 @@
 	unsigned int idx = 0;
 	const struct hob_header *hob = fsp_get_hob_list();
 	const struct hob_resource *res;
+	struct resource *gnb_apic;
 
 	uintptr_t early_reserved_dram_start, early_reserved_dram_end;
 	const struct memmap_early_dram *e = memmap_get_early_dram_usage();
@@ -129,6 +131,12 @@
 			printk(BIOS_ERR, "Error: failed to set resources for type %d\n",
 					res->type);
 	}
+
+	/* GNB IOAPIC resource */
+	gnb_apic = new_resource(dev, GNB_IO_APIC_ADDR);
+	gnb_apic->base = GNB_IO_APIC_ADDR;
+	gnb_apic->size = 0x00001000;
+	gnb_apic->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
 }
 
 /* Used by \_SB.PCI0._CRS */