alder_lake_bios/Intel/AlderLake/ClientOneSiliconPkg/SystemAgent/LibraryPrivate/PeiSaInitLib/SaInit.c

267 lines
8.0 KiB
C

/** @file
The PEIM implements the SA PEI Initialization.
@copyright
INTEL CONFIDENTIAL
Copyright 1999 - 2021 Intel Corporation.
The source code contained or described herein and all documents related to the
source code ("Material") are owned by Intel Corporation or its suppliers or
licensors. Title to the Material remains with Intel Corporation or its suppliers
and licensors. The Material may contain trade secrets and proprietary and
confidential information of Intel Corporation and its suppliers and licensors,
and is protected by worldwide copyright and trade secret laws and treaty
provisions. No part of the Material may be used, copied, reproduced, modified,
published, uploaded, posted, transmitted, distributed, or disclosed in any way
without Intel's prior express written permission.
No license under any patent, copyright, trade secret or other intellectual
property right is granted to or conferred upon you by disclosure or delivery
of the Materials, either expressly, by implication, inducement, estoppel or
otherwise. Any license under such intellectual property rights must be
express and approved by Intel in writing.
Unless otherwise agreed by Intel in writing, you may not remove or alter
this notice or any other notice embedded in Materials by Intel or
Intel's suppliers or licensors in any way.
This file contains an 'Intel Peripheral Driver' and is uniquely identified as
"Intel Reference Module" and is licensed for Intel CPUs and chipsets under
the terms of your license agreement with Intel or your vendor. This file may
be modified by the user, subject to additional terms of the license agreement.
@par Specification
**/
#include <Library/PeiServicesLib.h>
#include <Library/IoLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Ppi/MemoryDiscovered.h>
#include <Ppi/EndOfPeiPhase.h>
#include <Library/PciSegmentLib.h>
#include <CpuRegs.h>
#include <Register/IgdRegs.h>
#include <Register/GnaRegs.h>
#include <PcieRegs.h>
#include <VtdDataHob.h>
#include <Ppi/SiPolicy.h>
#include <Library/CpuMailboxLib.h>
#include <Library/SaInitLib.h>
#include <Library/PeiOcLib.h>
#include <Library/GnaInitLib.h>
#include <Library/PeiGraphicsInitLib.h>
#include <Library/PeiCpuTraceHubLib.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Library/ConfigBlockLib.h>
#include <Library/PeiDisplayInitLib.h>
#include <Library/GpioPrivateLib.h>
#include <Library/GpioNativePads.h>
#include <Library/PostCodeLib.h>
#include <Library/CpuDmiInfoLib.h>
#include <Library/CpuPlatformLib.h>
#include <Library/PeiHostBridgeInitLib.h>
#include <SaConfigHob.h>
#include <Library/CpuPcieRpLib.h>
#include <Library/GraphicsInfoLib.h>
typedef struct {
UINT8 DeviceNumber;
UINT8 FunctionNumber;
UINT8 SvidRegOffset;
} SA_SVID_SID_INIT_ENTRY;
/**
Function to handle SA at end of PEI
@retval None
**/
EFI_STATUS
EFIAPI
SaOnEndOfPei (
VOID
)
{
UINTN McD2BaseAddress;
EFI_BOOT_MODE BootMode;
EFI_STATUS Status;
SaS3ResumeAtEndOfPei ();
Status = PeiServicesGetBootMode (&BootMode);
if ((Status == EFI_SUCCESS) && (BootMode != BOOT_ON_S3_RESUME)) {
///
/// Clear IGD GttMmAdr, Aperture BAR and disable Bus Initiator and Memory Access for 0/2/0
///
DEBUG ((DEBUG_INFO, "Clear Temp Gfx BARs at End Of PEI.\n"));
McD2BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IGD_BUS_NUM, IGD_DEV_NUM, IGD_FUN_NUM, 0);
PciSegmentWrite32 (McD2BaseAddress + PCI_COMMAND_OFFSET, 0x0);
PciSegmentWrite32 (McD2BaseAddress + R_SA_IGD_GTTMMADR, 0x0);
PciSegmentWrite32 (McD2BaseAddress + R_SA_IGD_GTTMMADR + 0x4, 0x0);
PciSegmentWrite32 (McD2BaseAddress + GetIgfxApertureOffset (), 0x0);
PciSegmentWrite32 (McD2BaseAddress + GetIgfxApertureOffset () + 4, 0x0);
}
return EFI_SUCCESS;
}
///
/// Functions
///
/**
This function handles SA S3 resume task
@retval EFI_STATUS - Always return EFI_SUCCESS
**/
EFI_STATUS
SaS3ResumeAtEndOfPei (
VOID
)
{
EFI_BOOT_MODE BootMode;
EFI_STATUS Status;
#if FixedPcdGetBool(PcdFspBinaryEnable) == 0
SI_POLICY_PPI *SiPolicyPpi;
HOST_BRIDGE_PEI_CONFIG *HostBridgePeiConfig;
BOOLEAN SkipPamLock;
#endif
Status = PeiServicesGetBootMode (&BootMode);
DEBUG ((DEBUG_INFO, "[SA] BootMode = %X\n", BootMode));
if ((Status != EFI_SUCCESS) || (BootMode != BOOT_ON_S3_RESUME)) {
return EFI_SUCCESS;
}
DEBUG ((DEBUG_INFO, "SaS3ResumeAtEndOfPei Callback Entry\n"));
PostCode (0xA70);
//
// SA S3 tasks that must be done after S3 Boot Script Restore finished.
//
#if FixedPcdGetBool(PcdFspBinaryEnable) == 0
//
// In FSP S3 resume path, PAM lock is took care by Notify Phase API, so skipped it here.
//
SiPolicyPpi = NULL;
HostBridgePeiConfig = NULL;
SkipPamLock = FALSE;
Status = PeiServicesLocatePpi (
&gSiPolicyPpiGuid,
0,
NULL,
(VOID **) &SiPolicyPpi
);
if ((Status == EFI_SUCCESS) && (SiPolicyPpi != NULL)) {
Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gHostBridgePeiConfigGuid, (VOID *) &HostBridgePeiConfig);
ASSERT_EFI_ERROR (Status);
if (Status == EFI_SUCCESS) {
SkipPamLock = (BOOLEAN) (UINTN) HostBridgePeiConfig->SkipPamLock;
}
}
if (SkipPamLock == FALSE) {
DEBUG ((DEBUG_INFO, "S3 PAM_LOCK!!\n"));
PciSegmentOr32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, 0, 0, R_SA_PAM0), BIT0);
}
#endif
DEBUG ((DEBUG_INFO, "SaS3ResumeAtEndOfPei Callback Exit\n"));
PostCode (0xA7F);
return EFI_SUCCESS;
}
/**
Print SA PCI space in Debug log.
@retval None
**/
VOID
SaPciPrint (
VOID
)
{
UINT64 PciBase;
UINT8 Device;
UINT8 i;
UINT8 j;
for (Device = 0; Device <= 8; Device++) {
if ((PcdGetBool (PcdSaPciPrint)) || (Device == 0) || (Device == 2)) {
PciBase = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, Device, 0, 0);
if (PciSegmentRead16 (PciBase) != 0xFFFF) {
DEBUG ((DEBUG_INFO, "\nPrinting PCI space for device %x\n ", Device));
for (i = 0; i <= 0xF ; i++) {
DEBUG ((DEBUG_INFO," %2X",i));
}
for (i = 0; i <= 0xF; i++) {
DEBUG ((DEBUG_INFO, "\n%2X", (i * 0x10)));
for (j = 0; j <= 0xF; j++) {
DEBUG ((DEBUG_INFO, " %2X", PciSegmentRead8 (PciBase + (i * 0x10) + j)));
}
}
}
}
}
DEBUG ((DEBUG_INFO, "\n"));
}
/**
Set SAPMCTL Register.
@retval None
**/
VOID
SetSaPmCtlReg (
VOID
)
{
EFI_STATUS Status;
UINT64_STRUCT MchBar;
UINT32 Data32And;
UINT32 Data32Or;
SI_POLICY_PPI *SiPolicyPpi;
HOST_BRIDGE_PEI_CONFIG *HostBridgePeiConfig;
SiPolicyPpi = NULL;
///
/// Get policy settings through the SaPolicy PPI
///
Status = PeiServicesLocatePpi (&gSiPolicyPpiGuid, 0, NULL, (VOID **) &SiPolicyPpi);
ASSERT_EFI_ERROR (Status);
Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gHostBridgePeiConfigGuid, (VOID *) &HostBridgePeiConfig);
ASSERT_EFI_ERROR (Status);
MchBar.Data32.High = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MCHBAR + 4));
MchBar.Data32.Low = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MCHBAR));
MchBar.Data &= (UINT64) ~BIT0;
Data32And = (UINT32) ~(BIT10 | BIT9);
Data32Or = 0x3 << 9;
MmioAndThenOr32 ((UINTN) MchBar.Data + R_SA_MCHBAR_SAPMCTL_OFFSET, Data32And, Data32Or);
}
/**
This function is to Set BIOS_RESET_CPL bits.
@retval None
**/
VOID
SetBiosResetCpl (
VOID
)
{
UINT64_STRUCT MchBar;
MchBar.Data32.High = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MCHBAR + 4));
MchBar.Data32.Low = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MCHBAR));
MchBar.Data &= (UINT64) ~BIT0;
DEBUG ((DEBUG_INFO, "Set BIOS_RESET_CPL to indicate all configurations complete\n"));
PostCode (0xA61);
MmioOr8 ((UINTN) MchBar.Data + R_SA_MCHBAR_BIOS_RESET_CPL_OFFSET, BIT0 | BIT1);
}