summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c12
-rw-r--r--MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c49
-rw-r--r--MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c20
-rw-r--r--MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h15
4 files changed, 94 insertions, 2 deletions
diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c
index eeb7de34ab..f92521046f 100644
--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c
+++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c
@@ -1420,7 +1420,7 @@ KeyGetchar (
}
//
- // Invoke notification functions if exist
+ // Signal KeyNotify process event if this key pressed matches any key registered.
//
for (Link = GetFirstNode (&ConsoleIn->NotifyList); !IsNull (&ConsoleIn->NotifyList, Link); Link = GetNextNode (&ConsoleIn->NotifyList, Link)) {
CurrentNotify = CR (
@@ -1430,7 +1430,13 @@ KeyGetchar (
KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
- CurrentNotify->KeyNotificationFn (&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.
+ //
+ PushEfikeyBufTail (&ConsoleIn->EfiKeyQueueForNotify, &KeyData);
+ gBS->SignalEvent (ConsoleIn->KeyNotifyProcessEvent);
}
}
@@ -1629,6 +1635,8 @@ InitKeyboard (
ConsoleIn->ScancodeQueue.Tail = 0;
ConsoleIn->EfiKeyQueue.Head = 0;
ConsoleIn->EfiKeyQueue.Tail = 0;
+ ConsoleIn->EfiKeyQueueForNotify.Head = 0;
+ ConsoleIn->EfiKeyQueueForNotify.Tail = 0;
//
// Reset the status indicators
diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
index f6ccd9598f..bc58fe2f8c 100644
--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
+++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
@@ -681,3 +681,52 @@ Exit:
return Status;
}
+/**
+ 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;
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
+ EFI_KEY_DATA KeyData;
+ LIST_ENTRY *Link;
+ LIST_ENTRY *NotifyList;
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+ EFI_TPL OldTpl;
+
+ ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;
+
+ //
+ // Invoke notification functions.
+ //
+ NotifyList = &ConsoleIn->NotifyList;
+ while (TRUE) {
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+ Status = PopEfikeyBufHead (&ConsoleIn->EfiKeyQueueForNotify, &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, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
+ if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
+ CurrentNotify->KeyNotificationFn (&KeyData);
+ }
+ }
+ }
+}
+
diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c
index 4df1b890e6..6121d29fb7 100644
--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c
+++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c
@@ -351,6 +351,19 @@ KbdControllerDriverStart (
goto ErrorExit;
}
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ KeyNotifyProcessHandler,
+ ConsoleIn,
+ &ConsoleIn->KeyNotifyProcessEvent
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
+ goto ErrorExit;
+ }
+
REPORT_STATUS_CODE_WITH_DEVICE_PATH (
EFI_PROGRESS_CODE,
EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT,
@@ -430,6 +443,9 @@ ErrorExit:
if ((ConsoleIn != NULL) && (ConsoleIn->ConInEx.WaitForKeyEx != NULL)) {
gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
}
+ if ((ConsoleIn != NULL) && (ConsoleIn->KeyNotifyProcessEvent != NULL)) {
+ gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);
+ }
KbdFreeNotifyList (&ConsoleIn->NotifyList);
if ((ConsoleIn != NULL) && (ConsoleIn->ControllerNameTable != NULL)) {
FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
@@ -570,6 +586,10 @@ KbdControllerDriverStop (
gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
ConsoleIn->ConInEx.WaitForKeyEx = NULL;
}
+ if (ConsoleIn->KeyNotifyProcessEvent != NULL) {
+ gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);
+ ConsoleIn->KeyNotifyProcessEvent = NULL;
+ }
KbdFreeNotifyList (&ConsoleIn->NotifyList);
FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
gBS->FreePool (ConsoleIn);
diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h
index d0aecfb087..e41c1980fc 100644
--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h
+++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h
@@ -105,6 +105,7 @@ typedef struct {
//
SCAN_CODE_QUEUE ScancodeQueue;
EFI_KEY_QUEUE EfiKeyQueue;
+ EFI_KEY_QUEUE EfiKeyQueueForNotify;
//
// Error state
@@ -118,6 +119,7 @@ typedef struct {
// Notification Function List
//
LIST_ENTRY NotifyList;
+ EFI_EVENT KeyNotifyProcessEvent;
} KEYBOARD_CONSOLE_IN_DEV;
#define KEYBOARD_CONSOLE_IN_DEV_FROM_THIS(a) CR (a, KEYBOARD_CONSOLE_IN_DEV, ConIn, KEYBOARD_CONSOLE_IN_DEV_SIGNATURE)
@@ -269,6 +271,19 @@ KeyGetchar (
);
/**
+ 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
+ );
+
+/**
Perform 8042 controller and keyboard Initialization.
If ExtendedVerification is TRUE, do additional test for
the keyboard interface