alder_lake_bios/Intel/AlderLake/AlderLakePlatSamplePkg/Features/Rpe/RemotePlatformErase.c

665 lines
24 KiB
C

/**@file
Remote Platform Erase Implementation.
@copyright
INTEL CONFIDENTIAL
Copyright 2020 - 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 <Uefi.h>
#include <MeBiosPayloadHob.h>
#include <SetupVariable.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/UefiLib.h>
#include <Protocol/AmtWrapperProtocol.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/BaseLib.h>
#include <Library/DxeAmtHeciLib.h>
#include <Library/DxeAsfHeciLib.h>
#include <Library/TimerLib.h>
#include <AsfMsgs.h>
#include <Setup/MeSetup.h>
#include <Library/DxeAsfLib.h>
#include <PchResetPlatformSpecific.h>
#include "RpeAmtSupport.h"
#include "RpeEraseActions.h"
GLOBAL_REMOVE_IF_UNREFERENCED RPE_RESULT mRpeResult;
GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mRpeBoot;
/**
Check if Corporate firmware is installed
@retval TRUE The firmware is Corporate
@retval FALSE The firmware is NOT Corporate
**/
EFI_STATUS
IsCorporateFwInstalled (
VOID
)
{
ME_BIOS_PAYLOAD_HOB *MbpHob;
MbpHob = GetFirstGuidHob (&gMeBiosPayloadHobGuid);
if (MbpHob == NULL) {
return FALSE;
}
if ((MbpHob->MeBiosPayload.FwPlatType.Available) &&
(MbpHob->MeBiosPayload.FwPlatType.RuleData.Fields.IntelMeFwImageType == IntelMeCorporateFw)) {
DEBUG ((DEBUG_INFO, "RPE :: Installed CSME is a Corporate FW\n"));
return TRUE;
}
DEBUG ((DEBUG_INFO, "RPE :: Installed CSME is a Consumer FW, hence exiting the RPE Driver.\n"));
return FALSE;
}
/**
Checks if Remote Platform Erase is requested by AMT.
Note: Returns FALSE if both RSE and RPE are enabled.
@retval TRUE Remote Platform Erase was requested by AMT
@retval FALSE Remote Platform Erase wasn't requested by AMT
**/
BOOLEAN
IsRpeTriggeredByAmt (
VOID
)
{
if (AsfIsRemotePlatformEraseEnabled ()) {
DEBUG ((DEBUG_INFO, "RPE :: Requested by AMT.\n"));
if (AsfIsSecureEraseEnabled ()) {
DEBUG ((DEBUG_ERROR, "RPE: Aborting RPE as SecureErase is Enabled.\n"));
return FALSE;
}
return TRUE;
}
return FALSE;
}
/**
Get the RPE status from BIOS setup menu and from AMT. If AMT is not in sync with BIOS setup status
then inform AMT via "ASF_SetUEFIBootOptionsState" MEI Command with BIOS status.
If RPE is Enabled and Admin triggers the RPE boot via AMT then continue to perform erase actions.
Abort the Driver if RPE is disabled. In this case, if RPE boot is set, then update AMT with BIOS
Status report and PET logs with Error information.
@retval TRUE Remote Platform Erase is enabled and requested by AMT.
@retval FALSE Either Remote Platform Erase is disabled or not requested by AMT.
**/
BOOLEAN
IsRpeEnabledAndTriggeredByAmt (
VOID
)
{
EFI_STATUS Status;
ME_SETUP MeSetup;
UINTN VariableSize;
AMT_BOOT_CONTROL AmtBootControl;
BOOLEAN IsAmtRpeTriggered;
IsAmtRpeTriggered = FALSE;
//
// Read the BIOS Setup Variable to check if RPE is enabled.
//
VariableSize = sizeof (ME_SETUP);
Status = gRT->GetVariable (
L"MeSetup",
&gMeSetupVariableGuid,
NULL,
&VariableSize,
&MeSetup
);
if (EFI_ERROR (Status)) {
return FALSE;
}
//
// Read the Amt Boot Control Structure
//
Status = AsfGetUefiBootOptionsState (&AmtBootControl);
if (EFI_ERROR (Status)) {
return FALSE;
}
//
// BIOS passes the state of user enabled boot option to AMT, if AMT is out of sync with BIOS.
//
if (AmtBootControl.Bits.RemotePlatformErase != (BOOLEAN) MeSetup.EnableRpe) {
AmtBootControl.Bits.RemotePlatformErase = (BOOLEAN) MeSetup.EnableRpe;
AsfSetUefiBootOptionsState (AmtBootControl);
}
//
// If RPE is enabled in BIOS, return RPE status in AMT GetBootOption status.
//
IsAmtRpeTriggered = IsRpeTriggeredByAmt ();
if (MeSetup.EnableRpe == 1) { // Check if RPE is enabled in BIOS Setup.
return IsAmtRpeTriggered; // Returns TRUE if AMT has triggered the RPE Actions.
}
//
// If RPE is disabled in BIOS but AMT has still initiated RPE:
// BIOS shall send BIOSLastStatus with Failure and also send PET message with failure.
//
if (IsAmtRpeTriggered) {
DEBUG ((DEBUG_ERROR, "RPE: AMT initiated RPE, but feature is disabled from BIOS. Reporting failure to AMT\n"));
Status = ReportBiosStatus (AsfRbsGeneralFailure);
SendRpePetAlert (ASF_RPE_EVENT_DATA3_BOOT_PARAMETER_RECEIVE_FAILED, 0, ASF_RPE_EVENT_OFFSET_FAILURE);
}
return FALSE;
}
/**
Function to trigger all platform supported RPE actions.
@param[in] BiosRpeBootParameters BIOS RPE Boot Option parameters.
@retval EFI_SUCCESS. Operation is successful.
**/
EFI_STATUS
TriggerEraseActions (
IN BIOS_RPE_BOOT_PARAMETERS *BiosRpeBootParameters
)
{
EFI_STATUS Status;
UINTN Index;
UINT32 ActionItem;
UINT32 PendingRpeActionItems;
//
// Order of Erase Actions.
//
static const UINT32 OrderOfOperation [] = {
RPE_SECURE_ERASE_ALL_SSD,
RPE_TPM_CLEAR,
RPE_BIOS_RELOAD_GOLDEN_CONFIG
};
DEBUG ((DEBUG_INFO, "Platform Erase: EraseActionsToTrigger = %x\n", BiosRpeBootParameters->EraseActionsToTrigger));
for ( Index = 0;
Index < sizeof (OrderOfOperation) / sizeof (OrderOfOperation [0]);
Index++) {
if (BiosRpeBootParameters->ActionInProgress == TRUE) {
// Continue with the RPE Erase Action from previous boot.
ActionItem = BiosRpeBootParameters->LastActionBeforeReboot;
Index--; // Ignore one For Loop Iteration for performing the last action triggered in previous boot.
} else {
// Perform the action item as per the priority order.
ActionItem = OrderOfOperation[Index] & BiosRpeBootParameters->EraseActionsToTrigger;
}
switch (ActionItem) {
//
// SSD Erase Action
//
case RPE_SECURE_ERASE_ALL_SSD:
if (mRpeBoot) {
SendRpePetAlert (ASF_RPE_EVENT_DATA3_STARTED_ERASING_DEVICE, ASF_RPE_EVENT_DATA4_SSD_ERASE_ACTION, ASF_RPE_EVENT_OFFSET_PROGRESS);
// Set BIOS_LastStatus = 1 (InProgress)
ReportBiosStatus (AsfRbsInProgress);
}
// Register SSD Erase Action as an event to be performed in BDS Phase.
Status = RegisterRpeSsdEraseEvent ();
DEBUG ((DEBUG_INFO, "Platform Erase: SSD Erase Register Event Status = %r\n", Status));
if (Status == EFI_SUCCESS) {
// Success case here implies - registered SSD Erase Action as an event to be performed in BDS Phase.
// Forcefully returing EFI_NOT_READY to skip other actions, exit this DXE driver and continue booting to
// BDS Phase to perform SSD Erase.
DEBUG ((DEBUG_INFO, "Platform Erase: SSD Erase Action: Registered for BDS Phase Execution.\n"));
return EFI_NOT_READY;
} else if ((Status == EFI_UNSUPPORTED) && mRpeBoot) {
SendRpePetAlert (ASF_RPE_EVENT_DATA3_ERASING_DEVICE_UNSUPPORTED, ASF_RPE_EVENT_DATA4_SSD_ERASE_ACTION, ASF_RPE_EVENT_OFFSET_FAILURE);
} else if (mRpeBoot) {
SendRpePetAlert (ASF_RPE_EVENT_DATA3_ERROR_ERASING_DEVICE, ASF_RPE_EVENT_DATA4_SSD_ERASE_ACTION, ASF_RPE_EVENT_OFFSET_FAILURE);
}
// Decrement the SSD Erase Action BitMask in BiosRpeBootParameters and update to NVRAM.
DecrementBiosRpeBootParameter (BiosRpeBootParameters, RPE_SECURE_ERASE_ALL_SSD, Status);
break;
//
// TPM Clear Action
//
case RPE_TPM_CLEAR:
if (mRpeBoot) {
SendRpePetAlert (ASF_RPE_EVENT_DATA3_STARTED_ERASING_DEVICE, ASF_RPE_EVENT_DATA4_TPM_ERASE_ACTION, ASF_RPE_EVENT_OFFSET_PROGRESS);
// Set BIOS_LastStatus = 1 (InProgress)
ReportBiosStatus (AsfRbsInProgress);
}
//Trigger TPM clear erase action.
Status = TriggerTpmClear ();
DEBUG ((DEBUG_INFO, "Platform Erase: TPM Clear Action Status = %r\n", Status));
if ((Status == EFI_SUCCESS) && mRpeBoot) {
SendRpePetAlert (ASF_RPE_EVENT_DATA3_DEVICE_ERASED_SUCCESSFULLY, ASF_RPE_EVENT_DATA4_TPM_ERASE_ACTION, ASF_RPE_EVENT_OFFSET_PROGRESS);
} else if ((Status == EFI_NOT_READY) && mRpeBoot) {
// EFI_NOT_READY implies - registered TPM clear erase as an event to be performed at end of DXE after TCG2 Protocol execution.
// Forcefully returing EFI_NOT_READY to skip other actions, exit this DXE driver and perform operation at end of DXE.
DEBUG ((DEBUG_INFO, "Platform Erase: TPM Clear Action Registered for End of Dxe Execution.\n"));
return EFI_NOT_READY;
} else if ((Status == EFI_UNSUPPORTED) && mRpeBoot) {
SendRpePetAlert (ASF_RPE_EVENT_DATA3_ERASING_DEVICE_UNSUPPORTED, ASF_RPE_EVENT_DATA4_TPM_ERASE_ACTION, ASF_RPE_EVENT_OFFSET_FAILURE);
} else if (mRpeBoot) {
SendRpePetAlert (ASF_RPE_EVENT_DATA3_ERROR_ERASING_DEVICE, ASF_RPE_EVENT_DATA4_TPM_ERASE_ACTION, ASF_RPE_EVENT_OFFSET_FAILURE);
}
// Decrement the TPM Clear Action BitMask in BiosRpeBootParameters and update to NVRAM.
DecrementBiosRpeBootParameter (BiosRpeBootParameters, RPE_TPM_CLEAR, Status);
break;
//
// Reload BIOS Golden Config Action
//
case RPE_BIOS_RELOAD_GOLDEN_CONFIG:
PendingRpeActionItems = (BiosRpeBootParameters->CsmeEraseActionBitMask & RPE_CAPABILITY_SUPPORT) &
~RPE_SUPPORTED &
~RPE_BIOS_RELOAD_GOLDEN_CONFIG;
if (PendingRpeActionItems != 0) {
if (BiosRpeBootParameters->CurrentRetry < BiosRpeBootParameters->MaxRetries-1) {
break;
}
}
if (mRpeBoot) {
SendRpePetAlert (ASF_RPE_EVENT_DATA3_STARTED_ERASING_DEVICE, ASF_RPE_EVENT_DATA4_RELOAD_BIOS_GOLDEN_CONFIG, ASF_RPE_EVENT_OFFSET_PROGRESS);
// Set BIOS_LastStatus = 1 (InProgress)
ReportBiosStatus (AsfRbsInProgress);
}
// Reload the NvData Variables specified in the mUserDataVariableList with default values.
Status = SetBiosNvDataDefaultConfig ();
DEBUG ((DEBUG_INFO, "Platform Erase: BIOS Clear Status = %r\n", Status));
if ((Status == EFI_SUCCESS) && mRpeBoot) {
SendRpePetAlert (ASF_RPE_EVENT_DATA3_DEVICE_ERASED_SUCCESSFULLY, ASF_RPE_EVENT_DATA4_RELOAD_BIOS_GOLDEN_CONFIG, ASF_RPE_EVENT_OFFSET_PROGRESS);
} else if ((Status == EFI_UNSUPPORTED) && mRpeBoot) {
SendRpePetAlert (ASF_RPE_EVENT_DATA3_ERASING_DEVICE_UNSUPPORTED, ASF_RPE_EVENT_DATA4_RELOAD_BIOS_GOLDEN_CONFIG, ASF_RPE_EVENT_OFFSET_FAILURE);
} else if (mRpeBoot) {
SendRpePetAlert (ASF_RPE_EVENT_DATA3_ERROR_ERASING_DEVICE, ASF_RPE_EVENT_DATA4_RELOAD_BIOS_GOLDEN_CONFIG, ASF_RPE_EVENT_OFFSET_FAILURE);
}
// Decrement the Reload BIOS Config Action BitMask in BiosRpeBootParameters and update to NVRAM.
DecrementBiosRpeBootParameter (BiosRpeBootParameters, RPE_BIOS_RELOAD_GOLDEN_CONFIG, Status);
// Default variable settings will be loaded only after system reset, so if any Setup variables accessed later to this, it will fail and cause ASSERT
gRT->ResetSystem (EfiResetCold, Status, 0, NULL);
break;
default:
// Continue to next For loop iteration, as this action is not triggered by CSME.
break;
} // End of Switch Case
} // End of For loop.
//
// One iteration of all RPE Actions completed.
// Check for any failed action items to perform retry.
//
PendingRpeActionItems = (BiosRpeBootParameters->CsmeEraseActionBitMask & RPE_CAPABILITY_SUPPORT) & ~RPE_SUPPORTED;
if (PendingRpeActionItems != 0) {
// Prepare the BIOS_RPE_PARAMETERS structure for the next iteration and update to NVRAM.
BiosRpeBootParameters->CurrentRetry++;
BiosRpeBootParameters->EraseActionsToTrigger = BiosRpeBootParameters->CsmeEraseActionBitMask & RPE_CAPABILITY_SUPPORT;
StoreBiosRpeBootParameter (BiosRpeBootParameters);
if (mRpeBoot) {
// Set BIOS_LastStatus = 1 (InProgress)
ReportBiosStatus (AsfRbsInProgress);
DEBUG ((DEBUG_ERROR, "Platform Erase: Some of the EraseActions Failed: Rebooting System to retry.\n"));
}
// Perform reset to retry failed RPE Actions.
gRT->ResetSystem (EfiResetWarm, Status, 0, NULL);
// Control should not come here.
CpuDeadLoop ();
}
//
// Control will reach here only if, all RPE Actions are completed successfully.
//
// Delete "BiosRpeBootParameters" NVRAM Data
DeleteBiosRpeBootParameters ();
//
// Report RPE Actions completed status to AMT.
//
SendRpePetAlert (ASF_RPE_EVENT_DATA3_ALL_SETTINGS_DECREMENTED, 0, ASF_RPE_EVENT_OFFSET_PROGRESS);
ReportBiosStatus (AsfRbsSuccess);
// Inform CSME to clear RPE Boot. So that the next boot will be Normal Boot.
ClearBootOptions ();
return EFI_SUCCESS;
}
/**
Function to trigger Global Reset.
**/
VOID
IssueGlobalReset (
VOID
)
{
PCH_RESET_DATA ResetData;
CopyMem (&ResetData.Guid, &gPchGlobalResetGuid, sizeof (EFI_GUID));
StrCpyS (ResetData.Description, PCH_RESET_DATA_STRING_MAX_LENGTH, PCH_PLATFORM_SPECIFIC_RESET_STRING);
gRT->ResetSystem (EfiResetPlatformSpecific, EFI_SUCCESS, sizeof (PCH_RESET_DATA), &ResetData);
}
/**
Register callback function to display messages.
@param[in] Event The Event this notify function registered to.
@param[in] Context Pointer to the context data registered to the Event.
**/
VOID
EFIAPI
RpeGraphicsOutputCallback (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
VOID *Interface;
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
DEBUG ((DEBUG_INFO, "Platform Erase: %a enter.\n", __FUNCTION__));
Interface = NULL;
//
// Try to locate gEfiGraphicsOutputProtocolGuid once for registration.
// Return if it is not found.
//
Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, NULL, &Interface);
if (EFI_ERROR (Status)) {
return;
}
if (mRpeResult == RpeNotRequired) {
return;
}
//
// Make sure GraphicsOutput and SimpleTextOut are installed to display messages.
//
Status = gBS->HandleProtocol (
gST->ConsoleOutHandle,
&gEfiGraphicsOutputProtocolGuid,
(VOID**)&GraphicsOutput
);
if (EFI_ERROR (Status)) {
GraphicsOutput = NULL;
}
Status = gBS->HandleProtocol (
gST->ConsoleOutHandle,
&gEfiSimpleTextOutProtocolGuid,
(VOID**)&SimpleTextOut
);
if (EFI_ERROR (Status)) {
SimpleTextOut = NULL;
}
if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {
return;
}
gBS->CloseEvent (Event);
InitUiLib ();
switch (mRpeResult) {
case RpeAllSuccess:
gST->ConOut->OutputString (gST->ConOut, L"All RPE Actions are completed. System requires restart.");
MicroSecondDelay (5000000);
// Perform global reset after completing RPE actions
IssueGlobalReset ();
CpuDeadLoop ();
break;
case RpeCsmeUnconfigFail:
gST->ConOut->OutputString (gST->ConOut, L"CSME Unconfiguration failed. Rebooting the system in 5 seconds...");
MicroSecondDelay (5000000);
// Perform global reset after completing CSME Unconfigure
IssueGlobalReset ();
CpuDeadLoop ();
break;
default:
break;
}
}
/**
This function is to perform CSME unconfigure operation for Platform Erase
**/
VOID
CsmeUnconfigureAndSendStatus (
VOID
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "Entering to Perform CSME Unconfigure.\n"));
SendRpePetAlert (ASF_RPE_EVENT_DATA3_STARTED_ERASING_DEVICE, ASF_RPE_EVENT_DATA4_CSME_UNCONFIGURE, ASF_RPE_EVENT_OFFSET_PROGRESS);
ReportBiosStatus (AsfRbsInProgress);
//
// Send Heci command to CSME to perform CSME Unconfigure. When CSME Unconfigure is successfull, CSME issue a gloabl reset.
//
DEBUG ((DEBUG_INFO, "Platform Erase: Performing CSME Unconfiguration Flow. This might take up to 60 seconds.\n"));
//
// Inform CSME to clear boot options just before CSME unconfigure. So that the next boot will be Normal Boot
//
Status = ClearBootOptions ();
if (EFI_ERROR(Status)) {
DEBUG ((DEBUG_ERROR, "Platform Erase: Failed to ClearBootOptions.\n"));
}
Status = RpeCsmeUnconfigure ();
if (Status == EFI_SUCCESS) {
//In case of Success control won't come here since CSME issues a global reset, however Global reset is issued here for safe reboot
DEBUG ((DEBUG_INFO, "Platform Erase: CSME Unconfigure action is Success.\n"));
IssueGlobalReset ();
} else if (Status == EFI_UNSUPPORTED) {
DEBUG ((DEBUG_INFO, "Platform Erase: CSME Unconfigure action is Unsupported.\n"));
SendRpePetAlert (ASF_RPE_EVENT_DATA3_ERASING_DEVICE_UNSUPPORTED, ASF_RPE_EVENT_DATA4_CSME_UNCONFIGURE, ASF_RPE_EVENT_OFFSET_FAILURE);
ReportBiosStatus (AsfRbsGeneralFailure);
}
else {
DEBUG ((DEBUG_INFO, "Platform Erase: Failed to perform CSME Unconfigure action.\n"));
SendRpePetAlert (ASF_RPE_EVENT_DATA3_ERROR_ERASING_DEVICE, ASF_RPE_EVENT_DATA4_CSME_UNCONFIGURE, ASF_RPE_EVENT_OFFSET_FAILURE);
ReportBiosStatus (AsfRbsGeneralFailure);
}
}
/**
This function is to Initialize Platform Erase Operation
@param[in] BiosRpeBootParameters BIOS RPE Boot Option parameters.
@retval EFI_SUCCESS Secure erase procedure has been started
@retval EFI_ABORTED Failed to register ready to boot event
@retval EFI_UNSUPPORTED Feature is not supported by the FW
**/
EFI_STATUS
EFIAPI
InitializePlatformErase (
IN BIOS_RPE_BOOT_PARAMETERS *BiosRpeBootParameters
)
{
EFI_STATUS Status;
VOID *Registration;
mRpeResult = RpeNotRequired;
//
// Initialize the BiosRpeBootParameters Structure with ASF_BootParameters for RPE.
//
// Checks if BIOS_RPE_BOOT_PARAMETERS exists in NVRAM from previous RPE Erase Action Reboot.
// If exists:
// Update the BiosRpeBootParameters structure with NVRAM Data.
// If doesn't exist:
// - Send PET Alert : BEGIN_PLATFORM_ERASE
// - Update the BiosRpeBootParameters structure with BootParameters from ASF.
// If Fails: Send PET Alert : BOOT_PARAMETER_RECEIVE_FAILED
// - Store the BiosRpeBootParameters structure to NVRAM.
//
Status = RpeInitialize (BiosRpeBootParameters);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "Exiting Platform Erase : UNSUPPORTED\n"));
// Delete BIOS RPE NVRAM Structure.
DeleteBiosRpeBootParameters ();
FreePool (BiosRpeBootParameters);
return EFI_UNSUPPORTED;
}
//
// Register callback function for display message.
//
EfiCreateProtocolNotifyEvent (
&gEfiGraphicsOutputProtocolGuid,
TPL_CALLBACK,
RpeGraphicsOutputCallback,
NULL,
&Registration
);
return Status;
}
/**
RPE Driver's Entry Point.
Checks for CSME FW support, RPE Boot and if RPE boot is set, then perform the erase operations
as per erase action items set by CSME FW - ASF Boot settings.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS Secure erase procedure has been started
@retval EFI_ABORTED Failed to register ready to boot event
@retval EFI_UNSUPPORTED Feature is not supported by the FW
**/
EFI_STATUS
EFIAPI
RemotePlatformEraseEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
BIOS_RPE_BOOT_PARAMETERS *BiosRpeBootParameters;
mRpeBoot = FALSE;
DEBUG ((DEBUG_INFO, "Remote Platform Erase EntryPoint\n"));
// Create Empty BiosRpeBootParameters Structure, to locally store RPE Variables from CSME.
BiosRpeBootParameters = AllocateZeroPool (sizeof (BIOS_RPE_BOOT_PARAMETERS));
if (BiosRpeBootParameters == NULL) {
DEBUG ((DEBUG_ERROR, "Platform Erase: BiosRpeBootParameters EFI_OUT_OF_RESOURCES.\n"));
return EFI_OUT_OF_RESOURCES;
}
if (!IsCorporateFwInstalled ()) {
return EFI_UNSUPPORTED;
}
//
// Check if Remote Platform Erase is enabled from the BIOS Setup and Triggered by AMT.
//
if (IsRpeEnabledAndTriggeredByAmt ()) {
DEBUG ((DEBUG_INFO, "Platform Erase: Entering into Remote Platform Erase Actions.\n"));
mRpeBoot = TRUE;
} else if (AsfIsConfigurationDataResetEnabled ()) {
CsmeUnconfigureAndSendStatus ();
} else {
// Remote Platform Erase Not Requested, Aborting and continuing with normal boot.
DEBUG ((DEBUG_INFO, "Platform Erase: Erase actions are not Triggered, Exiting the Driver.\n"));
return EFI_SUCCESS;
}
//
// Starting RPE Operations.
//
Status = InitializePlatformErase (BiosRpeBootParameters);
DEBUG ((DEBUG_INFO, "Platform Erase: InitializePlatformErase Status : %r\n", Status));
//
// Triggers RPE Actions after checking the below conditions:
// Retries happens across boots.
//
// 1. Gets the CurrentRetry Value from NVRAM, if exist.
// 2. Send BIOS_LastStatus (In Progress)
// 3. Check if (CurrentRetry Count < MaxRetry):
// - Proceed with RPE Action.
// 4. CurrentRetry Count >= MaxRetry value:
// - Send PET Event (Max Retries Reached)
// - Set BIOS_LastStatus = 0 (Success)
// - Clear RPE Boot options and Boot Parameters.
// - Delete "BiosRpeBootParameters" NVRAM Data
//
if (CheckAmtRpeRetryCondition (BiosRpeBootParameters)) {
Status = TriggerEraseActions (BiosRpeBootParameters);
if (Status == EFI_SUCCESS) {
DEBUG ((DEBUG_INFO, "Platform Erase: All actions completed.\n"));
mRpeResult = RpeAllSuccess;
}
} else {
// Delete "BiosRpeBootParameters" NVRAM Data
DeleteBiosRpeBootParameters ();
//
// Inform CSME to clear RPE Boot. So that the next boot will be Normal Boot
//
Status = ClearBootOptions ();
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Platform Erase: Failed to ClearBootOptions.\n"));
}
}
DEBUG ((DEBUG_INFO, "Platform Erase Exit\n"));
FreePool (BiosRpeBootParameters);
return EFI_SUCCESS;
}