From a974b7668e21d138a3103f903a59e4504d98dd3b Mon Sep 17 00:00:00 2001 From: Ulysse Ballesteros Date: Thu, 30 Oct 2025 11:14:04 +0100 Subject: [PATCH] soc/intel/*: Disable InternalGfx w/o iGPU to prevent FSP-M/S crash Add verification to ensure that the integrated GPU is available, avoiding crashes in FSP-M and FSP-S. The problem was first identified on Skylake systems where the iGPU is missing or disabled, particularly when VT-D is enabled, which can cause FSP-S to hang during boot. Enabling SGX hides the issue, but it also leads to unstable virtualization. Apply the fix to Alderlake, Cannonlake, and Tigerlake SoCs in addition to Skylake. TEST=Build and boot to OS (Windows, Proxmox). Check to verify functions work. (Skylake H110 + Xeon E3-1245 V5, E3-1260L V5, i7-6700K, i3-7100) Change-Id: I394f46ed5a277218a8dd587705eaecabe59fd110 Signed-off-by: Ulysse Ballesteros Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/89821 Reviewed-by: Walter Sonius Tested-by: build bot (Jenkins) Reviewed-by: Alicja Michalska --- src/soc/intel/alderlake/romstage/fsp_params.c | 16 ++++++++++++++-- src/soc/intel/cannonlake/romstage/fsp_params.c | 16 ++++++++++------ src/soc/intel/skylake/chip.c | 14 +++++++++++++- src/soc/intel/skylake/romstage/fsp_params.c | 17 +++++++++++++---- src/soc/intel/tigerlake/romstage/fsp_params.c | 14 ++++++++++++-- 5 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/soc/intel/alderlake/romstage/fsp_params.c b/src/soc/intel/alderlake/romstage/fsp_params.c index 730b1f82b2..4bb2980b2b 100644 --- a/src/soc/intel/alderlake/romstage/fsp_params.c +++ b/src/soc/intel/alderlake/romstage/fsp_params.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -152,9 +153,19 @@ static void fill_fspm_igd_params(FSP_M_CONFIG *m_cfg, [DDI_PORT_3] = {&m_cfg->DdiPort3Ddc, &m_cfg->DdiPort3Hpd}, [DDI_PORT_4] = {&m_cfg->DdiPort4Ddc, &m_cfg->DdiPort4Hpd}, }; - m_cfg->InternalGfx = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) && is_devfn_enabled(SA_DEVFN_IGD); - if (m_cfg->InternalGfx) { + + bool igd_enabled = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) + && is_devfn_enabled(SA_DEVFN_IGD); + + /* Probe for no IGD and disable InternalGfx to prevent a crash in FSP-M. */ + if (igd_enabled && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) == 0xffff) { + printk(BIOS_ERR, "igd_enabled is set, but IGD is not present. Disabling IGD.\n"); + igd_enabled = false; + } + + if (igd_enabled) { /* IGD is enabled, set IGD stolen size to 60MB. */ + m_cfg->InternalGfx = 1; m_cfg->IgdDvmt50PreAlloc = get_uint_option("igd_dvmt_prealloc", IGD_SM_60MB); m_cfg->ApertureSize = get_uint_option("igd_aperture_size", IGD_AP_SZ_256MB); /* DP port config */ @@ -168,6 +179,7 @@ static void fill_fspm_igd_params(FSP_M_CONFIG *m_cfg, } } else { /* IGD is disabled, skip IGD init in FSP. */ + m_cfg->InternalGfx = 0; m_cfg->IgdDvmt50PreAlloc = 0; /* DP port config */ m_cfg->DdiPortAConfig = 0; diff --git a/src/soc/intel/cannonlake/romstage/fsp_params.c b/src/soc/intel/cannonlake/romstage/fsp_params.c index 38dfdd8922..c86da261d2 100644 --- a/src/soc/intel/cannonlake/romstage/fsp_params.c +++ b/src/soc/intel/cannonlake/romstage/fsp_params.c @@ -30,12 +30,16 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) m_cfg->HyperThreading = get_uint_option("hyper_threading", CONFIG(FSP_HYPERTHREADING)); - /* - * Probe for no IGD and disable InternalGfx and panel power to prevent a - * crash in FSP-M. - */ - const bool igd_on = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) && is_devfn_enabled(SA_DEVFN_IGD); - if (igd_on && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) != 0xffff) { + bool igd_enabled = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) + && is_devfn_enabled(SA_DEVFN_IGD); + + /* Probe for no IGD and disable InternalGfx and panel power to prevent a crash in FSP-M. */ + if (igd_enabled && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) == 0xffff) { + printk(BIOS_ERR, "igd_enabled is set, but IGD is not present. Disabling IGD.\n"); + igd_enabled = false; + } + + if (igd_enabled) { /* Set IGD stolen size to 64MB. */ m_cfg->InternalGfx = 1; m_cfg->IgdDvmt50PreAlloc = get_uint_option("igd_dvmt_prealloc", IGD_SM_64MB); diff --git a/src/soc/intel/skylake/chip.c b/src/soc/intel/skylake/chip.c index 0061c10ae8..a884035f59 100644 --- a/src/soc/intel/skylake/chip.c +++ b/src/soc/intel/skylake/chip.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -491,7 +492,18 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) /* Enable VT-d and X2APIC */ if (soc_vtd_enabled()) { - params->VtdBaseAddress[0] = GFXVT_BASE_ADDRESS; + /* + * Probe for no IGD and set VtdBaseAddress accordingly to prevent a + * crash in FSP-S. + */ + const struct device *igd_dev = pcidev_path_on_root(SA_DEVFN_IGD); + if (igd_dev && pci_read_config16(igd_dev, PCI_VENDOR_ID) != 0xffff) { + printk(BIOS_DEBUG, "iGPU present - GFXVT_BASE_ADDRESS set\n"); + params->VtdBaseAddress[0] = GFXVT_BASE_ADDRESS; + } else { + printk(BIOS_DEBUG, "No iGPU - GFXVT_BASE_ADDRESS disabled\n"); + params->VtdBaseAddress[0] = 0; + } params->VtdBaseAddress[1] = VTVC0_BASE_ADDRESS; params->X2ApicOptOut = 0; tconfig->VtdDisable = 0; diff --git a/src/soc/intel/skylake/romstage/fsp_params.c b/src/soc/intel/skylake/romstage/fsp_params.c index 3ca8a48472..5d59ff18c3 100644 --- a/src/soc/intel/skylake/romstage/fsp_params.c +++ b/src/soc/intel/skylake/romstage/fsp_params.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include #include @@ -104,7 +105,14 @@ static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, static void soc_primary_gfx_config_params(FSP_M_CONFIG *m_cfg, const struct soc_intel_skylake_config *config) { - m_cfg->InternalGfx = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) && is_devfn_enabled(SA_DEVFN_IGD); + bool igd_enabled = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) + && is_devfn_enabled(SA_DEVFN_IGD); + + /* Probe for no IGD and disable InternalGfx to prevent a crash in FSP-M. */ + if (igd_enabled && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) == 0xffff) { + printk(BIOS_ERR, "igd_enabled is set, but IGD is not present. Disabling IGD.\n"); + igd_enabled = false; + } /* * If iGPU is enabled, set IGD stolen size to 64MB. The FBC @@ -116,12 +124,13 @@ static void soc_primary_gfx_config_params(FSP_M_CONFIG *m_cfg, * * If disabled, don't reserve memory for it. */ - if (m_cfg->InternalGfx) { - /* IGD is enabled, set IGD stolen size to 64MB. */ + if (igd_enabled) { + /* Set IGD stolen size to 64MB. */ + m_cfg->InternalGfx = 1; m_cfg->IgdDvmt50PreAlloc = get_uint_option("igd_dvmt_prealloc", IGD_SM_64MB); m_cfg->ApertureSize = get_uint_option("igd_aperture_size", IGD_AP_SZ_256MB); } else { - /* IGD is disabled, skip IGD init in FSP. */ + m_cfg->InternalGfx = 0; m_cfg->IgdDvmt50PreAlloc = 0; } diff --git a/src/soc/intel/tigerlake/romstage/fsp_params.c b/src/soc/intel/tigerlake/romstage/fsp_params.c index 3e171b198a..0f6c80cfec 100644 --- a/src/soc/intel/tigerlake/romstage/fsp_params.c +++ b/src/soc/intel/tigerlake/romstage/fsp_params.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -27,14 +28,23 @@ static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, m_cfg->HyperThreading = get_uint_option("hyper_threading", CONFIG(FSP_HYPERTHREADING)); - m_cfg->InternalGfx = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) && is_devfn_enabled(SA_DEVFN_IGD); + bool igd_enabled = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) + && is_devfn_enabled(SA_DEVFN_IGD); - if (m_cfg->InternalGfx) { + /* Probe for no IGD and disable InternalGfx to prevent a crash in FSP-M. */ + if (igd_enabled && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) == 0xffff) { + printk(BIOS_ERR, "igd_enabled is set, but IGD is not present. Disabling IGD.\n"); + igd_enabled = false; + } + + if (igd_enabled) { /* IGD is enabled, set IGD stolen size to 60MB. */ + m_cfg->InternalGfx = 1; m_cfg->IgdDvmt50PreAlloc = get_uint_option("igd_dvmt_prealloc", IGD_SM_60MB); m_cfg->ApertureSize = get_uint_option("igd_aperture_size", IGD_AP_SZ_256MB); } else { /* IGD is disabled, skip IGD init in FSP. */ + m_cfg->InternalGfx = 0; m_cfg->IgdDvmt50PreAlloc = 0; }