/** @file
This file provide services for DXE phase policy default initialization
Copyright (c) 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "DxeSaPolicyLibrary.h"
#include
#include
#include
extern EFI_GUID gMemoryDxeConfigGuid;
extern EFI_GUID gPcieDxeConfigGuid;
/**
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;
PCIE_DXE_CONFIG *PcieDxeConfig;
MEMORY_DXE_CONFIG *MemoryDxeConfig;
//
// Get requisite IP Config Blocks which needs to be used here
//
Status = GetConfigBlock ((VOID *) SaPolicy, &gPcieDxeConfigGuid, (VOID *)&PcieDxeConfig);
ASSERT_EFI_ERROR (Status);
Status = GetConfigBlock ((VOID *) SaPolicy, &gMemoryDxeConfigGuid, (VOID *)&MemoryDxeConfig);
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] :", 4));
for (i = 0; i < 4; 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, "------------------------ CPU_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, " 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"));
DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (DXE) print END -----------------\n"));
DEBUG_CODE_END ();
return;
}
/**
Load DXE Config block default for PCIe
@param[in] ConfigBlockPointer Pointer to config block
**/
VOID
LoadPcieDxeDefault (
IN VOID *ConfigBlockPointer
)
{
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 (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
PcieDxeConfig->PegAspm[Index] = CpuPcieAspmAutoConfig;
}
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;
}
}
/**
Load DXE Config block default
@param[in] ConfigBlockPointer Pointer to config block
**/
VOID
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;
}
GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY mSaDxeIpBlocks [] = {
{&gPcieDxeConfigGuid, sizeof (PCIE_DXE_CONFIG), PCIE_DXE_CONFIG_REVISION, LoadPcieDxeDefault},
{&gMemoryDxeConfigGuid, sizeof (MEMORY_DXE_CONFIG), MEMORY_DXE_CONFIG_REVISION, LoadMemoryDxeDefault}
};
/**
CreateSaDxeConfigBlocks generates the config blocks 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;
EFI_STATUS Status;
SA_POLICY_PROTOCOL *SaInitPolicy;
UINT16 RequiredSize;
DEBUG ((DEBUG_INFO, "SA Create Dxe Config Blocks\n"));
SaInitPolicy = NULL;
TotalBlockSize = GetComponentConfigBlockTotalSize (&mSaDxeIpBlocks[0], sizeof (mSaDxeIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
TotalBlockSize += VtdGetConfigBlockTotalSizeDxe ();
TotalBlockSize += GraphicsGetConfigBlockTotalSizeDxe ();
DEBUG ((DEBUG_INFO, "TotalBlockSize = 0x%x\n", TotalBlockSize));
RequiredSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockSize;
Status = CreateConfigBlockTable (RequiredSize, (VOID *) &SaInitPolicy);
ASSERT_EFI_ERROR (Status);
//
// Initialize Policy Revision
//
SaInitPolicy->TableHeader.Header.Revision = SA_POLICY_PROTOCOL_REVISION;
//
// Add config blocks.
//
Status = AddComponentConfigBlocks ((VOID *) SaInitPolicy, &mSaDxeIpBlocks[0], sizeof (mSaDxeIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
ASSERT_EFI_ERROR (Status);
// Vtd
Status = VtdAddConfigBlocksDxe((VOID *) SaInitPolicy);
ASSERT_EFI_ERROR (Status);
// Gfx
Status = GraphicsAddConfigBlocksDxe ((VOID *) SaInitPolicy);
ASSERT_EFI_ERROR (Status);
//
// Assignment for returning SaInitPolicy config block base address
//
*SaPolicy = SaInitPolicy;
return Status;
}
/**
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);
GraphicsDxePolicyPrint (SaPolicy);
VtdPrintPolicyDxe (SaPolicy);
///
/// Install protocol to to allow access to this Policy.
///
Status = gBS->InstallMultipleProtocolInterfaces (
&ImageHandle,
&gSaPolicyProtocolGuid,
SaPolicy,
NULL
);
ASSERT_EFI_ERROR (Status);
return Status;
}