224 lines
6.0 KiB
C
224 lines
6.0 KiB
C
/** @file
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2019, 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.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include "ModernPreloadDxe.h"
|
|
|
|
/**
|
|
Get TPM Lock State.
|
|
|
|
@param L05TpmLockRegister Specifies the TPM lock register.
|
|
|
|
@retval EFI_SUCCESS The register was get from save state.
|
|
@retval EFI_UNSUPPORTED The register is not defined for the Save State.
|
|
**/
|
|
EFI_STATUS
|
|
GetTpmLockState (
|
|
IN OUT EFI_L05_TPM_LOCK_REGISTER *L05TpmLockRegister
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
#ifdef L05_SPECIFIC_VARIABLE_SERVICE_ENABLE
|
|
EFI_L05_VARIABLE_PROTOCOL *L05VariablePtr;
|
|
UINT32 DataLength;
|
|
UINT8 TpmLock;
|
|
#else
|
|
EFI_L05_EEPROM_MAP_120 EepromBuffer;
|
|
UINTN EepromBase;
|
|
UINTN EepromSize;
|
|
#endif
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
#ifdef L05_SPECIFIC_VARIABLE_SERVICE_ENABLE
|
|
L05VariablePtr = NULL;
|
|
|
|
Status = gBS->LocateProtocol (&gEfiL05VariableProtocolGuid, NULL, &L05VariablePtr);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
TpmLock = 0;
|
|
DataLength = sizeof (TpmLock);
|
|
|
|
//
|
|
// Get TPM Lock data
|
|
//
|
|
Status = L05VariablePtr->GetVariable (
|
|
L05VariablePtr,
|
|
&gL05TpmLockGuid,
|
|
&DataLength,
|
|
&TpmLock
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Get TPM Lock State
|
|
//
|
|
L05TpmLockRegister->Byte = TpmLock;
|
|
|
|
#else
|
|
ZeroMem (&EepromBuffer, sizeof (EepromBuffer));
|
|
EepromBase = (UINTN) FdmGetNAtAddr (&gL05H2OFlashMapRegionEepromGuid, 1);
|
|
EepromSize = (UINTN) FdmGetNAtSize (&gL05H2OFlashMapRegionEepromGuid, 1);
|
|
|
|
if ((EepromBase == 0) || (EepromSize == 0)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
//
|
|
// Get EEPROM data
|
|
//
|
|
CopyMem ((VOID *) &EepromBuffer, (VOID *) EepromBase, sizeof (EepromBuffer));
|
|
|
|
//
|
|
// Get TPM Lock State
|
|
//
|
|
L05TpmLockRegister->Byte = *EepromBuffer.TpmLock;
|
|
#endif
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Set TPM Lock Done flag to Setup variable.
|
|
|
|
@param L05TpmLockRegister TPM lock register.
|
|
|
|
@retval EFI_SUCCESS The operation completed successfully.
|
|
@retval Others An unexpected error occurred.
|
|
**/
|
|
EFI_STATUS
|
|
SetTpmLockDoneFlag (
|
|
EFI_L05_TPM_LOCK_REGISTER L05TpmLockRegister
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN BufferSize;
|
|
SYSTEM_CONFIGURATION SetupNvData;
|
|
|
|
BufferSize = sizeof (SYSTEM_CONFIGURATION);
|
|
Status = gRT->GetVariable (
|
|
L"Setup",
|
|
&gSystemConfigurationGuid,
|
|
NULL,
|
|
&BufferSize,
|
|
&SetupNvData
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (SetupNvData.L05TpmLockDone == (UINT8) L05TpmLockRegister.Bits.State) {
|
|
return Status;
|
|
}
|
|
|
|
SetupNvData.L05TpmLockDone = (UINT8) L05TpmLockRegister.Bits.State;
|
|
|
|
Status = gRT->SetVariable (
|
|
L"Setup",
|
|
&gSystemConfigurationGuid,
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
|
sizeof (SYSTEM_CONFIGURATION),
|
|
&SetupNvData
|
|
);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
This is the callback function after gEfiSetupUtilityProtocolGuid is installed.
|
|
It will set TPM lock done flag for BIOS setup used.
|
|
|
|
@param Event Event whose notification function is being invoked.
|
|
@param Context Pointer to the notification function's context.
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
ModernPreloadCallback (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
VOID *SetupUtility;
|
|
EFI_L05_TPM_LOCK_REGISTER L05TpmLockRegister;
|
|
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiSetupUtilityProtocolGuid,
|
|
NULL,
|
|
(VOID **) &SetupUtility
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return;
|
|
}
|
|
|
|
gBS->CloseEvent (Event);
|
|
|
|
ZeroMem (&L05TpmLockRegister, sizeof (EFI_L05_TPM_LOCK_REGISTER));
|
|
|
|
Status = GetTpmLockState (&L05TpmLockRegister);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// [BIOS and Tool Requirements for Modern Preload Support, Version 1.00 Draft]
|
|
// 1.4 BIOS Setup Items
|
|
// Requirements for BIOS Setup items related to TPM.
|
|
// Show "MFG MODE" when TPMLOCK is not Done.
|
|
//
|
|
Status = SetTpmLockDoneFlag (L05TpmLockRegister);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
Modern Preload DXE entry.
|
|
|
|
Lenovo Notebook to support Modern Preload (aka Cloud Preload) Platform Key generation in MFG.
|
|
The main reason is Modern Preload Platform Key generation need TPM PlatformAuth is NULL.
|
|
|
|
@param ImageHandle The firmware allocated handle for the UEFI image.
|
|
@param SystemTable A pointer to the EFI System Table.
|
|
|
|
@retval EFI_SUCCESS The operation completed successfully.
|
|
@retval Others An unexpected error occurred.
|
|
**/
|
|
EFI_STATUS
|
|
L05ModernPreloadDxeEntry (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
VOID *Registration;
|
|
|
|
Registration = NULL;
|
|
|
|
EfiCreateProtocolNotifyEvent (
|
|
&gEfiSetupUtilityProtocolGuid,
|
|
TPL_NOTIFY,
|
|
ModernPreloadCallback,
|
|
NULL,
|
|
&Registration
|
|
);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|