soc/intel/xeon_sp/cpx: fix MADT ACPI table

Fix MADT table generation to keep IIO stack design in consideration.

Signed-off-by: Jonathan Zhang <jonzhang@fb.com>
Signed-off-by: Reddy Chagam <anjaneya.chagam@intel.com>
Change-Id: If1bf6e39db545e227e9867aa8d24f7db1d820216
Reviewed-on: https://review.coreboot.org/c/coreboot/+/40383
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
diff --git a/src/soc/intel/xeon_sp/cpx/acpi.c b/src/soc/intel/xeon_sp/cpx/acpi.c
index 4a5cb64..2ecb6aa 100644
--- a/src/soc/intel/xeon_sp/cpx/acpi.c
+++ b/src/soc/intel/xeon_sp/cpx/acpi.c
@@ -10,7 +10,10 @@
 #include <cpu/x86/smm.h>
 #include <device/pci.h>
 #include <intelblocks/acpi.h>
+#include <hob_iiouds.h>
+#include <hob_memmap.h>
 #include <soc/acpi.h>
+#include <soc/cpu.h>
 #include <soc/iomap.h>
 #include <soc/nvs.h>
 #include <soc/pci_devs.h>
@@ -21,8 +24,8 @@
 
 #define SCI_INT_NUM		9
 
-unsigned long southbridge_write_acpi_tables(const struct device *device, unsigned long current,
-						struct acpi_rsdp *rsdp)
+unsigned long southbridge_write_acpi_tables(const struct device *device,
+	unsigned long current, struct acpi_rsdp *rsdp)
 {
 	current = acpi_write_hpet(device, current, rsdp);
 	current = (ALIGN(current, 16));
@@ -150,16 +153,79 @@
 	/* SCI */
 	current += acpi_create_madt_irqoverride((void *)current, 0, sci, sci, flags);
 
+	current +=
+		acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *) current, 0xff, 0x0d, 1);
+
+	return current;
+}
+
+static unsigned long xeonsp_acpi_create_madt_lapics(unsigned long current)
+{
+	struct device *cpu;
+	uint8_t num_cpus = 0;
+
+	for (cpu = all_devices; cpu; cpu = cpu->next) {
+		if ((cpu->path.type != DEVICE_PATH_APIC) ||
+			(cpu->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER)) {
+			continue;
+		}
+		if (!cpu->enabled)
+			continue;
+		current += acpi_create_madt_lapic((acpi_madt_lapic_t *)current,
+			num_cpus, cpu->path.apic.apic_id);
+		num_cpus++;
+	}
+
 	return current;
 }
 
 unsigned long acpi_fill_madt(unsigned long current)
 {
-	/* Local APICs */
-	current = acpi_create_madt_lapics(current);
+	int cur_index;
+	struct iiostack_resource stack_info = {0};
 
-	/* IOAPIC */
-	current += acpi_create_madt_ioapic((void *)current, 2, IO_APIC_ADDR, 0);
+	int gsi_bases[] = { 0, 0x18, 0x20, 0x28, 0x30, 0x48, 0x50, 0x58, 0x60 };
+	int ioapic_ids[] = { 0x8, 0x9, 0xa, 0xb, 0xc, 0xf, 0x10, 0x11, 0x12 };
+
+	/* Local APICs */
+	current = xeonsp_acpi_create_madt_lapics(current);
+
+	cur_index = 0;
+	get_iiostack_info(&stack_info);
+
+	for (int stack = 0; stack < stack_info.no_of_stacks; ++stack) {
+		const STACK_RES *ri = &stack_info.res[stack];
+		assert(cur_index < ARRAY_SIZE(ioapic_ids));
+		assert(cur_index < ARRAY_SIZE(gsi_bases));
+		int ioapic_id = ioapic_ids[cur_index];
+		int gsi_base = gsi_bases[cur_index];
+		printk(BIOS_DEBUG, "Adding MADT IOAPIC for stack: %d, ioapic_id: 0x%x, "
+			"ioapic_base: 0x%x, gsi_base: 0x%x\n",
+			stack,  ioapic_id, ri->IoApicBase, gsi_base);
+		current += acpi_create_madt_ioapic(
+			(acpi_madt_ioapic_t *)current,
+			ioapic_id, ri->IoApicBase, gsi_base);
+		++cur_index;
+
+		/*
+		 * Stack 0 has non-PCH IOAPIC and PCH IOAPIC.
+		 * Add entry for PCH IOAPIC.
+		 */
+		if (stack == 0) { /* PCH IOAPIC */
+			assert(cur_index < ARRAY_SIZE(ioapic_ids));
+			assert(cur_index < ARRAY_SIZE(gsi_bases));
+			ioapic_id = ioapic_ids[cur_index];
+			gsi_base = gsi_bases[cur_index];
+			printk(BIOS_DEBUG, "Adding MADT IOAPIC for stack: %d, ioapic_id: 0x%x, "
+				"ioapic_base: 0x%x, gsi_base: 0x%x\n",
+				stack,  ioapic_id,
+				ri->IoApicBase + 0x1000, gsi_base);
+			current += acpi_create_madt_ioapic(
+				(acpi_madt_ioapic_t *)current,
+				ioapic_id, ri->IoApicBase + 0x1000, gsi_base);
+			++cur_index;
+		}
+	}
 
 	return acpi_madt_irq_overrides(current);
 }
diff --git a/src/soc/intel/xeon_sp/cpx/include/soc/acpi.h b/src/soc/intel/xeon_sp/cpx/include/soc/acpi.h
index 0f010ec..2f923d4 100644
--- a/src/soc/intel/xeon_sp/cpx/include/soc/acpi.h
+++ b/src/soc/intel/xeon_sp/cpx/include/soc/acpi.h
@@ -14,4 +14,6 @@
 unsigned long northbridge_write_acpi_tables(const struct device *device,
 	unsigned long current, struct acpi_rsdp *rsdp);
 
+void motherboard_fill_fadt(acpi_fadt_t *fadt);
+
 #endif /* _SOC_ACPI_H_ */
diff --git a/src/soc/intel/xeon_sp/cpx/include/soc/pci_devs.h b/src/soc/intel/xeon_sp/cpx/include/soc/pci_devs.h
index 4953f93..d660d89 100644
--- a/src/soc/intel/xeon_sp/cpx/include/soc/pci_devs.h
+++ b/src/soc/intel/xeon_sp/cpx/include/soc/pci_devs.h
@@ -44,9 +44,9 @@
 #define VTD_CAP_HIGH			0x0C
 #define VTD_EXT_CAP_HIGH		0x14
 
-#define MMAP_VTD_CFG_REG_DEVID		0x2024
-#define VTD_DEV				5
-#define VTD_FUNC			0
+#define MMAP_VTD_CFG_REG_DEVID	0x2024
+#define VTD_DEV			5
+#define VTD_FUNC		0
 
 #define VMD_DEV_NUM             0x05
 #define VMD_FUNC_NUM            0x05
@@ -71,7 +71,35 @@
 #define HPET_DEV_NUM            PCH_DEV_SLOT_LPC
 #define HPET0_FUNC_NUM          0x00
 
-// ==================== IOAPIC Definitions for DMAR/ACPI ====================
+#define MMAP_VTD_CFG_REG_DEVID		0x2024
+#define VTD_DEV				5
+#define VTD_FUNC			0
+
+#define PCH_DEV_SLOT_LPC        0x1f
+#define  PCH_DEVFN_LPC          _PCH_DEVFN(LPC, 0)
+#define  PCH_DEVFN_P2SB         _PCH_DEVFN(LPC, 1)
+#define  PCH_DEVFN_PMC          _PCH_DEVFN(LPC, 2)
+#define  PCH_DEVFN_SPI          _PCH_DEVFN(LPC, 5)
+#define  PCH_DEV_LPC            _PCH_DEV(LPC, 0)
+#define  PCH_DEV_P2SB           _PCH_DEV(LPC, 1)
+#define  PCH_DEV_PMC            _PCH_DEV(LPC, 2)
+#define  PCH_DEV_SPI            _PCH_DEV(LPC, 5)
+
+
+#define CBDMA_DEV_NUM           0x04
+#define IIO_CBDMA_MMIO_SIZE     0x10000 //64kB for one CBDMA function
+
+#define VMD_DEV_NUM             0x05
+#define VMD_FUNC_NUM            0x05
+
+#define APIC_DEV_NUM            0x05
+#define APIC_FUNC_NUM           0x04
+
+#define PCH_IOAPIC_BUS_NUMBER   0x00
+#define PCH_IOAPIC_DEV_NUM      0x1F
+#define PCH_IOAPIC_FUNC_NUM     0x00
+
+// ========== IOAPIC Definitions for DMAR/ACPI ========
 #define PCH_IOAPIC_ID                   0x08
 #define PC00_IOAPIC_ID                  0x09
 #define PC01_IOAPIC_ID                  0x0A
@@ -86,14 +114,4 @@
 #define PC10_IOAPIC_ID                  0x13
 #define PC11_IOAPIC_ID                  0x14
 
-#define PCH_DEV_SLOT_LPC        0x1f
-#define  PCH_DEVFN_LPC          _PCH_DEVFN(LPC, 0)
-#define  PCH_DEVFN_P2SB         _PCH_DEVFN(LPC, 1)
-#define  PCH_DEVFN_PMC          _PCH_DEVFN(LPC, 2)
-#define  PCH_DEVFN_SPI          _PCH_DEVFN(LPC, 5)
-#define  PCH_DEV_LPC            _PCH_DEV(LPC, 0)
-#define  PCH_DEV_P2SB           _PCH_DEV(LPC, 1)
-#define  PCH_DEV_PMC            _PCH_DEV(LPC, 2)
-#define  PCH_DEV_SPI            _PCH_DEV(LPC, 5)
-
 #endif /* _SOC_PCI_DEVS_H_ */