diff options
author | Patrick Rudolph <patrick.rudolph@9elements.com> | 2024-10-24 13:12:14 +0200 |
---|---|---|
committer | Lean Sheng Tan <sheng.tan@9elements.com> | 2024-11-19 10:35:34 +0000 |
commit | dd46eb3c7c90063f652875036ea4cc50004a18f3 (patch) | |
tree | bbc04ce65e2671577eded1ba851b302bb1b22d0c /src/soc/intel | |
parent | 488e7bd9e4f964d80cd18c4ffa30e234a70982ce (diff) |
soc/intel/xeon_sp: Read IOAPIC ID from hardware
Currently coreboot hardcodes the same IOAPIC IDs as used on UEFI native,
however FSP does not program the IOAPIC IDs, except for PCH IOAPIC.
Drop existing code that hardcodes PCI addresses and IOAPIC IDs and
detect the IOAPIC inside the domain automatically, read the IOAPIC
base address and let existing code figure out the IOAPIC ID by reading
it back from HW.
Change-Id: I2543a46dcc4a98ec8629530ca87882a7106c9ed1
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/84850
Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Shuo Liu <shuo.liu@intel.com>
Diffstat (limited to 'src/soc/intel')
-rw-r--r-- | src/soc/intel/xeon_sp/cpx/include/soc/pci_devs.h | 6 | ||||
-rw-r--r-- | src/soc/intel/xeon_sp/cpx/soc_util.c | 21 | ||||
-rw-r--r-- | src/soc/intel/xeon_sp/include/soc/util.h | 1 | ||||
-rw-r--r-- | src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h | 4 | ||||
-rw-r--r-- | src/soc/intel/xeon_sp/skx/soc_util.c | 21 | ||||
-rw-r--r-- | src/soc/intel/xeon_sp/uncore_acpi.c | 39 |
6 files changed, 33 insertions, 59 deletions
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 762e2e2fd8..ffefd3e792 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 @@ -151,9 +151,6 @@ #define VTD_DEV(bus) PCI_DEV((bus), VTD_DEV_NUM, VTD_FUNC_NUM) #endif -#define APIC_DEV_NUM 0x05 -#define APIC_FUNC_NUM 0x04 - /* Root port Registers */ #define RP_UNCERRMSK 0x150 #define SURPRISE_DWN_ERR_MSK (1 << 5) @@ -165,6 +162,9 @@ #define DEVICES_PER_IIO_STACK 4 +// Per stack PCI IOAPIC (BxD5F4) +#define APIC_ABAR 0x40 + // DMI3 B0D0F0 registers #define DMI3_DEVID 0x2020 #define DMIRCBAR 0x50 diff --git a/src/soc/intel/xeon_sp/cpx/soc_util.c b/src/soc/intel/xeon_sp/cpx/soc_util.c index e56e9670cf..134b40cd76 100644 --- a/src/soc/intel/xeon_sp/cpx/soc_util.c +++ b/src/soc/intel/xeon_sp/cpx/soc_util.c @@ -35,27 +35,6 @@ bool is_ubox_stack_res(const STACK_RES *res) return res->Personality == TYPE_UBOX; } -uint8_t soc_get_iio_ioapicid(int socket, int stack) -{ - uint8_t ioapic_id = socket ? 0xf : 0x9; - switch (stack) { - case CSTACK: - break; - case PSTACK0: - ioapic_id += 1; - break; - case PSTACK1: - ioapic_id += 2; - break; - case PSTACK2: - ioapic_id += 3; - break; - default: - return 0xff; - } - return ioapic_id; -} - void soc_set_mrc_cold_boot_flag(bool cold_boot_required) { uint8_t mrc_status = cmos_read(CMOS_OFFSET_MRC_STATUS); diff --git a/src/soc/intel/xeon_sp/include/soc/util.h b/src/soc/intel/xeon_sp/include/soc/util.h index 95d127d825..8e5833a245 100644 --- a/src/soc/intel/xeon_sp/include/soc/util.h +++ b/src/soc/intel/xeon_sp/include/soc/util.h @@ -15,7 +15,6 @@ const IIO_UDS *get_iio_uds(void); unsigned int soc_get_num_cpus(void); bool soc_cpu_is_enabled(const size_t idx); void set_bios_init_completion(void); -uint8_t soc_get_iio_ioapicid(int socket, int stack); bool is_memtype_non_volatile(uint16_t mem_type); bool is_memtype_reserved(uint16_t mem_type); diff --git a/src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h b/src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h index e245bfb5dd..78393c1330 100644 --- a/src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h +++ b/src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h @@ -186,8 +186,8 @@ #define VMD_DEV_NUM 0x05 #define VMD_FUNC_NUM 0x05 -#define APIC_DEV_NUM 0x05 -#define APIC_FUNC_NUM 0x00 +// Per stack PCI IOAPIC (BxD5F4) +#define APIC_ABAR 0x40 // DMI3 B0D0F0 registers #define DMI3_DEVID 0x2020 diff --git a/src/soc/intel/xeon_sp/skx/soc_util.c b/src/soc/intel/xeon_sp/skx/soc_util.c index ed6fa4c544..387b5668f5 100644 --- a/src/soc/intel/xeon_sp/skx/soc_util.c +++ b/src/soc/intel/xeon_sp/skx/soc_util.c @@ -119,27 +119,6 @@ void config_reset_cpl3_csrs(void) } #endif -uint8_t soc_get_iio_ioapicid(int socket, int stack) -{ - uint8_t ioapic_id = socket ? 0xf : 0x9; - switch (stack) { - case CSTACK: - break; - case PSTACK0: - ioapic_id += 1; - break; - case PSTACK1: - ioapic_id += 2; - break; - case PSTACK2: - ioapic_id += 3; - break; - default: - return 0xff; - } - return ioapic_id; -} - bool is_memtype_reserved(uint16_t mem_type) { return !!(mem_type & MEM_TYPE_RESERVED); diff --git a/src/soc/intel/xeon_sp/uncore_acpi.c b/src/soc/intel/xeon_sp/uncore_acpi.c index 9823d947b2..a694d08abc 100644 --- a/src/soc/intel/xeon_sp/uncore_acpi.c +++ b/src/soc/intel/xeon_sp/uncore_acpi.c @@ -10,6 +10,7 @@ #include <device/pci.h> #include <device/pciexp.h> #include <device/pci_ids.h> +#include <device/pci_ops.h> #include <soc/acpi.h> #include <soc/chip_common.h> #include <soc/hest.h> @@ -275,21 +276,37 @@ static unsigned long acpi_create_drhd(unsigned long current, struct device *iomm if (is_dev_on_domain0(iommu)) { union p2sb_bdf ioapic_bdf = soc_get_ioapic_bdf(); printk(BIOS_DEBUG, " [IOAPIC Device] Enumeration ID: 0x%x, PCI Bus Number: 0x%x, " - "PCI Path: 0x%x, 0x%x\n", get_ioapic_id(IO_APIC_ADDR), ioapic_bdf.bus, - ioapic_bdf.dev, ioapic_bdf.fn); + "PCI Path: 0x%x, 0x%x, Address: 0x%x\n", get_ioapic_id(IO_APIC_ADDR), ioapic_bdf.bus, + ioapic_bdf.dev, ioapic_bdf.fn, IO_APIC_ADDR); current += acpi_create_dmar_ds_ioapic_from_hw(current, IO_APIC_ADDR, ioapic_bdf.bus, ioapic_bdf.dev, ioapic_bdf.fn); } -/* SPR and later SoCs have no per stack IOAPIC */ -#if CONFIG(SOC_INTEL_SKYLAKE_SP) || CONFIG(SOC_INTEL_COOPERLAKE_SP) - uint32_t enum_id; - // Add IOAPIC entry - enum_id = soc_get_iio_ioapicid(socket, stack); - printk(BIOS_DEBUG, " [IOAPIC Device] Enumeration ID: 0x%x, PCI Bus Number: 0x%x, " - "PCI Path: 0x%x, 0x%x\n", enum_id, bus, APIC_DEV_NUM, APIC_FUNC_NUM); - current += acpi_create_dmar_ds_ioapic(current, enum_id, bus, - APIC_DEV_NUM, APIC_FUNC_NUM); +#if (CONFIG(SOC_INTEL_SKYLAKE_SP) || CONFIG(SOC_INTEL_COOPERLAKE_SP)) + /* 14nm Xeon-SP have per stack PCI IOAPIC */ + { + const struct device *domain = dev_get_domain(iommu); + struct device *dev = NULL; + while ((dev = dev_bus_each_child(domain->downstream, dev))) { + if (!is_pci_ioapic(dev)) + continue; + + const uint32_t b = dev->upstream->secondary; + const uint32_t d = PCI_SLOT(dev->path.pci.devfn); + const uint32_t f = PCI_FUNC(dev->path.pci.devfn); + + u16 abar = pci_read_config16(dev, APIC_ABAR); + if (!abar) + continue; + const u32 addr = IO_APIC_ADDR | ((abar & 0xfff) << 8); + + printk(BIOS_DEBUG, " [IOAPIC Device] Enumeration ID: 0x%x, PCI Bus Number: 0x%x, " + "PCI Path: 0x%x, 0x%x, Address: 0x%x\n", get_ioapic_id(addr), b, d, f, addr); + + current += acpi_create_dmar_ds_ioapic_from_hw( + current, addr, b, d, f); + } + } #endif if (flags != DRHD_INCLUDE_PCI_ALL) { |