//***************************************************************************** // // // 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; }