/** @file This file provide services for DXE phase policy default initialization Copyright (c) 2019 - 2020 Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "DxeSaPolicyLibrary.h" #include GLOBAL_REMOVE_IF_UNREFERENCED PCIE_ASPM_OVERRIDE_LIST mPcieAspmDevsOverride[] = { {0x8086, 0x108b, 0xff, 2, 2}, ///< Tekoa w/o iAMT {0x8086, 0x108c, 0x00, 0, 0}, ///< Tekoa A2 {0x8086, 0x108c, 0xff, 2, 2}, ///< Tekoa others {0x8086, 0x109a, 0xff, 2, 2}, ///< Vidalia {0x8086, 0x4222, 0xff, 2, 3}, ///< 3945ABG {0x8086, 0x4227, 0xff, 2, 3}, ///< 3945ABG {0x8086, 0x4228, 0xff, 2, 3}, ///< 3945ABG /// /// Place structures for known bad OEM/IHV devices here /// {SA_PCIE_DEV_END_OF_TABLE, 0, 0, 0, 0} ///< End of table }; GLOBAL_REMOVE_IF_UNREFERENCED PCIE_LTR_DEV_INFO mPcieLtrDevsOverride[] = { /// /// Place holder for PCIe devices with correct LTR requirements /// {SA_PCIE_DEV_END_OF_TABLE, 0, 0, 0, 0} ///< End of table }; extern EFI_GUID gGraphicsDxeConfigGuid; extern EFI_GUID gMemoryDxeConfigGuid; extern EFI_GUID gMiscDxeConfigGuid; extern EFI_GUID gPcieDxeConfigGuid; extern EFI_GUID gVbiosDxeConfigGuid; /** This function prints the SA DXE phase policy. @param[in] SaPolicy - SA DXE Policy protocol **/ VOID SaPrintPolicyProtocol ( IN SA_POLICY_PROTOCOL *SaPolicy ) { EFI_STATUS Status; GRAPHICS_DXE_CONFIG *GraphicsDxeConfig; PCIE_DXE_CONFIG *PcieDxeConfig; MISC_DXE_CONFIG *MiscDxeConfig; MEMORY_DXE_CONFIG *MemoryDxeConfig; VBIOS_DXE_CONFIG *VbiosDxeConfig; // // Get requisite IP Config Blocks which needs to be used here // Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig); ASSERT_EFI_ERROR (Status); Status = GetConfigBlock ((VOID *) SaPolicy, &gMiscDxeConfigGuid, (VOID *)&MiscDxeConfig); ASSERT_EFI_ERROR (Status); Status = GetConfigBlock ((VOID *) SaPolicy, &gPcieDxeConfigGuid, (VOID *)&PcieDxeConfig); ASSERT_EFI_ERROR (Status); Status = GetConfigBlock ((VOID *) SaPolicy, &gMemoryDxeConfigGuid, (VOID *)&MemoryDxeConfig); ASSERT_EFI_ERROR (Status); Status = GetConfigBlock ((VOID *) SaPolicy, &gVbiosDxeConfigGuid, (VOID *)&VbiosDxeConfig); ASSERT_EFI_ERROR (Status); DEBUG_CODE_BEGIN (); INTN i; DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (DXE) print BEGIN -----------------\n")); DEBUG ((DEBUG_INFO, "Revision : %x\n", SaPolicy->TableHeader.Header.Revision)); ASSERT (SaPolicy->TableHeader.Header.Revision == SA_POLICY_PROTOCOL_REVISION); DEBUG ((DEBUG_INFO, "------------------------ SA_MEMORY_CONFIGURATION -----------------\n")); DEBUG ((DEBUG_INFO, " SpdAddressTable[%d] :", SA_MC_MAX_SOCKETS)); for (i = 0; i < SA_MC_MAX_SOCKETS; i++) { DEBUG ((DEBUG_INFO, " %x", MemoryDxeConfig->SpdAddressTable[i])); } DEBUG ((DEBUG_INFO, "\n")); DEBUG ((DEBUG_INFO, " ChannelASlotMap : %x\n", MemoryDxeConfig->ChannelASlotMap)); DEBUG ((DEBUG_INFO, " ChannelBSlotMap : %x\n", MemoryDxeConfig->ChannelBSlotMap)); DEBUG ((DEBUG_INFO, " MrcTimeMeasure : %x\n", MemoryDxeConfig->MrcTimeMeasure)); DEBUG ((DEBUG_INFO, " MrcFastBoot : %x\n", MemoryDxeConfig->MrcFastBoot)); DEBUG ((DEBUG_INFO, "------------------------ SA_PCIE_CONFIGURATION -----------------\n")); DEBUG ((DEBUG_INFO, " PegAspm[%d] :", SA_PEG_MAX_FUN)); for (i = 0; i < SA_PEG_MAX_FUN; i++) { DEBUG ((DEBUG_INFO, " %x", PcieDxeConfig->PegAspm[i])); } DEBUG ((DEBUG_INFO, "\n")); DEBUG ((DEBUG_INFO, " PegAspmL0s[%d] :", SA_PEG_MAX_FUN)); for (i = 0; i < SA_PEG_MAX_FUN; i++) { DEBUG ((DEBUG_INFO, " %x", PcieDxeConfig->PegAspmL0s[i])); } DEBUG ((DEBUG_INFO, "\n")); DEBUG ((DEBUG_INFO, " PegRootPortHPE[%d] :", SA_PEG_MAX_FUN)); for (i = 0; i < SA_PEG_MAX_FUN; i++) { DEBUG ((DEBUG_INFO, " %x", PcieDxeConfig->PegRootPortHPE[i])); } DEBUG ((DEBUG_INFO, "\n")); if (PcieDxeConfig->PcieAspmDevsOverride != NULL) { DEBUG ((DEBUG_INFO, "------------------------ PCIE_ASPM_OVERRIDE_LIST -----------------\n")); DEBUG ((DEBUG_INFO, " VendorId DeviceId RevId RootApmcMask EndpointApmcMask\n")); i = 0; while ((PcieDxeConfig->PcieAspmDevsOverride[i].VendorId != SA_PCIE_DEV_END_OF_TABLE) && (i < MAX_PCIE_ASPM_OVERRIDE)) { DEBUG ((DEBUG_INFO, " %04x %04x %02x %01x %01x\n", PcieDxeConfig->PcieAspmDevsOverride[i].VendorId, PcieDxeConfig->PcieAspmDevsOverride[i].DeviceId, PcieDxeConfig->PcieAspmDevsOverride[i].RevId, PcieDxeConfig->PcieAspmDevsOverride[i].RootApmcMask, PcieDxeConfig->PcieAspmDevsOverride[i].EndpointApmcMask)); i++; } DEBUG ((DEBUG_INFO, "------------------------ END_OF_TABLE -----------------------\n")); } if (PcieDxeConfig->PcieLtrDevsOverride != NULL) { DEBUG ((DEBUG_INFO, "------------------------ PCIE_LTR_DEV_INFO -----------------\n")); DEBUG ((DEBUG_INFO, " VendorId DeviceId RevId SnoopLatency NonSnoopLatency\n")); i = 0; while ((PcieDxeConfig->PcieLtrDevsOverride[i].VendorId != SA_PCIE_DEV_END_OF_TABLE) && (i < MAX_PCIE_LTR_OVERRIDE)) { DEBUG ((DEBUG_INFO, " %04x %04x %02x %01x %01x\n", PcieDxeConfig->PcieLtrDevsOverride[i].VendorId, PcieDxeConfig->PcieLtrDevsOverride[i].DeviceId, PcieDxeConfig->PcieLtrDevsOverride[i].RevId, PcieDxeConfig->PcieLtrDevsOverride[i].SnoopLatency, PcieDxeConfig->PcieLtrDevsOverride[i].NonSnoopLatency)); i++; } DEBUG ((DEBUG_INFO, "------------------------ END_OF_TABLE ----------------------\n")); } for (i = 0; i < SA_PEG_MAX_FUN; i++) { DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].LtrEnable : %x\n", i, PcieDxeConfig->PegPwrOpt[i].LtrEnable)); DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].LtrMaxSnoopLatency : %x\n", i, PcieDxeConfig->PegPwrOpt[i].LtrMaxSnoopLatency)); DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].ObffEnable : %x\n", i, PcieDxeConfig->PegPwrOpt[i].ObffEnable)); DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].LtrMaxNoSnoopLatency : %x\n", i, PcieDxeConfig->PegPwrOpt[i].LtrMaxNoSnoopLatency)); } if (VbiosDxeConfig != NULL) { DEBUG ((DEBUG_INFO, "------------------------ SA_SG_VBIOS_CONFIGURATION -----------------\n")); DEBUG ((DEBUG_INFO, " LoadVbios : %x\n", VbiosDxeConfig->LoadVbios)); DEBUG ((DEBUG_INFO, " ExecuteVbios : %x\n", VbiosDxeConfig->ExecuteVbios)); DEBUG ((DEBUG_INFO, " VbiosSource : %x\n", VbiosDxeConfig->VbiosSource)); } DEBUG ((DEBUG_INFO, "------------------------ SA_MISC_CONFIGURATION -----------------\n")); DEBUG ((DEBUG_INFO, " EnableAbove4GBMmio : %x\n", MiscDxeConfig->EnableAbove4GBMmio)); DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (DXE) print END -----------------\n")); DEBUG_CODE_END (); return; } EFI_STATUS EFIAPI LoadIgdDxeDefault ( IN VOID *ConfigBlockPointer ) { GRAPHICS_DXE_CONFIG *GraphicsDxeConfig; GraphicsDxeConfig = ConfigBlockPointer; DEBUG ((DEBUG_INFO, "GraphicsDxeConfig->Header.GuidHob.Name = %g\n", &GraphicsDxeConfig->Header.GuidHob.Name)); DEBUG ((DEBUG_INFO, "GraphicsDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", GraphicsDxeConfig->Header.GuidHob.Header.HobLength)); /// /// Initialize the Graphics configuration /// GraphicsDxeConfig->PlatformConfig = 1; GraphicsDxeConfig->AlsEnable = 2; GraphicsDxeConfig->BacklightControlSupport = 2; GraphicsDxeConfig->IgdBlcConfig = 2; GraphicsDxeConfig->IgdDvmtMemSize = 1; GraphicsDxeConfig->GfxTurboIMON = 31; /// /// Create a static Backlight Brightness Level Duty cycle Mapping Table /// Possible 20 entries (example used 11), each 16 bits as follows: /// [15] = Field Valid bit, [14:08] = Level in Percentage (0-64h), [07:00] = Desired duty cycle (0 - FFh). /// GraphicsDxeConfig->BCLM[0] = (0x0000 + WORD_FIELD_VALID_BIT); ///< 0% GraphicsDxeConfig->BCLM[1] = (0x0A19 + WORD_FIELD_VALID_BIT); ///< 10% GraphicsDxeConfig->BCLM[2] = (0x1433 + WORD_FIELD_VALID_BIT); ///< 20% GraphicsDxeConfig->BCLM[3] = (0x1E4C + WORD_FIELD_VALID_BIT); ///< 30% GraphicsDxeConfig->BCLM[4] = (0x2866 + WORD_FIELD_VALID_BIT); ///< 40% GraphicsDxeConfig->BCLM[5] = (0x327F + WORD_FIELD_VALID_BIT); ///< 50% GraphicsDxeConfig->BCLM[6] = (0x3C99 + WORD_FIELD_VALID_BIT); ///< 60% GraphicsDxeConfig->BCLM[7] = (0x46B2 + WORD_FIELD_VALID_BIT); ///< 70% GraphicsDxeConfig->BCLM[8] = (0x50CC + WORD_FIELD_VALID_BIT); ///< 80% GraphicsDxeConfig->BCLM[9] = (0x5AE5 + WORD_FIELD_VALID_BIT); ///< 90% GraphicsDxeConfig->BCLM[10] = (0x64FF + WORD_FIELD_VALID_BIT); ///< 100% return EFI_SUCCESS; } EFI_STATUS EFIAPI LoadPcieDxeDefault ( IN VOID *ConfigBlockPointer ) { UINT8 pegFn; UINT8 Index; PCIE_DXE_CONFIG *PcieDxeConfig; PcieDxeConfig = ConfigBlockPointer; DEBUG ((DEBUG_INFO, "PcieDxeConfig->Header.GuidHob.Name = %g\n", &PcieDxeConfig->Header.GuidHob.Name)); DEBUG ((DEBUG_INFO, "PcieDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PcieDxeConfig->Header.GuidHob.Header.HobLength)); /// /// Initialize the PCIE Configuration /// PEG ASPM per port configuration. 4 PEG controllers i.e. 0,1,2,3 /// for (pegFn = 0; pegFn < SA_PEG_MAX_FUN; pegFn++) { PcieDxeConfig->PegAspm[pegFn] = PcieAspmAutoConfig; PcieDxeConfig->PegAspmL0s[pegFn] = 0; } for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) { PcieDxeConfig->PegPwrOpt[Index].LtrEnable = 1; PcieDxeConfig->PegPwrOpt[Index].LtrMaxSnoopLatency = V_SA_LTR_MAX_SNOOP_LATENCY_VALUE; PcieDxeConfig->PegPwrOpt[Index].LtrMaxNoSnoopLatency = V_SA_LTR_MAX_NON_SNOOP_LATENCY_VALUE; PcieDxeConfig->PegPwrOpt[Index].ObffEnable = 1; } PcieDxeConfig->PcieAspmDevsOverride = mPcieAspmDevsOverride; PcieDxeConfig->PcieLtrDevsOverride = mPcieLtrDevsOverride; return EFI_SUCCESS; } EFI_STATUS EFIAPI LoadMiscDxeDefault ( IN VOID *ConfigBlockPointer ) { MISC_DXE_CONFIG *MiscDxeConfig; MiscDxeConfig = ConfigBlockPointer; DEBUG ((DEBUG_INFO, "MiscDxeConfig->Header.GuidHob.Name = %g\n", &MiscDxeConfig->Header.GuidHob.Name)); DEBUG ((DEBUG_INFO, "MiscDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", MiscDxeConfig->Header.GuidHob.Header.HobLength)); /// /// RMRR Base and Limit Address for USB /// MiscDxeConfig->RmrrUsbBaseAddress = AllocateZeroPool (sizeof (EFI_PHYSICAL_ADDRESS) * 2); ASSERT (MiscDxeConfig->RmrrUsbBaseAddress != NULL); if (MiscDxeConfig->RmrrUsbBaseAddress != NULL) { /// /// BIOS must update USB RMRR base address /// MiscDxeConfig->RmrrUsbBaseAddress[0] = 0; MiscDxeConfig->RmrrUsbBaseAddress[1] = 0; } return EFI_SUCCESS; } EFI_STATUS EFIAPI LoadMemoryDxeDefault ( IN VOID *ConfigBlockPointer ) { MEMORY_DXE_CONFIG *MemoryDxeConfig; MemoryDxeConfig = ConfigBlockPointer; DEBUG ((DEBUG_INFO, "MemoryDxeConfig->Header.GuidHob.Name = %g\n", &MemoryDxeConfig->Header.GuidHob.Name)); DEBUG ((DEBUG_INFO, "MemoryDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", MemoryDxeConfig->Header.GuidHob.Header.HobLength)); /// /// Initialize the Memory Configuration /// /// /// DIMM SMBus addresses info /// Refer to the SpdAddressTable[] mapping rule in DxeSaPolicyLibrary.h /// MemoryDxeConfig->SpdAddressTable = AllocateZeroPool (sizeof (UINT8) * 4); ASSERT (MemoryDxeConfig->SpdAddressTable != NULL); if (MemoryDxeConfig->SpdAddressTable != NULL) { MemoryDxeConfig->SpdAddressTable[0] = DIMM_SMB_SPD_P0C0D0; MemoryDxeConfig->SpdAddressTable[1] = DIMM_SMB_SPD_P0C0D1; MemoryDxeConfig->SpdAddressTable[2] = DIMM_SMB_SPD_P0C1D0; MemoryDxeConfig->SpdAddressTable[3] = DIMM_SMB_SPD_P0C1D1; } MemoryDxeConfig->ChannelASlotMap = 0x01; MemoryDxeConfig->ChannelBSlotMap = 0x01; return EFI_SUCCESS; } EFI_STATUS EFIAPI LoadVbiosDxeDefault ( IN VOID *ConfigBlockPointer ) { VBIOS_DXE_CONFIG *VbiosDxeConfig; VbiosDxeConfig = ConfigBlockPointer; DEBUG ((DEBUG_INFO, "VbiosDxeConfig->Header.GuidHob.Name = %g\n", &VbiosDxeConfig->Header.GuidHob.Name)); DEBUG ((DEBUG_INFO, "VbiosDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", VbiosDxeConfig->Header.GuidHob.Header.HobLength)); /// /// Initialize the SG VBIOS DXE Policies /// /// /// 1 = secondary display device VBIOS Source is PCI Card /// 0 = secondary display device VBIOS Source is FW Volume /// VbiosDxeConfig->VbiosSource = 1; return EFI_SUCCESS; } /** LoadSaDxeConfigBlockDefault - Initialize default settings for each SA Config block @param[in] ConfigBlockPointer The buffer pointer that will be initialized as specific config block @param[in] BlockId Request to initialize defaults of specified config block by given Block ID @retval EFI_SUCCESS The given buffer has contained the defaults of requested config block @retval EFI_NOT_FOUND Block ID is not defined so no default Config block will be initialized **/ EFI_STATUS EFIAPI LoadSaDxeConfigBlockDefault ( IN VOID *ConfigBlockPointer, IN EFI_GUID BlockGuid ) { if (CompareGuid (&BlockGuid, &gGraphicsDxeConfigGuid)) { LoadIgdDxeDefault (ConfigBlockPointer); } else if (CompareGuid (&BlockGuid, &gMiscDxeConfigGuid)) { LoadMiscDxeDefault (ConfigBlockPointer); } else if (CompareGuid (&BlockGuid, &gPcieDxeConfigGuid)) { LoadPcieDxeDefault (ConfigBlockPointer); } else if (CompareGuid (&BlockGuid, &gMemoryDxeConfigGuid)) { LoadMemoryDxeDefault (ConfigBlockPointer); } else if (CompareGuid (&BlockGuid, &gVbiosDxeConfigGuid)) { LoadVbiosDxeDefault (ConfigBlockPointer); } else { return EFI_NOT_FOUND; } return EFI_SUCCESS; } /** CreateSaDxeConfigBlocks generates the config blocksg of SA DXE Policy. It allocates and zero out buffer, and fills in the Intel default settings. @param[out] SaPolicy The pointer to get SA DXE Protocol instance @retval EFI_SUCCESS The policy default is initialized. @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer **/ EFI_STATUS EFIAPI CreateSaDxeConfigBlocks ( IN OUT SA_POLICY_PROTOCOL **SaPolicy ) { UINT16 TotalBlockSize; UINT16 TotalBlockCount; UINT16 BlockCount; VOID *ConfigBlockPointer; EFI_STATUS Status; SA_POLICY_PROTOCOL *SaInitPolicy; UINT16 RequiredSize; STATIC CONFIG_BLOCK_HEADER SaDxeIpBlocks [] = { {{{0, sizeof (GRAPHICS_DXE_CONFIG), 0}, {0}}, GRAPHICS_DXE_CONFIG_REVISION, 0, {0, 0}}, {{{0, sizeof (MEMORY_DXE_CONFIG), 0}, {0}}, MEMORY_DXE_CONFIG_REVISION, 0, {0, 0}}, {{{0, sizeof (MISC_DXE_CONFIG), 0}, {0}}, MISC_DXE_CONFIG_REVISION, 0, {0, 0}}, {{{0, sizeof (PCIE_DXE_CONFIG), 0}, {0}}, PCIE_DXE_CONFIG_REVISION, 0, {0, 0}}, {{{0, sizeof (VBIOS_DXE_CONFIG), 0}, {0}}, VBIOS_DXE_CONFIG_REVISION, 0, {0, 0}} }; SaInitPolicy = NULL; TotalBlockCount = sizeof (SaDxeIpBlocks) / sizeof (CONFIG_BLOCK_HEADER); DEBUG ((DEBUG_INFO, "TotalBlockCount = 0x%x\n", TotalBlockCount)); TotalBlockSize = 0; for (BlockCount = 0 ; BlockCount < TotalBlockCount; BlockCount++) { TotalBlockSize += (UINT32) SaDxeIpBlocks[BlockCount].GuidHob.Header.HobLength; DEBUG ((DEBUG_INFO, "TotalBlockSize after adding Block[0x%x]= 0x%x\n", BlockCount, TotalBlockSize)); } RequiredSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockSize; Status = CreateConfigBlockTable (RequiredSize, (VOID *)&SaInitPolicy); ASSERT_EFI_ERROR (Status); // // Initalize SklSaIpBlocks table GUID // CopyMem (&SaDxeIpBlocks[0].GuidHob.Name, &gGraphicsDxeConfigGuid, sizeof (EFI_GUID)); CopyMem (&SaDxeIpBlocks[1].GuidHob.Name, &gMemoryDxeConfigGuid, sizeof (EFI_GUID)); CopyMem (&SaDxeIpBlocks[2].GuidHob.Name, &gMiscDxeConfigGuid, sizeof (EFI_GUID)); CopyMem (&SaDxeIpBlocks[3].GuidHob.Name, &gPcieDxeConfigGuid, sizeof (EFI_GUID)); CopyMem (&SaDxeIpBlocks[4].GuidHob.Name, &gVbiosDxeConfigGuid, sizeof (EFI_GUID)); // // Initialize Policy Revision // SaInitPolicy->TableHeader.Header.Revision = SA_POLICY_PROTOCOL_REVISION; // // Initialize ConfigBlockPointer to NULL // ConfigBlockPointer = NULL; // // Loop to identify each config block from SaDxeIpBlocks[] Table and add each of them // for (BlockCount = 0 ; BlockCount < TotalBlockCount; BlockCount++) { ConfigBlockPointer = (VOID *)&SaDxeIpBlocks[BlockCount]; Status = AddConfigBlock ((VOID *) SaInitPolicy, (VOID *)&ConfigBlockPointer); ASSERT_EFI_ERROR (Status); LoadSaDxeConfigBlockDefault ((VOID *) ConfigBlockPointer, SaDxeIpBlocks[BlockCount].GuidHob.Name); } // // Assignment for returning SaPolicy config block base address // *SaPolicy = SaInitPolicy; return EFI_SUCCESS; } /** SaInstallPolicyProtocol installs SA Policy. While installed, RC assumes the Policy is ready and finalized. So please update and override any setting before calling this function. @param[in] ImageHandle Image handle of this driver. @param[in] SaPolicy The pointer to SA Policy Protocol instance @retval EFI_SUCCESS The policy is installed. @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer **/ EFI_STATUS EFIAPI SaInstallPolicyProtocol ( IN EFI_HANDLE ImageHandle, IN SA_POLICY_PROTOCOL *SaPolicy ) { EFI_STATUS Status; /// /// Print SA DXE Policy /// SaPrintPolicyProtocol (SaPolicy); /// /// Install protocol to to allow access to this Policy. /// Status = gBS->InstallMultipleProtocolInterfaces ( &ImageHandle, &gSaPolicyProtocolGuid, SaPolicy, NULL ); ASSERT_EFI_ERROR (Status); return Status; }