alder_lake_bios/Lcfc/LfcPkg/ChgBootDxeHook/ChgBootDxeHook.c

2078 lines
64 KiB
C

/** @file
Function Service for L05 Setup Menu
;******************************************************************************
;* Copyright (c) 2013 - 2015, Insyde Software Corporation. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include <Uefi.h>
#include <OemSwSmi.h>
#include <SmiTable.h>
#include <L05Config.h>
#include <SetupConfig.h>
#include <KernelSetupConfig.h>
#include <Guid/DebugMask.h>
#include <Guid/EventGroup.h>
#include <Guid/GlobalVariable.h>
#include <Guid/AdmiSecureBoot.h>
#include <Guid/LfcVariableGuid.h>
#include <Guid/H2OBdsCheckPoint.h>
#include <Protocol/BlockIo.h>
#include <Protocol/UsbIo.h>
#include <Protocol/UsbCore.h>
#include <Protocol/LegacyBios.h>
#include <Protocol/DevicePath.h>
#include <Protocol/L05SetupMenu.h>
#include <Protocol/LenovoVariable.h>
#include <Protocol/L05SecureBoot.h>
#include <Protocol/SimpleFileSystem.h>
#include <Library/IoLib.h>
#include <Library/UefiLib.h>
#include <Library/LfcEcLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseLib.h>
#include <Library/PrintLib.h>
#include <Library/DevicePathLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/GenericBdsLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#define LCFC_BOOT_TYPE_EFI_NETWORK_IPV4 ((0xE0)* 256 + BBS_EMBED_NETWORK)
#define LCFC_BOOT_TYPE_EFI_NETWORK_IPV6 ((0xE0)* 256 + BBS_EMBED_NETWORK + 1)
EFI_OVERRIDE_DEFAULT_SETUP_SETTING mOrgOverrideDefaultSetupSetting;
EFI_OVERRIDE_SETUP_SETTING_DURING_POST mOrgOverrideSetupSettingDuringPost;
//[-start-210514-BAINTEST-remove]//
//EFI_OVERRIDE_DEFAULT_PCH_SETUP_SETTING mOrgOverrideDefaultPchSetupSetting;
//[-end-210514-BAINTEST-remove]//
STATIC DUMMY_BOOT_OPTION_INFO mLcfcDummyBootOptionTable[] = {
{DummyUsbBootOptionNum, L"EFI USB Device"},
{DummyCDBootOptionNum, L"EFI DVD/CDROM"},
{DummyNetwokrBootOptionNum, L"EFI Network"}
};
typedef enum {
LcfcFirstBoot = 1,
LcfcSetChgboot,
LcfcF9LoadDefault
} LcfcOverrideDefaultReason;
VOID *
EFIAPI
LcfcBdsLibGetVariableAndSize (
IN CHAR16 *Name,
IN EFI_GUID *VendorGuid,
OUT UINTN *VariableSize
)
{
EFI_STATUS Status;
UINTN BufferSize;
VOID *Buffer;
Buffer = NULL;
//
// Pass in a zero size buffer to find the required buffer size.
//
BufferSize = 0;
Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
if (Status == EFI_BUFFER_TOO_SMALL) {
//
// Allocate the buffer to return
//
Buffer = AllocateZeroPool (BufferSize);
if (Buffer == NULL) {
*VariableSize = 0;
return NULL;
}
//
// Read variable into the allocated buffer.
//
Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
if (EFI_ERROR (Status)) {
BufferSize = 0;
gBS->FreePool (Buffer);
Buffer = NULL;
}
}
*VariableSize = BufferSize;
return Buffer;
}
EFI_STATUS
LcfcBootOrderSetDefault (
VOID
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT16 *BootOrderList = NULL;
UINTN BootOrderSize = 0;
UINT16 *PhyBootOrderList = NULL;
UINTN PhyBootOrderSize = 0;
BootOrderList = NULL;
BootOrderSize = 0;
Status = gRT->SetVariable (
L"BootOrder",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
BootOrderSize,
BootOrderList
);
PhyBootOrderList = NULL;
PhyBootOrderSize = 0;
Status = gRT->SetVariable (
L"PhysicalBootOrder",
&gEfiGenericVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
PhyBootOrderSize,
PhyBootOrderList
);
return Status;
}
BOOLEAN
LcfcIsUsbMemoryDevice (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePathPtr
)
{
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
EFI_DEVICE_PATH_PROTOCOL *UsbDevicePath;
EFI_STATUS Status;
EFI_BLOCK_IO_PROTOCOL *BlkIo;
EFI_HANDLE Handle;
BOOLEAN IsUsbMemory;
TempDevicePath = NULL;
UsbDevicePath = NULL;
BlkIo = NULL;
IsUsbMemory = FALSE;
TempDevicePath = DevicePathPtr;
UsbDevicePath = DevicePathPtr;
//
// 1. Check the device whether it is usb device or not
// 2. Use BlockIO to check Usb memory device
// 3. if the device is usb memory, exit the loop
//
while (!IsDevicePathEndType (TempDevicePath) && IsUsbMemory == FALSE) {
switch (DevicePathType (TempDevicePath)) {
case MESSAGING_DEVICE_PATH:
switch (DevicePathSubType(TempDevicePath)) {
case MSG_USB_DP:
Status = gBS->LocateDevicePath (
&gEfiDevicePathProtocolGuid,
&UsbDevicePath,
&Handle
);
if (!EFI_ERROR(Status)) {
Status = gBS->HandleProtocol (
Handle,
&gEfiBlockIoProtocolGuid,
&BlkIo
);
if (!EFI_ERROR(Status)) {
if (BlkIo->Media->RemovableMedia == TRUE) {
IsUsbMemory = TRUE;
break;
}
}
}
break;
default:
break;
}
break;
default:
break;
}
TempDevicePath = NextDevicePathNode (TempDevicePath);
}
if (IsUsbMemory) {
return TRUE;
} else {
return FALSE;
}
}
EFI_STATUS
LcfcDevicePathToBootType (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePathPtr,
OUT UINT16 *BootType
)
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_DEVICE_PATH_PROTOCOL *DevicePathNode = NULL;
EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL;
EFI_DEVICE_PATH_PROTOCOL *DevicePathTemp = NULL;
UINTN SATAPort = 0;
BOOLEAN IsUsbDevice = FALSE;
BOOLEAN Found = FALSE;
UINTN HandleCount;
EFI_HANDLE *HandleBuffer;
UINTN UsbMassDevicesCount;
UINTN Index;
UINTN Index2;
EFI_USB_CORE_PROTOCOL *UsbCore;
USB_MASS_STORAGE_DEVICE **UsbMassDevices;
EFI_USB_IO_PROTOCOL *UsbIoInstance;
EFI_FILE_PROTOCOL *FileSystem;
*BootType = L05_BOOT_TYPE_EFI_UNKNOWN;
//
// Check the device path to find which type it is
//
DevicePathNode = DevicePathPtr;
while (!IsDevicePathEnd (DevicePathNode)) {
if ((DevicePathType (DevicePathNode) == BBS_DEVICE_PATH) &&
(DevicePathSubType (DevicePathNode) == BBS_BBS_DP)) {
*BootType = L05_BOOT_TYPE_NON_EFI;
break;
} else if ((DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH) &&
(DevicePathSubType (DevicePathNode) == MSG_USB_DP)) {
IsUsbDevice = TRUE;
} else if ((DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH) &&
(DevicePathSubType (DevicePathNode) == MSG_SATA_DP)) {
SATAPort = ((SATA_DEVICE_PATH*)DevicePathNode)->HBAPortNumber;
} else if (((DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH) &&
(DevicePathSubType (DevicePathNode) == MSG_IPv4_DP))) {
*BootType = LCFC_BOOT_TYPE_EFI_NETWORK_IPV4;
}else if (((DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH) &&
(DevicePathSubType (DevicePathNode) == MSG_IPv6_DP))) {
*BootType = LCFC_BOOT_TYPE_EFI_NETWORK_IPV6;
break;
} else if ((DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) &&
(DevicePathSubType (DevicePathNode) == MEDIA_HARDDRIVE_DP)) {
if (IsUsbDevice) {
*BootType = L05_BOOT_TYPE_EFI_USB_HDD;
if (LcfcIsUsbMemoryDevice(DevicePathPtr)) {
*BootType = L05_BOOT_TYPE_EFI_USB_MEMORY;
}
} else {
*BootType = L05_BOOT_TYPE_EFI_HARDDISK;
}
break;
} else if ((DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) &&
(DevicePathSubType (DevicePathNode) == MEDIA_CDROM_DP)) {
if (IsUsbDevice) {
*BootType = L05_BOOT_TYPE_EFI_USB_CDROM;
} else {
*BootType = L05_BOOT_TYPE_EFI_CDROM;
}
break;
} else if ((DevicePathType (DevicePathNode) == ACPI_DEVICE_PATH) &&
(EISA_ID_TO_NUM(((ACPI_HID_DEVICE_PATH*)DevicePathNode)->HID) == 0x0604)) {
*BootType = L05_BOOT_TYPE_EFI_FLOPPY;
break;
}
DevicePathNode = NextDevicePathNode (DevicePathNode);
}
//
// Only for checking USB floppy
//
FileSystem = NULL;
if (IsUsbDevice == TRUE && *BootType == L05_BOOT_TYPE_EFI_UNKNOWN) {
Status = gBS->LocateProtocol (&gEfiUsbCoreProtocolGuid, NULL, &UsbCore);
if (EFI_ERROR(Status)) {
return Status;
}
Status = UsbCore->GetUsbDevices (
USB_CORE_USB_MASS_STORAGE,
&UsbMassDevicesCount,
(USB_DEVICE***) &UsbMassDevices
);
if (EFI_ERROR(Status)) {
return Status;
}
gBS->LocateHandleBuffer (
ByProtocol,
&gEfiUsbIoProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
for (Index = 0; Index < HandleCount; Index ++)
{
gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiUsbIoProtocolGuid,
&UsbIoInstance
);
for (Index2 = 0; Index2 < UsbMassDevicesCount; Index2 ++)
{
if (UsbMassDevices[Index2]->UsbIo == UsbIoInstance) {
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiDevicePathProtocolGuid,
(VOID *) &DevicePath
);
if (EFI_ERROR(Status)) {
continue;
}
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiSimpleFileSystemProtocolGuid,
(VOID *) &FileSystem
);
if (EFI_ERROR(Status)) {
continue;
}
DevicePathNode = DevicePathPtr;
while (!IsDevicePathEnd (DevicePathNode)) {
Found = FALSE;
DevicePathTemp = DevicePath;
while (!IsDevicePathEnd (DevicePathTemp)) {
if (CompareMem (DevicePathNode, DevicePathTemp, *((UINT16 *)(DevicePathNode->Length))) == 0) {
Found = TRUE;
break;
}
DevicePathTemp = NextDevicePathNode (DevicePathTemp);
}
if (!Found) {
break;
}
DevicePathNode = NextDevicePathNode (DevicePathNode);
}
if (Found) {
if (UsbMassDevices[Index2]->Media->RemovableMedia &&
(UsbMassDevices[Index2]->Transport->Protocol == USB_MASS_STORE_CBI0 ||
UsbMassDevices[Index2]->Transport->Protocol == USB_MASS_STORE_CBI1)) {
*BootType = L05_BOOT_TYPE_EFI_USB_FLOPPY;
}
}
}
}
}
}
return Status;
}
EFI_STATUS
LcfcChgBootSetPxeToFirst (
IN OUT SYSTEM_CONFIGURATION *SetupVariable,
IN OUT UINT8 *pRebootType
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT16 *BootOrderList = NULL;
UINTN BootOrderSize = 0;
UINT8 BootOrderCount = 0;
UINT16 *TmpBootOrderList = NULL;
UINTN TmpBootOrderSize = 0;
UINT8 TmpBootOrderCount = 0;
UINT16 *PhyBootOrderList = NULL;
UINTN PhyBootOrderSize = 0;
UINT8 PhyBootOrderCount = 0;
UINT16 *TmpPhyBootOrderList = NULL;
UINTN TmpPhyBootOrderSize = 0;
UINT8 TmpPhyBootOrderCount = 0;
CHAR16 BootString[10];
UINT8 *Buffer = NULL;
UINTN BufferSize = 0;
UINT8 *Ptr = NULL;
UINT16 DevicePathSize = 0;
UINTN Index = 0;
UINTN Index2 = 0;
BBS_TABLE *BbsItem = NULL;
UINT16 DeviceType = 0;
CHAR16 *DeviceName = NULL;
UINTN DeviceNameSize = 0;
EFI_DEVICE_PATH_PROTOCOL *DevicePathPtr = NULL;
UINT8 BootOrderIndex = 0x00;
UINT8 TmpBootOrderIndex = 0x00;
UINT8 PhyBootOrderIndex = 0x00;
UINT8 TmpPhyBootOrderIndex = 0x00;
UINT8 UefiFirstIndex;
UINT8 UefiLanIndex[2];
UINT8 LegacyLanIndex;
UINT8 LegacyFirstIndex;
UINT8 ChgBootDefaultTypeData = 0;
UINTN ChgBootDefaultTypeDataSize = sizeof (ChgBootDefaultTypeData);
Status = gRT->GetVariable (
L"ChgBootSetPxeToFirst",
&gLfcVariableGuid,
NULL,
&ChgBootDefaultTypeDataSize,
&ChgBootDefaultTypeData
);
if(!EFI_ERROR (Status)) {
*pRebootType = 1; // 1: EfiResetCold; 2: EfiResetWarm
Status = gRT->SetVariable (
L"ChgBootSetPxeToFirst",
&gLfcVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
&ChgBootDefaultTypeData
);
} else {
return EFI_UNSUPPORTED;
}
UefiFirstIndex = 0xFF;
UefiLanIndex[0] = 0xFF;
UefiLanIndex[1] = 0xFF;
LegacyLanIndex = 0xFF;
LegacyFirstIndex = 0xFF;
BootOrderList = LcfcBdsLibGetVariableAndSize (
L"BootOrder",
&gEfiGlobalVariableGuid,
&BootOrderSize
);
if((BootOrderList == NULL) || (BootOrderSize == 0)) {
return EFI_UNSUPPORTED;
}
PhyBootOrderList = LcfcBdsLibGetVariableAndSize (
L"PhysicalBootOrder",
&gEfiGenericVariableGuid,
&PhyBootOrderSize
);
if((PhyBootOrderList == NULL) || (PhyBootOrderSize == 0)) {
if(BootOrderList != NULL) {
gBS->FreePool (BootOrderList);
BootOrderList = NULL;
}
return EFI_UNSUPPORTED;
}
BootOrderCount = (UINT8)(BootOrderSize/sizeof(UINT16));
for(BootOrderIndex = 0; BootOrderIndex < BootOrderCount; BootOrderIndex++) {
ZeroMem(BootString, sizeof(BootString));
CopyMem (BootString, L"Boot", 4 * sizeof (CHAR16));
//[-start-210514-BAINTEST-modify]//
// UnicodeValueToStringS (&(BootString[4]), PREFIX_ZERO | RADIX_HEX, BootOrderList[BootOrderIndex], 4);
UnicodeValueToStringS (&(BootString[4]), 4 * sizeof (CHAR16), PREFIX_ZERO | RADIX_HEX, BootOrderList[BootOrderIndex], 4);
//[-end-210514-BAINTEST-modify]//
Buffer = LcfcBdsLibGetVariableAndSize (
BootString,
&gEfiGlobalVariableGuid,
&BufferSize
);
if((Buffer == NULL) || (BufferSize == 0)) {
continue;
}
Ptr = (UINT8 *) Buffer;
Ptr += sizeof (UINT32); // skip Load Option Attributes
DevicePathSize = *((UINT16 *) Ptr);
Ptr += sizeof (UINT16); // skip DevicePathSize
DeviceName = (CHAR16 *) Ptr;
DeviceNameSize = StrSize ((UINT16 *) Ptr);
Ptr += DeviceNameSize; // skip Device Name String
DevicePathPtr = (EFI_DEVICE_PATH_PROTOCOL*) Ptr;
Ptr += DevicePathSize; // skip Device Path
//
// Check if the device is EFI device or not.
//
Status = LcfcDevicePathToBootType (DevicePathPtr, &DeviceType);
if (DeviceType == L05_BOOT_TYPE_NON_EFI) {
// Legacy Device
BbsItem = (BBS_TABLE*)Ptr;
DeviceType = BbsItem->DeviceType;
Ptr += sizeof (BBS_TABLE);
Index = *((UINT16*)Ptr);
if(LegacyFirstIndex == 0xFF) {
LegacyFirstIndex = BootOrderIndex;
}
if((DeviceType == BBS_BEV_DEVICE) || (DeviceType == BBS_EMBED_NETWORK)) {
for(Index2 = 0; Index2 < (DeviceNameSize - 2); Index2++) {
if((DeviceName[Index2] == L'P') && (DeviceName[Index2 + 1] == L'X') && (DeviceName[Index2 + 2] == L'E')) {
if(LegacyLanIndex == 0xFF) {
LegacyLanIndex = BootOrderIndex;
break;
}
}
}
}
} else {
// UEFI Device
if(UefiFirstIndex == 0xFF) {
UefiFirstIndex = BootOrderIndex;
}
for(Index2 = 0; Index2 < (sizeof(mLcfcDummyBootOptionTable)/sizeof(DUMMY_BOOT_OPTION_INFO)); Index2++) {
if (StrnCmp (mLcfcDummyBootOptionTable[Index2].Description, DeviceName, StrLen (mLcfcDummyBootOptionTable[Index2].Description)) == 0) {
if(BootOrderList[BootOrderIndex] == DummyNetwokrBootOptionNum) {
if(UefiLanIndex[0] == 0xFF) {
UefiLanIndex[0] = BootOrderIndex;
}
}
}
}
}
if(Buffer != NULL) {
gBS->FreePool(Buffer);
Buffer = NULL;
}
}
TmpBootOrderList = NULL;
TmpBootOrderSize = BootOrderSize;
TmpBootOrderList = (UINT16 *)AllocateZeroPool (TmpBootOrderSize);
if(TmpBootOrderList == NULL) {
if(BootOrderList != NULL) {
gBS->FreePool (BootOrderList);
BootOrderList = NULL;
}
if(PhyBootOrderList != NULL) {
gBS->FreePool (PhyBootOrderList);
PhyBootOrderList = NULL;
}
return EFI_UNSUPPORTED;
}
TmpBootOrderCount = (UINT8)(TmpBootOrderSize/sizeof(UINT16));
BootOrderCount = (UINT8)(BootOrderSize/sizeof(UINT16));
for(TmpBootOrderIndex = 0; TmpBootOrderIndex < TmpBootOrderCount; TmpBootOrderIndex++) {
for(BootOrderIndex = 0; BootOrderIndex < BootOrderCount; BootOrderIndex++) {
if(BootOrderList[BootOrderIndex] == 0xFFFF) {
continue;
}
if(TmpBootOrderIndex == UefiFirstIndex) {
if(UefiLanIndex[0] != 0xFF) {
TmpBootOrderList[TmpBootOrderIndex] = BootOrderList[UefiLanIndex[0]];
BootOrderList[UefiLanIndex[0]] = 0xFFFF;
break;
}
}
if(TmpBootOrderIndex == LegacyFirstIndex) {
if(LegacyLanIndex != 0xFF) {
TmpBootOrderList[TmpBootOrderIndex] = BootOrderList[LegacyLanIndex];
BootOrderList[LegacyLanIndex] = 0xFFFF;
break;
}
}
TmpBootOrderList[TmpBootOrderIndex] = BootOrderList[BootOrderIndex];
BootOrderList[BootOrderIndex] = 0xFFFF;
break;
}
}
UefiFirstIndex = 0xFF;
UefiLanIndex[0] = 0xFF; // For IPv4 Network
UefiLanIndex[1] = 0xFF; // For IPv6 Network
LegacyLanIndex = 0xFF;
LegacyFirstIndex = 0xFF;
PhyBootOrderCount = (UINT8)(PhyBootOrderSize/sizeof(UINT16));
for(PhyBootOrderIndex = 0; PhyBootOrderIndex < PhyBootOrderCount; PhyBootOrderIndex++) {
ZeroMem(BootString, sizeof(BootString));
CopyMem (BootString, L"Boot", 4 * sizeof (CHAR16));
//[-start-210514-BAINTEST-modify]//
// UnicodeValueToStringS (&(BootString[4]), PREFIX_ZERO | RADIX_HEX, PhyBootOrderList[PhyBootOrderIndex], 4);
UnicodeValueToStringS (&(BootString[4]), 4 * sizeof (CHAR16), PREFIX_ZERO | RADIX_HEX, PhyBootOrderList[PhyBootOrderIndex], 4);
//[-end-210514-BAINTEST-modify]//
Buffer = LcfcBdsLibGetVariableAndSize (
BootString,
&gEfiGlobalVariableGuid,
&BufferSize
);
if((Buffer == NULL) || (BufferSize == 0)) {
continue;
}
Ptr = (UINT8 *) Buffer;
Ptr += sizeof (UINT32); // skip Load Option Attributes
DevicePathSize = *((UINT16 *) Ptr);
Ptr += sizeof (UINT16); // skip DevicePathSize
DeviceNameSize = StrSize ((UINT16 *) Ptr);
DeviceName = (VOID*)Ptr;
Ptr += DeviceNameSize; // skip Device Name String
DevicePathPtr = (VOID*)Ptr;
Ptr += DevicePathSize; // skip Device Path
//
// Check if the device is EFI device or not.
//
Status = LcfcDevicePathToBootType (DevicePathPtr, &DeviceType);
if (DeviceType == L05_BOOT_TYPE_NON_EFI) {
// Legacy Device
BbsItem = (BBS_TABLE*) Ptr;
DeviceType = BbsItem->DeviceType;
Ptr += sizeof (BBS_TABLE);
Index = *((UINT16*)Ptr);
if(LegacyFirstIndex == 0xFF) {
LegacyFirstIndex = PhyBootOrderIndex;
}
if((DeviceType == BBS_BEV_DEVICE) || (DeviceType == BBS_EMBED_NETWORK)) {
for(Index2 = 0; Index2 < (DeviceNameSize - 2); Index2++) {
if((DeviceName[Index2] == L'P') && (DeviceName[Index2 + 1] == L'X') && (DeviceName[Index2 + 2] == L'E')) {
if(LegacyLanIndex == 0xFF) {
LegacyLanIndex = PhyBootOrderIndex;
break;
}
}
}
}
} else {
// UEFI Device
if(UefiFirstIndex == 0xFF) {
UefiFirstIndex = PhyBootOrderIndex;
}
if(DeviceType == LCFC_BOOT_TYPE_EFI_NETWORK_IPV4) {
if (UefiLanIndex[0] == 0xFF) {
UefiLanIndex[0] = PhyBootOrderIndex;
}
}
if(DeviceType == LCFC_BOOT_TYPE_EFI_NETWORK_IPV6) {
if (UefiLanIndex[1] == 0xFF) {
UefiLanIndex[1] = PhyBootOrderIndex;
}
}
}
if(Buffer != NULL) {
gBS->FreePool(Buffer);
Buffer = NULL;
}
}
TmpPhyBootOrderList = NULL;
TmpPhyBootOrderSize = PhyBootOrderSize;
TmpPhyBootOrderList = (UINT16 *)AllocateZeroPool (TmpPhyBootOrderSize);
if(TmpPhyBootOrderList == NULL) {
if(BootOrderList != NULL) {
gBS->FreePool (BootOrderList);
BootOrderList = NULL;
}
if(TmpBootOrderList != NULL) {
gBS->FreePool (TmpBootOrderList);
TmpBootOrderList = NULL;
}
if(PhyBootOrderList != NULL) {
gBS->FreePool (PhyBootOrderList);
PhyBootOrderList = NULL;
}
return EFI_UNSUPPORTED;
}
TmpPhyBootOrderCount = (UINT8)(TmpPhyBootOrderSize/sizeof(UINT16));
PhyBootOrderCount = (UINT8)(PhyBootOrderSize/sizeof(UINT16));
for(TmpPhyBootOrderIndex = 0; TmpPhyBootOrderIndex < TmpPhyBootOrderCount; TmpPhyBootOrderIndex++) {
for(PhyBootOrderIndex = 0; PhyBootOrderIndex < PhyBootOrderCount; PhyBootOrderIndex++) {
if(PhyBootOrderList[PhyBootOrderIndex] == 0xFFFF) {
continue;
}
if(TmpPhyBootOrderIndex == UefiFirstIndex) {
if(SetupVariable->L05PxeIpv4First == 1) {
if(UefiLanIndex[0] != 0xFF) {
TmpPhyBootOrderList[TmpPhyBootOrderIndex] = PhyBootOrderList[UefiLanIndex[0]];
PhyBootOrderList[UefiLanIndex[0]] = 0xFFFF;
break;
}
} else {
if(UefiLanIndex[1] != 0xFF) {
TmpPhyBootOrderList[TmpPhyBootOrderIndex] = PhyBootOrderList[UefiLanIndex[1]];
PhyBootOrderList[UefiLanIndex[1]] = 0xFFFF;
break;
}
}
}
if(TmpPhyBootOrderIndex == (UefiFirstIndex + 1)) {
if(SetupVariable->L05PxeIpv4First == 0) {
if(UefiLanIndex[0] != 0xFF) {
TmpPhyBootOrderList[TmpPhyBootOrderIndex] = PhyBootOrderList[UefiLanIndex[0]];
PhyBootOrderList[UefiLanIndex[0]] = 0xFFFF;
break;
}
} else {
if(UefiLanIndex[1] != 0xFF) {
TmpPhyBootOrderList[TmpPhyBootOrderIndex] = PhyBootOrderList[UefiLanIndex[1]];
PhyBootOrderList[UefiLanIndex[1]] = 0xFFFF;
break;
}
}
}
if(TmpPhyBootOrderIndex == LegacyFirstIndex) {
if(LegacyLanIndex != 0xFF) {
TmpPhyBootOrderList[TmpPhyBootOrderIndex] = PhyBootOrderList[LegacyLanIndex];
PhyBootOrderList[LegacyLanIndex] = 0xFFFF;
break;
}
}
TmpPhyBootOrderList[TmpPhyBootOrderIndex] = PhyBootOrderList[PhyBootOrderIndex];
PhyBootOrderList[PhyBootOrderIndex] = 0xFFFF;
break;
}
}
Status = gRT->SetVariable (
L"BootOrder",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
TmpBootOrderSize,
TmpBootOrderList
);
Status = gRT->SetVariable (
L"PhysicalBootOrder",
&gEfiGenericVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
TmpPhyBootOrderSize,
TmpPhyBootOrderList
);
if(BootOrderList != NULL) {
gBS->FreePool (BootOrderList);
BootOrderList = NULL;
}
if(TmpBootOrderList != NULL) {
gBS->FreePool (TmpBootOrderList);
TmpBootOrderList = NULL;
}
if(PhyBootOrderList != NULL) {
gBS->FreePool (PhyBootOrderList);
PhyBootOrderList = NULL;
}
if(TmpPhyBootOrderList != NULL) {
gBS->FreePool (TmpPhyBootOrderList);
TmpPhyBootOrderList = NULL;
}
return Status;
}
EFI_STATUS
LcfcChgBootSetEfiPxeOneTime (
IN OUT SYSTEM_CONFIGURATION *SetupVariable,
IN OUT UINT8 *pRebootType
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT16 *PhyBootOrderList = NULL;
UINTN PhyBootOrderSize = 0;
UINT8 PhyBootOrderCount = 0;
UINT8 PhyBootOrderIndex = 0;
UINT16 *LfcBootNext = NULL;
UINTN LfcBootNextSize = 0;
CHAR16 BootString[10];
UINT8 *Buffer = NULL;
UINTN BufferSize = 0;
UINT8 *Ptr = NULL;
UINT16 DevicePathSize = 0;
UINT16 DeviceType = 0;
CHAR16 *DeviceName = NULL;
UINTN DeviceNameSize = 0;
EFI_DEVICE_PATH_PROTOCOL *DevicePathPtr = NULL;
UINT8 ChgBootDefaultTypeData = 0;
UINTN ChgBootDefaultTypeDataSize = sizeof (ChgBootDefaultTypeData);
UINT8 UefiLanIndex[2];
UefiLanIndex[0] = 0xFF; // For EFI IpV4
UefiLanIndex[1] = 0xFF; // For EFI IpV6
PhyBootOrderList = LcfcBdsLibGetVariableAndSize (
L"PhysicalBootOrder",
&gEfiGenericVariableGuid,
&PhyBootOrderSize
);
if((PhyBootOrderList == NULL) || (PhyBootOrderSize == 0)) {
return EFI_UNSUPPORTED;
}
Status = gRT->GetVariable (
L"ChgBootSetEfiPxeOneTime",
&gLfcVariableGuid,
NULL,
&ChgBootDefaultTypeDataSize,
&ChgBootDefaultTypeData
);
if(!EFI_ERROR (Status)) {
gRT->SetVariable (
L"ChgBootSetEfiPxeOneTime",
&gLfcVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
&ChgBootDefaultTypeData
);
}
//BootType = 0:Dual Boot, 2:EFI Boot
if(EFI_ERROR (Status) || (SetupVariable->BootType != 2)) {
if(PhyBootOrderList != NULL) {
gBS->FreePool (PhyBootOrderList);
PhyBootOrderList = NULL;
}
return EFI_UNSUPPORTED;
}
PhyBootOrderCount = (UINT8)(PhyBootOrderSize/sizeof(UINT16));
for(PhyBootOrderIndex = 0; PhyBootOrderIndex < PhyBootOrderCount; PhyBootOrderIndex++) {
ZeroMem(BootString, sizeof(BootString));
CopyMem (BootString, L"Boot", 4 * sizeof (CHAR16));
//[-start-210514-BAINTEST-modify]//
// UnicodeValueToStringS (&(BootString[4]), PREFIX_ZERO | RADIX_HEX, PhyBootOrderList[PhyBootOrderIndex], 4);
UnicodeValueToStringS (&(BootString[4]), 4 * sizeof (CHAR16), PREFIX_ZERO | RADIX_HEX, PhyBootOrderList[PhyBootOrderIndex], 4);
//[-end-210514-BAINTEST-modify]//
Buffer = LcfcBdsLibGetVariableAndSize (
BootString,
&gEfiGlobalVariableGuid,
&BufferSize
);
if((Buffer == NULL) || (BufferSize == 0)) {
continue;
}
Ptr = (UINT8 *) Buffer;
Ptr += sizeof (UINT32); // skip Load Option Attributes
DevicePathSize = *((UINT16 *) Ptr);
Ptr += sizeof (UINT16); // skip DevicePathSize
DeviceNameSize = StrSize ((UINT16 *) Ptr);
DeviceName = (VOID*)Ptr;
Ptr += DeviceNameSize; // skip Device Name String
DevicePathPtr = (VOID*)Ptr;
Ptr += DevicePathSize; // skip Device Path
//
// Check if the device is EFI device or not.
//
Status = LcfcDevicePathToBootType (DevicePathPtr, &DeviceType);
// UEFI Device
if (DeviceType != L05_BOOT_TYPE_NON_EFI) {
if(DeviceType == LCFC_BOOT_TYPE_EFI_NETWORK_IPV4) {
if (UefiLanIndex[0] == 0xFF) {
UefiLanIndex[0] = PhyBootOrderIndex;
}
}
if(DeviceType == LCFC_BOOT_TYPE_EFI_NETWORK_IPV6) {
if (UefiLanIndex[1] == 0xFF) {
UefiLanIndex[1] = PhyBootOrderIndex;
}
}
}
if(Buffer != NULL) {
gBS->FreePool(Buffer);
Buffer = NULL;
}
}
if((UefiLanIndex[0] != 0xFF) || (UefiLanIndex[1] != 0xFF)) {
LfcBootNext = LcfcBdsLibGetVariableAndSize (
EFI_BOOT_NEXT_VARIABLE_NAME,
&gEfiGlobalVariableGuid,
&LfcBootNextSize
);
if(LfcBootNext != NULL) {
gBS->FreePool(LfcBootNext);
LfcBootNextSize = 0;
LfcBootNext = NULL;
Status = gRT->SetVariable (
EFI_BOOT_NEXT_VARIABLE_NAME,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
LfcBootNextSize,
LfcBootNext
);
}
LfcBootNext = (UINT16 *)AllocateZeroPool (sizeof(UINT16));
LfcBootNextSize = sizeof(UINT16);
if(LfcBootNext != NULL) {
if(SetupVariable->L05PxeIpv4First == 1) {
// IPv4 First
if((UefiLanIndex[1] != 0xFF)) {
*LfcBootNext = PhyBootOrderList[UefiLanIndex[1]];
}
if((UefiLanIndex[0] != 0xFF)) {
*LfcBootNext = PhyBootOrderList[UefiLanIndex[0]];
}
} else {
// IPv6 First
if((UefiLanIndex[0] != 0xFF)) {
*LfcBootNext = PhyBootOrderList[UefiLanIndex[0]];
}
if((UefiLanIndex[1] != 0xFF)) {
*LfcBootNext = PhyBootOrderList[UefiLanIndex[1]];
}
}
Status = gRT->SetVariable (
EFI_BOOT_NEXT_VARIABLE_NAME,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
LfcBootNextSize,
LfcBootNext
);
gBS->FreePool (LfcBootNext);
LfcBootNext = NULL;
}
}
if(PhyBootOrderList != NULL) {
gBS->FreePool (PhyBootOrderList);
PhyBootOrderList = NULL;
}
return Status;
}
VOID
EFIAPI
LcfcRebootCallBack(
IN EFI_EVENT Event,
IN VOID *Context
)
{
UINT8 *pRebootType = NULL;
UINT8 RebootType = 0;
gBS->CloseEvent (Event);
pRebootType = (UINT8 *) Context;
if(pRebootType == NULL) {
return;
}
RebootType = *pRebootType;
if(pRebootType != NULL) {
gBS->FreePool (pRebootType);
pRebootType = NULL;
}
LfcEcLibEnableEcPower ();
// 1: EfiResetCold; 2: EfiResetWarm;
switch(RebootType) {
case 1:
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
break;
case 2:
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
break;
default:
// Do Nothing
break;
}
}
EFI_STATUS
LcfcChangeSecureBootStatusCallBack (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
EFI_L05_SECURE_BOOT_DATA *MySecureBootData;
EFI_L05_SECURE_BOOT_PROTOCOL *L05SecureBootPtr = NULL;
MySecureBootData = (EFI_L05_SECURE_BOOT_DATA *) Context;
Status = gBS->LocateProtocol (
&gEfiL05SecureBootProtocolGuid,
NULL,
&L05SecureBootPtr
);
if (!EFI_ERROR (Status)) {
Status = L05SecureBootPtr->L05SecureBootCallback (MySecureBootData);
}
if(MySecureBootData) {
gBS->FreePool (MySecureBootData);
MySecureBootData = NULL;
}
return Status;
}
EFI_STATUS
LcfcChangeSecureBootStatus (
IN EFI_L05_SECURE_BOOT_DATA *MySecureBootData
)
{
EFI_STATUS Status;
EFI_EVENT Event = NULL;
VOID *Registration = NULL;
EFI_L05_SECURE_BOOT_PROTOCOL *L05SecureBootPtr = NULL;
// EFI_EVENT BdsCpInitEvent = NULL;
// VOID *BdsCpInitRegistration = NULL;
//
// Status = gBS->CreateEvent (
// EVT_NOTIFY_SIGNAL,
// TPL_CALLBACK,
// LcfcChangeSecureBootStatusCallBack,
// MySecureBootData,
// &BdsCpInitEvent
// );
//
// Status = gBS->RegisterProtocolNotify (
// &gH2OBdsCpInitProtocolGuid,
// BdsCpInitEvent,
// (VOID **) &BdsCpInitRegistration
// );
Status = gBS->LocateProtocol (
&gEfiL05SecureBootProtocolGuid,
NULL,
&L05SecureBootPtr
);
if (!EFI_ERROR (Status)) {
Status = L05SecureBootPtr->L05SecureBootCallback (MySecureBootData);
} else {
// Register Event for change secure boot status if gEfiL05SecureBootProtocolGuid is not ready yet.
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
LcfcChangeSecureBootStatusCallBack,
MySecureBootData,
&Event
);
if (!EFI_ERROR (Status)) {
Status = gBS->RegisterProtocolNotify (
&gEfiL05SecureBootProtocolGuid,
Event,
&Registration
);
}
}
return Status;
}
EFI_STATUS
LcfcSecureBootRestoreFactory (
IN OUT SYSTEM_CONFIGURATION *SetupVariable
)
{
EFI_STATUS Status;
EFI_L05_SECURE_BOOT_DATA *MySecureBootData = NULL;
MySecureBootData = (EFI_L05_SECURE_BOOT_DATA *) AllocateZeroPool (sizeof (EFI_L05_SECURE_BOOT_DATA));
if(MySecureBootData == NULL) {
return EFI_UNSUPPORTED;
}
SetupVariable->L05SecureBoot = 1; // 0:Disable, 1:Enable
MySecureBootData->Action = L05_SECURE_BOOT_ENABLE;
MySecureBootData->RestoreFactoryKeys = L05_SECURE_BOOT_ENABLE;
Status = LcfcChangeSecureBootStatus (MySecureBootData);
return Status;
}
EFI_STATUS
LcfcSecureBootEnable (
IN OUT SYSTEM_CONFIGURATION *SetupVariable
)
{
EFI_STATUS Status;
EFI_L05_SECURE_BOOT_DATA *MySecureBootData = NULL;
MySecureBootData = (EFI_L05_SECURE_BOOT_DATA *) AllocateZeroPool (sizeof (EFI_L05_SECURE_BOOT_DATA));
if(MySecureBootData == NULL) {
return EFI_UNSUPPORTED;
}
SetupVariable->L05SecureBoot = 1; // 0:Disable, 1:Enable
MySecureBootData->Action = L05_SECURE_BOOT_ENABLE;
Status = LcfcChangeSecureBootStatus (MySecureBootData);
return Status;
}
EFI_STATUS
LcfcSecureBootDisable (
IN OUT SYSTEM_CONFIGURATION *SetupVariable
)
{
EFI_STATUS Status;
EFI_L05_SECURE_BOOT_DATA *MySecureBootData = NULL;
MySecureBootData = (EFI_L05_SECURE_BOOT_DATA *) AllocateZeroPool (sizeof (EFI_L05_SECURE_BOOT_DATA));
if(MySecureBootData == NULL) {
return EFI_UNSUPPORTED;
}
SetupVariable->L05SecureBoot = 0; // 0:Disable, 1:Enable
MySecureBootData->Action = L05_SECURE_BOOT_DISABLE;
Status = LcfcChangeSecureBootStatus (MySecureBootData);
return Status;
}
EFI_STATUS
LcfcChgBootUefiLoadDefault (
IN OUT SYSTEM_CONFIGURATION *SetupVariable,
IN OUT UINT8 *pRebootType,
IN OUT UINT8 *pLcfcChangeSecureBootReason
)
{
EFI_STATUS Status;
UINT8 ChgBootDefaultTypeData = 0;
UINTN ChgBootDefaultTypeDataSize = sizeof (ChgBootDefaultTypeData);
Status = gRT->GetVariable (
L"ChgBootUefiLoadDefault",
&gLfcVariableGuid,
NULL,
&ChgBootDefaultTypeDataSize,
&ChgBootDefaultTypeData
);
if (!EFI_ERROR (Status)) {
// ChgBoot tool set Win8 default
//[-start-210514-BAINTEST-modify]//
// SetupVariable->L05DefaultType = 0;
SetupVariable->L05OsOptimizedDefault = 0;
//[-end-210514-BAINTEST-modify]//
*pLcfcChangeSecureBootReason = LcfcSetChgboot;
Status = LcfcBootOrderSetDefault ();
Status = gRT->SetVariable (
L"ChgBootUefiLoadDefault",
&gLfcVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
&ChgBootDefaultTypeData
); //Delete it
*pRebootType = 1 ; // 1: EfiResetCold; 2: EfiResetWarm
}
return Status;
}
EFI_STATUS
LcfcChgBootLegacyLoadDefault (
IN OUT SYSTEM_CONFIGURATION *SetupVariable,
IN OUT UINT8 *pRebootType,
IN OUT UINT8 *pLcfcChangeSecureBootReason
)
{
EFI_STATUS Status;
UINT8 ChgBootDefaultTypeData = 0;
UINTN ChgBootDefaultTypeDataSize = sizeof (ChgBootDefaultTypeData);
Status = gRT->GetVariable (
L"ChgBootLegacyLoadDefault",
&gLfcVariableGuid,
NULL,
&ChgBootDefaultTypeDataSize,
&ChgBootDefaultTypeData
);
if (!EFI_ERROR (Status)) {
// ChgBoot tool set legacy default
//[-start-210514-BAINTEST-modify]//
// SetupVariable->L05DefaultType = 1;
SetupVariable->L05OsOptimizedDefault = 1;
//[-end-210514-BAINTEST-modify]//
*pLcfcChangeSecureBootReason = LcfcSetChgboot;
Status = LcfcBootOrderSetDefault();
Status = gRT->SetVariable (
L"ChgBootLegacyLoadDefault",
&gLfcVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
&ChgBootDefaultTypeData
); //Delete it
*pRebootType = 1 ; // 1: EfiResetCold; 2: EfiResetWarm
}
return Status;
}
EFI_STATUS
LcfcChgBootSecureBootEnable (
IN OUT SYSTEM_CONFIGURATION *SetupVariable,
IN OUT UINT8 *pRebootType
)
{
EFI_STATUS Status;
UINT8 ChgBootDefaultTypeData = 0;
UINTN ChgBootDefaultTypeDataSize = sizeof (ChgBootDefaultTypeData);
//If UEFI Mode do this, others do nothing
if (SetupVariable->BootType != 2) {
return EFI_UNSUPPORTED;
}
// Change Boot: Secure Boot Enable
Status = gRT->GetVariable (
L"ChgBootSecureBootEnable",
&gLfcVariableGuid,
NULL,
&ChgBootDefaultTypeDataSize,
&ChgBootDefaultTypeData
);
if (!EFI_ERROR (Status)) {
Status = LcfcSecureBootEnable (SetupVariable);
if (!EFI_ERROR (Status)) {
*pRebootType = 1; // 1: EfiResetCold; 2: EfiResetWarm
}
Status = gRT->SetVariable (
L"ChgBootSecureBootEnable",
&gLfcVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
&ChgBootDefaultTypeData
);
}
return Status;
}
EFI_STATUS
LcfcChgBootSecureBootDisable (
IN OUT SYSTEM_CONFIGURATION *SetupVariable,
IN OUT UINT8 *pRebootType
)
{
EFI_STATUS Status;
UINT8 ChgBootDefaultTypeData = 0;
UINTN ChgBootDefaultTypeDataSize = sizeof (ChgBootDefaultTypeData);
EFI_GUID LvarMfgModeFlagGuid = LVAR_MFG_MODE_FLAG_GUID;
UINT8 MfgModeFlag = 0;
UINT32 MfgModeFlagDataSize = 1;
LENOVO_VARIABLE_PROTOCOL *LenovoVariable;
//If UEFI Mode do this, others do nothing
if (SetupVariable->BootType != 2) {
return EFI_UNSUPPORTED;
}
//Check MfgMod
Status = gBS->LocateProtocol (&gLenovoVariableProtocolGuid, NULL, &LenovoVariable);
if (!EFI_ERROR (Status)) {
Status = LenovoVariable->GetVariable (
LenovoVariable,
&LvarMfgModeFlagGuid,
&MfgModeFlagDataSize,
(VOID*) (&MfgModeFlag)
) ;
}
// Change Boot: Secure Boot Disable
Status = gRT->GetVariable (
L"ChgBootSecureBootDisable",
&gLfcVariableGuid,
NULL,
&ChgBootDefaultTypeDataSize,
&ChgBootDefaultTypeData
);
if (!EFI_ERROR (Status) && (MfgModeFlag == 'Y')) {//Only chgboot command and Mfgmode both exist, do following thing.
Status = LcfcSecureBootDisable (SetupVariable);
if (!EFI_ERROR (Status)) {
*pRebootType = 1; // 1: EfiResetCold; 2: EfiResetWarm
}
Status = gRT->SetVariable (
L"ChgBootSecureBootDisable",
&gLfcVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
&ChgBootDefaultTypeData
);
}
return Status;
}
EFI_STATUS
LcfcChgBootRestoreFactory (
IN OUT SYSTEM_CONFIGURATION *SetupVariable,
IN OUT UINT8 *pRebootType
)
{
EFI_STATUS Status;
UINT8 ChgBootDefaultTypeData = 0;
UINTN ChgBootDefaultTypeDataSize = sizeof (ChgBootDefaultTypeData);
//If UEFI Mode do this, others do nothing
if (SetupVariable->BootType != 2) {
return EFI_UNSUPPORTED;
}
// Change Boot: Secure Boot Restore Factory Key
Status = gRT->GetVariable (
L"ChgBootRestoreFactory",
&gLfcVariableGuid,
NULL,
&ChgBootDefaultTypeDataSize,
&ChgBootDefaultTypeData
);
if (!EFI_ERROR (Status)) {
Status = LcfcSecureBootRestoreFactory(SetupVariable);
if (!EFI_ERROR (Status)) {
*pRebootType = 1; // 1: EfiResetCold; 2: EfiResetWarm
}
Status = gRT->SetVariable (
L"ChgBootRestoreFactory",
&gLfcVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
&ChgBootDefaultTypeData
);
}
return Status;
}
EFI_STATUS
LcfcChgBootChangeLegacy (
IN OUT SYSTEM_CONFIGURATION *SetupVariable,
IN OUT UINT8 *pRebootType
)
{
EFI_STATUS Status;
UINT8 ChgBootDefaultTypeData = 0;
UINTN ChgBootDefaultTypeDataSize = sizeof (ChgBootDefaultTypeData);
// Change Boot: Change to Legacy and Secure Boot Disable
Status = gRT->GetVariable (
L"ChgBootChangeLegacy",
&gLfcVariableGuid,
NULL,
&ChgBootDefaultTypeDataSize,
&ChgBootDefaultTypeData
);
if (!EFI_ERROR (Status)) {
Status = LcfcSecureBootDisable (SetupVariable);
if (!EFI_ERROR (Status)) {
*pRebootType = 1; // 1: EfiResetCold; 2: EfiResetWarm
}
Status = gRT->SetVariable (
L"ChgBootChangeLegacy",
&gLfcVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
&ChgBootDefaultTypeData
);
}
return Status;
}
EFI_STATUS
LcfcChgBootBootOrderSetDefault (
IN OUT SYSTEM_CONFIGURATION *SetupVariable,
IN OUT UINT8 *pRebootType
)
{
EFI_STATUS Status;
UINT8 ChgBootDefaultTypeData = 0;
UINTN ChgBootDefaultTypeDataSize = sizeof (ChgBootDefaultTypeData);
// Change Boot: Change to Legacy and Secure Boot Disable
Status = gRT->GetVariable (
L"ChgBootBootOrderSetDefault",
&gLfcVariableGuid,
NULL,
&ChgBootDefaultTypeDataSize,
&ChgBootDefaultTypeData
);
if (!EFI_ERROR (Status)) {
*pRebootType = 1; // 1: EfiResetCold; 2: EfiResetWarm
LcfcBootOrderSetDefault();
Status = gRT->SetVariable (
L"ChgBootBootOrderSetDefault",
&gLfcVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
&ChgBootDefaultTypeData
);
}
return Status;
}
EFI_STATUS
LcfcChgBootFullReset (
IN OUT SYSTEM_CONFIGURATION *SetupVariable,
IN OUT UINT8 *pRebootType
)
{
EFI_STATUS Status;
UINT8 ChgBootDefaultTypeData = 0;
UINTN ChgBootDefaultTypeDataSize = sizeof (ChgBootDefaultTypeData);
Status = gRT->GetVariable (
L"ChgBootFullReset",
&gLfcVariableGuid,
NULL,
&ChgBootDefaultTypeDataSize,
&ChgBootDefaultTypeData
);
if(!EFI_ERROR (Status)) {
*pRebootType = 1; // 1: EfiResetCold; 2: EfiResetWarm
Status = gRT->SetVariable (
L"ChgBootFullReset",
&gLfcVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
&ChgBootDefaultTypeData
);
}
return Status;
}
EFI_STATUS
LcfcLvarShowComputraceHelpString (
IN OUT SYSTEM_CONFIGURATION *SetupVariable,
IN OUT UINT8 *pRebootType
)
{
EFI_STATUS Status;
EFI_GUID ComputraceStringFlagGuid = LVAR_COMPUTRACE_STRING_FLAG_GUID;
UINT32 ComputraceStringFlagSize = 1;
UINT8 ComputraceStringFlag = 0;
LENOVO_VARIABLE_PROTOCOL *LenovoVariable;
if(SetupVariable->ComputraceState == 0) {
return EFI_UNSUPPORTED;
}
Status = gBS->LocateProtocol (&gLenovoVariableProtocolGuid, NULL, &LenovoVariable);
if (EFI_ERROR (Status)) {
return Status;
}
ComputraceStringFlagSize = sizeof(UINT8);
Status = LenovoVariable->GetVariable (
LenovoVariable,
&ComputraceStringFlagGuid,
&ComputraceStringFlagSize,
&ComputraceStringFlag
);
if (EFI_ERROR (Status)) {
return Status;
}
// ComputraceStringFlag: 1 (Hide Computrace String)
// ComputraceStringFlag: 0 (Show Computrace String)
SetupVariable->L05ShowComputraceHelpStringInScu = !ComputraceStringFlag;
return Status;
}
//[-start-210514-BAINTEST-modify]//
//EFI_STATUS
//LcfcOverrideDefaultSetupSetting (
// IN OUT UINT8 *SetupBuffer
// )
EFI_STATUS
LcfcOverrideDefaultSetupSetting (
IN OUT UINT8 *SetupBuffer,
IN OUT UINT8 *PchSetupBuffer,
IN OUT UINT8 *CpuSetupBuffer,
IN OUT UINT8 *SaSetupBuffer
)
//[-end-210514-BAINTEST-modify]//
{
EFI_STATUS Status;
SYSTEM_CONFIGURATION *SetupVariable;
UINT8 FirstBootFlag;
UINTN FirstBootFlagSize;
UINT8 OriginalBootType;
LENOVO_VARIABLE_PROTOCOL *LenovoVariable = NULL;
EFI_GUID VarGuid = LVAR_64BIT_CONFIGURATION_GUID;
UINT64 ConfigurationVariable = 0;
UINT32 ConfigVarDataSize = sizeof (ConfigurationVariable);
EFI_EVENT EndOfDxeEvent = NULL;
UINT8 *pRebootType = NULL;
// 1: First Boot; 2: Set Change Boot CMD; 3: F9 Load Default;
UINT8 LcfcChangeSecureBootReason = LcfcF9LoadDefault;
Status = mOrgOverrideDefaultSetupSetting(SetupBuffer, PchSetupBuffer, CpuSetupBuffer, SaSetupBuffer);
// Status = mOrgOverrideDefaultSetupSetting(SetupBuffer);
// 1: EfiResetCold; 2: EfiResetWarm
pRebootType = (UINT8 *) AllocateZeroPool (sizeof (UINT8));
if(pRebootType == NULL) {
return EFI_UNSUPPORTED;
}
SetupVariable = (SYSTEM_CONFIGURATION *) SetupBuffer;
//[-start-210514-BAINTEST-modify]//
// OriginalBootType = SetupVariable->L05DefaultType;
OriginalBootType = SetupVariable->L05OsOptimizedDefault;
//[-end-210514-BAINTEST-modify]//
Status = gBS->LocateProtocol (
&gLenovoVariableProtocolGuid,
NULL,
&LenovoVariable
);
FirstBootFlagSize = sizeof (FirstBootFlag);
Status = gRT->GetVariable (
L"CheckFirstBoot",
&gEfiGenericVariableGuid,
NULL,
&FirstBootFlagSize,
&FirstBootFlag
);
// First Boot, FirstBootFlag didn't exist in NVRam.
if (Status == EFI_NOT_FOUND) {
// First Boot after flash BIOS
LcfcChangeSecureBootReason = LcfcFirstBoot;
Status = gRT->SetVariable (
L"CheckFirstBoot",
&gEfiGenericVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (FirstBootFlag),
&FirstBootFlag
);
} else if (Status == EFI_SUCCESS) {
// F9 or Chgboot command
Status = LcfcChgBootUefiLoadDefault (SetupVariable, pRebootType, &LcfcChangeSecureBootReason);
Status = LcfcChgBootLegacyLoadDefault (SetupVariable, pRebootType, &LcfcChangeSecureBootReason);
//[-start-210514-BAINTEST-modify]//
// if (SetupVariable->L05DefaultType == 0) {
if (SetupVariable->L05OsOptimizedDefault == 0) {
//[-end-210514-BAINTEST-modify]//
//
// UEFI O.S
//
SetupVariable->BootType = 2; // 0:Dual Boot, 2:EFI Boot
//SetupVariable->L05FastBoot = 1; // Fast Boot = Enabled
SetupVariable->L05BiosBackFlash = 0; // Back Flash = Disabled
// 1: If Change Boot CMD enable SecureBoot; 2: F9 Load Default skip this;
if (LcfcChangeSecureBootReason != LcfcF9LoadDefault) {
Status = LcfcSecureBootEnable (SetupVariable);
}
//[-start-210514-BAINTEST-modify]//
// } else if (SetupVariable->L05DefaultType == 1) {
} else if (SetupVariable->L05OsOptimizedDefault == 1) {
//[-end-210514-BAINTEST-modify]//
//
// Legacy O.S.
//
SetupVariable->BootType = 0; // 0:Dual Boot, 2:EFI Boot
//SetupVariable->L05FastBoot = 0; // Fast Boot = Disabled
SetupVariable->L05BiosBackFlash = 0; // Back Flash = Disabled
// 1: If Change Boot CMD disable SecureBoot; 2: F9 Load Default skip this;
if (LcfcChangeSecureBootReason != LcfcF9LoadDefault) {
Status = LcfcSecureBootDisable (SetupVariable);
}
}
}
//[-start-210514-BAINTEST-modify]//
// SetupVariable->L05DefaultType = OriginalBootType;
SetupVariable->L05OsOptimizedDefault = OriginalBootType;
//[-end-210514-BAINTEST-modify]//
if (LenovoVariable != NULL) {
ConfigurationVariable = 0;
ConfigVarDataSize = sizeof (ConfigurationVariable);
Status = LenovoVariable->GetVariable (
LenovoVariable,
&VarGuid,
&ConfigVarDataSize,
&ConfigurationVariable
);
if (!EFI_ERROR(Status)) {
switch ((ConfigurationVariable & LVAR_TPM_MASK) >> 8) {
case LVAR_TPM_DISPLAY_ENABLE:
SetupVariable->L05OdmTpmImplement = 1;
#if (FixedPcdGet8 (PcdPlatformIntelOrAmd) == 1)
SetupVariable->L05FtpmEnable = 1;
#else
SetupVariable->EnableTPM = 2;
#endif
break;
case LVAR_TPM_DISPLAY_DISABLE:
SetupVariable->L05OdmTpmImplement = 1;
#if (FixedPcdGet8 (PcdPlatformIntelOrAmd) == 1)
SetupVariable->L05FtpmEnable = 0;
#else
SetupVariable->EnableTPM = 0;
#endif
break;
case LVAR_TPM_HIDE_ENABLE:
SetupVariable->L05OdmTpmImplement = 0; // Attention!!! If hidden, maybe always be disabled by L05, need double confirm!!!!
#if (FixedPcdGet8 (PcdPlatformIntelOrAmd) == 1)
//[-start-210514-BAINTEST-modify]//
// SetupVariable->PTTEnable = 1;
SetupVariable->L05FtpmEnable = 1;
//[-end-210514-BAINTEST-modify]//
#else
SetupVariable->EnableTPM = 2;
#endif
break;
case LVAR_TPM_HIDE_DISABLE:
SetupVariable->L05OdmTpmImplement = 0;
#if (FixedPcdGet8 (PcdPlatformIntelOrAmd) == 1)
SetupVariable->L05FtpmEnable = 0;
#else
SetupVariable->EnableTPM = 0;
#endif
break;
case LVAR_TPM_DO_NOTHING:
default:
// Do Nothing
break;
}
}
}
if (*pRebootType) {
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
LcfcRebootCallBack,
pRebootType,
&gEfiEndOfDxeEventGroupGuid,
&EndOfDxeEvent
);
} else {
if(pRebootType != NULL) {
gBS->FreePool (pRebootType);
pRebootType = NULL;
}
}
return Status;
}
EFI_STATUS
LcfcOverrideSetupSettingDuringPost (
IN OUT UINT8 *SetupBuffer
)
{
EFI_STATUS Status;
SYSTEM_CONFIGURATION *SetupVariable;
EFI_EVENT EndOfDxeEvent = NULL;
UINT8 *pRebootType = NULL; // 1: EfiResetCold; 2: EfiResetWarm
//[-start-220210-Dongxu0040-Modify]//
UINT8 ValidTool = 0;
Status = mOrgOverrideSetupSettingDuringPost (SetupBuffer);
// 1: EfiResetCold; 2: EfiResetWarm
pRebootType = (UINT8 *) AllocateZeroPool (sizeof (UINT8));
if(pRebootType == NULL) {
return EFI_UNSUPPORTED;
}
SetupVariable = (SYSTEM_CONFIGURATION *) SetupBuffer;
Status = LcfcLvarShowComputraceHelpString(SetupVariable, pRebootType);
Status = LfcCheckValidTool(&ValidTool);
if(ValidTool != 0X55){
return EFI_UNSUPPORTED;
}
//[-end-220210-Dongxu0040-Modify]//
Status = LcfcChgBootSecureBootEnable (SetupVariable, pRebootType);
Status = LcfcChgBootSecureBootDisable (SetupVariable, pRebootType);
Status = LcfcChgBootRestoreFactory (SetupVariable, pRebootType);
Status = LcfcChgBootChangeLegacy (SetupVariable, pRebootType);
Status = LcfcChgBootBootOrderSetDefault (SetupVariable, pRebootType);
Status = LcfcChgBootSetPxeToFirst (SetupVariable, pRebootType);
Status = LcfcChgBootSetEfiPxeOneTime (SetupVariable, pRebootType);
//Status = LcfcLvarShowComputraceHelpString(SetupVariable, pRebootType);
Status = LcfcChgBootFullReset (SetupVariable, pRebootType);
if(*pRebootType) {
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
LcfcRebootCallBack,
pRebootType,
&gEfiEndOfDxeEventGroupGuid,
&EndOfDxeEvent
);
} else {
if(pRebootType != NULL) {
gBS->FreePool (pRebootType);
pRebootType = NULL;
}
}
return Status;
}
/*
EFI_STATUS
LcfcOverrideDefaultPchSetupSetting (
IN OUT UINT8 *SetupBuffer,
IN OUT UINT8 *PchSetupBuffer
)
{
EFI_STATUS Status;
Status = mOrgOverrideDefaultPchSetupSetting(SetupBuffer,PchSetupBuffer);
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CANNONLAKE)
SYSTEM_CONFIGURATION *SetupVariable;
PCH_SETUP *PchSetup;
#ifdef L05_BIOS_OPTANE_SUPPORT_ENABLE
// EFI_STATUS Status;
UINTN BufferSize;
L05_BACKUP_SATAMODE_ITEM L05BackupSetupItem;
UINT32 L05BackupSetupItemSize;
UINT8 FirstPchBootFlag;
UINTN FirstPchBootFlagSize;
#endif
SetupVariable = (SYSTEM_CONFIGURATION *) SetupBuffer;
PchSetup = (PCH_SETUP *) PchSetupBuffer;
#ifdef L05_BIOS_OPTANE_SUPPORT_ENABLE
//
// According to Lenovo request, if system is in RST mode, after flash BIOS, should keep RST mode, unless user set it to AHCI
//
EFI_GUID SataModeVarGuid = LVAR_SATAMODE_STRING_FLAG_GUID;
LENOVO_VARIABLE_PROTOCOL *LenovoVariable = NULL;
BufferSize = sizeof (L05_BACKUP_SATAMODE_ITEM);
L05BackupSetupItemSize = sizeof (L05_BACKUP_SATAMODE_ITEM);
Status = gRT->GetVariable (
L"CheckPchFirstBoot",
&gEfiGenericVariableGuid,
NULL,
&FirstPchBootFlagSize,
&FirstPchBootFlag
);
if (Status == EFI_NOT_FOUND) {
Status = gBS->LocateProtocol (
&gLenovoVariableProtocolGuid,
NULL,
&LenovoVariable
);
if (LenovoVariable != NULL) {
Status = LenovoVariable->GetVariable (
LenovoVariable,
&SataModeVarGuid,
&L05BackupSetupItemSize,
&L05BackupSetupItem
);
if (!EFI_ERROR (Status)) {
PchSetup->SataInterfaceMode = L05BackupSetupItem.SataInterfaceMode;
PchSetup->SataRaidR0 = L05BackupSetupItem.SataRaidR0;
PchSetup->SataRaidR1 = L05BackupSetupItem.SataRaidR1;
PchSetup->SataRaidR5 = L05BackupSetupItem.SataRaidR5;
PchSetup->SataRaidR10 = L05BackupSetupItem.SataRaidR10;
CopyMem (PchSetup->RstPcieRemapEnabled, L05BackupSetupItem.RstPcieRemapEnabled, PCH_MAX_PCIE_ROOT_PORTS);
PchSetup->SataRstOptaneMemory = L05BackupSetupItem.SataRstOptaneMemory;
//TG support
//PchSetup->TetonGlacierMode = L05BackupSetupItem.TetonGlacierMode;
}
else {
LenovoVariable->SetVariable (
LenovoVariable,
&SataModeVarGuid,
L05BackupSetupItemSize,
&L05BackupSetupItem
);
}
}
Status = gRT->SetVariable (
L"CheckPchFirstBoot",
&gEfiGenericVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (FirstPchBootFlag),
&FirstPchBootFlag
);
}
// [Lenovo BIOS Optane Support Version 1.4 Page 13]
// OS Optimized Default
// When RST Mode is selected, BIOS keeps "UEFI/Legacy mode" "EFI only" even
// when "Optimized Default" is disabled.
//
if ((SetupVariable->L05DefaultType == 1) // 0: Enable 1:Disable
&& (PchSetup->SataInterfaceMode == SATA_MODE_AHCI)
) {
//
// Legacy O.S.
//
SetupVariable->BootType = 0; // 0:Dual Boot, 2:EFI Boot
SetupVariable->L05SecureBoot = 0; // 0:Disable, 1:Enable
} else if((SetupVariable->L05DefaultType == 0) // 0: Enable 1:Disable
&& (PchSetup->SataInterfaceMode == SATA_MODE_AHCI)
){
//
// Do nothing. user can change Boot Type.
//
}else {
//
// Windows 8 64 bit
//
SetupVariable->BootType = 2; // 0:Dual Boot, 2:EFI Boot
SetupVariable->L05SecureBoot = 1; // 0:Disable, 1:Enable
}
#endif
//
// When L05WlanSyncToCnvi is Enable (1),
// system will synchronize the L05 WLAN switch (SYSTEM_CONFIGURATION.L05WirelessFunction) with Intel CNVi switch (PCH_SETUP.PchCnviMode).
//
if (SetupVariable->L05WlanSyncToCnvi == 1 && SetupVariable->L05ODMWirelessImplement == 1) {
//
// "CNVi Mode" item, 0:Disable Integrated, 1:Auto Detection
// "Wireless LAN" item, 0:Disable, 1:Enable
//
PchSetup->PchCnviMode = SetupVariable->L05WirelessFunction;
}
#endif
return EFI_SUCCESS;
}
*/
VOID
EFIAPI
LcfcOverrideSetupSettingCallBack (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
EFI_L05_SETUP_MENU_PROTOCOL *L05SetupMenu;
gBS->CloseEvent (Event);
Status = gBS->LocateProtocol (
&gEfiL05SetupMenuProtocolGuid,
NULL,
&L05SetupMenu
);
if (!EFI_ERROR (Status)) {
mOrgOverrideDefaultSetupSetting = L05SetupMenu->OverrideDefaultSetupSetting;
L05SetupMenu->OverrideDefaultSetupSetting = LcfcOverrideDefaultSetupSetting;
mOrgOverrideSetupSettingDuringPost = L05SetupMenu->OverrideSetupSettingDuringPost;
L05SetupMenu->OverrideSetupSettingDuringPost = LcfcOverrideSetupSettingDuringPost;
//[-start-210514-BAINTEST-remove]//
// mOrgOverrideDefaultPchSetupSetting = L05SetupMenu->OverrideDefaultPchSetupSetting;
// L05SetupMenu->OverrideDefaultPchSetupSetting = LcfcOverrideDefaultPchSetupSetting;
//[-end-210514-BAINTEST-remove]//
}
}
EFI_STATUS
ChgBootDxeHookEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_L05_SETUP_MENU_PROTOCOL *L05SetupMenu;
EFI_EVENT Event;
VOID *Registration;
Status = gBS->LocateProtocol (
&gEfiL05SetupMenuProtocolGuid,
NULL,
&L05SetupMenu
);
if (!EFI_ERROR (Status)) {
mOrgOverrideDefaultSetupSetting = L05SetupMenu->OverrideDefaultSetupSetting;
L05SetupMenu->OverrideDefaultSetupSetting = LcfcOverrideDefaultSetupSetting;
mOrgOverrideSetupSettingDuringPost = L05SetupMenu->OverrideSetupSettingDuringPost;
L05SetupMenu->OverrideSetupSettingDuringPost = LcfcOverrideSetupSettingDuringPost;
//[-start-210514-BAINTEST-remove]//
// mOrgOverrideDefaultPchSetupSetting = L05SetupMenu->OverrideDefaultPchSetupSetting;
// L05SetupMenu->OverrideDefaultPchSetupSetting = LcfcOverrideDefaultPchSetupSetting;
//[-end-210514-BAINTEST-remove]//
} else {
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
LcfcOverrideSetupSettingCallBack ,
NULL,
&Event
);
if (!EFI_ERROR (Status)) {
Status = gBS->RegisterProtocolNotify (
&gEfiL05SetupMenuProtocolGuid,
Event,
&Registration
);
}
}
return Status;
}