diff options
Diffstat (limited to 'src/soc/intel')
113 files changed, 2190 insertions, 479 deletions
diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index 508606961a22..eb5b8c097b9a 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -34,6 +34,7 @@ config SOC_INTEL_ALDERLAKE select INTEL_GMA_VERSION_2 select INTEL_TXT_LIB select MP_SERVICES_PPI_V2 + select MRC_CACHE_USING_MRC_VERSION if SOC_INTEL_ALDERLAKE_PCH_N && !FSP_TYPE_IOT select MRC_SETTINGS_PROTECT select PARALLEL_MP_AP_WORK select PLATFORM_USES_FSP2_2 @@ -82,7 +83,7 @@ config SOC_INTEL_ALDERLAKE select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT select SOC_INTEL_COMMON_RESET - select SOC_INTEL_CSE_SEND_EOP_LATE if !BOARD_GOOGLE_BRYA_COMMON + select SOC_INTEL_CSE_SEND_EOP_LATE if !BOARD_GOOGLE_BRYA_COMMON && !BOARD_GOOGLE_BROX_COMMON select SOC_INTEL_CSE_SET_EOP select SOC_INTEL_GFX_MBUS_JOIN if MAINBOARD_HAS_CHROMEOS && BMP_LOGO select SOC_INTEL_MEM_MAPPED_PM_CONFIGURATION @@ -116,7 +117,7 @@ config SOC_INTEL_TWINLAKE config SOC_INTEL_ALDERLAKE_PCH_N bool - select HAVE_INTEL_FSP_REPO if !SOC_INTEL_TWINLAKE + select HAVE_INTEL_FSP_REPO if FSP_TYPE_IOT select SOC_INTEL_ALDERLAKE help Choose this option if your mainboard has a PCH-N chipset. @@ -146,6 +147,9 @@ config SOC_INTEL_RAPTORLAKE_PCH_S if SOC_INTEL_ALDERLAKE +config DIMM_SPD_SIZE + default 512 + config SOC_INTEL_ALDERLAKE_TCSS_USB4_SUPPORT bool default n if SOC_INTEL_ALDERLAKE_PCH_S @@ -405,7 +409,7 @@ config FSP_HEADER_PATH default "3rdparty/fsp/AlderLakeFspBinPkg/Client/AlderLakeP/Include/" if SOC_INTEL_ALDERLAKE_PCH_P && !SOC_INTEL_RAPTORLAKE default "3rdparty/fsp/RaptorLakeFspBinPkg/Client/RaptorLakeP/Include/" if SOC_INTEL_ALDERLAKE_PCH_P && SOC_INTEL_RAPTORLAKE default "3rdparty/fsp/AlderLakeFspBinPkg/Client/AlderLakeS/Include/" if SOC_INTEL_ALDERLAKE_PCH_S - default "3rdparty/fsp/AlderLakeFspBinPkg/IoT/AlderLakeN/Include/" if SOC_INTEL_ALDERLAKE_PCH_N + default "3rdparty/fsp/AlderLakeFspBinPkg/IoT/AlderLakeN/Include/" if SOC_INTEL_ALDERLAKE_PCH_N && FSP_TYPE_IOT default "src/vendorcode/intel/fsp/fsp2_0/alderlake/" if !FSP_USE_REPO config FSP_FD_PATH @@ -419,7 +423,7 @@ config FSP_FD_PATH default "3rdparty/fsp/AlderLakeFspBinPkg/Client/AlderLakeP/Fsp.fd" if SOC_INTEL_ALDERLAKE_PCH_P && !SOC_INTEL_RAPTORLAKE default "3rdparty/fsp/RaptorLakeFspBinPkg/Client/RaptorLakeP/Fsp.fd" if SOC_INTEL_ALDERLAKE_PCH_P && SOC_INTEL_RAPTORLAKE default "3rdparty/fsp/AlderLakeFspBinPkg/Client/AlderLakeS/Fsp.fd" if SOC_INTEL_ALDERLAKE_PCH_S - default "3rdparty/fsp/AlderLakeFspBinPkg/IoT/AlderLakeN/Fsp.fd" if SOC_INTEL_ALDERLAKE_PCH_N + default "3rdparty/fsp/AlderLakeFspBinPkg/IoT/AlderLakeN/Fsp.fd" if SOC_INTEL_ALDERLAKE_PCH_N && FSP_TYPE_IOT config SOC_INTEL_ALDERLAKE_DEBUG_CONSENT int "Debug Consent for ADL" diff --git a/src/soc/intel/alderlake/cpu.c b/src/soc/intel/alderlake/cpu.c index 5b1a690b9e13..92b253216ae5 100644 --- a/src/soc/intel/alderlake/cpu.c +++ b/src/soc/intel/alderlake/cpu.c @@ -11,6 +11,7 @@ #include <device/pci_ids.h> #include <cpu/x86/mp.h> #include <cpu/x86/msr.h> +#include <cpu/intel/microcode.h> #include <cpu/intel/smm_reloc.h> #include <cpu/intel/turbo.h> #include <cpu/intel/common/common.h> @@ -333,3 +334,24 @@ uint8_t get_supported_lpm_mask(void) return 0; } } + +int soc_skip_ucode_update(u32 current_patch_id, u32 new_patch_id) +{ + if (!CONFIG(CHROMEOS)) + return 0; + /* + * Locked RO Descriptor Implications: + * + * - A locked descriptor signals the RO binary is fixed; the FIT will load the + * RO's microcode during system reset. + * - Attempts to load newer microcode from the RW CBFS will cause a boot-time + * delay (~60ms, core-dependent), as the microcode must be reloaded on BSP+APs. + * - The kernel can load microcode updates without impacting AP FW boot time. + * - Skipping RW CBFS microcode loading is low-risk when the RO is locked, + * prioritizing fast boot times. + */ + if (CONFIG(LOCK_MANAGEMENT_ENGINE) && current_patch_id) + return 1; + + return 0; +} diff --git a/src/soc/intel/alderlake/fsp_params.c b/src/soc/intel/alderlake/fsp_params.c index ff5c83c3af18..d7b30c64da6c 100644 --- a/src/soc/intel/alderlake/fsp_params.c +++ b/src/soc/intel/alderlake/fsp_params.c @@ -932,7 +932,7 @@ static void fill_fsps_pcie_params(FSP_S_CONFIG *s_cfg, } s_cfg->PcieComplianceTestMode = CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE); -#if CONFIG(FSP_TYPE_IOT) +#if CONFIG(FSP_TYPE_IOT) && !CONFIG(SOC_INTEL_ALDERLAKE_PCH_N) /* * Intel requires that all enabled PCH PCIe ports have a CLK_REQ signal connected. * The CLK_REQ is used to wake the silicon when link entered L1 link-state. L1 diff --git a/src/soc/intel/alderlake/romstage/fsp_params.c b/src/soc/intel/alderlake/romstage/fsp_params.c index 84f83e3bbe5b..d917e6cdfecc 100644 --- a/src/soc/intel/alderlake/romstage/fsp_params.c +++ b/src/soc/intel/alderlake/romstage/fsp_params.c @@ -271,6 +271,11 @@ static void fill_fspm_tcss_params(FSP_M_CONFIG *m_cfg, m_cfg->TcssDma0En = is_devfn_enabled(SA_DEVFN_TCSS_DMA0); m_cfg->TcssDma1En = is_devfn_enabled(SA_DEVFN_TCSS_DMA1); + m_cfg->UsbTcPortEnPreMem = 0; + for (int i = 0; i < MAX_TYPE_C_PORTS; i++) + if (config->tcss_ports[i].enable) + m_cfg->UsbTcPortEnPreMem |= BIT(i); + #if (CONFIG(SOC_INTEL_RAPTORLAKE) && !CONFIG(FSP_USE_REPO)) || \ (!CONFIG(SOC_INTEL_ALDERLAKE_PCH_N) && CONFIG(FSP_USE_REPO)) m_cfg->DisableDynamicTccoldHandshake = diff --git a/src/soc/intel/apollolake/cpu.c b/src/soc/intel/apollolake/cpu.c index a49bf471a9a6..b8bf39197ea5 100644 --- a/src/soc/intel/apollolake/cpu.c +++ b/src/soc/intel/apollolake/cpu.c @@ -13,6 +13,7 @@ #include <cpu/x86/mtrr.h> #include <cpu/x86/smm.h> #include <cpu/intel/em64t100_save_state.h> +#include <cpu/intel/microcode.h> #include <cpu/intel/smm_reloc.h> #include <device/device.h> #include <device/pci.h> @@ -279,3 +280,26 @@ void mp_init_cpus(struct bus *cpu_bus) CONFIG(BOOT_DEVICE_SPI_FLASH)) fast_spi_cache_bios_region(); } + +#if CONFIG(SOC_INTEL_GEMINILAKE) +int soc_skip_ucode_update(u32 current_patch_id, u32 new_patch_id) +{ + /* + * If PRMRR/SGX is supported the FIT microcode load will set the msr + * 0x08b with the Patch revision id one less than the id in the + * microcode binary. The PRMRR support is indicated in the MSR + * MTRRCAP[12]. If SGX is not enabled, check and avoid reloading the + * same microcode during CPU initialization. If SGX is enabled, as + * part of SGX BIOS initialization steps, the same microcode needs to + * be reloaded after the core PRMRR MSRs are programmed. + */ + const msr_t mtrr_cap = rdmsr(MTRR_CAP_MSR); + if (mtrr_cap.lo & MTRR_CAP_PRMRR) { + const msr_t prmrr_phys_base = rdmsr(MSR_PRMRR_PHYS_BASE); + if (prmrr_phys_base.raw) { + return 0; + } + } + return current_patch_id == new_patch_id - 1; +} +#endif diff --git a/src/soc/intel/baytrail/Kconfig b/src/soc/intel/baytrail/Kconfig index 02b93c97ec38..09fdbbaae40b 100644 --- a/src/soc/intel/baytrail/Kconfig +++ b/src/soc/intel/baytrail/Kconfig @@ -33,6 +33,7 @@ config SOC_INTEL_BAYTRAIL select CPU_HAS_L2_ENABLE_MSR select TCO_SPACE_NOT_YET_SPLIT select USE_DDR3 + select NEED_SMALL_2MB_PAGE_TABLES help Bay Trail M/D part support. diff --git a/src/soc/intel/baytrail/romstage/raminit.c b/src/soc/intel/baytrail/romstage/raminit.c index b64364bed81c..6244072c55cf 100644 --- a/src/soc/intel/baytrail/romstage/raminit.c +++ b/src/soc/intel/baytrail/romstage/raminit.c @@ -59,7 +59,7 @@ static void populate_smbios_tables(void *dram_data, int speed, int num_channels) enum spd_status status; /* Decode into dimm_attr struct */ - status = spd_decode_ddr3(&dimm, *(spd_raw_data *)dram_data); + status = spd_decode_ddr3(&dimm, *(spd_ddr3_raw_data *)dram_data); /* Some SPDs have bad CRCs, nothing we can do about it */ if (status == SPD_STATUS_OK || status == SPD_STATUS_CRC_ERROR) { diff --git a/src/soc/intel/braswell/Kconfig b/src/soc/intel/braswell/Kconfig index d9bb481a1b8f..9b96d112fce0 100644 --- a/src/soc/intel/braswell/Kconfig +++ b/src/soc/intel/braswell/Kconfig @@ -39,6 +39,7 @@ config SOC_INTEL_BRASWELL select SOUTHBRIDGE_INTEL_COMMON_SPI_SILVERMONT select NO_CBFS_MCACHE select TCO_SPACE_NOT_YET_SPLIT + select NEED_SMALL_2MB_PAGE_TABLES help Braswell M/D part support. diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig index 7548e46b364a..3aa06f43d864 100644 --- a/src/soc/intel/cannonlake/Kconfig +++ b/src/soc/intel/cannonlake/Kconfig @@ -64,7 +64,7 @@ config SOC_INTEL_CANNONLAKE_BASE select SOC_INTEL_COMMON_NHLT select SOC_INTEL_COMMON_PCH_CLIENT select SOC_INTEL_COMMON_RESET - select SOC_INTEL_CONFIGURE_DDI_A_4_LANES + select SOC_INTEL_GFX_HAVE_DDI_A_BIFURCATION select SOC_INTEL_MEM_MAPPED_PM_CONFIGURATION select SSE2 select SUPPORT_CPU_UCODE_IN_CBFS diff --git a/src/soc/intel/cannonlake/acpi.c b/src/soc/intel/cannonlake/acpi.c index 9cad4ffaebd8..a58c4f01f4e2 100644 --- a/src/soc/intel/cannonlake/acpi.c +++ b/src/soc/intel/cannonlake/acpi.c @@ -255,10 +255,9 @@ int soc_madt_sci_irq_polarity(int sci) static unsigned long soc_fill_dmar(unsigned long current) { - struct device *const igfx_dev = pcidev_path_on_root(SA_DEVFN_IGD); uint64_t gfxvtbar = MCHBAR64(GFXVTBAR) & VTBAR_MASK; bool gfxvten = MCHBAR32(GFXVTBAR) & VTBAR_ENABLED; - const bool emit_igd = igfx_dev && igfx_dev->enabled && gfxvtbar && gfxvten; + const bool emit_igd = is_devfn_enabled(SA_DEVFN_IGD) && gfxvtbar && gfxvten; if (emit_igd) { unsigned long tmp = current; @@ -268,11 +267,10 @@ static unsigned long soc_fill_dmar(unsigned long current) acpi_dmar_drhd_fixup(tmp, current); } - struct device *const ipu_dev = pcidev_path_on_root(SA_DEVFN_IPU); uint64_t ipuvtbar = MCHBAR64(IPUVTBAR) & VTBAR_MASK; bool ipuvten = MCHBAR32(IPUVTBAR) & VTBAR_ENABLED; - if (ipu_dev && ipu_dev->enabled && ipuvtbar && ipuvten) { + if (is_devfn_enabled(SA_DEVFN_IPU) && ipuvtbar && ipuvten) { unsigned long tmp = current; current += acpi_create_dmar_drhd(current, 0, 0, ipuvtbar); diff --git a/src/soc/intel/cannonlake/chip.c b/src/soc/intel/cannonlake/chip.c index bda66bd1ddf6..e2e4a6bda5ee 100644 --- a/src/soc/intel/cannonlake/chip.c +++ b/src/soc/intel/cannonlake/chip.c @@ -2,6 +2,7 @@ #include <device/device.h> #include <device/pci.h> +#include <device/pci_ids.h> #include <fsp/api.h> #include <fsp/util.h> #include <gpio.h> @@ -153,10 +154,20 @@ void soc_init_pre_device(void *chip_info) soc_gpio_pm_configuration(); /* swap enabled PCI ports in device tree if needed */ - if (CONFIG(SOC_INTEL_CANNONLAKE_PCH_H)) + if (CONFIG(SOC_INTEL_CANNONLAKE_PCH_H)) { pcie_rp_update_devicetree(pch_h_rp_groups); - else + + /* + * Fix up device ID of hidden PCI device in devicetree. + * This is used by soc/intel/common/block/uart.c to generate ACPI + */ + struct device *uart2 = PCH_DEV_UART2; + if (uart2->hidden) + uart2->device = PCI_DID_INTEL_CNP_H_UART2; + + } else { pcie_rp_update_devicetree(pch_lp_rp_groups); + } } static void cpu_fill_ssdt(const struct device *dev) diff --git a/src/soc/intel/cannonlake/chipset_pch_h.cb b/src/soc/intel/cannonlake/chipset_pch_h.cb index 022e31f67d9b..77c0d8435184 100644 --- a/src/soc/intel/cannonlake/chipset_pch_h.cb +++ b/src/soc/intel/cannonlake/chipset_pch_h.cb @@ -92,7 +92,9 @@ chip soc/intel/cannonlake device pci 17.0 alias sata off end # SATA device pci 19.0 alias i2c4 off end # I2C #4 device pci 19.1 alias i2c5 off end # I2C #5 - device pci 19.2 alias uart2 off end # UART #2 + device pci 19.2 alias uart2 off # UART #2 + ops uart_ops + end device pci 1a.0 alias emmc off end # eMMC device pci 1b.0 alias pcie_rp17 off end # PCI Express Port 17 device pci 1b.1 alias pcie_rp18 off end # PCI Express Port 18 diff --git a/src/soc/intel/cannonlake/romstage/fsp_params.c b/src/soc/intel/cannonlake/romstage/fsp_params.c index 737e7c399d1e..2b25285ffa6c 100644 --- a/src/soc/intel/cannonlake/romstage/fsp_params.c +++ b/src/soc/intel/cannonlake/romstage/fsp_params.c @@ -32,8 +32,7 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) * Probe for no IGD and disable InternalGfx and panel power to prevent a * crash in FSP-M. */ - dev = pcidev_path_on_root(SA_DEVFN_IGD); - const bool igd_on = !CONFIG(SOC_INTEL_DISABLE_IGD) && dev && dev->enabled; + const bool igd_on = !CONFIG(SOC_INTEL_DISABLE_IGD) && is_devfn_enabled(SA_DEVFN_IGD); if (igd_on && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) != 0xffff) { /* Set IGD stolen size to 64MB. */ m_cfg->InternalGfx = 1; @@ -90,25 +89,11 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) m_cfg->CpuRatio = (flex_ratio.lo >> 8) & 0xff; } - dev = pcidev_path_on_root(PCH_DEVFN_ISH); - /* If ISH is enabled, enable ISH elements */ - if (!dev) - m_cfg->PchIshEnable = 0; - else - m_cfg->PchIshEnable = dev->enabled; + m_cfg->PchIshEnable = is_devfn_enabled(PCH_DEVFN_ISH); - /* If HDA is enabled, enable HDA elements */ - dev = pcidev_path_on_root(PCH_DEVFN_HDA); - if (!dev) - m_cfg->PchHdaEnable = 0; - else - m_cfg->PchHdaEnable = dev->enabled; + m_cfg->PchHdaEnable = is_devfn_enabled(PCH_DEVFN_HDA); - /* Enable IPU only if the device is enabled */ - m_cfg->SaIpuEnable = 0; - dev = pcidev_path_on_root(SA_DEVFN_IPU); - if (dev) - m_cfg->SaIpuEnable = dev->enabled; + m_cfg->SaIpuEnable = is_devfn_enabled(SA_DEVFN_IPU); /* SATA Gen3 strength */ for (i = 0; i < SOC_INTEL_CML_SATA_DEV_MAX; i++) { @@ -136,12 +121,7 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) tconfig->DisableHeciRetry = config->DisableHeciRetry; #endif - /* Enable SMBus controller based on config */ - dev = pcidev_path_on_root(PCH_DEVFN_SMBUS); - if (!dev) - m_cfg->SmbusEnable = 0; - else - m_cfg->SmbusEnable = dev->enabled; + m_cfg->SmbusEnable = is_devfn_enabled(PCH_DEVFN_SMBUS); /* Set debug probe type */ m_cfg->PlatformDebugConsent = diff --git a/src/soc/intel/common/block/acpi/cpu_hybrid.c b/src/soc/intel/common/block/acpi/cpu_hybrid.c index f52b68f7e222..68abba7eb8d6 100644 --- a/src/soc/intel/common/block/acpi/cpu_hybrid.c +++ b/src/soc/intel/common/block/acpi/cpu_hybrid.c @@ -9,6 +9,7 @@ #include <device/path.h> #include <intelblocks/acpi.h> #include <soc/cpu.h> +#include <stdio.h> #include <types.h> #define CPPC_NOM_FREQ_IDX 22 diff --git a/src/soc/intel/common/block/cnvi/cnvi.c b/src/soc/intel/common/block/cnvi/cnvi.c index fed95492f7e8..62c4615d602d 100644 --- a/src/soc/intel/common/block/cnvi/cnvi.c +++ b/src/soc/intel/common/block/cnvi/cnvi.c @@ -21,6 +21,14 @@ static struct device_operations cnvi_wifi_ops = { }; static const unsigned short wifi_pci_device_ids[] = { + PCI_DID_INTEL_PTL_CNVI_WIFI_0, + PCI_DID_INTEL_PTL_CNVI_WIFI_1, + PCI_DID_INTEL_PTL_CNVI_WIFI_2, + PCI_DID_INTEL_PTL_CNVI_WIFI_3, + PCI_DID_INTEL_LNL_CNVI_WIFI_0, + PCI_DID_INTEL_LNL_CNVI_WIFI_1, + PCI_DID_INTEL_LNL_CNVI_WIFI_2, + PCI_DID_INTEL_LNL_CNVI_WIFI_3, PCI_DID_INTEL_MTL_CNVI_WIFI_0, PCI_DID_INTEL_MTL_CNVI_WIFI_1, PCI_DID_INTEL_MTL_CNVI_WIFI_2, diff --git a/src/soc/intel/common/block/cpu/mp_init.c b/src/soc/intel/common/block/cpu/mp_init.c index 7abbb4063e2e..d5cc88397397 100644 --- a/src/soc/intel/common/block/cpu/mp_init.c +++ b/src/soc/intel/common/block/cpu/mp_init.c @@ -32,7 +32,9 @@ static struct device_operations cpu_dev_ops = { }; static const struct cpu_device_id cpu_table[] = { + { X86_VENDOR_INTEL, CPUID_PANTHERLAKE_A0, CPUID_EXACT_MATCH_MASK }, { X86_VENDOR_INTEL, CPUID_LUNARLAKE_A0_1, CPUID_EXACT_MATCH_MASK }, + { X86_VENDOR_INTEL, CPUID_LUNARLAKE_A0_2, CPUID_EXACT_MATCH_MASK }, { X86_VENDOR_INTEL, CPUID_METEORLAKE_A0_1, CPUID_EXACT_MATCH_MASK }, { X86_VENDOR_INTEL, CPUID_METEORLAKE_A0_2, CPUID_EXACT_MATCH_MASK }, { X86_VENDOR_INTEL, CPUID_METEORLAKE_B0, CPUID_EXACT_MATCH_MASK }, diff --git a/src/soc/intel/common/block/crashlog/crashlog.c b/src/soc/intel/common/block/crashlog/crashlog.c index a9ac8a530ecd..d92d7bc69b8b 100644 --- a/src/soc/intel/common/block/crashlog/crashlog.c +++ b/src/soc/intel/common/block/crashlog/crashlog.c @@ -112,7 +112,7 @@ int cpu_cl_poll_mailbox_ready(u32 cl_mailbox_addr) u16 stall_cnt = 0; do { - cl_mailbox_interface.data = read32((u32 *)cl_mailbox_addr); + cl_mailbox_interface.data = read32((u32 *)(uintptr_t)cl_mailbox_addr); udelay(CPU_CRASHLOG_WAIT_STALL); stall_cnt++; } while ((cl_mailbox_interface.fields.busy == 1) @@ -140,7 +140,7 @@ int cpu_cl_mailbox_cmd(u8 cmd, u8 param) cl_mailbox_intf.fields.param = param; cl_mailbox_intf.fields.busy = 1; - write32((u32 *)(cl_base_addr + cl_get_cpu_mb_int_addr()), + write32((u32 *)(uintptr_t)(cl_base_addr + cl_get_cpu_mb_int_addr()), cl_mailbox_intf.data); cpu_cl_poll_mailbox_ready(cl_base_addr + cl_get_cpu_mb_int_addr()); @@ -167,7 +167,7 @@ int pmc_cl_gen_descriptor_table(u32 desc_table_addr, pmc_crashlog_desc_table_t *descriptor_table) { int total_data_size = 0; - descriptor_table->numb_regions = read32((u32 *)desc_table_addr); + descriptor_table->numb_regions = read32((u32 *)(uintptr_t)desc_table_addr); printk(BIOS_DEBUG, "CL PMC desc table: numb of regions is 0x%x at addr 0x%x\n", descriptor_table->numb_regions, desc_table_addr); for (int i = 0; i < descriptor_table->numb_regions; i++) { @@ -178,7 +178,7 @@ int pmc_cl_gen_descriptor_table(u32 desc_table_addr, break; } desc_table_addr += 4; - descriptor_table->regions[i].data = read32((u32 *)(desc_table_addr)); + descriptor_table->regions[i].data = read32((u32 *)(uintptr_t)(desc_table_addr)); total_data_size += descriptor_table->regions[i].bits.size * sizeof(u32); printk(BIOS_DEBUG, "CL PMC desc table: region 0x%x has size 0x%x at offset 0x%x\n", i, descriptor_table->regions[i].bits.size, @@ -295,7 +295,7 @@ bool cl_copy_data_from_sram(u32 src_bar, u32 src_addr = src_bar + offset; - u32 data = read32((u32 *)src_addr); + u32 data = read32((u32 *)(uintptr_t)src_addr); /* First 32bits of the record must not be 0xdeadbeef */ if (data == INVALID_CRASHLOG_RECORD) { @@ -320,7 +320,7 @@ bool cl_copy_data_from_sram(u32 src_bar, u32 copied = 0; while (copied < size) { /* DW by DW copy: byte access to PMC SRAM not allowed */ - *dest_addr = read32((u32 *)src_addr); + *dest_addr = read32((u32 *)(uintptr_t)src_addr); dest_addr++; src_addr += 4; copied++; diff --git a/src/soc/intel/common/block/cse/Kconfig b/src/soc/intel/common/block/cse/Kconfig index b0524ea4f808..edc7e23d1b3b 100644 --- a/src/soc/intel/common/block/cse/Kconfig +++ b/src/soc/intel/common/block/cse/Kconfig @@ -150,6 +150,16 @@ config SOC_INTEL_CSE_SEND_EOP_BY_PAYLOAD In this case, the HECI interface needs to stay visible and the payload must support sending commands to CSE. +config SOC_INTEL_CSE_LITE_SYNC_BY_PAYLOAD + bool + depends on SOC_INTEL_COMMON_BLOCK_CSE + help + Use this config to specify that the payload will update the CSE RW partition instead + of coreboot. + + In this case, CSE shall not switch to RW partition and the payload must support + CSE RW update. + config SOC_INTEL_CSE_LITE_SKU bool default n diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c index d0ca57bc054f..d78b8a010129 100644 --- a/src/soc/intel/common/block/cse/cse.c +++ b/src/soc/intel/common/block/cse/cse.c @@ -1475,6 +1475,7 @@ struct device_operations cse_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_PTL_CSE0, PCI_DID_INTEL_LNL_CSE0, PCI_DID_INTEL_MTL_CSE0, PCI_DID_INTEL_APL_CSE0, diff --git a/src/soc/intel/common/block/cse/cse_lite.c b/src/soc/intel/common/block/cse/cse_lite.c index 3579bcea78dd..6e5b451c1249 100644 --- a/src/soc/intel/common/block/cse/cse_lite.c +++ b/src/soc/intel/common/block/cse/cse_lite.c @@ -923,6 +923,9 @@ static bool is_cse_fw_update_enabled(void) if (!CONFIG(SOC_INTEL_CSE_RW_UPDATE)) return false; + if (CONFIG(SOC_INTEL_CSE_LITE_SYNC_BY_PAYLOAD)) + return false; + if (CONFIG(SOC_INTEL_COMMON_BASECODE_DEBUG_FEATURE)) return !is_debug_cse_fw_update_disable(); @@ -1499,6 +1502,9 @@ static void do_cse_fw_sync(void) void cse_fw_sync(void) { + if (CONFIG(SOC_INTEL_CSE_LITE_SYNC_BY_PAYLOAD)) + return; + timestamp_add_now(TS_CSE_FW_SYNC_START); do_cse_fw_sync(); timestamp_add_now(TS_CSE_FW_SYNC_END); diff --git a/src/soc/intel/common/block/dsp/dsp.c b/src/soc/intel/common/block/dsp/dsp.c index 1f11df06cf2d..7e8322e38290 100644 --- a/src/soc/intel/common/block/dsp/dsp.c +++ b/src/soc/intel/common/block/dsp/dsp.c @@ -13,6 +13,14 @@ static struct device_operations dsp_dev_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_PTL_AUDIO_1, + PCI_DID_INTEL_PTL_AUDIO_2, + PCI_DID_INTEL_PTL_AUDIO_3, + PCI_DID_INTEL_PTL_AUDIO_4, + PCI_DID_INTEL_PTL_AUDIO_5, + PCI_DID_INTEL_PTL_AUDIO_6, + PCI_DID_INTEL_PTL_AUDIO_7, + PCI_DID_INTEL_PTL_AUDIO_8, PCI_DID_INTEL_LNL_AUDIO_1, PCI_DID_INTEL_LNL_AUDIO_2, PCI_DID_INTEL_LNL_AUDIO_3, diff --git a/src/soc/intel/common/block/fast_spi/fast_spi_flash.c b/src/soc/intel/common/block/fast_spi/fast_spi_flash.c index e9cfc230a409..a7762711fa76 100644 --- a/src/soc/intel/common/block/fast_spi/fast_spi_flash.c +++ b/src/soc/intel/common/block/fast_spi/fast_spi_flash.c @@ -75,18 +75,28 @@ static uint32_t fast_spi_flash_read_sfdp(struct fast_spi_flash_ctx *ctx, /* Fill FDATAn FIFO in preparation for a write transaction. */ static void fill_xfer_fifo(struct fast_spi_flash_ctx *ctx, const void *data, - size_t len) + size_t len) { - /* YES! memcpy() works. FDATAn does not require 32-bit accesses. */ - memcpy((void *)(ctx->mmio_base + SPIBAR_FDATA(0)), data, len); + const uint32_t *data32 = (const uint32_t *)data; + for (size_t i = 0; i < len / sizeof(uint32_t); i++) + write32p(ctx->mmio_base + SPIBAR_FDATA(i), *data32++); + + const uint8_t *data8 = (const uint8_t *)data32; + for (size_t i = 0; i < len % sizeof(uint32_t); i++) + write8p(ctx->mmio_base + SPIBAR_FDATA(len / sizeof(uint32_t)) + i, *data8++); } /* Drain FDATAn FIFO after a read transaction populates data. */ -static void drain_xfer_fifo(struct fast_spi_flash_ctx *ctx, void *dest, +static void drain_xfer_fifo(struct fast_spi_flash_ctx *ctx, void *data, size_t len) { - /* YES! memcpy() works. FDATAn does not require 32-bit accesses. */ - memcpy(dest, (void *)(ctx->mmio_base + SPIBAR_FDATA(0)), len); + uint32_t *data32 = (uint32_t *)data; + for (size_t i = 0; i < len / sizeof(uint32_t); i++) + *data32++ = read32p(ctx->mmio_base + SPIBAR_FDATA(i)); + + uint8_t *data8 = (uint8_t *)data32; + for (size_t i = 0; i < len % sizeof(uint32_t); i++) + *data8++ = read8p(ctx->mmio_base + SPIBAR_FDATA(len / sizeof(uint32_t)) + i); } /* Fire up a transfer using the hardware sequencer. */ diff --git a/src/soc/intel/common/block/graphics/Kconfig b/src/soc/intel/common/block/graphics/Kconfig index b5776b049fa4..eaa429ed393e 100644 --- a/src/soc/intel/common/block/graphics/Kconfig +++ b/src/soc/intel/common/block/graphics/Kconfig @@ -8,10 +8,20 @@ config SOC_INTEL_COMMON_BLOCK_GRAPHICS if SOC_INTEL_COMMON_BLOCK_GRAPHICS -config SOC_INTEL_CONFIGURE_DDI_A_4_LANES +config SOC_INTEL_GFX_HAVE_DDI_A_BIFURCATION bool help - Selected by platforms that require DDI-A bifurcation setup. + Skylake, Kaby Lake and Coffee Lake desktop CPUs support eDP + bifurcation, i.e. 4 eDP lanes get split between DDI-A (eDP) + and DDI-E (DP, used for VGA). Selected from SoC Kconfig, if + applicable. + +config SOC_INTEL_GFX_ENABLE_DDI_E_BIFURCATION + bool + depends on SOC_INTEL_GFX_HAVE_DDI_A_BIFURCATION + help + Selected by mainboards that use DDI-E, which is most commonly + used to drive a DP-to-VGA adapter to provide a VGA connector. config SOC_INTEL_DISABLE_IGD bool "Disable Integrated GFX Controller (0:2:0)" diff --git a/src/soc/intel/common/block/graphics/graphics.c b/src/soc/intel/common/block/graphics/graphics.c index eabcb9a5a8ca..1606b96485c7 100644 --- a/src/soc/intel/common/block/graphics/graphics.c +++ b/src/soc/intel/common/block/graphics/graphics.c @@ -124,6 +124,21 @@ int fsp_soc_report_external_display(void) return graphics_get_framebuffer_address() && get_external_display_status(); } +static void configure_ddi_a_bifurcation(void) +{ + u32 ddi_buf_ctl = graphics_gtt_read(DDI_BUF_CTL_A); + /* Only program if the buffer is not enabled yet. */ + if (ddi_buf_ctl & DDI_BUF_CTL_ENABLE) + return; + + if (CONFIG(SOC_INTEL_GFX_ENABLE_DDI_E_BIFURCATION)) + ddi_buf_ctl &= ~DDI_A_4_LANES; + else + ddi_buf_ctl |= DDI_A_4_LANES; + + graphics_gtt_write(DDI_BUF_CTL_A, ddi_buf_ctl); +} + static void gma_init(struct device *const dev) { intel_gma_init_igd_opregion(); @@ -135,12 +150,8 @@ static void gma_init(struct device *const dev) if (!CONFIG(RUN_FSP_GOP)) graphics_soc_panel_init(dev); - if (CONFIG(SOC_INTEL_CONFIGURE_DDI_A_4_LANES) && !acpi_is_wakeup_s3()) { - const u32 ddi_buf_ctl = graphics_gtt_read(DDI_BUF_CTL_A); - /* Only program if the buffer is not enabled yet. */ - if (!(ddi_buf_ctl & DDI_BUF_CTL_ENABLE)) - graphics_gtt_write(DDI_BUF_CTL_A, ddi_buf_ctl | DDI_A_4_LANES); - } + if (CONFIG(SOC_INTEL_GFX_HAVE_DDI_A_BIFURCATION) && !acpi_is_wakeup_s3()) + configure_ddi_a_bifurcation(); /* * GFX PEIM module inside FSP binary is taking care of graphics @@ -332,6 +343,7 @@ const struct device_operations graphics_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_PTL_GT2, PCI_DID_INTEL_LNL_M_GT2, PCI_DID_INTEL_RPL_U_GT1, PCI_DID_INTEL_RPL_U_GT2, @@ -348,6 +360,7 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_MTL_P_GT2_2, PCI_DID_INTEL_MTL_P_GT2_3, PCI_DID_INTEL_MTL_P_GT2_4, + PCI_DID_INTEL_MTL_P_GT2_5, PCI_DID_INTEL_APL_IGD_HD_505, PCI_DID_INTEL_APL_IGD_HD_500, PCI_DID_INTEL_CNL_GT2_ULX_1, diff --git a/src/soc/intel/common/block/hda/hda.c b/src/soc/intel/common/block/hda/hda.c index 44c03417b20c..ca503126752b 100644 --- a/src/soc/intel/common/block/hda/hda.c +++ b/src/soc/intel/common/block/hda/hda.c @@ -21,6 +21,14 @@ struct device_operations hda_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_PTL_AUDIO_1, + PCI_DID_INTEL_PTL_AUDIO_2, + PCI_DID_INTEL_PTL_AUDIO_3, + PCI_DID_INTEL_PTL_AUDIO_4, + PCI_DID_INTEL_PTL_AUDIO_5, + PCI_DID_INTEL_PTL_AUDIO_6, + PCI_DID_INTEL_PTL_AUDIO_7, + PCI_DID_INTEL_PTL_AUDIO_8, PCI_DID_INTEL_LNL_AUDIO_1, PCI_DID_INTEL_LNL_AUDIO_2, PCI_DID_INTEL_LNL_AUDIO_3, diff --git a/src/soc/intel/common/block/i2c/i2c.c b/src/soc/intel/common/block/i2c/i2c.c index c0f0b6e0bab6..f84b2cd32850 100644 --- a/src/soc/intel/common/block/i2c/i2c.c +++ b/src/soc/intel/common/block/i2c/i2c.c @@ -174,6 +174,12 @@ struct device_operations i2c_dev_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_PTL_I2C0, + PCI_DID_INTEL_PTL_I2C1, + PCI_DID_INTEL_PTL_I2C2, + PCI_DID_INTEL_PTL_I2C3, + PCI_DID_INTEL_PTL_I2C4, + PCI_DID_INTEL_PTL_I2C5, PCI_DID_INTEL_LNL_I2C0, PCI_DID_INTEL_LNL_I2C1, PCI_DID_INTEL_LNL_I2C2, diff --git a/src/soc/intel/common/block/include/intelblocks/vtd.h b/src/soc/intel/common/block/include/intelblocks/vtd.h index 222101a2444e..137124b43a61 100644 --- a/src/soc/intel/common/block/include/intelblocks/vtd.h +++ b/src/soc/intel/common/block/include/intelblocks/vtd.h @@ -3,8 +3,42 @@ #ifndef SOC_INTEL_COMMON_BLOCK_VTD_H #define SOC_INTEL_COMMON_BLOCK_VTD_H +#include <device/mmio.h> #include <stdint.h> +/* VT-d specification: https://cdrdv2.intel.com/v1/dl/getContent/671081 */ +#define VER_REG 0x0 +#define CAP_REG 0x8 +#define CAP_PMR_LO BIT(5) +#define CAP_PMR_HI BIT(6) +#define PMEN_REG 0x64 +#define PMEN_EPM BIT(31) +#define PMEN_PRS BIT(0) +#define PLMBASE_REG 0x68 +#define PLMLIMIT_REG 0x6C +#define PHMBASE_REG 0x70 +#define PHMLIMIT_REG 0x78 + +static __always_inline uint32_t vtd_read32(uintptr_t vtd_base, uint32_t reg) +{ + return read32p(vtd_base + reg); +} + +static __always_inline void vtd_write32(uintptr_t vtd_base, uint32_t reg, uint32_t value) +{ + return write32p(vtd_base + reg, value); +} + +static __always_inline uint64_t vtd_read64(uintptr_t vtd_base, uint32_t reg) +{ + return read64p(vtd_base + reg); +} + +static __always_inline void vtd_write64(uintptr_t vtd_base, uint32_t reg, uint64_t value) +{ + return write64p(vtd_base + reg, value); +} + /* * Enable DMA protection by setting PMR registers in VT-d for whole DRAM memory. */ diff --git a/src/soc/intel/common/block/ipu/ipu.c b/src/soc/intel/common/block/ipu/ipu.c index b2d3904b06d1..989da2e76a01 100644 --- a/src/soc/intel/common/block/ipu/ipu.c +++ b/src/soc/intel/common/block/ipu/ipu.c @@ -12,6 +12,7 @@ struct device_operations ipu_pci_ops = { }; static const uint16_t pci_device_ids[] = { + PCI_DID_INTEL_PTL_IPU, PCI_DID_INTEL_LNL_IPU, PCI_DID_INTEL_RPL_IPU, PCI_DID_INTEL_MTL_IPU, diff --git a/src/soc/intel/common/block/irq/irq.c b/src/soc/intel/common/block/irq/irq.c index 4ffe1387983a..386538e61b4d 100644 --- a/src/soc/intel/common/block/irq/irq.c +++ b/src/soc/intel/common/block/irq/irq.c @@ -373,7 +373,7 @@ bool generate_pin_irq_map(void) if (!cached_entries) return false; - pin_irq_map = calloc(MAX_SLOTS, sizeof(struct slot_pin_irq_map) * PCI_INT_MAX); + pin_irq_map = calloc(MAX_SLOTS * PCI_INT_MAX, sizeof(struct slot_pin_irq_map)); pirq_map.type = PIRQ_GSI; legacy_pirq_routing = lpc_get_pic_pirq_routing(&pirq_routes); diff --git a/src/soc/intel/common/block/lpc/lpc.c b/src/soc/intel/common/block/lpc/lpc.c index e8050354bcdf..0b8c722a69ac 100644 --- a/src/soc/intel/common/block/lpc/lpc.c +++ b/src/soc/intel/common/block/lpc/lpc.c @@ -141,6 +141,14 @@ struct device_operations lpc_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_PTL_ESPI_0, + PCI_DID_INTEL_PTL_ESPI_1, + PCI_DID_INTEL_PTL_ESPI_2, + PCI_DID_INTEL_PTL_ESPI_3, + PCI_DID_INTEL_PTL_ESPI_4, + PCI_DID_INTEL_PTL_ESPI_5, + PCI_DID_INTEL_PTL_ESPI_6, + PCI_DID_INTEL_PTL_ESPI_7, PCI_DID_INTEL_LNL_ESPI_0, PCI_DID_INTEL_LNL_ESPI_1, PCI_DID_INTEL_LNL_ESPI_2, diff --git a/src/soc/intel/common/block/pcie/pcie.c b/src/soc/intel/common/block/pcie/pcie.c index 5c6681d0d097..3c5e26a2e386 100644 --- a/src/soc/intel/common/block/pcie/pcie.c +++ b/src/soc/intel/common/block/pcie/pcie.c @@ -67,6 +67,14 @@ struct device_operations pcie_rp_ops = { }; static const unsigned short pcie_device_ids[] = { + PCI_DID_INTEL_PTL_PCIE_RP1, + PCI_DID_INTEL_PTL_PCIE_RP2, + PCI_DID_INTEL_PTL_PCIE_RP3, + PCI_DID_INTEL_PTL_PCIE_RP4, + PCI_DID_INTEL_PTL_PCIE_RP5, + PCI_DID_INTEL_PTL_PCIE_RP6, + PCI_DID_INTEL_PTL_PCIE_RP7, + PCI_DID_INTEL_PTL_PCIE_RP8, PCI_DID_INTEL_LNL_PCIE_RP1, PCI_DID_INTEL_LNL_PCIE_RP2, PCI_DID_INTEL_LNL_PCIE_RP3, diff --git a/src/soc/intel/common/block/pmc/pmc.c b/src/soc/intel/common/block/pmc/pmc.c index ca575ff7b0d3..bc70b1ac4388 100644 --- a/src/soc/intel/common/block/pmc/pmc.c +++ b/src/soc/intel/common/block/pmc/pmc.c @@ -111,6 +111,7 @@ struct device_operations pmc_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_PTL_PMC, PCI_DID_INTEL_LNL_PMC, PCI_DID_INTEL_MTL_SOC_PMC, PCI_DID_INTEL_MTL_IOE_M_PMC, diff --git a/src/soc/intel/common/block/smbus/smbus.c b/src/soc/intel/common/block/smbus/smbus.c index 97651c0f098e..7f87a523e8a5 100644 --- a/src/soc/intel/common/block/smbus/smbus.c +++ b/src/soc/intel/common/block/smbus/smbus.c @@ -49,6 +49,7 @@ struct device_operations smbus_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_PTL_SMBUS, PCI_DID_INTEL_LNL_SMBUS, PCI_DID_INTEL_MTL_SMBUS, PCI_DID_INTEL_RPP_P_SMBUS, diff --git a/src/soc/intel/common/block/spi/spi.c b/src/soc/intel/common/block/spi/spi.c index d1063f10a8fc..0e8aa261ce33 100644 --- a/src/soc/intel/common/block/spi/spi.c +++ b/src/soc/intel/common/block/spi/spi.c @@ -123,6 +123,10 @@ struct device_operations spi_dev_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_PTL_HWSEQ_SPI, + PCI_DID_INTEL_PTL_SPI0, + PCI_DID_INTEL_PTL_SPI1, + PCI_DID_INTEL_PTL_SPI2, PCI_DID_INTEL_LNL_GSPI0, PCI_DID_INTEL_LNL_GSPI1, PCI_DID_INTEL_LNL_GSPI2, diff --git a/src/soc/intel/common/block/sram/sram.c b/src/soc/intel/common/block/sram/sram.c index cd8c3fd0aa1e..649a6c6cb0f3 100644 --- a/src/soc/intel/common/block/sram/sram.c +++ b/src/soc/intel/common/block/sram/sram.c @@ -33,6 +33,7 @@ static const struct device_operations device_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_PTL_SRAM, PCI_DID_INTEL_LNL_SRAM, PCI_DID_INTEL_MTL_SOC_SRAM, PCI_DID_INTEL_MTL_IOE_M_SRAM, diff --git a/src/soc/intel/common/block/systemagent/systemagent.c b/src/soc/intel/common/block/systemagent/systemagent.c index b53814e35dfc..e8e75d7eb2b6 100644 --- a/src/soc/intel/common/block/systemagent/systemagent.c +++ b/src/soc/intel/common/block/systemagent/systemagent.c @@ -414,7 +414,9 @@ struct device_operations systemagent_ops = { }; static const unsigned short systemagent_ids[] = { + PCI_DID_INTEL_PTL_ID, PCI_DID_INTEL_LNL_M_ID, + PCI_DID_INTEL_LNL_M_ID_1, PCI_DID_INTEL_MTL_M_ID, PCI_DID_INTEL_MTL_P_ID_1, PCI_DID_INTEL_MTL_P_ID_2, diff --git a/src/soc/intel/common/block/tcss/Kconfig b/src/soc/intel/common/block/tcss/Kconfig index 25113d33f36c..89bab79235b0 100644 --- a/src/soc/intel/common/block/tcss/Kconfig +++ b/src/soc/intel/common/block/tcss/Kconfig @@ -6,10 +6,18 @@ config SOC_INTEL_COMMON_BLOCK_TCSS help Sets up USB2/3 port mapping in TCSS MUX +config SOC_INTEL_TCSS_USE_PDC_PMC_USBC_MUX_CONFIGURATION + def_bool n + help + TCSS uses PDC<->PMC communication to perform mux configuration. When this config is + enabled, communication happens directly between PDC and PMC. Avoid sending PMC + commands from AP/EC. + config TCSS_HAS_USBC_OPS bool "Enable USB-C MUX operations via the EC" default y if EC_GOOGLE_CHROMEEC - depends on SOC_INTEL_COMMON_BLOCK_TCSS + depends on SOC_INTEL_COMMON_BLOCK_TCSS && \ + !SOC_INTEL_TCSS_USE_PDC_PMC_USBC_MUX_CONFIGURATION help Enable USB-C operations via the EC. Requires `usbc_get_ops` to control features such as HPD and DP Mode entry. Currently, only the ChromeEC implements this, see diff --git a/src/soc/intel/common/block/tracehub/tracehub.c b/src/soc/intel/common/block/tracehub/tracehub.c index 4faa9ebc9124..480e9efe0f7f 100644 --- a/src/soc/intel/common/block/tracehub/tracehub.c +++ b/src/soc/intel/common/block/tracehub/tracehub.c @@ -43,6 +43,7 @@ static struct device_operations dev_ops = { static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_MTL_TRACEHUB, + PCI_DID_INTEL_RPL_TRACEHUB, 0 }; diff --git a/src/soc/intel/common/block/uart/chip.h b/src/soc/intel/common/block/uart/chip.h deleted file mode 100644 index 5981126fa91f..000000000000 --- a/src/soc/intel/common/block/uart/chip.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <stdint.h> -/* Indirect include for static.c: */ -#include <device/pci_ids.h> - -#ifndef _SOC_INTEL_COMMON_BLOCK_UART_CHIP_H_ -#define _SOC_INTEL_COMMON_BLOCK_UART_CHIP_H_ - -struct soc_intel_common_block_uart_config { - /* The Device ID read from config space at offset[2:4] when not hidden */ - u16 devid; -}; - -#endif /* _SOC_INTEL_COMMON_BLOCK_UART_CHIP_H_ */ diff --git a/src/soc/intel/common/block/uart/uart.c b/src/soc/intel/common/block/uart/uart.c index c03f5a9d367d..e454f7e91ae8 100644 --- a/src/soc/intel/common/block/uart/uart.c +++ b/src/soc/intel/common/block/uart/uart.c @@ -14,7 +14,6 @@ #include <soc/pci_devs.h> #include <soc/iomap.h> #include <soc/nvs.h> -#include "chip.h" #define UART_PCI_ENABLE (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER) @@ -309,6 +308,7 @@ static const char *uart_acpi_hid(const struct device *dev) static const char *uart_acpi_name(const struct device *dev) { switch (dev->device) { + case PCI_DID_INTEL_PTL_UART0: case PCI_DID_INTEL_LNL_UART0: case PCI_DID_INTEL_ADP_P_UART0: case PCI_DID_INTEL_APL_UART0: @@ -317,6 +317,7 @@ static const char *uart_acpi_name(const struct device *dev) case PCI_DID_INTEL_SPT_H_UART0: case PCI_DID_INTEL_CNP_H_UART0: return "UAR0"; + case PCI_DID_INTEL_PTL_UART1: case PCI_DID_INTEL_LNL_UART1: case PCI_DID_INTEL_ADP_P_UART1: case PCI_DID_INTEL_APL_UART1: @@ -325,6 +326,7 @@ static const char *uart_acpi_name(const struct device *dev) case PCI_DID_INTEL_SPT_H_UART1: case PCI_DID_INTEL_CNP_H_UART1: return "UAR1"; + case PCI_DID_INTEL_PTL_UART2: case PCI_DID_INTEL_LNL_UART2: case PCI_DID_INTEL_ADP_P_UART2: case PCI_DID_INTEL_APL_UART2: @@ -352,6 +354,9 @@ struct device_operations uart_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_PTL_UART0, + PCI_DID_INTEL_PTL_UART1, + PCI_DID_INTEL_PTL_UART2, PCI_DID_INTEL_LNL_UART0, PCI_DID_INTEL_LNL_UART1, PCI_DID_INTEL_LNL_UART2, @@ -424,17 +429,4 @@ static const struct pci_driver pch_uart __pci_driver = { .vendor = PCI_VID_INTEL, .devices = pci_device_ids, }; - -static void uart_enable(struct device *dev) -{ - struct soc_intel_common_block_uart_config *conf = dev->chip_info; - dev->ops = &uart_ops; - dev->device = conf ? conf->devid : 0; -} - -struct chip_operations soc_intel_common_block_uart_ops = { - .name = "LPSS UART in ACPI mode", - .enable_dev = uart_enable -}; - #endif /* ENV_RAMSTAGE */ diff --git a/src/soc/intel/common/block/usb4/usb4.c b/src/soc/intel/common/block/usb4/usb4.c index a47bb9b221ca..ff898abb125e 100644 --- a/src/soc/intel/common/block/usb4/usb4.c +++ b/src/soc/intel/common/block/usb4/usb4.c @@ -52,6 +52,8 @@ static void tbt_dma_fill_ssdt(const struct device *dev) #endif static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_PTL_TBT_DMA0, + PCI_DID_INTEL_PTL_TBT_DMA1, PCI_DID_INTEL_LNL_TBT_DMA0, PCI_DID_INTEL_LNL_TBT_DMA1, PCI_DID_INTEL_RPL_TBT_DMA0, diff --git a/src/soc/intel/common/block/usb4/xhci.c b/src/soc/intel/common/block/usb4/xhci.c index 4912e1a1ebae..4e1a2a8815ad 100644 --- a/src/soc/intel/common/block/usb4/xhci.c +++ b/src/soc/intel/common/block/usb4/xhci.c @@ -26,6 +26,7 @@ static struct device_operations usb4_xhci_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_PTL_TCSS_XHCI, PCI_DID_INTEL_LNL_TCSS_XHCI, PCI_DID_INTEL_RPP_P_TCSS_XHCI, PCI_DID_INTEL_MTL_M_TCSS_XHCI, diff --git a/src/soc/intel/common/block/vtd/vtd.c b/src/soc/intel/common/block/vtd/vtd.c index f67d8dbfd5ab..12ca151c7af6 100644 --- a/src/soc/intel/common/block/vtd/vtd.c +++ b/src/soc/intel/common/block/vtd/vtd.c @@ -12,19 +12,6 @@ #include <soc/iomap.h> #include <soc/pci_devs.h> -/* VT-d specification: https://cdrdv2.intel.com/v1/dl/getContent/671081 */ -#define VER_REG 0x0 -#define CAP_REG 0x8 -#define CAP_PMR_LO BIT(5) -#define CAP_PMR_HI BIT(6) -#define PMEN_REG 0x64 -#define PMEN_EPM BIT(31) -#define PMEN_PRS BIT(0) -#define PLMBASE_REG 0x68 -#define PLMLIMIT_REG 0x6C -#define PHMBASE_REG 0x70 -#define PHMLIMIT_REG 0x78 - /* FSP 2.x VT-d HOB from edk2-platforms */ static const uint8_t vtd_pmr_info_data_hob_guid[16] = { 0x45, 0x16, 0xb6, 0x6f, 0x68, 0xf1, 0xbe, 0x46, @@ -40,26 +27,6 @@ struct vtd_pmr_info_hob { static struct vtd_pmr_info_hob *pmr_hob; -static __always_inline uint32_t vtd_read32(uintptr_t vtd_base, uint32_t reg) -{ - return read32p(vtd_base + reg); -} - -static __always_inline void vtd_write32(uintptr_t vtd_base, uint32_t reg, uint32_t value) -{ - return write32p(vtd_base + reg, value); -} - -static __always_inline uint64_t vtd_read64(uintptr_t vtd_base, uint32_t reg) -{ - return read64p(vtd_base + reg); -} - -static __always_inline void vtd_write64(uintptr_t vtd_base, uint32_t reg, uint64_t value) -{ - return write64p(vtd_base + reg, value); -} - static bool is_vtd_enabled(uintptr_t vtd_base) { uint32_t version = vtd_read32(vtd_base, VER_REG); diff --git a/src/soc/intel/common/block/xhci/xhci.c b/src/soc/intel/common/block/xhci/xhci.c index 03ed578e2735..dd4e5de84901 100644 --- a/src/soc/intel/common/block/xhci/xhci.c +++ b/src/soc/intel/common/block/xhci/xhci.c @@ -131,6 +131,7 @@ struct device_operations usb_xhci_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_PTL_XHCI, PCI_DID_INTEL_LNL_XHCI, PCI_DID_INTEL_MTL_XHCI, PCI_DID_INTEL_APL_XHCI, diff --git a/src/soc/intel/elkhartlake/Kconfig b/src/soc/intel/elkhartlake/Kconfig index cb080f4ddc27..9bee9becae28 100644 --- a/src/soc/intel/elkhartlake/Kconfig +++ b/src/soc/intel/elkhartlake/Kconfig @@ -24,6 +24,7 @@ config SOC_INTEL_ELKHARTLAKE select INTEL_GMA_ADD_VBT if RUN_FSP_GOP select MP_SERVICES_PPI_V1 select MRC_SETTINGS_PROTECT + select NEED_SMALL_2MB_PAGE_TABLES select PARALLEL_MP_AP_WORK select PLATFORM_USES_FSP2_1 select PMC_GLOBAL_RESET_ENABLE_LOCK diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index a4ebad47068b..622d35f529d7 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -42,7 +42,8 @@ config SOC_INTEL_METEORLAKE select MRC_SETTINGS_PROTECT select PARALLEL_MP_AP_WORK select PCIE_CLOCK_CONTROL_THROUGH_P2SB - select PLATFORM_USES_FSP2_3 + select PLATFORM_USES_FSP2_4 if HAVE_X86_64_SUPPORT + select PLATFORM_USES_FSP2_3 if !HAVE_X86_64_SUPPORT select PMC_GLOBAL_RESET_ENABLE_LOCK select SOC_INTEL_COMMON select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE @@ -347,7 +348,8 @@ config CONSOLE_CBMEM_BUFFER_SIZE config FSP_HEADER_PATH string "Location of FSP headers" - default "src/vendorcode/intel/fsp/fsp2_0/meteorlake/" + default "src/vendorcode/intel/fsp/fsp2_0/meteorlake/x86_64/" if HAVE_X86_64_SUPPORT + default "src/vendorcode/intel/fsp/fsp2_0/meteorlake/x86_32/" config FSP_FD_PATH string @@ -457,7 +459,7 @@ config SOC_INTEL_COMMON_BLOCK_ACPI_SLP_S0_FREQ_HZ config SOC_INTEL_METEORLAKE_SIGN_OF_LIFE bool - default y if !SOC_INTEL_METEORLAKE_PRE_PRODUCTION_SILICON + default y if !SOC_INTEL_METEORLAKE_PRE_PRODUCTION_SILICON || !HAVE_X86_64_SUPPORT depends on MAINBOARD_HAS_CHROMEOS select VBT_CBFS_COMPRESSION_DEFAULT_LZ4 help diff --git a/src/soc/intel/meteorlake/acpi/tcss.asl b/src/soc/intel/meteorlake/acpi/tcss.asl index 84e15fd128ca..dbe76f25ced8 100644 --- a/src/soc/intel/meteorlake/acpi/tcss.asl +++ b/src/soc/intel/meteorlake/acpi/tcss.asl @@ -718,7 +718,7 @@ Scope (\_SB.PCI0) Method (_STA, 0x0, NotSerialized) { - If (TRE0 == 1) { + If (VDID != 0xFFFFFFFF) { Return (0x0F) } Else { Return (0x0) @@ -748,7 +748,7 @@ Scope (\_SB.PCI0) Method (_STA, 0x0, NotSerialized) { - If (TRE1 == 1) { + If (VDID != 0xFFFFFFFF) { Return (0x0F) } Else { Return (0x0) @@ -778,7 +778,7 @@ Scope (\_SB.PCI0) Method (_STA, 0x0, NotSerialized) { - If (TRE2 == 1) { + If (VDID != 0xFFFFFFFF) { Return (0x0F) } Else { Return (0x0) @@ -808,7 +808,7 @@ Scope (\_SB.PCI0) Method (_STA, 0x0, NotSerialized) { - If (TRE3 == 1) { + If (VDID != 0xFFFFFFFF) { Return (0x0F) } Else { Return (0x0) diff --git a/src/soc/intel/meteorlake/bootblock/report_platform.c b/src/soc/intel/meteorlake/bootblock/report_platform.c index 49d0661f30c5..bc8ae920c101 100644 --- a/src/soc/intel/meteorlake/bootblock/report_platform.c +++ b/src/soc/intel/meteorlake/bootblock/report_platform.c @@ -58,6 +58,7 @@ static struct { { PCI_DID_INTEL_MTL_P_GT2_2, "MeteorLake-P GT2" }, { PCI_DID_INTEL_MTL_P_GT2_3, "MeteorLake-P GT2" }, { PCI_DID_INTEL_MTL_P_GT2_4, "Meteorlake-P GT2" }, + { PCI_DID_INTEL_MTL_P_GT2_5, "Meteorlake-P GT2" }, }; static inline uint8_t get_dev_revision(pci_devfn_t dev) diff --git a/src/soc/intel/meteorlake/chip.c b/src/soc/intel/meteorlake/chip.c index 03adfdb73888..51e89dcf3a40 100644 --- a/src/soc/intel/meteorlake/chip.c +++ b/src/soc/intel/meteorlake/chip.c @@ -185,6 +185,9 @@ void soc_init_pre_device(void *chip_info) /* Swap enabled PCI ports in device tree if needed. */ pcie_rp_update_devicetree(get_pcie_rp_table()); + /* Swap enabled TBT root ports in device tree if needed. */ + pcie_rp_update_devicetree(get_tbt_pcie_rp_table()); + /* * Earlier when coreboot used to send EOP at late as possible caused * issue of delayed response from CSE since CSE was busy loading payload. diff --git a/src/soc/intel/meteorlake/chip.h b/src/soc/intel/meteorlake/chip.h index 1b08ccdbd647..716836994826 100644 --- a/src/soc/intel/meteorlake/chip.h +++ b/src/soc/intel/meteorlake/chip.h @@ -247,6 +247,7 @@ struct soc_intel_meteorlake_config { uint16_t sata_ports_dito_val[8]; /* Audio related */ + uint8_t pch_hda_audio_link_hda_enable; uint8_t pch_hda_dsp_enable; bool pch_hda_sdi_enable[MAX_HD_AUDIO_SDI_LINKS]; @@ -515,6 +516,9 @@ struct soc_intel_meteorlake_config { /* Platform Power Pmax in Watts. Zero means automatic. */ uint16_t psys_pmax_watts; + /* Platform Power Limit 2 in Watts. */ + uint16_t psys_pl2_watts; + /* Enable or Disable Acoustic Noise Mitigation feature */ uint8_t enable_acoustic_noise_mitigation; /* Disable Fast Slew Rate for Deep Package C States for VR domains */ diff --git a/src/soc/intel/meteorlake/crashlog.c b/src/soc/intel/meteorlake/crashlog.c index 6d654d7e0b1e..0321e0040647 100644 --- a/src/soc/intel/meteorlake/crashlog.c +++ b/src/soc/intel/meteorlake/crashlog.c @@ -34,7 +34,7 @@ static u32 disc_tab_addr; static u64 get_disc_tab_header(void) { - return read64((void *)disc_tab_addr); + return read64((void *)(uintptr_t)disc_tab_addr); } /* Get the SRAM BAR. */ @@ -338,7 +338,7 @@ static bool cpu_cl_gen_discovery_table(void) disc_tab_addr = bar_addr + get_disc_table_offset(); - u32 dw0 = read32((u32 *)disc_tab_addr); + u32 dw0 = read32((u32 *)(uintptr_t)disc_tab_addr); if (!is_crashlog_data_valid(dw0)) return false; @@ -351,7 +351,7 @@ static bool cpu_cl_gen_discovery_table(void) for (int i = 0; i < cpu_cl_disc_tab.header.fields.count; i++) { cur_offset = 8 + 24 * i; - dw0 = read32((u32 *)disc_tab_addr + cur_offset); + dw0 = read32((u32 *)(uintptr_t)disc_tab_addr + cur_offset); if (!is_crashlog_data_valid(dw0)) continue; @@ -361,7 +361,7 @@ static bool cpu_cl_gen_discovery_table(void) break; } - cpu_cl_disc_tab.buffers[i].data = read64((void *)(disc_tab_addr + cur_offset)); + cpu_cl_disc_tab.buffers[i].data = read64((void *)(uintptr_t)(disc_tab_addr + cur_offset)); printk(BIOS_DEBUG, "cpu_crashlog_discovery_table buffer: 0x%x size: " "0x%x offset: 0x%x\n", i, cpu_cl_disc_tab.buffers[i].fields.size, cpu_cl_disc_tab.buffers[i].fields.offset); @@ -450,7 +450,7 @@ void cpu_cl_rearm(void) cl_punit_control_interface_t punit_ctrl_intfc; memset(&punit_ctrl_intfc, 0, sizeof(cl_punit_control_interface_t)); punit_ctrl_intfc.fields.set_re_arm = 1; - write32((u32 *)(ctrl_sts_intfc_addr), punit_ctrl_intfc.data); + write32((u32 *)(uintptr_t)(ctrl_sts_intfc_addr), punit_ctrl_intfc.data); if (!wait_and_check(CRASHLOG_RE_ARM_STATUS_MASK)) printk(BIOS_ERR, "CPU crashlog re_arm not asserted\n"); @@ -480,7 +480,7 @@ void cpu_cl_cleanup(void) cl_punit_control_interface_t punit_ctrl_intfc; memset(&punit_ctrl_intfc, 0, sizeof(cl_punit_control_interface_t)); punit_ctrl_intfc.fields.set_storage_off = 1; - write32((u32 *)(ctrl_sts_intfc_addr), punit_ctrl_intfc.data); + write32((u32 *)(uintptr_t)(ctrl_sts_intfc_addr), punit_ctrl_intfc.data); if (!wait_and_check(CRASHLOG_PUNIT_STORAGE_OFF_MASK)) printk(BIOS_ERR, "CPU crashlog storage_off not asserted\n"); diff --git a/src/soc/intel/meteorlake/fsp_params.c b/src/soc/intel/meteorlake/fsp_params.c index a02d4b99c679..bf1d9d54f120 100644 --- a/src/soc/intel/meteorlake/fsp_params.c +++ b/src/soc/intel/meteorlake/fsp_params.c @@ -476,6 +476,8 @@ static void fill_fsps_xhci_params(FSP_S_CONFIG *s_cfg, s_cfg->Usb2OverCurrentPin[i] = config->usb2_ports[i].ocpin; else s_cfg->Usb2OverCurrentPin[i] = OC_SKIP; + + s_cfg->PortResetMessageEnable[i] = config->usb2_ports[i].type_c; } max_port = get_max_usb30_port(); @@ -703,18 +705,27 @@ static void fill_fsps_irq_params(FSP_S_CONFIG *s_cfg, printk(BIOS_INFO, "IRQ: Using dynamically assigned PCI IO-APIC IRQs\n"); } -static void arch_silicon_init_params(FSPS_ARCH_UPD *s_arch_cfg) +static void arch_silicon_init_params(FSPS_ARCHx_UPD *s_arch_cfg) { + +#if !CONFIG(PLATFORM_USES_FSP2_4) /* * EnableMultiPhaseSiliconInit for running MultiPhaseSiInit */ s_arch_cfg->EnableMultiPhaseSiliconInit = 1; +#endif /* Assign FspEventHandler arch Upd to use coreboot debug event handler */ if (CONFIG(FSP_USES_CB_DEBUG_EVENT_HANDLER) && CONFIG(CONSOLE_SERIAL) && CONFIG(FSP_ENABLE_SERIAL_DEBUG)) + +#if CONFIG(PLATFORM_USES_FSP2_X86_32) s_arch_cfg->FspEventHandler = (FSP_EVENT_HANDLER) fsp_debug_event_handler; +#else + s_arch_cfg->FspEventHandler = (EFI_PHYSICAL_ADDRESS) + fsp_debug_event_handler; +#endif } static void evaluate_ssid(const struct device *dev, uint16_t *svid, uint16_t *ssid) @@ -822,7 +833,7 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) { struct soc_intel_meteorlake_config *config; FSP_S_CONFIG *s_cfg = &supd->FspsConfig; - FSPS_ARCH_UPD *s_arch_cfg = &supd->FspsArchUpd; + FSPS_ARCHx_UPD *s_arch_cfg = &supd->FspsArchUpd; config = config_of_soc(); arch_silicon_init_params(s_arch_cfg); diff --git a/src/soc/intel/meteorlake/include/soc/pcie.h b/src/soc/intel/meteorlake/include/soc/pcie.h index f97543c9167d..7c098e9ca59f 100644 --- a/src/soc/intel/meteorlake/include/soc/pcie.h +++ b/src/soc/intel/meteorlake/include/soc/pcie.h @@ -6,5 +6,6 @@ #include <intelblocks/pcie_rp.h> const struct pcie_rp_group *get_pcie_rp_table(void); +const struct pcie_rp_group *get_tbt_pcie_rp_table(void); #endif /* __SOC_METEORLAKE_PCIE_H__ */ diff --git a/src/soc/intel/meteorlake/include/soc/usb.h b/src/soc/intel/meteorlake/include/soc/usb.h index e339c7261e0a..70a367ec5909 100644 --- a/src/soc/intel/meteorlake/include/soc/usb.h +++ b/src/soc/intel/meteorlake/include/soc/usb.h @@ -31,6 +31,7 @@ struct usb2_port_config { uint8_t tx_emp_enable; uint8_t pre_emp_bias; uint8_t pre_emp_bit; + uint8_t type_c; }; /* USB Overcurrent pins definition */ @@ -112,6 +113,7 @@ enum { .tx_emp_enable = USB2_PRE_EMP_ON, \ .pre_emp_bias = USB2_BIAS_56P3MV, \ .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \ + .type_c = 1, \ } struct usb3_port_config { diff --git a/src/soc/intel/meteorlake/meminit.c b/src/soc/intel/meteorlake/meminit.c index fa7e1fd09a76..32ab358b46be 100644 --- a/src/soc/intel/meteorlake/meminit.c +++ b/src/soc/intel/meteorlake/meminit.c @@ -77,7 +77,7 @@ static const struct soc_mem_cfg soc_mem_cfg[] = { static void mem_init_spd_upds(FSP_M_CONFIG *mem_cfg, const struct mem_channel_data *data) { - uint32_t *spd_upds[MRC_CHANNELS][CONFIG_DIMMS_PER_CHANNEL] = { + efi_uintn_t *spd_upds[MRC_CHANNELS][CONFIG_DIMMS_PER_CHANNEL] = { [0] = { &mem_cfg->MemorySpdPtr000, &mem_cfg->MemorySpdPtr001, }, [1] = { &mem_cfg->MemorySpdPtr010, &mem_cfg->MemorySpdPtr011, }, [2] = { &mem_cfg->MemorySpdPtr020, &mem_cfg->MemorySpdPtr021, }, @@ -106,7 +106,7 @@ static void mem_init_spd_upds(FSP_M_CONFIG *mem_cfg, const struct mem_channel_da bool enable_channel = 0; for (dimm = 0; dimm < CONFIG_DIMMS_PER_CHANNEL; dimm++) { - uint32_t *spd_ptr = spd_upds[ch][dimm]; + efi_uintn_t *spd_ptr = spd_upds[ch][dimm]; *spd_ptr = data->spd[ch][dimm]; if (*spd_ptr) diff --git a/src/soc/intel/meteorlake/pcie_rp.c b/src/soc/intel/meteorlake/pcie_rp.c index 9f59ce1f9701..7cfe3ed29181 100644 --- a/src/soc/intel/meteorlake/pcie_rp.c +++ b/src/soc/intel/meteorlake/pcie_rp.c @@ -5,6 +5,17 @@ #include <soc/pcie.h> #include <soc/soc_info.h> +/* + * TBT's LCAP registers are returning port index which starts from 0x10 (Usually for other PCIe + * root ports index starts from 1). Thus keeping lcap_port_base 0x10 for TBT, so that coreboot's + * PCIe remapping logic can return correct index (0-based) + */ + +static const struct pcie_rp_group tbt_rp_groups[] = { + { .slot = PCI_DEV_SLOT_TBT, .count = CONFIG_MAX_TBT_ROOT_PORTS, .lcap_port_base = 0x10 }, + { 0 } +}; + static const struct pcie_rp_group mtlp_rp_groups[] = { { .slot = PCI_DEV_SLOT_PCIE_1, .start = 0, .count = 8, .lcap_port_base = 1 }, { .slot = PCI_DEV_SLOT_PCIE_2, .start = 0, .count = 3, .lcap_port_base = 1 }, @@ -17,6 +28,11 @@ const struct pcie_rp_group *get_pcie_rp_table(void) return mtlp_rp_groups; } +const struct pcie_rp_group *get_tbt_pcie_rp_table(void) +{ + return tbt_rp_groups; +} + enum pcie_rp_type soc_get_pcie_rp_type(const struct device *dev) { return PCIE_RP_PCH; diff --git a/src/soc/intel/meteorlake/romstage/fsp_params.c b/src/soc/intel/meteorlake/romstage/fsp_params.c index caf57a3e9d22..ec0bb8dae6f2 100644 --- a/src/soc/intel/meteorlake/romstage/fsp_params.c +++ b/src/soc/intel/meteorlake/romstage/fsp_params.c @@ -288,17 +288,11 @@ static void fill_fspm_audio_params(FSP_M_CONFIG *m_cfg, m_cfg->PchHdaIDispLinkTmode = config->pch_hda_idisp_link_tmode; m_cfg->PchHdaIDispLinkFrequency = config->pch_hda_idisp_link_frequency; m_cfg->PchHdaIDispCodecDisconnect = !config->pch_hda_idisp_codec_enable; + m_cfg->PchHdaAudioLinkHdaEnable = config->pch_hda_audio_link_hda_enable; for (int i = 0; i < MAX_HD_AUDIO_SDI_LINKS; i++) m_cfg->PchHdaSdiEnable[i] = config->pch_hda_sdi_enable[i]; - /* - * All the PchHdaAudioLink{Hda|Dmic|Ssp|Sndw}Enable UPDs are used by FSP only to - * configure GPIO pads for audio. Mainboard is expected to perform all GPIO - * configuration in coreboot and hence these UPDs are set to 0 to skip FSP GPIO - * configuration for audio pads. - */ - m_cfg->PchHdaAudioLinkHdaEnable = 0; memset(m_cfg->PchHdaAudioLinkDmicEnable, 0, sizeof(m_cfg->PchHdaAudioLinkDmicEnable)); memset(m_cfg->PchHdaAudioLinkSspEnable, 0, sizeof(m_cfg->PchHdaAudioLinkSspEnable)); memset(m_cfg->PchHdaAudioLinkSndwEnable, 0, sizeof(m_cfg->PchHdaAudioLinkSndwEnable)); @@ -446,7 +440,7 @@ static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, #define VGA_INIT_CONTROL_TEAR_DOWN BIT(1) static void fill_fspm_sign_of_life(FSP_M_CONFIG *m_cfg, - FSPM_ARCH_UPD *arch_upd) + FSPM_ARCHx_UPD *arch_upd) { void *vbt; size_t vbt_size; @@ -485,22 +479,22 @@ static void fill_fspm_sign_of_life(FSP_M_CONFIG *m_cfg, elog_add_event_byte(ELOG_TYPE_FW_EARLY_SOL, sol_type); m_cfg->VgaInitControl = vga_init_control; - m_cfg->VbtPtr = (UINT32)vbt; + m_cfg->VbtPtr = (efi_uintn_t)vbt; m_cfg->VbtSize = vbt_size; m_cfg->LidStatus = CONFIG(VBOOT_LID_SWITCH) ? get_lid_switch() : CONFIG(RUN_FSP_GOP); - m_cfg->VgaMessage = (UINT32)text; + m_cfg->VgaMessage = (efi_uintn_t)text; } void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) { const struct soc_intel_meteorlake_config *config; FSP_M_CONFIG *m_cfg = &mupd->FspmConfig; - FSPM_ARCH_UPD *arch_upd = &mupd->FspmArchUpd; + FSPM_ARCHx_UPD *arch_upd = &mupd->FspmArchUpd; if (CONFIG(FSP_USES_CB_DEBUG_EVENT_HANDLER)) { if (CONFIG(CONSOLE_SERIAL) && CONFIG(FSP_ENABLE_SERIAL_DEBUG)) { enum fsp_log_level log_level = fsp_map_console_log_level(); - arch_upd->FspEventHandler = (UINT32)((FSP_EVENT_HANDLER *) + arch_upd->FspEventHandler = (efi_uintn_t)((FSP_EVENT_HANDLER *) fsp_debug_event_handler); /* Set Serial debug message level */ m_cfg->PcdSerialDebugLevel = log_level; diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig index 0d388049a485..3ec84abcc426 100644 --- a/src/soc/intel/skylake/Kconfig +++ b/src/soc/intel/skylake/Kconfig @@ -62,7 +62,7 @@ config SOC_INTEL_COMMON_SKYLAKE_BASE select SOC_INTEL_COMMON_NHLT select SOC_INTEL_COMMON_RESET select SOC_INTEL_COMMON_BLOCK_POWER_LIMIT - select SOC_INTEL_CONFIGURE_DDI_A_4_LANES + select SOC_INTEL_GFX_HAVE_DDI_A_BIFURCATION select SSE2 select SUPPORT_CPU_UCODE_IN_CBFS select TSC_MONOTONIC_TIMER diff --git a/src/soc/intel/xeon_sp/Kconfig b/src/soc/intel/xeon_sp/Kconfig index 45c7d9d25bc1..22cc3665dc1c 100644 --- a/src/soc/intel/xeon_sp/Kconfig +++ b/src/soc/intel/xeon_sp/Kconfig @@ -46,7 +46,6 @@ config XEON_SP_COMMON_BASE select USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM select USE_FSP_NOTIFY_PHASE_READY_TO_BOOT select USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE - select POSTCAR_STAGE if XEON_SP_COMMON_BASE diff --git a/src/soc/intel/xeon_sp/Makefile.mk b/src/soc/intel/xeon_sp/Makefile.mk index f4051eafa8ec..35b998c850d4 100644 --- a/src/soc/intel/xeon_sp/Makefile.mk +++ b/src/soc/intel/xeon_sp/Makefile.mk @@ -5,15 +5,20 @@ ifeq ($(CONFIG_XEON_SP_COMMON_BASE),y) subdirs-$(CONFIG_SOC_INTEL_SKYLAKE_SP) += skx lbg subdirs-$(CONFIG_SOC_INTEL_COOPERLAKE_SP) += cpx lbg subdirs-$(CONFIG_SOC_INTEL_SAPPHIRERAPIDS_SP) += spr ebg +## TODO: GNR IBL codes are initially reused from EBG, will update later. +subdirs-$(CONFIG_SOC_INTEL_GRANITERAPIDS) += gnr ebg 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 +romstage-y += config.c romstage-y += ../../../cpu/intel/car/romstage.c ramstage-y += uncore.c reset.c util.c lpc.c spi.c ramstage.c chip_common.c ramstage-y += memmap.c pch.c lockdown.c finalize.c +ramstage-y += numa.c +ramstage-y += config.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_PMC) += pmc.c pmutil.c ramstage-$(CONFIG_HAVE_ACPI_TABLES) += uncore_acpi.c acpi.c -ramstage-$(CONFIG_SOC_INTEL_HAS_CXL) += uncore_acpi_cxl.c numa.c +ramstage-$(CONFIG_SOC_INTEL_HAS_CXL) += uncore_acpi_cxl.c ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smmrelocate.c ramstage-$(CONFIG_XEON_SP_HAVE_IIO_IOAPIC) += iio_ioapic.c smm-y += smihandler.c pmutil.c diff --git a/src/soc/intel/xeon_sp/acpi.c b/src/soc/intel/xeon_sp/acpi.c index 0d66aec28257..f66f5e9e99b0 100644 --- a/src/soc/intel/xeon_sp/acpi.c +++ b/src/soc/intel/xeon_sp/acpi.c @@ -1,11 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include <acpi/acpigen.h> #include <assert.h> #include <intelblocks/acpi.h> #include <soc/chip_common.h> #include <soc/pci_devs.h> #include <soc/util.h> #include <stdint.h> +#include <stdio.h> #include <stdlib.h> #include "chip.h" @@ -118,3 +120,22 @@ const char *soc_acpi_name(const struct device *dev) return NULL; } + +void acpigen_write_OSC_pci_domain_fixed_caps(const struct device *domain, + const uint32_t granted_pcie_features, + const bool is_cxl_domain, + const uint32_t granted_cxl_features) +{ + acpigen_write_method("_OSC", 4); + + acpigen_write_return_namestr("\\_SB.POSC"); + acpigen_emit_byte(ARG0_OP); + acpigen_emit_byte(ARG1_OP); + acpigen_emit_byte(ARG2_OP); + acpigen_emit_byte(ARG3_OP); + acpigen_write_integer(granted_pcie_features); + acpigen_write_integer(is_cxl_domain); + acpigen_write_integer(granted_cxl_features); + + acpigen_pop_len(); +} diff --git a/src/soc/intel/xeon_sp/acpi/gpio.asl b/src/soc/intel/xeon_sp/acpi/gen1/gpio.asl index a67bdd7d5ac0..a67bdd7d5ac0 100644 --- a/src/soc/intel/xeon_sp/acpi/gpio.asl +++ b/src/soc/intel/xeon_sp/acpi/gen1/gpio.asl diff --git a/src/soc/intel/xeon_sp/acpi/gen1/iiostack.asl b/src/soc/intel/xeon_sp/acpi/gen1/iiostack.asl new file mode 100644 index 000000000000..0dd39a0f5464 --- /dev/null +++ b/src/soc/intel/xeon_sp/acpi/gen1/iiostack.asl @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define MAKE_IIO_DEV(id,rt) \ + Device (PC##id) \ + { \ + Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) \ + Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) \ + Name (_UID, 0x##id) \ + Method (_PRT, 0, NotSerialized) \ + { \ + If (PICM) \ + { \ + Return (\_SB_.AR##rt) \ + } \ + Return (\_SB_.PR##rt) \ + } \ + Name (SUPP, 0x00) \ + Name (CTRL, 0x00) \ + Name (_PXM, 0x00) /* _PXM: Device Proximity */ \ + Method (_OSC, 4, NotSerialized) \ + { \ + CreateDWordField (Arg3, 0x00, CDW1) \ + If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */)) \ + { \ + If (Arg2 < 0x03) \ + { \ + CDW1 |= 0x02 /* Unknown failure */ \ + Return (Arg3) \ + } \ + CreateDWordField (Arg3, 0x04, CDW2) \ + CreateDWordField (Arg3, 0x08, CDW3) \ + SUPP = CDW2 \ + CTRL = CDW3 \ + If ((SUPP & 0x16) != 0x16) \ + { \ + CTRL &= 0x1E \ + } \ + /* Never allow SHPC (no SHPC controller in system) */ \ + CTRL &= 0x1D \ + /* Disable Native PCIe AER handling from OS */ \ + CTRL &= 0x17 \ + If ((Arg1 != 1)) /* unknown revision */ \ + { \ + CDW1 |= 0x08 \ + } \ + If ((CDW3 != CTRL)) /* capabilities bits were masked */ \ + { \ + CDW1 |= 0x10 \ + } \ + CDW3 = CTRL \ + Return (Arg3) \ + } \ + Else \ + { \ + /* indicate unrecognized UUID */ \ + CDW1 |= 0x04 \ + DBG0 = 0xEE \ + Return (Arg3) \ + } \ + } \ + } + +MAKE_IIO_DEV(00, 00) +MAKE_IIO_DEV(01, 10) +MAKE_IIO_DEV(02, 20) +MAKE_IIO_DEV(03, 28) + +#if (CONFIG_MAX_SOCKET > 1) +MAKE_IIO_DEV(06, 40) +MAKE_IIO_DEV(07, 50) +MAKE_IIO_DEV(08, 60) +MAKE_IIO_DEV(09, 68) +#endif diff --git a/src/soc/intel/xeon_sp/acpi/pch.asl b/src/soc/intel/xeon_sp/acpi/gen1/pch.asl index fef68b081816..93d468a7ff3d 100644 --- a/src/soc/intel/xeon_sp/acpi/pch.asl +++ b/src/soc/intel/xeon_sp/acpi/gen1/pch.asl @@ -3,7 +3,7 @@ /* This file should be included in the proper platform ACPI \_SB PCI scope */ /* GPIO */ -#include <soc/intel/xeon_sp/acpi/gpio.asl> +#include <soc/intel/xeon_sp/acpi/gen1/gpio.asl> /* LPC 0:1f.0 */ #include <soc/intel/common/block/acpi/acpi/lpc.asl> diff --git a/src/soc/intel/xeon_sp/acpi/pch_irq.asl b/src/soc/intel/xeon_sp/acpi/gen1/pch_irq.asl index f36968f9cdb7..f36968f9cdb7 100644 --- a/src/soc/intel/xeon_sp/acpi/pch_irq.asl +++ b/src/soc/intel/xeon_sp/acpi/gen1/pch_irq.asl diff --git a/src/soc/intel/xeon_sp/acpi/pci_irqs.asl b/src/soc/intel/xeon_sp/acpi/gen1/pci_irqs.asl index eccb46b93dd5..eccb46b93dd5 100644 --- a/src/soc/intel/xeon_sp/acpi/pci_irqs.asl +++ b/src/soc/intel/xeon_sp/acpi/gen1/pci_irqs.asl diff --git a/src/soc/intel/xeon_sp/acpi/southcluster.asl b/src/soc/intel/xeon_sp/acpi/gen1/southcluster.asl index eb687784e755..eb687784e755 100644 --- a/src/soc/intel/xeon_sp/acpi/southcluster.asl +++ b/src/soc/intel/xeon_sp/acpi/gen1/southcluster.asl diff --git a/src/soc/intel/xeon_sp/acpi/uncore.asl b/src/soc/intel/xeon_sp/acpi/gen1/uncore.asl index 8d178cbb6bbb..8d178cbb6bbb 100644 --- a/src/soc/intel/xeon_sp/acpi/uncore.asl +++ b/src/soc/intel/xeon_sp/acpi/gen1/uncore.asl diff --git a/src/soc/intel/xeon_sp/acpi/uncore_irq.asl b/src/soc/intel/xeon_sp/acpi/gen1/uncore_irq.asl index e8d1b14c675d..e8d1b14c675d 100644 --- a/src/soc/intel/xeon_sp/acpi/uncore_irq.asl +++ b/src/soc/intel/xeon_sp/acpi/gen1/uncore_irq.asl diff --git a/src/soc/intel/xeon_sp/acpi/iiostack.asl b/src/soc/intel/xeon_sp/acpi/iiostack.asl index 0dd39a0f5464..c943dd5a3c38 100644 --- a/src/soc/intel/xeon_sp/acpi/iiostack.asl +++ b/src/soc/intel/xeon_sp/acpi/iiostack.asl @@ -1,73 +1,136 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#define MAKE_IIO_DEV(id,rt) \ - Device (PC##id) \ - { \ - Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) \ - Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) \ - Name (_UID, 0x##id) \ - Method (_PRT, 0, NotSerialized) \ - { \ - If (PICM) \ - { \ - Return (\_SB_.AR##rt) \ - } \ - Return (\_SB_.PR##rt) \ - } \ - Name (SUPP, 0x00) \ - Name (CTRL, 0x00) \ - Name (_PXM, 0x00) /* _PXM: Device Proximity */ \ - Method (_OSC, 4, NotSerialized) \ - { \ - CreateDWordField (Arg3, 0x00, CDW1) \ - If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */)) \ - { \ - If (Arg2 < 0x03) \ - { \ - CDW1 |= 0x02 /* Unknown failure */ \ - Return (Arg3) \ - } \ - CreateDWordField (Arg3, 0x04, CDW2) \ - CreateDWordField (Arg3, 0x08, CDW3) \ - SUPP = CDW2 \ - CTRL = CDW3 \ - If ((SUPP & 0x16) != 0x16) \ - { \ - CTRL &= 0x1E \ - } \ - /* Never allow SHPC (no SHPC controller in system) */ \ - CTRL &= 0x1D \ - /* Disable Native PCIe AER handling from OS */ \ - CTRL &= 0x17 \ - If ((Arg1 != 1)) /* unknown revision */ \ - { \ - CDW1 |= 0x08 \ - } \ - If ((CDW3 != CTRL)) /* capabilities bits were masked */ \ - { \ - CDW1 |= 0x10 \ - } \ - CDW3 = CTRL \ - Return (Arg3) \ - } \ - Else \ - { \ - /* indicate unrecognized UUID */ \ - CDW1 |= 0x04 \ - DBG0 = 0xEE \ - Return (Arg3) \ - } \ - } \ - } +#define PCI_HOST_BRIDGE_OSC_UUID "33db4d5b-1ff7-401c-9657-7441c03dd766" +#define CXL_HOST_BRIDGE_OSC_UUID "68f2d50b-c469-4d8a-bd3d-941a103fd3fc" + +#define OSC_RET_FAILURE 0x02 +#define OSC_RET_UNRECOGNIZED_UUID 0x04 +#define OSC_RET_UNRECOGNIZED_REV 0x08 +#define OSC_RET_CAPABILITIES_MASKED 0x10 + +#define OSC_QUERY_SUPPORT_SET 0x01 + +#define ASL_UUID_UNHANDLED 0x00 +#define ASL_UUID_HANDLED 0x01 + +Scope (\_SB) +{ + /* + * \_SB.POSC - OSC handler for PCIe _OSC calls + * + * Reference: + * 6.2.11 in https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/06_Device_Configuration/Device_Configuration.html + * + * Note: + * This call negotiate with OS on fixed firmware capabilities. It doesn't support to runtime + * change firmware settings. + * + * Arguments: (7) + * Arg0 - Map to _OSC Arg0. A Buffer containing a UUID + * Arg1 - Map to _OSC Arg1. An Integer containing a Revision ID of the buffer format + * Arg2 - Map to _OSC Arg2. An Integer containing a count of entries in Arg3 + * Arg3 - Map to _OSC Arg3. A Buffer containing a list of DWORD capabilities + * Arg4 - GrantedPCIeFeatures + * Arg5 - IsCxlDomain + * Arg6 - GrantedCxlFeatures + * + * _OSC ASL Return Value: + * A Buffer containing a list of capabilities + * + * Local Variables Assignment: + * Local0 - Not used + * Local1 - Not used + * Local2 - Not used + * Local3 - Not used + * Local4 - Not used + * Local5 - Not used + * Local6 - Record whether the UUID is handled + * Local7 - Backs up the input value of Arg3 + * + * Field Definitions: + * Name - Width Source Offset Description + * -------------------------------- + * RETE - DWord Arg3 0x00 Returned errors + * SUPP - Dword Arg3 0x04 PCIe Features that OS supported + * CTRL - Dword Arg3 0x08 PCIe Features that firmware grant control to OS + * OTRL - Dword Local7 0x08 PCIe Features that OS requests for control + * SUPC - Dword Arg3 0x0C CXL Features that OS supported + * CTRC - Dword Arg3 0x10 CXL Features that firmware grant control to OS + * OTRC - Dword Local7 0x10 CXL Features that OS requests for control + */ + + Method (POSC, 7, NotSerialized) + { + +#define OscArg0 Arg0 +#define OscArg1 Arg1 +#define OscArg2 Arg2 +#define OscArg3 Arg3 +#define GrantedPCIeFeatures Arg4 +#define IsCxlDomain Arg5 +#define GrantedCxlFeatures Arg6 + + Local7 = OscArg3 + CreateDWordField (OscArg3, Zero, RETE) + RETE = 0x0 + Local6 = ASL_UUID_UNHANDLED + + If ((OscArg1 != 0x01)) + { + RETE = OSC_RET_UNRECOGNIZED_REV + Return (OscArg3) + } + + If ((OscArg2 < 0x03)) + { + RETE = OSC_RET_FAILURE + Return (OscArg3) + } + + If ((OscArg0 == ToUUID (PCI_HOST_BRIDGE_OSC_UUID)) || + ((IsCxlDomain != 0x00) && + (OscArg0 == ToUUID (CXL_HOST_BRIDGE_OSC_UUID)))) + { + CreateDWordField (OscArg3, 0x04, SUPP) + CreateDWordField (OscArg3, 0x08, CTRL) + CreateDWordField (Local7, 0x08, OTRL) -MAKE_IIO_DEV(00, 00) -MAKE_IIO_DEV(01, 10) -MAKE_IIO_DEV(02, 20) -MAKE_IIO_DEV(03, 28) - -#if (CONFIG_MAX_SOCKET > 1) -MAKE_IIO_DEV(06, 40) -MAKE_IIO_DEV(07, 50) -MAKE_IIO_DEV(08, 60) -MAKE_IIO_DEV(09, 68) -#endif + CTRL &= GrantedPCIeFeatures + + /* TODO: further suppress CTRL bits per SUPP caps */ + + If ((CTRL != OTRL)) + { + RETE = OSC_RET_CAPABILITIES_MASKED + } + + Local6 = ASL_UUID_HANDLED + } + + If ((IsCxlDomain != 0x00) && + (OscArg0 == ToUUID (CXL_HOST_BRIDGE_OSC_UUID))) + { + CreateDWordField (OscArg3, 0x0C, SUPC) + CreateDWordField (OscArg3, 0x10, CTRC) + CreateDWordField (Local7, 0x10, OTRC) + + CTRC &= GrantedCxlFeatures + + /* TODO: further suppress CTRC bits per SUPC caps */ + + If ((CTRC != OTRC)) + { + RETE = OSC_RET_CAPABILITIES_MASKED + } + + Local6 = ASL_UUID_HANDLED + } + + If ((Local6 == ASL_UUID_UNHANDLED)) + { + RETE = OSC_RET_UNRECOGNIZED_UUID + } + + Return (OscArg3) + } +} diff --git a/src/soc/intel/xeon_sp/chip_gen1.c b/src/soc/intel/xeon_sp/chip_gen1.c index b17b77347e5a..117de9ca004b 100644 --- a/src/soc/intel/xeon_sp/chip_gen1.c +++ b/src/soc/intel/xeon_sp/chip_gen1.c @@ -27,7 +27,6 @@ static const STACK_RES *domain_to_stack_res(const struct device *dev) static void iio_pci_domain_read_resources(struct device *dev) { - struct resource *res; const STACK_RES *sr = domain_to_stack_res(dev); if (!sr) @@ -37,36 +36,24 @@ static void iio_pci_domain_read_resources(struct device *dev) if (is_domain0(dev)) { /* The 0 - 0xfff IO range is not reported by the HOB but still gets decoded */ - res = new_resource(dev, index++); + struct resource *res = new_resource(dev, index++); res->base = 0; res->size = 0x1000; res->limit = 0xfff; res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; } - if (sr->PciResourceIoBase < sr->PciResourceIoLimit) { - res = new_resource(dev, index++); - res->base = sr->PciResourceIoBase; - res->limit = sr->PciResourceIoLimit; - res->size = res->limit - res->base + 1; - res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED; - } + if (sr->PciResourceIoBase < sr->PciResourceIoLimit) + domain_io_window_from_to(dev, index++, + sr->PciResourceIoBase, sr->PciResourceIoLimit + 1); - if (sr->PciResourceMem32Base < sr->PciResourceMem32Limit) { - res = new_resource(dev, index++); - res->base = sr->PciResourceMem32Base; - res->limit = sr->PciResourceMem32Limit; - res->size = res->limit - res->base + 1; - res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED; - } + if (sr->PciResourceMem32Base < sr->PciResourceMem32Limit) + domain_mem_window_from_to(dev, index++, + sr->PciResourceMem32Base, sr->PciResourceMem32Limit + 1); - if (sr->PciResourceMem64Base < sr->PciResourceMem64Limit) { - res = new_resource(dev, index++); - res->base = sr->PciResourceMem64Base; - res->limit = sr->PciResourceMem64Limit; - res->size = res->limit - res->base + 1; - res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED; - } + if (sr->PciResourceMem64Base < sr->PciResourceMem64Limit) + domain_mem_window_from_to(dev, index++, + sr->PciResourceMem64Base, sr->PciResourceMem64Limit + 1); } /* @@ -129,7 +116,6 @@ void create_cxl_domains(const union xeon_domain_path dp, struct bus *bus, #if CONFIG(SOC_INTEL_HAS_CXL) static void iio_cxl_domain_read_resources(struct device *dev) { - struct resource *res; const STACK_RES *sr = domain_to_stack_res(dev); if (!sr) @@ -137,29 +123,17 @@ static void iio_cxl_domain_read_resources(struct device *dev) int index = 0; - if (sr->IoBase < sr->PciResourceIoBase) { - res = new_resource(dev, index++); - res->base = sr->IoBase; - res->limit = sr->PciResourceIoBase - 1; - res->size = res->limit - res->base + 1; - res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED; - } + if (sr->IoBase < sr->PciResourceIoBase) + domain_io_window_from_to(dev, index++, + sr->IoBase, sr->PciResourceIoBase); - if (sr->Mmio32Base < sr->PciResourceMem32Base) { - res = new_resource(dev, index++); - res->base = sr->Mmio32Base; - res->limit = sr->PciResourceMem32Base - 1; - res->size = res->limit - res->base + 1; - res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED; - } + if (sr->Mmio32Base < sr->PciResourceMem32Base) + domain_mem_window_from_to(dev, index++, + sr->Mmio32Base, sr->PciResourceMem32Base); - if (sr->Mmio64Base < sr->PciResourceMem64Base) { - res = new_resource(dev, index++); - res->base = sr->Mmio64Base; - res->limit = sr->PciResourceMem64Base - 1; - res->size = res->limit - res->base + 1; - res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED; - } + if (sr->Mmio64Base < sr->PciResourceMem64Base) + domain_mem_window_from_to(dev, index++, + sr->Mmio64Base, sr->PciResourceMem64Base); } static struct device_operations iio_cxl_domain_ops = { diff --git a/src/soc/intel/xeon_sp/chip_gen6.c b/src/soc/intel/xeon_sp/chip_gen6.c new file mode 100644 index 000000000000..c4462d56c98c --- /dev/null +++ b/src/soc/intel/xeon_sp/chip_gen6.c @@ -0,0 +1,88 @@ +/* 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/numa.h> +#include <soc/soc_util.h> +#include <soc/util.h> +#include <stdlib.h> + +static const UDS_PCIROOT_RES *domain_to_pciroot_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); + + const UDS_STACK_RES *sr = &hob->PlatformData.IIO_resource[dn.socket].StackRes[dn.stack]; + for (unsigned int index = 0; index < sr->PciRootBridgeNum; index++) { + if (sr->PciRoot[index].BusBase == dev->downstream->secondary) + return &sr->PciRoot[index]; + } + + return NULL; +} + +static void iio_pci_domain_read_resources(struct device *dev) +{ + int index = 0; + const UDS_PCIROOT_RES *pr = domain_to_pciroot_res(dev); + + /* Initialize the system-wide I/O space constraints. */ + if (pr->IoBase <= pr->IoLimit) + domain_io_window_from_to(dev, index++, + pr->IoBase, pr->IoLimit + 1); + + /* The 0 - 0xfff IO range is not reported by the HOB but still gets decoded */ + if (is_domain0(dev)) { + struct resource *res = new_resource(dev, index++); + res->base = 0; + res->limit = 0xfff; + res->size = 0x1000; + res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + } + + /* Initialize the system-wide memory resources constraints. */ + if (pr->Mmio32Base <= pr->Mmio32Limit) + domain_mem_window_from_to(dev, index++, + pr->Mmio32Base, pr->Mmio32Limit + 1); + + /* Initialize the system-wide memory resources constraints. */ + if (pr->Mmio64Base <= pr->Mmio64Limit) + domain_mem_window_from_to(dev, index++, + pr->Mmio64Base, pr->Mmio64Limit + 1); +} + +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 +}; + +void create_xeonsp_domains(const union xeon_domain_path dp, struct bus *bus, + const xSTACK_RES *sr, const size_t pci_segment_group) +{ + for (unsigned int index = 0; index < sr->PciRootBridgeNum; index++) { + const UDS_PCIROOT_RES *pr = &sr->PciRoot[index]; + create_domain(dp, bus, + pr->BusBase, + pr->BusLimit, + pciroot_res_to_domain_type(sr, pr), + &iio_pcie_domain_ops, + pci_segment_group); + } +} diff --git a/src/soc/intel/xeon_sp/config.c b/src/soc/intel/xeon_sp/config.c new file mode 100644 index 000000000000..c2a908c984ef --- /dev/null +++ b/src/soc/intel/xeon_sp/config.c @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <soc/config.h> + +__weak enum xeonsp_cxl_mode get_cxl_mode(void) +{ + return XEONSP_CXL_DISABLED; +} diff --git a/src/soc/intel/xeon_sp/cpx/chip.c b/src/soc/intel/xeon_sp/cpx/chip.c index 8b9a673597e0..e6b2bdbee994 100644 --- a/src/soc/intel/xeon_sp/cpx/chip.c +++ b/src/soc/intel/xeon_sp/cpx/chip.c @@ -12,6 +12,7 @@ #include <intelblocks/p2sb.h> #include <soc/acpi.h> #include <soc/chip_common.h> +#include <soc/numa.h> #include <soc/pch.h> #include <soc/soc_pch.h> #include <soc/ramstage.h> @@ -167,6 +168,7 @@ static void chip_init(void *data) printk(BIOS_DEBUG, "coreboot: calling fsp_silicon_init\n"); fsp_silicon_init(); + setup_pds(); attach_iio_stacks(); override_hpet_ioapic_bdf(); diff --git a/src/soc/intel/xeon_sp/cpx/romstage.c b/src/soc/intel/xeon_sp/cpx/romstage.c index fe2ca8654a2a..b72417e06afe 100644 --- a/src/soc/intel/xeon_sp/cpx/romstage.c +++ b/src/soc/intel/xeon_sp/cpx/romstage.c @@ -123,7 +123,6 @@ void save_dimm_info(void) void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) { FSP_M_CONFIG *m_cfg = &mupd->FspmConfig; - const struct device *dev; const config_t *config = config_of_soc(); /* ErrorLevel - 0 (disable) to 8 (verbose) */ @@ -175,8 +174,7 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) /* Enable PCH thermal device in FSP, the definition of ThermalDeviceEnable is 0: Disable, 1: Enabled in PCI mode, 2: Enabled in ACPI mode */ - dev = pcidev_path_on_root(PCH_DEVFN_THERMAL); - m_cfg->ThermalDeviceEnable = dev && dev->enabled; + m_cfg->ThermalDeviceEnable = is_devfn_enabled(PCH_DEVFN_THERMAL); /* Enable VT-d according to DTB */ m_cfg->VtdSupport = config->vtd_support; diff --git a/src/soc/intel/xeon_sp/cpx/soc_util.c b/src/soc/intel/xeon_sp/cpx/soc_util.c index 2d6005b08fde..3472d589a8f8 100644 --- a/src/soc/intel/xeon_sp/cpx/soc_util.c +++ b/src/soc/intel/xeon_sp/cpx/soc_util.c @@ -136,3 +136,8 @@ bool is_memtype_processor_attached(uint16_t mem_type) { return true; } + +uint8_t get_cxl_node_count(void) +{ + return 0; +} diff --git a/src/soc/intel/xeon_sp/gnr/Kconfig b/src/soc/intel/xeon_sp/gnr/Kconfig new file mode 100644 index 000000000000..abbf178edc07 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/Kconfig @@ -0,0 +1,130 @@ +## 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 Granite Rapids support + +if SOC_INTEL_GRANITERAPIDS + +config CHIPSET_DEVICETREE + string + default "soc/intel/xeon_sp/gnr/chipset.cb" + +config FSP_HEADER_PATH + string "Location of FSP headers" + 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 0x142000 + bytes of memory. + +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 0x58000 + 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 + +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 n + +config INTEL_SPI_BASE_ADDRESS + hex + default 0xf6830000 + help + SPI BAR0 Base address. + +endif diff --git a/src/soc/intel/xeon_sp/gnr/Makefile.mk b/src/soc/intel/xeon_sp/gnr/Makefile.mk new file mode 100644 index 000000000000..7fcb323f8024 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/Makefile.mk @@ -0,0 +1,29 @@ +## 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 +romstage-y += soc_util.c +romstage-y += soc_iio.c +romstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c + +ramstage-y += chip.c +ramstage-y += cpu.c +ramstage-y += soc_util.c +ramstage-y += ramstage.c +ramstage-y += soc_acpi.c +ramstage-y += ../chip_gen6.c + +CPPFLAGS_common += -I$(src)/soc/intel/xeon_sp/gnr/include +CPPFLAGS_common += -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 000000000000..b61ffcf4fb33 --- /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/chip.c b/src/soc/intel/xeon_sp/gnr/chip.c new file mode 100644 index 000000000000..aa9b37874bcc --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/chip.c @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <intelblocks/lpc_lib.h> +#include <intelblocks/pmclib.h> +#include <soc/pm.h> +#include <soc/chip_common.h> +#include <soc/numa.h> +#include <soc/ramstage.h> + +#include "chip.h" + +struct device_operations hpet_device_ops = { +#if CONFIG(HAVE_ACPI_TABLES) + .write_acpi_tables = &acpi_write_hpet, +#endif +}; + +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_GPIO: + block_gpio_enable(dev); + break; + default: + break; + } +} + +static void chip_init(void *data) +{ + printk(BIOS_DEBUG, "coreboot: calling fsp_silicon_init\n"); + fsp_silicon_init(); + + setup_pds(); + attach_iio_stacks(); + pch_enable_ioapic(); + + pmc_gpe_init(); + pmc_disable_all_gpe(); + pmc_write_pm1_control(pmc_read_pm1_control() | SCI_EN); +} + +struct chip_operations soc_intel_xeon_sp_gnr_ops = { + .name = "Intel GNR", + .enable_dev = chip_enable_dev, + .init = chip_init, +}; + +/* 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 000000000000..a94a2b5d932f --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/chip.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_CHIP_H_ +#define _SOC_CHIP_H_ + +#include <intelblocks/cfg.h> +#include <soc/acpi.h> +#include <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; + + bool vtd_support; + uint8_t debug_print_level; + 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/chipset.cb b/src/soc/intel/xeon_sp/gnr/chipset.cb new file mode 100644 index 000000000000..ef33eac9d2e1 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/chipset.cb @@ -0,0 +1,21 @@ +## SPDX-License-Identifier: GPL-2.0-or-later + +chip soc/intel/xeon_sp/gnr + + # configure VT-d + register "vtd_support" = "1" + + # configure BIOS lockdown + register "common_soc_config" = "{ + .chipset_lockdown = CHIPSET_LOCKDOWN_FSP, + }" + + # configure devices + device cpu_cluster 0 on ops cpu_bus_ops end + + device domain 0 on + device pci 00.0 mandatory end # MMAP/VT-d + device gpio 0 alias ibl_gpio_communities on end # GPIO + device mmio 0xfed00000 on ops hpet_device_ops end # HPET + end +end 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 000000000000..43120b33cc89 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/cpu.c @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <cpu/intel/common/common.h> +#include <cpu/intel/microcode.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/soc_util.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) +{ + // FIXME: not implemented yet + return false; +} + +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); + + /* 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, CPUID_ALL_STEPPINGS_MASK }, + { X86_VENDOR_INTEL, CPUID_SIERRAFOREST, CPUID_ALL_STEPPINGS_MASK }, + CPU_TABLE_END +}; + +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; + + /* + * This call calculates the thread count which is corresponding to num_virts + * (logical cores), while num_phys is corresponding to physical cores (in SMT + * system, one physical core has multiple threads, a.k.a. logical cores). + * Hence num_phys is not actually used. + */ + 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(); + intel_microcode_load_unlocked(microcode_patch); + + enum cb_err ret = mp_init_with_smm(bus, &mp_ops); + if (ret != CB_SUCCESS) + printk(BIOS_ERR, "MP initialization failure %d.\n", ret); +} 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 000000000000..76d33195f8ad --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/include/soc/cpu.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_CPU_H +#define _SOC_CPU_H + +#define CPUID_GRANITERAPIDS 0xA06D0 +#define CPUID_SIERRAFOREST 0xA06F0 + +#endif diff --git a/src/soc/intel/xeon_sp/gnr/include/soc/iio.h b/src/soc/intel/xeon_sp/gnr/include/soc/iio.h new file mode 100644 index 000000000000..cbc9113792e9 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/include/soc/iio.h @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _SOC_IIO_H_ +#define _SOC_IIO_H_ + +#include <soc/soc_util.h> + +#include <fsp/util.h> +#include <FspmUpd.h> +#include <IioPcieConfigUpd.h> + +#define CB_IIO_BIFURCATE_xxxxxxxx IIO_BIFURCATE_xxxxxxxx +#define CB_IIO_BIFURCATE_x4x4x4x4 IIO_BIFURCATE_x4x4x4x4 +#define CB_IIO_BIFURCATE_x8xxx4x4 IIO_BIFURCATE_x4x4xxx8 +#define CB_IIO_BIFURCATE_x4x4x8xx IIO_BIFURCATE_xxx8x4x4 +#define CB_IIO_BIFURCATE_x8xxx8xx IIO_BIFURCATE_xxx8xxx8 +#define CB_IIO_BIFURCATE_x16xxxxx IIO_BIFURCATE_xxxxxx16 +#define CB_IIO_BIFURCATE_x8x4x2x2 IIO_BIFURCATE_x2x2x4x8 +#define CB_IIO_BIFURCATE_x8x2x2x4 IIO_BIFURCATE_x4x2x2x8 +#define CB_IIO_BIFURCATE_x4x2x2x8 IIO_BIFURCATE_x8x2x2x4 +#define CB_IIO_BIFURCATE_x2x2x4x8 IIO_BIFURCATE_x8x4x2x2 +#define CB_IIO_BIFURCATE_x4x4x4x2x2 IIO_BIFURCATE_x2x2x4x4x4 +#define CB_IIO_BIFURCATE_x4x4x2x2x4 IIO_BIFURCATE_x4x2x2x4x4 +#define CB_IIO_BIFURCATE_x4x2x2x4x4 IIO_BIFURCATE_x4x4x2x2x4 +#define CB_IIO_BIFURCATE_x2x2x4x4x4 IIO_BIFURCATE_x4x4x4x2x2 +#define CB_IIO_BIFURCATE_x8x2x2x2x2 IIO_BIFURCATE_x2x2x2x2x8 +#define CB_IIO_BIFURCATE_x2x2x2x2x8 IIO_BIFURCATE_x8x2x2x2x2 +#define CB_IIO_BIFURCATE_x4x4x2x2x2x2 IIO_BIFURCATE_x2x2x2x2x4x4 +#define CB_IIO_BIFURCATE_x4x2x2x4x2x2 IIO_BIFURCATE_x2x2x4x2x2x4 +#define CB_IIO_BIFURCATE_x2x2x4x4x2x2 IIO_BIFURCATE_x2x2x4x4x2x2 +#define CB_IIO_BIFURCATE_x4x2x2x2x2x4 IIO_BIFURCATE_x4x2x2x2x2x4 +#define CB_IIO_BIFURCATE_x2x2x4x2x2x4 IIO_BIFURCATE_x4x2x2x4x2x2 +#define CB_IIO_BIFURCATE_x2x2x2x2x4x4 IIO_BIFURCATE_x4x4x2x2x2x2 +#define CB_IIO_BIFURCATE_x4x2x2x2x2x2x2 IIO_BIFURCATE_x2x2x2x2x2x2x4 +#define CB_IIO_BIFURCATE_x2x2x4x2x2x2x2 IIO_BIFURCATE_x2x2x2x2x4x2x2 +#define CB_IIO_BIFURCATE_x2x2x2x2x4x2x2 IIO_BIFURCATE_x2x2x4x2x2x2x2 +#define CB_IIO_BIFURCATE_x2x2x2x2x2x2x4 IIO_BIFURCATE_x4x2x2x2x2x2x2 +#define CB_IIO_BIFURCATE_x2x2x2x2x2x2x2x2 IIO_BIFURCATE_x2x2x2x2x2x2x2x2 +#define CB_IIO_BIFURCATE_AUTO IIO_BIFURCATE_AUTO + +struct iio_port_config { + uint8_t vpp_address; // SMBUS address of IO expander which provides VPP register + uint8_t vpp_port; // Port or bank on IoExpander which provides VPP register + uint8_t vpp_mux_address; // SMBUS address of MUX used to access VPP + uint8_t vpp_mux_channel; // Channel of the MUX used to access VPP + + uint8_t slot_eip:1; // Electromechanical Interlock Present - + // Slot Capabilities (D0-10 / F0 / R0xA4 / B17) + uint8_t slot_hps:1; // Hot Plug surprise supported - + // Slot Capabilities (D0-10 / F0 / R0xA4 / B5) + uint8_t slot_pind:1; // Power Indicator Present - + // Slot Capabilities (D0-10 / F0 / R0xA4 / B4) + uint8_t slot_aind:1; // Attention Inductor Present - + // Slot Capabilities (D0-10 / F0 / R0xA4 / B3) + uint8_t slot_pctl:1; // Power Controller Present - + // Slot Capabilities (D0-10 / F0 / R0xA4 / B1) + uint8_t slot_abtn:1; // Attention Button Present - + // Slot Capabilities (D0-10 / F0 / R0xA4 / B0) + uint8_t slot_rsvd:2; // Reserved + + uint8_t vpp_enabled:1; // If VPP is supported on given port + uint8_t vpp_exp_type:1; // IO Expander type used for VPP (see IIO_VPP_EXPANDER_TYPE + // for values definitions) + + uint8_t slot_implemented:1; + uint8_t reserved:4; + + uint16_t hot_plug:1; // If hotplug is supported on slot connected to this port + uint16_t mrl_sensor_present:1; // If MRL is present on slot connected to this port + uint16_t slot_power_limit_scale:2; // Slot Power Scale for slot connected to this port + uint16_t slot_power_limit_value:12; // Slot Power Value for slot connected to this port + + uint16_t physical_slot_number; // Slot number for slot connected to this port +}; + +struct iio_pe_config { + uint8_t socket; + IIO_PACKAGE_PE pe; + IIO_BIFURCATION bifurcation; + uint8_t cxl_support:1; + uint8_t reserved:7; + struct iio_port_config port_config[MAX_IIO_PORTS_PER_STACK]; +}; + +/* + * {_IIO_PE_CFG_STRUCT(socket, pe, bif, cxl) { + * _IIO_PORT_CFG_STRUCT(vppen vppex vaddr vport vmuxa vmuxc ...), + * _IIO_PORT_CFG_STRUCT(..), + * ... + * _IIO_PORT_CFG_STRUCT(..) //MAX_IIO_PORTS_PER_STACK port configs + * }} + */ + +#define PE_TYPE_CXL 1 +#define PE_TYPE_PCIE 0 + +#define _IIO_PE_CFG_STRUCT(s, p, bif, cxl) \ + .socket = (s),\ + .pe = (p),\ + .bifurcation = (bif),\ + .cxl_support = (cxl),\ + .reserved = 0,\ + .port_config = + +/* TODO: to update rsv1 - rsv5 after SoC launch */ +#define _IIO_PORT_CFG_STRUCT(vppen, vppex, vaddr, vport, vmuxa, vmuxc,\ + slteip, slthps, sltpind, sltaind, sltpctl, sltabtn, hotp, mrlsp,\ + sltimpl, sltpls, sltplv, psn,\ + rsv1, rsv2, rsv3, rsv4, rsv5) {\ + .vpp_enabled = (vppen),\ + .vpp_exp_type = (vppex),\ + .vpp_address = (vaddr),\ + .vpp_port = (vport),\ + .vpp_mux_address = (vmuxa),\ + .vpp_mux_channel = (vmuxc),\ + .slot_eip = (slteip),\ + .slot_hps = (slthps),\ + .slot_pind = (sltpind),\ + .slot_aind = (sltaind),\ + .slot_pctl = (sltpctl),\ + .slot_abtn = (sltabtn),\ + .slot_rsvd = 0,\ + .slot_implemented = (sltimpl),\ + .reserved = 0,\ + .hot_plug = (hotp),\ + .mrl_sensor_present = (mrlsp),\ + .slot_power_limit_scale = (sltpls),\ + .slot_power_limit_value = (sltplv),\ + .physical_slot_number = (psn)\ +} + +#define _IIO_PORT_CFG_STRUCT_DISABLED \ + _IIO_PORT_CFG_STRUCT(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0) + +#define _IIO_PORT_CFG_STRUCT_X8 _IIO_PORT_CFG_STRUCT +#define _IIO_PORT_CFG_STRUCT_X4 _IIO_PORT_CFG_STRUCT +#define _IIO_PORT_CFG_STRUCT_X2 _IIO_PORT_CFG_STRUCT + +#define _IIO_PORT_CFG_STRUCT_BASIC(sltpls, sltplv, psn)\ + _IIO_PORT_CFG_STRUCT(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,\ + 0x0, 0x0, 0x0, 0x1, sltpls, sltplv, psn, 0x0, 0x0, 0x0, 0x0, 0x0) + +#define _IIO_PORT_CFG_STRUCT_BASIC_X8 _IIO_PORT_CFG_STRUCT_BASIC +#define _IIO_PORT_CFG_STRUCT_BASIC_X4 _IIO_PORT_CFG_STRUCT_BASIC +#define _IIO_PORT_CFG_STRUCT_BASIC_X2 _IIO_PORT_CFG_STRUCT_BASIC + +void soc_config_iio_pe_ports(FSPM_UPD *mupd, const struct iio_pe_config *config_table, + unsigned int num_entries); + +const struct iio_pe_config *get_iio_config_table(int *size); + +#endif /* _SOC_IIO_H_ */ 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 000000000000..e2c63dbd2158 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/include/soc/pci_devs.h @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* TEMPORARY PLACE HOLDER! DO NOT USE! */ +/* FORKED FROM src/soc/intel/xeon_sp/spr/include/soc/pci_devs.h */ + +#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 000000000000..1cd7ab4739c3 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/include/soc/soc_msr.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* TEMPORARY PLACE HOLDER! DO NOT USE! */ +/* FORMED FROM src/soc/intel/xeon_sp/spr/include/soc/soc_msr.h */ + +#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 000000000000..1cfb10553bf6 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/include/soc/soc_util.h @@ -0,0 +1,31 @@ +/* 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 <CxlNodeHob.h> +#include <FspAcpiHobs.h> +#include <IioUniversalDataHob.h> +#include <MemoryMapDataHob.h> + +#define xSTACK_RES UDS_STACK_RES +#define xIIO_RESOURCE_INSTANCE UDS_SOCKET_RES + +#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 *pciroot_res_to_domain_type(const UDS_STACK_RES *sr, const UDS_PCIROOT_RES *rr); + +#endif /* _SOC_UTIL_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 000000000000..7a0453a67af1 --- /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 000000000000..95b2e15a5d03 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/romstage.c @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <soc/romstage.h> + +static uint8_t get_mmcfg_base_upd_index(const uint64_t base_addr) +{ + switch (base_addr) { + case 1ULL * GiB: // 1G + return 0; + case 1ULL * GiB + 512ULL * MiB: // 1.5G + return 0x1; + case 1ULL * GiB + 768ULL * MiB: // 1.75G + return 0x2; + case 2ULL * GiB: // 2G + return 0x3; + case 2ULL * GiB + 256ULL * MiB: // 2.25G + return 0x4; + case 3ULL * GiB: // 3G + return 0x5; + default: // Auto + return 0x6; + } +} + +static uint8_t get_mmcfg_size_upd_index(const uint64_t size) +{ + switch (size) { + case 64ULL * MiB: // 64M + return 0; + case 128ULL * MiB: // 128M + return 0x1; + case 256ULL * MiB: // 256M + return 0x2; + case 512ULL * MiB: // 512M + return 0x3; + case 1ULL * GiB: // 1G + return 0x4; + case 2ULL * GiB: // 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); + + /* 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 000000000000..6f1df7c386c5 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/soc_acpi.c @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <assert.h> +#include <intelblocks/acpi.h> +#include <intelblocks/pcr.h> +#include <intelblocks/itss.h> +#include <soc/acpi.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)); + + return (val & (1 << offset)) ? MP_IRQ_POLARITY_LOW : 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 soc_power_states_generation(int core, int cores_per_package) +{ + generate_p_state_entries(core, cores_per_package); +} diff --git a/src/soc/intel/xeon_sp/gnr/soc_iio.c b/src/soc/intel/xeon_sp/gnr/soc_iio.c new file mode 100644 index 000000000000..230d40706858 --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/soc_iio.c @@ -0,0 +1,65 @@ + /* SPDX-License-Identifier: GPL-2.0-only */ + +#include <soc/iio.h> + +#include <fsp/util.h> +#include <IioPcieConfigUpd.h> + +static IIO_BOARD_SETTINGS_HOB iio_upd_hob; + +void soc_config_iio_pe_ports(FSPM_UPD *mupd, const struct iio_pe_config *config_table, + unsigned int num_entries) +{ + int i; + uint8_t socket, pe, port; + + const struct iio_pe_config *board_pe_config; + const struct iio_port_config *board_port_config; + + IIO_BOARD_SETTINGS_PER_PE *upd_pe_config; + IIO_BOARD_SETTINGS_PER_PORT *upd_port_config; + + for (i = 0; i < num_entries; i++) { + board_pe_config = &config_table[i]; + socket = board_pe_config->socket; + pe = board_pe_config->pe; + + upd_pe_config = &(iio_upd_hob.Socket[socket].Pe[pe]); + + if ((socket >= MAX_SOCKET) || (pe >= MAX_IIO_PCIE_PER_SOCKET)) + continue; + + for (port = 0; port < MAX_IIO_PORTS_PER_STACK; port++) { + upd_port_config = &(upd_pe_config->Port[port]); + board_port_config = &(board_pe_config->port_config[port]); + + upd_pe_config->Bifurcation = board_pe_config->bifurcation; + upd_pe_config->CxlSupportInUba = board_pe_config->cxl_support; + + upd_port_config->Vpp.Address = board_port_config->vpp_address; + upd_port_config->Vpp.Port = board_port_config->vpp_port; + upd_port_config->Vpp.MuxAddress = board_port_config->vpp_mux_address; + upd_port_config->Vpp.MuxChannel = board_port_config->vpp_mux_channel; + + upd_port_config->Slot.Eip = board_port_config->slot_eip; + upd_port_config->Slot.HotPlugSurprise = board_port_config->slot_hps; + upd_port_config->Slot.PowerInd = board_port_config->slot_pind; + upd_port_config->Slot.AttentionInd = board_port_config->slot_aind; + upd_port_config->Slot.PowerCtrl = board_port_config->slot_pctl; + upd_port_config->Slot.AttentionBtn = board_port_config->slot_abtn; + + upd_port_config->VppEnabled = board_port_config->vpp_enabled; + upd_port_config->VppExpType = board_port_config->vpp_exp_type; + + upd_port_config->SlotImplemented = board_port_config->slot_implemented; + upd_port_config->HotPlug = board_port_config->hot_plug; + upd_port_config->MrlSensorPresent = board_port_config->mrl_sensor_present; + upd_port_config->SlotPowerLimitScale = board_port_config->slot_power_limit_scale; + upd_port_config->SlotPowerLimitValue = board_port_config->slot_power_limit_value; + upd_port_config->PhysicalSlotNumber = board_port_config->physical_slot_number; + } + } + + mupd->FspmConfig.IioBoardSettingsHobPtr = (UINT32)&iio_upd_hob; + mupd->FspmConfig.IioBoardSettingsHobLength = sizeof(iio_upd_hob); +} 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 000000000000..a65e5fcc52ae --- /dev/null +++ b/src/soc/intel/xeon_sp/gnr/soc_util.c @@ -0,0 +1,150 @@ +/* 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> + +const char *pciroot_res_to_domain_type(const UDS_STACK_RES *sr, const UDS_PCIROOT_RES *pr) +{ + int index = 0; + int instance = -1; + + for (; index < sr->PciRootBridgeNum; index++) { + if (sr->PciRoot[index].UidType == pr->UidType) + instance++; + if (sr->PciRoot[index].BusBase == pr->BusBase) + break; + } + + if (index == sr->PciRootBridgeNum) + return NULL; + + switch (pr->UidType) { + case PC_UID: + return DOMAIN_TYPE_PCIE; + case DINO_UID: + return DOMAIN_TYPE_DINO; + case CPM0_UID: + return DOMAIN_TYPE_CPM0; + case HQM0_UID: + return DOMAIN_TYPE_HQM0; + case UB_UID: + return (instance == 0) ? DOMAIN_TYPE_UBX0 : DOMAIN_TYPE_UBX1; + default: + return NULL; + } +} + +static bool is_domain_type_supported_on_stack(const xSTACK_RES *sr, const char *dt) +{ + for (unsigned int index = 0; index < sr->PciRootBridgeNum; index++) + if (!strcmp(dt, pciroot_res_to_domain_type(sr, &sr->PciRoot[index]))) + return true; + + return false; +} + +bool is_pcie_iio_stack_res(const xSTACK_RES *res) +{ + return is_domain_type_supported_on_stack(res, DOMAIN_TYPE_PCIE); +} + +bool is_ioat_iio_stack_res(const xSTACK_RES *res) +{ + return (is_domain_type_supported_on_stack(res, DOMAIN_TYPE_DINO) || + is_domain_type_supported_on_stack(res, DOMAIN_TYPE_CPM0) || + is_domain_type_supported_on_stack(res, DOMAIN_TYPE_HQM0)); + +} + +bool is_ubox_stack_res(const xSTACK_RES *res) +{ + return (is_domain_type_supported_on_stack(res, DOMAIN_TYPE_UBX0) || + is_domain_type_supported_on_stack(res, DOMAIN_TYPE_UBX1)); +} + +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 (unsigned int skt_id = 0 ; skt_id < MAX_SOCKET; skt_id++) + count += hob[skt_id].CxlNodeCount; + + return count; +} + +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/acpi.h b/src/soc/intel/xeon_sp/include/soc/acpi.h index e37454496238..7c7aee0ad40f 100644 --- a/src/soc/intel/xeon_sp/include/soc/acpi.h +++ b/src/soc/intel/xeon_sp/include/soc/acpi.h @@ -18,11 +18,25 @@ enum acpi_cstate_mode { unsigned long northbridge_write_acpi_tables(const struct device *device, unsigned long current, struct acpi_rsdp *rsdp); -unsigned long xeonsp_acpi_create_madt_lapics(unsigned long current); unsigned long acpi_fill_cedt(unsigned long current); unsigned long acpi_fill_hmat(unsigned long current); unsigned long cxl_fill_srat(unsigned long current); void iio_domain_set_acpi_name(struct device *dev, const char *prefix); +#define PCIE_NATIVE_HOTPLUG_CONTROL 0x01 +#define SHPC_NATIVE_HOTPLUG_CONTROL 0x02 +#define PCIE_PME_CONTROL 0x04 +#define PCIE_AER_CONTROL 0x08 +#define PCIE_CAP_STRUCTURE_CONTROL 0x10 +#define PCIE_LTR_CONTROL 0x20 +#define PCIE_DPC_COTROL 0x80 + +#define CXL_ERROR_REPORTING_CONTROL 0x01 + +void acpigen_write_OSC_pci_domain_fixed_caps(const struct device *domain, + const uint32_t granted_pcie_features, + const bool is_cxl_domain, + const uint32_t granted_cxl_features); + #endif /* _SOC_ACPI_H_ */ diff --git a/src/soc/intel/xeon_sp/include/soc/config.h b/src/soc/intel/xeon_sp/include/soc/config.h new file mode 100644 index 000000000000..6d5f3d587d43 --- /dev/null +++ b/src/soc/intel/xeon_sp/include/soc/config.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _XEON_SP_SOC_CONFIG_H_ +#define _XEON_SP_SOC_CONFIG_H_ + +enum xeonsp_cxl_mode { + XEONSP_CXL_DISABLED = 0, + XEONSP_CXL_SYS_MEM, + XEONSP_CXL_SP_MEM, +}; + +enum xeonsp_cxl_mode get_cxl_mode(void); + +#endif diff --git a/src/soc/intel/xeon_sp/include/soc/ddr.h b/src/soc/intel/xeon_sp/include/soc/ddr.h index bb10caaf1fb0..0b5bdb6b1529 100644 --- a/src/soc/intel/xeon_sp/include/soc/ddr.h +++ b/src/soc/intel/xeon_sp/include/soc/ddr.h @@ -9,7 +9,6 @@ * currently DDR4 only supports 1.2V, DDR5 only supports 1.1V. */ #define SPD_VDD_DDR4 3 #define SPD_VDD_DDR5 0 -#define SPD_TYPE_DDR5 0x12 /* DDR_*_TCK_MIN are in picoseconds */ #define DDR_800_TCK_MIN 2500 diff --git a/src/soc/intel/xeon_sp/include/soc/numa.h b/src/soc/intel/xeon_sp/include/soc/numa.h index aba3f0926bc3..b64488190fa2 100644 --- a/src/soc/intel/xeon_sp/include/soc/numa.h +++ b/src/soc/intel/xeon_sp/include/soc/numa.h @@ -7,8 +7,11 @@ #ifndef NUMA_H #define NUMA_H +#include <soc/soc_util.h> #include <types.h> +#define XEONSP_INVALID_PD_INDEX UINT32_MAX + enum proximity_domain_type { PD_TYPE_PROCESSOR, /* @@ -16,6 +19,18 @@ enum proximity_domain_type { * Generic Initiator domain is a CXL memory device. */ PD_TYPE_GENERIC_INITIATOR, + /* + * PD_TYPE_CLUSTER is for Sub-NUMA cluster (SNC). SNC is localization + * domain within a socket, composed of a set of CPU cores, last-level + * cache pieces and memory controllers, which are close to each other. + * SNC will be reported as NUMA nodes to OS so that the performance + * proximity could be fully exploited for task assignment and scheduling. + * + * For more, please refer to + * https://www.intel.com/content/www/us/en/developer/articles/technical/xeon-processor-scalable-family-technical-overview.html + */ + PD_TYPE_CLUSTER, + PD_TYPE_MAX }; /* @@ -36,6 +51,7 @@ struct proximity_domain { * sockets, so we need a bitmap. */ uint8_t socket_bitmap; + uint8_t cluster_bitmap; /* Relative distances (memory latency) from all domains */ uint8_t *distances; /* @@ -53,8 +69,7 @@ struct proximity_domains { extern struct proximity_domains pds; -void dump_pds(void); -void fill_pds(void); +void setup_pds(void); /* * Return the total size of memory regions in generic initiator affinity @@ -62,4 +77,10 @@ void fill_pds(void); */ uint32_t get_generic_initiator_mem_size(void); +uint32_t memory_to_pd(const struct SystemMemoryMapElement *mem); +uint32_t device_to_pd(const struct device *dev); + +uint8_t soc_get_cluster_count(void); +void soc_set_cpu_node_id(struct device *cpu); + #endif /* NUMA_H */ diff --git a/src/soc/intel/xeon_sp/include/soc/util.h b/src/soc/intel/xeon_sp/include/soc/util.h index 177d6d50e338..e694af3e3ca8 100644 --- a/src/soc/intel/xeon_sp/include/soc/util.h +++ b/src/soc/intel/xeon_sp/include/soc/util.h @@ -4,6 +4,7 @@ #define _XEON_SP_SOC_UTIL_H_ #include <cpu/x86/msr.h> +#include <intelblocks/p2sb.h> #include <soc/soc_util.h> #define MEM_ADDR_64MB_SHIFT_BITS 26 @@ -27,5 +28,7 @@ bool is_ubox_stack_res(const xSTACK_RES *res); bool is_ioat_iio_stack_res(const xSTACK_RES *res); bool is_iio_cxl_stack_res(const xSTACK_RES *res); void bios_done_msr(void *unused); +union p2sb_bdf soc_get_hpet_bdf(void); +union p2sb_bdf soc_get_ioapic_bdf(void); #endif diff --git a/src/soc/intel/xeon_sp/lockdown.c b/src/soc/intel/xeon_sp/lockdown.c index 9e25920011b9..a3d17b46c331 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 @@ static void lpc_lockdown_config(void) 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/numa.c b/src/soc/intel/xeon_sp/numa.c index 62657dce1f91..8ce49818e94c 100644 --- a/src/soc/intel/xeon_sp/numa.c +++ b/src/soc/intel/xeon_sp/numa.c @@ -5,12 +5,13 @@ #include <device/pci_ops.h> #include <device/pci.h> #include <device/pciexp.h> +#include <soc/chip_common.h> #include <soc/numa.h> #include <soc/soc_util.h> #include <soc/util.h> #include <types.h> -void dump_pds(void) +static void dump_pds(void) { printk(BIOS_DEBUG, "====== Proximity Domain Dump ======\n"); printk(BIOS_DEBUG, "number of proximity domains: %d\n", pds.num_pds); @@ -18,30 +19,41 @@ void dump_pds(void) printk(BIOS_DEBUG, "\tproximity domain %d:\n", i); printk(BIOS_DEBUG, "\t\ttype:%d\n", pds.pds[i].pd_type); printk(BIOS_DEBUG, "\t\tsocket_bitmap:0x%x\n", pds.pds[i].socket_bitmap); - printk(BIOS_DEBUG, "\t\tdevice:%s\n", pds.pds[i].dev ? dev_path(pds.pds[i].dev) : ""); - printk(BIOS_DEBUG, "\t\tbase(64MB):0x%x\n", pds.pds[i].base); - printk(BIOS_DEBUG, "\t\tsize(64MB):0x%x\n", pds.pds[i].size); + if (pds.pds[i].pd_type == PD_TYPE_GENERIC_INITIATOR) { + printk(BIOS_DEBUG, "\t\tdevice:%s\n", + pds.pds[i].dev ? dev_path(pds.pds[i].dev) : ""); + printk(BIOS_DEBUG, "\t\tbase(64MB):0x%x\n", pds.pds[i].base); + printk(BIOS_DEBUG, "\t\tsize(64MB):0x%x\n", pds.pds[i].size); + } + if (pds.pds[i].pd_type == PD_TYPE_CLUSTER) { + printk(BIOS_DEBUG, "\t\tcluster_bitmap:0x%x\n", pds.pds[i].cluster_bitmap); + } } } -void fill_pds(void) +static void fill_pds(void) { uint8_t num_sockets = soc_get_num_cpus(); uint8_t num_cxlnodes = get_cxl_node_count(); + uint8_t num_clusters = soc_get_cluster_count(); const IIO_UDS *hob = get_iio_uds(); /* * Rules/assumptions: - * 1. Each processor has a processor proximity domain regardless whether + * 1. Each socket has a processor proximity domain regardless whether * a processor has DIMM attached to it or not. - * 2. All system memory map elements are either from processor attached memory, + * 2. When sub-NUMA cluster (SNC) is on, soc_get_cluster_count() will return a + * non-zero value and each SNC cluster will have one proximity domain. + * For SNC case, DIMMs and CPU cores are attached to SNC proximity domains instead + * of the processor proximity domains. + * 3. All system memory map elements are either from processor attached memory, * or from CXL memory. Each CXL node info entry has a corresponding entry * in system memory map elements. - * 3. Each CXL device may have multiple HDMs (Host-managed Device Memory). Each + * 4. Each CXL device may have multiple HDMs (Host-managed Device Memory). Each * HDM has one and only one CXL node info entry. Each CXL node info entry * represents a generic initiator proximity domain. */ - pds.num_pds = num_cxlnodes + num_sockets; + pds.num_pds = num_cxlnodes + num_sockets + num_sockets * num_clusters; pds.pds = xmalloc(sizeof(struct proximity_domain) * pds.num_pds); if (!pds.pds) die("%s %d out of memory.", __FILE__, __LINE__); @@ -49,54 +61,52 @@ void fill_pds(void) memset(pds.pds, 0, sizeof(struct proximity_domain) * pds.num_pds); /* Fill in processor domains */ - uint8_t i, j, socket; - struct device *dev; - for (socket = 0, i = 0; i < num_sockets; socket++) { + uint8_t i = 0; + for (uint8_t socket = 0; socket < num_sockets; socket++) { if (!soc_cpu_is_enabled(socket)) continue; + const uint8_t socket_id = hob->PlatformData.IIO_resource[socket].SocketID; pds.pds[i].pd_type = PD_TYPE_PROCESSOR; - pds.pds[i].socket_bitmap = 1 << hob->PlatformData.IIO_resource[socket].SocketID; + pds.pds[i].socket_bitmap = 1 << socket_id; pds.pds[i].distances = malloc(sizeof(uint8_t) * pds.num_pds); if (!pds.pds[i].distances) die("%s %d out of memory.", __FILE__, __LINE__); - /* hard code the distances for now, till we know how to calculate them. */ - for (j = 0; j < pds.num_pds; j++) { - if (j == i) - pds.pds[i].distances[j] = 0x0a; - else - pds.pds[i].distances[j] = 0x0e; - } i++; + /* Fill in cluster domains */ + for (uint8_t cluster = 0; cluster < num_clusters; cluster++) { + pds.pds[i].pd_type = PD_TYPE_CLUSTER; + pds.pds[i].socket_bitmap = 1 << socket_id; + pds.pds[i].cluster_bitmap = 1 << cluster; + pds.pds[i].distances = malloc(sizeof(uint8_t) * pds.num_pds); + if (!pds.pds[i].distances) + die("%s %d out of memory.", __FILE__, __LINE__); + i++; + } } /* If there are no CXL nodes, we are done */ if (num_cxlnodes == 0) return; +#if CONFIG(SOC_INTEL_HAS_CXL) /* There are CXL nodes, fill in generic initiator domain after the processors pds */ - uint8_t skt_id, cxl_id; const CXL_NODE_SOCKET *cxl_hob = get_cxl_node(); - for (skt_id = 0, i = num_sockets; skt_id < MAX_SOCKET; skt_id++, i++) { - for (cxl_id = 0; cxl_id < cxl_hob[skt_id].CxlNodeCount; ++cxl_id) { + for (uint8_t skt_id = 0; skt_id < MAX_SOCKET; skt_id++) { + for (uint8_t cxl_id = 0; cxl_id < cxl_hob[skt_id].CxlNodeCount; ++cxl_id) { const CXL_NODE_INFO node = cxl_hob[skt_id].CxlNodeInfo[cxl_id]; pds.pds[i].pd_type = PD_TYPE_GENERIC_INITIATOR; pds.pds[i].socket_bitmap = node.SocketBitmap; pds.pds[i].base = node.Address; pds.pds[i].size = node.Size; - dev = pcie_find_dsn(node.SerialNumber, node.VendorId, 0); + struct device *dev = pcie_find_dsn(node.SerialNumber, node.VendorId, 0); pds.pds[i].dev = dev; pds.pds[i].distances = malloc(sizeof(uint8_t) * pds.num_pds); if (!pds.pds[i].distances) die("%s %d out of memory.", __FILE__, __LINE__); - /* hard code the distances until we know how to calculate them */ - for (j = 0; j < pds.num_pds; j++) { - if (j == i) - pds.pds[i].distances[j] = 0x0a; - else - pds.pds[i].distances[j] = 0x0e; - } + i++; } } +#endif } /* @@ -109,10 +119,121 @@ uint32_t get_generic_initiator_mem_size(void) uint32_t size = 0; for (i = 0; i < pds.num_pds; i++) { - if (pds.pds[i].pd_type == PD_TYPE_PROCESSOR) + if (pds.pds[i].pd_type != PD_TYPE_GENERIC_INITIATOR) continue; size += pds.pds[i].size; } return size; } + +static uint32_t socket_to_pd(uint8_t socket) +{ + for (uint8_t i = 0; i < pds.num_pds; i++) { + if (pds.pds[i].pd_type != PD_TYPE_PROCESSOR) + continue; + if (pds.pds[i].socket_bitmap == (1 << socket)) + return i; + } + + printk(BIOS_ERR, "%s: could not find proximity domain for socket %d.\n", + __func__, socket); + + return XEONSP_INVALID_PD_INDEX; +} + +static uint32_t cluster_to_pd(uint8_t socket, uint8_t cluster) +{ + for (uint8_t i = 0; i < pds.num_pds; i++) { + if (pds.pds[i].pd_type != PD_TYPE_CLUSTER) + continue; + if (pds.pds[i].socket_bitmap == (1 << socket) && + pds.pds[i].cluster_bitmap == (1 << cluster)) + return i; + } + + printk(BIOS_ERR, "%s: could not find proximity domain for socket/cluster %d/%d.\n", + __func__, socket, cluster); + + return XEONSP_INVALID_PD_INDEX; +} + +uint32_t device_to_pd(const struct device *dev) +{ + /* first to see if the dev is bound to specific pd */ + for (int i = 0; i < pds.num_pds; i++) + if (pds.pds[i].dev == dev) + return i; + + if (dev->path.type == DEVICE_PATH_APIC) { + if (soc_get_cluster_count()) + return cluster_to_pd(dev->path.apic.package_id, dev->path.apic.node_id); + else + return socket_to_pd(dev->path.apic.package_id); + } + + if ((dev->path.type == DEVICE_PATH_DOMAIN) || + (dev->path.type == DEVICE_PATH_PCI)) + return socket_to_pd(iio_pci_domain_socket_from_dev(dev)); + + printk(BIOS_ERR, "%s: could not find proximity domain for device %s.\n", + __func__, dev_path(dev)); + + return XEONSP_INVALID_PD_INDEX; +} + +__weak uint32_t memory_to_pd(const struct SystemMemoryMapElement *mem) +{ + /* + * TODO: For SNC case, link DRAM range to cluster id instead of socket id + * in SoC codes. + */ + return socket_to_pd(mem->SocketId); +} + +#define PD_DISTANCE_SELF 0x0A +#define PD_DISTANCE_SAME_SOCKET 0x0C +#define PD_DISTANCE_CROSS_SOCKET 0x14 +#define PD_DISTANCE_MAX 0xFF +#define PD_DISTANCE_IO_EXTRA 0x01 + +static void fill_pd_distances(void) +{ + for (int i = 0; i < pds.num_pds; i++) { + for (int j = 0; j < pds.num_pds; j++) { + if (i == j) { + pds.pds[i].distances[j] = PD_DISTANCE_SELF; + continue; + } + + if (pds.pds[i].socket_bitmap == pds.pds[j].socket_bitmap) + pds.pds[i].distances[j] = PD_DISTANCE_SAME_SOCKET; + else + pds.pds[i].distances[j] = PD_DISTANCE_CROSS_SOCKET; + + if (pds.pds[i].pd_type == PD_TYPE_GENERIC_INITIATOR) + pds.pds[i].distances[j] += PD_DISTANCE_IO_EXTRA; + + if (pds.pds[j].pd_type == PD_TYPE_GENERIC_INITIATOR) + pds.pds[i].distances[j] += PD_DISTANCE_IO_EXTRA; + } + } +} + +void setup_pds(void) +{ + fill_pds(); + fill_pd_distances(); + dump_pds(); +} + +__weak uint8_t soc_get_cluster_count(void) +{ + //TODO: Implement in SoC codes. + return 0; +} + +__weak void soc_set_cpu_node_id(struct device *cpu) +{ + //TODO: Implement in SoC codes. +}; diff --git a/src/soc/intel/xeon_sp/skx/chip.c b/src/soc/intel/xeon_sp/skx/chip.c index 903d0cc69b5d..37535a3cf021 100644 --- a/src/soc/intel/xeon_sp/skx/chip.c +++ b/src/soc/intel/xeon_sp/skx/chip.c @@ -7,6 +7,7 @@ #include <intelblocks/acpi.h> #include <soc/acpi.h> #include <soc/chip_common.h> +#include <soc/numa.h> #include <soc/pch.h> #include <soc/soc_pch.h> #include <soc/ramstage.h> @@ -42,6 +43,7 @@ static void soc_init(void *data) printk(BIOS_DEBUG, "coreboot: calling fsp_silicon_init\n"); fsp_silicon_init(); + setup_pds(); attach_iio_stacks(); override_hpet_ioapic_bdf(); diff --git a/src/soc/intel/xeon_sp/skx/soc_util.c b/src/soc/intel/xeon_sp/skx/soc_util.c index 6f482466cea0..0ccacfb73c37 100644 --- a/src/soc/intel/xeon_sp/skx/soc_util.c +++ b/src/soc/intel/xeon_sp/skx/soc_util.c @@ -209,3 +209,8 @@ bool is_memtype_processor_attached(uint16_t mem_type) { return true; } + +uint8_t get_cxl_node_count(void) +{ + return 0; +} diff --git a/src/soc/intel/xeon_sp/spr/Kconfig b/src/soc/intel/xeon_sp/spr/Kconfig index 401c8e498159..b84a8ff26771 100644 --- a/src/soc/intel/xeon_sp/spr/Kconfig +++ b/src/soc/intel/xeon_sp/spr/Kconfig @@ -107,9 +107,6 @@ config SOC_INTEL_HAS_BIOS_DONE_MSR config SOC_INTEL_HAS_NCMEM def_bool y -config SOC_INTEL_PCIE_64BIT_ALLOC - def_bool y - config SOC_INTEL_MMAPVTD_ONLY_FOR_DPR def_bool y diff --git a/src/soc/intel/xeon_sp/spr/chip.c b/src/soc/intel/xeon_sp/spr/chip.c index ec23940f2bba..e179df0e1516 100644 --- a/src/soc/intel/xeon_sp/spr/chip.c +++ b/src/soc/intel/xeon_sp/spr/chip.c @@ -125,6 +125,7 @@ static void chip_init(void *data) printk(BIOS_DEBUG, "coreboot: calling fsp_silicon_init\n"); fsp_silicon_init(); + setup_pds(); attach_iio_stacks(); override_hpet_ioapic_bdf(); @@ -175,7 +176,7 @@ static void rcec_init(struct device *dev) uint32_t ep_bus; uint8_t i; for (i = 0; i < pds.num_pds; i++) { - if (pds.pds[i].pd_type == PD_TYPE_PROCESSOR) + if (pds.pds[i].pd_type != PD_TYPE_GENERIC_INITIATOR) continue; ep_bus = PCI_BDF(pds.pds[i].dev) >> 20; if (ep_bus == ecrc_bus + 1) diff --git a/src/soc/intel/xeon_sp/spr/cpu.c b/src/soc/intel/xeon_sp/spr/cpu.c index f9c8e2627393..ad099ab70b71 100644 --- a/src/soc/intel/xeon_sp/spr/cpu.c +++ b/src/soc/intel/xeon_sp/spr/cpu.c @@ -1,28 +1,17 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include <acpi/acpigen.h> -#include <acpi/acpi.h> -#include <console/console.h> #include <console/debug.h> -#include <cpu/cpu.h> -#include <cpu/intel/cpu_ids.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 <cpu/x86/topology.h> -#include <device/pci_mmio_cfg.h> #include <intelblocks/cpulib.h> #include <intelblocks/mp_init.h> #include <intelpch/lockdown.h> #include <soc/msr.h> -#include <soc/pci_devs.h> #include <soc/pm.h> -#include <soc/soc_util.h> #include <soc/smmrelocate.h> #include <soc/util.h> @@ -235,6 +224,12 @@ static int get_thread_count(void) { unsigned int num_phys = 0, num_virts = 0; + /* + * This call calculates the thread count which is corresponding to num_virts + * (logical cores), while num_phys is corresponding to physical cores (in SMT + * system, one physical core has multiple threads, a.k.a. logical cores). + * Hence num_phys is not actually used. + */ 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(); @@ -273,12 +268,9 @@ void mp_init_cpus(struct bus *bus) 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"); + enum cb_err ret = mp_init_with_smm(bus, &mp_ops); + if (ret != CB_SUCCESS) + printk(BIOS_ERR, "MP initialization failure %d.\n", ret); } diff --git a/src/soc/intel/xeon_sp/spr/ioat.c b/src/soc/intel/xeon_sp/spr/ioat.c index 9ed9576ef369..a0babee5feec 100644 --- a/src/soc/intel/xeon_sp/spr/ioat.c +++ b/src/soc/intel/xeon_sp/spr/ioat.c @@ -61,21 +61,11 @@ static void create_ioat_domain(const union xeon_domain_path dp, struct bus *cons unsigned int index = 0; - if (mem32_base <= mem32_limit) { - struct resource *const res = new_resource(domain, index++); - res->base = mem32_base; - res->limit = mem32_limit; - res->size = res->limit - res->base + 1; - res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED; - } + if (mem32_base <= mem32_limit) + domain_mem_window_from_to(domain, index++, mem32_base, mem32_limit + 1); - if (mem64_base <= mem64_limit) { - struct resource *const res = new_resource(domain, index++); - res->base = mem64_base; - res->limit = mem64_limit; - res->size = res->limit - res->base + 1; - res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED; - } + if (mem64_base <= mem64_limit) + domain_mem_window_from_to(domain, index++, mem64_base, mem64_limit + 1); } void create_ioat_domains(const union xeon_domain_path path, diff --git a/src/soc/intel/xeon_sp/spr/romstage.c b/src/soc/intel/xeon_sp/spr/romstage.c index 3e16608ca4c8..26bb3081a121 100644 --- a/src/soc/intel/xeon_sp/spr/romstage.c +++ b/src/soc/intel/xeon_sp/spr/romstage.c @@ -13,12 +13,16 @@ #include <fsp/util.h> #include <hob_iiouds.h> #include <hob_memmap.h> +#include <spd.h> +#include <soc/chip_common.h> #include <soc/romstage.h> #include <soc/pci_devs.h> #include <soc/soc_pch.h> #include <soc/intel/common/smbios.h> #include <string.h> +#include <soc/config.h> #include <soc/soc_util.h> +#include <soc/util.h> #include <soc/ddr.h> #include "chip.h" @@ -32,73 +36,10 @@ void __weak mainboard_memory_init_params(FSPM_UPD *mupd) /* Default weak implementation */ } -/* - * Search from VPD_RW first then VPD_RO for UPD config variables, - * overwrites them from VPD if it's found. - */ -static void config_upd_from_vpd(FSPM_UPD *mupd) +static void config_upd(FSPM_UPD *mupd) { - uint8_t val; - int val_int, cxl_mode; - - /* Send FSP log message to SOL */ - if (vpd_get_bool(FSP_LOG, VPD_RW_THEN_RO, &val)) - mupd->FspmConfig.SerialIoUartDebugEnable = val; - else { - printk(BIOS_INFO, - "Not able to get VPD %s, default set " - "SerialIoUartDebugEnable to %d\n", - FSP_LOG, FSP_LOG_DEFAULT); - mupd->FspmConfig.SerialIoUartDebugEnable = FSP_LOG_DEFAULT; - } - - if (mupd->FspmConfig.SerialIoUartDebugEnable) { - /* FSP memory debug log level */ - if (vpd_get_int(FSP_MEM_LOG_LEVEL, VPD_RW_THEN_RO, &val_int)) { - if (val_int < 0 || val_int > 4) { - printk(BIOS_DEBUG, - "Invalid serialDebugMsgLvl value from VPD: " - "%d\n", - val_int); - val_int = FSP_MEM_LOG_LEVEL_DEFAULT; - } - printk(BIOS_DEBUG, "Setting serialDebugMsgLvl to %d\n", val_int); - mupd->FspmConfig.serialDebugMsgLvl = (uint8_t)val_int; - } else { - printk(BIOS_INFO, - "Not able to get VPD %s, default set " - "DebugPrintLevel to %d\n", - FSP_MEM_LOG_LEVEL, FSP_MEM_LOG_LEVEL_DEFAULT); - mupd->FspmConfig.serialDebugMsgLvl = FSP_MEM_LOG_LEVEL_DEFAULT; - } - /* If serialDebugMsgLvl less than 1, disable FSP memory train results */ - if (mupd->FspmConfig.serialDebugMsgLvl <= 1) { - printk(BIOS_DEBUG, "Setting serialDebugMsgLvlTrainResults to 0\n"); - mupd->FspmConfig.serialDebugMsgLvlTrainResults = 0x0; - } - } - - /* FSP Dfx PMIC Secure mode */ - if (vpd_get_int(FSP_PMIC_SECURE_MODE, VPD_RW_THEN_RO, &val_int)) { - if (val_int < 0 || val_int > 2) { - printk(BIOS_DEBUG, - "Invalid PMIC secure mode value from VPD: " - "%d\n", - val_int); - val_int = FSP_PMIC_SECURE_MODE_DEFAULT; - } - printk(BIOS_DEBUG, "Setting PMIC secure mode to %d\n", val_int); - mupd->FspmConfig.DfxPmicSecureMode = (uint8_t)val_int; - } else { - printk(BIOS_INFO, - "Not able to get VPD %s, default set " - "PMIC secure mode to %d\n", - FSP_PMIC_SECURE_MODE, FSP_PMIC_SECURE_MODE_DEFAULT); - mupd->FspmConfig.DfxPmicSecureMode = FSP_PMIC_SECURE_MODE_DEFAULT; - } - - cxl_mode = get_cxl_mode_from_vpd(); - if (cxl_mode == CXL_SYSTEM_MEMORY || cxl_mode == CXL_SPM) + int cxl_mode = get_cxl_mode(); + if (cxl_mode == XEONSP_CXL_SYS_MEM || cxl_mode == XEONSP_CXL_SP_MEM) mupd->FspmConfig.DfxCxlType3LegacyEn = 1; else /* Disable CXL */ mupd->FspmConfig.DfxCxlType3LegacyEn = 0; @@ -272,9 +213,8 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) printk(BIOS_DEBUG, "CPU is D stepping, setting package C state to C0/C1\n"); mupd->FspmConfig.CpuPmPackageCState = 0; } - /* Set some common UPDs from VPD, mainboard can still override them if needed */ - if (CONFIG(VPD)) - config_upd_from_vpd(mupd); + + config_upd(mupd); initialize_iio_upd(mupd); mainboard_memory_init_params(mupd); @@ -392,7 +332,7 @@ void save_dimm_info(void) dest_dimm->soc_num = soc; - if (hob->DramType == SPD_TYPE_DDR5) { + if (hob->DramType == SPD_MEMORY_TYPE_DDR5_SDRAM) { /* hard-coded memory device type as DDR5 */ mem_dev_type = 0x22; data_width = 64; diff --git a/src/soc/intel/xeon_sp/spr/soc_acpi.c b/src/soc/intel/xeon_sp/spr/soc_acpi.c index 1249b8ff041d..32ef1edb20f2 100644 --- a/src/soc/intel/xeon_sp/spr/soc_acpi.c +++ b/src/soc/intel/xeon_sp/spr/soc_acpi.c @@ -12,6 +12,7 @@ #include <intelblocks/pmclib.h> #include <soc/acpi.h> #include <soc/iomap.h> +#include <soc/numa.h> #include <soc/msr.h> #include <soc/pci_devs.h> #include <soc/pm.h> @@ -155,25 +156,6 @@ void soc_power_states_generation(int core, int cores_per_package) acpigen_pop_len(); } -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) { const IIO_UDS *hob = get_iio_uds(); diff --git a/src/soc/intel/xeon_sp/spr/soc_util.c b/src/soc/intel/xeon_sp/spr/soc_util.c index 9ad09f4c4be8..584532785e1a 100644 --- a/src/soc/intel/xeon_sp/spr/soc_util.c +++ b/src/soc/intel/xeon_sp/spr/soc_util.c @@ -90,8 +90,11 @@ bool is_ioat_iio_stack_res(const STACK_RES *res) */ bool is_iio_cxl_stack_res(const STACK_RES *res) { + /* pds should be setup ahead of this call */ + assert(pds.num_pds); + for (uint8_t i = 0; i < pds.num_pds; i++) { - if (pds.pds[i].pd_type == PD_TYPE_PROCESSOR) + if (pds.pds[i].pd_type != PD_TYPE_GENERIC_INITIATOR) continue; uint32_t bus = PCI_BDF(pds.pds[i].dev) >> 20; diff --git a/src/soc/intel/xeon_sp/uncore.c b/src/soc/intel/xeon_sp/uncore.c index a177a89d6622..d2d46220a2d7 100644 --- a/src/soc/intel/xeon_sp/uncore.c +++ b/src/soc/intel/xeon_sp/uncore.c @@ -6,8 +6,8 @@ #include <cpu/x86/lapic_def.h> #include <device/pci.h> #include <device/pci_ids.h> -#include <drivers/ocp/include/vpd.h> #include <soc/acpi.h> +#include <soc/chip_common.h> #include <soc/iomap.h> #include <soc/pci_devs.h> #include <soc/ramstage.h> @@ -15,6 +15,7 @@ #include <fsp/util.h> #include <security/intel/txt/txt_platform.h> #include <security/intel/txt/txt.h> +#include <soc/config.h> #include <soc/numa.h> #include <soc/soc_util.h> #include <stdint.h> @@ -283,25 +284,23 @@ static void mc_add_dram_resources(struct device *dev, int *res_count) /* CXL Memory */ uint8_t i; for (i = 0; i < pds.num_pds; i++) { - if (pds.pds[i].pd_type == PD_TYPE_PROCESSOR) + if (pds.pds[i].pd_type != PD_TYPE_GENERIC_INITIATOR) continue; - if (CONFIG(OCP_VPD)) { - unsigned long flags = IORESOURCE_CACHEABLE; - int cxl_mode = get_cxl_mode_from_vpd(); - if (cxl_mode == CXL_SPM) - flags |= IORESOURCE_SOFT_RESERVE; - else - flags |= IORESOURCE_STORED; - - res = fixed_mem_range_flags(dev, index++, - (uint64_t)pds.pds[i].base << 26, - (uint64_t)pds.pds[i].size << 26, flags); - if (cxl_mode == CXL_SPM) - LOG_RESOURCE("specific_purpose_memory", dev, res); - else - LOG_RESOURCE("CXL_memory", dev, res); - } + unsigned long flags = IORESOURCE_CACHEABLE; + int cxl_mode = get_cxl_mode(); + if (cxl_mode == XEONSP_CXL_SP_MEM) + flags |= IORESOURCE_SOFT_RESERVE; + else + flags |= IORESOURCE_STORED; + + res = fixed_mem_range_flags(dev, index++, + (uint64_t)pds.pds[i].base << 26, + (uint64_t)pds.pds[i].size << 26, flags); + if (cxl_mode == XEONSP_CXL_SP_MEM) + LOG_RESOURCE("specific_purpose_memory", dev, res); + else + LOG_RESOURCE("CXL_memory", dev, res); } } else { /* 4GiB -> TOHM */ @@ -338,16 +337,6 @@ static void mmapvtd_read_resources(struct device *dev) { int index = 0; - if (CONFIG(SOC_INTEL_HAS_CXL)) { - static bool once; - if (!once) { - /* Construct NUMA data structure. This is needed for CXL. */ - fill_pds(); - dump_pds(); - once = true; - } - } - /* Read standard PCI resources. */ pci_dev_read_resources(dev); diff --git a/src/soc/intel/xeon_sp/uncore_acpi.c b/src/soc/intel/xeon_sp/uncore_acpi.c index bcfb4da92d75..6b6363d8ec54 100644 --- a/src/soc/intel/xeon_sp/uncore_acpi.c +++ b/src/soc/intel/xeon_sp/uncore_acpi.c @@ -18,7 +18,6 @@ #include <soc/pci_devs.h> #include <soc/soc_util.h> #include <soc/util.h> -#include <intelblocks/p2sb.h> #include "chip.h" /* NUMA related ACPI table generation. SRAT, SLIT, etc */ @@ -60,16 +59,16 @@ unsigned long acpi_create_srat_lapics(unsigned long current) if (is_x2apic_mode()) { printk(BIOS_DEBUG, "SRAT: x2apic cpu_index=%04x, node_id=%02x, apic_id=%08x\n", - i, cpu->path.apic.node_id, cpu->path.apic.apic_id); + i, device_to_pd(cpu), cpu->path.apic.apic_id); current += acpi_create_srat_x2apic((acpi_srat_x2apic_t *)current, - cpu->path.apic.node_id, cpu->path.apic.apic_id); + device_to_pd(cpu), cpu->path.apic.apic_id); } else { printk(BIOS_DEBUG, "SRAT: lapic cpu_index=%02x, node_id=%02x, apic_id=%02x\n", - i, cpu->path.apic.node_id, cpu->path.apic.apic_id); + i, device_to_pd(cpu), cpu->path.apic.apic_id); current += acpi_create_srat_lapic((acpi_srat_lapic_t *)current, - cpu->path.apic.node_id, cpu->path.apic.apic_id); + device_to_pd(cpu), cpu->path.apic.apic_id); } } return current; @@ -129,7 +128,7 @@ static unsigned int get_srat_memory_entries(acpi_srat_mem_t *srat_mem) srat_mem[mmap_index].base_address_high = (uint32_t)(addr >> 32); srat_mem[mmap_index].length_low = (uint32_t)(size & 0xffffffff); srat_mem[mmap_index].length_high = (uint32_t)(size >> 32); - srat_mem[mmap_index].proximity_domain = mem_element->SocketId; + srat_mem[mmap_index].proximity_domain = memory_to_pd(mem_element); srat_mem[mmap_index].flags = ACPI_SRAT_MEMORY_ENABLED; if (is_memtype_non_volatile(mem_element->Type)) srat_mem[mmap_index].flags |= ACPI_SRAT_MEMORY_NONVOLATILE; @@ -283,7 +282,7 @@ static unsigned long acpi_create_drhd(unsigned long current, struct device *iomm // Add PCH IOAPIC if (is_dev_on_domain0(iommu)) { - union p2sb_bdf ioapic_bdf = p2sb_get_ioapic_bdf(); + 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); @@ -318,7 +317,7 @@ static unsigned long acpi_create_drhd(unsigned long current, struct device *iomm const struct device *domain = dev_get_domain(iommu); struct device *dev = NULL; while ((dev = dev_bus_each_child(domain->downstream, dev))) - if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) + if (is_pci_bridge(dev)) current += acpi_create_dmar_ds_pci_br_for_port( current, dev, pcie_seg, false, NULL); @@ -363,7 +362,7 @@ static unsigned long acpi_create_drhd(unsigned long current, struct device *iomm //BIT 15 if (num_hpets && (num_hpets != 0x1f) && (read32p(HPET_BASE_ADDRESS + 0x100) & (0x00008000))) { - union p2sb_bdf hpet_bdf = p2sb_get_hpet_bdf(); + union p2sb_bdf hpet_bdf = soc_get_hpet_bdf(); printk(BIOS_DEBUG, " [Message-capable HPET Device] Enumeration ID: 0x%x, " "PCI Bus Number: 0x%x, PCI Path: 0x%x, 0x%x\n", 0, hpet_bdf.bus, hpet_bdf.dev, hpet_bdf.fn); @@ -422,7 +421,7 @@ static unsigned long acpi_create_atsr(unsigned long current) continue; for (child = dev->upstream->children; child; child = child->sibling) { - if ((child->hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) + if (!is_pci_bridge(child)) continue; current += acpi_create_dmar_ds_pci_br_for_port( @@ -445,7 +444,6 @@ static unsigned long acpi_create_rhsa(unsigned long current) { struct device *dev = NULL; struct resource *resource; - int socket; while ((dev = dev_find_device(PCI_VID_INTEL, MMAP_VTD_CFG_REG_DEVID, dev))) { /* See if there is a resource with the appropriate index. */ @@ -453,11 +451,9 @@ static unsigned long acpi_create_rhsa(unsigned long current) if (!resource) continue; - socket = iio_pci_domain_socket_from_dev(dev); - printk(BIOS_DEBUG, "[Remapping Hardware Static Affinity] Base Address: %p, " - "Proximity Domain: 0x%x\n", res2mmio(resource, 0, 0), socket); - current += acpi_create_dmar_rhsa(current, (uintptr_t)res2mmio(resource, 0, 0), socket); + "Proximity Domain: 0x%x\n", res2mmio(resource, 0, 0), device_to_pd(dev)); + current += acpi_create_dmar_rhsa(current, (uintptr_t)res2mmio(resource, 0, 0), device_to_pd(dev)); } return current; diff --git a/src/soc/intel/xeon_sp/uncore_acpi_cxl.c b/src/soc/intel/xeon_sp/uncore_acpi_cxl.c index 40a5f1249672..6e1fa71f93de 100644 --- a/src/soc/intel/xeon_sp/uncore_acpi_cxl.c +++ b/src/soc/intel/xeon_sp/uncore_acpi_cxl.c @@ -13,7 +13,9 @@ unsigned long cxl_fill_srat(unsigned long current) * are after processor domains. */ uint32_t base, size; - for (uint8_t i = soc_get_num_cpus(); i < pds.num_pds; i++) { + for (uint8_t i = 0; i < pds.num_pds; i++) { + if (pds.pds[i].pd_type != PD_TYPE_GENERIC_INITIATOR) + continue; if (!pds.pds[i].dev) continue; diff --git a/src/soc/intel/xeon_sp/util.c b/src/soc/intel/xeon_sp/util.c index 81dc77db8008..4dbe7a4cd7fc 100644 --- a/src/soc/intel/xeon_sp/util.c +++ b/src/soc/intel/xeon_sp/util.c @@ -9,8 +9,10 @@ #include <device/pci_ids.h> #include <intelblocks/cfg.h> #include <intelblocks/cpulib.h> +#include <intelblocks/p2sb.h> #include <intelpch/lockdown.h> #include <soc/chip_common.h> +#include <soc/pch_pci_devs.h> #include <soc/pci_devs.h> #include <soc/msr.h> #include <soc/soc_util.h> @@ -88,6 +90,32 @@ unsigned int soc_get_num_cpus(void) return get_iio_uds()->SystemStatus.numCpus; } +union p2sb_bdf soc_get_hpet_bdf(void) +{ + if (CONFIG(SOC_INTEL_COMMON_IBL_BASE)) { + union p2sb_bdf bdf = { + .bus = HPET_BUS_NUM, + .dev = HPET_DEV_NUM, + .fn = HPET0_FUNC_NUM + }; + return bdf; + } + return p2sb_get_hpet_bdf(); +} + +union p2sb_bdf soc_get_ioapic_bdf(void) +{ + if (CONFIG(SOC_INTEL_COMMON_IBL_BASE)) { + union p2sb_bdf bdf = { + .bus = PCH_IOAPIC_BUS_NUMBER, + .dev = PCH_IOAPIC_DEV_NUM, + .fn = PCH_IOAPIC_FUNC_NUM + }; + return bdf; + } + return p2sb_get_ioapic_bdf(); +} + #if ENV_RAMSTAGE /* Setting devtree variables is only allowed in ramstage. */ void lock_pam0123(void) |