alder_lake_bios/Oem/L05/FeatureCommon/InsydeL05ModulePkg/SetupMenuService/SetupMenuService.c

1718 lines
55 KiB
C

/** @file
Function Service for L05 Setup Menu
;******************************************************************************
;* Copyright (c) 2013 - 2019, 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 "SetupMenuService.h"
//[-start-211026-QINGLIN0105-add]//
#ifdef LCFC_SUPPORT
#include <Protocol/LenovoVariable.h>
#endif
//[-end-211026-QINGLIN0105-add]//
BOOLEAN mIsNeedRestart = FALSE;
BOOLEAN mIsNeedUpdateSecureBoot = FALSE;
BOOLEAN mIsNeedUpdateApcbTpmConfig = FALSE;
UINT8 mSetL05SecureBoot = 0;
EFI_KEYBOARD_SCANCODE_LIST mScanCodeMap[] = {
{L'a', 0x001E},
{L'b', 0x0030},
{L'c', 0x002E},
{L'd', 0x0020},
{L'e', 0x0012},
{L'f', 0x0021},
{L'g', 0x0022},
{L'h', 0x0023},
{L'i', 0x0017},
{L'j', 0x0024},
{L'k', 0x0025},
{L'l', 0x0026},
{L'm', 0x0032},
{L'n', 0x0031},
{L'o', 0x0018},
{L'p', 0x0019},
{L'q', 0x0010},
{L'r', 0x0013},
{L's', 0x001F},
{L't', 0x0014},
{L'u', 0x0016},
{L'v', 0x002F},
{L'w', 0x0011},
{L'x', 0x002D},
{L'y', 0x0015},
{L'z', 0x002C},
{L'1', 0x0002},
{L'2', 0x0003},
{L'3', 0x0004},
{L'4', 0x0005},
{L'5', 0x0006},
{L'6', 0x0007},
{L'7', 0x0008},
{L'8', 0x0009},
{L'9', 0x000A},
{L'0', 0x000B},
#ifdef L05_SMB_BIOS_ENABLE
{L' ', 0x0039},
#endif
};
/**
Adjust password character is valid.
@param This Points to L05 Setup Menu Protocol
@retval EFI_SUCCESS The image has been unloaded.
@retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
**/
BOOLEAN
IsValidKeyData (
IN EFI_L05_SETUP_MENU_PROTOCOL *This
)
{
BOOLEAN IsValid;
IsValid = FALSE;
#ifdef L05_NOTEBOOK_CLOUD_BOOT_WIFI_ENABLE
if (PcdGetBool (PcdL05InputWifiPassword)) {
//
// Can input special symbols
//
return TRUE;
}
#endif
//
// Step 1. "Esc" is vaild key
//
if (This->CurrentKeyData.Key.ScanCode == SCAN_ESC && This->CurrentKeyData.Key.UnicodeChar == CHAR_NULL) {
IsValid = TRUE;
}
//
// Step 2. "Enter", BackSpace" are vaild key
//
if ((This->CurrentKeyData.Key.UnicodeChar == CHAR_CARRIAGE_RETURN || This->CurrentKeyData.Key.UnicodeChar == CHAR_BACKSPACE) &&
This->CurrentKeyData.Key.ScanCode == SCAN_NULL) {
IsValid = TRUE;
}
//
// Step 3. Only 'a'~'z', '0'~'9' are valid key data for password Character
//
if ((This->CurrentKeyData.Key.UnicodeChar >= L'a' && This->CurrentKeyData.Key.UnicodeChar <= L'z') ||
#ifdef L05_SMB_BIOS_ENABLE
//
// [Lenovo SMB BIOS Special Requirements V1.1]
// 2.1 BIOS Password Characters
// Supported characters
// - Alphabet (case insensitive)
// - Space ' '
//
(This->CurrentKeyData.Key.UnicodeChar >= L'A' && This->CurrentKeyData.Key.UnicodeChar <= L'Z') ||
(This->CurrentKeyData.Key.UnicodeChar == L' ') ||
#endif
(This->CurrentKeyData.Key.UnicodeChar >= L'0' && This->CurrentKeyData.Key.UnicodeChar <= L'9')) {
IsValid = TRUE;
}
//
// Step 4. ScanCode & UnicodeChar are NULL for mouse click blank space, that is valid key for don't generate beep
//
if ((This->CurrentKeyData.Key.UnicodeChar == CHAR_NULL) && (This->CurrentKeyData.Key.ScanCode == SCAN_NULL)) {
IsValid = TRUE;
}
//
// Step 5. Determine valid key by adjusting Key status if key data is valid
//
if (IsValid) {
//
// "Ctrl", "Alt" are not vaild key status
//
if ((This->CurrentKeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) ||
(This->CurrentKeyData.KeyState.KeyShiftState & (EFI_LEFT_ALT_PRESSED | EFI_RIGHT_ALT_PRESSED))) {
IsValid = FALSE;
}
}
//[-start-220125-BAIN000092-modify]//
#ifdef L05_NOTEBOOK_PASSWORD_V1_1_ENABLE
//#ifdef L05_NOTEBOOK_PASSWORD_ENABLE
//[-end-220125-BAIN000092-modify]//
//
// [Lenovo Notebook Password Design Spec V1.1]
// 4.1.1. Check HDP
// User can press F1 to switch Master Password and User Password.
//
// "F1" is vaild key for Notebook Password Design
//
if (This->CurrentKeyData.Key.ScanCode == SCAN_F1 && This->CurrentKeyData.Key.UnicodeChar == CHAR_NULL &&
PcdGetBool (PcdL05NotebookPasswordDesignDialogF1Flag)) {
PcdSetBoolS (PcdL05NotebookPasswordDesignPressF1Flag, TRUE);
//[-start-2200405-BAIN000100-add]//
#if defined(S370_SUPPORT)
PcdSetBoolS (PcdHddStrWAFlag3, TRUE);
#endif
//[-start-2200405-BAIN000100-add]//
IsValid = TRUE;
}
#endif
//
// Clean all Key Data
//
ZeroMem (&(This->CurrentKeyData), sizeof (EFI_KEY_DATA));
return IsValid;
}
/**
Convert Unicode Char to Keyboard Scancode(Normal)
@param KeyData Point to Key Data(Unicode)
@retval EFI_SUCCESS The image has been unloaded.
@retval EFI_NOT_FOUND ImageHandle is not a valid image handle.
**/
EFI_STATUS
ConvertUnicodeCharToKeyboardScancode (
OUT CHAR16 *KeyData
)
{
UINTN Index;
#ifdef L05_NOTEBOOK_CLOUD_BOOT_WIFI_ENABLE
if (PcdGetBool (PcdL05InputWifiPassword)) {
return EFI_SUCCESS;
}
#endif
for (Index = 0x00; Index < sizeof (mScanCodeMap) / sizeof (EFI_KEYBOARD_SCANCODE_LIST); Index++) {
#ifdef L05_SMB_BIOS_ENABLE
//
// [Lenovo SMB BIOS Special Requirements V1.1]
// 2.1 BIOS Password Characters
// Supported characters
// - Alphabet (case insensitive)
//
if (*KeyData >= L'A' && *KeyData <= L'Z') {
*KeyData += 0x20;
}
#endif
if (*KeyData == mScanCodeMap[Index].UnicodeChar) {
(UINT16) *KeyData = mScanCodeMap[Index].KeyboardScanCode;
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
/**
Hide and Disable Project Dependency Item.
@param SetupBuffer Points to System Configuration Structure
@param PchSetupBuffer Points to PCH_SETUP Structure
@param CpuSetupBuffer Points to CPU_SETUP Structure
@param SaSetupBuffer Points to SA_SETUP Structure
@retval EFI_SUCCESS Returns success by default. The return status will not be referenced.
**/
EFI_STATUS
HideDisableProjectDependencyItem (
IN OUT UINT8 *SetupBuffer,
IN OUT UINT8 *PchSetupBuffer,
IN OUT UINT8 *CpuSetupBuffer,
IN OUT UINT8 *SaSetupBuffer
)
{
SYSTEM_CONFIGURATION *SetupVariable;
#if (FixedPcdGetBool (PcdL05PchSetupSupported))
PCH_SETUP *PchSetup;
CPU_SETUP *CpuSetup;
SA_SETUP *SaSetup;
#endif
if (SetupBuffer == NULL) {
return EFI_UNSUPPORTED;
}
#if (FixedPcdGetBool (PcdL05PchSetupSupported))
if ((PchSetupBuffer == NULL) || (CpuSetupBuffer == NULL) || (SaSetupBuffer == NULL)) {
return EFI_UNSUPPORTED;
}
#endif
SetupVariable = (SYSTEM_CONFIGURATION *) SetupBuffer;
#if (FixedPcdGetBool (PcdL05PchSetupSupported))
PchSetup = (PCH_SETUP *) PchSetupBuffer;
CpuSetup = (CPU_SETUP *) CpuSetupBuffer;
SaSetup = (SA_SETUP *) SaSetupBuffer;
#endif
//
// "Wireless LAN" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05OdmWirelessLanImplement == 0) {
SetupVariable->L05WirelessLan = 0;
}
//
// "Intel VMD Controller" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05VmdControllerSupport == 0) {
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE)
SaSetup->VmdEnable = 0;
#endif
}
//
// "Intel Virtual Technology" or "AMD SVM Technology" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05VtSupport == 0) {
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_SHARKBAY || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_BROADWELL)
SetupVariable->VTSupport = 0;
#endif
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_SKYLAKE)
SetupVariable->VT = 0;
#endif
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_BAYTRAIL_M || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_BRASWELL || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_APOLLOLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_GEMINILAKE)
SetupVariable->ProcessorVmxEnable = 0;
#endif
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_KABYLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CANNONLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ICELAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_COMETLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_JASPERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE)
CpuSetup->VT = 0;
#endif
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CARRIZOLITE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CARRIZO || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_STONEY || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_BRISTOL || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_MULLINLS || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_RAVENRIDGE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_PICASSO || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_RENOIR || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT)
SetupVariable->EnableSVM = 0;
#endif
}
//
// "Intel (R) VT-d Feature" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05VtdSupport == 0) {
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_KABYLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CANNONLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ICELAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_COMETLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_JASPERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE)
SaSetup->EnableVtd = 0;
#endif
}
//
// "Intel (R) Hyper Threading Technology" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05HyperThreadingSupport == 0) {
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_SKYLAKE)
SetupVariable->HyperThreading = 0;
#endif
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_KABYLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CANNONLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ICELAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_COMETLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_JASPERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE)
CpuSetup->HyperThreading = 0;
#endif
}
//
// "Hotkey Mode" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05HotKeyModeSupport == 0) {
SetupVariable->L05HotKeyMode = 0;
}
//
// "Fool Proof Fn Ctrl" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05FoolProofFnCtrlSupport == 0) {
SetupVariable->L05FoolProofFnCtrl = 0;
}
//[-start-210701-FLINT00010-add]//
//[-start-210721-QINGLIN0001-modify]//
//[-start-210817-DABING0002-modify]//
#if defined(C970_SUPPORT) || defined(C770_SUPPORT) || defined(S570_SUPPORT) || defined(S77014_SUPPORT) || defined(S77014IAH_SUPPORT)
//
// "Charge In Battery Mode" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05AlwaysOnUsb == 0) {
SetupVariable->L05ChargeInBatteryMode = 0;
}
#endif
//[-end-210817-DABING0002-modify]//
//[-end-210721-QINGLIN0001-modify]//
//[-end-210701-FLINT00010-add]//
//
// "Always On USB" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05AlwaysOnUsbSupport == 0) {
SetupVariable->L05AlwaysOnUsb = 0;
}
//
// "Charge in Battery Mode" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05ChargeInBatteryModeSupport == 0) {
SetupVariable->L05ChargeInBatteryMode = 0;
}
//
// "Intel PTT" or "AMD PSP" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05OdmTpmImplement == 0) {
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_BROADWELL || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_SKYLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_KABYLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CANNONLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ICELAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_COMETLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_JASPERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE)
SetupVariable->PTTEnable = 0;
#endif
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_APOLLOLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_GEMINILAKE)
//
// TargetTPM = 1, means the platform switch to support DTPM.
// If there is no DTPM device, means TPM is unsupported.
//
SetupVariable->TargetTPM = 1;
#endif
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CARRIZOLITE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CARRIZO || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_STONEY || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_BRISTOL || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_MULLINLS || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_RAVENRIDGE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_PICASSO || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_RENOIR || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT)
SetupVariable->EnableTPM = 0;
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT)
mIsNeedUpdateApcbTpmConfig = TRUE;
#endif
#endif
}
//
// "Device Guard" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05DeviceGuardSupport == 0) {
SetupVariable->L05DeviceGuard = 0;
}
//
// "Fast Boot" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05FastBootImplement == 0) {
SetupVariable->L05FastBoot = 0;
}
//
// I/O Port Access
//
// "Ethernet LAN" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05OdmEthernetLanImplement == 0) {
SetupVariable->L05EthernetLan = 0;
}
//
// "Wireless WAN" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05OdmWirelessWanImplement == 0) {
SetupVariable->L05WirelessWan = 0;
}
//
// "Bluetooth" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05OdmBluetoothImplement == 0) {
SetupVariable->L05Bluetooth = 0;
}
//
// "USB Port" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05OdmUsbPortImplement == 0) {
SetupVariable->L05UsbPort = 0;
}
//
// "Memory Card Slot" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05OdmMemoryCardSlotImplement == 0) {
SetupVariable->L05MemoryCardSlot = 0;
}
//
// "Smart Card Slot" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05OdmSmartCardSlotImplement == 0) {
SetupVariable->L05SmartCardSlot = 0;
}
//
// "Integrated Camera" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05OdmIntegratedCameraImplement == 0) {
SetupVariable->L05IntegratedCamera = 0;
}
//
// "Microphone" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05OdmMicrophoneImplement == 0) {
SetupVariable->L05Microphone = 0;
}
//
// "Fingerprint Reader" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05OdmFingerprintReaderImplement == 0) {
SetupVariable->L05FingerprintReader = 0;
}
//
// "Thunderbolt(TM)" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05OdmThunderboltImplement == 0) {
SetupVariable->L05Thunderbolt = 0;
}
//
// "NFC Device" item, 0:Disable, 1:Enable
//
if (SetupVariable->L05OdmNfcDeviceImplement == 0) {
SetupVariable->L05NfcDevice = 0;
}
return EFI_SUCCESS;
}
/**
Update TPM Switch.
1. Update the status of "L05TpmInterfaceType" item.
2. Sync FTPM to Chipset switch.
@param SetupVariable Points to System Configuration Structure
@retval EFI_SUCCESS Returns success by default. The return status will not be referenced.
**/
EFI_STATUS
UpdateTpmSwitch (
IN OUT SYSTEM_CONFIGURATION *SetupVariable
)
{
UINT8 TpmAccess;
TpmAccess = 0;
//
// Update the status of "L05TpmInterfaceType" item
//
TpmAccess = MmioRead8 ((UINTN) PcdGet64 (PcdTpmBaseAddress));
if (IsCrbInterfaceActive () || (TpmAccess == 0xFF)) {
//
// When Interface Type is CRB, or platform can't get valid value from TPM Base,
// that means Discrete TPM is not present.
// So set L05TpmInterfaceType to B_TPM_INTERFACE_CRB for Firmware TPM usage.
//
SetupVariable->L05TpmInterfaceType = B_TPM_INTERFACE_CRB;
} else {
SetupVariable->L05TpmInterfaceType = B_TPM_INTERFACE_FIFO;
}
//
// Sync FTPM to Chipset switch
//
if ((SetupVariable->L05TpmInterfaceType == B_TPM_INTERFACE_CRB) &&
(SetupVariable->L05OdmTpmImplement == 1)) {
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_BROADWELL || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_SKYLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_KABYLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CANNONLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ICELAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_COMETLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_JASPERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE)
if (SetupVariable->PTTEnable != SetupVariable->L05FtpmEnable) {
mIsNeedRestart = TRUE;
}
if ((SetupVariable->L05SetupVariableValid == 1)) {
SetupVariable->PTTEnable = SetupVariable->L05FtpmEnable;
}
#endif
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_APOLLOLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_GEMINILAKE)
//
// TargetTPM = 1, means the platform switch to support DTPM.
// If there is no DTPM device, means TPM is unsupported.
//
if (SetupVariable->TargetTPM != ((SetupVariable->L05FtpmEnable == 1) ? 0 : 1)) {
mIsNeedRestart = TRUE;
}
if ((SetupVariable->L05SetupVariableValid == 1)) {
SetupVariable->TargetTPM = (SetupVariable->L05FtpmEnable == 1) ? 0 : 1;
}
#endif
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CARRIZOLITE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CARRIZO || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_STONEY || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_BRISTOL || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_MULLINLS || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_RAVENRIDGE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_PICASSO || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_RENOIR || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT)
//
// [EnableTPM] 1: DTPM, 2: FTPM.
//
if (SetupVariable->EnableTPM != ((SetupVariable->L05FtpmEnable == 1) ? 2 : 1)) {
mIsNeedRestart = TRUE;
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT)
mIsNeedUpdateApcbTpmConfig = TRUE;
#endif
}
if ((SetupVariable->L05SetupVariableValid == 1)) {
SetupVariable->EnableTPM = (SetupVariable->L05FtpmEnable == 1) ? 2 : 1;
}
#endif
//
// Update TpmHide
// [TpmHide] 0:TPM available, 1:TPM Hidden
// [L05FtpmEnable] 0:Disable, 1:Enable
//
if ((SetupVariable->L05SetupVariableValid == 1)) {
SetupVariable->TpmHide = (SetupVariable->L05FtpmEnable == 1) ? 0 : 1;
}
}
return EFI_SUCCESS;
}
/**
Update BIOS Optane Feature Default.
1. If system is in RST mode, after flash BIOS, should keep RST mode.
2. When RST Mode is selected, BIOS keeps "UEFI/Legacy mode" "EFI only" even when "Optimized Default" is disabled.
@param SetupVariable Points to System Configuration Structure
@param PchSetupBuffer Points to PCH_SETUP Structure
@retval EFI_SUCCESS Returns success by default. The return status will not be referenced.
**/
EFI_STATUS
UpdateBiosOptaneDefault (
IN OUT SYSTEM_CONFIGURATION *SetupVariable,
IN OUT UINT8 *PchSetupBuffer
)
{
#ifdef L05_BIOS_OPTANE_SUPPORT_ENABLE
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CANNONLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ICELAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_COMETLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_JASPERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE)
EFI_STATUS Status;
PCH_SETUP *PchSetup;
UINTN BufferSize;
L05_BACKUP_SETUP_ITEM L05BackupSetupItem;
PchSetup = (PCH_SETUP *) PchSetupBuffer;
//
// According to Lenovo request, if system is in RST mode, after flash BIOS, should keep RST mode, unless user set it to AHCI
//
BufferSize = sizeof (L05_BACKUP_SETUP_ITEM);
Status = gRT->GetVariable (
L05_BACKUP_SETUP_ITEM_VARIABLE_NAME,
&gEfiL05BackupSetupItemVariableGuid,
NULL,
&BufferSize,
&L05BackupSetupItem
);
if (!EFI_ERROR (Status)) {
PchSetup->SataInterfaceMode = L05BackupSetupItem.SataInterfaceMode;
CopyMem (PchSetup->RstPcieRemapEnabled, L05BackupSetupItem.RstPcieRemapEnabled, PCH_MAX_PCIE_ROOT_PORTS);
PchSetup->SataRstOptaneMemory = L05BackupSetupItem.SataRstOptaneMemory;
//
// Clean Backup Setup Item variable
//
Status = gRT->SetVariable (
L05_BACKUP_SETUP_ITEM_VARIABLE_NAME,
&gEfiL05BackupSetupItemVariableGuid,
(EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS),
0,
NULL
);
}
// [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->L05OsOptimizedDefault == 1) // 0: Enable 1:Disable
&& (PchSetup->SataInterfaceMode == SATA_MODE_RAID)) {
//
// Windows 8 64 bit
//
SetupVariable->BootType = 2; // 0:Dual Boot, 2:EFI Boot
SetupVariable->L05SecureBoot = 1; // 0:Disable, 1:Enable
}
#endif
#endif
return EFI_SUCCESS;
}
//[-start-211026-QINGLIN0105-add]//
#ifdef LCFC_SUPPORT
/**
Provide an opportunity to get MFG Mode status.
@param IsMfgMode TRUE: Platform is in MFG Mode.
FALSE: Platform is not in MFG Mode.
@retval EFI_UNSUPPORTED Feature will use the internal function by default.
@retval EFI_MEDIA_CHANGED Feature will refer IsMfgMode flag to update MFG Mode status.
**/
EFI_STATUS
OemSvcGetMfgMode (
IN OUT BOOLEAN *IsMfgMode
)
{
EFI_STATUS Status ;
EFI_GUID LvarMfgModeFlagGuid = LVAR_MFG_MODE_FLAG_GUID;
UINT8 Flag = 0;
UINT32 FlagDataSize = 1;
LENOVO_VARIABLE_PROTOCOL *LenovoVariable;
*IsMfgMode = FALSE;
Status = gBS->LocateProtocol (&gLenovoVariableProtocolGuid, NULL, &LenovoVariable);
if (!EFI_ERROR (Status)) {
Status = LenovoVariable->GetVariable (
LenovoVariable,
&LvarMfgModeFlagGuid,
&FlagDataSize,
(VOID*) (&Flag)
);
if (!EFI_ERROR (Status) && (Flag == 'Y')) {
// MFG mode
*IsMfgMode = TRUE;
return EFI_SUCCESS;
}
}
return EFI_UNSUPPORTED;
}
#endif
//[-end-211026-QINGLIN0105-add]//
/**
Set Variable Exist.
@retval EFI_SUCCESS The operation completed successfully.
@retval Others An unexpected error occurred.
**/
EFI_STATUS
SetVariableExist (
)
{
EFI_STATUS Status;
UINT8 VariableExist;
VariableExist = 0x01;
Status = gRT->SetVariable(
L05_VARIABLE_EXIST_NAME,
&gEfiL05VariableExistGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof (UINT8),
&VariableExist
);
return Status;
}
/**
Update Secure Boot.
@param L05SecureBoot L05 Secure Boot.
@retval EFI_SUCCESS The operation completed successfully.
@retval Others An unexpected error occurred.
**/
EFI_STATUS
UpdateSecureBoot (
IN UINT8 L05SecureBoot
)
{
EFI_STATUS Status;
UINT8 SecureBoot;
UINTN SecureBootSize;
//[-start-20211213-BAIN000066-add]//
#ifdef LCFC_SUPPORT
UINT8 KeepSecureBootMode = 0;
UINTN KeepSecureBootModeSize = sizeof (KeepSecureBootMode);
#endif
//[-end-20211213-BAIN000066-add]//
//
// Check Secure Boot status.
//
SecureBootSize = sizeof (UINT8);
Status = gRT->GetVariable (
EFI_SECURE_BOOT_ENFORCE_NAME,
&gEfiGenericVariableGuid,
NULL,
&SecureBootSize,
&SecureBoot
);
if (EFI_ERROR (Status)) {
return Status;
}
//[-start-20211213-BAIN000066-add]//
#ifdef LCFC_SUPPORT
Status = gRT->GetVariable (
L"KeepSecureBootMode",
&gLfcVariableGuid,
NULL,
&KeepSecureBootModeSize,
&KeepSecureBootMode
);
if(Status == EFI_SUCCESS) {
return Status;
}
#endif
//[-end-20211213-BAIN000066-add]//
if (L05SecureBoot != SecureBoot) {
mIsNeedUpdateSecureBoot = TRUE;
mSetL05SecureBoot = L05SecureBoot;
}
return Status;
}
/**
New BIOS set Secure Boot to Disable.
@param SetupVariable Points to System Configuration Structure.
@retval EFI_SUCCESS The operation completed successfully.
@retval Others An unexpected error occurred.
**/
EFI_STATUS
NewBiosUpdateSecureBoot (
IN OUT SYSTEM_CONFIGURATION *SetupVariable
)
{
EFI_STATUS Status;
UINTN BufferSize;
UINT8 VariableExist;
BufferSize = sizeof (UINT8);
Status = gRT->GetVariable (
L05_VARIABLE_EXIST_NAME,
&gEfiL05VariableExistGuid,
NULL,
&BufferSize,
&VariableExist
);
if (!EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
//
// "L05 Secure Boot" item, 0:Disable, 1:Enable
//
SetupVariable->L05SecureBoot = 0;
//
// Set Variable Exist.
//
Status = SetVariableExist ();
return Status;
}
/**
MFG mode set Secure Boot to Enable.
@param SetupVariable Points to System Configuration Structure.
@retval EFI_SUCCESS The operation completed successfully.
@retval Others An unexpected error occurred.
**/
EFI_STATUS
MfgModeUpdateSecureBoot (
IN OUT SYSTEM_CONFIGURATION *SetupVariable
)
{
EFI_STATUS Status;
BOOLEAN IsMfgMode;
IsMfgMode = FALSE;
Status = OemSvcGetMfgMode (&IsMfgMode);
if (EFI_ERROR (Status) || !IsMfgMode) {
return EFI_UNSUPPORTED;
}
//
// "L05 Secure Boot" item, 0:Disable, 1:Enable
//
SetupVariable->L05SecureBoot = 0;
return Status;
}
/**
Override Default Setup Setting Function.
It will be called in two cases as below,
1. Variable L"Setup" not exist during POST
2. End user do "Load Default" in Setup Menu
@param SetupBuffer Points to System Configuration Structure
@param PchSetupBuffer Points to PCH_SETUP Structure
@param CpuSetupBuffer Points to CPU_SETUP Structure
@param SaSetupBuffer Points to SA_SETUP Structure
@retval EFI_SUCCESS Returns success by default. The return status will not be referenced.
**/
EFI_STATUS
OverrideDefaultSetupSetting (
IN OUT UINT8 *SetupBuffer,
IN OUT UINT8 *PchSetupBuffer,
IN OUT UINT8 *CpuSetupBuffer,
IN OUT UINT8 *SaSetupBuffer
)
{
EFI_STATUS Status;
SYSTEM_CONFIGURATION *SetupVariable;
#if (FixedPcdGetBool (PcdL05PchSetupSupported))
PCH_SETUP *PchSetup;
CPU_SETUP *CpuSetup;
SA_SETUP *SaSetup;
#endif
if (SetupBuffer == NULL) {
return EFI_UNSUPPORTED;
}
#if (FixedPcdGetBool (PcdL05PchSetupSupported))
if ((PchSetupBuffer == NULL) || (CpuSetupBuffer == NULL) || (SaSetupBuffer == NULL)) {
return EFI_UNSUPPORTED;
}
#endif
Status = EFI_SUCCESS;
SetupVariable = (SYSTEM_CONFIGURATION *) SetupBuffer;
#if (FixedPcdGetBool (PcdL05PchSetupSupported))
PchSetup = (PCH_SETUP *) PchSetupBuffer;
CpuSetup = (CPU_SETUP *) CpuSetupBuffer;
SaSetup = (SA_SETUP *) SaSetupBuffer;
#endif
//
// [Lenovo China Minimum BIOS Spec 1.29]
// [3.12.4 Boot Menu] - Enable EFI boot type in Windows 8 64 bit
// [3.12.2 Configuration menu] - Hide "Usb legacy" item in EFI Boot
// [10.1 Secure boot] - Secure boot only support in EFI boot
//
if (SetupVariable->L05OsOptimizedDefault == 0) {
//
// Windows 8 64 bit
//
SetupVariable->BootType = 2; // 0:Dual Boot, 2:EFI Boot
SetupVariable->L05SecureBoot = 1; // 0:Disable, 1:Enable
} else {
//
// Legacy O.S.
//
SetupVariable->BootType = 0; // 0:Dual Boot, 2:EFI Boot
SetupVariable->L05SecureBoot = 0; // 0:Disable, 1:Enable
}
//
// When L05WlanSyncToChipsetWlan is Enable (1),
// system will synchronize the L05 WLAN switch (SYSTEM_CONFIGURATION.L05WirelessLan) with with Chipset WLAN.
// Intel: CNVi switch (PCH_SETUP.CnviMode).
// AMD: WLAN/WIFI Power Enable (AMD_PBS_SETUP_OPTION.WlanPowerControl)
//
if (SetupVariable->L05WlanSyncToChipsetWlan == 1 && SetupVariable->L05OdmWirelessLanImplement == 1) {
//
// "CNVi Mode" item, 0:Disable Integrated, 1:Auto Detection
// "Wireless LAN" item, 0:Disable, 1:Enable
//
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CANNONLAKE)
//
// "CNVi Mode" item, 0:Disable Integrated, 1:Auto Detection
// "Wireless LAN" item, 0:Disable, 1:Enable
//
PchSetup->PchCnviMode = SetupVariable->L05WirelessLan;
#endif
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ICELAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_COMETLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_TIGERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_JASPERLAKE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE)
PchSetup->CnviMode = SetupVariable->L05WirelessLan;
#endif
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_RAVENRIDGE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_PICASSO || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_RENOIR || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_CEZANNE || \
FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT)
{
AMD_PBS_SETUP_OPTION AmdPbsSetupConfig;
UINTN AmdPbsSetupBufferSize;
GUID AmdPbsSystemConfigurationGuid = AMD_PBS_SETUP_GUID;
ZeroMem (&AmdPbsSetupConfig, sizeof (AMD_PBS_SETUP_OPTION));
AmdPbsSetupBufferSize = sizeof (AMD_PBS_SETUP_OPTION);
Status = gRT->GetVariable (
AMD_PBS_SETUP_VARIABLE_NAME,
&AmdPbsSystemConfigurationGuid,
NULL,
&AmdPbsSetupBufferSize,
&AmdPbsSetupConfig
);
if (!EFI_ERROR (Status)) {
if (AmdPbsSetupConfig.WlanPowerControl != SetupVariable->L05WirelessLan) {
//
// "WLAN/WIFI Power Enable" item, 0:Disable, 1:Enable
// "Wireless LAN" item, 0:Disable, 1:Enable
//
AmdPbsSetupConfig.WlanPowerControl = SetupVariable->L05WirelessLan;
Status = gRT->SetVariable(
AMD_PBS_SETUP_VARIABLE_NAME,
&AmdPbsSystemConfigurationGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof (AMD_PBS_SETUP_OPTION),
&AmdPbsSetupConfig
);
}
}
}
#endif
}
//
// Set AMD Switchable Graphics default value by L05GraphicsDeviceSupport
//
#if (FixedPcdGetBool (PcdL05SwitchableGraphicsSupported))
#if (FixedPcdGetBool (PcdL05AmdSetupSupported))
{
AMD_PBS_SETUP_OPTION AmdPbsSetupConfig;
UINTN AmdPbsSetupBufferSize;
GUID AmdPbsSystemConfigurationGuid = AMD_PBS_SETUP_GUID;
ZeroMem (&AmdPbsSetupConfig, sizeof (AMD_PBS_SETUP_OPTION));
AmdPbsSetupBufferSize = sizeof (AMD_PBS_SETUP_OPTION);
Status = gRT->GetVariable (
AMD_PBS_SETUP_VARIABLE_NAME,
&AmdPbsSystemConfigurationGuid,
NULL,
&AmdPbsSetupBufferSize,
&AmdPbsSetupConfig
);
if (!EFI_ERROR (Status)) {
//
// "Switchable Graphics" item, 0:UMA Graphics, 4:Switchable Graphics
//
if (SetupVariable->L05GraphicsDeviceSupport == 1) {
AmdPbsSetupConfig.SpecialVgaFeature = 4;
} else {
AmdPbsSetupConfig.SpecialVgaFeature = 0;
}
Status = gRT->SetVariable(
AMD_PBS_SETUP_VARIABLE_NAME,
&AmdPbsSystemConfigurationGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof (AMD_PBS_SETUP_OPTION),
&AmdPbsSetupConfig
);
}
}
#endif
#endif
//
// Update TPM switch
//
UpdateTpmSwitch (SetupVariable);
#ifdef L05_BIOS_OPTANE_SUPPORT_ENABLE
//
// Update BIOS Optane Feature Default
//
UpdateBiosOptaneDefault (SetupVariable, PchSetupBuffer);
#endif
#ifdef L05_MFG_MODE_SECURE_BOOT_ENABLE
//
// New BIOS Mode set Secure Boot to Disable
//
NewBiosUpdateSecureBoot (SetupVariable);
//
// MFG Mode update Secure Boot
//
MfgModeUpdateSecureBoot (SetupVariable);
//
// Update Secure Boot
//
UpdateSecureBoot (SetupVariable->L05SecureBoot);
#endif
return EFI_SUCCESS;
}
/**
Update the Setup Variable L05FlipToBoot if Variable "FBSWIF' is exist.
@param SetupVariable Points to System Configuration Structure.
@retval EFI_SUCCESS The operation completed successfully.
@retval Others An unexpected error occurred.
**/
EFI_STATUS
UpdateFlipToBoot (
IN OUT SYSTEM_CONFIGURATION *SetupVariable
)
{
EFI_STATUS Status;
LENOVO_FLIP_TO_BOOT_SW_INTERFACE L05FlipToBootVar;
UINTN L05FlipToBootVarSize;
L05FlipToBootVarSize = sizeof (LENOVO_FLIP_TO_BOOT_SW_INTERFACE);
Status = gRT->GetVariable (
L05_EFI_FLIP_TO_BOOT_VARIABLE_NAME,
&gEfiL05FliptoBootVariableGuid,
NULL,
&L05FlipToBootVarSize,
&L05FlipToBootVar
);
if (!EFI_ERROR (Status)) {
SetupVariable->L05FlipToBoot = L05FlipToBootVar.FlipToBootEn;
return EFI_SUCCESS;
}
L05FlipToBootVar.FlipToBootEn = SetupVariable->L05FlipToBoot;
Status = gRT->SetVariable (
L05_EFI_FLIP_TO_BOOT_VARIABLE_NAME,
&gEfiL05FliptoBootVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (LENOVO_FLIP_TO_BOOT_SW_INTERFACE),
&L05FlipToBootVar
);
if (EFI_ERROR (Status)) {
return Status;
}
return Status;
}
/**
Override Setup Setting During Post Function.
It will be called during every POST (G3/S5 -> S0, S4 -> S0).
@param SetupBuffer Points to System Configuration Structure
@retval EFI_SUCCESS Returns success by default. The return status will not be referenced.
**/
EFI_STATUS
OverrideSetupSettingDuringPost (
IN OUT UINT8 *SetupBuffer
)
{
EFI_STATUS Status;
UINTN L05BufferSize;
UINT8 L05Data;
SYSTEM_CONFIGURATION *SetupVariable;
UINT8 IsNvmePresence;
SetupVariable = (SYSTEM_CONFIGURATION *) SetupBuffer;
IsNvmePresence = 0;
//
// Update the status of "Secure Boot" item
//
L05BufferSize = sizeof (UINT8);
Status = gRT->GetVariable (
EFI_SECURE_BOOT_ENFORCE_NAME,
&gEfiGenericVariableGuid,
NULL,
&L05BufferSize,
&L05Data
);
if (!EFI_ERROR (Status)) {
SetupVariable->L05SecureBoot = L05Data;
} else {
if (SetupVariable->BootType == 2) { // 0:Dual Boot, 2:EFI Boot
SetupVariable->L05SecureBoot = 1; // 0:Disable, 1:Enable
} else {
SetupVariable->L05SecureBoot = 0; // 0:Disable, 1:Enable
}
}
//
// Update the status of "Platform Mode" item
//
L05BufferSize = sizeof (UINT8);
Status = gRT->GetVariable (
EFI_SETUP_MODE_NAME,
&gEfiGlobalVariableGuid,
NULL,
&L05BufferSize,
&L05Data
);
if (!EFI_ERROR (Status)) {
SetupVariable->L05PlatformMode = L05Data;
} else {
SetupVariable->L05PlatformMode = 1; // 0:User Mode, 1:Setup Mode
}
//
// Update the status of "Secure Boot Mode" item
//
L05BufferSize = sizeof (UINT8);
Status = gRT->GetVariable (
EFI_CUSTOM_SECURITY_NAME,
&gEfiGenericVariableGuid,
NULL,
&L05BufferSize,
&L05Data
);
if (!EFI_ERROR (Status)) {
SetupVariable->L05SecureBootMode = L05Data;
} else {
SetupVariable->L05SecureBootMode = 0; // 0:Standard, 1:Custom
}
//
// Update the status of "Win8FastBoot" item with L05FastBoot.
//
if (SetupVariable->L05FastBootImplement == 1) {
if (SetupVariable->L05FastBoot == 1) { // 1:Enable, 0:Disable
SetupVariable->Win8FastBoot = 0; // 0:Enable, 1:Disable
} else {
SetupVariable->Win8FastBoot = 1; // 0:Enable, 1:Disable
}
}
//
// [Lenovo BIOS Optane Support Version 1.4 Page 12]
// BIOS detects NVMe device by using GPIO and ECFW I/F Space
// IsNvmePresence 0: Optane does not exist in Optane/WWAN Slot and NVMe does not exist in Main Storage Slot.
// 1: Optane does not exist in Optane/WWAN Slot and NVMe exists in Main Storage Slot.
// 2: Optane exists in Optane/WWAN Slot. It's no matter whether Main Storage Slot have NVMe or not.
//
Status = OemSvcDetectNvmePresence (&IsNvmePresence);
SetupVariable->L05IsNvmePresence = IsNvmePresence;
//
// Update TPM switch
//
UpdateTpmSwitch (SetupVariable);
#ifdef L05_MFG_MODE_SECURE_BOOT_ENABLE
//
// MFG Mode update Secure Boot
//
MfgModeUpdateSecureBoot (SetupVariable);
//
// Update Secure Boot status
//
UpdateSecureBoot (SetupVariable->L05SecureBoot);
#endif
//
// Update the Setup Variable L05FlipToBoot if Variable "FBSWIF' is exist.
//
Status = UpdateFlipToBoot (SetupVariable);
Status = OemSvcOverrideSetupSettingDuringPost (SetupBuffer);
//
// OEM Switch
//
Status = OemSvcSwitchWirelessLan (DuringPost, SetupVariable->L05WirelessLan);
Status = OemSvcSwitchHotKeyMode (DuringPost, SetupVariable->L05HotKeyMode);
Status = OemSvcSwitchFoolProofFnCtrl (DuringPost, SetupVariable->L05FoolProofFnCtrl);
Status = OemSvcSwitchAlwaysOnUsb (DuringPost, SetupVariable->L05AlwaysOnUsb);
Status = OemSvcSwitchChargeInBatteryMode (DuringPost, SetupVariable->L05ChargeInBatteryMode);
#ifndef L05_GAMING_UI_ENABLE
Status = OemSvcSwitchSystemPerformanceMode (DuringPost, SetupVariable->L05SystemPerformanceMode);
#else
Status = OemSvcSwitchThermalMode (DuringPost, SetupVariable->L05ThermalMode);
Status = OemSvcSwitchRestoreDefaultOverclocking (DuringPost, SetupVariable->L05RestoreDefaultOverclocking);
Status = OemSvcSwitchWakeOnVoice (DuringPost, SetupVariable->L05WakeOnVoice);
Status = OemSvcSwitchUltraQuietMode (DuringPost, SetupVariable->L05UltraQuietMode);
Status = OemSvcSwitchInstantBoot (DuringPost, SetupVariable->L05InstantBoot);
// [Lenovo BIOS Setup Design Guide V2.8]
// Configuration Page
// Restore Default Overclocking
// The item will work once, if Users select "Enabled", system will set it to "Disabled" in next boot.
//
SetupVariable->L05RestoreDefaultOverclocking = 0; // 1:Enable, 0:Disable
#endif
Status = OemSvcSwitchFlipToBoot (DuringPost, SetupVariable->L05FlipToBoot);
#ifdef L05_ONE_KEY_BATTERY_ENABLE
Status = OemSvcSwitchOneKeyBattery (DuringPost, SetupVariable->L05OneKeyBattery);
#endif
//
// I/O Port Access
//
Status = OemSvcSwitchEthernetLan (DuringPost, SetupVariable->L05EthernetLan);
Status = OemSvcSwitchWirelessWan (DuringPost, SetupVariable->L05WirelessWan);
Status = OemSvcSwitchBluetooth (DuringPost, SetupVariable->L05Bluetooth);
Status = OemSvcSwitchUsbPort (DuringPost, SetupVariable->L05UsbPort);
Status = OemSvcSwitchMemoryCardSlot (DuringPost, SetupVariable->L05MemoryCardSlot);
Status = OemSvcSwitchSmartCardSlot (DuringPost, SetupVariable->L05SmartCardSlot);
Status = OemSvcSwitchIntegratedCamera (DuringPost, SetupVariable->L05IntegratedCamera);
Status = OemSvcSwitchMicrophone (DuringPost, SetupVariable->L05Microphone);
Status = OemSvcSwitchFingerprintReader (DuringPost, SetupVariable->L05FingerprintReader);
Status = OemSvcSwitchThunderbolt (DuringPost, SetupVariable->L05Thunderbolt);
Status = OemSvcSwitchNfcDevice (DuringPost, SetupVariable->L05NfcDevice);
//
// Get GPU Type for Overclock
//
Status = OemSvcGetGpuType (&SetupVariable->L05GpuType);
//
// This flag should be last item.
// Make sure all L05 Setup Variable is valid.
//
SetupVariable->L05SetupVariableValid = 1;
return EFI_SUCCESS;
}
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT)
/**
Update APCB with System TPM configuration.
(refer to AMD\Rembrandt\Fp7ChipsetPkg\UefiSetupUtilityDxe\GenericCallback.c AmdUpdateAPCBWithTpmConfig())
@param SystemTpmConfig System TPM configuration.
@retval EFI_SUCCESS Returns success by default. The return status will not be referenced.
**/
EFI_STATUS
AmdUpdateAPCBWithTpmConfig (
IN UINT8 SystemTpmConfig
)
{
EFI_STATUS Status;
UINT8 ApcbTpmConfig;
UINT8 ApcbPurpose;
BOOLEAN IsTpmConfigChanged;
AMD_APCB_SERVICE_PROTOCOL *ApcbDxeServiceProtocol;
DEBUG ((DEBUG_INFO, "Enter %a: SystemTpmConfig %x \n", __FUNCTION__, SystemTpmConfig));
Status = gBS->LocateProtocol (&gAmdApcbDxeServiceProtocolGuid, NULL, &ApcbDxeServiceProtocol);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO,"Unable to locate APCB Protocol \n"));
return Status;
}
// Since it is select on IBV Setup item, it need to sync back to PSP APOB correct value
switch (SystemTpmConfig) {
case 0: // BIOS Setup Disable
SystemTpmConfig = 0xFF;
break;
case 1: // BIOS Setup d-TPM
SystemTpmConfig = 0x00;
break;
case 2: // BIOS Setup AMD PSP fTPM
SystemTpmConfig = 0x01;
break;
case 3: // BIOS Setup AMD HSP
SystemTpmConfig = 0x02;
break;
default:
SystemTpmConfig = 0xFF;
break;
}
IsTpmConfigChanged = FALSE;
ASSERT (ApcbDxeServiceProtocol != NULL);
//step 2: sync TPM config
//system TPM config is set by SBIOS in PEI phase
//read APCB TPM config
ApcbTpmConfig = SYSTEM_TPM_CONFIG_NONE;
Status = ApcbDxeServiceProtocol->ApcbGetToken8 (ApcbDxeServiceProtocol, &ApcbPurpose, APCB_TOKEN_UID_PSP_SYSTEM_TPM_CONFIG, &ApcbTpmConfig);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO,"1.Unable to get APCB token APCB_TOKEN_UID_PSP_SYSTEM_TPM_CONFIG \n"));
} else {
if (SystemTpmConfig != ApcbTpmConfig) { //ABL TPM config is out of date, update it and reset system
DEBUG ((DEBUG_INFO,"SystemTpmConfig: %d, ApcbTpmConfig: %d, update TPM config in APCB \n", SystemTpmConfig, ApcbTpmConfig));
Status = ApcbDxeServiceProtocol->ApcbSetToken8 (ApcbDxeServiceProtocol, APCB_TYPE_PURPOSE_ADMIN, APCB_TOKEN_UID_PSP_SYSTEM_TPM_CONFIG, SystemTpmConfig);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO,"Unable to set APCB token APCB_TOKEN_UID_PSP_SYSTEM_TPM_CONFIG \n"));
} else {
Status = ApcbDxeServiceProtocol->ApcbGetToken8 (ApcbDxeServiceProtocol, &ApcbPurpose, APCB_TOKEN_UID_PSP_SYSTEM_TPM_CONFIG, &ApcbTpmConfig);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO,"2.Unable to get APCB token APCB_TOKEN_UID_PSP_SYSTEM_TPM_CONFIG \n"));
} else {
if (SystemTpmConfig == ApcbTpmConfig) { //update successfully
IsTpmConfigChanged = TRUE;
} else { //update failed
DEBUG ((DEBUG_INFO,"Critial error: update to APCB token APCB_TOKEN_UID_PSP_SYSTEM_TPM_CONFIG doesn't take effect\n"));
}
}
}
}
}
if (IsTpmConfigChanged) {
//Write back updated data to SPI
ApcbDxeServiceProtocol->ApcbFlushData (ApcbDxeServiceProtocol);
DEBUG ((DEBUG_INFO,"TPM config changed...\n"));
}
return Status;
}
#endif
/**
This is the callback function after gEfiSetupUtilityProtocolGuid is installed.
It will ensure SYSTEM_CONFIGURATION.TpmHide status is consistent & correct in POST.
If not, reset platform.
@param Event Event whose notification function is being invoked.
@param Context Pointer to the notification function's context.
**/
VOID
EFIAPI
RestartCallback (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
VOID *SetupUtility;
UINTN BufferSize;
SYSTEM_CONFIGURATION SetupNvData;
EFI_BOOT_MODE BootMode;
EFI_L05_SECURE_BOOT_PROTOCOL *L05SecureBootProtocol;
EFI_L05_SECURE_BOOT_DATA L05SecureBootData;
BootMode = GetBootModeHob();
Status = gBS->LocateProtocol (
&gEfiSetupUtilityProtocolGuid,
NULL,
(VOID **) &SetupUtility
);
if (EFI_ERROR (Status)) {
return;
}
gBS->CloseEvent (Event);
BufferSize = sizeof (SYSTEM_CONFIGURATION);
Status = gRT->GetVariable (
L"Setup",
&gSystemConfigurationGuid,
NULL,
&BufferSize,
&SetupNvData
);
if (EFI_ERROR (Status)) {
return;
}
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_REMBRANDT)
//
// Update APCB TPM configuration.
//
if (mIsNeedUpdateApcbTpmConfig) {
AmdUpdateAPCBWithTpmConfig (SetupNvData.EnableTPM);
}
#endif
//
// Ensure TpmHide status is consistent in POST.
// If not, reset platform.
//
if (SetupNvData.TpmHide != PcdGetBool (PcdTpmHide)) {
mIsNeedRestart = TRUE;
}
//
// Ensure TpmHide status is correct for FTPM in POST.
// If not, reset platform.
//
if ((SetupNvData.L05TpmInterfaceType == B_TPM_INTERFACE_CRB) &&
(SetupNvData.L05OdmTpmImplement == 1) &&
(SetupNvData.TpmHide != ((SetupNvData.L05FtpmEnable == 1) ? 0 : 1))) {
mIsNeedRestart = TRUE;
}
//
// Update Secure Boot for MFG Mode.
//
if (mIsNeedUpdateSecureBoot) {
L05SecureBootProtocol = NULL;
ZeroMem (&L05SecureBootData, sizeof (EFI_L05_SECURE_BOOT_DATA));
L05SecureBootData.Action = (mSetL05SecureBoot == 0) ? L05_SECURE_BOOT_DISABLE : L05_SECURE_BOOT_ENABLE;
Status = gBS->LocateProtocol (
&gEfiL05SecureBootProtocolGuid,
NULL,
&L05SecureBootProtocol
);
if (!EFI_ERROR (Status)) {
Status = L05SecureBootProtocol->L05SecureBootCallback (&L05SecureBootData);
mIsNeedRestart = TRUE;
}
}
if (mIsNeedRestart && (BootMode != BOOT_IN_RECOVERY_MODE)) {
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
}
return;
}
/**
Display strings before handler to display before/after string based on H2O_BDS_CP_DISPLAY_STRING_BEFORE_DATA.AfterSelect with Boot Mode.
@param[in] Event A pointer to the Event that triggered the callback.
@param[in] Handle Checkpoint handle.
**/
STATIC
VOID
EFIAPI
DisplayStringBeforeWithBootModeHandler (
IN EFI_EVENT Event,
IN H2O_CP_HANDLE Handle
)
{
EFI_STATUS Status;
H2O_BDS_CP_DISPLAY_STRING_BEFORE_DATA *BdsDisplayStringBeforeData;
EFI_GUID BdsDisplayStringBeforeGuid;
EFI_BOOT_MODE BootMode;
Status = H2OCpLookup (Handle, (VOID **) &BdsDisplayStringBeforeData, &BdsDisplayStringBeforeGuid);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Checkpoint Data Not Found: %x (%r)\n", Handle, Status));
DEBUG ((DEBUG_ERROR, " %a\n", __FUNCTION__));
return;
}
BootMode = GetBootModeHob ();
#ifdef L05_SMB_BIOS_ENABLE
//_Start_L05_INTERRUPT_MENU_
//
// [Lenovo SMB BIOS Special Requirements V1.1]
// 2.2 Hotkey Definition
// Startup Interrupt Menu
// During BIOS POST, the feature needs to show POST string "To interrupt normal startup, press Enter",
// in order to keep same behavior with ThinkPad, we only need to show it while S5 or reset, not request
// for S4.
//
{
if (BootMode != BOOT_WITH_FULL_CONFIGURATION) {
BdsDisplayStringBeforeData->Status = H2O_BDS_TASK_SKIP;
}
}
//_End_L05_INTERRUPT_MENU_
#endif
return;
}
/**
This is the declaration of an EFI image entry point. This entry point is
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
both device drivers and bus drivers.
@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
EFIAPI
SetupMenuServiceDriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_L05_SETUP_MENU_PROTOCOL *L05SetupMenuPtr;
EFI_HANDLE Handle;
VOID *Registration;
H2O_CP_HANDLE CpHandle;
Status = EFI_SUCCESS;
Handle = NULL;
L05SetupMenuPtr = AllocateZeroPool (sizeof (EFI_L05_SETUP_MENU_PROTOCOL));
if (L05SetupMenuPtr == NULL) {
return EFI_OUT_OF_RESOURCES;
}
L05SetupMenuPtr->IsValidKeyData = IsValidKeyData;
L05SetupMenuPtr->ConvertUnicodeCharToKeyboardScancode = ConvertUnicodeCharToKeyboardScancode;
L05SetupMenuPtr->HideDisableProjectDependencyItem = HideDisableProjectDependencyItem;
L05SetupMenuPtr->OverrideDefaultSetupSetting = OverrideDefaultSetupSetting;
L05SetupMenuPtr->OverrideSetupSettingDuringPost = OverrideSetupSettingDuringPost;
Status = gBS->InstallProtocolInterface (
&Handle,
&gEfiL05SetupMenuProtocolGuid,
EFI_NATIVE_INTERFACE,
L05SetupMenuPtr
);
if (EFI_ERROR (Status)) {
return Status;
}
if (FeaturePcdGet (PcdL05EnsureTpmStatusSupported)) {
Registration = NULL;
EfiCreateProtocolNotifyEvent (
&gEfiSetupUtilityProtocolGuid,
TPL_NOTIFY,
RestartCallback,
NULL,
&Registration
);
}
if (FeaturePcdGet (PcdH2OBdsCpDisplayStringBeforeSupported)) {
Status = H2OCpRegisterHandler (
&gH2OBdsCpDisplayStringBeforeGuid,
DisplayStringBeforeWithBootModeHandler,
H2O_CP_MEDIUM,
&CpHandle
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Checkpoint Register Fail: %g (%r)\n", &gH2OBdsCpDisplayStringBeforeGuid, Status));
return Status;
}
DEBUG ((DEBUG_INFO, "Checkpoint Registered: %g (%r)\n", &gH2OBdsCpDisplayStringBeforeGuid, Status));
}
return Status;
}