diff options
-rw-r--r-- | IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c | 86 | ||||
-rw-r--r-- | IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h | 17 |
2 files changed, 97 insertions, 6 deletions
diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c index 8dcb131778..a597d99a97 100644 --- a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c +++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c @@ -1,7 +1,7 @@ /** @file
ConsoleOut Routines that speak VGA.
-Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@@ -272,6 +272,8 @@ BiosKeyboardDriverBindingStart ( BiosKeyboardPrivate->Queue.Front = 0;
BiosKeyboardPrivate->Queue.Rear = 0;
+ BiosKeyboardPrivate->QueueForNotify.Front = 0;
+ BiosKeyboardPrivate->QueueForNotify.Rear = 0;
BiosKeyboardPrivate->SimpleTextInputEx.Reset = BiosKeyboardResetEx;
BiosKeyboardPrivate->SimpleTextInputEx.ReadKeyStrokeEx = BiosKeyboardReadKeyStrokeEx;
BiosKeyboardPrivate->SimpleTextInputEx.SetState = BiosKeyboardSetState;
@@ -339,7 +341,20 @@ BiosKeyboardDriverBindingStart ( StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
goto Done;
}
-
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ KeyNotifyProcessHandler,
+ BiosKeyboardPrivate,
+ &BiosKeyboardPrivate->KeyNotifyProcessEvent
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
+ goto Done;
+ }
+
//
// Report a Progress Code for an attempt to detect the precense of the keyboard device in the system
//
@@ -462,6 +477,11 @@ Done: if ((BiosKeyboardPrivate->SimpleTextInputEx).WaitForKeyEx != NULL) {
gBS->CloseEvent ((BiosKeyboardPrivate->SimpleTextInputEx).WaitForKeyEx);
}
+
+ if (BiosKeyboardPrivate->KeyNotifyProcessEvent != NULL) {
+ gBS->CloseEvent (BiosKeyboardPrivate->KeyNotifyProcessEvent);
+ }
+
BiosKeyboardFreeNotifyList (&BiosKeyboardPrivate->NotifyList);
if (BiosKeyboardPrivate->TimerEvent != NULL) {
@@ -566,6 +586,7 @@ BiosKeyboardDriverBindingStop ( gBS->CloseEvent ((BiosKeyboardPrivate->SimpleTextIn).WaitForKey);
gBS->CloseEvent (BiosKeyboardPrivate->TimerEvent);
gBS->CloseEvent (BiosKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx);
+ gBS->CloseEvent (BiosKeyboardPrivate->KeyNotifyProcessEvent);
BiosKeyboardFreeNotifyList (&BiosKeyboardPrivate->NotifyList);
FreePool (BiosKeyboardPrivate);
@@ -1941,7 +1962,7 @@ BiosKeyboardTimerHandler ( }
//
- // Invoke notification functions if exist
+ // Signal KeyNotify process event if this key pressed matches any key registered.
//
for (Link = BiosKeyboardPrivate->NotifyList.ForwardLink; Link != &BiosKeyboardPrivate->NotifyList; Link = Link->ForwardLink) {
CurrentNotify = CR (
@@ -1950,8 +1971,14 @@ BiosKeyboardTimerHandler ( NotifyEntry,
BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
- if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
- CurrentNotify->KeyNotificationFn (&KeyData);
+ if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
+ //
+ // The key notification function needs to run at TPL_CALLBACK
+ // while current TPL is TPL_NOTIFY. It will be invoked in
+ // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.
+ //
+ Enqueue (&BiosKeyboardPrivate->QueueForNotify, &KeyData);
+ gBS->SignalEvent (BiosKeyboardPrivate->KeyNotifyProcessEvent);
}
}
@@ -1965,6 +1992,55 @@ BiosKeyboardTimerHandler ( }
/**
+ Process key notify.
+
+ @param Event Indicates the event that invoke this function.
+ @param Context Indicates the calling context.
+**/
+VOID
+EFIAPI
+KeyNotifyProcessHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ BIOS_KEYBOARD_DEV *BiosKeyboardPrivate;
+ EFI_KEY_DATA KeyData;
+ LIST_ENTRY *Link;
+ LIST_ENTRY *NotifyList;
+ BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+ EFI_TPL OldTpl;
+
+ BiosKeyboardPrivate = (BIOS_KEYBOARD_DEV *) Context;
+
+ //
+ // Invoke notification functions.
+ //
+ NotifyList = &BiosKeyboardPrivate->NotifyList;
+ while (TRUE) {
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+ Status = Dequeue (&BiosKeyboardPrivate->QueueForNotify, &KeyData);
+ //
+ // Leave critical section
+ //
+ gBS->RestoreTPL (OldTpl);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {
+ CurrentNotify = CR (Link, BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
+ if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
+ CurrentNotify->KeyNotificationFn (&KeyData);
+ }
+ }
+ }
+}
+
+/**
Free keyboard notify list.
@param ListHead The list head
diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h index e83608659b..f38411aaa6 100644 --- a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h +++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h @@ -1,6 +1,6 @@ /** @file
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@@ -223,11 +223,13 @@ typedef struct { // Buffer storing EFI_KEY_DATA
//
SIMPLE_QUEUE Queue;
+ SIMPLE_QUEUE QueueForNotify;
//
// Notification Function List
//
LIST_ENTRY NotifyList;
+ EFI_EVENT KeyNotifyProcessEvent;
EFI_EVENT TimerEvent;
} BIOS_KEYBOARD_DEV;
@@ -555,6 +557,19 @@ BiosKeyboardTimerHandler ( );
/**
+ Process key notify.
+
+ @param Event Indicates the event that invoke this function.
+ @param Context Indicates the calling context.
+**/
+VOID
+EFIAPI
+KeyNotifyProcessHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
Reset the input device and optionaly run diagnostics
@param This Protocol instance pointer.
|