955 lines
35 KiB
C
955 lines
35 KiB
C
/*****************************************************************************
|
|
*
|
|
*
|
|
* Copyright (c) 2012 - 2015, Hefei LCFC Information Technology Co.Ltd.
|
|
* And/or its affiliates. All rights reserved.
|
|
* Hefei LCFC Information Technology Co.Ltd. PROPRIETARY/CONFIDENTIAL.
|
|
* Use is subject to license terms.
|
|
*
|
|
*****************************************************************************/
|
|
/*
|
|
Data Name Version Description
|
|
2013.12.13 dahai.zhou v1.00 Initial release it for EDK2 projects
|
|
2013.12.16 dahai.zhou v1.01 Fix the issue that ChgBoot.exe can't change LAN sequence
|
|
2013.12.23 dahai.zhou v1.02 Add Lenovo Fast Boot supported
|
|
2014.01.25 dahai.zhou v1.03 Update UsbLegacy if change boot type
|
|
2014.04.22 dahai.zhou v1.04 Remove the UsbLegacy item since it's for BaytrailM only, and remove some project code
|
|
2014.05.21 dahai.zhou v1.05 Update the OneTimeDisableFastBoot GUID to LFC GUID
|
|
2014.06.03 dahai.zhou v1.06 Remove project dependent code, use library routine GetSwSmiSubFunctionNumber and SetSwSmiSubFunctionNumber instead
|
|
2015.01.05 erhu.wang v1.07 Add debug mode secure flash method, which use a self-defined varible to control
|
|
2015.03.26 cissie.gu v1.08 Add usb charge disable and enable function
|
|
2015.05.25 dahai.zhou v1.09 Support tpmdis and tpmen command
|
|
2015.09.15 dahai.zhou v1.10 Rename LOAD_WIN8_64_DEFAULT_FUNCTION to LOAD_UEFI_OS_DEFAULT_FUNCTION
|
|
Support sbrestore command
|
|
2015.11.03 dahai.zhou v1.11 Update ChgBoot load default method to use UEFI variable instead of use LVAR
|
|
Add new command SB_RESTORE_FACTORY_DEFAULT_FUNCTION, sbrestore
|
|
Must co-work with BIOS design guide V2.19 or newer
|
|
2016.01.03 ned.li v1.12 Add full reset on the next reboot.
|
|
2016.02.03 rita.zhang v1.13 Write disable Secure Boot flag when use dualboot command.
|
|
2016.05.25 rita.zhang v1.14 Update ChgBoot driver in LfcPkg trunk according to the new spec. Add new OutPut status FUNCTION_UNSUPPORTED.
|
|
2016.08.31 Brick.Ji v1.15 Add /pben and /pbdis command.
|
|
2016.09.28 rita.zhang v1.16 Add /ooen and /oodis command.
|
|
2016.09.28 Ned.li v1.17 Add /sataraid and /sataahci command.
|
|
2018.09.29 rita.zhang v1.18 Remove /pben and /pbdis command.
|
|
2018.12.21 wita/rita v1.19 Add charge in battery mode code to sync with Lenovo Vantage to support AOU.
|
|
2019.01.04 rita.zhang v1.20 Uefios&legacyos command remove delete "Setup" variable behavior.(commands sync to F9 common porting part)
|
|
2019.01.14 rita.zhang v1.21 Add igpu/idgpu/dgpu command.
|
|
*/
|
|
|
|
#include "ChgBootSmm.h"
|
|
//[-start-211027-QINGLIN0106-add]//
|
|
//[-start-211124-kebin000069-modify]//
|
|
//[-start-220113-YUNLEI0158-modify]//
|
|
#if defined(S370_SUPPORT) || defined(C970_SUPPORT) || defined(C770_SUPPORT)
|
|
//[-end-220113-YUNLEI0158-modify]//
|
|
//[-end-211124-kebin000069-modify]//
|
|
#ifndef B_CPUID_POWER_MANAGEMENT_EAX_TURBO
|
|
#define B_CPUID_POWER_MANAGEMENT_EAX_TURBO BIT1
|
|
#endif
|
|
#ifndef MSR_IA32_MISC_ENABLE
|
|
#define MSR_IA32_MISC_ENABLE 0x1A0
|
|
#endif
|
|
#ifndef B_MSR_IA32_MISC_DISABLE_TURBO
|
|
#define B_MSR_IA32_MISC_DISABLE_TURBO BIT38
|
|
#endif
|
|
|
|
#pragma pack(1)
|
|
typedef union _MSR_REGISTER {
|
|
UINT64 Qword;
|
|
|
|
struct _DWORDS {
|
|
UINT32 Low;
|
|
UINT32 High;
|
|
} Dwords;
|
|
|
|
struct _BYTES {
|
|
UINT8 FirstByte;
|
|
UINT8 SecondByte;
|
|
UINT8 ThirdByte;
|
|
UINT8 FouthByte;
|
|
UINT8 FifthByte;
|
|
UINT8 SixthByte;
|
|
UINT8 SeventhByte;
|
|
UINT8 EighthByte;
|
|
} Bytes;
|
|
|
|
} MSR_REGISTER;
|
|
#pragma pack()
|
|
|
|
#pragma pack(1)
|
|
typedef struct {
|
|
UINT32 RegEax;
|
|
UINT32 RegEbx;
|
|
UINT32 RegEcx;
|
|
UINT32 RegEdx;
|
|
} EFI_CPUID_REGISTER;
|
|
#pragma pack()
|
|
#endif
|
|
//[-end-211027-QINGLIN0106-add]//
|
|
|
|
EFI_STATUS
|
|
CheckLcfcSubFunction (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 SmiData;
|
|
|
|
GetSwSmiSubFunctionNumber (&SmiData); // Read SMI ID
|
|
|
|
switch (SmiData) {
|
|
case FUNCTION_ENABLE_HOT_KEY_MODE:
|
|
case FUNCTION_DISABLE_HOT_KEY_MODE:
|
|
{
|
|
UINTN DataSize;
|
|
EFI_SMM_VARIABLE_PROTOCOL *SmmVariable;
|
|
SYSTEM_CONFIGURATION SetupVariable;
|
|
EFI_GUID SystemConfigurationGuid = SYSTEM_CONFIGURATION_GUID;
|
|
|
|
Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, &SmmVariable);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
DataSize = sizeof (SYSTEM_CONFIGURATION);
|
|
Status = SmmVariable->SmmGetVariable (
|
|
L"Setup",
|
|
&SystemConfigurationGuid,
|
|
NULL,
|
|
&DataSize,
|
|
&SetupVariable
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
SetupVariable.L05HotKeyMode = (SmiData == FUNCTION_ENABLE_HOT_KEY_MODE)?1:0;
|
|
Status = SmmVariable->SmmSetVariable (
|
|
L"Setup",
|
|
&SystemConfigurationGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
DataSize,
|
|
&SetupVariable
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
case FUNCTION_ENABLE_USB_CHARGE_MODE:
|
|
case FUNCTION_DISABLE_USB_CHARGE_MODE:
|
|
{
|
|
UINTN DataSize;
|
|
EFI_SMM_VARIABLE_PROTOCOL *SmmVariable;
|
|
SYSTEM_CONFIGURATION SetupVariable;
|
|
EFI_GUID SystemConfigurationGuid = SYSTEM_CONFIGURATION_GUID;
|
|
|
|
Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, &SmmVariable);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
DataSize = sizeof (SYSTEM_CONFIGURATION);
|
|
Status = SmmVariable->SmmGetVariable (
|
|
L"Setup",
|
|
&SystemConfigurationGuid,
|
|
NULL,
|
|
&DataSize,
|
|
&SetupVariable
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
//[-start-210514-BAINTEST-modify]//
|
|
// SetupVariable.L05AlwaysOnUSB = (SmiData == FUNCTION_ENABLE_USB_CHARGE_MODE)?1:0;
|
|
SetupVariable.L05AlwaysOnUsb = (SmiData == FUNCTION_ENABLE_USB_CHARGE_MODE)?1:0;
|
|
//[-end-210514-BAINTEST-modify]//
|
|
Status = SmmVariable->SmmSetVariable (
|
|
L"Setup",
|
|
&SystemConfigurationGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
DataSize,
|
|
&SetupVariable
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
case FUNCTION_ENABLE_CHARGE_IN_BATTERY_MODE:
|
|
case FUNCTION_DISABLE_CHARGE_IN_BATTERY_MODE:
|
|
{
|
|
UINTN DataSize;
|
|
EFI_SMM_VARIABLE_PROTOCOL *SmmVariable;
|
|
SYSTEM_CONFIGURATION SetupVariable;
|
|
EFI_GUID SystemConfigurationGuid = SYSTEM_CONFIGURATION_GUID;
|
|
|
|
Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, &SmmVariable);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
DataSize = sizeof (SYSTEM_CONFIGURATION);
|
|
Status = SmmVariable->SmmGetVariable (
|
|
L"Setup",
|
|
&SystemConfigurationGuid,
|
|
NULL,
|
|
&DataSize,
|
|
&SetupVariable
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
SetupVariable.L05ChargeInBatteryMode = (SmiData == FUNCTION_ENABLE_CHARGE_IN_BATTERY_MODE)?1:0;
|
|
Status = SmmVariable->SmmSetVariable (
|
|
L"Setup",
|
|
&SystemConfigurationGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
DataSize,
|
|
&SetupVariable
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
}
|
|
case SET_GFX_IGPU_ONLY_FUNCTION:
|
|
case SET_GFX_IGPU_DGPU_FUNCTION:
|
|
case SET_GFX_DGPU_ONLY_FUNCTION:
|
|
{
|
|
UINTN DataSize;
|
|
EFI_SMM_VARIABLE_PROTOCOL *SmmVariable;
|
|
SA_SETUP SaSetup;
|
|
|
|
Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, &SmmVariable);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
DataSize = sizeof (SA_SETUP);
|
|
Status = SmmVariable->SmmGetVariable (
|
|
L"SaSetup",
|
|
&gSaSetupVariableGuid,
|
|
NULL,
|
|
&DataSize,
|
|
&SaSetup
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
//SET_GFX_IGPU_ONLY_FUNCTION set PrimaryDisplay = 0;
|
|
//SET_GFX_IGPU_DGPU_FUNCTION set PrimaryDisplay = 4;
|
|
//SET_GFX_DGPU_ONLY_FUNCTION set PrimaryDisplay = 1;
|
|
SaSetup.PrimaryDisplay = (SmiData == SET_GFX_IGPU_ONLY_FUNCTION)?0:((SmiData == SET_GFX_DGPU_ONLY_FUNCTION)?1:4);
|
|
Status = SmmVariable->SmmSetVariable (
|
|
L"SaSetup",
|
|
&gSaSetupVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
DataSize,
|
|
&SaSetup
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
}
|
|
default:
|
|
Status = EFI_UNSUPPORTED;
|
|
break;
|
|
}
|
|
|
|
SmiData = 0;
|
|
SetSwSmiSubFunctionNumber (SmiData); // Clear this SMI data
|
|
|
|
return Status;
|
|
}
|
|
//[-start-220210-Dongxu0040-Modify]//
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ChgBootSmiCallback (
|
|
IN EFI_HANDLE DispatchHandle,
|
|
IN CONST VOID *Context OPTIONAL,
|
|
IN OUT VOID *CommBuffer OPTIONAL,
|
|
IN OUT UINTN *CommBufferSize OPTIONAL
|
|
)
|
|
/*
|
|
SW SMI handler.
|
|
Input:
|
|
AX = 0x53ca
|
|
BX = Function number
|
|
ECX = Physics address low 32bit of BOOT_DEVICE_DATA
|
|
EDI = Physics address high 32bit of BOOT_DEVICE_DATA
|
|
|
|
Output:
|
|
AL = Return status
|
|
*/
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN CpuIndex;
|
|
UINT32 TempValue;
|
|
// UINT8 DefaultBootTypeOrderSequence[] = {L05_BOOT_ORDER_SEQUENCE}; //From L05Project.h
|
|
// BOOT_DEVICE_DATA *SmiData = NULL;
|
|
// UINTN SmiDataAddressLow32, SmiDataAddressHigh32;
|
|
EFI_SMM_VARIABLE_PROTOCOL *SmmVariable;
|
|
SYSTEM_CONFIGURATION SetupVariable;
|
|
EFI_GUID SystemConfigurationGuid = SYSTEM_CONFIGURATION_GUID;
|
|
UINTN DataSize;
|
|
UINT8 IsNeedUpdateSetup;
|
|
UINT8 ValidTool;
|
|
|
|
if (CheckLcfcSubFunction () == EFI_SUCCESS) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
Status = IdentifyCpuIndexByEax (BOOT_SEQUENCE_UPDATE_FLAG|BOOT_SEQUENCE_UPDATE_SWSMI, 0xffff, &CpuIndex);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
// Status = GetDwordRegisterByCpuIndex (EFI_SMM_SAVE_STATE_REGISTER_RCX, CpuIndex, sizeof (UINT32), &TempValue);
|
|
// ASSERT_EFI_ERROR (Status);
|
|
// SmiDataAddressLow32 = (UINTN)TempValue;
|
|
//
|
|
// Status = GetDwordRegisterByCpuIndex (EFI_SMM_SAVE_STATE_REGISTER_RDI, CpuIndex, sizeof (UINT32), &TempValue);
|
|
// ASSERT_EFI_ERROR (Status);
|
|
// SmiDataAddressHigh32 = (UINTN)(((UINT64)TempValue)<<32);
|
|
//
|
|
// SmiData = (SMAPI_DATA *)(SmiDataAddressLow32 + SmiDataAddressHigh32);
|
|
|
|
Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, &SmmVariable);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
Status = GetDwordRegisterByCpuIndex (EFI_SMM_SAVE_STATE_REGISTER_RBX, CpuIndex, sizeof (UINT32), &TempValue);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
DataSize = sizeof (SYSTEM_CONFIGURATION);
|
|
Status = SmmVariable->SmmGetVariable (
|
|
L"Setup",
|
|
&SystemConfigurationGuid,
|
|
NULL,
|
|
&DataSize,
|
|
&SetupVariable
|
|
);
|
|
|
|
IsNeedUpdateSetup = TRUE;
|
|
|
|
switch(TempValue) {
|
|
case SET_DEFAULT_FUNCTION:
|
|
case SET_SECURE_BOOT_ENABLE_FUNCTION:
|
|
case LOAD_UEFI_OS_DEFAULT_FUNCTION:
|
|
case LOAD_LEGACY_OS_DEFAULT_FUNCTION:
|
|
case LCFC_SECURE_FLASH_ENABLE_FUNCTION:
|
|
case SB_RESTORE_FACTORY_DEFAULT_FUNCTION:
|
|
case SET_FULLRESET_FUNCTION:
|
|
case SET_SECURE_BOOT_DISABLE_FUNCTION:
|
|
case SET_PXE_FIRST_FUNCTION:
|
|
case SET_HDD_FIRST_FUNCTION:
|
|
case SET_USB_FIRST_FUNCTION:
|
|
case SET_EFI_PXE_ONE_TIME_FUNCTION:
|
|
IsNeedUpdateSetup = FALSE;
|
|
break;
|
|
default:
|
|
if(EFI_ERROR(Status)) {
|
|
IsNeedUpdateSetup = FALSE;
|
|
TempValue = SETUP_NOT_FOUND;
|
|
SetDwordRegisterByCpuIndex (EFI_SMM_SAVE_STATE_REGISTER_RAX, CpuIndex, sizeof (UINT32), &TempValue);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if(TempValue == SETUP_NOT_FOUND) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
switch ((UINT16)TempValue) {
|
|
// case GET_CURRENT_SEQ_FUNCTION:
|
|
// CopyMem (SmiData->BootTypeOrderSequence, SetupVariable.BootTypeOrder, MAX_BOOT_ORDER_NUMBER);
|
|
// return;
|
|
//
|
|
case SET_DEFAULT_FUNCTION:
|
|
{
|
|
UINT8 ChgBootDefaultTypeData = 0;
|
|
UINTN ChgBootDefaultTypeDataSize = sizeof (ChgBootDefaultTypeData);
|
|
SmmVariable->SmmSetVariable (
|
|
L"ChgBootBootOrderSetDefault",
|
|
&gLfcVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
ChgBootDefaultTypeDataSize,
|
|
&ChgBootDefaultTypeData
|
|
);
|
|
IsNeedUpdateSetup = FALSE;
|
|
}
|
|
break;
|
|
|
|
case SET_UEFI_FIRST_FUNCTION:
|
|
SetupVariable.BootNormalPriority = 0;
|
|
break;
|
|
|
|
case SET_LEGACY_FIRST_FUNCTION:
|
|
SetupVariable.BootNormalPriority = 1;
|
|
break;
|
|
|
|
case SET_UEFI_ONLY_FUNCTION:
|
|
//SetupVariable.BootType = 2; //UEFI only
|
|
{
|
|
UINT8 BootTypeVariable = 2;
|
|
Status = SmmVariable->SmmSetVariable (
|
|
L"BootType",
|
|
&gSystemConfigurationGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
sizeof (BootTypeVariable),
|
|
&BootTypeVariable
|
|
);
|
|
}
|
|
// SetupVariable.NetworkProtocol = 2; // Special case for LAN boot
|
|
SetupVariable.BootType = 2; // UEFI only
|
|
break;
|
|
|
|
case SET_DUAL_BOOT_FUNCTION:
|
|
//SetupVariable.BootType = 0; //Dual boot mode
|
|
{
|
|
UINT8 BootTypeVariable = 0;
|
|
Status = SmmVariable->SmmSetVariable (
|
|
L"BootType",
|
|
&gSystemConfigurationGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
sizeof (BootTypeVariable),
|
|
&BootTypeVariable
|
|
);
|
|
}
|
|
// SetupVariable.NetworkProtocol = 3; // Special case for LAN boot
|
|
SetupVariable.BootType = 0; //Dual boot mode
|
|
SetupVariable.L05SecureBoot = 0;
|
|
{
|
|
UINT8 TempVariable = 0;
|
|
UINT32 TempDataLength = sizeof (UINT8);
|
|
SmmVariable->SmmSetVariable (
|
|
L"ChgBootChangeLegacy",
|
|
&gLfcVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
TempDataLength,
|
|
&TempVariable
|
|
);
|
|
}
|
|
break;
|
|
|
|
case SET_SECURE_BOOT_ENABLE_FUNCTION:
|
|
// TODO: reset factory default
|
|
{
|
|
UINT8 TempVariable = 0;
|
|
UINT32 TempDataLength = sizeof (UINT8);
|
|
SmmVariable->SmmSetVariable (
|
|
L"ChgBootSecureBootEnable",
|
|
&gLfcVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
TempDataLength,
|
|
&TempVariable
|
|
);
|
|
IsNeedUpdateSetup = FALSE;
|
|
}
|
|
break;
|
|
|
|
case SET_FAST_BOOT_ENABLE_FUNCTION:
|
|
// Enable this code if Lenovo Fast Boot implemented
|
|
// SetupVariable.QuickBoot = 1;
|
|
SetupVariable.L05FastBoot = 1;
|
|
break;
|
|
|
|
case SET_FAST_BOOT_DISABLE_FUNCTION:
|
|
// Enable this code if Lenovo Fast Boot implemented
|
|
// SetupVariable.QuickBoot = 0;
|
|
SetupVariable.L05FastBoot = 0;
|
|
break;
|
|
|
|
case SET_PXE_BOOT_ENABLE_FUNCTION:
|
|
SetupVariable.PxeBootToLan = 1;
|
|
break;
|
|
|
|
case SET_PXE_BOOT_DISABLE_FUNCTION:
|
|
SetupVariable.PxeBootToLan = 0;
|
|
break;
|
|
|
|
case SET_BACK_FLASH_ENABLE_FUNCTION:
|
|
SetupVariable.L05BiosBackFlash = 1;
|
|
break;
|
|
|
|
case SET_BACK_FLASH_DISABLE_FUNCTION:
|
|
SetupVariable.L05BiosBackFlash = 0;
|
|
break;
|
|
|
|
case SET_TPM_ENABLE_FUNCTION:
|
|
#if (FixedPcdGet8 (PcdPlatformIntelOrAmd) == 1)
|
|
SetupVariable.L05FtpmEnable= 1;
|
|
#else
|
|
SetupVariable.EnableTPM = 2;
|
|
#endif
|
|
break;
|
|
|
|
case SET_TPM_DISABLE_FUNCTION:
|
|
#if (FixedPcdGet8 (PcdPlatformIntelOrAmd) == 1)
|
|
SetupVariable.L05FtpmEnable = 0;
|
|
#else
|
|
SetupVariable.EnableTPM = 0;
|
|
#endif
|
|
break;
|
|
|
|
// case SET_POWER_BEEP_ENABLE_FUNCTION:
|
|
// SetupVariable.L05PowerBeepFunction = 1;
|
|
// break;
|
|
|
|
// case SET_POWER_BEEP_DISABLE_FUNCTION:
|
|
// SetupVariable.L05PowerBeepFunction = 0;
|
|
// break;
|
|
|
|
case SET_OS_OPTINIZED_ENABLE_FUNCTION:
|
|
//[-start-210514-BAINTEST-modify]//
|
|
// SetupVariable.L05DefaultType = 0;
|
|
SetupVariable.L05OsOptimizedDefault = 0;
|
|
//[-end-210514-BAINTEST-modify]//
|
|
break;
|
|
|
|
case SET_OS_OPTINIZED_DISABLE_FUNCTION:
|
|
//[-start-210514-BAINTEST-modify]//
|
|
// SetupVariable.L05DefaultType = 1;
|
|
SetupVariable.L05OsOptimizedDefault = 0;
|
|
//[-end-210514-BAINTEST-modify]//
|
|
break;
|
|
// LCFCTODO: You must follow your project setting.
|
|
// In Big Core, it should be PCH_SETUP.SataInterfaceMode.
|
|
// In Small Core, it should be SetupVariable.SataInterfaceMode.
|
|
// case SET_SATA_RAID_FUNCTION:
|
|
// SetupVariable.SataInterfaceMode = 1;
|
|
// break;
|
|
// case SET_SATA_AHCI_FUNCTION:
|
|
// SetupVariable.SataInterfaceMode = 0;
|
|
// break;
|
|
case LOAD_UEFI_OS_DEFAULT_FUNCTION:
|
|
case LOAD_LEGACY_OS_DEFAULT_FUNCTION:
|
|
{
|
|
UINT8 TempVariable = 0;
|
|
UINT32 TempDataLength = sizeof (UINT8);
|
|
|
|
if (TempValue == LOAD_UEFI_OS_DEFAULT_FUNCTION) {
|
|
SmmVariable->SmmSetVariable (
|
|
L"ChgBootUefiLoadDefault",
|
|
&gLfcVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
TempDataLength,
|
|
&TempVariable
|
|
);
|
|
} else {
|
|
SmmVariable->SmmSetVariable (
|
|
L"ChgBootLegacyLoadDefault",
|
|
&gLfcVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
TempDataLength,
|
|
&TempVariable
|
|
);
|
|
}
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
//Delete it to make it load default at next boot
|
|
//DataSize = 0;
|
|
//Status = SmmVariable->SmmSetVariable (
|
|
// L"Setup",
|
|
// &SystemConfigurationGuid,
|
|
// EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
// DataSize,
|
|
// &SetupVariable
|
|
// );
|
|
//if (Status == EFI_NOT_FOUND) {
|
|
// //Already deleted, so skip next code
|
|
//} else {
|
|
// ASSERT_EFI_ERROR (Status);
|
|
//}
|
|
IsNeedUpdateSetup = FALSE;
|
|
}
|
|
break;
|
|
|
|
// case SET_SEQ_FUNCTION:
|
|
// CopyMem (SetupVariable.BootTypeOrder, SmiData->BootTypeOrderSequence, MAX_BOOT_ORDER_NUMBER);
|
|
// //Clear BootOrder variable to make it re-enumerate all boot device when next boot
|
|
// Status = SmmVariable->SmmSetVariable (
|
|
// L"BootOrder",
|
|
// &gEfiGlobalVariableGuid,
|
|
// EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
// 0,
|
|
// NULL
|
|
// );
|
|
// break;
|
|
|
|
case LCFC_SECURE_FLASH_ENABLE_FUNCTION:
|
|
{
|
|
BOOLEAN LfcSecureFlashCer = TRUE;
|
|
// It is a BOOLEAN type flag
|
|
// It exist = use ODM itself secure flash ceritfication
|
|
// It doesn't exist = use formal secure flash certification
|
|
// No matter its value
|
|
SmmVariable->SmmSetVariable (
|
|
L"@Rm",
|
|
&gLfcVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
sizeof (LfcSecureFlashCer),
|
|
&LfcSecureFlashCer
|
|
);
|
|
IsNeedUpdateSetup = FALSE;
|
|
}
|
|
break;
|
|
|
|
case SB_RESTORE_FACTORY_DEFAULT_FUNCTION:
|
|
{
|
|
UINT8 TempVariable = 0;
|
|
UINT32 TempDataLength = sizeof (UINT8);
|
|
SmmVariable->SmmSetVariable (
|
|
L"ChgBootRestoreFactory",
|
|
&gLfcVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
TempDataLength,
|
|
&TempVariable
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
IsNeedUpdateSetup = FALSE;
|
|
}
|
|
break;
|
|
|
|
case SET_FULLRESET_FUNCTION:
|
|
{
|
|
UINT8 ChgBootDefaultTypeData = 0;
|
|
UINTN ChgBootDefaultTypeDataSize = sizeof (ChgBootDefaultTypeData);
|
|
SmmVariable->SmmSetVariable (
|
|
L"ChgBootFullReset",
|
|
&gLfcVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
ChgBootDefaultTypeDataSize,
|
|
&ChgBootDefaultTypeData
|
|
);
|
|
IsNeedUpdateSetup = FALSE;
|
|
}
|
|
break;
|
|
|
|
case SET_SECURE_BOOT_DISABLE_FUNCTION:
|
|
{
|
|
UINT8 TempVariable = 0;
|
|
UINT32 TempDataLength = sizeof (UINT8);
|
|
SmmVariable->SmmSetVariable (
|
|
L"ChgBootSecureBootDisable",
|
|
&gLfcVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
TempDataLength,
|
|
&TempVariable
|
|
);
|
|
IsNeedUpdateSetup = FALSE;
|
|
}
|
|
break;
|
|
|
|
case SET_PXE_FIRST_FUNCTION:
|
|
{
|
|
UINT8 TempVariable = 0;
|
|
UINT32 TempDataLength = sizeof (UINT8);
|
|
SmmVariable->SmmSetVariable (
|
|
L"ChgBootSetPxeToFirst",
|
|
&gLfcVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
TempDataLength,
|
|
&TempVariable
|
|
);
|
|
IsNeedUpdateSetup = FALSE;
|
|
}
|
|
break;
|
|
|
|
case SET_HDD_FIRST_FUNCTION:
|
|
|
|
break;
|
|
|
|
case SET_USB_FIRST_FUNCTION:
|
|
|
|
break;
|
|
|
|
case SET_EFI_PXE_ONE_TIME_FUNCTION:
|
|
{
|
|
UINT8 TempVariable = 0;
|
|
UINT32 TempDataLength = sizeof (UINT8);
|
|
SmmVariable->SmmSetVariable (
|
|
L"ChgBootSetEfiPxeOneTime",
|
|
&gLfcVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
TempDataLength,
|
|
&TempVariable
|
|
);
|
|
IsNeedUpdateSetup = FALSE;
|
|
}
|
|
break;
|
|
case GET_OPTION_FUNCTION:
|
|
{
|
|
UINT16 Data=0x00;
|
|
UINT8 Data1 =0x00;
|
|
UINT32 Data2 =0x00;
|
|
DataSize = sizeof (SYSTEM_CONFIGURATION);
|
|
Status = SmmVariable->SmmGetVariable (
|
|
L"Setup",
|
|
&SystemConfigurationGuid,
|
|
NULL,
|
|
&DataSize,
|
|
&SetupVariable
|
|
);
|
|
|
|
Data =(UINT16)(TempValue>>16);
|
|
Data1 = (((UINT8*)(UINTN)(&SetupVariable))[Data]);
|
|
Data2=(UINT32)Data1;
|
|
SetDwordRegisterByCpuIndex (EFI_SMM_SAVE_STATE_REGISTER_RBX, CpuIndex, sizeof (UINT32), &Data2);
|
|
}
|
|
|
|
break;
|
|
case SET_GFX_IGPU_ONLY_FUNCTION:
|
|
case SET_GFX_IGPU_DGPU_FUNCTION:
|
|
case SET_GFX_DGPU_ONLY_FUNCTION:
|
|
{
|
|
|
|
//For kernel 5.4 update build code error remove DataSize & *SmmVariable.
|
|
// UINTN DataSize;
|
|
// EFI_SMM_VARIABLE_PROTOCOL *SmmVariable;
|
|
SA_SETUP SaSetup;
|
|
|
|
Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, &SmmVariable);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
DataSize = sizeof (SA_SETUP);
|
|
Status = SmmVariable->SmmGetVariable (
|
|
L"SaSetup",
|
|
&gSaSetupVariableGuid,
|
|
NULL,
|
|
&DataSize,
|
|
&SaSetup
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
//SET_GFX_IGPU_ONLY_FUNCTION set PrimaryDisplay = 0;
|
|
//SET_GFX_IGPU_DGPU_FUNCTION set PrimaryDisplay = 4;
|
|
//SET_GFX_DGPU_ONLY_FUNCTION set PrimaryDisplay = 1;
|
|
SaSetup.PrimaryDisplay = ((UINT16)TempValue == SET_GFX_IGPU_ONLY_FUNCTION)?0:(((UINT16)TempValue == SET_GFX_DGPU_ONLY_FUNCTION)?1:4);
|
|
Status = SmmVariable->SmmSetVariable (
|
|
L"SaSetup",
|
|
&gSaSetupVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
DataSize,
|
|
&SaSetup
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
}
|
|
default:
|
|
TempValue = FUNCTION_UNSUPPORTED;
|
|
SetDwordRegisterByCpuIndex (EFI_SMM_SAVE_STATE_REGISTER_RAX, CpuIndex, sizeof (UINT32), &TempValue);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if(IsNeedUpdateSetup) {
|
|
Status = LfcCheckValidTool(&ValidTool);
|
|
if(ValidTool != 0X55){
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
DataSize = sizeof (SYSTEM_CONFIGURATION);
|
|
Status = SmmVariable->SmmSetVariable (
|
|
L"Setup",
|
|
&SystemConfigurationGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
DataSize,
|
|
&SetupVariable
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
|
|
// Need disable next time smart boot
|
|
// Enable this code if Lenovo Fast Boot implemented
|
|
{
|
|
BOOLEAN DisableFastBootFlag = 1;
|
|
// It is a BOOLEAN type flag
|
|
// It exist = disable Fast Boot in next boot
|
|
// It doesn't exist = don't
|
|
// No matter its value
|
|
SmmVariable->SmmSetVariable (L"OneTimeDisableFastBoot", &gLfcVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, sizeof (DisableFastBootFlag), &DisableFastBootFlag);
|
|
|
|
//Set CMOS flag also to double confirm disable Fast Boot
|
|
IoWrite8 (LFC_CMOS_INDEX, LFC_FAST_BOOT_PREVIOUS_BOOT_SUCCESS_INDEX);
|
|
IoWrite8 (LFC_CMOS_DATA, FAST_BOOT_BOOT_FAIL);
|
|
}
|
|
|
|
TempValue = SUCCESS;
|
|
SetDwordRegisterByCpuIndex (EFI_SMM_SAVE_STATE_REGISTER_RAX, CpuIndex, sizeof (UINT32), &TempValue);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
//[-end-220210-Dongxu0040-Modify]//
|
|
//[-start-211027-QINGLIN0106-add]//
|
|
//[-start-211124-kebin000069-modify]//
|
|
//[-start-220113-YUNLEI0158-modify]//
|
|
#if defined(S370_SUPPORT) || defined(C970_SUPPORT) || defined(C770_SUPPORT)
|
|
//[-end-220113-YUNLEI0158-modify]//
|
|
//[-end-211124-kebin000069-modify]//
|
|
EFI_STATUS
|
|
EFIAPI
|
|
TurboOffCallback (
|
|
IN EFI_HANDLE DispatchHandle,
|
|
IN CONST VOID *Context OPTIONAL,
|
|
IN OUT VOID *CommBuffer OPTIONAL,
|
|
IN OUT UINTN *CommBufferSize OPTIONAL
|
|
)
|
|
{
|
|
EFI_CPUID_REGISTER Cpuid06;
|
|
MSR_REGISTER Ia32MiscEnable;
|
|
////[-start-200113-JANSEN0100-add]//
|
|
// UINT8 Data;
|
|
////[-end-200113-JANSEN0100-add]//
|
|
|
|
AsmCpuid (6, &Cpuid06.RegEax, &Cpuid06.RegEbx, &Cpuid06.RegEcx, &Cpuid06.RegEdx);
|
|
|
|
///
|
|
/// Check if turbo mode is supported and update the flag
|
|
///
|
|
Ia32MiscEnable.Qword = AsmReadMsr64 (MSR_IA32_MISC_ENABLE);
|
|
if (((Cpuid06.RegEax & B_CPUID_POWER_MANAGEMENT_EAX_TURBO) == 0) &&
|
|
((Ia32MiscEnable.Qword & B_MSR_IA32_MISC_DISABLE_TURBO) == 0)
|
|
) {
|
|
///
|
|
/// Turbo Mode is not available in this physical processor package.
|
|
/// BIOS should not attempt to enable Turbo Mode via IA32_MISC_ENABLE MSR.
|
|
/// BIOS should show Turbo Mode as Disabled and Not Configurable.
|
|
///
|
|
} else if ((Cpuid06.RegEax & B_CPUID_POWER_MANAGEMENT_EAX_TURBO) == 0) {
|
|
///
|
|
/// Turbo Mode is available but globally disabled for the all logical
|
|
/// processors in this processor package.
|
|
/// BIOS can enable Turbo Mode by IA32_MISC_ENABLE MSR 1A0h bit [38] = 0.
|
|
///
|
|
Ia32MiscEnable.Qword |= BIT38; // disable Turbo Mode.
|
|
} else if ((Cpuid06.RegEax & B_CPUID_POWER_MANAGEMENT_EAX_TURBO) == B_CPUID_POWER_MANAGEMENT_EAX_TURBO) {
|
|
///
|
|
/// Turbo Mode is factory-configured as available and enabled for all logical processors in this processor package.
|
|
/// This case handles the cases where turbo mode is enabled before PPM gets chance to enable it
|
|
///
|
|
Ia32MiscEnable.Qword |= BIT38; // disable Turbo Mode.
|
|
}
|
|
|
|
AsmWriteMsr64(MSR_IA32_MISC_ENABLE, Ia32MiscEnable.Qword);
|
|
|
|
////[-start-200113-JANSEN0100-add]//
|
|
// //
|
|
// // Notify EC the CPU real turbo status.
|
|
// //
|
|
// LfcEcLibEcRamRead (0x1E, &Data);
|
|
// Data |= BIT5; //Set BIT5
|
|
// LfcEcLibEcRamWrite (0x1E, Data);
|
|
////[-end-200113-JANSEN0100-add]//
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
TurboOnCallback (
|
|
IN EFI_HANDLE DispatchHandle,
|
|
IN CONST VOID *Context OPTIONAL,
|
|
IN OUT VOID *CommBuffer OPTIONAL,
|
|
IN OUT UINTN *CommBufferSize OPTIONAL
|
|
)
|
|
{
|
|
EFI_CPUID_REGISTER Cpuid06;
|
|
MSR_REGISTER Ia32MiscEnable;
|
|
////[-start-200113-JANSEN0100-add]//
|
|
// UINT8 Data;
|
|
////[-end-200113-JANSEN0100-add]//
|
|
|
|
AsmCpuid (6, &Cpuid06.RegEax, &Cpuid06.RegEbx, &Cpuid06.RegEcx, &Cpuid06.RegEdx);
|
|
|
|
///
|
|
/// Check if turbo mode is supported and update the flag
|
|
///
|
|
Ia32MiscEnable.Qword = AsmReadMsr64 (MSR_IA32_MISC_ENABLE);
|
|
if (((Cpuid06.RegEax & B_CPUID_POWER_MANAGEMENT_EAX_TURBO) == 0) &&
|
|
((Ia32MiscEnable.Qword & B_MSR_IA32_MISC_DISABLE_TURBO) == 0)
|
|
) {
|
|
///
|
|
/// Turbo Mode is not available in this physical processor package.
|
|
/// BIOS should not attempt to enable Turbo Mode via IA32_MISC_ENABLE MSR.
|
|
/// BIOS should show Turbo Mode as Disabled and Not Configurable.
|
|
///
|
|
} else if ((Cpuid06.RegEax & B_CPUID_POWER_MANAGEMENT_EAX_TURBO) == 0) {
|
|
///
|
|
/// Turbo Mode is available but globally disabled for the all logical
|
|
/// processors in this processor package.
|
|
/// BIOS can enable Turbo Mode by IA32_MISC_ENABLE MSR 1A0h bit [38] = 0.
|
|
///
|
|
Ia32MiscEnable.Qword &= ~BIT38; // enable Turbo Mode.
|
|
} else if ((Cpuid06.RegEax & B_CPUID_POWER_MANAGEMENT_EAX_TURBO) == B_CPUID_POWER_MANAGEMENT_EAX_TURBO) {
|
|
///
|
|
/// Turbo Mode is factory-configured as available and enabled for all logical processors in this processor package.
|
|
/// This case handles the cases where turbo mode is enabled before PPM gets chance to enable it
|
|
///
|
|
Ia32MiscEnable.Qword &= ~BIT38; // enable Turbo Mode.
|
|
}
|
|
|
|
AsmWriteMsr64(MSR_IA32_MISC_ENABLE, Ia32MiscEnable.Qword);
|
|
|
|
////[-start-200113-JANSEN0100-add]//
|
|
// //
|
|
// // Notify EC the CPU real turbo status.
|
|
// //
|
|
// LfcEcLibEcRamRead (0x1E, &Data);
|
|
// Data &= ~BIT5; //Clear BIT5
|
|
// LfcEcLibEcRamWrite (0x1E, Data);
|
|
////[-end-200113-JANSEN0100-add]//
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
#endif
|
|
//[-end-211027-QINGLIN0106-add]//
|
|
|
|
EFI_STATUS
|
|
ChgBootSmmEntry (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
if (!InSmm ()) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
//Register Software SMI
|
|
{
|
|
EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;
|
|
EFI_SMM_SW_REGISTER_CONTEXT SwContext;
|
|
EFI_HANDLE SwHandle;
|
|
EFI_STATUS Status;
|
|
|
|
Status = gSmst->SmmLocateProtocol (
|
|
&gEfiSmmSwDispatch2ProtocolGuid,
|
|
NULL,
|
|
&SwDispatch
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
SwContext.SwSmiInputValue = BOOT_SEQUENCE_UPDATE_SWSMI;
|
|
Status = SwDispatch->Register (
|
|
SwDispatch,
|
|
ChgBootSmiCallback,
|
|
&SwContext,
|
|
&SwHandle
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
//[-start-211027-QINGLIN0106-add]//
|
|
//[-start-211124-kebin000069-modify]//
|
|
//[-start-220113-YUNLEI0158-modify]//
|
|
#if defined(S370_SUPPORT) || defined(C970_SUPPORT) || defined(C770_SUPPORT)
|
|
//[-end-220113-YUNLEI0158-modify]//
|
|
//[-end-211124-kebin000069-modify]//
|
|
// Turbo off
|
|
SwContext.SwSmiInputValue = 0XCC;
|
|
Status = SwDispatch->Register (
|
|
SwDispatch,
|
|
TurboOffCallback,
|
|
&SwContext,
|
|
&SwHandle
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
// Turbo on
|
|
SwContext.SwSmiInputValue = 0XCD;
|
|
Status = SwDispatch->Register (
|
|
SwDispatch,
|
|
TurboOnCallback,
|
|
&SwContext,
|
|
&SwHandle
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
#endif
|
|
//[-end-211027-QINGLIN0106-add]//
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|