1553 lines
53 KiB
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;
|
|
}
|
|
|