Attention is currently required from: Arthur Heymans, Chen, Gang C, Christian Walter, Jincheng Li, Johnny Lin, Lean Sheng Tan, Patrick Rudolph, Tim Chu.
Hello Chen, Gang C, Jincheng Li,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/81316?usp=email
to review the following change.
Change subject: soc/intel/xeon_sp: Add GraniteRapids initial codes ......................................................................
soc/intel/xeon_sp: Add GraniteRapids initial codes
coreboot GNR (GraniteRapids) is a FSP2.4 based, no-PCH, single IO-APIC Xeon-SP platform. The same set of codes is also used for SRF (SierraForest) SoC.
This patch initially setups the code set. All register definitions are forked from SPR (SapphireRapids).
Change-Id: I3084e1b5abf25d8d9504bebeaed2a15b916ed56b Signed-off-by: Shuo Liu shuo.liu@intel.com Signed-off-by: Gang Chen gang.c.chen@intel.com Signed-off-by: Li, Jincheng jincheng.li@intel.com --- M src/soc/intel/xeon_sp/Makefile.mk M src/soc/intel/xeon_sp/acpi.c M src/soc/intel/xeon_sp/chip_common.c A src/soc/intel/xeon_sp/chip_fsp24.c A src/soc/intel/xeon_sp/gnr/Kconfig A src/soc/intel/xeon_sp/gnr/Makefile.inc A src/soc/intel/xeon_sp/gnr/acpi/gpe.asl A src/soc/intel/xeon_sp/gnr/acpi/platform.asl A src/soc/intel/xeon_sp/gnr/chip.c A src/soc/intel/xeon_sp/gnr/chip.h A src/soc/intel/xeon_sp/gnr/cpu.c A src/soc/intel/xeon_sp/gnr/include/soc/cpu.h A src/soc/intel/xeon_sp/gnr/include/soc/pci_devs.h A src/soc/intel/xeon_sp/gnr/include/soc/soc_msr.h A src/soc/intel/xeon_sp/gnr/include/soc/soc_util.h A src/soc/intel/xeon_sp/gnr/include/soc/vpd.h A src/soc/intel/xeon_sp/gnr/ramstage.c A src/soc/intel/xeon_sp/gnr/romstage.c A src/soc/intel/xeon_sp/gnr/soc_acpi.c A src/soc/intel/xeon_sp/gnr/soc_pmutil.c A src/soc/intel/xeon_sp/gnr/soc_util.c M src/soc/intel/xeon_sp/include/soc/chip_common.h M src/soc/intel/xeon_sp/include/soc/fsp_adoption.h M src/soc/intel/xeon_sp/lockdown.c M src/soc/intel/xeon_sp/uncore.c M src/soc/intel/xeon_sp/uncore_acpi.c M src/soc/intel/xeon_sp/util.c 27 files changed, 1,322 insertions(+), 3 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/16/81316/1
diff --git a/src/soc/intel/xeon_sp/Makefile.mk b/src/soc/intel/xeon_sp/Makefile.mk index f9210a2..bb548c3 100644 --- a/src/soc/intel/xeon_sp/Makefile.mk +++ b/src/soc/intel/xeon_sp/Makefile.mk @@ -5,6 +5,7 @@ subdirs-$(CONFIG_SOC_INTEL_SKYLAKE_SP) += skx lbg subdirs-$(CONFIG_SOC_INTEL_COOPERLAKE_SP) += cpx lbg subdirs-$(CONFIG_SOC_INTEL_SAPPHIRERAPIDS_SP) += spr ebg +subdirs-$(CONFIG_SOC_INTEL_GRANITERAPIDS) += gnr ibl
bootblock-y += bootblock.c spi.c lpc.c pch.c report_platform.c romstage-y += romstage.c reset.c util.c spi.c pmutil.c memmap.c ddr.c @@ -18,6 +19,7 @@ ramstage-$(CONFIG_SOC_INTEL_SKYLAKE_SP) += chip_fsp20.c ramstage-$(CONFIG_SOC_INTEL_COOPERLAKE_SP) += chip_fsp20.c ramstage-$(CONFIG_SOC_INTEL_SAPPHIRERAPIDS_SP) += chip_fsp20.c +ramstage-$(CONFIG_SOC_INTEL_GRANITERAPIDS) += chip_fsp24.c smm-y += smihandler.c pmutil.c postcar-y += spi.c
diff --git a/src/soc/intel/xeon_sp/acpi.c b/src/soc/intel/xeon_sp/acpi.c index 2e17b4d..53c8e23 100644 --- a/src/soc/intel/xeon_sp/acpi.c +++ b/src/soc/intel/xeon_sp/acpi.c @@ -90,6 +90,7 @@ return map; }
+#if CONFIG(XEON_SP_HAVE_IIO_IOAPIC) static uintptr_t xeonsp_ioapic_bases[CONFIG(XEON_SP_HAVE_IIO_IOAPIC) * 8 + 1];
size_t soc_get_ioapic_info(const uintptr_t *ioapic_bases[]) @@ -124,6 +125,7 @@
return index; } +#endif
void iio_domain_set_acpi_name(struct device *dev, const char *prefix) { diff --git a/src/soc/intel/xeon_sp/chip_common.c b/src/soc/intel/xeon_sp/chip_common.c index 70a6aa8..f61ec58 100644 --- a/src/soc/intel/xeon_sp/chip_common.c +++ b/src/soc/intel/xeon_sp/chip_common.c @@ -181,7 +181,7 @@ struct device_operations *ops) { struct device_path path; - init_xeon_domain_path(&path, dp.socket, dp.stack, bus_base); + init_xeon_domain_path(&path, dp.socket, dp.stack, dp.root, bus_base);
struct device *const domain = alloc_find_dev(upstream, &path); if (!domain) diff --git a/src/soc/intel/xeon_sp/chip_fsp24.c b/src/soc/intel/xeon_sp/chip_fsp24.c new file mode 100644 index 0000000..8c76601 --- /dev/null +++ b/src/soc/intel/xeon_sp/chip_fsp24.c @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <acpi/acpigen_pci.h> +#include <assert.h> +#include <console/console.h> +#include <device/pci.h> +#include <intelblocks/acpi.h> +#include <post.h> +#include <soc/acpi.h> +#include <soc/chip_common.h> +#include <soc/soc_util.h> +#include <soc/util.h> +#include <stdlib.h> + +static const UDS_PCIROOT_RES *domain_to_root_res(const struct device *dev) +{ + assert(dev->path.type == DEVICE_PATH_DOMAIN); + const union xeon_domain_path dn = { + .domain_path = dev->path.domain.domain + }; + + const IIO_UDS *hob = get_iio_uds(); + assert(hob != NULL); + + return &hob->PlatformData.IIO_resource[dn.socket].StackRes[dn.stack]. + PciRoot[dn.root]; +} + +static struct device_operations iio_pcie_domain_ops = { + .read_resources = iio_pci_domain_read_resources, + .set_resources = pci_domain_set_resources, + .scan_bus = pci_host_bridge_scan_bus, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_name = soc_acpi_name, + .write_acpi_tables = northbridge_write_acpi_tables, + .acpi_fill_ssdt = pci_domain_fill_ssdt, +#endif +}; + +static void soc_pci_domain_read_resources(struct device *dev) +{ + int index = 0; + struct resource *res; + const UDS_PCIROOT_RES *rr = domain_to_root_res(dev); + + /* Initialize the system-wide I/O space constraints. */ + if (rr->IoBase <= rr->IoLimit) { + if (is_domain0(dev)) { + res = new_resource(dev, IOINDEX_SUBTRACTIVE(index++, 0)); + res->flags = IORESOURCE_SUBTRACTIVE; + } else { + res = new_resource(dev, IOINDEX(index++, 0)); + } + res->base = rr->IoBase; + res->limit = rr->IoLimit; + res->size = res->limit - res->base + 1; + res->flags |= IORESOURCE_IO | IORESOURCE_ASSIGNED; + } + + /* Initialize the system-wide memory resources constraints. */ + if (rr->Mmio32Base <= rr->Mmio32Limit) { + if (is_domain0(dev)) { + res = new_resource(dev, IOINDEX_SUBTRACTIVE(index++, 0)); + res->flags = IORESOURCE_SUBTRACTIVE; + } else { + res = new_resource(dev, IOINDEX(index++, 0)); + } + res->base = rr->Mmio32Base; + res->limit = rr->Mmio32Limit; + res->size = res->limit - res->base + 1; + res->flags |= IORESOURCE_MEM | IORESOURCE_ASSIGNED; + } + + /* Initialize the system-wide memory resources constraints. */ + if (rr->Mmio64Base <= rr->Mmio64Limit) { + if (is_domain0(dev)) { + res = new_resource(dev, IOINDEX_SUBTRACTIVE(index++, 0)); + res->flags = IORESOURCE_SUBTRACTIVE; + } else { + res = new_resource(dev, IOINDEX(index++, 0)); + } + res->base = rr->Mmio64Base; + res->limit = rr->Mmio64Limit; + res->size = res->limit - res->base + 1; + res->flags |= IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_PCI64; + } + return; +} + +static void soc_create_fsp24_domains(union xeon_domain_path dp, struct bus *upstream, + const xSTACK_RES *sr) +{ + for (uint8_t index = 0; index < sr->PciRootBridgeNum; index++) { + const char *dt = map_uid_to_domain_type(sr->PciRoot[index].UidType); + if (!dt) + continue; + dp.root = index; + soc_create_domains(dp, upstream, + sr->PciRoot[index].BusBase, + sr->PciRoot[index].BusLimit, + dt, + &iio_pcie_domain_ops); + } +} + +void iio_pci_domain_read_resources(struct device *dev) +{ + return soc_pci_domain_read_resources(dev); +} + +void soc_create_pcie_domains(const union xeon_domain_path dp, struct bus *upstream, + const xSTACK_RES *sr) +{ + soc_create_fsp24_domains(dp, upstream, sr); +} + +void soc_create_ubox_domains(const union xeon_domain_path dp, struct bus *upstream, + const xSTACK_RES *sr) +{ + soc_create_fsp24_domains(dp, upstream, sr); +} + +void soc_create_cxl_domains(const union xeon_domain_path dp, struct bus *upstream, + const xSTACK_RES *sr) +{ + soc_create_fsp24_domains(dp, upstream, sr); +} + +void soc_create_ioat_domains(const union xeon_domain_path dp, struct bus *upstream, + const xSTACK_RES *sr) +{ + soc_create_fsp24_domains(dp, upstream, sr); +} diff --git a/src/soc/intel/xeon_sp/gnr/Kconfig b/src/soc/intel/xeon_sp/gnr/Kconfig new file mode 100644 index 0000000..a709fcc --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/Kconfig @@ -0,0 +1,148 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_GRANITERAPIDS + bool + select MICROCODE_BLOB_NOT_HOOKED_UP + select FSP_NVS_DATA_POST_SILICON_INIT + select SOC_INTEL_MEM_MAPPED_PM_CONFIGURATION + select XEON_SP_COMMON_BASE + select PLATFORM_USES_FSP2_4 + select CACHE_MRC_SETTINGS + select CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED + select XEON_SP_IBL + select DEFAULT_X2APIC_RUNTIME + select UDK_202302_BINDING + select PLATFORM_USES_FSP2_X86_32 + select HAVE_IOAT_DOMAINS + select FSP_SPEC_VIOLATION_XEON_SP_HEAP_WORKAROUND + select VPD + help + Intel GraniteRapids support + +if SOC_INTEL_GRANITERAPIDS + +config FSP_HEADER_PATH + string "Location of FSP headers" + depends on MAINBOARD_USES_FSP2_0 + default "src/vendorcode/intel/fsp/fsp2_0/graniterapids/ap" + +config MAX_CPUS + int + default 255 + +config PCR_BASE_ADDRESS + hex + default 0xf7000000 + help + This option allows you to select MMIO Base Address of sideband bus. + +config INTEL_PCH_PWRM_BASE_ADDRESS + hex + default 0xf6800000 + help + PCH PWRM Base address. + +config DCACHE_RAM_BASE + hex + default 0xfe800000 + +config DCACHE_RAM_SIZE + hex + default 0x1fff00 + help + The size of the cache-as-ram region required during bootblock + and/or romstage. FSP-T reserves the upper 0x100 for + FspReservedBuffer. + +config DCACHE_BSP_STACK_SIZE + hex + default 0x60000 + help + The amount of anticipated stack usage in CAR by bootblock and + other stages. It needs to include FSP-M stack requirement and + CB romstage stack requirement. The integration documentation + says this needs to be 256KiB. + +config FSP_M_RC_HEAP_SIZE + hex + default 0x142000 + help + On xeon_sp/gnr FSP-M has two separate heap managers, one regular + whose size and base are controllable via the StackBase and + StackSize UPDs and a 'rc' heap manager that is statically + allocated at 0xfe800000 (the CAR base) and consumes about 0x150000 + bytes of memory. + +config CPU_MICROCODE_CBFS_LEN + hex + default 0x27b800 + +config HEAP_SIZE + hex + default 0x80000 + +config STACK_SIZE + hex + default 0x4000 + +config FSP_TEMP_RAM_SIZE + hex + depends on FSP_USES_CB_STACK + default 0x51000 + help + The amount of anticipated heap usage in CAR by FSP. + Refer to Platform FSP integration guide document to know + the exact FSP requirement for Heap setup. The FSP integration + documentation says this needs to be at least 128KiB, but practice + show this needs to be 256KiB or more. + +config IED_REGION_SIZE + hex + default 0x400000 + +config CPU_BCLK_MHZ + int + default 100 + +# DDR4 +config DIMM_SPD_SIZE + int + default 1024 + +config MAX_ACPI_TABLE_SIZE_KB + int + default 224 + +if INTEL_TXT + +config INTEL_TXT_SINIT_SIZE + hex + default 0x50000 + help + According to document number 572782 this needs to be 256KiB + for the SINIT module and 64KiB for SINIT data. + +config INTEL_TXT_HEAP_SIZE + hex + default 0xf0000 + help + This must be 960KiB according to 572782. + +endif # INTEL_TXT + +config SOC_INTEL_HAS_NCMEM + def_bool y + +config SOC_INTEL_MMAPVTD_ONLY_FOR_DPR + def_bool y + +config SOC_INTEL_HAS_CXL + def_bool y + +config INTEL_SPI_BASE_ADDRESS + hex + default 0xf6830000 + help + SPI BAR0 Base address. + +endif diff --git a/src/soc/intel/xeon_sp/gnr/Makefile.inc b/src/soc/intel/xeon_sp/gnr/Makefile.inc new file mode 100644 index 0000000..3d1880d --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/Makefile.inc @@ -0,0 +1,21 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ifeq ($(CONFIG_SOC_INTEL_GRANITERAPIDS),y) + +subdirs-y += ../../../../cpu/intel/turbo +subdirs-y += ../../../../cpu/x86/lapic +subdirs-y += ../../../../cpu/x86/mtrr +subdirs-y += ../../../../cpu/x86/smm +subdirs-y += ../../../../cpu/x86/tsc +subdirs-y += ../../../../cpu/intel/microcode + +romstage-y += romstage.c soc_util.c soc_pmutil.c +romstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c + +ramstage-y += chip.c cpu.c soc_util.c ramstage.c soc_acpi.c soc_pmutil.c + +CPPFLAGS_common += -I$(src)/soc/intel/xeon_sp/gnr/include -I$(src)/soc/intel/xeon_sp/gnr + +CFLAGS_common += -fshort-wchar + +endif ## CONFIG_SOC_INTEL_GRANITERAPIDS diff --git a/src/soc/intel/xeon_sp/gnr/acpi/gpe.asl b/src/soc/intel/xeon_sp/gnr/acpi/gpe.asl new file mode 100644 index 0000000..b61ffcf --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/acpi/gpe.asl @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <soc/iomap.h> + +Scope (_SB) +{ + Scope (_GPE) + { + OperationRegion (PMIO, SystemIO, ACPI_BASE_ADDRESS, 0xFF) + Field (PMIO, ByteAcc, NoLock, Preserve) { + Offset(0x34), /* 0x34, SMI/SCI STS*/ + , 9, + SGCS, 1, /* SWGPE STS BIT */ + + Offset(0x40), /* 0x40, SMI/SCI_EN*/ + , 17, + SGPC, 1, /* SWGPE CTRL BIT */ + + Offset(0x6C), /* 0x6C, General Purpose Event 0 Status [127:96] */ + , 2, + SGPS, 1, /* SWGPE STATUS */ + + Offset(0x7C), /* 0x7C, General Purpose Event 0 Enable [127:96] */ + , 2, + SGPE, 1 /* SWGPE ENABLE */ + } + Method (_L62, 0, NotSerialized) + { + DBGO("\_GPE\_L62\n") + SGPC = 0 // clear SWGPE control + SGPS = 1 // clear SWGPE Status + } + } +} diff --git a/src/soc/intel/xeon_sp/gnr/acpi/platform.asl b/src/soc/intel/xeon_sp/gnr/acpi/platform.asl new file mode 100644 index 0000000..68f5281 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/acpi/platform.asl @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * System Sleep States + */ +Name (_S0, Package () // mandatory system state +{ + 0x00, 0x00, 0x00, 0x00 +}) + +Name (_S5, Package () // mandatory system state +{ + 0x07, 0x00, 0x00, 0x00 +}) diff --git a/src/soc/intel/xeon_sp/gnr/chip.c b/src/soc/intel/xeon_sp/gnr/chip.c new file mode 100644 index 0000000..e57521c --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/chip.c @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <arch/hpet.h> +#include <arch/ioapic.h> +#include <assert.h> +#include <console/console.h> +#include <console/debug.h> +#include <cpu/x86/lapic.h> +#include <device/pci.h> +#include <gpio.h> +#include <intelblocks/gpio.h> +#include <intelblocks/lpc_lib.h> +#include <intelblocks/pcr.h> +#include <intelblocks/pmclib.h> +#include <soc/pm.h> +#include <soc/pmc.h> +#include <soc/acpi.h> +#include <soc/chip_common.h> +#include <soc/cpu.h> +#include <soc/pch.h> +#include <soc/ramstage.h> +#include <soc/soc_util.h> +#include <soc/util.h> +#include <soc/pci_devs.h> +#include "chip.h" + +static struct device_operations hpet_device_ops = { +#if CONFIG(HAVE_ACPI_TABLES) + .write_acpi_tables = &acpi_write_hpet, +#endif +}; + +static struct device_operations cpu_bus_ops = { + .init = mp_cpu_bus_init, +}; + +struct pci_operations soc_pci_ops = { + .set_subsystem = pci_dev_set_subsystem, +}; + +static void chip_enable_dev(struct device *dev) +{ + switch (dev->path.type) { + case DEVICE_PATH_DOMAIN: + /* device ops already assigned at domain creation */ + break; + case DEVICE_PATH_CPU_CLUSTER: + dev->ops = &cpu_bus_ops; + break; + case DEVICE_PATH_GPIO: + block_gpio_enable(dev); + break; + case DEVICE_PATH_MMIO: + if (dev->path.mmio.addr == HPET_BASE_ADDRESS) + dev->ops = &hpet_device_ops; + default: + break; + } + + return; +} + +static void chip_final(void *data) +{ + return; +} + +static void chip_init(void *data) +{ + printk(BIOS_DEBUG, "coreboot: calling fsp_silicon_init\n"); + + fsp_silicon_init(); + attach_iio_stacks(); + pch_enable_ioapic(); + + pmc_gpe_init(); + pmc_disable_all_gpe(); + pmc_write_pm1_control(pmc_read_pm1_control() | SCI_EN); + + return; +} + +struct chip_operations soc_intel_xeon_sp_gnr_ops = { + .name = "Intel GNR", + .enable_dev = chip_enable_dev, + .init = chip_init, + .final = chip_final, +}; + +/* UPD parameters to be initialized before SiliconInit */ +void platform_fsp_silicon_init_params_cb(FSPS_UPD *silupd) +{ + mainboard_silicon_init_params(silupd); +} diff --git a/src/soc/intel/xeon_sp/gnr/chip.h b/src/soc/intel/xeon_sp/gnr/chip.h new file mode 100644 index 0000000..b3cfeb5 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/chip.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_CHIP_H_ +#define _SOC_CHIP_H_ + +#include <intelblocks/cfg.h> +#include <soc/acpi.h> +#include <soc/gpio.h> +#include <soc/irq.h> +#include <stdint.h> + +struct soc_intel_xeon_sp_gnr_config { + /* Common struct containing soc config data required by common code */ + struct soc_intel_common_config common_soc_config; + + uint8_t vtd_support; + uint8_t x2apic; + uint8_t debug_print_level; + uint8_t serial_debug_msg_lvl; + uint16_t serial_io_uart_debug_io_base; + + /* Generic IO decode ranges */ + uint32_t gen1_dec; + uint32_t gen2_dec; + uint32_t gen3_dec; + uint32_t gen4_dec; + + uint32_t tcc_offset; + enum acpi_cstate_mode cstate_states; +}; + +typedef struct soc_intel_xeon_sp_gnr_config config_t; + +#endif diff --git a/src/soc/intel/xeon_sp/gnr/cpu.c b/src/soc/intel/xeon_sp/gnr/cpu.c new file mode 100644 index 0000000..5aa4c63 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/cpu.c @@ -0,0 +1,141 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <acpi/acpigen.h> +#include <acpi/acpi.h> +#include <assert.h> +#include <console/console.h> +#include <console/debug.h> +#include <cpu/cpu.h> +#include <cpu/intel/common/common.h> +#include <cpu/intel/em64t101_save_state.h> +#include <cpu/intel/microcode.h> +#include <cpu/intel/smm_reloc.h> +#include <cpu/intel/turbo.h> +#include <cpu/x86/lapic.h> +#include <cpu/x86/mp.h> +#include <cpu/x86/mtrr.h> +#include <intelblocks/cpulib.h> +#include <intelblocks/mp_init.h> +#include <soc/cpu.h> +#include <soc/msr.h> +#include <soc/soc_util.h> +#include <soc/smmrelocate.h> +#include <soc/util.h> + +#include "chip.h" + +static const void *microcode_patch; + +static const config_t *chip_config = NULL; + +bool cpu_soc_is_in_untrusted_mode(void) +{ + return false; +} + +static void xeon_configure_mca(void) +{ + msr_t msr; + + /* Check MCE and MCA support status */ + if ((cpuid_edx(1) & (CPUID_FEATURE_MCE | CPUID_FEATURE_MCA)) != + (CPUID_FEATURE_MCE | CPUID_FEATURE_MCA)) + return; + + msr = rdmsr(IA32_MCG_CAP); + if (msr.lo & IA32_MCG_CAP_CTL_P_MASK) { + /* Enable all error logging */ + msr.lo = msr.hi = 0xffffffff; + wrmsr(IA32_MCG_CTL, msr); + } + + mca_configure(); +} + +/* + * On server platforms the FIT mechanism only updates the microcode on + * the BSP. Loading MCU on AP in parallel seems to fail in 10% of the cases + * so do it serialized. + */ +void get_microcode_info(const void **microcode, int *parallel) +{ + *microcode = intel_microcode_find(); + *parallel = 0; +} + +static void each_cpu_init(struct device *cpu) +{ + printk(BIOS_SPEW, "%s dev: %s, cpu: %lu, apic_id: 0x%x\n", + __func__, dev_path(cpu), cpu_index(), cpu->path.apic.apic_id); + + /* Clear out pending MCEs */ + xeon_configure_mca(); + + /* Enable VMX */ + set_vmx_and_lock(); +} + +static struct device_operations cpu_dev_ops = { + .init = each_cpu_init, +}; + +static const struct cpu_device_id cpu_table[] = { + {X86_VENDOR_INTEL, CPUID_GRANITERAPIDS}, + {X86_VENDOR_INTEL, CPUID_SIERRAFOREST}, + {0, 0}, +}; + +static const struct cpu_driver driver __cpu_driver = { + .ops = &cpu_dev_ops, + .id_table = cpu_table, +}; + +/* + * Do essential initialization tasks before APs can be fired up + */ +static void pre_mp_init(void) +{ + x86_setup_mtrrs_with_detect(); + x86_mtrr_check(); +} + +static int get_thread_count(void) +{ + unsigned int num_phys = 0, num_virts = 0; + + cpu_read_topology(&num_phys, &num_virts); + printk(BIOS_SPEW, "Detected %u cores and %u threads\n", num_phys, num_virts); + return num_virts * soc_get_num_cpus(); +} + +static void post_mp_init(void) +{ + if (CONFIG(HAVE_SMI_HANDLER)) + global_smi_enable(); +} + +static const struct mp_ops mp_ops = { + .pre_mp_init = pre_mp_init, + .get_cpu_count = get_thread_count, + .get_microcode_info = get_microcode_info, + .post_mp_init = post_mp_init, +}; + +void mp_init_cpus(struct bus *bus) +{ + /* + * chip_config is used in cpu device callback. Other than cpu 0, + * rest of the CPU devices do not have chip_info updated. + */ + chip_config = bus->dev->chip_info; + + microcode_patch = intel_microcode_find(); + + if (!microcode_patch) + printk(BIOS_ERR, "microcode not found in CBFS!\n"); + + intel_microcode_load_unlocked(microcode_patch); + + if (mp_init_with_smm(bus, &mp_ops) < 0) + printk(BIOS_ERR, "MP initialization failure.\n"); +} diff --git a/src/soc/intel/xeon_sp/gnr/include/soc/cpu.h b/src/soc/intel/xeon_sp/gnr/include/soc/cpu.h new file mode 100644 index 0000000..34c6add --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/include/soc/cpu.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_CPU_H +#define _SOC_CPU_H + +#include <device/device.h> +#include <cpu/x86/msr.h> + +#define CPUID_GRANITERAPIDS 0xA06D0 +#define CPUID_SIERRAFOREST 0xA06F0 + +#endif diff --git a/src/soc/intel/xeon_sp/gnr/include/soc/pci_devs.h b/src/soc/intel/xeon_sp/gnr/include/soc/pci_devs.h new file mode 100644 index 0000000..0ad5ea0 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/include/soc/pci_devs.h @@ -0,0 +1,198 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_PCI_DEVS_H_ +#define _SOC_PCI_DEVS_H_ + +#include <device/pci_def.h> +#include <device/pci_type.h> +#include <soc/pch_pci_devs.h> +#include <types.h> + +#define _SA_DEVFN(slot) PCI_DEVFN(SA_DEV_SLOT_##slot, 0) + +#if !defined(__SIMPLE_DEVICE__) +#include <device/device.h> +#define _SA_DEV(slot) pcidev_path_on_root_debug(_SA_DEVFN(slot), __func__) +#else +#define _SA_DEV(slot) PCI_DEV(0, SA_DEV_SLOT_##slot, 0) +#endif + +#define UNCORE_BUS_0 0 +#define UNCORE_BUS_1 1 + +/* UBOX Registers [U(1), D:0, F:1] */ +#define SMM_FEATURE_CONTROL 0x8c +#define SMM_CODE_CHK_EN BIT(2) +#define SMM_FEATURE_CONTROL_LOCK BIT(0) +#define UBOX_DFX_DEVID 0x3251 + +/* CHA registers [B:31, D:29, F:0/F:1] + * SAD is the previous xeon_sp register name. Keep defines for shared code. + */ +#define CHA_DEV 29 + +#define SAD_ALL_DEV CHA_DEV +#define SAD_ALL_FUNC 0 +#define SAD_ALL_PAM0123_CSR 0x80 +#define SAD_ALL_PAM456_CSR 0x84 +#define SAD_ALL_DEVID 0x344f + +#if !defined(__SIMPLE_DEVICE__) +#define _PCU_DEV(bus, func) pcidev_path_on_bus(bus, PCI_DEVFN(PCU_DEV, func)) +#else +#define _PCU_DEV(bus, func) PCI_DEV(bus, PCU_DEV, func) +#endif + +/* PCU [B:31, D:30, F:0->F:6] */ +#define PCU_IIO_STACK UNCORE_BUS_1 +#define PCU_DEV 30 + +#define PCU_CR0_FUN 0 +#define PCU_CR0_DEVID 0x3258 +#define PCU_DEV_CR0(bus) _PCU_DEV(bus, PCU_CR0_FUN) +#define PCU_CR0_PLATFORM_INFO 0xa8 +#define PCU_CR0_TURBO_ACTIVATION_RATIO 0xb0 +#define TURBO_ACTIVATION_RATIO_LOCK BIT(31) +#define PCU_CR0_P_STATE_LIMITS 0xd8 +#define P_STATE_LIMITS_LOCK BIT(31) +#define PCU_CR0_PACKAGE_RAPL_LIMIT_LWR 0xe8 +#define PCU_CR0_PACKAGE_RAPL_LIMIT_UPR (PCU_CR0_PACKAGE_RAPL_LIMIT_LWR + 4) +#define PKG_PWR_LIM_LOCK_UPR BIT(31) +#define PCU_CR0_PMAX 0xf0 +#define PMAX_LOCK BIT(31) +#define PCU_CR0_VR_CURRENT_CONFIG_CFG 0xf8 +#define VR_CURRENT_CONFIG_LOCK BIT(31) + +#define PCU_CR1_FUN 1 +#define PCU_CR1_DEVID 0x3259 +#define PCU_DEV_CR1(bus) _PCU_DEV(bus, PCU_CR1_FUN) +#define PCU_CR1_BIOS_MB_DATA_REG 0x8c + +#define PCU_CR1_BIOS_MB_INTERFACE_REG 0x90 +#define BIOS_MB_RUN_BUSY_MASK BIT(31) +#define BIOS_MB_CMD_MASK 0xff +#define BIOS_CMD_READ_PCU_MISC_CFG 0x5 +#define BIOS_CMD_WRITE_PCU_MISC_CFG 0x6 +#define BIOS_ERR_INVALID_CMD 0x01 + +#define PCU_CR1_BIOS_RESET_CPL_REG 0x94 +#define RST_CPL1_MASK BIT(1) +#define RST_CPL2_MASK BIT(2) +#define RST_CPL3_MASK BIT(3) +#define RST_CPL4_MASK BIT(4) +#define PCODE_INIT_DONE1_MASK BIT(9) +#define PCODE_INIT_DONE2_MASK BIT(10) +#define PCODE_INIT_DONE3_MASK BIT(11) +#define PCODE_INIT_DONE4_MASK BIT(12) + +#define PCU_CR1_DESIRED_CORES_CFG2_REG 0xbc +#define PCU_CR1_DESIRED_CORES_CFG2_REG_LOCK_MASK BIT(31) + +#define PCU_CR2_FUN 2 +#define PCU_CR2_DEVID 0x325a +#define PCU_DEV_CR2(bus) _PCU_DEV(bus, PCU_CR2_FUN) +#define PCU_CR2_DRAM_POWER_INFO_LWR 0xa8 +#define PCU_CR2_DRAM_POWER_INFO_UPR (PCU_CR2_DRAM_POWER_INFO_LWR + 4) +#define DRAM_POWER_INFO_LOCK_UPR BIT(31) + +#define PCU_CR2_DRAM_PLANE_POWER_LIMIT_LWR 0xf0 +#define PCU_CR2_DRAM_PLANE_POWER_LIMIT_UPR (PCU_CR2_DRAM_PLANE_POWER_LIMIT_LWR + 4) +#define PP_PWR_LIM_LOCK_UPR BIT(31) + +#define PCU_CR3_FUN 3 +#define PCU_CR3_DEVID 0x325b +#define PCU_CR3_CAPID4 0x94 +#define ERR_SPOOFING_DIS 1 +#define PCU_DEV_CR3(bus) _PCU_DEV(bus, PCU_CR3_FUN) +#define PCU_CR3_CONFIG_TDP_CONTROL 0xd8 +#define TDP_LOCK BIT(31) +#define PCU_CR3_FLEX_RATIO 0xa0 +#define OC_LOCK BIT(20) + +#define PCU_CR4_FUN 4 +#define PCU_CR4_DEVID 0x325c +#define PCU_VIRAL_CONTROL 0x84 +#define PCU_FW_ERR_EN (1 << 10) +#define PCU_UC_ERR_EN (1 << 9) +#define PCU_HW_ERR_EN (1 << 8) +#define PCU_EMCA_MODE (1 << 2) + +#define PCU_CR6_FUN 6 +#define PCU_CR6_DEVID 0x325e +#define PCU_DEV_CR6(bus) _PCU_DEV(bus, PCU_CR6_FUN) +#define PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_LWR 0xa8 +#define PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_UPR (PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_LWR + 4) +#define PLT_PWR_LIM_LOCK_UPR BIT(31) +#define PCU_CR6_PLATFORM_POWER_INFO_CFG_LWR 0xb0 +#define PCU_CR6_PLATFORM_POWER_INFO_CFG_UPR (PCU_CR6_PLATFORM_POWER_INFO_CFG_LWR + 4) +#define PLT_PWR_INFO_LOCK_UPR BIT(31) + +/* Memory Map/VTD Device Functions + * These are available in each IIO stack + */ +#define MMAP_VTD_DEV 0x0 +#define MMAP_VTD_FUNC 0x0 + +#define VTD_TOLM_CSR 0xd0 +#define VTD_TSEG_BASE_CSR 0xa8 +#define VTD_TSEG_LIMIT_CSR 0xac +#define VTD_EXT_CAP_LOW 0x10 +#define VTD_MMCFG_BASE_CSR 0x90 +#define VTD_MMCFG_LIMIT_CSR 0x98 +#define VTD_TOHM_CSR 0xc8 +#define VTD_MMIOL_CSR 0xd8 +#define VTD_NCMEM_BASE_CSR 0xe0 +#define VTD_NCMEM_LIMIT_CSR 0xe8 +#define VTD_BAR_CSR 0x180 +#define VTD_LTDPR 0x290 + +#define VMD_DEV_NUM 0x00 +#define VMD_FUNC_NUM 0x05 + +#define MMAP_VTD_CFG_REG_DEVID 0x09a2 +#define MMAP_VTD_STACK_CFG_REG_DEVID 0x09a2 +#define VTD_DEV_NUM 0x0 +#define VTD_FUNC_NUM 0x0 + +#if !defined(__SIMPLE_DEVICE__) +#define VTD_DEV(bus) pcidev_path_on_bus((bus), PCI_DEVFN(VTD_DEV_NUM, VTD_FUNC_NUM)) +#else +#define VTD_DEV(bus) PCI_DEV((bus), VTD_DEV_NUM, VTD_FUNC_NUM) +#endif + +/* Root port Registers */ + +/* IEH */ +#define IEH_EXT_CAP_ID 0x7 /* At 0x160 */ +#define GSYSEVTCTL 0x104 /* Offset from IEH_EXT_CAP_ID */ +#define CE_ERR_UNMSK 1 +#define NON_FATAL_UNMSK (1 << 1) +#define FATAL_UNMSK (1 << 2) +#define GSYSEVTMAP 0x108 /* Offset from IEH_EXT_CAP_ID */ +#define CE_SMI 1 +#define NF_SMI (1 << 2) +#define FA_SMI (1 << 4) + + +#define DMIRCBAR 0x50 +#define DMI3_DEVID 0x2020 +#define PCIE_ROOTCTL 0x5c +#define ERRINJCON 0x198 + +// IIO DFX Global D7F7 registers +#define IIO_DFX_TSWCTL0 0x30c +#define IIO_DFX_LCK_CTL 0x504 + +// XHCI register +#define SYS_BUS_CFG2 0x44 + +/* MSM registers */ +#define MSM_BUS 0xF2 +#define MSM_DEV 3 +#define MSM_FUN 0 +#define MSM_FUN_PMON 1 +#define CRASHLOG_CTL 0x1B8 +#define BIOS_CRASHLOG_CTL 0x158 +#define CRASHLOG_CTL_DIS BIT(2) + +#endif /* _SOC_PCI_DEVS_H_ */ diff --git a/src/soc/intel/xeon_sp/gnr/include/soc/soc_msr.h b/src/soc/intel/xeon_sp/gnr/include/soc/soc_msr.h new file mode 100644 index 0000000..cfae169 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/include/soc/soc_msr.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _SOC_MSR_SPR_H_ +#define _SOC_MSR_SPR_H_ + +#define MSR_CPU_BUSNO 0x128 +#define BUSNO_VALID (1 << 31) /* used as msr.hi */ + +/* IA32_ERR_CTRL */ +#define CMCI_DISABLE (1 << 4) + +/* MSR_PKG_CST_CONFIG_CONTROL */ +#define PKG_CSTATE_NO_LIMIT (0x8 << PKG_CSTATE_LIMIT_SHIFT) + +/* MSR_POWER_CTL */ +#define RESERVED1_SHIFT 2 +#define PWR_PERF_PLTFRM_OVR_SHIFT 18 +#define PWR_PERF_PLTFRM_OVR (1 << PWR_PERF_PLTFRM_OVR_SHIFT) +#define EE_TURBO_DISABLE_SHIFT 19 +#define EE_TURBO_DISABLE (1 << EE_TURBO_DISABLE_SHIFT) +#define RTH_DISABLE_SHIFT 20 +#define RTH_DISABLE (1 << RTH_DISABLE_SHIFT) +#define PROCHOT_OUTPUT_DISABLE_SHIFT 21 +#define PROCHOT_OUTPUT_DISABLE (1 << PROCHOT_OUTPUT_DISABLE_SHIFT) +#define PROCHOT_RESPONSE_SHIFT 22 +#define PROCHOT_RESPONSE (1 << PROCHOT_RESPONSE_SHIFT) +#define PROCHOT_LOCK_SHIFT 23 +#define PROCHOT_LOCK (1 << PROCHOT_LOCK_SHIFT) +#define VR_THERM_ALERT_DISABLE_SHIFT 24 +#define VR_THERM_ALERT_DISABLE (1 << VR_THERM_ALERT_DISABLE_SHIFT) +#define DISABLE_RING_EE_SHIFT 25 +#define DISABLE_RING_EE (1 << DISABLE_RING_EE_SHIFT) +#define RESERVED2_SHIFT 26 +#define DISABLE_AUTONOMOUS_SHIFT 28 +#define DISABLE_AUTONOMOUS (1 << DISABLE_AUTONOMOUS_SHIFT) +#define RESERVED3_SHIFT 29 +#define CSTATE_PREWAKE_DISABLE_SHIFT 30 +#define CSTATE_PREWAKE_DISABLE (1 << CSTATE_PREWAKE_DISABLE_SHIFT) + +/* SPR has banks 0-20 and 29-31 */ +#define IA32_MC20_CTL2 0x294 +#define IA32_MC29_CTL2 0x29D +#define IA32_MC30_CTL2 0x29E +#define IA32_MC31_CTL2 0x29F + +#define MSR_PERRINJ_AT_IP 0x107 +#define MSR_PERRINJ_AT_IP_ENABLE BIT(31) + +#define MSR_BIOS_DONE 0x151 +#define XEON_SP_ENABLE_IA_UNTRUSTED BIT(0) + +#define MSR_FLEX_RATIO 0x194 +#define MSR_FLEX_RATIO_OC_LOCK BIT(20) + +/* B1:D30:F0 offset 0xe8 on previous generations */ +#define PACKAGE_RAPL_LIMIT 0x610 + +#define MSR_DRAM_PLANE_POWER_LIMIT 0x618 +#define MSR_HI_PP_PWR_LIM_LOCK BIT(31) /* used as msr.hi */ + +#endif /* _SOC_MSR_SPR_H_ */ diff --git a/src/soc/intel/xeon_sp/gnr/include/soc/soc_util.h b/src/soc/intel/xeon_sp/gnr/include/soc/soc_util.h new file mode 100644 index 0000000..baba2b0 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/include/soc/soc_util.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_UTIL_H_ +#define _SOC_UTIL_H_ + +#include <device/device.h> +#include <device/pci.h> +#include <fsp/util.h> +#include <FspAcpiHobs.h> +#include <CxlNodeHob.h> +#include <IioUniversalDataHob.h> + +#define FSP_HOB_IIO_UNIVERSAL_DATA_GUID { \ + 0xa1, 0x96, 0xf3, 0x7f, 0x7d, 0xee, 0x1e, 0x43, \ + 0xba, 0x53, 0x8f, 0xCa, 0x12, 0x7c, 0x44, 0xc0 \ +} + +const struct SystemMemoryMapHob *get_system_memory_map(void); +const struct SystemMemoryMapElement *get_system_memory_map_elment(uint8_t *num); + +const CXL_NODE_SOCKET *get_cxl_node(void); +uint8_t get_cxl_node_count(void); + +const char *map_uid_to_domain_type(uint16_t uid); + +#endif /* _SOC_UTIL_H_ */ diff --git a/src/soc/intel/xeon_sp/gnr/include/soc/vpd.h b/src/soc/intel/xeon_sp/gnr/include/soc/vpd.h new file mode 100644 index 0000000..ae0fceb --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/include/soc/vpd.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _SOC_VPD_H_ +#define _SOC_VPD_H_ + +#define FAST_BOOT_EN "fast_boot_en" /* 1 or 0: enable or disable fast boot for warm/cold reset */ +#define FAST_BOOT_EN_DEFAULT 1 /* Default value when this VPD variable is not found */ + +#endif /* _SOC_VPD_H_ */ diff --git a/src/soc/intel/xeon_sp/gnr/ramstage.c b/src/soc/intel/xeon_sp/gnr/ramstage.c new file mode 100644 index 0000000..7a0453a --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/ramstage.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <fsp/api.h> +#include <soc/ramstage.h> + +unsigned int smbios_cpu_get_voltage(void) +{ + return 16; /* Per SMBIOS spec, voltage times 10 */ +} diff --git a/src/soc/intel/xeon_sp/gnr/romstage.c b/src/soc/intel/xeon_sp/gnr/romstage.c new file mode 100644 index 0000000..759c38d --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/romstage.c @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <assert.h> +#include <arch/romstage.h> +#include <console/console.h> +#include <cbmem.h> +#include <fsp/api.h> +#include <fsp/util.h> +#include <MemoryMapDataHob.h> +#include <soc/romstage.h> +#include <soc/pci_devs.h> +#include <soc/intel/common/smbios.h> +#include <string.h> +#include <soc/soc_util.h> +#include <soc/ddr.h> +#include <soc/vpd.h> + +#include "chip.h" + +void __weak mainboard_memory_init_params(FSPM_UPD *mupd) +{ + /* Default weak implementation */ +} + +static uint8_t get_mmcfg_base_upd_index(const uint64_t base_addr) +{ + switch (base_addr) { + case 0x40000000: // 1G + return 0; + case 0x60000000: // 1.5G + return 0x1; + case 0x70000000: // 1.75G + return 0x2; + case 0x80000000: // 2G + return 0x3; + case 0x90000000: // 2.25G + return 0x4; + case 0xC0000000: // 3G + return 0x5; + default: // Auto + return 0x6; + } +} + +static uint8_t get_mmcfg_size_upd_index(const uint64_t size) +{ + switch (size) { + case 0x4000000: // 64M + return 0; + case 0x8000000: // 128M + return 0x1; + case 0x10000000: // 256M + return 0x2; + case 0x20000000: // 512M + return 0x3; + case 0x40000000: // 1G + return 0x4; + case 0x80000000: // 2G + return 0x5; + default: // Auto + return 0x6; + } +} + +void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) +{ + FSP_M_CONFIG *m_cfg = &mupd->FspmConfig; + m_cfg->mmCfgBase = get_mmcfg_base_upd_index(CONFIG_ECAM_MMCONF_BASE_ADDRESS); + m_cfg->mmCfgSize = get_mmcfg_size_upd_index(CONFIG_ECAM_MMCONF_LENGTH); + + /* FSP_LOG */ + const config_t *config = config_of_soc(); + m_cfg->DebugPrintLevel = config->debug_print_level; + m_cfg->serialDebugMsgLvl = config->serial_debug_msg_lvl; + m_cfg->SerialIoUartDebugIoBase = config->serial_io_uart_debug_io_base; + + /* FAST_BOOT_EN */ + uint8_t val = FAST_BOOT_EN_DEFAULT; + vpd_get_bool(FAST_BOOT_EN, VPD_RW_THEN_RO, &val); + m_cfg->AttemptFastBoot = val; + m_cfg->AttemptFastBootCold = val; + + FSPM_ARCHx_UPD *arch_upd = &mupd->FspmArchUpd; + if ((arch_upd->NvsBufferPtr != 0) && (val != FAST_BOOT_EN_DEFAULT)) { + arch_upd->BootMode = + FSP_BOOT_WITH_FULL_CONFIGURATION; + printk(BIOS_NOTICE, "Reset BootMode as " + "FSP_BOOT_WITH_FULL_CONFIGURATION.\n"); + } + + /* Board level settings */ + mainboard_memory_init_params(mupd); +} diff --git a/src/soc/intel/xeon_sp/gnr/soc_acpi.c b/src/soc/intel/xeon_sp/gnr/soc_acpi.c new file mode 100644 index 0000000..7aa2561 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/soc_acpi.c @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <acpi/acpigen.h> +#include <arch/smp/mpspec.h> +#include <assert.h> +#include <cbmem.h> +#include <cpu/intel/turbo.h> +#include <device/mmio.h> +#include <device/pci.h> +#include <device/device.h> +#include <intelblocks/acpi.h> +#include <intelblocks/cpulib.h> +#include <intelblocks/pcr.h> +#include <intelblocks/pmclib.h> +#include <intelblocks/p2sb.h> +#include <intelblocks/itss.h> +#include <soc/acpi.h> +#include <soc/cpu.h> +#include <soc/iomap.h> +#include <soc/msr.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/soc_util.h> +#include <soc/util.h> +#include <soc/itss.h> +#include <soc/pcr_ids.h> + +int soc_madt_sci_irq_polarity(int sci) +{ + int reg = sci / IRQS_PER_IPC; + int offset = sci % IRQS_PER_IPC; + uint32_t val = pcr_read32(PID_ITSS, PCR_ITSS_IPC0_CONF + reg * sizeof(uint32_t)); + + if (val & (1 << offset)) { + return MP_IRQ_POLARITY_LOW; + } else { + return MP_IRQ_POLARITY_HIGH; + } +} + +uint32_t soc_read_sci_irq_select(void) +{ + const uint16_t pmbase = ACPI_BASE_ADDRESS; + return inl(pmbase + PMC_ACPI_CNT); +} + +void soc_fill_fadt(acpi_fadt_t *fadt) +{ + const uint16_t pmbase = ACPI_BASE_ADDRESS; + + fadt->pm_tmr_blk = pmbase + PM1_TMR; + fadt->pm_tmr_len = 4; + fadt->flags &= ~(ACPI_FADT_SEALED_CASE | ACPI_FADT_S4_RTC_WAKE); + fadt->preferred_pm_profile = PM_ENTERPRISE_SERVER; +} + +void uncore_fill_ssdt(const struct device *device) +{ + return; +} + +void soc_power_states_generation(int core, int cores_per_package) +{ + generate_p_state_entries(core, cores_per_package); + return; +} + +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->upstream->dev->path.type != DEVICE_PATH_CPU_CLUSTER)) { + continue; + } + if (!cpu->enabled) + continue; + current += acpi_create_madt_one_lapic(current, num_cpus, cpu->path.apic.apic_id); + num_cpus++; + } + + return current; +} + +unsigned long acpi_fill_cedt(unsigned long current) +{ + return current; +} diff --git a/src/soc/intel/xeon_sp/gnr/soc_pmutil.c b/src/soc/intel/xeon_sp/gnr/soc_pmutil.c new file mode 100644 index 0000000..f13c532 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/soc_pmutil.c @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * Helper functions for dealing with power management registers + * and the differences between PCH variants. + */ + +#define __SIMPLE_DEVICE__ + +#include <console/console.h> +#include <device/pci.h> +#include <device/device.h> +#include <intelblocks/pmclib.h> +#include <intelblocks/rtc.h> +#include <soc/pm.h> +#include <soc/pmc.h> + +#include "chip.h" diff --git a/src/soc/intel/xeon_sp/gnr/soc_util.c b/src/soc/intel/xeon_sp/gnr/soc_util.c new file mode 100644 index 0000000..016f332 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/soc_util.c @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <assert.h> +#include <device/device.h> +#include <device/pci.h> +#include <fsp/util.h> +#include <soc/util.h> +#include <soc/acpi.h> +#include <soc/chip_common.h> +#include <soc/cpu.h> +#include <soc/pci_devs.h> +#include <soc/soc_util.h> +#include <stdlib.h> +#include <string.h> +#include <MemoryMapDataHob.h> + +static bool is_stack_uid_matched(const xSTACK_RES *res, uint16_t uid_type) +{ + for (uint8_t index = 0; index < res->PciRootBridgeNum; index++) { + if (res->PciRoot[index].UidType == uid_type) + return true; + } + + return false; +} + +bool is_pcie_iio_stack_res(const xSTACK_RES *res) +{ + return is_stack_uid_matched(res, PC_UID); +} + +bool is_ioat_iio_stack_res(const xSTACK_RES *res) +{ + return (is_stack_uid_matched(res, DINO_UID) || + is_stack_uid_matched(res, CPM0_UID) || + is_stack_uid_matched(res, HQM0_UID)); + +} + +bool is_ubox_stack_res(const xSTACK_RES *res) +{ + return is_stack_uid_matched(res, UB_UID); +} + +bool is_iio_cxl_stack_res(const xSTACK_RES *res) +{ + return false; +} + +const struct SystemMemoryMapHob *get_system_memory_map(void) +{ + size_t hob_size; + const EFI_GUID mem_hob_guid = MEMORY_MAP_HOB_GUID; + const struct SystemMemoryMapHob **memmap_addr; + + memmap_addr = (const struct SystemMemoryMapHob **) + fsp_find_extension_hob_by_guid((uint8_t*)&mem_hob_guid, &hob_size); + /* hob_size is the size of the 8-byte address not the hob data */ + assert(memmap_addr != NULL && hob_size != 0); + /* assert the pointer to the hob is not NULL */ + assert(*memmap_addr != NULL); + + return *memmap_addr; +} + +const struct SystemMemoryMapElement *get_system_memory_map_elment(uint8_t *num) +{ + const struct SystemMemoryMapHob *hob = get_system_memory_map(); + if (!hob) + return NULL; + + *num = hob->numberEntries; + return (hob->Element); +} + +const CXL_NODE_SOCKET *get_cxl_node(void) +{ + size_t hob_size; + static const CXL_NODE_SOCKET *hob; + const EFI_GUID fsp_hob_cxl_node_socket_guid = CXL_NODE_HOB_GUID; + + if (hob != NULL) + return hob; + + hob = fsp_find_extension_hob_by_guid((uint8_t*)&fsp_hob_cxl_node_socket_guid, &hob_size); + if (hob == NULL || hob_size == 0) + { + printk(BIOS_DEBUG, + "CXL_NODE_HOB_GUID not found: CXL may not be installed\n"); + return NULL ; + } + return hob; +} + +uint8_t get_cxl_node_count(void) +{ + const CXL_NODE_SOCKET *hob = get_cxl_node(); + uint8_t count = 0; + + if (hob == NULL) + return 0; + for (uint8_t skt_id = 0 ; skt_id < MAX_SOCKET; skt_id++) + count += hob[skt_id].CxlNodeCount; + + return count; +} + +uint8_t soc_get_iio_ioapicid(int socket, int stack) +{ + return 0xff; +} + +struct uid_to_domain_type { + uint16_t uid; + const char *domain_type; +}; + +static struct uid_to_domain_type uid_to_domain_map[] = { + { .uid = PC_UID, .domain_type = DOMAIN_TYPE_PCIE }, + { .uid = DINO_UID, .domain_type = DOMAIN_TYPE_DINO }, + { .uid = CPM0_UID, .domain_type = DOMAIN_TYPE_CPM0 }, + { .uid = HQM0_UID, .domain_type = DOMAIN_TYPE_HQM0 }, + { .uid = UB_UID, .domain_type = DOMAIN_TYPE_UBX0 }, +}; + +const char* map_uid_to_domain_type(uint16_t uid) +{ + int n = sizeof(uid_to_domain_map)/sizeof(struct uid_to_domain_type); + struct uid_to_domain_type *m; + + for (int i = 0; i < n; i++) { + m = &(uid_to_domain_map[i]); + if (m->uid == uid) + return m->domain_type; + } + + return NULL; +} + +bool is_memtype_reserved(uint16_t mem_type) +{ + return FALSE; +} + +bool is_memtype_non_volatile(uint16_t mem_type) +{ + return FALSE; +} + +bool is_memtype_processor_attached(uint16_t mem_type) +{ + return TRUE; +} diff --git a/src/soc/intel/xeon_sp/include/soc/chip_common.h b/src/soc/intel/xeon_sp/include/soc/chip_common.h index cb7a841..e0c7703 100644 --- a/src/soc/intel/xeon_sp/include/soc/chip_common.h +++ b/src/soc/intel/xeon_sp/include/soc/chip_common.h @@ -13,7 +13,7 @@ u8 bus; u8 stack; u8 socket; - u8 unused; + u8 root; }; };
@@ -23,12 +23,13 @@ #define XEONSP_VENDOR_MAX UINT16_MAX
static inline void init_xeon_domain_path(struct device_path *path, int socket, - int stack, int bus) + int stack, int root, int bus) { union xeon_domain_path dp = { .socket = socket, .stack = stack, .bus = bus, + .root = root, }; path->type = DEVICE_PATH_DOMAIN; path->domain.domain = dp.domain_path; diff --git a/src/soc/intel/xeon_sp/include/soc/fsp_adoption.h b/src/soc/intel/xeon_sp/include/soc/fsp_adoption.h index 8eb1a34..33e0ba8 100644 --- a/src/soc/intel/xeon_sp/include/soc/fsp_adoption.h +++ b/src/soc/intel/xeon_sp/include/soc/fsp_adoption.h @@ -25,4 +25,11 @@ #define xIIO_RESOURCE_INSTANCE IIO_RESOURCE_INSTANCE #endif
+/* + * GNRSRF_HOST is required when using GraniteRapids FSP headers. + */ +#if CONFIG(SOC_INTEL_GRANITERAPIDS) +#define GNRSRF_HOST +#endif + #endif diff --git a/src/soc/intel/xeon_sp/lockdown.c b/src/soc/intel/xeon_sp/lockdown.c index 9e25920..a3d17b4 100644 --- a/src/soc/intel/xeon_sp/lockdown.c +++ b/src/soc/intel/xeon_sp/lockdown.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */
+#include <intelblocks/cfg.h> #include <intelblocks/lpc_lib.h> #include <intelpch/lockdown.h> #include <soc/lockdown.h> @@ -20,6 +21,9 @@
void soc_lockdown_config(int chipset_lockdown) { + if (chipset_lockdown == CHIPSET_LOCKDOWN_FSP) + return; + lpc_lockdown_config(); pmc_lockdown_config(); sata_lockdown_config(chipset_lockdown); diff --git a/src/soc/intel/xeon_sp/uncore.c b/src/soc/intel/xeon_sp/uncore.c index 1db80a2..157749b 100644 --- a/src/soc/intel/xeon_sp/uncore.c +++ b/src/soc/intel/xeon_sp/uncore.c @@ -303,6 +303,12 @@ * * @return The added resource counts. */ +#if CONFIG(PLATFORM_USES_FSP2_4) +int soc_add_dram_resources(struct device *dev, int start_index) +{ + return 0; +} +#else int soc_add_dram_resources(struct device *dev, int start_index) { const struct resource *res; @@ -354,6 +360,7 @@
return index - start_index; } +#endif
static void mmapvtd_read_resources(struct device *dev) { diff --git a/src/soc/intel/xeon_sp/uncore_acpi.c b/src/soc/intel/xeon_sp/uncore_acpi.c index 1ec30a3..e44f6cb 100644 --- a/src/soc/intel/xeon_sp/uncore_acpi.c +++ b/src/soc/intel/xeon_sp/uncore_acpi.c @@ -20,6 +20,10 @@ #include <soc/soc_util.h> #include <soc/util.h> #include <intelblocks/p2sb.h> + +#include <fsp/util.h> +#include <MemoryMapDataHob.h> + #include "chip.h"
/* NUMA related ACPI table generation. SRAT, SLIT, etc */ diff --git a/src/soc/intel/xeon_sp/util.c b/src/soc/intel/xeon_sp/util.c index b3ee02b..8c590d5 100644 --- a/src/soc/intel/xeon_sp/util.c +++ b/src/soc/intel/xeon_sp/util.c @@ -18,6 +18,9 @@ #include <timer.h>
/* Only call this code from socket0! */ +#if CONFIG(SOC_INTEL_GRANITERAPIDS) +void unlock_pam_regions(void) {} +#else void unlock_pam_regions(void) { uint32_t pam0123_unlock_dram = 0x33333330; @@ -38,6 +41,7 @@ printk(BIOS_DEBUG, "%s:%s pam0123_csr: 0x%x, pam456_csr: 0x%x\n", __FILE__, __func__, reg1, reg2); } +#endif
msr_t read_msr_ppin(void) {