alder_lake_bios/Oem/L05/FeatureCommon/InsydeL05ModulePkg/Computrace/Dxe/L05Computrace.c

923 lines
24 KiB
C

/** @file
SPEC : Computrace implement requirement v1.2.doc
;******************************************************************************
;* Copyright (c) 2013 - 2016, 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 "L05Computrace.h"
EFI_EVENT AfterDiskInfoEvent;
VOID *DiskInfoEventRegistration;
EFI_EVENT L05ComputraceStartUpEvent;
VOID *L05ComputraceStartUpRegistration;
EFI_HANDLE mImageHandle = NULL_HANDLE;
UINT8 BatterySerialBuffer[L05_COMPUTRACE_SERIAL_LENGTH];
UINT8 HardDiskSerialBuffer[L05_COMPUTRACE_SERIAL_LENGTH];
UINT8 SystemSerialBuffer[L05_COMPUTRACE_SERIAL_LENGTH];
UINT32 ComputraceState;
VOID
EFIAPI
DiksInfoProtocolNotify (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
UINTN BufferSize;
EFI_HANDLE Handle;
EFI_DISK_INFO_PROTOCOL *DiskInfo;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
UINT32 IdDataSize;
EFI_IDENTIFY_DATA IdData;
Status = EFI_SUCCESS;
BufferSize = 0;
DiskInfo = NULL;
BlockIo = NULL;
IdDataSize = 0;
BufferSize = sizeof (EFI_HANDLE);
Status = gBS->LocateHandle (
ByRegisterNotify,
NULL,
DiskInfoEventRegistration,
&BufferSize,
&Handle
);
if (EFI_ERROR (Status)) {
return;
}
Status = gBS->HandleProtocol (
Handle,
&gEfiDiskInfoProtocolGuid,
&DiskInfo
);
if (EFI_ERROR (Status)) {
return;
}
Status = gBS->HandleProtocol (
Handle,
&gEfiBlockIoProtocolGuid,
&BlockIo
);
if (EFI_ERROR (Status)) {
return;
}
//
// Skip CD-ROM or other Removable Media
//
if (BlockIo->Media->RemovableMedia) {
return;
}
IdDataSize = sizeof (EFI_IDENTIFY_DATA);
ZeroMem (&IdData, sizeof (EFI_IDENTIFY_DATA));
Status = DiskInfo->Identify (DiskInfo, &IdData, &IdDataSize);
if (EFI_ERROR (Status)) {
return;
}
CopyMem (HardDiskSerialBuffer, IdData.AtaData.SerialNo, sizeof (IdData.AtaData.SerialNo));
gBS->CloseEvent (AfterDiskInfoEvent);
return;
}
EFI_STATUS
GetSystemSerial (
VOID
)
{
EFI_STATUS Status;
UINT8 Length;
Status = EFI_SUCCESS;
Length = L05_COMPUTRACE_SERIAL_LENGTH;
Status = OemSvcGetSystemSerial (&Length, SystemSerialBuffer);
return EFI_SUCCESS;
}
EFI_STATUS
GetBatterySerial (
VOID
)
{
EFI_STATUS Status;
UINT8 Length;
Status = EFI_SUCCESS;
Length = L05_COMPUTRACE_SERIAL_LENGTH;
Status = OemSvcGetBatterySerial (&Length, BatterySerialBuffer);
return EFI_SUCCESS;
}
EFI_STATUS
SyncComputraceStateWithSetup (
VOID
)
{
EFI_STATUS Status;
UINTN VarSize;
SYSTEM_CONFIGURATION SetupVariable;
Status = EFI_SUCCESS;
//
// Sync Computrace state with Setup varibale.
//
VarSize = sizeof (SYSTEM_CONFIGURATION);
Status = gRT->GetVariable (
L"Setup",
&gSystemConfigurationGuid,
NULL,
&VarSize,
&SetupVariable
);
if (EFI_ERROR (Status)) {
//
// Setup menu is default setting.
//
return Status;
}
if ((UINT8) ComputraceState != SetupVariable.ComputraceState) {
SetupVariable.ComputraceState = (UINT8) ComputraceState;
Status = gRT->SetVariable (
L"Setup",
&gSystemConfigurationGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
VarSize,
&SetupVariable
);
}
return Status;
}
EFI_STATUS
EFIAPI
LoadAndStartImage
(
IN EFI_HANDLE *ImageHandle,
IN EFI_GUID *ImageGuid
)
{
EFI_STATUS Status;
UINTN FvHandleCount;
EFI_HANDLE *FvHandleBuffer;
UINTN Index;
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
UINTN ImageSize;
EFI_FV_FILETYPE Type;
EFI_FV_FILE_ATTRIBUTES FvFileAttributes;
UINT32 AuthenticationStatus;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ImageNode;
EFI_HANDLE NewImageHandle;
UINTN ExitDataSize;
CHAR16 *ExitData;
//
//Get ComputraceComponents.efi
//
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiFirmwareVolume2ProtocolGuid,
NULL,
&FvHandleCount,
&FvHandleBuffer
);
if (EFI_ERROR (Status)) {
return Status;
}
for (Index = 0; Index < FvHandleCount; Index++) {
gBS->HandleProtocol (
FvHandleBuffer[Index],
&gEfiFirmwareVolume2ProtocolGuid,
(VOID **) &Fv
);
Status = Fv->ReadFile (
Fv,
ImageGuid,
NULL,
&ImageSize,
&Type,
&FvFileAttributes,
&AuthenticationStatus
);
if (EFI_ERROR (Status)) {
continue;
}
//
// Get FV device path.
//
DevicePath = DevicePathFromHandle (FvHandleBuffer[Index]);
//
// Get ComputraceComponents.efi device path.
//
EfiInitializeFwVolDevicepathNode (&ImageNode, ImageGuid);
//
// Append ComputraceComponents.efi device path to FV device path.
//
DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &ImageNode);
//
// Load ComputraceComponents.efi.
//
Status = gBS->LoadImage (
FALSE,
mImageHandle,
DevicePath,
NULL,
0,
&NewImageHandle
);
if (EFI_ERROR (Status)) {
break;
}
//
// Start ComputraceComponent.efi.
//
Status = gBS->StartImage (NewImageHandle, &ExitDataSize, &ExitData);
if (EFI_ERROR (Status)) {
break;
}
}
return Status;
}
EFI_STATUS
SaveL05ComputraceInfo (
IN EFI_L05_COMPUTRACE_AREA *L05ComputraceArea
)
{
EFI_STATUS Status;
UINTN DataLength;
UINTN L05ComputraceRegionBase;
UINTN L05ComputraceRegionSize;
EFI_SMM_FW_BLOCK_SERVICE_PROTOCOL *SmmFwb;
Status = EFI_SUCCESS;
DataLength = 0;
SmmFwb = NULL;
L05ComputraceRegionBase = (UINTN) FdmGetNAtAddr (&gL05H2OFlashMapRegionComputraceGuid, 1);
L05ComputraceRegionSize = (UINTN) FdmGetNAtSize (&gL05H2OFlashMapRegionComputraceGuid, 1);
if ((L05ComputraceRegionBase == (UINTN) L05_INVALID_VALUE) ||
(L05ComputraceRegionSize == (UINTN) L05_INVALID_VALUE)) {
return EFI_UNSUPPORTED;
}
Status = gBS->LocateProtocol (&gEfiSmmFwBlockServiceProtocolGuid, NULL, (VOID **) &SmmFwb);
if (EFI_ERROR (Status)) {
return Status;
}
Status = SmmFwb->EraseBlocks (SmmFwb, L05ComputraceRegionBase, &L05ComputraceRegionSize);
if (!EFI_ERROR (Status)) {
DataLength = MIN (L05ComputraceRegionSize, sizeof (EFI_L05_COMPUTRACE_AREA));
Status = SmmFwb->Write (
SmmFwb,
L05ComputraceRegionBase,
&DataLength,
(UINT8 *) L05ComputraceArea
);
}
return Status;
}
EFI_STATUS
GetL05ComputraceInfo (
IN OUT EFI_L05_COMPUTRACE_AREA *L05ComputraceArea
)
{
if (((UINTN) FdmGetNAtAddr (&gL05H2OFlashMapRegionComputraceGuid, 1) == (UINTN) L05_INVALID_VALUE) ||
((UINTN) FdmGetNAtSize (&gL05H2OFlashMapRegionComputraceGuid, 1) == (UINTN) L05_INVALID_VALUE)) {
return EFI_UNSUPPORTED;
}
CopyMem (L05ComputraceArea, (VOID *) (UINTN) FdmGetNAtAddr (&gL05H2OFlashMapRegionComputraceGuid, 1), sizeof (EFI_L05_COMPUTRACE_AREA));
return EFI_SUCCESS;
}
EFI_STATUS
GetComputraceState (
IN OUT UINT32 *EfiL05ComputraceState
)
{
EFI_STATUS Status;
EFI_L05_COMPUTRACE_AREA L05ComputraceArea;
Status = EFI_SUCCESS;
Status = GetL05ComputraceInfo (&L05ComputraceArea);
if (EFI_ERROR (Status)) {
return Status;
}
*EfiL05ComputraceState = L05ComputraceArea.ComputraceState;
return Status;
}
EFI_STATUS
SetComputraceState (
IN UINT32 *EfiL05ComputraceState
)
{
EFI_STATUS Status;
EFI_L05_COMPUTRACE_AREA L05ComputraceArea;
Status = EFI_SUCCESS;
switch (*EfiL05ComputraceState) {
case EFI_L05_COMPUTRACE_ENABLED:
Status = GetL05ComputraceInfo (&L05ComputraceArea);
if (EFI_ERROR (Status)) {
return Status;
}
break;
case EFI_L05_COMPUTRACE_DISABLED:
//
// Clear All Computrace Area when disable it.
//
SetMem (&L05ComputraceArea, sizeof (EFI_L05_COMPUTRACE_AREA), 0xFF);
break;
default:
return EFI_UNSUPPORTED;
}
L05ComputraceArea.ComputraceState = *EfiL05ComputraceState;
return SaveL05ComputraceInfo (&L05ComputraceArea);
}
/**
Check Erase Flag is exist or not.
@param None
@retval TRUE Erase Flag is exist.
@retval FALSE Erase Flag is not exist.
**/
BOOLEAN
IsExistingEraseFlag (
VOID
)
{
#ifdef L05_SPECIFIC_VARIABLE_SERVICE_ENABLE
EFI_STATUS Status;
EFI_L05_VARIABLE_PROTOCOL *L05VariablePtr;
UINT32 DataLength;
UINT8 ComputraceEraseFlag;
#else
UINTN EepromBase;
#endif
#ifdef L05_SPECIFIC_VARIABLE_SERVICE_ENABLE
Status = EFI_SUCCESS;
L05VariablePtr = NULL;
Status = gBS->LocateProtocol (&gEfiL05VariableProtocolGuid, NULL, &L05VariablePtr);
if (EFI_ERROR (Status)) {
return Status;
}
ComputraceEraseFlag = 0;
DataLength = sizeof (ComputraceEraseFlag);
Status = L05VariablePtr->GetVariable (
L05VariablePtr,
&gL05ComputraceEraseFlagGuid,
&DataLength,
&ComputraceEraseFlag
);
if (EFI_ERROR (Status)) {
return FALSE;
}
return (ComputraceEraseFlag == L05_ERASE_FLAG_ENABLE) ? TRUE : FALSE;
#else
EepromBase = (UINTN) FdmGetNAtAddr (&gL05H2OFlashMapRegionEepromGuid, 1);
if (EepromBase == 0) {
return FALSE;
}
return (((EFI_L05_EEPROM_MAP_120 *) EepromBase)->ComputraceEraseFlag[0] == L05_ERASE_FLAG_ENABLE) ? TRUE : FALSE;
#endif
}
/**
Clear Erase Flag.
@param None
@retval EFI_SUCCESS The operation completed successfully.
@retval Others An unexpected error occurred.
**/
EFI_STATUS
ClearEraseFlag (
VOID
)
{
EFI_STATUS Status;
#ifdef L05_SPECIFIC_VARIABLE_SERVICE_ENABLE
EFI_L05_VARIABLE_PROTOCOL *L05VariablePtr;
UINT8 ComputraceEraseFlag;
UINT32 DataLength;
#else
EFI_SMM_FW_BLOCK_SERVICE_PROTOCOL *SmmFwb;
UINTN EepromBase;
UINTN EepromSize;
UINT8 *EepromBuffer;
#endif
Status = EFI_SUCCESS;
#ifdef L05_SPECIFIC_VARIABLE_SERVICE_ENABLE
L05VariablePtr = NULL;
Status = gBS->LocateProtocol (&gEfiL05VariableProtocolGuid, NULL, &L05VariablePtr);
if (EFI_ERROR (Status)) {
return Status;
}
ComputraceEraseFlag = L05_ERASE_FLAG_DISABLE;
DataLength = sizeof (ComputraceEraseFlag);
Status = L05VariablePtr->SetVariable (
L05VariablePtr,
&gL05ComputraceEraseFlagGuid,
DataLength,
&ComputraceEraseFlag
);
if (EFI_ERROR (Status)) {
return Status;
}
#else
SmmFwb = NULL;
EepromBuffer = NULL;
Status = gBS->LocateProtocol (&gEfiSmmFwBlockServiceProtocolGuid, NULL, (VOID **) &SmmFwb);
if (EFI_ERROR (Status)) {
return Status;
}
EepromBase = (UINTN) FdmGetNAtAddr (&gL05H2OFlashMapRegionEepromGuid, 1);
EepromSize = (UINTN) FdmGetNAtSize (&gL05H2OFlashMapRegionEepromGuid, 1);
if ((EepromBase == 0) || (EepromSize == 0)) {
return EFI_UNSUPPORTED;
}
EepromBuffer = AllocatePages (EFI_SIZE_TO_PAGES (EepromSize));
if (EepromBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
ZeroMem (EepromBuffer, (EFI_SIZE_TO_PAGES (EepromSize) * EFI_PAGE_SIZE));
CopyMem (EepromBuffer, (VOID *) EepromBase, EepromSize);
((EFI_L05_EEPROM_MAP_120 *) EepromBuffer)->ComputraceEraseFlag[0] = L05_ERASE_FLAG_DISABLE;
Status = SmmFwb->EraseBlocks (SmmFwb, EepromBase, &EepromSize);
if (EFI_ERROR (Status)) {
return Status;
}
Status = SmmFwb->Write (SmmFwb, EepromBase, &EepromSize, EepromBuffer);
if (EFI_ERROR (Status)) {
return Status;
}
FreePages (EepromBuffer, EFI_SIZE_TO_PAGES (EepromSize));
#endif
return Status;
}
/**
Erase Computrace FV.
@param ComputraceFvBase Point to Computrace FV.
@param ComputraceFvSize Size of Computrace FV.
@retval EFI_SUCCESS The operation completed successfully.
@retval Others An unexpected error occurred.
**/
EFI_STATUS
EraseComputraceFv (
IN UINTN ComputraceFvBase,
IN UINTN ComputraceFvSize
)
{
EFI_STATUS Status;
EFI_SMM_FW_BLOCK_SERVICE_PROTOCOL *SmmFwb;
UINTN EraseSize;
Status = EFI_SUCCESS;
SmmFwb = NULL;
EraseSize = ComputraceFvSize;
Status = gBS->LocateProtocol (&gEfiSmmFwBlockServiceProtocolGuid, NULL, (VOID **) &SmmFwb);
if (EFI_ERROR (Status)) {
return Status;
}
Status = SmmFwb->EraseBlocks (SmmFwb, ComputraceFvBase, &EraseSize);
return Status;
}
/**
Check Computrace Erase Request.
@param None
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_ABORTED No need to do this operation.
@retval Others An unexpected error occurred.
**/
EFI_STATUS
CheckComputraceEraseRequest (
VOID
)
{
UINTN ComputraceFvBase;
UINTN ComputraceFvSize;
EFI_FIRMWARE_VOLUME_HEADER *Fvh;
ComputraceFvBase = 0;
ComputraceFvSize = 0;
Fvh = NULL;
//
// According to Lenovo Notebook Remove Computrace Requirement for PRC Version 1.32 draft
// 3. Compatible Design
//
//
// Step1: Check Erase Flag
//
if (!IsExistingEraseFlag ()) {
return EFI_ABORTED;
}
//
// Step2: Check Computrace FV already earsed or not
//
ComputraceFvBase = (UINTN) FdmGetAddressById (&gH2OFlashMapRegionFvGuid, &gL05H2OFlashMapRegionComputraceFvGuid, 1);
ComputraceFvSize = (UINTN) FdmGetSizeById (&gH2OFlashMapRegionFvGuid, &gL05H2OFlashMapRegionComputraceFvGuid, 1);
if ((ComputraceFvBase == 0) || (ComputraceFvSize == 0)) {
return EFI_UNSUPPORTED;
}
Fvh = (EFI_FIRMWARE_VOLUME_HEADER *) ComputraceFvBase;
if (Fvh->Signature != EFI_FVH_SIGNATURE) {
return EFI_SUCCESS;
}
//
// Step3: Check Computrace state is enabled & activated or not
//
if (ComputraceState == EFI_L05_COMPUTRACE_ENABLED) {
//
// Computrace state is enabled, so keep Computrace module in ROM
//
ClearEraseFlag ();
return EFI_ABORTED;
}
EraseComputraceFv (ComputraceFvBase, ComputraceFvSize);
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
//
// Waiting for system reset
//
CpuDeadLoop ();
return EFI_SUCCESS;
}
EFI_STATUS
L05ComputraceEntry (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
UINT16 SmiPort;
BOOLEAN ComputraceSupported;
SmiPort = 0;
mImageHandle = ImageHandle;
ComputraceSupported = TRUE;
Status = GetComputraceState (&ComputraceState);
if (EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
//
// According to Lenovo Notebook Remove Computrace Requirement for PRC Version 1.32 draft
// 2. Lenovo Requirements of Removing Computrace for PRC
// 2.2 SMB
// For SMB products, if Computrace function supported, then for the systems ship to PRC:
// - Computrace module such as efiinstnats.efi / efiinstnats64.efi MUST be completely removed from SPI rom.
// - Computrace SMM service code MUST be completely removed from SPI rom.
//
CheckComputraceEraseRequest ();
//
// Skip Computrace init if the OemSvc return platform doesn't support Computrace.
//
Status = OemSvcCheckComputraceSupportStatus (&ComputraceSupported);
if (Status == EFI_MEDIA_CHANGED && !ComputraceSupported) {
//
// If Computrace is Enabled, and then ComputraceSupportStatus changes to unsupported.
// The Computace string in SCU need to be hidden.
//
ComputraceState = EFI_L05_COMPUTRACE_DISABLED;
Status = SyncComputraceStateWithSetup ();
return EFI_SUCCESS;
}
//
// Check SMI port address in CMOS.
//
SmiPort = SW_SMI_PORT;
if (SmiPort != ReadCmos16 (EFI_L05_COMPUTRACE_CMOS_ADDRESS_LOW)) {
WriteCmos16 (EFI_L05_COMPUTRACE_CMOS_ADDRESS_LOW, SmiPort);
}
//
// Disable Computrace when first boot.
//
if (ComputraceState == EFI_L05_COMPUTRACE_NOT_SUPPORTED) {
ComputraceState = EFI_L05_COMPUTRACE_DISABLED;
SetComputraceState (&ComputraceState);
if (EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
}
Status = SyncComputraceStateWithSetup ();
if (EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
switch (ComputraceState) {
case EFI_L05_COMPUTRACE_ENABLING:
case EFI_L05_COMPUTRACE_ENABLED:
break;
default :
//
// Only need to continue when Computrace enabled.
//
return EFI_SUCCESS;
}
//
// Clear each serial buffer.
//
ZeroMem (BatterySerialBuffer, L05_COMPUTRACE_SERIAL_LENGTH);
ZeroMem (HardDiskSerialBuffer, L05_COMPUTRACE_SERIAL_LENGTH);
ZeroMem (SystemSerialBuffer, L05_COMPUTRACE_SERIAL_LENGTH);
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
DiksInfoProtocolNotify,
NULL,
&AfterDiskInfoEvent
);
if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
Status = gBS->RegisterProtocolNotify (
&gEfiDiskInfoProtocolGuid,
AfterDiskInfoEvent,
&DiskInfoEventRegistration
);
if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
//
// Register notify function to install WPBT on ReadyToBoot Event.
//
Status = EfiCreateEventReadyToBootEx (
TPL_CALLBACK,
L05ComputraceFunction,
NULL,
&L05ComputraceStartUpEvent
);
return Status;
}
EFI_STATUS
GetComputraceSerialCrc (
IN OUT VOID *EfiL05ComputraceSerialCrc
)
{
EFI_STATUS Status;
EFI_L05_COMPUTRACE_AREA L05ComputraceArea;
Status = EFI_SUCCESS;
Status = GetL05ComputraceInfo (&L05ComputraceArea);
if (EFI_ERROR (Status)) {
return Status;
}
CopyMem (EfiL05ComputraceSerialCrc, &L05ComputraceArea.ComputraceSerialCrc, sizeof (EFI_L05_COMPUTRACE_SERIAL_CRC));
return Status;
}
EFI_STATUS
SetComputraceSerialCrc (
IN VOID *EfiL05ComputraceSerialCrc
)
{
EFI_STATUS Status;
EFI_L05_COMPUTRACE_AREA L05ComputraceArea;
Status = EFI_SUCCESS;
Status = GetL05ComputraceInfo (&L05ComputraceArea);
if (EFI_ERROR (Status)) {
return Status;
}
CopyMem (&L05ComputraceArea.ComputraceSerialCrc, EfiL05ComputraceSerialCrc, sizeof (EFI_L05_COMPUTRACE_SERIAL_CRC));
return SaveL05ComputraceInfo (&L05ComputraceArea);
}
VOID
EFIAPI
L05ComputraceFunction (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
EFI_GUID DriverGuid = L05_COMPUTRACE_EFI_DRIVER_FILE_GUID;
//WOD EFI_GUID WpbtGuid = L05_COMPUTRACE_EFI_WPBT_FILE_GUID;
EFI_L05_COMPUTRACE_SERIAL_CRC SerialCrc;
UINT32 BatteryCrc;
UINT32 HardDiskCrc;
UINT32 SystemCrc;
Status = EFI_SUCCESS;
gBS->CloseEvent (Event);
GetBatterySerial ();
GetSystemSerial ();
gBS->CalculateCrc32 ((VOID *) BatterySerialBuffer, L05_COMPUTRACE_SERIAL_LENGTH, &BatteryCrc);
gBS->CalculateCrc32 ((VOID *) HardDiskSerialBuffer, L05_COMPUTRACE_SERIAL_LENGTH, &HardDiskCrc);
gBS->CalculateCrc32 ((VOID *) SystemSerialBuffer, L05_COMPUTRACE_SERIAL_LENGTH, &SystemCrc);
if (ComputraceState == EFI_L05_COMPUTRACE_ENABLING) {
//
// If Computrace was just enabled, we should store CRC of each serial.
//
SerialCrc.BatterySerialCrc = BatteryCrc;
SerialCrc.HardDiskSerialCrc = HardDiskCrc;
SerialCrc.SystemSerialCrc = SystemCrc;
SetComputraceSerialCrc (&SerialCrc);
if (EFI_ERROR (Status)) {
return;
}
//
// After CRCs are stored, change the Computrace state.
//
ComputraceState = EFI_L05_COMPUTRACE_ENABLED;
SetComputraceState (&ComputraceState);
if (EFI_ERROR (Status)) {
return;
}
} else {
GetComputraceSerialCrc (&SerialCrc);
if (EFI_ERROR (Status)) {
return;
}
//
// If all serials changes at the same time, we should auto-disable Computrace.
//
if ((BatteryCrc != SerialCrc.BatterySerialCrc) &&
(HardDiskCrc != SerialCrc.HardDiskSerialCrc) &&
(SystemCrc != SerialCrc.SystemSerialCrc)
) {
ComputraceState = EFI_L05_COMPUTRACE_DISABLED;
SetComputraceState (&ComputraceState);
if (EFI_ERROR (Status)) {
return;
}
Status = SyncComputraceStateWithSetup ();
if (EFI_ERROR (Status)) {
return;
}
}
}
//
// Prepare to load Computrace EFI Driver.
//
//WOD Status = LoadAndStartImage((EFI_HANDLE*)Context, &WpbtGuid);
Status = GetComputraceState (&ComputraceState);
if (!EFI_ERROR (Status) && (ComputraceState == EFI_L05_COMPUTRACE_ENABLED)) {
LoadAndStartImage ((EFI_HANDLE *) Context, &DriverGuid);
}
return;
}