alder_lake_bios/Intel/AlderLake/AlderLakeBoardPkg/Library/PeiBootModeLib/PeiBootModeLib.c

1781 lines
57 KiB
C

/** @file
;******************************************************************************
;* Copyright (c) 2020 -2021, Insyde Software Corp. 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.
;*
;******************************************************************************
*/
/** @file
Source code file for the Boot Mode Library
@copyright
INTEL CONFIDENTIAL
Copyright 2018 - 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 a 'Sample Driver' and is licensed as such under the terms
of your license agreement with Intel or your vendor.This file may be modified
by the user, subject to the additional terms of the license agreement.
@par Specification Reference:
**/
#include <Base.h>
#include <PiPei.h>
#include <Library/BaseLib.h>
#include <Library/PcdLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/PeiServicesLib.h>
#include <Ppi/Capsule.h>
#include <SetupVariable.h>
#include <Library/PmcLib.h>
#include <Register/TcoRegs.h>
#include <FastBootDataDef.h>
#include <FastBootExceptionInfoHob.h>
#include <CmosMap.h>
//[-start-190814-IB11270244-add]//
#include <Guid/H2OCp.h>
//[-end-190814-IB11270244-add]//
#include <Library/CmosAccessLib.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Library/GpioNativeLib.h>
#include <Library/GpioLib.h>
#include <PlatformBoardConfig.h>
#include <Library/PeiBootModeLib.h>
#include "PeiBootModeLibInternal.h"
#include <PlatformBoardId.h>
#include <PlatformBoardType.h>
#include <PlatformNvRamHookLib.h>
#include <Library/SetupInitLib.h>
#include <Include/ChassisIntrDetHob.h>
#include <Library/HobLib.h>
#include <Library/BaseMemoryLib.h>
#include <BootStateLib.h>
//[-start-190724-IB11270244-add]//
#include <Library/FlashRegionLib.h>
#include <Library/H2OCpLib.h>
#include <Library/PeiCapsuleLib.h>
#include <Library/PeiOemSvcKernelLib.h>
//[-end-190724-IB11270244-add]//
//[-start-190829-IB17040083-add]//
#include <Library/SeamlessRecoveryLib.h>
#include <Library/PrintLib.h>
#include <Library/CapsuleUpdateCriteriaLib.h>
//[-start-201030-IB16810136-add]//
#include <Ppi/FirmwareVolumeInfo.h>
#include <Guid/SysFwUpdateProgress.h>
#include <Uefi/UefiSpec.h>
#include <Ppi/Capsule.h>
#include <Library/SpiAccessLib.h>
//[-start-210505-IB16810152-add]//
#include <Library/TopSwapLib.h>
#include <Library/ResetSystemLib.h>
#include <Library/CmosLib.h>
#include <ChipsetCmos.h>
//[-start-210728-BAIN000025-add]//
#ifdef LCFC_SUPPORT
#include <Library/TimerLib.h>
#endif
//[-end-210728-BAIN000025-add]//
//[-end-210505-IB16810152-add]//
//[-end-201030-IB16810136-add]//
//[-start-211109-IB18410132-add]//
#include <SecureFlash.h>
//[-end-211109-IB18410132-add]//
//[-start-210720-IB16810158-add]//
#include <Guid/BootStateCapsule.h>
//[-end-210720-IB16810158-add]//
//[-start-211116-IB16560281-add]//
#include <Library/VariableLib.h>
#include <Library/BootGuardPlatformLib.h>
//[-end-211116-IB16560281-add]//
#define MAX_STRING_LENGTH 160
//[-end-190829-IB17040083-add]//
#define FAST_BOOT_OR_MASK 0x01
//[-start-201030-IB16810136-add]//
#define SHA256_DIGEST_HASH_SIZE 0x20
//[-end-201030-IB16810136-add]//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR mPpiListNonS3BootMode = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gPeiBootInNonS3ModePpiGuid,
NULL
};
///
/// Priority of our boot modes, highest priority first
///
GLOBAL_REMOVE_IF_UNREFERENCED EFI_BOOT_MODE mBootModePriority[] = {
BOOT_IN_RECOVERY_MODE,
BOOT_WITH_DEFAULT_SETTINGS,
BOOT_ON_FLASH_UPDATE,
BOOT_ON_S3_RESUME,
BOOT_ON_S4_RESUME,
BOOT_WITH_MINIMAL_CONFIGURATION,
BOOT_ASSUMING_NO_CONFIGURATION_CHANGES,
BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS,
BOOT_WITH_FULL_CONFIGURATION,
BOOT_ON_S5_RESUME,
BOOT_SPECIAL_MASK
};
EFI_STATUS
EFIAPI
PreMemUpdateBootMode (
IN OUT EFI_BOOT_MODE *BootMode
);
//[-start-210415-IB19010024-add]//
EFI_STATUS
EFIAPI
InstallFvExtendedPostMemoryCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
);
EFI_STATUS
EFIAPI
InstallFvExtendedAdvancedCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
);
/**
Notify list for FV installation to the memory for Extended BIOS Region.
Each entry of the notify list may need to be registered based on a boot path.
Make sure what FV is installed by each callback and notify them per needs.
**/
static EFI_PEI_NOTIFY_DESCRIPTOR mExtendedBiosDecodeReadyNotifyList [] = {
{
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gExtendedBiosDecodeReadyPpiGuid,
InstallFvExtendedPostMemoryCallback
},
{
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gExtendedBiosDecodeReadyPpiGuid,
InstallFvExtendedAdvancedCallback
},
};
VOID
PrintFvHeaderInfo (
EFI_FIRMWARE_VOLUME_HEADER *FvHeader
);
//[-end-210415-IB19010024-add]//
//[-start-210720-IB16810158-add]//
/**
FvCnvUncompact section dependency PPI
**/
static EFI_PEI_PPI_DESCRIPTOR mFvCnvDispatchFlagPpi = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gPeiFvCnvDispatchFlagPpiGuid,
NULL
};
/**
This function call checks if this is after capsule update by BootStateAfterCapsule variable.
The variable is set to TRUE at the end of capsule update process.
The boot paths always require all FVs to be installed
so UEFI global boot option variables are initialized.
@retval TRUE This is the first boot after capsule update.
@retval FALSE This is NOT the first boot after capsule update.
**/
BOOLEAN
IsAfterCapsule (
VOID
)
{
EFI_STATUS Status;
EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi;
UINTN VariableSize;
BOOLEAN BootStateAfterCapsule;
BOOLEAN IsAfterCapsule;
BOOLEAN CapsuleUpdateEnable;
BootStateAfterCapsule = FALSE;
IsAfterCapsule = FALSE;
Status = PeiServicesLocatePpi (
&gEfiPeiReadOnlyVariable2PpiGuid,
0,
NULL,
(VOID **)&VariablePpi
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "IsAfterCapsule : Read Only Variable PPI is not found.\n"));
ASSERT_EFI_ERROR (Status);
return FALSE;
}
CapsuleUpdateEnable = PcdGetBool (PcdCapsuleEnable);
if (CapsuleUpdateEnable) {
VariableSize = sizeof (BOOLEAN);
Status = VariablePpi->GetVariable (
VariablePpi,
BOOT_STATE_AFTER_CAPSULE_VARIABLE_NAME,
&gBootStateAfterCapsuleGuid,
NULL,
&VariableSize,
&BootStateAfterCapsule
);
if ((Status != EFI_NOT_FOUND) && EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "IsAfterCapsule : Get variable failure.\n"));
ASSERT_EFI_ERROR (Status);
IsAfterCapsule = FALSE;
}
if (BootStateAfterCapsule) {
DEBUG ((DEBUG_INFO, "IsAfterCapsule : This is the first boot path after Capsule update.\n"));
IsAfterCapsule = TRUE;
} else {
DEBUG ((DEBUG_INFO, "IsAfterCapsule : This is NOT the first boot path after capsule update.\n"));
IsAfterCapsule = FALSE;
}
}
return IsAfterCapsule;
}
/**
This function call checks if Network is enabled by Setup variables.
@retval TRUE Network is enabled.
@retval FALSE Network is not enabled.
**/
BOOLEAN
IsNetworkEnabled (
VOID
)
{
EFI_STATUS Status;
EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi;
UINTN VariableSize;
SETUP_DATA SystemConfiguration;
Status = PeiServicesLocatePpi (
&gEfiPeiReadOnlyVariable2PpiGuid,
0,
NULL,
(VOID **)&VariablePpi
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "IsNetworkEnabled : Read Only Variable PPI is not found.\n"));
ASSERT_EFI_ERROR (Status);
return FALSE;
}
VariableSize = sizeof (SETUP_DATA);
Status = VariablePpi->GetVariable (
VariablePpi,
L"Setup",
&gSetupVariableGuid,
NULL,
&VariableSize,
&SystemConfiguration
);
ASSERT_EFI_ERROR (Status);
if (!EFI_ERROR (Status)) {
if ((SystemConfiguration.EfiNetworkSupport != 0) || (SystemConfiguration.PrebootBleEnable == 1)) {
DEBUG ((DEBUG_INFO, "IsNetworkEnabled : Network wants to be initialized. \n"));
return TRUE;
}
}
return FALSE;
}
/**
This function call installs section dependency PPIs for the child FVs in Optional FV.
@param[out] *Installed Return TRUE if section dependencies in Optional FV are installed.
Return FALSE when none of section dependencies in Optional FV are installed.
@retval EFI_SUCCESS Section dependency installation completes successfully.
@retval Others Section dependency installation fails to complete.
**/
EFI_STATUS
InstallOptionalFvDependency (
OUT BOOLEAN *Installed
)
{
EFI_STATUS Status;
Status = EFI_SUCCESS;
*Installed = FALSE;
#if FixedPcdGetBool (PcdFspModeSelection) == 0 // #if Dispatch Mode
if (IsAfterCapsule () || IsNetworkEnabled ()) {
#endif
DEBUG ((DEBUG_INFO, "InstallOptionalFvDependency : Installing FvCnvUncompact dependency.\n"));
Status = PeiServicesInstallPpi (&mFvCnvDispatchFlagPpi);
*Installed = TRUE;
ASSERT_EFI_ERROR (Status);
#if FixedPcdGetBool (PcdFspModeSelection) == 0 // #if Dispatch Mode
}
#endif
return Status;
}
//[-end-210720-IB16810158-add]//
/**
Update boot mode if it is in capsule update boot mode.
@param[in,out] BootMode Current System BootMode.
@retval EFI_SUCCESS If we have a capsule available.
@retval EFI_NOT_FOUND No capsule detected.
**/
EFI_STATUS
EFIAPI
PreMemUpdateCapsuleBootMode (
IN OUT EFI_BOOT_MODE *BootMode
)
{
PEI_CAPSULE_PPI *Capsule;
EFI_STATUS Status;
EFI_PEI_SERVICES **PeiServices = NULL;
DEBUG((DEBUG_INFO, "PeiBootModeLib PreMemUpdateCapsuleBootMode PeiServicesGetBootMode = 0x%x\n", *BootMode));
//[-start-201030-IB16810136-modify]//
Status = PeiServicesLocatePpi (
&gEfiPeiCapsulePpiGuid,
0,
NULL,
(VOID **) PeiServices
);
//[-end-201030-IB16810136-modify]//
if (EFI_ERROR(Status)) {
return EFI_NOT_FOUND;
}
///
/// Determine if we're in capsule update mode
///
//[-start-201030-IB16810136-modify]//
Status = PeiServicesLocatePpi (
&gEfiPeiCapsulePpiGuid,
0,
NULL,
(VOID **) &Capsule
);
//[-end-201030-IB16810136-modify]//
if (Status == EFI_SUCCESS) {
Status = Capsule->CheckCapsuleUpdate((EFI_PEI_SERVICES **) PeiServices);
if (Status == EFI_SUCCESS) {
PrioritizeBootMode(BootMode, BOOT_ON_FLASH_UPDATE);
}
}
//[-start-201030-IB16810136-remove]//
// if (*BootMode != BOOT_ON_FLASH_UPDATE) {
// Status = PreMemUpdateBootMode (BootMode);
// }
//[-end-201030-IB16810136-remove]//
DEBUG((DEBUG_INFO, "PeiBootModeLib PreMemUpdateCapsuleBootMode PeiServicesSetBootMode = 0x%x\n", *BootMode));
return Status;
}
/**
Check fast boot is enabled or not
@retval FastBootEnabledStatus TRUE means fast boot is enabled
FALSE means fast boot is disabled
**/
BOOLEAN
EFIAPI
IsFastBootEnabled (
VOID
)
{
EFI_STATUS Status;
EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiReadOnlyVarPpi;
UINTN VarSize;
SETUP_DATA SystemConfiguration;
BOOLEAN FastBootEnabledStatus;
FastBootEnabledStatus = FALSE;
Status = PeiServicesLocatePpi (
&gEfiPeiReadOnlyVariable2PpiGuid,
0,
NULL,
(VOID **) &PeiReadOnlyVarPpi
);
if (Status == EFI_SUCCESS) {
VarSize = sizeof (SETUP_DATA);
Status = PeiReadOnlyVarPpi->GetVariable (
PeiReadOnlyVarPpi,
L"Setup",
&gSetupVariableGuid,
NULL,
&VarSize,
&SystemConfiguration
);
if (Status == EFI_SUCCESS) {
if (SystemConfiguration.FastBoot != 0) {
FastBootEnabledStatus = TRUE;
}
}
}
return FastBootEnabledStatus;
}
/**
Update boot mode
@param[in,out] BootMode Current System BootMode.
@retval EFI_SUCCESS The boot mode was returned successfully.
**/
EFI_STATUS
EFIAPI
PreMemUpdateBootMode (
IN OUT EFI_BOOT_MODE *BootMode
)
{
//[-start-190724-IB11270244-remove]//
// EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
// UINTN VarSize;
// BOOLEAN IsFastBootEnable;
//[-end-190724-IB11270244-remove]//
EFI_STATUS Status;
//[-start-190724-IB11270244-remove]//
// UINT8 FastBootRegData;
// FAST_BOOT_EXCEPTION_INFO_HOB *FastBootExceptionInfoHob;
//[-end-190724-IB11270243-remove]//
DEBUG ((DEBUG_INFO, "PeiBootModeLib PreMemUpdateBootMode Entry\n"));
//[-start-210728-BAIN000025-add]//
#ifdef LCFC_SUPPORT
MicroSecondDelay(5000);
MicroSecondDelay(5000);
#endif
//[-end-210728-BAIN000025-add]//
//[-start-190724-IB11270244-modify]//
// FastBootRegData = 0;
//
// IsFastBootEnable = IsFastBootEnabled ();
//[-end-190724-IB11270244-modify]//
//[-start-190724-IB11270244-add]//
//
// Change boot mode here if Secure flash is enabled.
//
//[-start-201030-IB16810136-modify]//
if (DetectPendingUpdateImage()) {
PrioritizeBootMode (BootMode, BOOT_ON_FLASH_UPDATE);
}
if (*BootMode != BOOT_ON_FLASH_UPDATE && *BootMode != BOOT_IN_RECOVERY_MODE) {
if ((*BootMode != BOOT_ON_S5_RESUME) && IsBootWithNoChange ()) {
PrioritizeBootMode (BootMode, BOOT_ASSUMING_NO_CONFIGURATION_CHANGES);
} else {
PrioritizeBootMode (BootMode, BOOT_WITH_FULL_CONFIGURATION);
}
}
//[-end-201030-IB16810136-modify]//
//[-end-190724-IB11270244-add]//
//[-start-190724-IB11270244-remove]//
// if (IsFastBootEnable) {
// if (IsPreviousBootSuccessful () && !IsTimeOutOccurred () && !IsPowerButtonOverride ()) {
// PrioritizeBootMode (BootMode, BOOT_WITH_MINIMAL_CONFIGURATION);
// } else {
// Status = PeiServicesCreateHob (
// EFI_HOB_TYPE_GUID_EXTENSION,
// sizeof (FAST_BOOT_EXCEPTION_INFO_HOB),
// (VOID **) &FastBootExceptionInfoHob
// );
// if (!EFI_ERROR (Status)) {
// FastBootExceptionInfoHob->Header.Name = gFastBootExceptionInfoHobGuid;
// FastBootExceptionInfoHob->FbExceptionType = ExceptionType2;
// FastBootExceptionInfoHob->FbExceptionCategory = BootFailure;
// }
// DEBUG ((DEBUG_INFO, "PeiBootModeLib Exception has occurred. Prioritizing Boot mode to BOOT_WITH_FULL_CONFIGURATION\n"));
// PrioritizeBootMode (BootMode, BOOT_WITH_FULL_CONFIGURATION);
// }
// } else {
// if ((*BootMode != BOOT_ON_S5_RESUME) && IsBootWithNoChange ()) {
// PrioritizeBootMode (BootMode, BOOT_ASSUMING_NO_CONFIGURATION_CHANGES);
// } else {
// PrioritizeBootMode (BootMode, BOOT_WITH_FULL_CONFIGURATION);
// }
// }
//
// ///
// /// FastBoot - set boot progress bit to indicate boot is in progress
// /// bit will be cleared before booting to OS/Shell/BIOS Setup or ResetSystem() been triggered
// ///
// if (IsFastBootEnable) {
// if (*BootMode != BOOT_ON_S3_RESUME) {
// FastBootRegData = GetFastBootFlagStatus ();
// FastBootRegData |= FAST_BOOT_OR_MASK;
// UpdateFastBootFlagStatus (FastBootRegData);
// }
// }
//[-end-190724-IB11270244-remove]//
if (*BootMode != BOOT_ON_S3_RESUME) {
///
/// If not in S3 mode, signal it.
///
Status = PeiServicesInstallPpi (&mPpiListNonS3BootMode);
ASSERT_EFI_ERROR (Status);
}
//[-start-190724-IB11270244-remove]//
// if (IsFastBootEnable) {
// Status = PeiServicesLocatePpi (
// &gEfiPeiReadOnlyVariable2PpiGuid,
// 0,
// NULL,
// (VOID **) &VariableServices
// );
// VarSize = 0;
// if (!RETURN_ERROR (Status)) {
// Status = VariableServices->GetVariable (
// VariableServices,
// L"ConOut",
// &gEfiGlobalVariableGuid,
// NULL,
// &VarSize,
// NULL
// );
// if (Status == EFI_NOT_FOUND) {
// PrioritizeBootMode (BootMode, BOOT_WITH_FULL_CONFIGURATION);
// }
// }
// }
//[-end-190724-IB11270244-remove]//
DEBUG ((DEBUG_INFO, "PeiBootModeLib PreMemUpdateBootMode Exit "));
return EFI_SUCCESS;
}
//[-start-190814-IB11270244-add]//
/**
If boot mode is recovery mode and FSP is API mode, we should not report FSP-S FV.
@param[in] Event - A pointer to the Event that triggered the callback.
@param[in] Handle - Checkpoint handle.
**/
VOID
EFIAPI
PublishFvInRecoveryCallback (
IN EFI_EVENT Event,
IN H2O_CP_HANDLE Handle
)
{
EFI_STATUS Status;
H2O_PEI_CP_CRISIS_RECOVERY_PUBLISH_FV_DATA *CrisisRecoveryPublishFvData;
EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExtHeader;
Status = H2OCpLookup (
Handle,
(VOID **)&CrisisRecoveryPublishFvData,
&gH2OPeiCpCrisisRecoveryPublishFvGuid
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Checkpoint Data Not Found: %x (%r)\n", Handle, Status));
DEBUG ((DEBUG_ERROR, " %a\n", __FUNCTION__));
return;
}
FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)CrisisRecoveryPublishFvData->FvHeader + CrisisRecoveryPublishFvData->FvHeader->ExtHeaderOffset);
if (CompareGuid (&FwVolExtHeader->FvName, &gFspSiliconFvGuid)) {
DEBUG ((DEBUG_INFO, "Do not report FSP-S FV when API mode.\n"));
CrisisRecoveryPublishFvData->Status = H2O_CP_TASK_SKIP;
}
}
//[-start-201030-IB16810136-add]//
/**
Install FvInfoPpi For FV.
@param[in] FvAddr FV Address
@param[in] FvSize FV Size
**/
STATIC
VOID
InstallFvInfoPpi (
IN UINT64 FvAddr,
IN UINT64 FvSize
)
{
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
UINTN FvInfoInstance;
EFI_STATUS Status;
BOOLEAN IsFvInoPpiHasInstalled;
EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *FvInfoPpi;
FvInfoInstance = 0;
IsFvInoPpiHasInstalled = FALSE;
while (TRUE) {
Status = PeiServicesLocatePpi (&gEfiPeiFirmwareVolumeInfoPpiGuid, FvInfoInstance, NULL, &FvInfoPpi);
if (EFI_ERROR (Status)) {
break;
}
if ((FvAddr == (UINT64)(UINTN)FvInfoPpi->FvInfo) && (FvInfoPpi->FvInfoSize == (UINT32)FvSize)) {
IsFvInoPpiHasInstalled = TRUE;
break;
}
FvInfoInstance++;
}
if (!IsFvInoPpiHasInstalled) {
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)FvAddr;
PeiServicesInstallFvInfoPpi (
&FvHeader->FileSystemGuid,
(VOID*)(UINTN)FvAddr,
(UINT32)FvSize,
NULL,
NULL
);
}
}
//[-end-201030-IB16810136-add]//
//[-start-201030-IB16810136-add]//
/**
Check whether loading backup OBB is needed.
@retval TRUE Load backup OBB is needed.
@retval FALSE Load backup OBB is not needed.
**/
STATIC
BOOLEAN
LoadBackupObbIsRequired (
VOID
)
{
EFI_STATUS Status;
UINT32 Progress;
EFI_HOB_GUID_TYPE *GuidHob;
GuidHob = GetFirstGuidHob (&gH2OSeamlessRecoveryDigestGuid);
if (GuidHob == NULL) {
//
// Backup OBB not found.
//
return FALSE;
}
Status = GetFirmwareUpdateProgress (&Progress);
if (EFI_ERROR (Status)) {
//
// Load backup OBB for recovery in default.
//
return TRUE;
}
if (IsFirmwareUpdateResiliencySupported ()) {
return (Progress == FlashPbb);
} else {
return (Progress == FlashPbbR);
}
}
//[-end-201030-IB16810136-add]//
//[-start-210415-IB19010024-add]//
/**
Callback on Extended BIOS Decode Ready Ppi so Extended PostMemory FV is installed to the memory
for Extended BIOS Region. The callback is called regardless of Extended BIOS Region support
in platform code.
@param[in] PeiServices General purpose services available to every PEIM.
@param[in] NotifyDescriptor The notification structure this PEIM registered on install.
@param[in] Ppi The gExtendedBiosDecodeReady PPI. Not used.
@retval EFI_SUCCESS Always returns EFI_SUCCESS
**/
EFI_STATUS
EFIAPI
InstallFvExtendedPostMemoryCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
)
{
#if FixedPcdGetBool(PcdExtendedBiosRegionSupport) == 1
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
DEBUG ((DEBUG_INFO, "Install FlashFvExtendedPostMemory - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvExtendedPostMemoryBase), PcdGet32 (PcdFlashFvExtendedPostMemorySize)));
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (UINT32) PcdGet32 (PcdFlashFvExtendedPostMemoryBase);
PeiServicesInstallFvInfo2Ppi (
&(FvHeader->FileSystemGuid),
(VOID *) (UINTN) PcdGet32 (PcdFlashFvExtendedPostMemoryBase),
PcdGet32 (PcdFlashFvExtendedPostMemorySize),
NULL,
NULL,
0
);
PrintFvHeaderInfo (FvHeader);
#else
DEBUG ((DEBUG_INFO, "Extended BIOS Region is not supported by the image. No FV installed here\n"));
#endif
return EFI_SUCCESS;
}
/**
Callback on Extended BIOS Decode Ready Ppi so Extended Advanced FV is installed to the memory
for Extended BIOS Region. The callback is called regardless of Extended BIOS Region support in
platform code. Extended Advanced FV contains DXE phase drivers only and may want to be skipped
on S3 path for responsiveness.
@param[in] PeiServices General purpose services available to every PEIM.
@param[in] NotifyDescriptor The notification structure this PEIM registered on install.
@param[in] Ppi The gExtendedBiosDecodeReady PPI. Not used.
@retval EFI_SUCCESS Always returns EFI_SUCCESS
**/
EFI_STATUS
EFIAPI
InstallFvExtendedAdvancedCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
)
{
#if FixedPcdGetBool(PcdExtendedBiosRegionSupport) == 1
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
DEBUG ((DEBUG_INFO, "Install FlashFvExtendedAdvanced - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvExtendedAdvancedBase), PcdGet32 (PcdFlashFvExtendedAdvancedSize)));
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (UINT32) PcdGet32 (PcdFlashFvExtendedAdvancedBase);
PeiServicesInstallFvInfo2Ppi (
&(FvHeader->FileSystemGuid),
(VOID *) (UINTN) PcdGet32 (PcdFlashFvExtendedAdvancedBase),
PcdGet32 (PcdFlashFvExtendedAdvancedSize),
NULL,
NULL,
0
);
PrintFvHeaderInfo (FvHeader);
#else
DEBUG ((DEBUG_INFO, "Extended BIOS Region is not supported by the image. No FV installed here\n"));
#endif
return EFI_SUCCESS;
}
/**
Debug support function to output detailed information on a firmware volume being installed.
Setting DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask lets the function to be
included in a module. Refer to DEBUG_CODE macro.
@param[in] FvHeader Pointer to firmware volume header
**/
VOID
PrintFvHeaderInfo (
EFI_FIRMWARE_VOLUME_HEADER *FvHeader
)
{
DEBUG_CODE (
EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader;
EFI_FFS_FILE_HEADER *FfsHeader;
DEBUG ((DEBUG_INFO, "[ FV @ 0x%x ] \n", FvHeader));
DEBUG ((DEBUG_INFO, " FV File System : %g \n", &FvHeader->FileSystemGuid));
if (FvHeader->ExtHeaderOffset != 0) {
FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *) ((UINT8 *) FvHeader + FvHeader->ExtHeaderOffset);
FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FvExtHeader + FvExtHeader->ExtHeaderSize);
FfsHeader = (EFI_FFS_FILE_HEADER *) ALIGN_POINTER (FfsHeader, 8);
DEBUG ((DEBUG_INFO, " FV GUID : %g \n", &FvExtHeader->FvName));
DEBUG ((DEBUG_INFO, " File GUID : %g \n", &FfsHeader->Name));
}
);
}
//[-end-210415-IB19010024-add]//
VOID
BootModeBuildFv(
EFI_BOOT_MODE BootMode
)
{
EFI_STATUS Status;
UINT8 Index;
//[-start-201030-IB16810136-add]//
UINT64 FvAddr;
UINT64 FvSize;
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExtHeader;
//[-end-201030-IB16810136-add]//
//[-start-210720-IB16810158-add]//
BOOLEAN IsOptFvDependencyInstalled;
IsOptFvDependencyInstalled = FALSE;
//[-end-210720-IB16810158-add]//
#if FixedPcdGetBool (PcdFspModeSelection) == 1
H2O_CP_HANDLE CpHandle;
#endif
//
// OemServices
//
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcBootModeCreateFv \n"));
Status = OemSvcBootModeCreateFv (BootMode);
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcBootModeCreateFv Status: %r\n", Status));
if (Status == EFI_MEDIA_CHANGED) {
return;
}
if (BootMode != BOOT_ON_S3_RESUME && BootMode != BOOT_IN_RECOVERY_MODE) {
for (Index = 1; FdmGetNAtSize (&gH2OFlashMapRegionFvGuid, Index) != 0; Index++){
//[-start-201021-IB11790397-modify]//
// BuildFvHob (
// FdmGetNAtAddr (&gH2OFlashMapRegionFvGuid, Index),
// FdmGetNAtSize (&gH2OFlashMapRegionFvGuid, Index)
// );
FvAddr = FdmGetNAtAddr (&gH2OFlashMapRegionFvGuid, Index);
FvSize = FdmGetNAtSize (&gH2OFlashMapRegionFvGuid, Index);
//[-start-210105-IB17510137-add]//
if (FvAddr == 0 || FvSize == 0) {
return;
}
//[-end-210105-IB17510137-add]//
BuildFvHob (FvAddr, FvSize);
InstallFvInfoPpi (FvAddr, FvSize);
//[-end-201021-IB11790397-modify]//
}
BuildFvHob (
FdmGetNAtAddr (&gH2OFlashMapRegionVarGuid, 1),
FdmGetNAtSize (&gH2OFlashMapRegionVarGuid, 1)
+ FdmGetNAtSize(&gH2OFlashMapRegionFtwStateGuid, 1)
+ FdmGetNAtSize(&gH2OFlashMapRegionFtwBackupGuid, 1)
+ FdmGetSizeById(&gH2OFlashMapRegionVarDefaultGuid, &gH2OFlashMapRegionFactoryCopyGuid, 1)
);
//[-start-210720-IB16810158-add]//
Status = InstallOptionalFvDependency (&IsOptFvDependencyInstalled);
if (!EFI_ERROR (Status) && IsOptFvDependencyInstalled) {
DEBUG ((DEBUG_INFO, "Install FlashFvOptional - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvOptionalBase), PcdGet32 (PcdFlashFvOptionalSize)));
PeiServicesInstallFvInfo2Ppi (
&(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvOptionalBase))->FileSystemGuid),
(VOID *) (UINTN) PcdGet32 (PcdFlashFvOptionalBase),
PcdGet32 (PcdFlashFvOptionalSize),
NULL,
NULL,
0
);
}
//[-end-210720-IB16810158-add]//
//[-start-210415-IB19010024-add]//
Status = PeiServicesNotifyPpi (&mExtendedBiosDecodeReadyNotifyList[1]);
ASSERT_EFI_ERROR (Status);
//[-end-210415-IB19010024-add]//
}
//[-start-210415-IB19010024-add]//
Status = PeiServicesNotifyPpi (&mExtendedBiosDecodeReadyNotifyList[0]);
ASSERT_EFI_ERROR (Status);
//[-end-210415-IB19010024-add]//
//[-start-201021-IB11790397-add]//
if (((BootMode == BOOT_IN_RECOVERY_MODE) || (BootMode == BOOT_ON_S3_RESUME)) && PcdGetBool (PcdBiosGuardEnable) == TRUE) {
for (Index = 1; FdmGetNAtSize (&gH2OFlashMapRegionFvGuid, Index) != 0; Index++) {
FvAddr = FdmGetNAtAddr (&gH2OFlashMapRegionFvGuid, Index);
FvSize = FdmGetNAtSize (&gH2OFlashMapRegionFvGuid, Index);
//[-start-210105-IB17510137-add]//
if (FvAddr == 0 || FvSize == 0) {
return;
}
//[-end-210105-IB17510137-add]//
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvAddr;
FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->ExtHeaderOffset);
if (CompareGuid (&FwVolExtHeader->FvName, &gFwBinaryFvGuid)) {
InstallFvInfoPpi (FvAddr, FvSize);
}
}
//[-end-201021-IB11790397-add]//
}
//[-start-201030-IB16810136-add]//
if (BootMode == BOOT_IN_RECOVERY_MODE) {
//[-start-210505-IB16810152-modify]//
if (SpiIsTopSwapEnabled () || LoadBackupObbIsRequired ()) {
//[-end-210505-IB16810152-modify]//
for (Index = 1; FdmGetNAtSize (&gH2OFlashMapRegionFvGuid, Index) != 0; Index++) {
FvAddr = FdmGetNAtAddr (&gH2OFlashMapRegionFvGuid, Index);
FvSize = FdmGetNAtSize (&gH2OFlashMapRegionFvGuid, Index);
//[-start-210105-IB17510137-add]//
if (FvAddr == 0 || FvSize == 0) {
return;
}
//[-end-210105-IB17510137-add]//
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvAddr;
FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->ExtHeaderOffset);
if (CompareGuid (&FwVolExtHeader->FvName, &gFwRecovery2FvGuid) || CompareGuid (&FwVolExtHeader->FvName, &gH2OFlashMapRegionPeiFvGuid)) {
BuildFvHob (FvAddr, FvSize);
InstallFvInfoPpi (FvAddr, FvSize);
}
}
//[-start-210506-IB16810153-add]//
if (PcdGet8 (PcdChasmFallsSupport) == 2 && FeaturePcdGet (PcdUcodeCapsuleUpdateSupported) == TRUE) {
BuildFvHob (FdmGetAddressById (&gH2OFlashMapRegionFvGuid, &gH2OFlashMapRegionMicrocodeGuid, 1), FdmGetSizeById (&gH2OFlashMapRegionFvGuid, &gH2OFlashMapRegionMicrocodeGuid, 1));
InstallFvInfoPpi (FdmGetAddressById (&gH2OFlashMapRegionFvGuid, &gH2OFlashMapRegionMicrocodeGuid, 1), FdmGetSizeById (&gH2OFlashMapRegionFvGuid, &gH2OFlashMapRegionMicrocodeGuid, 1));
}
//[-end-210506-IB16810153-add]//
}
}
//[-end-201030-IB16810136-add]//
//
// Register callback function for gH2OPeiCpCrisisRecoveryPublishFvGuid check point.
//
#if FixedPcdGetBool (PcdFspModeSelection) == 1
if (FeaturePcdGet (PcdH2OPeiCpCrisisRecoveryPublishFvSupported)) {
if (BootMode == BOOT_IN_RECOVERY_MODE) {
Status = H2OCpRegisterHandler (
&gH2OPeiCpCrisisRecoveryPublishFvGuid,
PublishFvInRecoveryCallback,
H2O_CP_MEDIUM,
&CpHandle
);
if (EFI_ERROR (Status)) {
DEBUG_CP ((DEBUG_ERROR, "Checkpoint Register Fail: %g (%r)\n", &gH2OPeiCpCrisisRecoveryPublishFvGuid, Status));
return;
}
DEBUG_CP ((DEBUG_INFO, "Checkpoint Registered: %g (%r)\n", &gH2OPeiCpCrisisRecoveryPublishFvGuid, Status));
}
}
#endif
}
//[-end-190814-IB11270244-add]//
/**
Get Vpd binary address
Parse through each FV for VPD FFS file and return the address
@retval Address on VPD FFS detection else returns 0
**/
UINTN
EFIAPI
GetVpdFfsAddress (
)
{
EFI_STATUS Status;
VOID *Address;
UINTN Instance;
EFI_PEI_FV_HANDLE VolumeHandle;
EFI_PEI_FILE_HANDLE FileHandle;
Address = NULL;
VolumeHandle = NULL;
Instance = 0;
while (TRUE) {
//
// Traverse all firmware volume instances.
//
Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle);
if (EFI_ERROR (Status)) {
break;
}
FileHandle = NULL;
Status = PeiServicesFfsFindFileByName (&gVpdFfsGuid, VolumeHandle, &FileHandle);
if (!EFI_ERROR (Status)) {
//
// Search RAW section.
//
Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &Address);
if (!EFI_ERROR (Status)) {
return (UINTN)Address;
}
}
//
// Search the next volume.
//
Instance++;
}
DEBUG ((EFI_D_ERROR, " PEI get VPD address: %r\n", EFI_NOT_FOUND));
return 0;
}
/**
Detect boot mode
@retval EFI_BOOT_MODE Current System BootMode.
**/
EFI_BOOT_MODE
EFIAPI
DetectBootMode (
VOID
)
{
EFI_STATUS Status;
EFI_BOOT_MODE BootMode;
UINTN VpdBaseAddress;
//[-start-190815-IB11270244-add]//
BOOLEAN SkipPriorityPolicy = FALSE;
CHAR16 *StrBootMode;
//[-end-190815-IB11270244-add]//
//[-start-211116-IB16560281-add]//
UINTN DataSize;
REVOCATION_VALUE Revocation;
REVOCATION_VALUE_HOB *RevocationHobData;
//[-end-211116-IB16560281-add]//
VpdBaseAddress = (UINTN) PcdGet64 (PcdVpdBaseAddress64);
DEBUG ((EFI_D_INFO, "VpdFfsAddress: %x\n", VpdBaseAddress));
if (VpdBaseAddress == 0) {
VpdBaseAddress= (UINTN) GetVpdFfsAddress();
//[-start-210105-IB17510137-modify]//
Status = PcdSet64S (PcdVpdBaseAddress64,VpdBaseAddress);
ASSERT_EFI_ERROR (Status);
//[-end-210105-IB17510137-modify]//
DEBUG ((EFI_D_INFO, "VpdFfsAddress updated: %x\n", VpdBaseAddress));
}
PMC_SLEEP_STATE SleepType;
Status = PeiServicesGetBootMode (&BootMode);
ASSERT_EFI_ERROR (Status);
DEBUG ((DEBUG_INFO, "PeiBootModeLib DetectBootMode PeiServicesGetBootMode BootMode= 0x%x \n", BootMode));
//
// OemServices
//
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcChangeBootMode \n"));
Status = OemSvcChangeBootMode (&BootMode, &SkipPriorityPolicy);
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcChangeBootMode Status: %r\n", Status));
//[-start-190815-IB11270244-modify]//
if (!SkipPriorityPolicy) {
Status = IsRecoveryMode ();
if (Status == EFI_SUCCESS) {
//[-start-211117-IB16560281-add]//
//
// HECI command for Arb Svn Info only exist in DXE phase
// Restore SVN related data from variable before boot mode changed to "BOOT_IN_RECOVERY_MODE".
// Then create a HOB to transfer these data to BootGuardRecoveryHook().
//
DataSize = sizeof (Revocation);
Status = CommonGetVariable (
L"ArbSvnInfo",
&gArbSvnInfoGuid,
&DataSize,
&Revocation
);
if (!EFI_ERROR (Status)) {
Status = PeiServicesCreateHob (
EFI_HOB_TYPE_GUID_EXTENSION,
sizeof (REVOCATION_VALUE_HOB),
(VOID **)&RevocationHobData
);
if (!EFI_ERROR (Status)) {
CopyGuid (&RevocationHobData->EfiHobGuidType.Name, &gArbSvnInfoHobGuid);
RevocationHobData->ACMSVN = Revocation.ACMSVN;
RevocationHobData->BPMSVN = Revocation.BPMSVN;
RevocationHobData->KMSVN = Revocation.KMSVN;
RevocationHobData->KMID = Revocation.KMID;
RevocationHobData->BootGuardStatus = Revocation.BootGuardStatus;
} else {
DEBUG ((EFI_D_ERROR, "Failed to create gArbSvnInfoHobGuid HOB, Status = %r\n", Status));
}
} else {
DEBUG ((EFI_D_ERROR, "Failed to get ArbSvnInfo variable, Status = %r\n", Status));
}
//[-end-211117-IB16560281-add]//
BootMode = BOOT_IN_RECOVERY_MODE;
DEBUG((DEBUG_INFO, "PeiBootModeLib IsRecoveryMode BOOT_IN_RECOVERY_MODE"));
//mPpiListRecoveryBootMode is installed by MinPlatform
}
SleepType = PmcGetSleepTypeAfterWake ();
DEBUG((DEBUG_INFO, "PeiBootModeLib PmcGetSleepTypeAfterWake SleepType= %d \n", SleepType));
if (SleepType != PmcNotASleepState) {
if (!PmcIsPowerFailureDetected () && PmcIsRtcBatteryGood()) {
switch (SleepType) {
case PmcS3SleepState:
PrioritizeBootMode (&BootMode, BOOT_ON_S3_RESUME);
DEBUG((DEBUG_INFO, "PeiBootModeLib PmcS3SleepState BootMode= 0x%x \n", BootMode));
break;
case PmcS4SleepState:
PrioritizeBootMode (&BootMode, BOOT_ON_S4_RESUME);
DEBUG((DEBUG_INFO, "PeiBootModeLib PmcS4SleepState BootMode= 0x%x \n", BootMode));
break;
case PmcS5SleepState:
PrioritizeBootMode (&BootMode, BOOT_ON_S5_RESUME);
DEBUG((DEBUG_INFO, "PeiBootModeLib PmcS5SleepState BootMode= 0x%x \n", BootMode));
break;
default:
break;
}
}
} else {
///
/// Clear Wake Status and Sleep Type
///
PmcClearWakeStatus ();
PmcSetSleepState (PmcInS0State);
}
if (!PmcIsRtcBatteryGood ()) {
DEBUG ((DEBUG_ERROR, "RTC Power failure !! Could be due to a weak or missing battery, BootMode BOOT_WITH_DEFAULT_SETTINGS.\n"));
//[-start-211109-IB18410133-modify]//
PrioritizeBootMode (&BootMode, BOOT_WITH_DEFAULT_SETTINGS);
//[-end-211109-IB18410133-modify]//
}
}
switch (BootMode) {
case BOOT_WITH_FULL_CONFIGURATION:
StrBootMode = L"BOOT_WITH_FULL_CONFIGURATION";
break;
case BOOT_WITH_MINIMAL_CONFIGURATION:
StrBootMode = L"BOOT_WITH_MINIMAL_CONFIGURATION";
break;
case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
StrBootMode = L"BOOT_ASSUMING_NO_CONFIGURATION_CHANGES";
break;
case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
StrBootMode = L"BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS";
break;
case BOOT_WITH_DEFAULT_SETTINGS:
StrBootMode = L"BOOT_WITH_DEFAULT_SETTINGS";
break;
case BOOT_ON_S4_RESUME:
StrBootMode = L"BOOT_ON_S4_RESUME";
break;
case BOOT_ON_S5_RESUME:
StrBootMode = L"BOOT_ON_S5_RESUME";
break;
case BOOT_ON_S2_RESUME:
StrBootMode = L"BOOT_ON_S2_RESUME";
break;
case BOOT_ON_S3_RESUME:
StrBootMode = L"BOOT_ON_S3_RESUME";
break;
case BOOT_ON_FLASH_UPDATE:
StrBootMode = L"BOOT_ON_FLASH_UPDATE";
break;
case BOOT_IN_RECOVERY_MODE:
StrBootMode = L"BOOT_IN_RECOVERY_MODE";
break;
default:
StrBootMode = L"Unknown boot mode";
}
DEBUG ((EFI_D_INFO, "Setting BootMode to %s\n", StrBootMode));
//[-end-190815-IB11270244-modify]//
///
/// Check whether Setup Variable have been changed with new capsule, if changed, set to default
/// Note: Any modification to the below code will impact RPE feature : "Revert to BIOS Golden Config ".
///
//[-start-190724-IB11270244-remove]//
//#if FixedPcdGetBool (PcdSetupEnable) == 1
// if (!IsSetupStructuresUnChanged ()) {
// DEBUG((DEBUG_INFO, "Setup changed in DetectBootMode\n"));
// BootMode = BOOT_WITH_DEFAULT_SETTINGS;
// }
// DEBUG((DEBUG_ERROR, "PeiBootModeLib after Setup Variables check, BootMode = 0x%x\n", BootMode));
//#endif
//[-end-190724-IB11270244-modify]//
DEBUG((DEBUG_ERROR, "PeiBootModeLib after Setup Variables check, BootMode = 0x%x\n", BootMode));
//[-start-190724-IB11270244-modify]//
//#if FixedPcdGetBool (PcdCapsuleEnable) == 1
// ///
// /// Update BootMode
// ///
// Status = PreMemUpdateCapsuleBootMode(&BootMode);
//#else
Status = PreMemUpdateBootMode (&BootMode);
//#endif
//[-end-190724-IB11270244-modify]//
//[-start-190815-IB11270244-add]//
if (FeaturePcdGet (PcdH2OPeiCpSetBootModeBeforeSupported)) {
H2O_PEI_CP_SET_BOOT_MODE_BEFORE_DATA SetBootModeBeforeData;
SetBootModeBeforeData.Size = sizeof (H2O_PEI_CP_SET_BOOT_MODE_BEFORE_DATA);
SetBootModeBeforeData.Status = H2O_CP_TASK_NORMAL;
SetBootModeBeforeData.BootMode = BootMode;
SetBootModeBeforeData.CustomBootModePolicy = FALSE;
DEBUG ((EFI_D_INFO, "Checkpoint Trigger: %g\n", &gH2OPeiCpSetBootModeBeforeGuid));
H2OCpTrigger (&gH2OPeiCpSetBootModeBeforeGuid, &SetBootModeBeforeData);
DEBUG ((EFI_D_INFO, "Checkpoint Result: %x\n", SetBootModeBeforeData.Status));
if (SetBootModeBeforeData.Status == H2O_CP_TASK_UPDATE) {
BootMode = SetBootModeBeforeData.BootMode;
} else if (SetBootModeBeforeData.Status == H2O_CP_TASK_SKIP) {
DEBUG ((EFI_D_ERROR, "WARNING! It doesn't support the H2O_CP_TASK_SKIP status of H2O_PEI_CP_SET_BOOT_MODE_BEFORE checkpoint.\n"));
}
}
switch (BootMode) {
case BOOT_WITH_FULL_CONFIGURATION:
StrBootMode = L"BOOT_WITH_FULL_CONFIGURATION";
break;
case BOOT_WITH_MINIMAL_CONFIGURATION:
StrBootMode = L"BOOT_WITH_MINIMAL_CONFIGURATION";
break;
case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
StrBootMode = L"BOOT_ASSUMING_NO_CONFIGURATION_CHANGES";
break;
case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
StrBootMode = L"BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS";
break;
case BOOT_WITH_DEFAULT_SETTINGS:
StrBootMode = L"BOOT_WITH_DEFAULT_SETTINGS";
break;
case BOOT_ON_S4_RESUME:
StrBootMode = L"BOOT_ON_S4_RESUME";
break;
case BOOT_ON_S5_RESUME:
StrBootMode = L"BOOT_ON_S5_RESUME";
break;
case BOOT_ON_S2_RESUME:
StrBootMode = L"BOOT_ON_S2_RESUME";
break;
case BOOT_ON_S3_RESUME:
StrBootMode = L"BOOT_ON_S3_RESUME";
break;
case BOOT_ON_FLASH_UPDATE:
StrBootMode = L"BOOT_ON_FLASH_UPDATE";
break;
case BOOT_IN_RECOVERY_MODE:
StrBootMode = L"BOOT_IN_RECOVERY_MODE";
break;
default:
StrBootMode = L"Unknown boot mode";
}
DEBUG ((EFI_D_INFO, "Setting BootMode to %s\n", StrBootMode));
//[-end-190815-IB11270244-add]//
//[-start-190814-IB11270244-add]//
BootModeBuildFv (BootMode);
//[-end-190814-IB11270244-add]//
DEBUG((DEBUG_INFO, "PeiBootModeLib Exit of DetectBootModeLib, BootMode =0x%x\n", BootMode));
return BootMode;
}
//[-start-190724-IB11270244-remove]//
// /**
// Check Boot Flag Status to determine if previous boot was successful
// Boot Progress bit will be cleared before booting to OS/Shell/BIOS Setup
// or ResetSystem() been triggered while Fastboot enabled.
// @retval TRUE Previous Fast Boot was success.
// @retval FALSE Previous Fast Boot wasn't success.
// **/
// BOOLEAN
// EFIAPI
// IsPreviousFastBootCompleted (
// VOID
// )
// {
// UINT8 PreviousFastBootCompletionFlag;
// ///
// /// Get last Boot State Variable to confirm that it is not a first boot.
// ///
// if (!IsBootStatePresent()) {
// return FALSE;
// }
// PreviousFastBootCompletionFlag = 0;
// PreviousFastBootCompletionFlag = GetFastBootFlagStatus ();
// PreviousFastBootCompletionFlag &= FAST_BOOT_OR_MASK;
// if(PreviousFastBootCompletionFlag){
// DEBUG((DEBUG_INFO, "IsPreviousFastBootCompleted() returns FALSE as previous boot is still in progress \n"));
// return FALSE;
// }
// DEBUG ((DEBUG_INFO, "IsPreviousFastBootCompleted() return TRUE as previoius boot is successfully completed.\n"));
// return TRUE;
// }
//[-end-190724-IB11270244-remove]//
/**
Query PCH to determine if Intrusion Detection set
@retval TRUE No Change.
@retavl FALSE Change.
**/
BOOLEAN
EFIAPI
IsBootWithNoChange (
VOID
)
{
#if 1
EFI_STATUS Status;
BOOLEAN IsNoChange;
IsNoChange = FALSE;
//
// TODO : IsNoChange = SmartBoot
//
//
// OemServices
//
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcIsBootWithNoChange \n"));
Status = OemSvcIsBootWithNoChange (
&IsNoChange
);
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcIsBootWithNoChange Status: %r\n", Status));
if(Status != EFI_MEDIA_CHANGED) {
//
// Default setting
//
IsNoChange = FALSE;
}
return IsNoChange;
#else
EFI_STATUS Status;
UINT16 TcoBase;
UINT16 Tco2Status;
BOOLEAN BoxOpen;
DEBUG((DEBUG_INFO, "PeiBootModeLib IsBootWithNoChange Entry \n"));
CHASSIS_INTR_DET_HOB *ChassisIntrDetHob;
ChassisIntrDetHob = GetFirstGuidHob (&gChassisIntrudeDetHobGuid);
if (ChassisIntrDetHob == NULL) {
///
/// Create HOB for Chassis Intrusion Detection Status
///
Status = PeiServicesCreateHob (
EFI_HOB_TYPE_GUID_EXTENSION,
sizeof (CHASSIS_INTR_DET_HOB),
(VOID **) &ChassisIntrDetHob
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return FALSE;
}
DEBUG ((DEBUG_INFO, "Chassis Intrusion Detection Status HOB installed\n"));
//
// Initialize default HOB data
//
ZeroMem (&(ChassisIntrDetHob->Revision), (sizeof (CHASSIS_INTR_DET_HOB) - sizeof (EFI_HOB_GUID_TYPE)));
ChassisIntrDetHob->EfiHobGuidType.Name = gChassisIntrudeDetHobGuid;
ChassisIntrDetHob->Revision = 1;
}
DEBUG ((DEBUG_INFO, "Chassis Intrusion Detection HOB data updated\n"));
///
/// Read the TCO registers
///
TcoBase = (UINT16)PcdGet16 (PcdTcoBaseAddress);
Tco2Status = IoRead16 (TcoBase + R_TCO_IO_TCO2_STS);
///
/// This is the state of the hardware
///
BoxOpen = (BOOLEAN) (Tco2Status & B_TCO_IO_TCO2_STS_INTRD_DET);
if (BoxOpen) {
/// Record Chassis Intrusion Status in a Hob right before clearing it.
ChassisIntrDetHob->Status = 1;
///
/// Clear the bit for next boot.
///
Tco2Status |= B_TCO_IO_TCO2_STS_INTRD_DET;
IoWrite16 (TcoBase + R_TCO_IO_TCO2_STS, Tco2Status);
///
/// Since it was OPEN, return that it cannot be in "no config change boot"
///
DEBUG ((DEBUG_INFO, "PeiBootModeLib BoxOpen \n"));
return FALSE;
} else {
/// Record Chassis Intrusion Status in a Hob right before clearing it.
ChassisIntrDetHob->Status = 0;
///
/// Since it was CLOSED, return that can be "no config change boot"
/// Need variable to know that memory was tested AT LEAST one time!
///
if (IsBootStatePresent()) {
DEBUG ((DEBUG_INFO, "PeiBootModeLib BootState TRUE\n"));
return TRUE;
} else {
DEBUG ((DEBUG_INFO, "PeiBootModeLib BootState FALSE\n"));
return FALSE;
}
}
#endif
}
/**
Given the current boot mode, and a proposed new boot mode, determine
which has priority. If the new boot mode has higher priority, then
make it the current boot mode.
@param[in][out] CurrentBootMode Pointer to current planned boot mode
@param[in][out] NewBootMode Proposed boot mode.
@retval EFI_NOT_FOUND If either boot mode is not recognized.
@retval EFI_SUCCESS If both boot mode values were
recognized and were processed.
**/
EFI_STATUS
EFIAPI
PrioritizeBootMode (
IN OUT EFI_BOOT_MODE *CurrentBootMode,
IN EFI_BOOT_MODE NewBootMode
)
{
UINT32 CurrentIndex;
UINT32 NewIndex;
DEBUG((DEBUG_INFO, "PeiBootModeLib PrioritizeBootMode Entry \n"));
///
/// Find the position of the current boot mode in our priority array
///
for ( CurrentIndex = 0;
CurrentIndex < sizeof (mBootModePriority) / sizeof (mBootModePriority[0]);
CurrentIndex++) {
if (mBootModePriority[CurrentIndex] == *CurrentBootMode) {
break;
}
}
if (CurrentIndex >= sizeof (mBootModePriority) / sizeof (mBootModePriority[0])) {
return EFI_NOT_FOUND;
}
///
/// Find the position of the new boot mode in our priority array
///
for ( NewIndex = 0;
NewIndex < sizeof (mBootModePriority) / sizeof (mBootModePriority[0]);
NewIndex++) {
if (mBootModePriority[NewIndex] == NewBootMode) {
///
/// If this new boot mode occurs before the current boot mode in the
/// priority array, then take it.
///
if (NewIndex < CurrentIndex) {
*CurrentBootMode = NewBootMode;
DEBUG((DEBUG_INFO, "PeiBootModeLib NewIndex < CurrentIndex, Update PrioritizeBootMode CurrentBootMode: 0x%x \n", *CurrentBootMode));
}
else {
DEBUG((DEBUG_INFO, "PeiBootModeLib NewIndex > CurrentIndex Exit PrioritizeBootMode CurrentBootMode 0x%x \n", *CurrentBootMode));
}
return EFI_SUCCESS;
}
}
DEBUG((DEBUG_INFO, "PeiBootModeLib PrioritizeBootMode Exit\n"));
return EFI_NOT_FOUND;
}
/**
Check if this system boot is due to 4sec power button override has occurred
@retval TRUE Power Button Override occurred in last system boot
@retval FALSE Power Button Override didnt occur
**/
BOOLEAN
EFIAPI
IsPowerButtonOverride (
VOID
)
{
if (PmcIsPowerButtonOverrideDetected ()) {
DEBUG ((DEBUG_INFO, "IsPowerButtonOverride TRUE\n"));
return TRUE;
}
return FALSE;
}
/**
Check Fast Boot 30-second WDT (TCO Timer) timeout has occurred
@retval TRUE Timeout has occurred
@retval FALSE Timeout didnt occur
**/
BOOLEAN
IsTimeOutOccurred (
VOID
)
{
if (IoRead8 (PcdGet16 (PcdTcoBaseAddress) + R_TCO_IO_TWDS) == FAST_BOOT_WDT_RESET_SIGNATURE) {
IoWrite8 (PcdGet16 (PcdTcoBaseAddress) + R_TCO_IO_TWDS, 0);
DEBUG ((DEBUG_INFO, "IsTimeOutOccurred TRUE\n"));
return TRUE;
}
return FALSE;
}
/**
Check if the value is of ODD parity.
@param[in] Value The 8 bits value
@retval TRUE The value is of ODD parity
@retval FALSE The value is not of ODD parity
**/
BOOLEAN
CheckOddParity (
IN UINT8 Value
)
{
UINT8 OddNum;
UINT8 Index;
OddNum = 0;
for (Index = 0; Index < 8; Index++) {
if (Value & (1 << Index)) {
OddNum++;
}
}
return (BOOLEAN) (OddNum % 2 != 0);
}
//[-start-190829-IB17040083-add]//
/**
Perform firmware update failure detection
@param[in] None
@retval Returns TRUE if the previous firmware update failed, otherwise returns FALSE
**/
BOOLEAN
DetectFirmwareUpdateFailure (
VOID
)
{
CHAR16 RecoveryFile[MAX_STRING_LENGTH];
UINTN Size;
EFI_STATUS Status;
//[-start-211215-IB16810177-add]//
EFI_STATUS VarSecureFlashStatus;
EFI_STATUS VarCapsuleUpdateStatus;
//[-end-211215-IB16810177-add]//
//[-start-211215-IB16810177-modify]//
//[-start-211109-IB18410132-add]//
UINT64 OsIndications;
IMAGE_INFO ImageInfo;
EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiVar;
BOOLEAN DoingCapsuleOrSecureflash;
DoingCapsuleOrSecureflash = FALSE;
OsIndications = 0;
Status = PeiServicesLocatePpi (
&gEfiPeiReadOnlyVariable2PpiGuid,
0,
NULL,
(VOID **) &PeiVar
);
ASSERT_EFI_ERROR (Status);
Size = sizeof (IMAGE_INFO);
VarSecureFlashStatus = PeiVar->GetVariable (
PeiVar,
SECURE_FLASH_INFORMATION_NAME,
&gSecureFlashInfoGuid,
NULL,
&Size,
&ImageInfo
);
Size = sizeof(UINT64);
VarCapsuleUpdateStatus = PeiVar->GetVariable (
PeiVar,
L"OsIndications",
&gEfiGlobalVariableGuid,
NULL,
&Size,
&OsIndications
);
if (((VarCapsuleUpdateStatus == EFI_SUCCESS) && (OsIndications & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED)) || ((VarSecureFlashStatus == EFI_SUCCESS) && (ImageInfo.FlashMode == 1))) {
DoingCapsuleOrSecureflash = TRUE;
} else {
DoingCapsuleOrSecureflash = FALSE;
}
//[-end-211109-IB18410132-add]//
//[-end-211215-IB16810177-modify]//
//[-start-211109-IB18410132-modify]//
if (IsFirmwareFailureRecovery() || (IsFirmwareUpdateInterrupted() && DoingCapsuleOrSecureflash)) {
//[-end-211109-IB18410132-modify]//
//
// If the previous firmware update is not successful (FirmwareUpdateOngoing variable is not cleared),
// then update the recovery file path and update BootMode to activate recovery
//
UnicodeSPrint (RecoveryFile, MAX_STRING_LENGTH, L"%s\\%s1000.bin;%s\\isflash.bin", EFI_CAPSULE_FILE_PATH, EFI_CAPSULE_FILE_NAME, PcdGetPtr(PcdCapsuleImageFolder));
Size = StrSize(RecoveryFile);
Status = PcdSetPtrS (PcdPeiRecoveryFile, &Size, RecoveryFile);
ASSERT_EFI_ERROR (Status);
return TRUE;
//[-start-211109-IB18410132-add]//
} else {
if (SpiIsTopSwapEnabled () || (IsFirmwareUpdateInterrupted() && !DoingCapsuleOrSecureflash)) {
return TRUE;
}
//[-end-211109-IB18410132-add]//
}
return FALSE;
}
/**
Detect recovery mode
@retval EFI_SUCCESS System in Recovery Mode
@retval EFI_UNSUPPORTED System doesn't support Recovery Mode
@retval EFI_NOT_FOUND System is not in Recovery Mode
**/
EFI_STATUS
IsRecoveryMode (
VOID
)
{
EFI_STATUS Status;
BOOLEAN IsRecovery = FALSE;
//[-start-210505-IB16810152-add]//
BOOLEAN SwapState;
SwapState = FALSE;
//[-end-210505-IB16810152-add]//
//
// OemServices
//
//[-start-190723-IB17700055-modify]//
DEBUG_OEM_SVC ((EFI_D_INFO, "OemKernelServices Call: OemSvcDetectRecoveryRequest \n"));
Status = OemSvcDetectRecoveryRequest (
&IsRecovery
);
DEBUG_OEM_SVC ((EFI_D_INFO, "OemKernelServices OemSvcDetectRecoveryRequest Status: %r\n", Status));
//[-end-190723-IB17700055-modify]//
if (!IsRecovery) {
if (DetectFirmwareUpdateFailure()) {
return EFI_SUCCESS;
} else {
return EFI_NOT_FOUND;
}
}
//[-start-210505-IB16810152-modify]//
//[-start-211014-BAIN000051-add]//
//#ifdef LCFC_SUPPORT
//#if defined(C970_BSH_SUPPORT)
//[-start-21119-TAMT000032-modify]//
//[-start-211203-QINGLIN0125-modify]//
//[-start-211206-OWENWU0029-modify]//
//[-start-211214-Ching000017-modify]//
#if defined(C970_BSH_SUPPORT) || defined(C770_BSH_SUPPORT) || defined(S77014_BSH_SUPPORT) || defined(S370_BSH_SUPPORT) || defined(S570_BSH_SUPPORT) || defined(S77013_BSH_SUPPORT) || defined(S77014IAH_BSH_SUPPORT)
if((PcdGetBool(PcdL05BiosRecoveryHotkeyFlag))==TRUE) {
return EFI_SUCCESS;
}
#endif
//[-end-211214-Ching000017-modify]//
//[-end-211206-OWENWU0029-modify]//
//[-end-211203-QINGLIN0125-modify]//
//[-end-21119-TAMT000032-modify]//
//[-end-211014-BAIN000051-add]//
if (IsRecovery && (EFI_ERROR (Status))) {
if (PcdGet8(PcdChasmFallsSupport) == 2) {
TopSwapSet (TRUE);
SwapState = TopSwapStatus();
WriteExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, ChipsetRecoveryFlag, 0x00);
DEBUG ((DEBUG_ERROR, "Detect recovery mode with chasmfalls gen2 enable, top swap status %x\n", SwapState));
ResetCold();
} else {
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
//[-end-210505-IB16810152-modify]//
}
//[-end-190829-IB17040083-add]//
//[-start-190724-IB11270243-remove]//
///**
// Detect recovery mode
//
// Detect Jumper to determine if recovery mode is set
//
// @retval EFI_SUCCESS System in Recovery Mode
// @retval EFI_UNSUPPORTED System doesn't support Recovery Mode
// @retval EFI_NOT_FOUND System is not in Recovery Mode
//**/
//
//EFI_STATUS
//EFIAPI
//IsRecoveryMode (
// VOID
// )
//{
// BOOLEAN RecJumperFlag;
// UINT32 BitMask;
// EFI_STATUS Status;
// UINT32 RecoveryModeGpio;
// PCD64_BLOB Pcd64;
//
// if (PcdGet8 (PcdBoardType) == BoardTypeSv ||
// PcdGet8 (PcdBoardType) == BoardTypeRvpErb ||
// PcdGet8 (PcdPlatformFlavor) == FlavorUpServer) {
// return RETURN_UNSUPPORTED; /* No Recovery Jumper*/
// }
//
// RecoveryModeGpio = 0;
// Pcd64.Blob = PcdGet64 (PcdRecoveryModeGpio);
// if (Pcd64.Blob != 0 && Pcd64.BoardGpioConfig.Type == BoardGpioTypePch) {
// Status = GpioGetInputValue (Pcd64.BoardGpioConfig.u.Pin, &RecoveryModeGpio);
// ASSERT_EFI_ERROR (Status);
// if (EFI_ERROR (Status)) {
// return Status;
// }
// } else {
// DEBUG ((DEBUG_ERROR, "Invalid Recovery GPIO, PcdRecoveryModeGpio = 0x%x\n", PcdGet64 (PcdRecoveryModeGpio)));
// return EFI_NOT_FOUND;
// }
//
// BitMask = BIT0;
// RecJumperFlag = ((BOOLEAN)(!(RecoveryModeGpio & BitMask)));
// if (RecJumperFlag) {
// DEBUG ((DEBUG_INFO, "RecJumperFlag SET\n"));
// return EFI_SUCCESS;
// } else {
// DEBUG ((DEBUG_INFO, "RecJumperFlag NOT SET\n"));
// return EFI_NOT_FOUND;
// }
//}
//[-end-190724-IB11270243-remove]//