669 lines
18 KiB
C
669 lines
18 KiB
C
/** @file
|
|
Hot key function
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2012 - 2019, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include "HotKey.h"
|
|
#include <Protocol/DynamicHotKey.h>
|
|
#include <Guid/HotKeyEvent.h>
|
|
|
|
STATIC EFI_EVENT mGetHotKeyEvent;
|
|
STATIC EFI_EVENT mStopHotKeyEvent;
|
|
STATIC EFI_EVENT mHotKeyDelayTimeEvent;
|
|
STATIC EFI_EVENT mBadgingStringEvent;
|
|
STATIC EFI_MONITOR_KEY_FILTER_PROTOCOL *mMonitorKey = NULL;
|
|
STATIC BOOLEAN mGetFunctionKey = FALSE;
|
|
STATIC UINT16 mFunctionKey;
|
|
STATIC BOOLEAN mDisableQuietBoot = FALSE;
|
|
STATIC EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *mSimpleTextInEx = NULL;
|
|
STATIC EFI_GUID mPringBadgingStringGuid = { 0x39948f26, 0xf610, 0x4ec3, { 0x97, 0x28, 0x3a, 0xdd, 0x9f, 0xac, 0x11, 0x23 } };
|
|
|
|
|
|
STATIC
|
|
VOID
|
|
EFIAPI
|
|
GetKeyFunction (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
);
|
|
|
|
STATIC
|
|
EFI_STATUS
|
|
DisplayBadgingString (
|
|
IN HOT_KEY_CONTEXT *HotkeyContext
|
|
);
|
|
|
|
|
|
/**
|
|
Callback function to display badging string
|
|
|
|
@param[in] Event Event
|
|
@param[in] Context Event Context Pointer
|
|
**/
|
|
STATIC
|
|
VOID
|
|
EFIAPI
|
|
BadgingStringCallback (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
gBS->CloseEvent (Event);
|
|
DisplayBadgingString ((HOT_KEY_CONTEXT *) Context);
|
|
}
|
|
|
|
/**
|
|
Callback function to stop HotKey event
|
|
|
|
@param[in] Event Event
|
|
@param[in] Context Event Context Pointer
|
|
**/
|
|
STATIC
|
|
VOID
|
|
EFIAPI
|
|
StopHotKeyEventCallback (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
gBS->CloseEvent (Event);
|
|
BdsLibStopHotKeyEvent ();
|
|
}
|
|
|
|
/**
|
|
HotKey services init
|
|
|
|
@param NotifyContext A user defined context which is used in hot key service
|
|
|
|
@retval EFI_SUCCESS Init Success
|
|
@retval EFI_INVALID_PARAMETER Input value is invalid
|
|
|
|
**/
|
|
EFI_STATUS
|
|
BdsLibInstallHotKeys (
|
|
IN HOT_KEY_CONTEXT *NotifyContext
|
|
)
|
|
{
|
|
UINT64 Timeout;
|
|
EFI_STATUS Status;
|
|
UINTN Size;
|
|
IMAGE_INFO ImageInfo;
|
|
VOID *Registration;
|
|
|
|
if (NotifyContext == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (FeaturePcdGet(PcdSecureFlashSupported)) {
|
|
Size = sizeof (IMAGE_INFO);
|
|
Status = gRT->GetVariable (
|
|
L"SecureFlashInfo",
|
|
&gSecureFlashInfoGuid,
|
|
NULL,
|
|
&Size,
|
|
&ImageInfo
|
|
);
|
|
if ((Status == EFI_SUCCESS) && (ImageInfo.FlashMode)) {
|
|
mGetHotKeyEvent = NULL;
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
//
|
|
// BDS phase may spend much time to execute code in driver level or TPL_CALLBACK (callback
|
|
// function or checkpoint and cause hokey doesn't work. The TPL of get hotkey callback function
|
|
// must be TPL_NOTIFY.
|
|
//
|
|
Timeout = SPECIFIED_TIME;
|
|
Status = gBS->CreateEvent (
|
|
EVT_TIMER | EVT_NOTIFY_SIGNAL,
|
|
TPL_NOTIFY,
|
|
GetKeyFunction,
|
|
(VOID *) NotifyContext,
|
|
&mGetHotKeyEvent
|
|
);
|
|
if (!EFI_ERROR(Status)) {
|
|
Status = gBS->SetTimer (mGetHotKeyEvent, TimerPeriodic, Timeout);
|
|
}
|
|
//
|
|
// To prevent from gH2OBdsCpDisplayStringBeforeGuid checkpoint doesn't work properly.
|
|
// (will be called in TPL_NOTIFY TPL). Instead of display badging string in GetKeyFunction,
|
|
// we register a callback function using 5 TPL to make sure the checkpoint can work properly.
|
|
//
|
|
Status = gBS->CreateEvent (
|
|
EVT_NOTIFY_SIGNAL,
|
|
TPL_APPLICATION + 1,
|
|
BadgingStringCallback,
|
|
(VOID *) NotifyContext,
|
|
&mBadgingStringEvent
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = gBS->RegisterProtocolNotify (
|
|
&mPringBadgingStringGuid,
|
|
mBadgingStringEvent,
|
|
&Registration
|
|
);
|
|
}
|
|
//
|
|
// Use to stop HotKey event
|
|
//
|
|
Status = gBS->CreateEvent (
|
|
EVT_NOTIFY_SIGNAL,
|
|
TPL_NOTIFY,
|
|
StopHotKeyEventCallback,
|
|
NULL,
|
|
&mStopHotKeyEvent
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = gBS->RegisterProtocolNotify (
|
|
&gH2OStopHotKeyGuid,
|
|
mStopHotKeyEvent,
|
|
&Registration
|
|
);
|
|
}
|
|
//
|
|
// According to platform quiet boot policy to initialize disable quiet boot state
|
|
//
|
|
mDisableQuietBoot = NotifyContext->EnableQuietBootPolicy ? FALSE : TRUE;
|
|
|
|
gBS->LocateProtocol (&gEfiMonitorKeyFilterProtocolGuid, NULL, (VOID **) &mMonitorKey);
|
|
|
|
gBS->HandleProtocol (
|
|
gST->ConsoleInHandle,
|
|
&gEfiSimpleTextInputExProtocolGuid,
|
|
(VOID **) &mSimpleTextInEx
|
|
);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
Set specific hot key
|
|
|
|
@param Key Input hot key value
|
|
|
|
@retval EFI_SUCCESS Set specific key to hot key service successful
|
|
|
|
**/
|
|
EFI_STATUS
|
|
BdsLibSetKey (
|
|
IN UINT16 Key,
|
|
IN HOT_KEY_CONTEXT *HotKeyContext
|
|
)
|
|
{
|
|
|
|
mFunctionKey = Key;
|
|
mGetFunctionKey = TRUE;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
According input context and key value to determine to enable
|
|
quiet boot or disable quiet boot
|
|
|
|
@param HotKeyContext pointer to HOT_KEY_CONTEXT which save user quiet boot requirement
|
|
@param key pointer to save key value
|
|
@param EnableQuietBoot Aboolean value to save the enable quiet boot or disable quiet boot
|
|
|
|
@retval EFI_SUCCESS Get Quiet boot condition successful
|
|
@retval EFI_INVALID_PARAMETER Input value is invalid
|
|
|
|
**/
|
|
EFI_STATUS
|
|
GetQuietBootCondition (
|
|
IN HOT_KEY_CONTEXT *HotKeyContext,
|
|
IN EFI_INPUT_KEY *Key,
|
|
OUT BOOLEAN *EnableQuietBoot
|
|
)
|
|
{
|
|
UINTN Index;
|
|
|
|
if (HotKeyContext == NULL || Key == NULL || EnableQuietBoot == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// According context policy to set EableQuietBoot
|
|
//
|
|
if (HotKeyContext->EnableQuietBootPolicy) {
|
|
*EnableQuietBoot = TRUE;
|
|
} else {
|
|
*EnableQuietBoot = FALSE;
|
|
}
|
|
|
|
//
|
|
// check key value is disable quiet boot hot key
|
|
//
|
|
if (*EnableQuietBoot) {
|
|
for (Index = 0; Index < HotKeyContext->DisableQueitBootHotKeyCnt; Index++) {
|
|
if ((HotKeyContext->HotKeyList[Index].ScanCode == Key->ScanCode) &&
|
|
(HotKeyContext->HotKeyList[Index].UnicodeChar == Key->UnicodeChar)) {
|
|
*EnableQuietBoot = FALSE;
|
|
}
|
|
}
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This function uses to check gEfiConsoleControlProtocolGuid exists or not.
|
|
|
|
@retval TRUE System supports console control protocol.
|
|
@retval FALSE System doesn't support console control protocol.
|
|
**/
|
|
BOOLEAN
|
|
SupportConsoleControl (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
|
|
EFI_STATUS Status;
|
|
|
|
Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
|
|
if (EFI_ERROR (Status)) {
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
According to pressed hotkey to display relative badging string.
|
|
|
|
@param[in] HotkeyContext Pointer to HOT_KEY_CONTEXT instance.
|
|
|
|
@retval EFI_SUCCESS Print badging string successful.
|
|
@retval EFI_INVALID_PARAMETER HotkeyContext is NULL.
|
|
@retval EFI_UNSUPPORTED Cannot find gEfiOEMBadgingSupportProtocolGuid or cannot show badging string.
|
|
@retval EFI_NOT_READY User doesn't press hotkey or hardware isn't ready.
|
|
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
DisplayBadgingString (
|
|
IN HOT_KEY_CONTEXT *HotkeyContext
|
|
)
|
|
{
|
|
UINT16 FunctionKey;
|
|
BOOLEAN KeyPressed;
|
|
EFI_OEM_BADGING_SUPPORT_PROTOCOL *Badging;
|
|
EFI_STATUS Status;
|
|
|
|
if (HotkeyContext == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = gBS->LocateProtocol (&gEfiOEMBadgingSupportProtocolGuid, NULL, (VOID **) &Badging);
|
|
if (EFI_ERROR (Status) || !HotkeyContext->CanShowString) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = BdsLibGetHotKey (&FunctionKey, &KeyPressed);
|
|
if (EFI_ERROR (Status) || !KeyPressed) {
|
|
return EFI_NOT_READY;
|
|
}
|
|
|
|
Status = EFI_SUCCESS;
|
|
if (SupportConsoleControl ()) {
|
|
//
|
|
// print OEM string in text mode and GOP mode, if support console control protocol.
|
|
//
|
|
Status = ShowOemString (Badging, TRUE, (UINT8) FunctionKey);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_NOT_READY;
|
|
}
|
|
Status = BdsLibShowOemStringInTextMode (TRUE, (UINT8) FunctionKey);
|
|
} else if (!mDisableQuietBoot) {
|
|
//
|
|
// Only print OEM string in GOP mode, if quiet boot is disabled and system doesn't
|
|
// support console control protocol.
|
|
//
|
|
Status = ShowOemString (Badging, TRUE, (UINT8) FunctionKey);
|
|
} else {
|
|
//
|
|
// Only print OEM string in text mode, if quiet boot is disabled and system doesn't
|
|
// support console control protocol.
|
|
//
|
|
Status = BdsLibShowOemStringInTextMode (TRUE, (UINT8) FunctionKey);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
HotKey Check Event Handler
|
|
|
|
@param[in] Event Event
|
|
@param[in] Context Event Context Pointer
|
|
**/
|
|
STATIC
|
|
VOID
|
|
EFIAPI
|
|
GetKeyFunction (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT32 KeyDetected = 0;
|
|
UINT16 GetKey;
|
|
UINTN KeyValue;
|
|
EFI_STATUS KeyStatus;
|
|
EFI_INPUT_KEY Key;
|
|
BOOLEAN EnableQuietBoot;
|
|
HOT_KEY_CONTEXT *HotKeyContext;
|
|
EFI_KEY_DATA KeyData;
|
|
BOOLEAN CheckPlatformHook;
|
|
STATIC BOOLEAN BadgingStrPrinted = FALSE;
|
|
EFI_HANDLE Handle;
|
|
|
|
HotKeyContext = (HOT_KEY_CONTEXT *) Context;
|
|
if (mSimpleTextInEx != NULL) {
|
|
KeyStatus = mSimpleTextInEx->ReadKeyStrokeEx (mSimpleTextInEx, &KeyData);
|
|
Key = KeyData.Key;
|
|
} else {
|
|
KeyStatus = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
|
|
}
|
|
|
|
if (!EFI_ERROR (KeyStatus)) {
|
|
EnableQuietBoot = TRUE;
|
|
GetQuietBootCondition (HotKeyContext, &Key, &EnableQuietBoot);
|
|
//
|
|
// 1. Check the Quiet boot requirement from input context
|
|
// 2. Check the mDisableQuiete to determine is whether already disable quiet boot
|
|
//
|
|
if (!EnableQuietBoot && !mDisableQuietBoot) {
|
|
DisableQuietBoot ();
|
|
mDisableQuietBoot = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
if (!mGetFunctionKey) {
|
|
if (mMonitorKey == NULL) {
|
|
return;
|
|
}
|
|
|
|
mMonitorKey->GetMonitoredKeys (mMonitorKey, &KeyDetected);
|
|
if (FeaturePcdGet (PcdDynamicHotKeySupported)) {
|
|
STATIC DYNAMIC_HOTKEY_PROTOCOL *DynamicHotKey;
|
|
//
|
|
// Get dynamic key first so that OEM can use dynamic hot key to override built-in hot key
|
|
//
|
|
if (DynamicHotKey == NULL) {
|
|
Status = gBS->LocateProtocol (&gDynamicHotKeyProtocolGuid, NULL, (VOID **)&DynamicHotKey);
|
|
if (EFI_ERROR (Status)) {
|
|
DynamicHotKey = NULL;
|
|
}
|
|
}
|
|
if (DynamicHotKey != NULL) {
|
|
Status = DynamicHotKey->GetDynamicHotKeyOperation (DynamicHotKey, KeyDetected, &KeyValue);
|
|
if (!EFI_ERROR (Status)) {
|
|
mFunctionKey = (UINT16)KeyValue;
|
|
mGetFunctionKey = TRUE;
|
|
if (!BadgingStrPrinted) {
|
|
//
|
|
// Display badging string again if hot key is pressed but system doesn't print bading string before.
|
|
//
|
|
Handle = NULL;
|
|
gBS->InstallProtocolInterface (
|
|
&Handle,
|
|
&mPringBadgingStringGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
NULL
|
|
);
|
|
BadgingStrPrinted = TRUE;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// OemServices
|
|
//
|
|
KeyValue = 0;
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcInstallPostKeyTable \n"));
|
|
Status = OemSvcInstallPostKeyTable (
|
|
KeyDetected,
|
|
SCAN_NULL,
|
|
&KeyValue
|
|
);
|
|
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcInstallPostKeyTable Status: %r\n", Status));
|
|
if (!EFI_ERROR(Status) || KeyValue == 0) {
|
|
return;
|
|
}
|
|
GetKey = (UINT16) KeyValue;
|
|
CheckPlatformHook = TRUE;
|
|
if (HotKeyContext != NULL && HotKeyContext->PlatformGetKeyFunction != NULL) {
|
|
CheckPlatformHook = HotKeyContext->PlatformGetKeyFunction (GetKey);
|
|
}
|
|
|
|
if (CheckPlatformHook) {
|
|
BdsLibSetKey (GetKey, HotKeyContext);
|
|
}
|
|
}
|
|
|
|
if (!BadgingStrPrinted) {
|
|
//
|
|
// Display badging string again if hot key is pressed but system doesn't print bading string before.
|
|
//
|
|
Handle = NULL;
|
|
gBS->InstallProtocolInterface (
|
|
&Handle,
|
|
&mPringBadgingStringGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
NULL
|
|
);
|
|
BadgingStrPrinted = TRUE;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
Check if the hot key is detected or not.
|
|
|
|
@retval TRUE The hot key is detected.
|
|
@retval FALSE The hot key is not detected.
|
|
**/
|
|
BOOLEAN
|
|
IsHotKeyDetected (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
H2O_BDS_CP_DISPLAY_STRING_BEFORE_DATA *BdsDisplayStringBeforeData;
|
|
|
|
Status = gBS->LocateProtocol (&gH2OBdsCpDisplayStringBeforeGuid, NULL, (VOID **) &BdsDisplayStringBeforeData);
|
|
if (!EFI_ERROR (Status)) {
|
|
return BdsDisplayStringBeforeData->AfterSelect;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
Stop HotKey event
|
|
|
|
@retval EFI_SUCCESS Stop HotKeyEvent successful
|
|
@retval Other Cannot stop HotKey event.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
BdsLibStopHotKeyEvent (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_STATUS KeyStatus;
|
|
UINT16 FunctionKey;
|
|
BOOLEAN HotKeyPressed;
|
|
|
|
while (mHotKeyDelayTimeEvent != NULL) {
|
|
Status = gBS->CheckEvent (mHotKeyDelayTimeEvent);
|
|
|
|
if (mGetFunctionKey || IsHotKeyDetected () || Status != EFI_NOT_READY) {
|
|
//
|
|
// If user inputs hotkey or delay time has expired, close events.
|
|
//
|
|
gBS->CloseEvent (mHotKeyDelayTimeEvent);
|
|
mHotKeyDelayTimeEvent = NULL;
|
|
} else {
|
|
gBS->Stall (500);
|
|
}
|
|
}
|
|
|
|
Status = EFI_ABORTED;
|
|
BdsLibGetHotKey (&FunctionKey, &HotKeyPressed);
|
|
if (mGetHotKeyEvent != NULL) {
|
|
Status = gBS->CloseEvent (mGetHotKeyEvent);
|
|
if (!HotKeyPressed) {
|
|
BdsLibGetHotKey (&FunctionKey, &HotKeyPressed);
|
|
}
|
|
mGetHotKeyEvent = NULL;
|
|
}
|
|
|
|
if (BdsLibIsBootOrderHookEnabled ()) {
|
|
KeyStatus = BdsLibGetHotKey (&FunctionKey, &HotKeyPressed);
|
|
if (!EFI_ERROR (KeyStatus) && HotKeyPressed) {
|
|
BdsLibRestoreBootOrderFromPhysicalBootOrder ();
|
|
}
|
|
}
|
|
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
Get the state of user is whether pressed hotkey and the pressed hotkey value
|
|
|
|
@param FunctionKey pointer to user pressed hotkey value
|
|
@param HotKeyPressed TRUE: user has pressed hotkey
|
|
FALSE: user hasn't pressed hotkey yet
|
|
|
|
@retval EFI_SUCCESS Get hotkey value and state successful
|
|
@retval EFI_INVALID_PARAMETER Input value is invalid
|
|
|
|
**/
|
|
EFI_STATUS
|
|
BdsLibGetHotKey (
|
|
OUT UINT16 *FunctionKey,
|
|
OUT BOOLEAN *HotKeyPressed
|
|
)
|
|
{
|
|
if (FunctionKey == NULL || HotKeyPressed == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (!mGetFunctionKey && IsHotKeyDetected ()) {
|
|
mGetFunctionKey = TRUE;
|
|
mFunctionKey = 0;
|
|
}
|
|
|
|
*HotKeyPressed = mGetFunctionKey;
|
|
//
|
|
// Only need output hotkey after hot key pressed
|
|
//
|
|
if (mGetFunctionKey) {
|
|
*FunctionKey = mFunctionKey;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
Get current quiet boot state
|
|
|
|
@param QuietBootState TRUE: indicate current quiet boot state is enable quiet boot
|
|
FALSE: indicate current quiet boot state is disable quiet boot
|
|
|
|
@retval EFI_SUCCESS Get quiet boot state successful
|
|
@retval EFI_INVALID_PARAMETER Input value is invalid
|
|
|
|
**/
|
|
EFI_STATUS
|
|
BdsLibGetQuietBootState (
|
|
OUT BOOLEAN *QuietBootState
|
|
)
|
|
{
|
|
if (QuietBootState == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
*QuietBootState = mDisableQuietBoot ? FALSE : TRUE;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
Based on BootDelayTime of "Setup" variable, create hotkey delay timer event.
|
|
|
|
@param Level The memory test intensive level.
|
|
|
|
@retval EFI_SUCCESS Create event success
|
|
@retval EFI_UNSUPPORTED Hot key is not installed. Not support hot key delay.
|
|
@retval EFI_NOT_FOUND Locate EfiSetupUtility protocol fail
|
|
@retval Other Create event or set timer fail
|
|
|
|
**/
|
|
EFI_STATUS
|
|
BdsLibSetHotKeyDelayTime (
|
|
VOID
|
|
)
|
|
{
|
|
UINT16 Timeout;
|
|
EFI_STATUS Status;
|
|
UINTN Size;
|
|
UINT64 TimeOutMs;
|
|
|
|
//
|
|
// If hot key is not initialized or delay event is already set, return unsupported.
|
|
//
|
|
if (mGetHotKeyEvent == NULL || mHotKeyDelayTimeEvent != NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
TimeOutMs = PcdGet32 (PcdPlatformBootTimeOutMs);
|
|
Timeout = 0;
|
|
Size = sizeof (Timeout);
|
|
Status = gRT->GetVariable (
|
|
L"Timeout",
|
|
&gEfiGlobalVariableGuid,
|
|
NULL,
|
|
&Size,
|
|
&Timeout
|
|
);
|
|
TimeOutMs += MultU64x32 ((UINT64) Timeout, 1000);
|
|
if (TimeOutMs == 0) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
Status = gBS->CreateEvent (
|
|
EVT_TIMER,
|
|
TPL_NOTIFY,
|
|
NULL,
|
|
NULL,
|
|
&mHotKeyDelayTimeEvent
|
|
);
|
|
if (!EFI_ERROR(Status)) {
|
|
Status = gBS->SetTimer (mHotKeyDelayTimeEvent, TimerRelative, MultU64x32 (TimeOutMs, TIMER_EVENT_ONE_MILLISEC));
|
|
}
|
|
return Status;
|
|
}
|
|
|