alder_lake_bios/Oem/L05/FeatureCommon/InsydeL05ModulePkg/Library/BiosSelfHealingLib/BiosSelfHealingLib.c

379 lines
12 KiB
C

/** @file
Instance of BIOS Self-Healing Services Library.
;******************************************************************************
;* Copyright (c) 2020, Insyde Software Corporation. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include <Uefi.h>
#include <L05BiosSelfHealingConfig.h>
#include <L05ChipsetNameList.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/FeatureLib/OemSvcGetMfgMode.h>
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE)
#include <PchBdfAssignment.h> // PCI_DEVICE_NUMBER_PCH_ESPI, PCI_FUNCTION_NUMBER_PCH_ESPI
#include <Register/PchRegs.h> // DEFAULT_PCI_BUS_NUMBER_PCH
#include <Register/SpiRegs.h> // R_SPI_CFG_BC, B_SPI_CFG_BC_TSS
#include <Register/PchPcrRegs.h> // PID_RTC_HOST
#include <Register/RtcRegs.h> // R_RTC_PCR_BUC, B_RTC_PCR_BUC_TS
#include <Register/HeciRegs.h> // HECI_FWS_REGISTER
#include <Register/MeRegs.h> // ME_DEVICE_NUMBER
#include <Library/PciSegmentLib.h> // PciSegmentRead32
#include <Library/IoLib.h> // MmioRead32
#include <Library/MmPciLib.h> // MmPciBase
#include <Library/PchPcrLib.h> // PchPcrAndThenOr32
#endif
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT)
#include <Library/AmdPspBaseLibV2.h> // CheckPspRecoveryFlagV2
#endif
//
// Block definition for TigerLake
//
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE)
UINT32 mPrimaryFvBase[] = {FixedPcdGet32 (PcdFlashFirmwareBinariesFvBase)};
UINT32 mBackupFvBase[] = {FixedPcdGet32 (PcdFlashFvL05BackupIbbBase)};
UINT32 mBackupFvSize[] = {FixedPcdGet32 (PcdFlashFvL05BackupIbbSize)};
#endif
//[-start-220125-BAIN000092-remove]//
#ifndef LCFC_SUPPORT
//
// Block definition for AlderLake
//
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE)
UINT32 mBackupFvBase[] = {FixedPcdGet32 (PcdFwResiliencyReservedBase)};
UINT32 mBackupFvSize[] = {FixedPcdGet32 (PcdFwResiliencyReservedSize)};
#endif
#endif
//[-end-220125-BAIN000092-remove]//
//
// Block definition for Cezanne
//
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE)
UINT32 mPrimaryFvBase[] = {
#ifdef CZN_COMBO_SUPPORT
FixedPcdGet32 (PcdFlashCznPspDirLv2ABase), FixedPcdGet32 (PcdFlashCznBiosDirLv2ABase),
#endif
#ifdef LCN_COMBO_SUPPORT
FixedPcdGet32 (PcdFlashRnPspDirLv2ABase), FixedPcdGet32 (PcdFlashRnBiosDirLv2ABase),
#endif
FixedPcdGet32 (PcdFlashFvRecovery2PadBase)
};
UINT32 mBackupFvBase[] = {
#ifdef CZN_COMBO_SUPPORT
FixedPcdGet32 (PcdFlashCznPspDirLv2BBase), FixedPcdGet32 (PcdFlashCznBiosDirLv2BBase),
#endif
#ifdef LCN_COMBO_SUPPORT
FixedPcdGet32 (PcdFlashRnPspDirLv2BBase), FixedPcdGet32 (PcdFlashRnBiosDirLv2BBase),
#endif
FixedPcdGet32 (PcdFlashFvRecoveryPadBase)
};
UINT32 mBackupFvSize[] = {
#ifdef CZN_COMBO_SUPPORT
FixedPcdGet32 (PcdFlashCznPspDirLv2BSize), FixedPcdGet32 (PcdFlashCznBiosDirLv2BSize),
#endif
#ifdef LCN_COMBO_SUPPORT
FixedPcdGet32 (PcdFlashRnPspDirLv2BSize), FixedPcdGet32 (PcdFlashRnBiosDirLv2BSize),
#endif
FixedPcdGet32 (PcdFlashFvRecoveryPadSize)
};
#endif
//
// Block definition for Rembrandt
//
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT)
UINT32 mPrimaryFvBase[] = {
FixedPcdGet32 (PcdFlashPspDirABase),
FixedPcdGet32 (PcdFlashBiosDirABase),
FixedPcdGet32 (PcdFlashFvRecoveryBase)
};
UINT32 mBackupFvBase[] = {
FixedPcdGet32 (PcdFlashPspDirBBase),
FixedPcdGet32 (PcdFlashBiosDirBBase),
FixedPcdGet32 (PcdFlashPeiFlashBBase)
};
UINT32 mBackupFvSize[] = {
FixedPcdGet32 (PcdFlashPspDirBSize),
FixedPcdGet32 (PcdFlashBiosDirBSize),
FixedPcdGet32 (PcdFlashPeiFlashBSize)
};
#endif
//[-start-220125-BAIN000092-remove]//
#ifndef LCFC_SUPPORT
UINT8 mPbbrSyncSignature[] = {'P', 'B', 'B', 'R', 'S', 'Y', 'N', 'C'};
UINT8 mPbbrSyncSignatureSize = sizeof (mPbbrSyncSignature);
#endif
//[-end-220125-BAIN000092-remove]//
#if (FixedPcdGet32 (PcdL05ChipsetName) != L05_CHIPSET_NAME_ALDERLAKE)
/**
Retrieve IBB FV info.
@param PrimaryFvBase Point to PrimaryFvBase table.
@param BackupFvBase Point to BackupFvBase table.
@param BackupFvSize Point to BackupFvSize table.
@retval FvCount FV count.
**/
UINTN
RetrieveIbbFvInfo (
IN UINT32 **PrimaryFvBase,
IN UINT32 **BackupFvBase,
IN UINT32 **BackupFvSize
)
{
*PrimaryFvBase = mPrimaryFvBase;
*BackupFvBase = mBackupFvBase;
*BackupFvSize = mBackupFvSize;
return (sizeof (mBackupFvBase) / sizeof (UINT32));
}
/**
Source data processing.
@param FvBase FvBase of IBBR.
@param Buffer Point to source buffer.
@retval EFI_SUCCESS This function execute successfully.
**/
EFI_STATUS
PatchDataToBuffer (
IN UINT32 FvBase,
IN VOID *Buffer
)
{
//
// Cezanne only
//
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE)
UINTN Index;
EFI_L05_BSH_DATA_HEADER *BshDataHdr;
EFI_L05_PATCH_DATA_HEADER *PatchDataHdr;
VOID *PatchData;
BshDataHdr = (EFI_L05_BSH_DATA_HEADER *) (UINTN) PcdGet32 (PcdFlashFvL05BshDataBase);
PatchDataHdr = NULL;
PatchData = NULL;
if (BshDataHdr->PatchCount > 0) {
PatchDataHdr = (EFI_L05_PATCH_DATA_HEADER *) ((UINTN) BshDataHdr + sizeof (EFI_L05_BSH_DATA_HEADER));
PatchData = (VOID *) ((UINTN) PatchDataHdr + sizeof (EFI_L05_PATCH_DATA_HEADER) * BshDataHdr->PatchCount);
}
for (Index = 0; Index < BshDataHdr->PatchCount; Index++) {
if (FvBase == PatchDataHdr->FvBase) {
CopyMem ((VOID *) ((UINTN) Buffer + PatchDataHdr->Offset), PatchData, PatchDataHdr->Size);
}
PatchData = (VOID *) ((UINTN) PatchData + PatchDataHdr->Size);
PatchDataHdr = (EFI_L05_PATCH_DATA_HEADER *) ((UINTN) PatchDataHdr + sizeof (EFI_L05_PATCH_DATA_HEADER));
}
#endif
return EFI_SUCCESS;
}
//[-start-220125-BAIN000092-remove]//
//#endif
//[-end-220125-BAIN000092-remove]//
/**
Check if address is in backup IBB region.
@retval TRUE Address is in backup IBB region.
@retval FALSE Normal region.
**/
BOOLEAN
IsBackupIbbRegion (
IN UINT32 Address
)
{
UINTN Index;
for (Index = 0; Index < (sizeof (mBackupFvBase) / sizeof (UINT32)); Index++) {
if ((Address >= mBackupFvBase[Index]) && (Address < (mBackupFvBase[Index] + mBackupFvSize[Index]))) {
return TRUE;
}
}
return FALSE;
}
//[-start-220125-BAIN000092-add]//
#endif
//[-end-220125-BAIN000092-add]//
/**
Get Top Swap status.
@retval TRUE Top Swap is enabled.
@retval FALSE Top Swap is disabled.
**/
BOOLEAN
TopSwapStatus (
VOID
)
{
BOOLEAN TopSwapDetected = FALSE;
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE)
UINTN SpiPciBase;
UINT32 Data32;
//
// Refer to Intel PCH EDS Volume 1 of 2
// Charpter 9 Pin Straps
// GPP_B14 - The status of this strap is readable using the Top Swap bit
// (Bus 0, Device 31, Function 0, Offset DCh, BIT4)
//
SpiPciBase = MmPciBase (
DEFAULT_PCI_BUS_NUMBER_PCH,
PCI_DEVICE_NUMBER_PCH_ESPI,
PCI_FUNCTION_NUMBER_PCH_ESPI
);
Data32 = MmioRead32 (SpiPciBase + R_SPI_CFG_BC);
TopSwapDetected = ((Data32 & B_SPI_CFG_BC_TSS) == B_SPI_CFG_BC_TSS) ? TRUE : FALSE;
#endif
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT)
TopSwapDetected = CheckPspRecoveryFlagV2 ();
#endif
DEBUG ((DEBUG_INFO, "%a() TopSwapDetected = %d\n", __FUNCTION__, TopSwapDetected));
return TopSwapDetected;
}
/**
Set Top Swap status.
@param TopSwapEnable Enable Top Swap or Disable it.
@retval EFI_SUCCESS Top Swap set successfully.
**/
EFI_STATUS
TopSwapSet (
IN BOOLEAN TopSwapEnable
)
{
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE)
//
// Refer to Intel PCH EDS Volume 2 of 2
// RTC PCR Register
// Chapter 34.2.2 Backed Up Control (BUC) - Offset 3414h
//
if (TopSwapEnable) {
PchPcrAndThenOr32 (PID_RTC_HOST, R_RTC_PCR_BUC, ~0u, B_RTC_PCR_BUC_TS);
} else {
PchPcrAndThenOr32 (PID_RTC_HOST, R_RTC_PCR_BUC, (UINT32) ~B_RTC_PCR_BUC_TS, 0);
}
#endif
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT)
//
// Not support
//
#endif
return EFI_SUCCESS;
}
/**
Check if system is in manufacturing mode.
@retval TRUE System is in manufacturing mode.
@retval FALSE Normal mode.
**/
BOOLEAN
IsManufacturingMode (
VOID
)
{
EFI_STATUS Status;
BOOLEAN IsMfgMode;
Status = EFI_UNSUPPORTED;
IsMfgMode = FALSE;
Status = OemSvcGetMfgMode (&IsMfgMode);
if (Status == EFI_MEDIA_CHANGED) {
DEBUG ((DEBUG_INFO, "%a() IsMfgMode = %d\n", __FUNCTION__, IsMfgMode));
return IsMfgMode;
}
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE)
HECI_FWS_REGISTER MeFirmwareStatus;
MeFirmwareStatus.ul = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (ME_SEGMENT, ME_BUS, ME_DEVICE_NUMBER, HECI_FUNCTION_NUMBER, R_ME_HFS));
DEBUG ((DEBUG_INFO, "%a() MeFirmwareStatus = %lx\n", __FUNCTION__, MeFirmwareStatus.ul));
IsMfgMode = (MeFirmwareStatus.r.SpiProtectionMode == 1) ? TRUE : FALSE;
#endif
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT)
//
// If OemSvcGetMfgMode() is not implemented, system is not in manufacturing mode by default
//
IsMfgMode = FALSE;
#endif
DEBUG ((DEBUG_INFO, "%a() IsMfgMode = %d\n", __FUNCTION__, IsMfgMode));
return IsMfgMode;
}
//[-start-220125-BAIN000092-remove]//
#ifndef LCFC_SUPPORT
/**
Check PBBR Sync in process signature.
@param None
@retval TRUE Need to sync PBBR.
@retval FALSE No need to sync PBBR.
**/
BOOLEAN
CheckPbbrSyncFlag (
VOID
)
{
UINTN L05FvReservedBase;
L05FvReservedBase = (UINTN) FixedPcdGet32 (PcdFlashFvReservedBase);
if (L05FvReservedBase == 0) {
return FALSE;
}
return (CompareMem ((VOID *)L05FvReservedBase, mPbbrSyncSignature, sizeof (mPbbrSyncSignature)) == 0) ? TRUE : FALSE;
}
#endif
//[-end-220125-BAIN000092-remove]//