267 lines
8.0 KiB
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);
|
|
}
|
|
|