alder_lake_bios/Lcfc/LfcPkg/BiosWmiSmm/BiosWmiSmm.c

1553 lines
53 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.
//
//******************************************************************************
/*++
Abstract:
This driver is used BIOS WMI feature, it will public BIOS WMI SSDT table, register
software SMI handler for dealing with the request by APP.
History:
Date Name Version Change Notes
2015.12.7 Steven Wang v1.00 Initial release
Module Name:
BiosWmiSmm.c
--*/
#include "BiosWmiSmm.h"
BIOS_WMI_NVS *mBiosWmiNvs;
UINT8 mAscii[62] = {
// a~z
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
//A~Z
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A,
// 0~9
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39
};
UINT8 mScanCode[62] = {
//a~z(A~Z)
0x1E, 0x30, 0x2E, 0x20, 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26, 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1F, 0x14, 0x16, 0x2F, 0x11, 0x2D, 0x15, 0x2C,
//a~z(A~Z)
0x1E, 0x30, 0x2E, 0x20, 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26, 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1F, 0x14, 0x16, 0x2F, 0x11, 0x2D, 0x15, 0x2C,
//0~9
0x0B, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A
};
/**
Add length and checksum to password
@param Password Unicode password string pointer.
@param PasswordLength Password string length.
@retval ASCII password string pointer
**/
UINT8 *
EncodePassword (
IN VOID *Password
)
{
UINT8 CheckSum = 0;
UINT8 *EncodeCode;
UINT8 *W16PasswordPtr = Password;
UINTN W16PaswdLength;
UINTN Index;
UINTN PasswordSize = FixedPcdGet16(PcdDefaultSysPasswordMaxLength);
EncodeCode = NULL;
//
//Calculate real Password length
//
for (Index = 0; Index < PasswordSize; Index++) {
if (W16PasswordPtr[Index] == 0) {
break;
}
}
W16PaswdLength = Index;
EncodeCode = AllocateZeroPool (W16PaswdLength + 2);
if (EncodeCode == NULL) {
return NULL;
}
//
//Put Password length at the first byte
//
EncodeCode[0] = (UINT8) W16PaswdLength;
CheckSum = EncodeCode[0];
for (Index = 1; Index < W16PaswdLength + 1; Index++) {
EncodeCode[Index] = W16PasswordPtr[Index - 1];
CheckSum = CheckSum + EncodeCode[Index];
}
CheckSum = ~CheckSum + 0x01;
//
//put Checksum at the end of password
//
EncodeCode[Index] = CheckSum;
return EncodeCode;
}
/**
This function converts ASCII to Hex.
@param PasswordPtr Password string address.
@param EncodePasswordPtr Encoded Password.
@param EncodePasswordLength Password string length.
@retval EFI_SUCCESS Convert successfully.
@retval EFI_INVALID_PARAMETER Invalid password.
**/
EFI_STATUS
Ascii2Hex (
IN UINT8 *PasswordPtr,
OUT UINT8 *EncodePasswordPtr,
OUT UINTN *EncodePasswordLength
)
{
UINT8 i = 0;
UINT8 Index = 0;
UINT8 *PasswordPtrTemp;
UINT8 PasswordPrtLength;
PasswordPtrTemp = AllocateZeroPool (FixedPcdGet16(PcdDefaultSysPasswordMaxLength) + 2);
for(Index = 0; ; Index ++ ){
if(PasswordPtr[Index] == 0) {
break;
}
if((PasswordPtr[Index] >= 0x30) && (PasswordPtr[Index] <= 0x39)) {// 0~9
PasswordPtrTemp[Index] = PasswordPtr[Index] - 0x30;
} else if ((PasswordPtr[Index] >= 0x41) && (PasswordPtr[Index] <= 0x46)) { //A~Z
PasswordPtrTemp[Index] = PasswordPtr[Index] - 0x37;
} else if ((PasswordPtr[Index] >= 0x61) && (PasswordPtr[Index] <= 0x66)) { //a~z
PasswordPtrTemp[Index] = PasswordPtr[Index] - 0x57;
} else {
return EFI_INVALID_PARAMETER;
}
}
*EncodePasswordLength = Index / 2;
PasswordPrtLength = Index;
// combine two number to one hex
for(Index = 0; Index < PasswordPrtLength;) {
EncodePasswordPtr[i] = ((PasswordPtrTemp[Index] << 4) | PasswordPtrTemp[Index+1]);
Index += 2;
i++;
}
return EFI_SUCCESS;
}
/**
This function converts ASCII to Scan Code.
@param PasswordPtr Password string address.
@param AsciiLang Password encode as ASCII by which language.
@param EncodePasswordPtr Encoded Password.
@param EncodePasswordLength Password string length.
@retval EFI_SUCCESS Convert successfully.
@retval Others Convert fail.
**/
EFI_STATUS
Ascii2ScanCode (
IN UINT8 *PasswordPtr,
IN UINT8 AsciiLang,
OUT UINT8 *EncodePasswordPtr,
OUT UINTN *EncodePasswordLength
)
{
UINT8 i = 0;
UINT8 Index = 0;
//
// US ascii
//
if (AsciiLang == 0) {
//
//ascii to scan code
//
for (Index = 0; ; Index++) {
if (PasswordPtr[Index] == 0) {
break;
}
for (i = 0; i < 62; i++) {
if (PasswordPtr[Index] == mAscii[i]) {
EncodePasswordPtr[Index] = mScanCode[i];
break;
}
}
}
*EncodePasswordLength = Index;
} else if (AsciiLang == 1) {
// FR ascii
//Todo
} else if (AsciiLang == 2) {
// US ascii
//Todo
}
return EFI_SUCCESS;
}
/**
compare two password for system password.
@param s1 password 1 in variable
@param s2 password 2 in operation region
@retval TRUE they are the same
@retval FALSE they are different
**/
BOOLEAN
PasswordCmp (
UINT8 *s1,
UINT8 *s2,
UINT8 EncodeType,
UINT8 AsciiLang
)
{
UINT8 *s2Temp;
UINT8 Index = 0;
UINTN EncodePasswordLength = 0;
EFI_STATUS Status = EFI_SUCCESS;
s2Temp = AllocateZeroPool (FixedPcdGet16(PcdDefaultSysPasswordMaxLength) + 2);
// ascii password, need to change to scan code
if (EncodeType == 0) {
//
// Convert Ascci code to Scan Code, because password is Scan Code.
//
Ascii2ScanCode(s2, AsciiLang, s2Temp, &EncodePasswordLength);
} else if (EncodeType == 1) {
//scan code
Status = Ascii2Hex (s2, s2Temp, &EncodePasswordLength);
if (EFI_ERROR (Status)) {
return FALSE;
}
}
//
//Length is not equal
//
if (EncodePasswordLength != s1[0]) {
return FALSE;
}
//
//compare one by one byte
//
for (Index = 0; Index < s1[0]; Index++) {
if (s1[Index+1] != s2Temp[Index]) {
return FALSE;
}
}
return TRUE;
}
/**
Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
buffer, and the size of the buffer. If failure return NULL.
@param Name String part of EFI variable name
@param VendorGuid GUID part of EFI variable name
@param VariableSize Returns the size of the EFI variable that was read
@return Dynamically allocated memory that contains a copy of the EFI variable
Caller is responsible freeing the buffer.
@retval NULL Variable was not read
**/
VOID *
EFIAPI
BiosWmiGetVariableAndSize (
IN CHAR16 *Name,
IN EFI_GUID *VendorGuid,
OUT UINTN *VariableSize
)
{
EFI_STATUS Status;
UINTN BufferSize;
VOID *Buffer;
EFI_SMM_VARIABLE_PROTOCOL *nSmmVariable;
Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, &nSmmVariable);
ASSERT_EFI_ERROR (Status);
Buffer = NULL;
//
// Pass in a zero size buffer to find the required buffer size.
//
BufferSize = 0;
Status = nSmmVariable->SmmGetVariable (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 = nSmmVariable->SmmGetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
if (EFI_ERROR (Status)) {
BufferSize = 0;
gSmst->SmmFreePool (Buffer);
Buffer = NULL;
}
}
*VariableSize = BufferSize;
return Buffer;
}
EFI_STATUS
EFIAPI
BiosWmiSetBootOrder (
IN UINT32 *SortBootOrder,
IN UINT8 CheckValidBoot,
IN EFI_SMM_VARIABLE_PROTOCOL *SmmVariable
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT16 *BootOrder = NULL;
BOOT_OPTION_MAP BootOptionMap [8];
UINTN BootOrderSize = 0;
UINTN BootOptionCnt = 0;
UINTN Index = 0;
UINT8 *BootOption = NULL;
CHAR16 *BootOptionDes = NULL;
UINTN BootOptionSize = 0;
UINT16 OptionName[10] = {0};
UINT8 BtOdCount = 0;
UINT8 BtOdIndex = 0;
UINT8 BootOrderIndex =0;
UINT8 FoundFlag = 0;
//
// Get all boot option
//
BootOrder = BiosWmiGetVariableAndSize (
L"BootOrder",
&gEfiGlobalVariableGuid,
&BootOrderSize
);
if (NULL == BootOrder) {
mBiosWmiNvs->ReturnCode = WMI_GET_BOOTORDER_FAIL;
return WMI_GET_BOOTORDER_FAIL;
}
BootOptionCnt = BootOrderSize / sizeof (UINT16);
for (Index = 0; Index < BootOptionCnt; Index++) {
UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);
BootOption = BiosWmiGetVariableAndSize (
OptionName,
&gEfiGlobalVariableGuid,
&BootOptionSize
);
if (BootOption == NULL) {
mBiosWmiNvs->ReturnCode = WMI_GET_BOOTOPTION_FAIL;
return WMI_GET_BOOTOPTION_FAIL;
}
BootOption = BootOption + sizeof (UINT32) + sizeof (UINT16); //Pass "option attribute(UINT32)", "option file path size(UINT16)"
BootOptionDes = (CHAR16 *) BootOption;
if (!(StrCmp (BootOptionDes, L"Windows Boot Manager"))){
BootOptionMap[Index].BootOrder = BootOrder[Index];
BootOptionMap[Index].BootType = EFI_SATA;
} else if (!(StrCmp (BootOptionDes, L"EFI USB Device"))){
BootOptionMap[Index].BootOrder = BootOrder[Index];
BootOptionMap[Index].BootType = EFI_USB;
} else if (!(StrCmp (BootOptionDes, L"EFI Network"))){
BootOptionMap[Index].BootOrder = BootOrder[Index];
BootOptionMap[Index].BootType = EFI_PXE;
} else if (!(StrCmp (BootOptionDes, L"EFI DVD/CDROM"))){
BootOptionMap[Index].BootOrder = BootOrder[Index];
BootOptionMap[Index].BootType = EFI_DVD;
} else {
mBiosWmiNvs->ReturnCode = WMI_UNKNOWN_BOOT_OPTION;
return WMI_UNKNOWN_BOOT_OPTION;
}
}
//
// Make sure the each input boot order item different
//
{
UINT8 x;
UINT8 y;
UINT8 BtOdTable[8];
UINT8 BtCount;
for (x = 0; (((*SortBootOrder) >> (x * 4)) & 0xF) != 0; x++) {
BtOdTable[x] = ((*SortBootOrder) >> (x * 4)) & 0xF;
}
BtCount = x;
for (x = 0; x < BtCount; x++) {
for (y = 0; y < BtCount; y++) {
if (BtOdTable[x] == BtOdTable[y] && (x != y)) {
mBiosWmiNvs->ReturnCode = WMI_INVALID_BOOT_SORT_REQUEST;
return EFI_SUCCESS;
}
}
}
}
BtOdCount = 0;
for (BtOdIndex = 0; (((*SortBootOrder) >> (BtOdIndex * 4)) & 0xF) != 0; BtOdIndex++) {
BootOrderIndex = ((*SortBootOrder) >> (BtOdIndex * 4)) & 0xF;
for (Index = 0; Index < BootOptionCnt; Index++) {
if (BootOrderIndex == BootOptionMap[Index].BootType){
BootOrder[BtOdCount] = BootOptionMap[Index].BootOrder;
FoundFlag = 1;
BtOdCount++;
} else if (BootOrderIndex == BootOptionMap[Index].BootType){
BootOrder[BtOdCount] = BootOptionMap[Index].BootOrder;
BtOdCount++;
} else if (BootOrderIndex == BootOptionMap[Index].BootType){
BootOrder[BtOdCount] = BootOptionMap[Index].BootOrder;
FoundFlag = 1;
BtOdCount++;
} else if (BootOrderIndex == BootOptionMap[Index].BootType){
BootOrder[BtOdCount] = BootOptionMap[Index].BootOrder;
FoundFlag = 1;
BtOdCount++;
} else {
if ((Index == (BootOptionCnt - 1)) && (FoundFlag == 0) && (CheckValidBoot == 1)) {
mBiosWmiNvs->ReturnCode = WMI_UNKNOWN_BOOT_OPTION;
return WMI_UNKNOWN_BOOT_OPTION;
}
}
}
}
Status = SmmVariable->SmmSetVariable (
L"BootOrder",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
BootOrderSize,
BootOrder
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR(Status)) {
mBiosWmiNvs->ReturnCode = WMI_UNSUPPORTED;
return WMI_UNSUPPORTED;
}
mBiosWmiNvs->ReturnCode = WMI_SUCCESS;
return EFI_SUCCESS;
}
/**
Get Password and Set Password indicator.
@retval EFI_SUCCESS Set Password indicator successfully.
@retval Others Password Service protocol is not ready.
**/
EFI_STATUS
SetPasswordindicator(
VOID
)
{
EFI_GUID SystemSupervisorPasswordGuid = LVAR_SYSTEM_SUPER_PASSWORD_GUID;
EFI_GUID SystemUserPasswordGuid = LVAR_SYSTEM_USER_PASSWORD_GUID;
EFI_STATUS Status;
UINT32 DataSize = WMI_MAX_PASSWORD_LENGTH + 2; //Length(1) + Password(16) + Checksum(1)
LENOVO_VARIABLE_PROTOCOL *LenovoVariable = NULL;
UINT8 *PasswordBuf = NULL;
mBiosWmiNvs->PasswordIndicator = 0;
Status = gSmst->SmmLocateProtocol (&gLenovoVariableProtocolGuid, NULL, &LenovoVariable);
if (EFI_ERROR(Status)) {
return Status;
}
PasswordBuf = AllocateZeroPool (DataSize);
Status = LenovoVariable->GetVariable (
LenovoVariable,
&SystemSupervisorPasswordGuid,
&DataSize,
PasswordBuf);
if (!EFI_ERROR (Status)) {
if ((PasswordBuf[0] <= 16) && (PasswordBuf[0] > 0)) {
mBiosWmiNvs->PasswordIndicator |= SYS_SUPERVISOR_PASSWORD_LOCK;
}
}
Status = LenovoVariable->GetVariable (
LenovoVariable,
&SystemUserPasswordGuid,
&DataSize,
PasswordBuf);
if (!EFI_ERROR (Status)) {
if ((PasswordBuf[0] <= 16) && (PasswordBuf[0] > 0)) {
mBiosWmiNvs->PasswordIndicator |= SYS_USER_PASSWORD_LOCK;
}
}
gSmst->SmmFreePool(PasswordBuf);
return Status;
}
/**
Software SMI callback for handle the request from BIOS WMI ASL.
Caution: This function may receive untrusted input.
Variable and ACPINvs are external input, so this function will validate
its data structure to be valid value.
@param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
@param[in] Context Points to an optional handler context which was specified when the
handler was registered.
@param[in, out] CommBuffer A pointer to a collection of data in memory that will
be conveyed from a non-SMM environment into an SMM environment.
@param[in, out] CommBufferSize The size of the CommBuffer.
@retval EFI_SUCCESS The interrupt was handled successfully.
**/
EFI_STATUS
EFIAPI
BiosWmiCallback (
IN EFI_HANDLE DispatchHandle,
IN CONST VOID *Context,
IN OUT VOID *CommBuffer,
IN OUT UINTN *CommBufferSize
)
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_SMM_VARIABLE_PROTOCOL *SmmVariable = NULL;
SYSTEM_CONFIGURATION SetupVariable = {0};
EFI_GUID SystemConfigurationGuid = SYSTEM_CONFIGURATION_GUID;
UINTN DataSize = 0;
LENOVO_VARIABLE_PROTOCOL *mLenovoVariable = NULL;
EFI_GUID SystemSupervisorPasswordGuid = LVAR_SYSTEM_SUPER_PASSWORD_GUID;
EFI_GUID SystemUserPasswordGuid = LVAR_SYSTEM_USER_PASSWORD_GUID;
UINT8 *SystemSupervisorBuffer = NULL;
UINT8 *SystemUserBuffer = NULL;
UINT8 *SystemPasswordBuffer = NULL;
UINT8 *SystemPasswordEncode = NULL;
UINT8 SCUItemBuffer[25] = {0};
UINTN PasswordSize = FixedPcdGet16(PcdDefaultSysPasswordMaxLength) + 2;
UINTN PasswordSetSize = FixedPcdGet16(PcdDefaultSysPasswordMaxLength) + 2;
UINT16 *BootOrder = NULL;
BOOT_OPTION_MAP BootOptionMap [8];
UINTN BootOrderSize = 0;
UINTN BootOptionCnt = 0;
UINTN Index = 0;
UINT8 *BootOption = NULL;
CHAR16 *BootOptionDes = NULL;
UINTN BootOptionSize = 0;
UINT16 OptionName[10] = {0};
UINT32 WmiBootOrder = 0;
UINT32 WmiDefaultBootOrder = 0x3421;
UINT8 BootCount = 0;
UINT8 EfiSataFlag = 0;
UINT8 EfiUsbFlag = 0;
UINT8 EfiPxeFlag = 0;
UINT8 EfiDvdFlag = 0;
Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, &SmmVariable);
ASSERT_EFI_ERROR (Status);
DataSize = sizeof (SYSTEM_CONFIGURATION);
Status = SmmVariable->SmmGetVariable (
L"Setup",
&SystemConfigurationGuid,
NULL,
&DataSize,
&SetupVariable
);
if (EFI_ERROR(Status)) {
mBiosWmiNvs->ReturnCode = WMI_UNSUPPORTED;
return EFI_SUCCESS;
}
Status = gSmst->SmmLocateProtocol (&gLenovoVariableProtocolGuid, NULL, &mLenovoVariable);
if (EFI_ERROR (Status)) {
mBiosWmiNvs->ReturnCode = WMI_UNSUPPORTED;
return EFI_SUCCESS;
}
if (mBiosWmiNvs->SmiSubNum == SMM_SYS_PASSWORD_VALIDATE_SUB_CALL) {
// no system password set
if((mBiosWmiNvs->PasswordIndicator & SYS_SUPERVISOR_PASSWORD_LOCK) != SYS_SUPERVISOR_PASSWORD_LOCK) {
mBiosWmiNvs->ReturnCode = WMI_SUCCESS;
return EFI_SUCCESS;
}
// system supervisor password has been set
if((mBiosWmiNvs->PasswordIndicator & SYS_SUPERVISOR_PASSWORD_LOCK) == SYS_SUPERVISOR_PASSWORD_LOCK) {
SystemSupervisorBuffer = AllocateZeroPool (PasswordSize);
// supervisor password
Status = mLenovoVariable->GetVariable (
mLenovoVariable,
&SystemSupervisorPasswordGuid,
&(UINT32)PasswordSize,
SystemSupervisorBuffer);
if (!EFI_ERROR (Status)) {
// password check
if (PasswordCmp (SystemSupervisorBuffer, mBiosWmiNvs->Password, mBiosWmiNvs->EncodeTypeForCheck, mBiosWmiNvs->AsciiLang)) {
gSmst->SmmFreePool(SystemSupervisorBuffer);
mBiosWmiNvs->ReturnCode = WMI_SUCCESS;
return EFI_SUCCESS;
}
}
}
gSmst->SmmFreePool (SystemSupervisorBuffer);
mBiosWmiNvs->ReturnCode = WMI_INVALID_PARAMETER;
return EFI_SUCCESS;
} else if (mBiosWmiNvs->SmiSubNum == SMM_SCU_GET_PASSWORD_STATE) {
SetPasswordindicator ();
return EFI_SUCCESS;
} else if (mBiosWmiNvs->SmiSubNum == SMM_SCU_CHANGE_BIOS_PASSWORD_SETTING) {
// Password Type undeclared and can't change password with no password set.
if((mBiosWmiNvs->PasswordType == 0) || (mBiosWmiNvs->PasswordIndicator == 0)){
mBiosWmiNvs->ReturnCode = WMI_INVALID_PARAMETER;
return EFI_SUCCESS;
}
//
// check supervisor password
//
if(((mBiosWmiNvs->PasswordType & SYS_SUPERVISOR_PASSWORD_LOCK) == SYS_SUPERVISOR_PASSWORD_LOCK)
&& ((mBiosWmiNvs->PasswordIndicator & SYS_SUPERVISOR_PASSWORD_LOCK) == SYS_SUPERVISOR_PASSWORD_LOCK)) {
//
// SuperVisor password have been set, need check
//
SystemSupervisorBuffer = AllocateZeroPool (PasswordSize);
// supervisor password
Status = mLenovoVariable->GetVariable (
mLenovoVariable,
&SystemSupervisorPasswordGuid,
&(UINT32)PasswordSize,
SystemSupervisorBuffer);
if (!EFI_ERROR (Status)) {
// password check
if (PasswordCmp (SystemSupervisorBuffer, mBiosWmiNvs->CurrentPassword, mBiosWmiNvs->EncodeTypeForSave, mBiosWmiNvs->AsciiLang)) {
ZeroMem (mBiosWmiNvs->CurrentPassword, 34);
gSmst->SmmFreePool(SystemSupervisorBuffer);
mBiosWmiNvs->ReturnCode = WMI_SUCCESS;
return EFI_SUCCESS;
}
}
ZeroMem (mBiosWmiNvs->CurrentPassword, 34);
gSmst->SmmFreePool(SystemSupervisorBuffer);
}// check supervisor password
//
// check user password
//
if(((mBiosWmiNvs->PasswordType & SYS_USER_PASSWORD_LOCK) == SYS_USER_PASSWORD_LOCK)
&& ((mBiosWmiNvs->PasswordIndicator & SYS_USER_PASSWORD_LOCK) == SYS_USER_PASSWORD_LOCK)) {
//
// SuperVisor password have been set, need check
//
SystemUserBuffer = AllocateZeroPool (PasswordSize);
// supervisor password
Status = mLenovoVariable->GetVariable (
mLenovoVariable,
&SystemUserPasswordGuid,
&(UINT32)PasswordSize,
SystemUserBuffer);
if (!EFI_ERROR (Status)) {
// password check
if (PasswordCmp (SystemUserBuffer, mBiosWmiNvs->CurrentPassword, mBiosWmiNvs->EncodeTypeForSave, mBiosWmiNvs->AsciiLang)) {
ZeroMem (mBiosWmiNvs->CurrentPassword, 34);
gSmst->SmmFreePool(SystemUserBuffer);
mBiosWmiNvs->ReturnCode = WMI_SUCCESS;
return EFI_SUCCESS;
}
}
ZeroMem (mBiosWmiNvs->CurrentPassword, 34);
gSmst->SmmFreePool(SystemUserBuffer);
}// check user password
mBiosWmiNvs->ReturnCode = WMI_INVALID_PARAMETER;
return EFI_SUCCESS;
} else if (mBiosWmiNvs->SmiSubNum == SMM_SCU_SAVE_BIOS_SETTING_SUB_CALL) {
if (mBiosWmiNvs->LoadDefaultFlag == 0x01) {
BiosWmiSetBootOrder (&WmiDefaultBootOrder, FALSE, SmmVariable);
//"Wireless LAN";
SetupVariable.L05WirelessFunction = WMI_ENABLE;
//"Power Beep";
SetupVariable.L05PowerBeepFunction = WMI_DISABLE;
//"Intel Virtual Technology";
#if (FixedPcdGet32 (PcdPlatformIntelOrAmd) == 1)
SetupVariable.VT = 0x00;
#endif
//"BIOS Back Flash";
SetupVariable.L05BiosBackFlash = WMI_DISABLE;
//"HotKey Mode";
SetupVariable.L05HotKeyMode = WMI_ENABLE;
//"Intel Platform Trust";
#if (FixedPcdGet32 (PcdPlatformIntelOrAmd) == 1)
SetupVariable.PTTEnable = WMI_ENABLE;
#endif
//"Secure Boot";
SetupVariable.L05SecureBoot = WMI_ENABLE;
//"Boot Mode";
if (SetupVariable.L05DefaultType == WMI_DISABLE) {
SetupVariable.BootTypeReserved = WMI_UEFI;
} else {
SetupVariable.BootTypeReserved = WMI_LEGACY_SUPPORT;
}
//"Fast Boot";
SetupVariable.L05FastBoot = WMI_ENABLE;
//"USB Boot";
SetupVariable.UsbBoot = WMI_USB_ENABLE;
//"PXE Boot to LAN";
SetupVariable.PxeBootToLan = WMI_ENABLE;
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);
if (EFI_ERROR(Status)) {
mBiosWmiNvs->ReturnCode = WMI_UNSUPPORTED;
return EFI_SUCCESS;
}
mBiosWmiNvs->ReturnCode = WMI_SUCCESS;
return EFI_SUCCESS;
}
//"Password"
strcpy (SCUItemBuffer, "Password");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
//
//change password
//
SystemPasswordBuffer = AllocateZeroPool (PasswordSetSize);
//Encode as ASCII
if(mBiosWmiNvs->EncodeTypeForSave == 0) {
Ascii2ScanCode(mBiosWmiNvs->NewPassword, mBiosWmiNvs->AsciiLang, SystemPasswordBuffer, &PasswordSetSize);
}
//Encode as Scan Code
if(mBiosWmiNvs->EncodeTypeForSave == 1) {
Status = Ascii2Hex (mBiosWmiNvs->NewPassword, SystemPasswordBuffer, &PasswordSetSize);
if (EFI_ERROR(Status)) {
gSmst->SmmFreePool(SystemPasswordBuffer);
ZeroMem (mBiosWmiNvs->NewPassword, 34);
mBiosWmiNvs->ReturnCode = WMI_INVALID_PARAMETER;
return EFI_SUCCESS;
}
}
//
//Encode password
//
SystemPasswordEncode = AllocateZeroPool (PasswordSetSize + 2);
SystemPasswordEncode = EncodePassword(SystemPasswordBuffer);
ZeroMem (mBiosWmiNvs->NewPassword, 34);
//
//Change SuperVisor password
//
if(((mBiosWmiNvs->PasswordType & SYS_SUPERVISOR_PASSWORD_LOCK) == SYS_SUPERVISOR_PASSWORD_LOCK)
&& ((mBiosWmiNvs->PasswordIndicator & SYS_SUPERVISOR_PASSWORD_LOCK) == SYS_SUPERVISOR_PASSWORD_LOCK)) {
//if length is 0, then delete the password
if(SystemPasswordEncode == NULL){
PasswordSetSize = 0;
//
// User password can't exist only, so delete it.
//
Status = mLenovoVariable->SetVariable (
mLenovoVariable,
&SystemUserPasswordGuid,
(UINT32)PasswordSetSize,
SystemPasswordEncode);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR(Status)) {
gSmst->SmmFreePool(SystemPasswordEncode);
mBiosWmiNvs->ReturnCode = WMI_INVALID_PARAMETER;
return EFI_SUCCESS;
}
} else {
PasswordSetSize = SystemPasswordEncode[0] + 2;
}
Status = mLenovoVariable->SetVariable (
mLenovoVariable,
&SystemSupervisorPasswordGuid,
(UINT32)PasswordSetSize,
SystemPasswordEncode);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR(Status)) {
gSmst->SmmFreePool(SystemPasswordEncode);
mBiosWmiNvs->ReturnCode = WMI_INVALID_PARAMETER;
return EFI_SUCCESS;
}
gSmst->SmmFreePool(SystemPasswordEncode);
mBiosWmiNvs->ReturnCode = WMI_SUCCESS;
return EFI_SUCCESS;
}
//
//Change User password
//
if(((mBiosWmiNvs->PasswordType & SYS_USER_PASSWORD_LOCK) == SYS_USER_PASSWORD_LOCK)
&& ((mBiosWmiNvs->PasswordIndicator & SYS_USER_PASSWORD_LOCK) == SYS_USER_PASSWORD_LOCK)) {
//if length is 0, then delete the password
if (SystemPasswordEncode == NULL) {
PasswordSetSize = 0;
} else {
PasswordSetSize = SystemPasswordEncode[0] + 2;
}
Status = mLenovoVariable->SetVariable (
mLenovoVariable,
&SystemUserPasswordGuid,
(UINT32)PasswordSetSize,
SystemPasswordEncode);
ASSERT_EFI_ERROR (Status);
if (!EFI_ERROR(Status)) {
gSmst->SmmFreePool(SystemPasswordEncode);
mBiosWmiNvs->ReturnCode = WMI_SUCCESS;
return EFI_SUCCESS;
}
}
gSmst->SmmFreePool(SystemPasswordEncode);
mBiosWmiNvs->ReturnCode = WMI_INVALID_PARAMETER;
return EFI_SUCCESS;
}
//"BootOrder"
strcpy (SCUItemBuffer, "BootOrder");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
BiosWmiSetBootOrder (&(mBiosWmiNvs->WmiBootorder), TRUE, SmmVariable);
return EFI_SUCCESS;
}
//"Wireless LAN";
strcpy (SCUItemBuffer, "Wireless LAN");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
SetupVariable.L05WirelessFunction = mBiosWmiNvs->ScuValue;
goto WMIOK;
}
//"Power Beep";
strcpy (SCUItemBuffer, "Power Beep");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
SetupVariable.L05PowerBeepFunction = mBiosWmiNvs->ScuValue;
goto WMIOK;
}
#if (FixedPcdGet32 (PcdPlatformIntelOrAmd) == 1)
//"Intel Virtual Technology";
strcpy (SCUItemBuffer, "Intel Virtual Technology");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
SetupVariable.VT = mBiosWmiNvs->ScuValue;
goto WMIOK;
}
#endif
//"BIOS Back Flash";
strcpy (SCUItemBuffer, "BIOS Back Flash");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
SetupVariable.L05BiosBackFlash = mBiosWmiNvs->ScuValue;
goto WMIOK;
}
//"HotKey Mode";
strcpy (SCUItemBuffer, "HotKey Mode");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
SetupVariable.L05HotKeyMode = mBiosWmiNvs->ScuValue;
goto WMIOK;
}
#if (FixedPcdGet32 (PcdPlatformIntelOrAmd) == 1)
//"Intel Platform Trust";
strcpy (SCUItemBuffer, "Intel Platform Trust");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
SetupVariable.PTTEnable = mBiosWmiNvs->ScuValue;
goto WMIOK;
}
#endif
//"Secure Boot";
strcpy (SCUItemBuffer, "Secure Boot");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
SetupVariable.L05SecureBoot = mBiosWmiNvs->ScuValue;
goto WMIOK;
}
//"Boot Mode";
strcpy (SCUItemBuffer, "Boot Mode");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
SetupVariable.BootTypeReserved = mBiosWmiNvs->ScuValue;
goto WMIOK;
}
//"Fast Boot";
strcpy (SCUItemBuffer, "Fast Boot");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
SetupVariable.L05FastBoot = mBiosWmiNvs->ScuValue;
goto WMIOK;
}
//"USB Boot";
strcpy (SCUItemBuffer, "USB Boot");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
SetupVariable.UsbBoot = mBiosWmiNvs->ScuValue;
goto WMIOK;
}
//"PXE Boot to LAN";
strcpy (SCUItemBuffer, "PXE Boot to LAN");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
SetupVariable.PxeBootToLan = mBiosWmiNvs->ScuValue;
goto WMIOK;
}
//"OS Optimized Default";
strcpy (SCUItemBuffer, "OS Optimized Default");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
SetupVariable.L05DefaultType = mBiosWmiNvs->ScuValue;
goto WMIOK;
}
goto WMIFAIL;
WMIFAIL:
mBiosWmiNvs->ReturnCode = WMI_INVALID_PARAMETER;
return EFI_SUCCESS;
WMIOK:
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);
if (EFI_ERROR(Status)) {
mBiosWmiNvs->ReturnCode = WMI_UNSUPPORTED;
return EFI_SUCCESS;
}
mBiosWmiNvs->ReturnCode = WMI_SUCCESS;
return EFI_SUCCESS;
} else if (mBiosWmiNvs->SmiSubNum == SMM_SCU_GET_BIOS_CURRENT_SETTING) {
if (mBiosWmiNvs->SettingFlag == 0x00) { // Deal with Query BIOS String
//"BootOrder"
strcpy (SCUItemBuffer, "BootOrder");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
//
// Get all boot option
//
BootOrder = BiosWmiGetVariableAndSize (
L"BootOrder",
&gEfiGlobalVariableGuid,
&BootOrderSize
);
if (NULL == BootOrder) {
mBiosWmiNvs->ReturnCode = WMI_GET_BOOTORDER_FAIL;
goto SBOEXIT;
}
BootOptionCnt = BootOrderSize / sizeof (UINT16);
for (Index = 0; Index < BootOptionCnt; Index++) {
UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);
BootOption = BiosWmiGetVariableAndSize (
OptionName,
&gEfiGlobalVariableGuid,
&BootOptionSize
);
if (BootOption == NULL) {
mBiosWmiNvs->ReturnCode = WMI_GET_BOOTOPTION_FAIL;
goto SBOEXIT;
}
BootOption = BootOption + sizeof (UINT32) + sizeof (UINT16); //Pass "option attribute(UINT32)", "option file path size(UINT16)"
BootOptionDes = (CHAR16 *) BootOption;
if ((!(StrCmp (BootOptionDes, L"Windows Boot Manager"))) && (EfiSataFlag ==0)) {
BootOptionMap[BootCount].BootOrder = BootOrder[Index];
BootOptionMap[BootCount].BootType = EFI_SATA;
EfiSataFlag = 1;
BootCount++;
} else if ((!(StrCmp (BootOptionDes, L"EFI USB Device"))) && (EfiUsbFlag ==0)) {
BootOptionMap[BootCount].BootOrder = BootOrder[Index];
BootOptionMap[BootCount].BootType = EFI_USB;
EfiUsbFlag = 1;
BootCount++;
} else if ((!(StrCmp (BootOptionDes, L"EFI Network"))) && (EfiPxeFlag ==0)) {
BootOptionMap[BootCount].BootOrder = BootOrder[Index];
BootOptionMap[BootCount].BootType = EFI_PXE;
EfiPxeFlag = 1;
BootCount++;
} else if ((!(StrCmp (BootOptionDes, L"EFI DVD/CDROM"))) && (EfiDvdFlag ==0)) {
BootOptionMap[BootCount].BootOrder = BootOrder[Index];
BootOptionMap[BootCount].BootType = EFI_DVD;
EfiDvdFlag = 1;
BootCount++;
} else {
if (((StrCmp (BootOptionDes, L"Windows Boot Manager"))) && ((StrCmp (BootOptionDes, L"EFI USB Device"))) \
&& ((StrCmp (BootOptionDes, L"EFI Network"))) && ((StrCmp (BootOptionDes, L"EFI DVD/CDROM")))) {
mBiosWmiNvs->ReturnCode = WMI_UNKNOWN_BOOT_OPTION;
goto SBOEXIT;
}
}
}
for (Index = 0; Index < BootCount; Index++) {
WmiBootOrder = WmiBootOrder | ((BootOptionMap[Index].BootType) << (Index*4));
}
mBiosWmiNvs->WmiBootCount = BootCount;
mBiosWmiNvs->WmiBootorder = WmiBootOrder;
mBiosWmiNvs->ReturnCode = WMI_SUCCESS;
goto SBOEXIT;
}
//"Wireless LAN";
strcpy (SCUItemBuffer, "Wireless LAN");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.L05WirelessFunction == WMI_DISABLE) {
mBiosWmiNvs->ScuValue = WMI_DISABLE;
} else {
mBiosWmiNvs->ScuValue = WMI_ENABLE;
}
goto GBOEXIT;
}
//"Power Beep";
strcpy (SCUItemBuffer, "Power Beep");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.L05PowerBeepFunction == WMI_DISABLE) {
mBiosWmiNvs->ScuValue = WMI_DISABLE;
} else {
mBiosWmiNvs->ScuValue = WMI_ENABLE;
}
goto GBOEXIT;
}
#if (FixedPcdGet32 (PcdPlatformIntelOrAmd) == 1)
//"Intel Virtual Technology";
strcpy (SCUItemBuffer, "Intel Virtual Technology");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.VT == WMI_DISABLE) {
mBiosWmiNvs->ScuValue = WMI_DISABLE;
} else {
mBiosWmiNvs->ScuValue = WMI_ENABLE;
}
goto GBOEXIT;
}
#endif
//"BIOS Back Flash";
strcpy (SCUItemBuffer, "BIOS Back Flash");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.L05BiosBackFlash == WMI_DISABLE) {
mBiosWmiNvs->ScuValue = WMI_DISABLE;
} else {
mBiosWmiNvs->ScuValue = WMI_ENABLE;
}
goto GBOEXIT;
}
//"HotKey Mode";
strcpy (SCUItemBuffer, "HotKey Mode");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.L05HotKeyMode == WMI_DISABLE) {
mBiosWmiNvs->ScuValue = WMI_DISABLE;
} else {
mBiosWmiNvs->ScuValue = WMI_ENABLE;
}
goto GBOEXIT;
}
#if (FixedPcdGet32 (PcdPlatformIntelOrAmd) == 1)
//"Intel Platform Trust";
strcpy (SCUItemBuffer, "Intel Platform Trust");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.PTTEnable == WMI_DISABLE) {
mBiosWmiNvs->ScuValue = WMI_DISABLE;
} else {
mBiosWmiNvs->ScuValue = WMI_ENABLE;
}
goto GBOEXIT;
}
#endif
//"Secure Boot";
strcpy (SCUItemBuffer, "Secure Boot");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.L05SecureBoot == WMI_DISABLE) {
mBiosWmiNvs->ScuValue = WMI_DISABLE;
} else {
mBiosWmiNvs->ScuValue = WMI_ENABLE;
}
goto GBOEXIT;
}
//"Boot Mode";
strcpy (SCUItemBuffer, "Boot Mode");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.BootTypeReserved == WMI_LEGACY_SUPPORT) {
mBiosWmiNvs->ScuValue = WMI_LEGACY_SUPPORT;
} else {
mBiosWmiNvs->ScuValue = WMI_UEFI;
}
goto GBOEXIT;
}
//"Fast Boot";
strcpy (SCUItemBuffer, "Fast Boot");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.L05FastBoot == WMI_DISABLE) {
mBiosWmiNvs->ScuValue = WMI_DISABLE;
} else {
mBiosWmiNvs->ScuValue = WMI_ENABLE;
}
goto GBOEXIT;
}
//"USB Boot";
strcpy (SCUItemBuffer, "USB Boot");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.UsbBoot == WMI_USB_ENABLE) {
mBiosWmiNvs->ScuValue = WMI_USB_ENABLE;
} else {
mBiosWmiNvs->ScuValue = WMI_USB_DISABLE;
}
goto GBOEXIT;
}
//"PXE Boot to LAN";
strcpy (SCUItemBuffer, "PXE Boot to LAN");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.PxeBootToLan == WMI_DISABLE) {
mBiosWmiNvs->ScuValue = WMI_DISABLE;
} else {
mBiosWmiNvs->ScuValue = WMI_ENABLE;
}
goto GBOEXIT;
}
//"OS Optimized Default";
strcpy (SCUItemBuffer, "OS Optimized Default");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.L05DefaultType == WMI_OS_OPTIMIZE_ENABLE) {
mBiosWmiNvs->ScuValue = WMI_OS_OPTIMIZE_ENABLE;
} else {
mBiosWmiNvs->ScuValue = WMI_OS_OPTIMIZE_DISABLE;
}
goto GBOEXIT;
}
} // Deal with Query BIOS String end
if (mBiosWmiNvs->SettingFlag == 0x01) { // Deal with setting BIOS string
//"BootOrder"
strcpy (SCUItemBuffer, "BootOrder");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
//
// Get all boot option
//
BootOrder = BiosWmiGetVariableAndSize (
L"BootOrder",
&gEfiGlobalVariableGuid,
&BootOrderSize
);
if (NULL == BootOrder) {
mBiosWmiNvs->ReturnCode = WMI_GET_BOOTORDER_FAIL;
goto SBOEXIT;
}
BootOptionCnt = BootOrderSize / sizeof (UINT16);
for (Index = 0; Index < BootOptionCnt; Index++) {
UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);
BootOption = BiosWmiGetVariableAndSize (
OptionName,
&gEfiGlobalVariableGuid,
&BootOptionSize
);
if (BootOption == NULL) {
mBiosWmiNvs->ReturnCode = WMI_GET_BOOTOPTION_FAIL;
goto SBOEXIT;
}
BootOption = BootOption + sizeof (UINT32) + sizeof (UINT16); //Pass "option attribute(UINT32)", "option file path size(UINT16)"
BootOptionDes = (CHAR16 *) BootOption;
if ((!(StrCmp (BootOptionDes, L"Windows Boot Manager"))) && (EfiSataFlag ==0)) {
BootOptionMap[BootCount].BootOrder = BootOrder[Index];
BootOptionMap[BootCount].BootType = EFI_SATA;
EfiSataFlag = 1;
BootCount++;
} else if ((!(StrCmp (BootOptionDes, L"EFI USB Device"))) && (EfiUsbFlag ==0)) {
BootOptionMap[BootCount].BootOrder = BootOrder[Index];
BootOptionMap[BootCount].BootType = EFI_USB;
EfiUsbFlag = 1;
BootCount++;
} else if ((!(StrCmp (BootOptionDes, L"EFI Network"))) && (EfiPxeFlag ==0)) {
BootOptionMap[BootCount].BootOrder = BootOrder[Index];
BootOptionMap[BootCount].BootType = EFI_PXE;
EfiPxeFlag = 1;
BootCount++;
} else if ((!(StrCmp (BootOptionDes, L"EFI DVD/CDROM"))) && (EfiDvdFlag ==0)) {
BootOptionMap[BootCount].BootOrder = BootOrder[Index];
BootOptionMap[BootCount].BootType = EFI_DVD;
EfiDvdFlag = 1;
BootCount++;
} else {
if (((StrCmp (BootOptionDes, L"Windows Boot Manager"))) && ((StrCmp (BootOptionDes, L"EFI USB Device"))) \
&& ((StrCmp (BootOptionDes, L"EFI Network"))) && ((StrCmp (BootOptionDes, L"EFI DVD/CDROM")))) {
mBiosWmiNvs->ReturnCode = WMI_UNKNOWN_BOOT_OPTION;
goto SBOEXIT;
}
}
}
for (Index = 0; Index < BootCount; Index++) {
WmiBootOrder = WmiBootOrder | ((BootOptionMap[Index].BootType) << (Index*4));
}
mBiosWmiNvs->WmiBootCount = BootCount;
mBiosWmiNvs->TempWmiBootorder = WmiBootOrder;
mBiosWmiNvs->ReturnCode = WMI_SUCCESS;
goto SBOEXIT;
}
//"Wireless LAN";
strcpy (SCUItemBuffer, "Wireless LAN");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.L05WirelessFunction == WMI_DISABLE) {
mBiosWmiNvs->TempValue = WMI_DISABLE;
} else {
mBiosWmiNvs->TempValue = WMI_ENABLE;
}
goto GBOEXIT;
}
//"Power Beep";
strcpy (SCUItemBuffer, "Power Beep");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.L05PowerBeepFunction == WMI_DISABLE) {
mBiosWmiNvs->TempValue = WMI_DISABLE;
} else {
mBiosWmiNvs->TempValue = WMI_ENABLE;
}
goto GBOEXIT;
}
#if (FixedPcdGet32 (PcdPlatformIntelOrAmd) == 1)
//"Intel Virtual Technology";
strcpy (SCUItemBuffer, "Intel Virtual Technology");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.VT == WMI_DISABLE) {
mBiosWmiNvs->TempValue = WMI_DISABLE;
} else {
mBiosWmiNvs->TempValue = WMI_ENABLE;
}
goto GBOEXIT;
}
#endif
//"BIOS Back Flash";
strcpy (SCUItemBuffer, "BIOS Back Flash");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.L05BiosBackFlash == WMI_DISABLE) {
mBiosWmiNvs->TempValue = WMI_DISABLE;
} else {
mBiosWmiNvs->TempValue = WMI_ENABLE;
}
goto GBOEXIT;
}
//"HotKey Mode";
strcpy (SCUItemBuffer, "HotKey Mode");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.L05HotKeyMode == WMI_DISABLE) {
mBiosWmiNvs->TempValue = WMI_DISABLE;
} else {
mBiosWmiNvs->TempValue = WMI_ENABLE;
}
goto GBOEXIT;
}
#if (FixedPcdGet32 (PcdPlatformIntelOrAmd) == 1)
//"Intel Platform Trust";
strcpy (SCUItemBuffer, "Intel Platform Trust");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (mBiosWmiNvs->ScuValue == WMI_DISABLE) {
mBiosWmiNvs->ReturnCode = WMI_ACCESS_DENIED;
return EFI_SUCCESS;
}
if (SetupVariable.PTTEnable == WMI_DISABLE) {
mBiosWmiNvs->TempValue = WMI_DISABLE;
} else {
mBiosWmiNvs->TempValue = WMI_ENABLE;
}
goto GBOEXIT;
}
#endif
//"Secure Boot";
strcpy (SCUItemBuffer, "Secure Boot");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (mBiosWmiNvs->ScuValue == WMI_DISABLE) {
mBiosWmiNvs->ReturnCode = WMI_ACCESS_DENIED;
return EFI_SUCCESS;
}
if (SetupVariable.L05SecureBoot == WMI_DISABLE) {
mBiosWmiNvs->TempValue = WMI_DISABLE;
} else {
mBiosWmiNvs->TempValue = WMI_ENABLE;
}
goto GBOEXIT;
}
//"Boot Mode";
strcpy (SCUItemBuffer, "Boot Mode");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.BootTypeReserved == WMI_LEGACY_SUPPORT) {
mBiosWmiNvs->TempValue = WMI_LEGACY_SUPPORT;
} else {
mBiosWmiNvs->TempValue = WMI_UEFI;
}
goto GBOEXIT;
}
//"Fast Boot";
strcpy (SCUItemBuffer, "Fast Boot");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.L05FastBoot == WMI_DISABLE) {
mBiosWmiNvs->TempValue = WMI_DISABLE;
} else {
mBiosWmiNvs->TempValue = WMI_ENABLE;
}
goto GBOEXIT;
}
//"USB Boot";
strcpy (SCUItemBuffer, "USB Boot");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.UsbBoot == WMI_USB_ENABLE) {
mBiosWmiNvs->TempValue = WMI_USB_ENABLE;
} else {
mBiosWmiNvs->TempValue = WMI_USB_DISABLE;
}
goto GBOEXIT;
}
//"PXE Boot to LAN";
strcpy (SCUItemBuffer, "PXE Boot to LAN");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))) {
if (SetupVariable.PxeBootToLan == WMI_DISABLE) {
mBiosWmiNvs->TempValue = WMI_DISABLE;
} else {
mBiosWmiNvs->TempValue = WMI_ENABLE;
}
goto GBOEXIT;
}
//"OS Optimized Default";
strcpy (SCUItemBuffer, "OS Optimized Default");
if (!(strcmp (SCUItemBuffer, mBiosWmiNvs->ScuItem))){
if (SetupVariable.L05DefaultType == WMI_OS_OPTIMIZE_ENABLE) {
mBiosWmiNvs->TempValue = WMI_OS_OPTIMIZE_ENABLE;
} else {
mBiosWmiNvs->TempValue = WMI_OS_OPTIMIZE_DISABLE;
}
goto GBOEXIT;
}
} // Deal with setting BIOS string end
goto GBOFAIL;
GBOFAIL:
mBiosWmiNvs->ReturnCode = WMI_INVALID_PARAMETER;
return EFI_SUCCESS;
GBOEXIT:
mBiosWmiNvs->ReturnCode = WMI_SUCCESS;
return EFI_SUCCESS;
SBOEXIT:
return EFI_SUCCESS;
} else {
mBiosWmiNvs->ReturnCode = WMI_UNSUPPORTED;
return EFI_SUCCESS;
}
}
/**
Find the operation region in BIOS WMI ACPI table by given Name and Size,
and initialize it if the region is found.
@param[in, out] Table The BIOS WMI item in ACPI table.
@param[in] Name The name string to find in BIOS WMI table.
@param[in] Size The size of the region to find.
@return The allocated address for the found region.
**/
VOID *
AssignOpRegion (
EFI_ACPI_DESCRIPTION_HEADER *Table,
UINT32 Name,
UINT16 Size
)
{
EFI_STATUS Status;
AML_OP_REGION_32_8 *OpRegion;
EFI_PHYSICAL_ADDRESS MemoryAddress;
MemoryAddress = SIZE_4GB - 1;
//
// Patch some pointers for the ASL code before loading the SSDT.
//
for (OpRegion = (AML_OP_REGION_32_8 *) (Table + 1);
OpRegion <= (AML_OP_REGION_32_8 *) ((UINT8 *) Table + Table->Length);
OpRegion = (AML_OP_REGION_32_8 *) ((UINT8 *) OpRegion + 1)) {
if ((OpRegion->OpRegionOp == AML_EXT_REGION_OP) &&
(OpRegion->NameString == Name) &&
(OpRegion->DWordPrefix == AML_DWORD_PREFIX) &&
(OpRegion->BytePrefix == AML_BYTE_PREFIX)) {
Status = gBS->AllocatePages(AllocateMaxAddress, EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES (Size), &MemoryAddress);
ASSERT_EFI_ERROR (Status);
ZeroMem ((VOID *)(UINTN)MemoryAddress, Size);
OpRegion->RegionOffset = (UINT32) (UINTN) MemoryAddress;
OpRegion->RegionLen = (UINT8) Size;
break;
}
}
return (VOID *) (UINTN) MemoryAddress;
}
/**
Initialize and publish BIOS WMI SSDT table in ACPI table.
@retval EFI_SUCCESS BIOS WMI SSDT table is published successfully.
@retval Others BIOS WMI SSDT table is not published.
**/
EFI_STATUS
PublishBiosWmiAcpiTable (
VOID
)
{
EFI_STATUS Status;
EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
UINTN TableKey;
EFI_ACPI_DESCRIPTION_HEADER *Table;
UINTN TableSize;
Status = GetSectionFromFv (
&gEfiCallerIdGuid,
EFI_SECTION_RAW,
0,
(VOID **) &Table,
&TableSize
);
ASSERT_EFI_ERROR (Status);
ASSERT (Table->OemTableId == SIGNATURE_64 ('W', 'm', 'i', 'T', 'a', 'b', 'l', 'e'));
mBiosWmiNvs = AssignOpRegion (Table, SIGNATURE_32 ('B', 'N', 'V', 'S'), (UINT16) sizeof (BIOS_WMI_NVS));
ASSERT (mBiosWmiNvs != NULL);
//
// Publish the BIOS WMI ACPI table
//
Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
ASSERT_EFI_ERROR (Status);
TableKey = 0;
Status = AcpiTable->InstallAcpiTable (
AcpiTable,
Table,
TableSize,
&TableKey
);
ASSERT_EFI_ERROR (Status);
return Status;
}
/**
The driver's entry point.
It install software SMI callbacks for communication between WMI asl and Smm c code.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
@retval Others Some error occurs when executing this entry point.
**/
EFI_STATUS
EFIAPI
InitializeBiosWmiSmm (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;
EFI_SMM_SW_REGISTER_CONTEXT SwContext;
EFI_HANDLE SwHandle;
Status = PublishBiosWmiAcpiTable ();
ASSERT_EFI_ERROR (Status);
//
// Get the Sw dispatch protocol and register SMI callback functions.
//
Status = gSmst->SmmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, NULL, (VOID**)&SwDispatch);
ASSERT_EFI_ERROR (Status);
SwContext.SwSmiInputValue = SMM_BIOS_WMI_CALL;
Status = SwDispatch->Register (SwDispatch, (EFI_SMM_HANDLER_ENTRY_POINT2) BiosWmiCallback, &SwContext, &SwHandle);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
return EFI_SUCCESS;
}