379 lines
12 KiB
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]//
|