2019 lines
63 KiB
C
2019 lines
63 KiB
C
/** @file
|
|
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2013 - 2021, Insyde Software Corporation. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
|
|
*/
|
|
|
|
|
|
#include "DynamicHotKeyDxe.h"
|
|
#include <ChipsetSetupConfig.h>
|
|
#include <Uefi/UefiBaseType.h>
|
|
|
|
#include <Include/Base.h>
|
|
|
|
#include <Library/HiiDbLib.h>
|
|
#include <Library/HiiStringLib.h>
|
|
#include <Library/HiiConfigAccessLib.h>
|
|
#include <Library/printlib.h>
|
|
#include <Library/FdSupportLib.h>
|
|
#include <Library/SpiAccessLib.h>
|
|
|
|
#include <Protocol/UgaDraw.h>
|
|
#include <Protocol/GraphicsOutput.h>
|
|
#include <Protocol/StringTransform.h>
|
|
#include <Library/DxeInsydeChipsetLib.h>
|
|
|
|
BOOLEAN
|
|
GetMeFwType (
|
|
IN DYNAMIC_STRING *Structure,
|
|
OUT CHAR16 **StringData
|
|
);
|
|
|
|
DYNAMIC_HOTKEY mHotKeyDefine[] = {
|
|
//
|
|
// KeyId ScanCode ShiftKey AltKey CtrlKey Operation
|
|
//
|
|
{KEYID0, F1_KEY, 0x0, 0x0, 0x0, DEVICE_MANAGER_HOT_KEY},
|
|
{KEYID1, F2_KEY, 0x0, 0x0, 0x0, SETUP_HOT_KEY},
|
|
{KEYID2, DEL_KEY, 0x0, 0x0, 0x0, BOOT_MANAGER_HOT_KEY},
|
|
{KEYID3, F10_KEY, 0x0, 0x0, 0x0, BOOT_MAINTAIN_HOT_KEY},
|
|
{KEYID4, ESC_KEY, 0x0, 0x0, 0x0, FRONT_PAGE_HOT_KEY}
|
|
};
|
|
|
|
|
|
DYNAMIC_STRING StringDefine[] = {
|
|
{
|
|
KEYID4, ///< KeyId
|
|
DSTRING_NOT_SYSTEM_INFO, ///< SystemInfoId
|
|
STRING_LOCATION_MIN, ///< LocationX
|
|
STRING_LOCATION_MAX, ///< LocationY
|
|
{
|
|
1, ///< TextMode
|
|
0, ///< GraphicMode
|
|
1, ///< BeforePress
|
|
0, ///< AfterPress
|
|
0 ///< Reserved
|
|
},
|
|
{0xFF, 0xFF, 0xFF, 0}, /// Foreground
|
|
{0, 0, 0, 0}, /// Background
|
|
STRING_TOKEN (STR_DYNAMIC_STR_ESC) ///< StringToken
|
|
},
|
|
{
|
|
KEYID4, ///< KeyId
|
|
DSTRING_NOT_SYSTEM_INFO, ///< SystemInfoId
|
|
STRING_LOCATION_MIN, ///< LocationX
|
|
STRING_LOCATION_MAX, ///< LocationY
|
|
{
|
|
1, ///< TextMode
|
|
0, ///< GraphicMode
|
|
0, ///< BeforePress
|
|
1, ///< AfterPress
|
|
0 ///< Reserved
|
|
},
|
|
{0xFF, 0xFF, 0xFF, 0}, /// Foreground
|
|
{0, 0, 0, 0}, /// Background
|
|
STRING_TOKEN (STR_DYNAMIC_STR_ESC_SELECT) ///< StringToken
|
|
},
|
|
{
|
|
KEYID4, ///< KeyId
|
|
DSTRING_NOT_SYSTEM_INFO, ///< SystemInfoId
|
|
STRING_LOCATION_CENTER, ///< LocationX
|
|
STRING_LOCATION_CENTER, ///< LocationY
|
|
{
|
|
0, ///< TextMode
|
|
1, ///< GraphicMode
|
|
0, ///< BeforePress
|
|
1, ///< AfterPress
|
|
0 ///< Reserved
|
|
},
|
|
{0xFF, 0xFF, 0xFF, 0}, ///Foreground
|
|
{0, 0, 0, 0}, /// Background
|
|
STRING_TOKEN (STR_DYNAMIC_STR_ESC_SELECT2) ///< StringToken
|
|
}
|
|
};
|
|
|
|
//
|
|
// System information table
|
|
//
|
|
DYNAMIC_SYSTEM_INFO SystemInfoTable[] = {
|
|
{BIOS_VERSION, STRING_TOKEN (STR_DYNAMIC_STR_VERSION), STRING_LOCATION_MIN, STRING_LOCATION_MIN},
|
|
{BIOS_RELEASE_DATE, STRING_TOKEN (STR_DYNAMIC_STR_DATE), STRING_LOCATION_MIN, STRING_LOCATION_MIN},
|
|
{CPU_TYPE, STRING_TOKEN (STR_DYNAMIC_STR_CPUTYPE), STRING_LOCATION_MIN, STRING_LOCATION_MIN},
|
|
{MEMORY_BUS_SPEED, STRING_TOKEN (STR_DYNAMIC_STR_MEMSPEED), STRING_LOCATION_MIN, STRING_LOCATION_MIN},
|
|
{CPU_ID, STRING_TOKEN (STR_DYNAMIC_STR_CPUID), STRING_LOCATION_MIN, STRING_LOCATION_MIN}
|
|
};
|
|
|
|
//
|
|
// Hot key operation table
|
|
//
|
|
DYNAMIC_OPERATION OperationTable[] = {
|
|
{NO_OPERATION, STRING_TOKEN (STR_DYNAMIC_STR_NO_OPERATION)},
|
|
{FRONT_PAGE_HOT_KEY, STRING_TOKEN (STR_DYNAMIC_STR_FRONT_PAGE)},
|
|
{MEBX_HOT_KEY, STRING_TOKEN (STR_DYNAMIC_STR_MEBX)},
|
|
{REMOTE_ASST_HOT_KEY, STRING_TOKEN (STR_DYNAMIC_STR_REMOTE_ASST)},
|
|
{SETUP_HOT_KEY, STRING_TOKEN (STR_DYNAMIC_STR_SETUP)},
|
|
{DEVICE_MANAGER_HOT_KEY, STRING_TOKEN (STR_DYNAMIC_STR_DEVICE_MANAGER)},
|
|
{BOOT_MANAGER_HOT_KEY, STRING_TOKEN (STR_DYNAMIC_STR_BOOT_MANAGER)},
|
|
{BOOT_MAINTAIN_HOT_KEY, STRING_TOKEN (STR_DYNAMIC_STR_BOOT_MAINTAINCE)},
|
|
{SECURE_BOOT_HOT_KEY, STRING_TOKEN (STR_DYNAMIC_STR_SECURE_BOOT)}
|
|
};
|
|
|
|
//
|
|
// For variable editor.
|
|
//
|
|
DYNAMIC_HOTKEY_PACKAGE_HEAD DynamicHotKeyInfo = {
|
|
HOTKEY_INFO_SIGNATURE,
|
|
1,
|
|
(UINT64)(UINTN)DynamicHotKeyDxeStrings,
|
|
(UINT64)(UINTN)mHotKeyDefine,
|
|
(UINT64)(UINTN)StringDefine,
|
|
(UINT64)(UINTN)SystemInfoTable,
|
|
(UINT64)(UINTN)OperationTable,
|
|
(UINT8)GET_ARRAY_COUNT (mHotKeyDefine),
|
|
(UINT8)GET_ARRAY_COUNT (StringDefine),
|
|
(UINT8)GET_ARRAY_COUNT (SystemInfoTable),
|
|
(UINT8)GET_ARRAY_COUNT (OperationTable),
|
|
{0}
|
|
};
|
|
|
|
//
|
|
// Module variable
|
|
//
|
|
DYNAMIC_HOTKEY_PROTOCOL mDynamicHotKey;
|
|
KEY_ELEMENT *UpdatedHotKeyList = NULL;
|
|
DYNAMIC_HOTKEY_INTERNAL *mHotKeyList = NULL;
|
|
DYNAMIC_STRING *mStringList = NULL;
|
|
UINTN mHotKeyListCount = 0;
|
|
UINTN mStringListCount = 0;
|
|
BOOLEAN mHotKeyPressed = FALSE;
|
|
UINT8 mPressedKdyId = DSTRING_NO_HOTKEY;
|
|
EFI_HII_HANDLE mHotKeyStringPackHandle;
|
|
VOID *MultiConfigRegionBuffer = NULL;
|
|
BOOLEAN mIsPageType = FALSE;
|
|
UINTN mPageNum = 0;
|
|
HOTKEY_AND_STRING_TABLE *mHotkeyStringTable = NULL;
|
|
EFI_EVENT mReadyToBootEvent = NULL;
|
|
VOID *mFEaddress = 0;
|
|
|
|
|
|
BOOLEAN
|
|
GetMeFwType (
|
|
IN DYNAMIC_STRING *Structure,
|
|
OUT CHAR16 **StringData
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
ME_SETUP *MeSetup;
|
|
|
|
MeSetup = NULL;
|
|
*StringData = HiiGetPackageString (&gEfiCallerIdGuid, Structure->StringToken, NULL);
|
|
|
|
MeSetup = AllocateZeroPool (sizeof (ME_SETUP));
|
|
if (MeSetup == NULL) {
|
|
return FALSE;
|
|
}
|
|
Status = GetChipsetMeSetupVariableDxe (MeSetup, sizeof (ME_SETUP));
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (MeSetup);
|
|
ASSERT_EFI_ERROR (Status);
|
|
return FALSE;
|
|
}
|
|
|
|
if (MeSetup->MeImageType == ME_IMAGE_CORPORATE_SKU_FW) {
|
|
if (MeSetup != NULL) {
|
|
FreePool (MeSetup);
|
|
}
|
|
return TRUE;
|
|
}
|
|
if (MeSetup != NULL) {
|
|
FreePool (MeSetup);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
VOID
|
|
BottomStringCount (
|
|
IN UINTN Operation,
|
|
IN UINT16 Position,
|
|
OUT UINTN *Count
|
|
)
|
|
{
|
|
static UINTN LeftBootomStringCount;
|
|
static UINTN CenterBootomStringCount;
|
|
static UINTN RightBootomStringCount;
|
|
|
|
switch (Operation) {
|
|
|
|
case INITIAL_VALUE:
|
|
LeftBootomStringCount = 0;
|
|
CenterBootomStringCount = 0;
|
|
RightBootomStringCount = 0;
|
|
break;
|
|
|
|
case SET_COUNT:
|
|
if (Position == 0) {
|
|
LeftBootomStringCount++;
|
|
} else if (Position == (UINT16)-1) {
|
|
CenterBootomStringCount++;
|
|
} else if (Position == (UINT16)-2) {
|
|
RightBootomStringCount++;
|
|
}
|
|
break;
|
|
|
|
case GET_LEFT_COUNT:
|
|
*Count = LeftBootomStringCount;
|
|
break;
|
|
|
|
case GET_CENTER_COUNT:
|
|
*Count = CenterBootomStringCount;
|
|
break;
|
|
|
|
case GET_RIGHT_COUNT:
|
|
*Count = RightBootomStringCount;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
FreeInternalResource (
|
|
VOID
|
|
)
|
|
{
|
|
|
|
if (mHotKeyList != NULL) {
|
|
FreePool (mHotKeyList);
|
|
}
|
|
|
|
if (mStringList != NULL) {
|
|
FreePool (mStringList);
|
|
mStringList = NULL;
|
|
}
|
|
}
|
|
|
|
CHAR16 *
|
|
GetStringByStringToken (
|
|
EFI_STRING_ID StringToken
|
|
)
|
|
{
|
|
return HiiGetPackageString (&gEfiCallerIdGuid, StringToken, NULL);
|
|
}
|
|
|
|
BOOLEAN
|
|
IsExistHotkeySetting (
|
|
UINTN *AddrPtr
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT32 Index;
|
|
CONFIG_HEADER *TempHeader;
|
|
UINT16 ConfigOrder;
|
|
VOID *TempConfigData;
|
|
UINTN MultiConfigRegionBase;
|
|
UINT64 Signature;
|
|
UINT16 ConfigCount;
|
|
BOOLEAN IsFindSetting;
|
|
CONFIG_HEADER *TempConfigHeader;
|
|
|
|
TempHeader = NULL;
|
|
ConfigOrder = 0;
|
|
TempConfigData = NULL;
|
|
ConfigCount = 0;
|
|
TempConfigHeader = NULL;
|
|
//
|
|
// Read from Flash Part
|
|
//
|
|
MultiConfigRegionBase = FLASH_REGION_MULTI_CONFIG_BASE;
|
|
Status = FlashRead (
|
|
(UINT8*)MultiConfigRegionBuffer,
|
|
(UINT8*)MultiConfigRegionBase,
|
|
(UINTN)FLASH_REGION_MULTI_CONFIG_SIZE
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Verify Signature
|
|
//
|
|
Signature = MULTI_CONFIG_SIGNATURE;
|
|
if (CompareMem (&Signature, MultiConfigRegionBuffer, sizeof (UINT64)) != 0) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Check CRC32 for Multi Config Header
|
|
//
|
|
Status = CheckMultiConfigHeaderCrc32 (MultiConfigRegionBuffer);
|
|
if (EFI_ERROR (Status)) {
|
|
return FALSE;
|
|
}
|
|
|
|
ConfigCount = GetConfigCount ();
|
|
IsFindSetting = FALSE;
|
|
for (Index = 0; Index < ConfigCount; Index++) {
|
|
TempConfigHeader = GetConfigHeaderByOrder ((UINT16)Index);
|
|
Status = GetConfigHeaderOrder (
|
|
MULTI_CONFIG_TYPE_HOTKEY_SETTING_VALUE,
|
|
TempConfigHeader->ConfigId,
|
|
MultiConfigRegionBuffer,
|
|
&TempHeader,
|
|
&ConfigOrder
|
|
);
|
|
//
|
|
// Check config data is active or not.
|
|
//
|
|
if ((Status == EFI_SUCCESS) &&
|
|
(TempHeader->Type == MULTI_CONFIG_TYPE_HOTKEY_SETTING_VALUE) &&
|
|
((TempHeader->Attribute & MULTI_CONFIG_ATTRIBUTE_VALID) == MULTI_CONFIG_ATTRIBUTE_VALID) &&
|
|
((TempHeader->Attribute & MULTI_CONFIG_ATTRIBUTE_DEFAULT) == MULTI_CONFIG_ATTRIBUTE_DEFAULT)
|
|
) {
|
|
IsFindSetting = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (!IsFindSetting) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Check CRC32 for Multi Config Data
|
|
// Direct get Config Data by Config Data Offset
|
|
//
|
|
TempConfigData = (UINT8*)MultiConfigRegionBuffer + TempHeader->ConfigDataOffset;
|
|
Status = CheckMultiConfigDataCrc32 (TempHeader->Crc32, TempHeader->ConfigDataSize, TempConfigData);
|
|
if (EFI_ERROR (Status)) {
|
|
//
|
|
// Get Config Data by Config Order
|
|
//
|
|
TempConfigData = GetConfigDataByOrder (ConfigOrder, MultiConfigRegionBuffer);
|
|
Status = CheckMultiConfigDataCrc32 (TempHeader->Crc32, TempHeader->ConfigDataSize, TempConfigData);
|
|
if (EFI_ERROR (Status)) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
*AddrPtr = (UINTN)TempConfigData;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN
|
|
IsExistMatchedHotkey (
|
|
IN DYNAMIC_HOTKEY Hotkey,
|
|
IN OUT UINTN *IndexOfList
|
|
)
|
|
{
|
|
UINTN Index;
|
|
|
|
for (Index = 0; Index < GET_ARRAY_COUNT (mHotKeyDefine); ++Index) {
|
|
//
|
|
// Check the Hot Key in Multi-Config data
|
|
// region is matched with the default Hot Key or not.
|
|
//
|
|
if ((Hotkey.ScanCode == mHotKeyList[Index].HotKeyList.ScanCode) &&
|
|
(Hotkey.AltKey == mHotKeyList[Index].HotKeyList.AltKey) &&
|
|
(Hotkey.ShiftKey == mHotKeyList[Index].HotKeyList.ShiftKey) &&
|
|
(Hotkey.CtrlKey == mHotKeyList[Index].HotKeyList.CtrlKey)) {
|
|
|
|
*IndexOfList = Index;
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOLEAN
|
|
IsExistMatchedSystemInfo (
|
|
IN DYNAMIC_STRING_EXTERNAL *SystemInfo,
|
|
IN UINTN StringCount,
|
|
IN OUT UINTN *IndexOfList
|
|
)
|
|
{
|
|
UINTN Index;
|
|
|
|
for (Index = 0; Index < StringCount ; ++Index) {
|
|
//
|
|
// Check the system information string in Multi-Config
|
|
// data region is matched with the system information string or not.
|
|
//
|
|
if (SystemInfo->SystemInfoId == mStringList[Index].SystemInfoId) {
|
|
*IndexOfList = Index;
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
VOID
|
|
ModifyStringList (
|
|
IN UINT8 KeyListId,
|
|
IN DYNAMIC_HOTKEY HotKey,
|
|
IN DYNAMIC_STRING_EXTERNAL *McStringPtr,
|
|
IN UINTN McStringCount,
|
|
IN OUT UINTN *TotalStringCount
|
|
)
|
|
{
|
|
UINTN McIndex;
|
|
UINTN StrCmpIndex;
|
|
CHAR16 *UniStr;
|
|
DYNAMIC_STRING_EXTERNAL *DynamicStringPtr;
|
|
|
|
UniStr = NULL;
|
|
DynamicStringPtr = McStringPtr;
|
|
//
|
|
//Search string list (Multi-config side)
|
|
//
|
|
for (McIndex = 0; McIndex < McStringCount; McIndex++, DynamicStringPtr = GET_NEXT_DYNAMIC_STRING_PTR (DynamicStringPtr)) {
|
|
//
|
|
//Find string about assign key (Multi-config side)
|
|
//
|
|
if (DynamicStringPtr->KeyId == HotKey.KeyId) {
|
|
//
|
|
//Find the existed string to replace
|
|
//
|
|
for (StrCmpIndex = 0; StrCmpIndex < GET_ARRAY_COUNT (StringDefine); StrCmpIndex++) {
|
|
//
|
|
//Find it & replace it
|
|
//
|
|
if ((DynamicStringPtr->Flag.TextMode == mStringList[StrCmpIndex].Flag.TextMode) &&
|
|
(DynamicStringPtr->Flag.GraphicMode == mStringList[StrCmpIndex].Flag.GraphicMode) &&
|
|
(DynamicStringPtr->Flag.BeforePress == mStringList[StrCmpIndex].Flag.BeforePress) &&
|
|
(DynamicStringPtr->Flag.AfterPress == mStringList[StrCmpIndex].Flag.AfterPress) &&
|
|
(mStringList[StrCmpIndex].KeyId == KeyListId)) {
|
|
|
|
mStringList[StrCmpIndex].LocationX = DynamicStringPtr->LocationX;
|
|
mStringList[StrCmpIndex].LocationY = DynamicStringPtr->LocationY;
|
|
CopyMem (&(mStringList[StrCmpIndex].Foreground), &(DynamicStringPtr->Foreground), sizeof (EFI_UGA_PIXEL));
|
|
CopyMem (&(mStringList[StrCmpIndex].Background), &(DynamicStringPtr->Background), sizeof (EFI_UGA_PIXEL));
|
|
|
|
UniStr = (CHAR16 *)AllocateZeroPool (AsciiStrSize (&(DynamicStringPtr->String)));
|
|
AsciiStrToUnicodeStrS (&(DynamicStringPtr->String), UniStr, AsciiStrSize (&(DynamicStringPtr->String)) / sizeof (CHAR16));
|
|
HiiSetString (mHotKeyStringPackHandle, mStringList[StrCmpIndex].StringToken, UniStr, NULL);
|
|
FREE (UniStr);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (StrCmpIndex < GET_ARRAY_COUNT (StringDefine)) {
|
|
continue;
|
|
}
|
|
mStringList[*TotalStringCount].KeyId = KeyListId;
|
|
mStringList[*TotalStringCount].SystemInfoId = DynamicStringPtr->SystemInfoId;
|
|
mStringList[*TotalStringCount].LocationX = DynamicStringPtr->LocationX;
|
|
mStringList[*TotalStringCount].LocationY = DynamicStringPtr->LocationY;
|
|
mStringList[*TotalStringCount].Flag = DynamicStringPtr->Flag;
|
|
CopyMem (&(mStringList[*TotalStringCount].Foreground), &(DynamicStringPtr->Foreground), sizeof (EFI_UGA_PIXEL));
|
|
CopyMem (&(mStringList[*TotalStringCount].Background), &(DynamicStringPtr->Background), sizeof (EFI_UGA_PIXEL));
|
|
|
|
UniStr = (CHAR16 *)AllocateZeroPool (AsciiStrSize (&(DynamicStringPtr->String)));
|
|
AsciiStrToUnicodeStrS (&(DynamicStringPtr->String), UniStr, AsciiStrSize (&(DynamicStringPtr->String)) / sizeof (CHAR16));
|
|
mStringList[*TotalStringCount].StringToken = HiiSetString (mHotKeyStringPackHandle, 0, UniStr, NULL);
|
|
FREE (UniStr);
|
|
(*TotalStringCount)++;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
VOID
|
|
UpdateList (
|
|
IN DYNAMIC_HOTKEY *McHotkeyPtr,
|
|
IN UINTN McHotkeyCount,
|
|
IN DYNAMIC_STRING_EXTERNAL *McStringPtr,
|
|
IN UINTN McStringCount
|
|
)
|
|
{
|
|
UINTN ActualHotkeyCount;
|
|
UINTN ActualStringCount;
|
|
UINTN Index;
|
|
UINTN Num;
|
|
CHAR16 *UniStr;
|
|
|
|
ActualHotkeyCount = 0;
|
|
ActualStringCount = 0;
|
|
UniStr = NULL;
|
|
|
|
if ((McHotkeyCount == 0) && (McStringCount == 0)) {
|
|
return ;
|
|
}
|
|
|
|
ActualHotkeyCount = GET_ARRAY_COUNT (mHotKeyDefine);
|
|
ActualStringCount = (GET_ARRAY_COUNT (StringDefine) + GET_ARRAY_COUNT (SystemInfoTable));
|
|
|
|
//
|
|
//Handle String with Hotkey
|
|
//
|
|
for (Index = 0; Index < McHotkeyCount; Index++) {
|
|
if (IsExistMatchedHotkey (McHotkeyPtr[Index], &Num)) {
|
|
mHotKeyList[Num].HotKeyList.Operation = McHotkeyPtr[Index].Operation;
|
|
ModifyStringList (mHotKeyList[Num].HotKeyList.KeyId, McHotkeyPtr[Index], McStringPtr, McStringCount, &ActualStringCount);
|
|
} else {
|
|
CopyMem ((UINT8 *)&mHotKeyList[ActualHotkeyCount].HotKeyList, (UINT8 *)&McHotkeyPtr[Index], sizeof (DYNAMIC_HOTKEY));
|
|
mHotKeyList[ActualHotkeyCount].HotKeyList.KeyId |= 0x80;
|
|
ModifyStringList (mHotKeyList[ActualHotkeyCount].HotKeyList.KeyId, McHotkeyPtr[Index], McStringPtr, McStringCount, &ActualStringCount);
|
|
ActualHotkeyCount++;
|
|
}
|
|
}
|
|
|
|
//
|
|
//Handle String with No Hotkey
|
|
//
|
|
for (Index = 0; Index < McStringCount; Index++, McStringPtr = GET_NEXT_DYNAMIC_STRING_PTR (McStringPtr)) {
|
|
if ((McStringPtr->KeyId == DSTRING_NO_HOTKEY) && (McStringPtr->SystemInfoId == DSTRING_NOT_SYSTEM_INFO)) {
|
|
mStringList[ActualStringCount].KeyId = McStringPtr->KeyId;
|
|
mStringList[ActualStringCount].SystemInfoId= McStringPtr->SystemInfoId;
|
|
mStringList[ActualStringCount].LocationX = McStringPtr->LocationX;
|
|
mStringList[ActualStringCount].LocationY = McStringPtr->LocationY;
|
|
mStringList[ActualStringCount].Flag = McStringPtr->Flag;
|
|
CopyMem (&(mStringList[ActualStringCount].Foreground), &(McStringPtr->Foreground), sizeof (EFI_UGA_PIXEL));
|
|
CopyMem (&(mStringList[ActualStringCount].Background), &(McStringPtr->Background), sizeof (EFI_UGA_PIXEL));
|
|
|
|
UniStr = (CHAR16 *)AllocateZeroPool (AsciiStrSize (&(McStringPtr->String)));
|
|
AsciiStrToUnicodeStrS (&(McStringPtr->String), UniStr, AsciiStrSize (&(McStringPtr->String)) / sizeof (CHAR16));
|
|
mStringList[ActualStringCount].StringToken = HiiSetString (mHotKeyStringPackHandle, 0, UniStr, NULL);
|
|
FREE (UniStr);
|
|
ActualStringCount++;
|
|
} else if ((McStringPtr->KeyId == DSTRING_NO_HOTKEY) && (McStringPtr->SystemInfoId != DSTRING_NOT_SYSTEM_INFO)) {
|
|
if (IsExistMatchedSystemInfo (McStringPtr, ActualStringCount, &Num)) {
|
|
mStringList[Num].KeyId = McStringPtr->KeyId;
|
|
mStringList[Num].SystemInfoId = McStringPtr->SystemInfoId;
|
|
mStringList[Num].LocationX = McStringPtr->LocationX;
|
|
mStringList[Num].LocationY = McStringPtr->LocationY;
|
|
mStringList[Num].Flag = McStringPtr->Flag;
|
|
UniStr = (CHAR16 *)AllocateZeroPool (AsciiStrSize (&(McStringPtr->String)));
|
|
AsciiStrToUnicodeStrS (&(McStringPtr->String), UniStr, AsciiStrSize (&(McStringPtr->String)) / sizeof (CHAR16));
|
|
mStringList[Num].StringToken = HiiSetString (mHotKeyStringPackHandle, 0, UniStr, NULL);
|
|
FREE (UniStr);
|
|
} else {
|
|
mStringList[ActualStringCount].KeyId = McStringPtr->KeyId;
|
|
mStringList[ActualStringCount].SystemInfoId= McStringPtr->SystemInfoId;
|
|
mStringList[ActualStringCount].LocationX = McStringPtr->LocationX;
|
|
mStringList[ActualStringCount].LocationY = McStringPtr->LocationY;
|
|
mStringList[ActualStringCount].Flag = McStringPtr->Flag;
|
|
CopyMem (&(mStringList[ActualStringCount].Foreground), &(McStringPtr->Foreground), sizeof (EFI_UGA_PIXEL));
|
|
CopyMem (&(mStringList[ActualStringCount].Background), &(McStringPtr->Background), sizeof (EFI_UGA_PIXEL));
|
|
|
|
UniStr = (CHAR16 *)AllocateZeroPool (AsciiStrSize (&(McStringPtr->String)));
|
|
AsciiStrToUnicodeStrS (&(McStringPtr->String), UniStr, AsciiStrSize (&(McStringPtr->String)) / sizeof (CHAR16));
|
|
mStringList[ActualStringCount].StringToken = HiiSetString (mHotKeyStringPackHandle, 0, UniStr, NULL);
|
|
FREE (UniStr);
|
|
ActualStringCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
mHotKeyListCount = ActualHotkeyCount;
|
|
mStringListCount = ActualStringCount;
|
|
}
|
|
|
|
EFI_STATUS
|
|
GetHotKeyAndString (
|
|
VOID
|
|
)
|
|
{
|
|
UINTN Index;
|
|
UINTN BaseIndex;
|
|
UINT8 *AddrPtr;
|
|
UINTN MCAddr;
|
|
UINTN McHotkeyCount;
|
|
UINTN McStringCount;
|
|
DYNAMIC_HOTKEY *McHotkeyPtr;
|
|
DYNAMIC_STRING_EXTERNAL *McStringPtr;
|
|
UINTN HotkeyCountOri;
|
|
UINTN StringCountOri;
|
|
EFI_STATUS Status;
|
|
|
|
AddrPtr = NULL;
|
|
McHotkeyCount = 0;
|
|
McStringCount = 0;
|
|
McHotkeyPtr = NULL;
|
|
McStringPtr = NULL;
|
|
HotkeyCountOri = 0;
|
|
StringCountOri = 0;
|
|
|
|
//
|
|
// 1. Get Multi-Config Address
|
|
// 2. allocate space for mHotKeyList and mStringList
|
|
//
|
|
MultiConfigRegionBuffer = AllocateZeroPool (FLASH_REGION_MULTI_CONFIG_SIZE);
|
|
if (IsExistHotkeySetting (&MCAddr)) {
|
|
AddrPtr = (UINT8*)MCAddr;
|
|
McHotkeyCount = (UINTN)(*AddrPtr);
|
|
mHotKeyListCount += McHotkeyCount;
|
|
++AddrPtr;
|
|
McStringCount = (UINTN)(*AddrPtr);
|
|
mStringListCount += McStringCount;
|
|
++AddrPtr;
|
|
if (McHotkeyCount != 0) {
|
|
McHotkeyPtr = (DYNAMIC_HOTKEY *)AddrPtr;
|
|
} else {
|
|
McHotkeyPtr = NULL;
|
|
}
|
|
McStringPtr = (DYNAMIC_STRING_EXTERNAL *)((UINTN)AddrPtr + (sizeof (DYNAMIC_HOTKEY) * McHotkeyCount));
|
|
} else {
|
|
FREE (MultiConfigRegionBuffer);
|
|
}
|
|
|
|
//
|
|
// Add Const HotKey
|
|
//
|
|
mHotKeyListCount += GET_ARRAY_COUNT (mHotKeyDefine);
|
|
if (mHotKeyListCount != 0) {
|
|
mHotKeyList = (DYNAMIC_HOTKEY_INTERNAL *)AllocateZeroPool (sizeof (DYNAMIC_HOTKEY_INTERNAL) * mHotKeyListCount);
|
|
if (mHotKeyList == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto GetHotKeyAndStringEXIT;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add Const String
|
|
//
|
|
mStringListCount += (GET_ARRAY_COUNT (StringDefine) + GET_ARRAY_COUNT (SystemInfoTable));
|
|
if (mStringListCount != 0) {
|
|
mStringList = (DYNAMIC_STRING *)AllocateZeroPool (sizeof (DYNAMIC_STRING) * mStringListCount);
|
|
if (mStringList == NULL) {
|
|
FreePool (mHotKeyList);
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto GetHotKeyAndStringEXIT;
|
|
}
|
|
}
|
|
|
|
//
|
|
// 3. copy Bios HotKey to mHotKeyList and mStringList
|
|
//
|
|
|
|
for (Index = 0; Index < GET_ARRAY_COUNT (mHotKeyDefine); ++Index) {
|
|
CopyMem (&mHotKeyList[Index].HotKeyList, &mHotKeyDefine[Index], sizeof (DYNAMIC_HOTKEY));
|
|
}
|
|
|
|
for (Index = 0; Index < GET_ARRAY_COUNT (StringDefine); ++Index) {
|
|
mStringList[Index].KeyId = StringDefine[Index].KeyId;
|
|
mStringList[Index].SystemInfoId = StringDefine[Index].SystemInfoId;
|
|
mStringList[Index].LocationX = StringDefine[Index].LocationX;
|
|
mStringList[Index].LocationY = StringDefine[Index].LocationY;
|
|
mStringList[Index].Flag = StringDefine[Index].Flag;
|
|
mStringList[Index].StringToken = StringDefine[Index].StringToken;
|
|
CopyMem (&(mStringList[Index].Foreground), &(StringDefine[Index].Foreground), sizeof (EFI_UGA_PIXEL));
|
|
CopyMem (&(mStringList[Index].Background), &(StringDefine[Index].Background), sizeof (EFI_UGA_PIXEL));
|
|
}
|
|
|
|
BaseIndex = Index;
|
|
//
|
|
//Copy system info to string list.
|
|
//
|
|
for (Index = 0; Index < GET_ARRAY_COUNT (SystemInfoTable); ++Index) {
|
|
//
|
|
//Because memory is ZeroPool, so Flag is all zero.(we can don't care it)
|
|
//
|
|
mStringList[BaseIndex + Index].KeyId = DSTRING_NO_HOTKEY;
|
|
mStringList[BaseIndex + Index].SystemInfoId = (UINT8)SystemInfoTable[Index].Type;
|
|
mStringList[BaseIndex + Index].LocationX = SystemInfoTable[Index].LocationX;
|
|
mStringList[BaseIndex + Index].LocationY = SystemInfoTable[Index].LocationY;
|
|
mStringList[BaseIndex + Index].StringToken = SystemInfoTable[Index].StringToken;
|
|
}
|
|
|
|
HotkeyCountOri = mHotKeyListCount;
|
|
StringCountOri = mStringListCount;
|
|
//
|
|
// 4. Update Dynamic HotKey to list, and recalculate List count.
|
|
//
|
|
UpdateList (
|
|
McHotkeyPtr,
|
|
McHotkeyCount,
|
|
McStringPtr,
|
|
McStringCount
|
|
);
|
|
|
|
if (HotkeyCountOri != mHotKeyListCount) {
|
|
mHotKeyList = (DYNAMIC_HOTKEY_INTERNAL *) ReallocatePool (
|
|
HotkeyCountOri * sizeof (DYNAMIC_HOTKEY_INTERNAL),
|
|
mHotKeyListCount * sizeof (DYNAMIC_HOTKEY_INTERNAL),
|
|
mHotKeyList
|
|
);
|
|
if (mHotKeyList == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto GetHotKeyAndStringEXIT;
|
|
}
|
|
}
|
|
|
|
if (StringCountOri != mStringListCount) {
|
|
mStringList = (DYNAMIC_STRING *) ReallocatePool (
|
|
StringCountOri * sizeof (DYNAMIC_STRING),
|
|
mStringListCount * sizeof (DYNAMIC_STRING),
|
|
mStringList
|
|
);
|
|
if (mStringList == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto GetHotKeyAndStringEXIT;
|
|
}
|
|
}
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
GetHotKeyAndStringEXIT:
|
|
|
|
FREE (MultiConfigRegionBuffer);
|
|
return Status;
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
GetDynamicHotKeyList (
|
|
IN DYNAMIC_HOTKEY_PROTOCOL *This,
|
|
IN OUT KEY_ELEMENT **HotKeyList
|
|
)
|
|
{
|
|
|
|
KEY_ELEMENT *OrigHotKeyList;
|
|
UINTN OrigHotKeyListCount;
|
|
UINTN Index;
|
|
UINTN BitIndex;
|
|
BOOLEAN Found;
|
|
|
|
//
|
|
// If there is no dynamic hot key list, do not change anything
|
|
//
|
|
if (mHotKeyListCount == 0) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// If we already updated hot key list, just return it
|
|
//
|
|
if (UpdatedHotKeyList != NULL) {
|
|
*HotKeyList = UpdatedHotKeyList;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// Calculate original hot key list count
|
|
//
|
|
OrigHotKeyList = *HotKeyList;
|
|
OrigHotKeyListCount = 0;
|
|
for (Index = 0; OrigHotKeyList[Index].ScanCode != 0x00; ++Index) {
|
|
++OrigHotKeyListCount;
|
|
}
|
|
++OrigHotKeyListCount;
|
|
|
|
//
|
|
// Calculate max size and copy from original list
|
|
//
|
|
UpdatedHotKeyList = (KEY_ELEMENT *)AllocateZeroPool ((OrigHotKeyListCount + mHotKeyListCount) * sizeof (KEY_ELEMENT));
|
|
if (UpdatedHotKeyList == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
CopyMem (UpdatedHotKeyList, OrigHotKeyList, OrigHotKeyListCount * sizeof (KEY_ELEMENT));
|
|
|
|
//
|
|
// Add dynamic hot key list to newly created one
|
|
//
|
|
for (Index = 0; Index < mHotKeyListCount; ++Index) {
|
|
|
|
Found = FALSE;
|
|
for (BitIndex = 0; UpdatedHotKeyList[BitIndex].ScanCode != 0x00; ++BitIndex) {
|
|
//
|
|
// Compare each dynamic hot key to check if this hot key already existed or not
|
|
// If it exist, we will not add another one but we will use dynamic hot key setting
|
|
// to override original one
|
|
//
|
|
if (UpdatedHotKeyList[BitIndex].ScanCode == mHotKeyList[Index].HotKeyList.ScanCode &&
|
|
UpdatedHotKeyList[BitIndex].Keyattribute.AltKey == mHotKeyList[Index].HotKeyList.AltKey &&
|
|
UpdatedHotKeyList[BitIndex].Keyattribute.ShiftKey == mHotKeyList[Index].HotKeyList.ShiftKey &&
|
|
UpdatedHotKeyList[BitIndex].Keyattribute.CtrlKey == mHotKeyList[Index].HotKeyList.CtrlKey) {
|
|
mHotKeyList[Index].BitIndex = (UINT8)BitIndex;
|
|
Found = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (Found) {
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Add dynamic hot key list
|
|
//
|
|
UpdatedHotKeyList[BitIndex].ScanCode = mHotKeyList[Index].HotKeyList.ScanCode;
|
|
UpdatedHotKeyList[BitIndex].Keyattribute.AltKey = mHotKeyList[Index].HotKeyList.AltKey;
|
|
UpdatedHotKeyList[BitIndex].Keyattribute.ShiftKey = mHotKeyList[Index].HotKeyList.ShiftKey;
|
|
UpdatedHotKeyList[BitIndex].Keyattribute.CtrlKey = mHotKeyList[Index].HotKeyList.CtrlKey;
|
|
mHotKeyList[Index].BitIndex = (UINT8)BitIndex;
|
|
}
|
|
|
|
*HotKeyList = UpdatedHotKeyList;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
GetDynamicHotKeyOperation (
|
|
IN DYNAMIC_HOTKEY_PROTOCOL *This,
|
|
IN UINT32 KeyDetected,
|
|
OUT UINTN *Operation
|
|
)
|
|
{
|
|
UINTN Index;
|
|
|
|
for (Index = 0; Index < mHotKeyListCount; ++Index) {
|
|
//
|
|
// Check bit to know which dynamic hot key is pressed
|
|
//
|
|
if (KeyDetected & (1 << mHotKeyList[Index].BitIndex)) {
|
|
mHotKeyPressed = TRUE;
|
|
mPressedKdyId = mHotKeyList[Index].HotKeyList.KeyId;
|
|
*Operation = (UINTN)mHotKeyList[Index].HotKeyList.Operation;
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
|
|
}
|
|
|
|
UINTN
|
|
GetDynamicStringCountInternal (
|
|
IN BOOLEAN KeyPressed,
|
|
OUT UINTN *SelectedIndex OPTIONAL
|
|
)
|
|
{
|
|
UINTN Index;
|
|
UINTN Count;
|
|
UINT16 Mask;
|
|
EFI_STATUS Status;
|
|
DYNAMIC_STRING_FLAG TempFlag;
|
|
UINT16 Temp;
|
|
CHIPSET_CONFIGURATION *SetupVariable = NULL;
|
|
|
|
Count = 0;
|
|
//
|
|
// Get setup config to know QuietBoot
|
|
//
|
|
SetupVariable = AllocateZeroPool (sizeof (CHIPSET_CONFIGURATION));
|
|
if (SetupVariable == NULL) {
|
|
return Count;
|
|
}
|
|
Status = GetChipsetSetupVariableDxe (SetupVariable, sizeof (CHIPSET_CONFIGURATION));
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (SetupVariable);
|
|
ASSERT_EFI_ERROR (Status);
|
|
return Count;
|
|
}
|
|
|
|
//
|
|
// Use a Mask to know which string is we want
|
|
//
|
|
ZeroMem (&TempFlag, sizeof (DYNAMIC_STRING_FLAG));
|
|
if (SetupVariable->QuietBoot) {
|
|
TempFlag.GraphicMode = 1;
|
|
} else {
|
|
TempFlag.TextMode = 1;
|
|
}
|
|
Mask = *(UINT16 *)&TempFlag;
|
|
|
|
|
|
BottomStringCount (INITIAL_VALUE, 0, NULL);
|
|
|
|
//
|
|
// Find matched string and count it
|
|
//
|
|
for (Index = 0; Index < mStringListCount; ++Index) {
|
|
Temp = *(UINT16 *)&mStringList[Index].Flag;
|
|
//
|
|
// Basic check mode
|
|
//
|
|
if (((Mask & Temp) == Mask) || (mStringList[Index].SystemInfoId != DSTRING_NOT_SYSTEM_INFO)) {
|
|
//
|
|
// If a string does not bond any hot key, always show it
|
|
//
|
|
if (mStringList[Index].KeyId == DSTRING_NO_HOTKEY) {
|
|
if (SelectedIndex != NULL) {
|
|
SelectedIndex[Count] = Index;
|
|
}
|
|
++Count;
|
|
if (mStringList[Index].LocationY == (UINT16)(-2)) {
|
|
BottomStringCount (SET_COUNT, mStringList[Index].LocationX, NULL);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// If a string bond a specified hot key, do advance check
|
|
//
|
|
if (KeyPressed == TRUE) {
|
|
if ((mStringList[Index].KeyId == mPressedKdyId) && mStringList[Index].Flag.AfterPress) {
|
|
//
|
|
// If key match, show string with AfterPress flag
|
|
//
|
|
if (SelectedIndex != NULL) {
|
|
SelectedIndex[Count] = Index;
|
|
}
|
|
++Count;
|
|
if (mStringList[Index].LocationY == (UINT16)(-2)) {
|
|
BottomStringCount (SET_COUNT, mStringList[Index].LocationX, NULL);
|
|
}
|
|
} else if ((mStringList[Index].KeyId != mPressedKdyId) && mStringList[Index].Flag.BeforePress) {
|
|
//
|
|
// If key does not match, show original string (with BeforePress)
|
|
//
|
|
if (SelectedIndex != NULL) {
|
|
SelectedIndex[Count] = Index;
|
|
}
|
|
++Count;
|
|
if (mStringList[Index].LocationY == (UINT16)(-2)) {
|
|
BottomStringCount (SET_COUNT, mStringList[Index].LocationX, NULL);
|
|
}
|
|
}
|
|
} else {
|
|
if (mStringList[Index].Flag.BeforePress) {
|
|
//
|
|
// Since there is no hot key pressed, show string with BeforePress
|
|
//
|
|
if (SelectedIndex != NULL) {
|
|
SelectedIndex[Count] = Index;
|
|
}
|
|
++Count;
|
|
if (mStringList[Index].LocationY == (UINT16)(-2)) {
|
|
BottomStringCount (SET_COUNT, mStringList[Index].LocationX, NULL);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SetupVariable != NULL) {
|
|
FreePool (SetupVariable);
|
|
}
|
|
return Count;
|
|
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
GetDynamicStringCount (
|
|
IN DYNAMIC_HOTKEY_PROTOCOL *This,
|
|
IN BOOLEAN KeyPressed,
|
|
OUT UINTN *StringCount
|
|
)
|
|
{
|
|
|
|
UINTN Count;
|
|
|
|
|
|
Count = GetDynamicStringCountInternal (KeyPressed, NULL);
|
|
if (Count == 0) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
*StringCount = (UINTN)Count;
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
GetDynamicString (
|
|
IN DYNAMIC_HOTKEY_PROTOCOL *This,
|
|
IN UINTN Index,
|
|
IN BOOLEAN KeyPressed,
|
|
OUT CHAR16 **String,
|
|
OUT UINTN *CoordinateX,
|
|
OUT UINTN *CoordinateY
|
|
)
|
|
{
|
|
UINTN Count;
|
|
UINTN StringIndex;
|
|
UINTN SelectedIndex[0xFF];
|
|
|
|
|
|
//
|
|
// Get count first
|
|
//
|
|
Count = GetDynamicStringCountInternal (KeyPressed, SelectedIndex);
|
|
if (Count == 0) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
//
|
|
// Check selected range
|
|
//
|
|
if (Index >= Count) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Find specified string by Index and matched with flag
|
|
//
|
|
StringIndex = SelectedIndex[Index];
|
|
|
|
//
|
|
//System Information DO NOT display at this moment.
|
|
//It will show in BootSystemInformation.c
|
|
//
|
|
if(mStringList[StringIndex].SystemInfoId != DSTRING_NOT_SYSTEM_INFO) {
|
|
return EFI_ABORTED;
|
|
}
|
|
|
|
*String = GetStringByStringToken (mStringList[StringIndex].StringToken);
|
|
if (*String == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
if (mStringList[StringIndex].LocationX == ((UINT16)-1)) {
|
|
*CoordinateX = STRING_LOCATION_CENTER;
|
|
} else if (mStringList[StringIndex].LocationX == ((UINT16)-2)) {
|
|
*CoordinateX = STRING_LOCATION_MAX;
|
|
} else {
|
|
*CoordinateX = (UINTN)mStringList[StringIndex].LocationX;
|
|
}
|
|
|
|
if (mStringList[StringIndex].LocationY == ((UINT16)-1)) {
|
|
*CoordinateY = STRING_LOCATION_CENTER;
|
|
} else if (mStringList[StringIndex].LocationY == ((UINT16)-2)) {
|
|
*CoordinateY = STRING_LOCATION_MAX;
|
|
} else {
|
|
*CoordinateY = (UINTN)mStringList[StringIndex].LocationY;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
GetDynamicStringColor (
|
|
IN UINTN Index,
|
|
IN BOOLEAN KeyPressed,
|
|
OUT EFI_UGA_PIXEL *Foreground,
|
|
OUT EFI_UGA_PIXEL *Background
|
|
)
|
|
{
|
|
UINTN StringIndex;
|
|
UINTN SelectedIndex[0xFF];
|
|
|
|
//
|
|
// Get SelectedIndex
|
|
//
|
|
GetDynamicStringCountInternal (KeyPressed, SelectedIndex);
|
|
|
|
//
|
|
// Find specified string by Index and matched with flag
|
|
//
|
|
StringIndex = SelectedIndex[Index];
|
|
|
|
CopyMem (Foreground, &(mStringList[StringIndex].Foreground), sizeof (EFI_UGA_PIXEL));
|
|
CopyMem (Background, &(mStringList[StringIndex].Background), sizeof (EFI_UGA_PIXEL));
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
BOOLEAN
|
|
EFIAPI
|
|
IsDynamicHotKeyPressed (
|
|
IN DYNAMIC_HOTKEY_PROTOCOL *This
|
|
)
|
|
{
|
|
return mHotKeyPressed;
|
|
}
|
|
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ShowSystemInformation (
|
|
IN OUT UINT8 *PrintLine
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN Index;
|
|
CHAR16 *String;
|
|
UINTN MaxX;
|
|
UINTN MaxY;
|
|
UINTN LocX;
|
|
UINTN LocY;
|
|
CHAR16 *StrPtr;
|
|
STRING_TRANSFORM_PROTOCOL *mStringTransform;
|
|
BOOLEAN IsTransformed;
|
|
|
|
String = NULL;
|
|
StrPtr = NULL;
|
|
IsTransformed = FALSE;
|
|
|
|
Status = gBS->LocateProtocol (&gStringTransformProtocolGuid, NULL, (VOID **)&mStringTransform);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = gST->ConOut->QueryMode (
|
|
gST->ConOut,
|
|
gST->ConOut->Mode->Mode,
|
|
&MaxX,
|
|
&MaxY
|
|
);
|
|
|
|
for (Index = 0; Index < mStringListCount; Index++) {
|
|
if ((mStringList[Index].KeyId == DSTRING_NO_HOTKEY) && (mStringList[Index].SystemInfoId != DSTRING_NOT_SYSTEM_INFO)) {
|
|
String = GetStringByStringToken (mStringList[Index].StringToken);
|
|
if (String == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
IsTransformed = FALSE;
|
|
|
|
Status = mStringTransform->Transform (mStringTransform, String, &StrPtr);
|
|
//
|
|
//Because mStringTransform->Transform replace one keyword variable at one time.
|
|
//So we try to transform another system info keyword.
|
|
//
|
|
while (Status == EFI_SUCCESS) {
|
|
IsTransformed = TRUE;
|
|
String = StrPtr;
|
|
Status = mStringTransform->Transform (mStringTransform, String, &StrPtr);
|
|
if (Status == EFI_SUCCESS) {
|
|
FreePool (String);
|
|
String = NULL;
|
|
}
|
|
}
|
|
|
|
if (mStringList[Index].LocationX == (UINT16)-2) {
|
|
LocX = (UINTN)-2;
|
|
} else if (mStringList[Index].LocationX == (UINT16)-1){
|
|
LocX = (UINTN)-1;
|
|
} else {
|
|
LocX = mStringList[Index].LocationX;
|
|
}
|
|
|
|
if (mStringList[Index].LocationY == (UINT16)-2) {
|
|
LocY = (UINTN)-2;
|
|
} else if (mStringList[Index].LocationY == (UINT16)-1){
|
|
LocY = (UINTN)-1;
|
|
} else {
|
|
LocY = mStringList[Index].LocationY;
|
|
}
|
|
mDynamicHotKey.AdjustStringPosition (&mDynamicHotKey, FALSE, FALSE, (MaxY / 2), StrPtr, &LocX, &LocY);
|
|
|
|
gST->ConOut->SetCursorPosition (gST->ConOut, LocX, LocY);
|
|
//
|
|
// For debug
|
|
//
|
|
gST->ConOut->EnableCursor (gST->ConOut, TRUE);
|
|
|
|
gST->ConOut->OutputString (gST->ConOut, StrPtr);
|
|
(*PrintLine)++;
|
|
//
|
|
//mStringTransform->Transform will allocate memory for new string,
|
|
//So we need to free it.
|
|
//
|
|
if (IsTransformed) {
|
|
FreePool (StrPtr);
|
|
StrPtr = NULL;
|
|
}
|
|
Status = EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
AdjustStringPosition (
|
|
IN DYNAMIC_HOTKEY_PROTOCOL *This,
|
|
IN BOOLEAN IsClearCountMode,
|
|
IN BOOLEAN IsGraphicMode,
|
|
IN UINTN StrDestCenterY,
|
|
IN CHAR16 *TmpStr,
|
|
IN OUT UINTN *CoordinateX,
|
|
IN OUT UINTN *CoordinateY
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
static EFI_UGA_DRAW_PROTOCOL *UgaDraw;
|
|
static EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
|
|
static UINTN SizeOfX;
|
|
static UINTN SizeOfY;
|
|
UINT32 ColorDepth;
|
|
UINT32 RefreshRate;
|
|
static UINTN LeftTopCount;
|
|
static UINTN CenterTopCount;
|
|
static UINTN RightTopCount;
|
|
static UINTN LeftCenterCount;
|
|
static UINTN CenterCount;
|
|
static UINTN RightCenterCount;
|
|
static UINTN LeftBottomCount;
|
|
static UINTN CenterBottomCount;
|
|
static UINTN RightBottomCount;
|
|
UINTN Count;
|
|
|
|
Status = EFI_SUCCESS;
|
|
Count = 0;
|
|
|
|
if (IsClearCountMode) {
|
|
LeftTopCount = 0;
|
|
CenterTopCount = 0;
|
|
RightTopCount = 0;
|
|
LeftCenterCount = 0;
|
|
CenterCount = 0;
|
|
RightCenterCount = 0;
|
|
LeftBottomCount = 0;
|
|
CenterBottomCount = 0;
|
|
RightBottomCount = 0;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if ((CoordinateX == NULL) || (CoordinateY == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (((INTN)*CoordinateX > 0) && ((INTN)*CoordinateY > 0)) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
if ((SizeOfX == 0) && (SizeOfY == 0)) {
|
|
//
|
|
// Get Screen size of x and y
|
|
//
|
|
|
|
if (IsGraphicMode) {
|
|
|
|
if ((GraphicsOutput == NULL) && (UgaDraw == NULL)) {
|
|
Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **)&GraphicsOutput);
|
|
if (EFI_ERROR (Status)) {
|
|
GraphicsOutput = NULL;
|
|
Status = gBS->HandleProtocol (
|
|
gST->ConsoleOutHandle,
|
|
&gEfiUgaDrawProtocolGuid,
|
|
(VOID **)&UgaDraw
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (GraphicsOutput == NULL && UgaDraw == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
if (GraphicsOutput != NULL) {
|
|
SizeOfX = (UINTN)GraphicsOutput->Mode->Info->HorizontalResolution;
|
|
SizeOfY = (UINTN)GraphicsOutput->Mode->Info->VerticalResolution;
|
|
} else {
|
|
Status = UgaDraw->GetMode (
|
|
UgaDraw,
|
|
&((UINT32)SizeOfX),
|
|
&((UINT32)SizeOfY),
|
|
&ColorDepth,
|
|
&RefreshRate
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
Status = gST->ConOut->QueryMode (
|
|
gST->ConOut,
|
|
gST->ConOut->Mode->Mode,
|
|
&SizeOfX,
|
|
&SizeOfY
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set Location
|
|
//
|
|
if ((*CoordinateX == STRING_LOCATION_MIN) && (*CoordinateY == STRING_LOCATION_MIN)) {
|
|
//
|
|
// Left and Top
|
|
//
|
|
*CoordinateX = 0;
|
|
*CoordinateY = IsGraphicMode ? (0 + LeftTopCount * EFI_GLYPH_HEIGHT) : (0 + LeftTopCount);
|
|
LeftTopCount++;
|
|
|
|
} else if ((*CoordinateX == STRING_LOCATION_CENTER) && (*CoordinateY == STRING_LOCATION_MIN)) {
|
|
//
|
|
// Center and Top
|
|
//
|
|
*CoordinateX = IsGraphicMode ? ((SizeOfX - StrLen (TmpStr) * EFI_GLYPH_WIDTH) / 2) : ((SizeOfX - StrLen (TmpStr)) / 2);
|
|
*CoordinateY = IsGraphicMode ? (0 + CenterTopCount * EFI_GLYPH_HEIGHT) : (0 + CenterTopCount);
|
|
CenterTopCount++;
|
|
|
|
} else if ((*CoordinateX == STRING_LOCATION_MAX) && (*CoordinateY == STRING_LOCATION_MIN)) {
|
|
//
|
|
// Right and Top
|
|
//
|
|
*CoordinateX = IsGraphicMode ? ((SizeOfX - (StrLen (TmpStr) + 1) * EFI_GLYPH_WIDTH)) : ((SizeOfX - (StrLen (TmpStr) + 1)));
|
|
*CoordinateY = IsGraphicMode ? (0 + RightTopCount * EFI_GLYPH_HEIGHT) : (0 + RightTopCount);
|
|
RightTopCount++;
|
|
|
|
} else if ((*CoordinateX == STRING_LOCATION_MIN) && (*CoordinateY == STRING_LOCATION_CENTER)) {
|
|
//
|
|
// Left and Center
|
|
//
|
|
*CoordinateX = 0;
|
|
*CoordinateY = IsGraphicMode ? (StrDestCenterY + LeftCenterCount * EFI_GLYPH_HEIGHT) : (StrDestCenterY + LeftCenterCount);
|
|
LeftCenterCount++;
|
|
|
|
} else if ((*CoordinateX == STRING_LOCATION_CENTER) && (*CoordinateY == STRING_LOCATION_CENTER)) {
|
|
//
|
|
// Center
|
|
//
|
|
*CoordinateX = IsGraphicMode ? ((SizeOfX - StrLen (TmpStr) * EFI_GLYPH_WIDTH) / 2) : ((SizeOfX - StrLen (TmpStr)) / 2);
|
|
*CoordinateY = IsGraphicMode ? (StrDestCenterY + CenterCount * EFI_GLYPH_HEIGHT) : (StrDestCenterY + CenterCount);
|
|
CenterCount++;
|
|
|
|
} else if ((*CoordinateX == STRING_LOCATION_MAX) && (*CoordinateY == STRING_LOCATION_CENTER)) {
|
|
//
|
|
// Right and Center
|
|
//
|
|
*CoordinateX = IsGraphicMode ? ((SizeOfX - (StrLen (TmpStr) + 1) * EFI_GLYPH_WIDTH)) : ((SizeOfX - (StrLen (TmpStr) + 1)));
|
|
*CoordinateY = IsGraphicMode ? (StrDestCenterY + RightCenterCount * EFI_GLYPH_HEIGHT) : (StrDestCenterY + RightCenterCount);
|
|
RightCenterCount++;
|
|
|
|
} else if ((*CoordinateX == STRING_LOCATION_MIN) && (*CoordinateY == STRING_LOCATION_MAX)) {
|
|
//
|
|
// Left and Bottom
|
|
//
|
|
BottomStringCount (GET_LEFT_COUNT, 0, &Count);
|
|
*CoordinateX = 0;
|
|
*CoordinateY = IsGraphicMode ? (SizeOfY - (Count - LeftBottomCount) * EFI_GLYPH_HEIGHT) : (SizeOfY - (Count - LeftBottomCount));
|
|
LeftBottomCount++;
|
|
|
|
|
|
} else if ((*CoordinateX == STRING_LOCATION_CENTER) && (*CoordinateY == STRING_LOCATION_MAX)) {
|
|
//
|
|
// Center and Bottom
|
|
//
|
|
BottomStringCount (GET_CENTER_COUNT, 0, &Count);
|
|
*CoordinateX = IsGraphicMode ? ((SizeOfX - StrLen (TmpStr) * EFI_GLYPH_WIDTH) / 2) : ((SizeOfX - StrLen (TmpStr)) / 2);
|
|
*CoordinateY = IsGraphicMode ? (SizeOfY - (Count - CenterBottomCount) * EFI_GLYPH_HEIGHT) : (SizeOfY - (Count - CenterBottomCount));
|
|
CenterBottomCount++;
|
|
|
|
} else if ((*CoordinateX == STRING_LOCATION_MAX) && (*CoordinateY == STRING_LOCATION_MAX)) {
|
|
//
|
|
// Right and Bottom
|
|
//
|
|
BottomStringCount (GET_RIGHT_COUNT, 0, &Count);
|
|
*CoordinateX = IsGraphicMode ? ((SizeOfX - (StrLen (TmpStr) + 1) * EFI_GLYPH_WIDTH)) : ((SizeOfX - (StrLen (TmpStr) + 1)));
|
|
*CoordinateY = IsGraphicMode ? (SizeOfY - (Count - RightBottomCount) * EFI_GLYPH_HEIGHT) : (SizeOfY - (Count - RightBottomCount));
|
|
RightBottomCount++;
|
|
|
|
} else {
|
|
switch (*CoordinateX) {
|
|
|
|
case STRING_LOCATION_MIN:
|
|
*CoordinateX = 0;
|
|
break;
|
|
|
|
case STRING_LOCATION_CENTER:
|
|
*CoordinateX = IsGraphicMode ? ((SizeOfX - StrLen (TmpStr) * EFI_GLYPH_WIDTH) / 2) : ((SizeOfX - StrLen (TmpStr)) / 2);
|
|
break;
|
|
|
|
case STRING_LOCATION_MAX:
|
|
*CoordinateX = IsGraphicMode ? ((SizeOfX - (StrLen (TmpStr) + 1) * EFI_GLYPH_WIDTH)) : ((SizeOfX - (StrLen (TmpStr) + 1)));
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch (*CoordinateY) {
|
|
|
|
case STRING_LOCATION_MIN:
|
|
*CoordinateY = 0;
|
|
break;
|
|
|
|
case STRING_LOCATION_CENTER:
|
|
*CoordinateY = StrDestCenterY;
|
|
break;
|
|
|
|
case STRING_LOCATION_MAX:
|
|
*CoordinateY = (SizeOfY - 1);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
/**
|
|
Get all list size.
|
|
|
|
@param[in] *TotalSize the size to filll
|
|
@param[in] *HotkeyCount the number of hot key
|
|
@param[in] *StringCount the number of string
|
|
@param[in] *SystemInfoCount the number of system information
|
|
@param[in] *OperationCount the number of hot key operation
|
|
|
|
@retval EFI_SUCCESS Get all list size success.
|
|
@retval EFI_INVALID_PARAMETER The parameter is NULL.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
GetRequiredSize (
|
|
OUT UINTN *TotalSize,
|
|
OUT UINTN *HotkeyCount,
|
|
OUT UINTN *StringCount,
|
|
OUT UINTN *SystemInfoCount,
|
|
OUT UINTN *OperationCount
|
|
)
|
|
{
|
|
UINTN StrIndex;
|
|
CHAR16 *StrPtr;
|
|
|
|
StrPtr = NULL;
|
|
|
|
if ((NULL == TotalSize) || (NULL == HotkeyCount) || (NULL == StringCount) || (NULL == SystemInfoCount) || (NULL == OperationCount)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
*TotalSize = sizeof (HOTKEY_AND_STRING_TABLE);
|
|
|
|
//
|
|
// Calcuate hot key table size
|
|
//
|
|
*HotkeyCount = GET_ARRAY_COUNT (mHotKeyDefine);
|
|
*TotalSize += *HotkeyCount * sizeof (DYNAMIC_HOTKEY);
|
|
|
|
//
|
|
// Calcuate string table size
|
|
//
|
|
*StringCount = GET_ARRAY_COUNT (StringDefine);
|
|
*TotalSize += *StringCount * (sizeof (DYNAMIC_STRING_EXTERNAL) - sizeof (CHAR8));
|
|
for (StrIndex = 0; StrIndex < *StringCount; StrIndex++) {
|
|
StrPtr = GetStringByStringToken (StringDefine[StrIndex].StringToken);
|
|
*TotalSize += (StrLen (StrPtr) + 1);
|
|
}
|
|
|
|
//
|
|
// Calcuate system information table size
|
|
//
|
|
*SystemInfoCount = GET_ARRAY_COUNT (SystemInfoTable);
|
|
*TotalSize += *SystemInfoCount * (sizeof (DYNAMIC_SYSTEM_INFO_EXTERNAL) - sizeof (CHAR8));
|
|
for (StrIndex = 0; StrIndex < *SystemInfoCount; StrIndex++) {
|
|
StrPtr = GetStringByStringToken (SystemInfoTable[StrIndex].StringToken);
|
|
*TotalSize += (StrLen (StrPtr) + 1);
|
|
}
|
|
|
|
//
|
|
// Calcuate hot key operation table size
|
|
//
|
|
*OperationCount = GET_ARRAY_COUNT (OperationTable);
|
|
*TotalSize += *OperationCount * (sizeof (DYNAMIC_OPERATION_EXTERNAL) - sizeof (CHAR8));
|
|
for (StrIndex = 0; StrIndex < *OperationCount; StrIndex++) {
|
|
StrPtr = GetStringByStringToken (OperationTable[StrIndex].StringToken);
|
|
*TotalSize += (StrLen (StrPtr) + 1);
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Allocate memory to store Hotkey and String Table
|
|
|
|
@param[in] NeedSize the size of all data.
|
|
@param[in] *AllocateSize the actual size by allocating.
|
|
|
|
@retval EFI_SUCCESS Allocate success
|
|
@retval other Allocate fail
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
AllocateReservedMemory (
|
|
IN UINTN NeedSize,
|
|
OUT UINTN *AllocateSize
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
VOID *TempAddress;
|
|
EFI_PHYSICAL_ADDRESS PhyAddress;
|
|
|
|
Status = EFI_SUCCESS;
|
|
TempAddress = NULL;
|
|
PhyAddress = 0;
|
|
|
|
if (NULL == AllocateSize) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = gBS->AllocatePool (
|
|
EfiReservedMemoryType,
|
|
NeedSize,
|
|
(VOID **)&TempAddress
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Check whether the address is smaller than the 4G
|
|
//
|
|
if ( (UINTN) TempAddress > HOTKEY_AND_STRING_TABLE_MAX_ADDRESS) {
|
|
Status = gBS->FreePool (TempAddress);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
PhyAddress = HOTKEY_AND_STRING_TABLE_MAX_ADDRESS;
|
|
Status = gBS->AllocatePages (
|
|
AllocateMaxAddress,
|
|
EfiReservedMemoryType,
|
|
EFI_SIZE_TO_PAGES (NeedSize),
|
|
&PhyAddress
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
mIsPageType = TRUE;
|
|
mPageNum = EFI_SIZE_TO_PAGES (NeedSize);
|
|
*AllocateSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (NeedSize));
|
|
mHotkeyStringTable = (HOTKEY_AND_STRING_TABLE *)(UINTN)PhyAddress;
|
|
|
|
} else {
|
|
mIsPageType = FALSE;
|
|
*AllocateSize = NeedSize;
|
|
mHotkeyStringTable = (HOTKEY_AND_STRING_TABLE *)TempAddress;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Fill data into hot key and string table
|
|
|
|
@param[in] HotkeyCount the number of hot Key
|
|
@param[in] StringCount the number of string
|
|
@param[in] SystemInfoCount the number of system information
|
|
@param[in] OperationCount the number of hot key operation
|
|
|
|
@retval EFI_SUCCESS Fill success
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FillDataToTable (
|
|
IN UINTN HotkeyCount,
|
|
IN UINTN StringCount,
|
|
IN UINTN SystemInfoCount,
|
|
IN UINTN OperationCount
|
|
)
|
|
{
|
|
UINTN Index;
|
|
VOID *FillDataPtr;
|
|
DYNAMIC_STRING_EXTERNAL *DyStrPtr;
|
|
DYNAMIC_SYSTEM_INFO_EXTERNAL *DySysInfoPtr;
|
|
CHAR8 *TempAsciiString;
|
|
CHAR16 *TempUniString;
|
|
DYNAMIC_OPERATION_EXTERNAL *DyOperationPtr;
|
|
|
|
Index = 0;
|
|
FillDataPtr = NULL;
|
|
DyStrPtr = NULL;
|
|
DySysInfoPtr = NULL;
|
|
TempAsciiString = NULL;
|
|
TempUniString = NULL;
|
|
DyOperationPtr = NULL;
|
|
|
|
mHotkeyStringTable->Signature = HOTKEY_TABLE_PTR_SIGNATURE;
|
|
mHotkeyStringTable->HotkeyCount = (UINT8)HotkeyCount;
|
|
mHotkeyStringTable->StringCount = (UINT8)StringCount;
|
|
mHotkeyStringTable->SystemInfoCount = (UINT8)SystemInfoCount;
|
|
mHotkeyStringTable->OperationCount = (UINT8)OperationCount;
|
|
//
|
|
//Point to Hotkey table location.
|
|
//
|
|
FillDataPtr = (VOID *) (mHotkeyStringTable + 1);
|
|
|
|
//
|
|
// Fill hot key data
|
|
//
|
|
CopyMem (FillDataPtr, mHotKeyDefine, sizeof (mHotKeyDefine));
|
|
|
|
//
|
|
// Fill string data
|
|
//
|
|
DyStrPtr = (DYNAMIC_STRING_EXTERNAL *)((UINTN)FillDataPtr + sizeof (mHotKeyDefine));
|
|
for (Index = 0; Index < GET_ARRAY_COUNT (StringDefine); Index++) {
|
|
DyStrPtr->KeyId = StringDefine[Index].KeyId;
|
|
DyStrPtr->SystemInfoId = StringDefine[Index].SystemInfoId;
|
|
DyStrPtr->LocationX = StringDefine[Index].LocationX;
|
|
DyStrPtr->LocationY = StringDefine[Index].LocationY;
|
|
DyStrPtr->Flag = StringDefine[Index].Flag;
|
|
CopyMem (&(DyStrPtr->Foreground), &StringDefine[Index].Foreground, sizeof (EFI_UGA_PIXEL));
|
|
CopyMem (&(DyStrPtr->Background), &StringDefine[Index].Background, sizeof (EFI_UGA_PIXEL));
|
|
|
|
TempUniString = GetStringByStringToken (mStringList[Index].StringToken);
|
|
TempAsciiString = AllocateZeroPool (StrSize (TempUniString));
|
|
UnicodeStrToAsciiStrS (TempUniString, TempAsciiString, StrSize (TempUniString));
|
|
CopyMem (&(DyStrPtr->String), TempAsciiString, AsciiStrSize (TempAsciiString));
|
|
DyStrPtr = (DYNAMIC_STRING_EXTERNAL *)((UINTN)DyStrPtr + sizeof (DYNAMIC_STRING_EXTERNAL) - sizeof (CHAR8) + AsciiStrSize (TempAsciiString));
|
|
FreePool (TempAsciiString);
|
|
}
|
|
|
|
//
|
|
// Fill system information
|
|
//
|
|
DySysInfoPtr = (DYNAMIC_SYSTEM_INFO_EXTERNAL *)DyStrPtr;
|
|
for (Index = 0; Index < GET_ARRAY_COUNT (SystemInfoTable); Index++) {
|
|
DySysInfoPtr->SystemInfoId = (UINT8)SystemInfoTable[Index].Type;
|
|
DySysInfoPtr->LocationX = SystemInfoTable[Index].LocationX;
|
|
DySysInfoPtr->LocationY = SystemInfoTable[Index].LocationY;
|
|
TempUniString = GetStringByStringToken (SystemInfoTable[Index].StringToken);
|
|
TempAsciiString = AllocateZeroPool (StrSize (TempUniString));
|
|
UnicodeStrToAsciiStrS (TempUniString, TempAsciiString, StrSize (TempUniString));
|
|
CopyMem (&(DySysInfoPtr->String), TempAsciiString, AsciiStrSize (TempAsciiString));
|
|
DySysInfoPtr = (DYNAMIC_SYSTEM_INFO_EXTERNAL *)((UINTN)DySysInfoPtr + sizeof (DYNAMIC_SYSTEM_INFO_EXTERNAL) - sizeof (CHAR8) + AsciiStrSize (TempAsciiString));
|
|
FreePool (TempAsciiString);
|
|
}
|
|
//
|
|
// Fill hot key operation
|
|
//
|
|
DyOperationPtr = (DYNAMIC_OPERATION_EXTERNAL *)DySysInfoPtr;
|
|
for (Index = 0; Index < GET_ARRAY_COUNT (OperationTable); Index++) {
|
|
DyOperationPtr->OperationId = OperationTable[Index].OperationId;
|
|
TempUniString = GetStringByStringToken (OperationTable[Index].StringToken);
|
|
TempAsciiString = AllocateZeroPool (StrSize (TempUniString));
|
|
UnicodeStrToAsciiStrS (TempUniString, TempAsciiString, StrSize (TempUniString));
|
|
CopyMem (&(DyOperationPtr->String), TempAsciiString, AsciiStrSize (TempAsciiString));
|
|
DyOperationPtr = (DYNAMIC_OPERATION_EXTERNAL *)((UINTN)DyOperationPtr + sizeof (DYNAMIC_OPERATION_EXTERNAL) - sizeof (CHAR8) + AsciiStrSize (TempAsciiString));
|
|
FreePool (TempAsciiString);
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Free the allocated memory of hot key and string table.
|
|
|
|
None
|
|
|
|
@retval None
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
FreeHotkeyStringTable (
|
|
VOID
|
|
)
|
|
{
|
|
if (NULL == mHotkeyStringTable) {
|
|
return;
|
|
}
|
|
|
|
if (mIsPageType == TRUE) {
|
|
gBS->FreePages ((EFI_PHYSICAL_ADDRESS)mHotkeyStringTable, mPageNum);
|
|
|
|
} else {
|
|
gBS->FreePool (mHotkeyStringTable);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
Find a suitable memory space to store Dynamic Hotkey and String Table Ptr
|
|
find the E/F segment first. If there is no memory space, allocate it in high memory then store
|
|
the address in the Variable - DynamicHotkey
|
|
|
|
@param[in] AllocateSize the Hotkey and String table size
|
|
@param[in] **FEAddress the address to store the signature
|
|
|
|
@retval EFI_SUCCESS Install protocol success.
|
|
@retval other Install protocol fail.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
GetFEsegmentTableAddress (
|
|
IN UINTN AllocateSize,
|
|
OUT VOID **FEAddress
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
LEGACY_BIOS_INSTANCE *BiosPrivate;
|
|
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
|
|
EFI_LEGACY_REGION2_PROTOCOL *LegacyRegion;
|
|
EFI_IA32_REGISTER_SET Regs;
|
|
HOTKEY_AND_STRING_PTR *Point;
|
|
|
|
BiosPrivate = NULL;
|
|
LegacyBios = NULL;
|
|
LegacyRegion = NULL;
|
|
Point = NULL;
|
|
ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));
|
|
|
|
if (NULL == FEAddress) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// LocateProtocol : LegacyBios
|
|
//
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiLegacyBiosProtocolGuid,
|
|
NULL,
|
|
(VOID **)&LegacyBios
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
//
|
|
// Pure EFI Boot. Allocate high memory to store the signature, and store the address in the variable
|
|
//
|
|
Status = gBS->AllocatePool (
|
|
EfiRuntimeServicesData,
|
|
sizeof (HOTKEY_AND_STRING_PTR),
|
|
(VOID **)&Point
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Point->Signature = HOTKEY_TABLE_PTR_SIGNATURE;
|
|
Point->Address = (UINT32)(UINTN)mHotkeyStringTable;
|
|
Point->Size = (UINT32)AllocateSize;
|
|
|
|
*FEAddress = (VOID *)Point;
|
|
|
|
DEBUG ( (DEBUG_INFO, "GetFEsegmentTableAddress: Table at 0x%x\n", *FEAddress));
|
|
|
|
Status = gRT->SetVariable (
|
|
L"DynamicHotkey",
|
|
&gDynamicHotKeyGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
|
sizeof (HOTKEY_AND_STRING_PTR),
|
|
(VOID *)Point
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// LocateProtocol : LegacyRegion
|
|
//
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiLegacyRegion2ProtocolGuid,
|
|
NULL,
|
|
(VOID **)&LegacyRegion
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Get FE segment Table Address
|
|
//
|
|
LegacyRegion->UnLock (LegacyRegion, 0xE0000, 0x20000, NULL);
|
|
|
|
ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));
|
|
Regs.X.AX = Legacy16GetTableAddress;
|
|
Regs.X.BX = F0000Region;
|
|
Regs.X.CX = (UINT16)sizeof (HOTKEY_AND_STRING_PTR);
|
|
Regs.X.DX = HOTKEY_TABLE_PTR_ALIGNMENT;
|
|
|
|
BiosPrivate = LEGACY_BIOS_INSTANCE_FROM_THIS (LegacyBios);
|
|
Status = LegacyBios->FarCall86 (
|
|
LegacyBios,
|
|
BiosPrivate->Legacy16CallSegment,
|
|
BiosPrivate->Legacy16CallOffset,
|
|
&Regs,
|
|
NULL,
|
|
0
|
|
);
|
|
|
|
if (!EFI_ERROR (Regs.X.AX)) {
|
|
Point = (HOTKEY_AND_STRING_PTR *)(UINTN)(Regs.X.DS * 16 + Regs.X.BX);
|
|
Point->Signature = HOTKEY_TABLE_PTR_SIGNATURE;
|
|
Point->Address = (UINT32)(UINTN)mHotkeyStringTable;
|
|
Point->Size = (UINT32)AllocateSize;
|
|
}
|
|
|
|
LegacyRegion->Lock (LegacyRegion, 0xE0000, 0x20000, NULL);
|
|
|
|
if (EFI_ERROR (Regs.X.AX)) {
|
|
return Regs.X.AX;
|
|
}
|
|
|
|
//
|
|
// Return value
|
|
//
|
|
*FEAddress = (VOID *)Point;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Initialize hot key and string table
|
|
|
|
@param[in] Event Event whose notification function is being invoked.
|
|
@param[in] *Context Pointer to the notification function's context.
|
|
|
|
@retval None
|
|
*/
|
|
VOID
|
|
EFIAPI
|
|
InitializeHotkeyAndStringTable (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
UINTN TotalSize;
|
|
UINTN HotkeyCount;
|
|
UINTN StringCount;
|
|
UINTN SystemInfoCount;
|
|
UINTN OperationCount;
|
|
UINTN AllocateSize;
|
|
|
|
TotalSize = 0;
|
|
HotkeyCount = 0;
|
|
StringCount = 0;
|
|
SystemInfoCount = 0;
|
|
OperationCount = 0;
|
|
AllocateSize = 0;
|
|
|
|
DEBUG ( (DEBUG_INFO, "[InitializeHotkeyAndStringTable] %a Start\n", __FUNCTION__));
|
|
|
|
//
|
|
// Off events to prevent re-entry into the function
|
|
//
|
|
Status = gBS->CloseEvent (mReadyToBootEvent);
|
|
if (EFI_ERROR (Status)) {
|
|
//
|
|
// There is no need to free memory, this function Automatically free memory
|
|
//
|
|
return;
|
|
}
|
|
|
|
|
|
//
|
|
// Get size and count
|
|
//
|
|
Status = GetRequiredSize (&TotalSize, &HotkeyCount, &StringCount, &SystemInfoCount, &OperationCount);
|
|
if (EFI_ERROR (Status)) {
|
|
//
|
|
// There is no need to free memory, this function Automatically free memory
|
|
//
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Allocate Reserved Memory
|
|
//
|
|
Status = AllocateReservedMemory (TotalSize, &AllocateSize);
|
|
if (EFI_ERROR (Status)) {
|
|
//
|
|
// There is no need to free memory, this function Automatically free memory
|
|
//
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Copy String, VfrBin
|
|
//
|
|
Status = FillDataToTable (HotkeyCount, StringCount, SystemInfoCount, OperationCount);
|
|
if (EFI_ERROR (Status)) {
|
|
//
|
|
// It should free memory
|
|
//
|
|
FreeHotkeyStringTable ();
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Fill FE segment
|
|
//
|
|
Status = GetFEsegmentTableAddress (AllocateSize, &mFEaddress);
|
|
if (EFI_ERROR (Status)) {
|
|
//
|
|
// It should free memory
|
|
//
|
|
FreeHotkeyStringTable ();
|
|
return;
|
|
}
|
|
DEBUG ( (DEBUG_INFO, "[InitializeVariableEditTable] %a End\n", __FUNCTION__));
|
|
|
|
//
|
|
// Print Information
|
|
//
|
|
DEBUG ( (DEBUG_INFO, "Dynamic HotKey PTR at 0x%x\n", mFEaddress));
|
|
DEBUG ( (DEBUG_INFO, "Dynamic HotKey TABLE at 0x%x\n", mHotkeyStringTable));
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/**
|
|
Entrypoint of this module.
|
|
|
|
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
|
@param[in] SystemTable A pointer to the EFI System Table.
|
|
|
|
@retval EFI_SUCCESS Install protocol success.
|
|
@retval other Install protocol fail.
|
|
*/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DynamicHotKeyEntry (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE Handle;
|
|
DYNAMIC_HOTKEY_PROTOCOL *DynamicHotKey;
|
|
|
|
//
|
|
// Check if the custom-define protocol is installed or not
|
|
//
|
|
Status = gBS->LocateProtocol (
|
|
&gDynamicHotKeyProtocolGuid,
|
|
NULL,
|
|
(VOID **)&DynamicHotKey
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
return EFI_ALREADY_STARTED;
|
|
}
|
|
|
|
//
|
|
// Create "ReadyToBoot" Event
|
|
//
|
|
Status = EfiCreateEventReadyToBootEx (
|
|
TPL_NOTIFY,
|
|
InitializeHotkeyAndStringTable,
|
|
NULL,
|
|
&mReadyToBootEvent
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
|
|
//
|
|
// Fill context
|
|
//
|
|
mDynamicHotKey.GetDynamicHotKeyList = GetDynamicHotKeyList;
|
|
mDynamicHotKey.GetDynamicHotKeyOperation = GetDynamicHotKeyOperation;
|
|
mDynamicHotKey.GetDynamicStringCount = GetDynamicStringCount;
|
|
mDynamicHotKey.GetDynamicString = GetDynamicString;
|
|
mDynamicHotKey.GetDynamicStringColor = GetDynamicStringColor;
|
|
mDynamicHotKey.IsDynamicHotKeyPressed = IsDynamicHotKeyPressed;
|
|
mDynamicHotKey.AdjustStringPosition = AdjustStringPosition;
|
|
mDynamicHotKey.ShowSystemInformation = ShowSystemInformation;
|
|
|
|
//
|
|
// Initialize strings to HII database
|
|
//
|
|
mHotKeyStringPackHandle = HiiAddPackages (
|
|
&gEfiCallerIdGuid,
|
|
NULL,
|
|
DynamicHotKeyDxeStrings,
|
|
NULL
|
|
);
|
|
ASSERT (mHotKeyStringPackHandle != NULL);
|
|
|
|
Status = GetHotKeyAndString ();
|
|
|
|
//
|
|
// Install protocol
|
|
//
|
|
Handle = NULL;
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
&Handle,
|
|
&gDynamicHotKeyProtocolGuid,
|
|
&mDynamicHotKey,
|
|
NULL
|
|
);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|