alder_lake_bios/Oem/L05/FeatureCommon/InsydeL05ModulePkg/WmiSetupUnderOsSmm/WmiSetBiosSettingA1.c

632 lines
18 KiB
C

/** @file
;******************************************************************************
;* Copyright (c) 2018, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include "WmiSetupUnderOsSmm.h"
/**
WMI set boot order.
@param ParameterValue A pointer to the parameter value.
@param BootOrder A pointer to boot order.
@param L05BootOrderCount Count of L05 boot order.
@param L05WmiBootDescription A pointer to the L05 WMI boot description.
@retval EFI_SUCCESS This function execute successfully.
@retval Others An unexpected error occurred.
**/
EFI_STATUS
WmiSetBootOrder (
CHAR8 *ParameterValue,
UINT16 *BootOrder,
UINT16 L05BootOrderCount,
L05_WMI_BOOT_DESCRIPTION *L05WmiBootDescription
)
{
EFI_STATUS Status;
UINT16 *TempBootOrder;
UINTN BufferOffset;
UINTN TempBufferOffset;
UINTN Index;
UINTN Index2;
UINTN BootOrderIndex;
UINTN BootOrderCheckSum;
UINTN BootOrderCheckSumCount;
UINTN VerifyBootOrderCheckSum;
UINTN ValueSize;
CHAR8 *Ipv4NetworkStr = WMI_L05_PXE_IPV4_STRING;
CHAR8 *Ipv6NetworkStr = WMI_L05_PXE_IPV6_STRING;
BOOLEAN FindNewNetworkOption;
UINTN NewNetworkOptionShift;
UINTN NewNetworkOptionIndex;
//
// Initialization
//
Status = EFI_SUCCESS;
BufferOffset = 0;
TempBufferOffset = 0;
BootOrderIndex = 0;
BootOrderCheckSum = 0;
BootOrderCheckSumCount = 0;
VerifyBootOrderCheckSum = 0;
ValueSize = AsciiStrSize (ParameterValue);
FindNewNetworkOption = FALSE;
NewNetworkOptionShift = FALSE;
NewNetworkOptionIndex = 0;
//
// Allocate resources
//
TempBootOrder = AllocateRuntimeZeroPool (sizeof (UINT16) * L05BootOrderCount);
if (TempBootOrder == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Find Network Option index & set Network Option shift
//
for (Index = 0; Index < L05BootOrderCount; Index++) {
if ((CompareMem (Ipv4NetworkStr, L05WmiBootDescription[Index].BootDescription, AsciiStrSize (Ipv4NetworkStr) - sizeof (CHAR8)) == 0x0) ||
(CompareMem (Ipv6NetworkStr, L05WmiBootDescription[Index].BootDescription, AsciiStrSize (Ipv6NetworkStr) - sizeof (CHAR8)) == 0x0)) {
NewNetworkOptionShift = 1;
NewNetworkOptionIndex = Index;
break;
}
}
//
// Part Boot Order section
//
for (BufferOffset = 0; BufferOffset < ValueSize; BufferOffset++) {
if ((ParameterValue[BufferOffset] != ':')
&&(ParameterValue[BufferOffset] != 0)) {
continue;
}
ParameterValue[BufferOffset] = 0;
//
// Get Boot Order index for setting
//
Index = AsciiStrDecimalToUintn (&ParameterValue[TempBufferOffset]);
//
// Count Boot Order value check sum
//
BootOrderCheckSum += Index;
BootOrderCheckSumCount++;
//
// Transform for index of array
//
Index--;
//
// Index shift for merge PXE
//
Index += (Index > NewNetworkOptionIndex ? NewNetworkOptionShift : 0);
//
// Check Index is valid
//
if (Index >= L05BootOrderCount) {
Status = EFI_INVALID_PARAMETER;
break;
}
//
// Check is NewNetwork Option
//
if ((CompareMem (Ipv4NetworkStr, L05WmiBootDescription[Index].BootDescription, AsciiStrSize (Ipv4NetworkStr) - sizeof (CHAR8)) == 0x0) ||
(CompareMem (Ipv6NetworkStr, L05WmiBootDescription[Index].BootDescription, AsciiStrSize (Ipv6NetworkStr) - sizeof (CHAR8)) == 0x0)) {
FindNewNetworkOption = TRUE;
}
//
// Sorting Boot Order
//
for (Index2 = 0; Index2 < (FindNewNetworkOption ? (UINTN) 2 : (UINTN) 1); Index2++) {
TempBootOrder[BootOrderIndex] = L05WmiBootDescription[Index + Index2].BootOption;
BootOrderIndex++;
}
TempBufferOffset = BufferOffset;
TempBufferOffset++;
FindNewNetworkOption = FALSE;
Status = EFI_SUCCESS;
}
//
// Check Set BootOrder count is correct
//
if (BootOrderIndex != L05BootOrderCount) {
Status = EFI_INVALID_PARAMETER;
}
//
// Check Set BootOrder value is correct, not repeat.
//
VerifyBootOrderCheckSum = ((1 + BootOrderCheckSumCount) * BootOrderCheckSumCount) / 2;
if (VerifyBootOrderCheckSum != BootOrderCheckSum) {
Status = EFI_INVALID_PARAMETER;
}
if (EFI_ERROR (Status)) {
FreePool (TempBootOrder);
return Status;
}
//
// When Boot Order change will set Boot Order.
//
if (CompareMem (BootOrder, TempBootOrder, (sizeof (UINT16) * L05BootOrderCount)) != 0) {
CopyMem (BootOrder, TempBootOrder, (sizeof (UINT16) * L05BootOrderCount));
}
//
// Free resources
//
FreePool (TempBootOrder);
return Status;
}
/**
Set setup value.
@param SelectStrListIndex Select string list index.
@param ConfigValue A pointer to the config value.
@retval EFI_SUCCESS Set setup value successfully.
@retval EFI_NO_MAPPING Can't find select value.
**/
EFI_STATUS
SetSetupValue (
UINTN SelectStrListIndex,
CHAR8 *ConfigValue
)
{
EFI_STATUS Status;
UINTN Index;
//
// Initialization
//
Status = EFI_SUCCESS;
//
// Get select value
//
for (Index = 0; Index < mWmiSelectStrListMap[SelectStrListIndex].SelectStrCount; Index++) {
if (AsciiStrCmp (ConfigValue, mWmiSelectStrListMap[SelectStrListIndex].SelectStrList[Index]) == 0) {
//
// Set select value, when select value different with L05WmiSetupItem.
//
if (*mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].L05WmiSetupItem != Index) {
*mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].L05WmiSetupItem = (UINT8) Index;
}
break;
}
}
//
// Check set config value is valid
//
if (Index >= mWmiSelectStrListMap[SelectStrListIndex].SelectStrCount) {
Status = EFI_NO_MAPPING;
}
return Status;
}
/**
Extend check for set BIOS setting.
@param WmiSetBiosSettingParameter A pointer to the WMI set BIOS setting parameter.
@retval EFI_SUCCESS Extend check is successfully.
@retval EFI_ACCESS_DENIED Extend check is denied.
**/
EFI_STATUS
SetBiosSettingExtendCheck (
WMI_SET_BIOS_SETTING_PARAMETER *WmiSetBiosSettingParameter
)
{
EFI_STATUS Status;
Status = EFI_SUCCESS;
//
// [Lenovo BIOS Setup Design Guide V2.5]
// [Configuration]
// BIOS Back Flash - WMI Enable Only.
// Disable is also avilable when BIOS Administrator password is installed.
//
if (mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ConfigDataType == BiosBackFlashType) {
if (mAdminPasswordExist) {
return EFI_SUCCESS;
}
if (AsciiStrCmp (WmiSetBiosSettingParameter->Value, "Disable") == 0) {
return EFI_ACCESS_DENIED;
}
}
//
// [Lenovo BIOS Setup Design Guide V2.7]
// [Security]
// Device Guard - WMI
// when administrator password is installed.
//
if (mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ConfigDataType == DeviceGuardType) {
if (mAdminPasswordExist) {
return EFI_SUCCESS;
} else {
return EFI_ACCESS_DENIED;
}
}
//
// Unselectable for Device Guard
// If "Device Guard" is Enabled, below items should be gray out.
//
if ((mL05WmiSetupItem.L05DeviceGuard == L05_WMI_SETUP_ITEM_ENABLE) &&
((mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ConfigDataType == IntelVtType) ||
(mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ConfigDataType == IntelVtdType) ||
(mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ConfigDataType == AmdVType) ||
(mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ConfigDataType == SecureBootType) ||
(mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ConfigDataType == BootModeType) ||
(mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ConfigDataType == EfiBootOrderType) ||
(mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ConfigDataType == LegacyBootOrderType) ||
(mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ConfigDataType == OsOptimizedDefaultsType))) {
return EFI_ACCESS_DENIED;
}
//
// [Lenovo BIOS Setup Design Guide V2.5]
// [Security]
// Intel (R) SGX Control - If the system is in "Software Controlled(Enabled)" or "Enabled" state,
// the request of "Disabled" or "Software Controlled" are rejected.
//
if (mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ConfigDataType == IntelSgxType) {
//
// Allow Intel (R) SGX set to "Enable".
//
if (AsciiStrCmp (WmiSetBiosSettingParameter->Value, "Enable") == 0) {
return EFI_SUCCESS;
}
//
// Not allowed setting when Intel (R) SGX is in "Enable" state.
//
if (*mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].L05WmiSetupItem == 1) { // mIntelSgxStrList[1]: Enable
return EFI_ACCESS_DENIED;
}
//
// Allow Intel (R) SGX set to "Software Controlled(Enabled)".
//
if ((mIsSgxFeatureCtrlSet) &&
(AsciiStrCmp (WmiSetBiosSettingParameter->Value, "Software Controlled") == 0)) {
return EFI_SUCCESS;
}
//
// Not allowed setting when Intel (R) SGX is in "Software Controlled(Enabled)" state.
//
if ((mIsSgxFeatureCtrlSet) &&
(*mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].L05WmiSetupItem == 0)) { // mIntelSgxStrList[0]: Software Controlled
return EFI_ACCESS_DENIED;
}
return EFI_SUCCESS;
}
//
// [Lenovo BIOS Setup Design Guide V2.5]
// [Security]
// Secure Boot - WMI Enable Only.
//
if (mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ConfigDataType == SecureBootType) {
if (AsciiStrCmp (WmiSetBiosSettingParameter->Value, "Disable") == 0) {
return EFI_ACCESS_DENIED;
}
}
return Status;
}
/**
Extend setting for switch config type.
@param None.
@retval EFI_SUCCESS This function execute successfully.
@retval Others An unexpected error occurred.
**/
EFI_STATUS
SwitchConfigExtendSetting (
VOID
)
{
EFI_STATUS Status;
Status = EFI_SUCCESS;
//
// Extend setting for switch config type
//
switch (mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ConfigDataType) {
case DeviceGuardType:
//
// Intel - Set "Intel Virtualization Technology, Intel VT-d Feature" to Enabled.
// AMD - Set "AMD V (TM) Technology" to Enabled.
// Common - Set "Secure Boot and Os Optimized Defaults" to Enabled.
// Set "Boot Mode" to UEFI.
//
if (mL05WmiSetupItem.L05DeviceGuard == L05_WMI_SETUP_ITEM_ENABLE) {
mL05WmiSetupItem.L05IntelVt = L05_WMI_SETUP_ITEM_ENABLE;
mL05WmiSetupItem.L05IntelVtd = L05_WMI_SETUP_ITEM_ENABLE;
mL05WmiSetupItem.L05SecureBoot = L05_WMI_SETUP_ITEM_ENABLE;
mL05WmiSetupItem.L05OsOptimizedDefault = L05_WMI_SETUP_ITEM_ENABLE;
mL05WmiSetupItem.L05BootMode = L05_WMI_BOOT_MODE_UEFI;
}
break;
}
return Status;
}
/**
WMI Method for Set BIOS setting -
Mapping to WMI class : Lenovo_SetBiosSetting
Mapping to ASL method : WMA1
@param None
@retval EFI_SUCCESS This function execute successfully.
@retval EFI_ACCESS_DENIED WMI input password is invalid.
@retval Others An unexpected error occurred.
**/
EFI_STATUS
EFIAPI
WmiSetBiosSettingA1 (
VOID
)
{
EFI_STATUS Status;
UINTN BufferOffset;
UINTN TempBufferOffset;
CHAR8 SelectStr[L05_WMI_BUFFER_MAX_SIZE];
UINT16 SelectStrLen;
UINTN SelectStrListIndex;
UINTN SectionCount;
WMI_SET_BIOS_SETTING_PARAMETER WmiSetBiosSettingParameter;
WMI_CHECK_PASSWORD_PARAMETER WmiCheckPasswordParameter;
//
// Initialization
//
Status = EFI_SUCCESS;
BufferOffset = 0;
ZeroMem (&WmiSetBiosSettingParameter, sizeof (WMI_SET_BIOS_SETTING_PARAMETER));
ZeroMem (&WmiCheckPasswordParameter, sizeof (WMI_CHECK_PASSWORD_PARAMETER));
//
// Analyze WMI input buffer
//
Status = AnalyzeWmiInputBuffer (SelectStr, &SelectStrLen, &mL05GlobalNVSArea->L05WmiItem, &SelectStrListIndex);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Check L05 WMI Setup Item is Valid
//
if (*mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].L05WmiSetupItemValid == FALSE) {
return EFI_UNSUPPORTED;
}
//
// Check SCU access level is Read Only
//
if (mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ScuAccessLevel == ReadOnly) {
return EFI_UNSUPPORTED;
}
//
// Part section
//
SectionCount = 0;
TempBufferOffset = 0;
for (BufferOffset = 0; BufferOffset < mL05GlobalNVSArea->L05WmiBufferLen; BufferOffset++) {
if ((mL05GlobalNVSArea->L05WmiBuffer[BufferOffset] != ',')
&&(mL05GlobalNVSArea->L05WmiBuffer[BufferOffset] != ';')) {
continue;
}
mL05GlobalNVSArea->L05WmiBuffer[BufferOffset] = 0;
switch (SectionCount) {
case SetBiosSettingItem:
WmiSetBiosSettingParameter.Item = &mL05GlobalNVSArea->L05WmiBuffer[TempBufferOffset];
break;
case SetBiosSettingValue:
WmiSetBiosSettingParameter.Value = &mL05GlobalNVSArea->L05WmiBuffer[TempBufferOffset];
break;
case SetBiosSettingPassword:
WmiCheckPasswordParameter.Password = &mL05GlobalNVSArea->L05WmiBuffer[TempBufferOffset];
break;
case SetBiosSettingPasswordEncoding:
WmiCheckPasswordParameter.PasswordEncodingStr = &mL05GlobalNVSArea->L05WmiBuffer[TempBufferOffset];
break;
case SetBiosSettingPasswordLanguage:
WmiCheckPasswordParameter.PasswordLanguageStr = &mL05GlobalNVSArea->L05WmiBuffer[TempBufferOffset];
break;
}
TempBufferOffset = BufferOffset;
TempBufferOffset++;
SectionCount++;
}
switch (SectionCount) {
case SetBiosSettingWithoutPassword:
//
// [Lenovo BIOS Setup using WMI Deployment Guide - Third Edition (February 2016)]
// Password Authentication:
// If a supervisor password is already set, you must specify that supervisor password before you can change any
// BIOS settings.
//
if (mAdminPasswordExist) {
Status = EFI_ACCESS_DENIED;
return Status;
}
case SetBiosSettingWithPassword:
//
// When admin password exist need to check password
//
if (mAdminPasswordExist) {
Status = WmiCheckAdminPassword (
WmiCheckPasswordParameter.Password,
WmiCheckPasswordParameter.PasswordEncodingStr,
WmiCheckPasswordParameter.PasswordLanguageStr
);
if (EFI_ERROR (Status)) {
return Status;
}
}
//
// Extend check for set BIOS setting.
//
Status = SetBiosSettingExtendCheck (&WmiSetBiosSettingParameter);
if (EFI_ERROR (Status)) {
return Status;
}
if (mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ConfigDataType < SwitchConfigTypeMax) {
//
// Switch config type to get config value
//
Status = GetConfigValue ();
if (EFI_ERROR (Status)) {
return Status;
}
//
// Set setup value
//
Status = SetSetupValue (SelectStrListIndex, WmiSetBiosSettingParameter.Value);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Extend setting for switch config type.
//
Status = SwitchConfigExtendSetting ();
if (EFI_ERROR (Status)) {
return Status;
}
} else {
//
// Special type to set config value
//
Status = EFI_INVALID_PARAMETER;
switch (mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].ConfigDataType) {
case ClearUserPasswordType:
case ClearIntelPttKeyType:
case ClearAmdPspKeyType:
case ResetToSetupModeType:
case RestoreFactoryKeysType:
*mWmiBiosConfigEnumMap[mL05GlobalNVSArea->L05WmiItem].L05WmiSetupItem = TRUE;
Status = EFI_SUCCESS;
break;
case EfiBootOrderType:
Status = WmiSetBootOrder (
WmiSetBiosSettingParameter.Value,
mL05WmiSetupItem.L05EfiBootOrder,
mL05WmiSetupItem.L05EfiBootOrderCount,
mL05WmiSetupItem.L05WmiEfiBootDescription
);
break;
case LegacyBootOrderType:
Status = WmiSetBootOrder (
WmiSetBiosSettingParameter.Value,
mL05WmiSetupItem.L05LegacyBootOrder,
mL05WmiSetupItem.L05LegacyBootOrderCount,
mL05WmiSetupItem.L05WmiLegacyBootDescription
);
break;
default:
return EFI_UNSUPPORTED;
}
}
break;
default:
Status = EFI_UNSUPPORTED;
}
if (EFI_ERROR (Status)) {
return Status;
}
//
// Clean WMI buffer
//
ZeroMem (mL05GlobalNVSArea->L05WmiBuffer, L05_WMI_BUFFER_MAX_SIZE);
return Status;
}