X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FConsole%2FTerminalDxe%2FTerminalConIn.c;h=4ede41677493da9c72af5a37ac8cb175cb3b4567;hp=4b3eb370237499f882ca953c2f7dfbbddb3d8af3;hb=9d510e61fceee7b92955ef9a3c20343752d8ce3f;hpb=66aa04e4e3a0b84369cbb483a78c4113b619663a
diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
index 4b3eb37023..4ede416774 100644
--- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
+++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
@@ -1,120 +1,69 @@
-/**@file
+/** @file
Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol.
-
-Copyright (c) 2006 - 2007 Intel Corporation.
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+(C) Copyright 2014 Hewlett-Packard Development Company, L.P.
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+Copyright (C) 2016 Silicon Graphics, Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "Terminal.h"
-STATIC
+/**
+ Reads the next keystroke from the input device. The WaitForKey Event can
+ be used to test for existence of a keystroke via WaitForEvent () call.
+
+ @param TerminalDevice Terminal driver private structure
+ @param KeyData A pointer to a buffer that is filled in with the
+ keystroke state data for the key that was
+ pressed.
+
+ @retval EFI_SUCCESS The keystroke information was returned.
+ @retval EFI_NOT_READY There was no keystroke data available.
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.
+
+**/
EFI_STATUS
ReadKeyStrokeWorker (
IN TERMINAL_DEV *TerminalDevice,
OUT EFI_KEY_DATA *KeyData
)
-/*++
-
- Routine Description:
- Reads the next keystroke from the input device. The WaitForKey Event can
- be used to test for existance of a keystroke via WaitForEvent () call.
-
- Arguments:
- TerminalDevice - Terminal driver private structure
- KeyData - A pointer to a buffer that is filled in with the keystroke
- state data for the key that was pressed.
-
- Returns:
- EFI_SUCCESS - The keystroke information was returned.
- EFI_NOT_READY - There was no keystroke data availiable.
- EFI_DEVICE_ERROR - The keystroke information was not returned due to
- hardware errors.
- EFI_INVALID_PARAMETER - KeyData is NULL.
-
---*/
{
- EFI_STATUS Status;
- LIST_ENTRY *Link;
- TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
-
if (KeyData == NULL) {
return EFI_INVALID_PARAMETER;
- }
-
- //
- // Initialize *Key to nonsense value.
- //
- KeyData->Key.ScanCode = SCAN_NULL;
- KeyData->Key.UnicodeChar = 0;
-
- Status = TerminalConInCheckForKey (&TerminalDevice->SimpleInput);
- if (EFI_ERROR (Status)) {
- return EFI_NOT_READY;
- }
-
- if (!EfiKeyFiFoRemoveOneKey (TerminalDevice, &KeyData->Key)) {
- return EFI_NOT_READY;
}
KeyData->KeyState.KeyShiftState = 0;
KeyData->KeyState.KeyToggleState = 0;
- //
- // Invoke notification functions if exist
- //
- for (Link = TerminalDevice->NotifyList.ForwardLink; Link != &TerminalDevice->NotifyList; Link = Link->ForwardLink) {
- CurrentNotify = CR (
- Link,
- TERMINAL_CONSOLE_IN_EX_NOTIFY,
- NotifyEntry,
- TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
- );
- if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
- CurrentNotify->KeyNotificationFn (KeyData);
- }
+ if (!EfiKeyFiFoRemoveOneKey (TerminalDevice, &KeyData->Key)) {
+ return EFI_NOT_READY;
}
return EFI_SUCCESS;
}
+/**
+ Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset().
+ This driver only perform dependent serial device reset regardless of
+ the value of ExtendeVerification
+
+ @param This Indicates the calling context.
+ @param ExtendedVerification Skip by this driver.
+ @retval EFI_SUCCESS The reset operation succeeds.
+ @retval EFI_DEVICE_ERROR The dependent serial port reset fails.
+
+**/
EFI_STATUS
EFIAPI
TerminalConInReset (
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
-/*++
- Routine Description:
-
- Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset().
- This driver only perform dependent serial device reset regardless of
- the value of ExtendeVerification
-
- Arguments:
-
- This - Indicates the calling context.
-
- ExtendedVerification - Skip by this driver.
-
- Returns:
-
- EFI_SUCCESS
- The reset operation succeeds.
-
- EFI_DEVICE_ERROR
- The dependent serial port reset fails.
-
---*/
{
EFI_STATUS Status;
TERMINAL_DEV *TerminalDevice;
@@ -126,23 +75,24 @@ TerminalConInReset (
//
REPORT_STATUS_CODE_WITH_DEVICE_PATH (
EFI_PROGRESS_CODE,
- PcdGet32 (PcdStatusCodeValueRemoteConsoleReset),
+ (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_PC_RESET),
TerminalDevice->DevicePath
);
Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo);
//
- // clear all the internal buffer for keys
+ // Make all the internal buffer empty for keys
//
- InitializeRawFiFo (TerminalDevice);
- InitializeUnicodeFiFo (TerminalDevice);
- InitializeEfiKeyFiFo (TerminalDevice);
+ TerminalDevice->RawFiFo->Head = TerminalDevice->RawFiFo->Tail;
+ TerminalDevice->UnicodeFiFo->Head = TerminalDevice->UnicodeFiFo->Tail;
+ TerminalDevice->EfiKeyFiFo->Head = TerminalDevice->EfiKeyFiFo->Tail;
+ TerminalDevice->EfiKeyFiFoForNotify->Head = TerminalDevice->EfiKeyFiFoForNotify->Tail;
if (EFI_ERROR (Status)) {
REPORT_STATUS_CODE_WITH_DEVICE_PATH (
EFI_ERROR_CODE | EFI_ERROR_MINOR,
- PcdGet32 (PcdStatusCodeValueRemoteConsoleError),
+ (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_CONTROLLER_ERROR),
TerminalDevice->DevicePath
);
}
@@ -150,36 +100,25 @@ TerminalConInReset (
return Status;
}
+/**
+ Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke().
+
+ @param This Indicates the calling context.
+ @param Key A pointer to a buffer that is filled in with the
+ keystroke information for the key that was sent
+ from terminal.
+
+ @retval EFI_SUCCESS The keystroke information is returned successfully.
+ @retval EFI_NOT_READY There is no keystroke data available.
+ @retval EFI_DEVICE_ERROR The dependent serial device encounters error.
+
+**/
EFI_STATUS
EFIAPI
TerminalConInReadKeyStroke (
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
OUT EFI_INPUT_KEY *Key
)
-/*++
- Routine Description:
-
- Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke().
-
- Arguments:
-
- This - Indicates the calling context.
-
- Key - A pointer to a buffer that is filled in with the keystroke
- information for the key that was sent from terminal.
-
- Returns:
-
- EFI_SUCCESS
- The keystroke information is returned successfully.
-
- EFI_NOT_READY
- There is no keystroke data available.
-
- EFI_DEVICE_ERROR
- The dependent serial device encounters error.
-
---*/
{
TERMINAL_DEV *TerminalDevice;
EFI_STATUS Status;
@@ -201,97 +140,79 @@ TerminalConInReadKeyStroke (
}
+/**
+ Check if the key already has been registered.
+ If both RegsiteredData and InputData is NULL, then ASSERT().
+
+ @param RegsiteredData A pointer to a buffer that is filled in with the
+ keystroke state data for the key that was
+ registered.
+ @param InputData A pointer to a buffer that is filled in with the
+ keystroke state data for the key that was
+ pressed.
+
+ @retval TRUE Key be pressed matches a registered key.
+ @retval FALSE Match failed.
+
+**/
BOOLEAN
IsKeyRegistered (
IN EFI_KEY_DATA *RegsiteredData,
IN EFI_KEY_DATA *InputData
)
-/*++
-
-Routine Description:
-
-Arguments:
-
- RegsiteredData - A pointer to a buffer that is filled in with the keystroke
- state data for the key that was registered.
- InputData - A pointer to a buffer that is filled in with the keystroke
- state data for the key that was pressed.
-
-Returns:
- TRUE - Key be pressed matches a registered key.
- FLASE - Match failed.
-
---*/
{
ASSERT (RegsiteredData != NULL && InputData != NULL);
-
+
if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
(RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {
- return FALSE;
- }
-
+ return FALSE;
+ }
+
return TRUE;
}
+
+/**
+ Event notification function for EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event
+ Signal the event if there is key available
+
+ @param Event Indicates the event that invoke this function.
+ @param Context Indicates the calling context.
+
+**/
VOID
EFIAPI
TerminalConInWaitForKeyEx (
IN EFI_EVENT Event,
IN VOID *Context
)
-/*++
- Routine Description:
-
- Event notification function for EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event
- Signal the event if there is key available
-
- Arguments:
-
- Event - Indicates the event that invoke this function.
-
- Context - Indicates the calling context.
-
- Returns:
-
- N/A
-
---*/
{
- TERMINAL_DEV *TerminalDevice;
-
- TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (Context);
-
- TerminalConInWaitForKey (Event, &TerminalDevice->SimpleInput);
-
+ TerminalConInWaitForKey (Event, Context);
}
//
// Simple Text Input Ex protocol functions
//
+/**
+ Reset the input device and optionally run diagnostics
+
+ @param This Protocol instance pointer.
+ @param ExtendedVerification Driver may perform diagnostics on reset.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could
+ not be reset.
+
+**/
EFI_STATUS
EFIAPI
TerminalConInResetEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
-/*++
-
- Routine Description:
- Reset the input device and optionaly run diagnostics
-
- Arguments:
- This - Protocol instance pointer.
- ExtendedVerification - Driver may perform diagnostics on reset.
-
- Returns:
- EFI_SUCCESS - The device was reset.
- EFI_DEVICE_ERROR - The device is not functioning properly and could
- not be reset.
-
---*/
{
EFI_STATUS Status;
TERMINAL_DEV *TerminalDevice;
@@ -304,40 +225,38 @@ TerminalConInResetEx (
}
return EFI_SUCCESS;
-
+
}
+
+/**
+ Reads the next keystroke from the input device. The WaitForKey Event can
+ be used to test for existence of a keystroke via WaitForEvent () call.
+
+ @param This Protocol instance pointer.
+ @param KeyData A pointer to a buffer that is filled in with the
+ keystroke state data for the key that was
+ pressed.
+
+ @retval EFI_SUCCESS The keystroke information was returned.
+ @retval EFI_NOT_READY There was no keystroke data available.
+ @retval EFI_DEVICE_ERROR The keystroke information was not returned due
+ to hardware errors.
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.
+
+**/
EFI_STATUS
EFIAPI
TerminalConInReadKeyStrokeEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
OUT EFI_KEY_DATA *KeyData
)
-/*++
-
- Routine Description:
- Reads the next keystroke from the input device. The WaitForKey Event can
- be used to test for existance of a keystroke via WaitForEvent () call.
-
- Arguments:
- This - Protocol instance pointer.
- KeyData - A pointer to a buffer that is filled in with the keystroke
- state data for the key that was pressed.
-
- Returns:
- EFI_SUCCESS - The keystroke information was returned.
- EFI_NOT_READY - There was no keystroke data availiable.
- EFI_DEVICE_ERROR - The keystroke information was not returned due to
- hardware errors.
- EFI_INVALID_PARAMETER - KeyData is NULL.
-
---*/
{
TERMINAL_DEV *TerminalDevice;
if (KeyData == NULL) {
return EFI_INVALID_PARAMETER;
- }
+ }
TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This);
@@ -345,71 +264,77 @@ TerminalConInReadKeyStrokeEx (
}
+
+/**
+ Set certain state for the input device.
+
+ @param This Protocol instance pointer.
+ @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
+ state for the input device.
+
+ @retval EFI_SUCCESS The device state was set successfully.
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly and
+ could not have the setting adjusted.
+ @retval EFI_UNSUPPORTED The device does not have the ability to set its
+ state.
+ @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
+
+**/
EFI_STATUS
EFIAPI
TerminalConInSetState (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_TOGGLE_STATE *KeyToggleState
)
-/*++
-
- Routine Description:
- Set certain state for the input device.
-
- Arguments:
- This - Protocol instance pointer.
- KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the
- state for the input device.
-
- Returns:
- EFI_SUCCESS - The device state was set successfully.
- EFI_DEVICE_ERROR - The device is not functioning correctly and could
- not have the setting adjusted.
- EFI_UNSUPPORTED - The device does not have the ability to set its state.
- EFI_INVALID_PARAMETER - KeyToggleState is NULL.
-
---*/
{
if (KeyToggleState == NULL) {
return EFI_INVALID_PARAMETER;
}
+ if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {
+ return EFI_UNSUPPORTED;
+ }
+
return EFI_SUCCESS;
}
+
+/**
+ Register a notification function for a particular keystroke for the input device.
+
+ @param This Protocol instance pointer.
+ @param KeyData A pointer to a buffer that is filled in with
+ the keystroke information for the key that was
+ pressed. If KeyData.Key, KeyData.KeyState.KeyToggleState
+ and KeyData.KeyState.KeyShiftState are 0, then any incomplete
+ keystroke will trigger a notification of the KeyNotificationFunction.
+ @param KeyNotificationFunction Points to the function to be called when the key
+ sequence is typed specified by KeyData. This notification function
+ should be called at <=TPL_CALLBACK.
+ @param NotifyHandle Points to the unique handle assigned to the
+ registered notification.
+
+ @retval EFI_SUCCESS The notification function was registered
+ successfully.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necessary data
+ structures.
+ @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL.
+
+**/
EFI_STATUS
EFIAPI
TerminalConInRegisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_DATA *KeyData,
IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
- OUT EFI_HANDLE *NotifyHandle
+ OUT VOID **NotifyHandle
)
-/*++
-
- Routine Description:
- Register a notification function for a particular keystroke for the input device.
-
- Arguments:
- This - Protocol instance pointer.
- KeyData - A pointer to a buffer that is filled in with the keystroke
- information data for the key that was pressed.
- KeyNotificationFunction - Points to the function to be called when the key
- sequence is typed specified by KeyData.
- NotifyHandle - Points to the unique handle assigned to the registered notification.
-
- Returns:
- EFI_SUCCESS - The notification function was registered successfully.
- EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures.
- EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.
-
---*/
{
- EFI_STATUS Status;
TERMINAL_DEV *TerminalDevice;
TERMINAL_CONSOLE_IN_EX_NOTIFY *NewNotify;
LIST_ENTRY *Link;
- TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+ LIST_ENTRY *NotifyList;
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {
return EFI_INVALID_PARAMETER;
@@ -420,16 +345,17 @@ TerminalConInRegisterKeyNotify (
//
// Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
//
- for (Link = TerminalDevice->NotifyList.ForwardLink; Link != &TerminalDevice->NotifyList; Link = Link->ForwardLink) {
+ NotifyList = &TerminalDevice->NotifyList;
+ for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) {
CurrentNotify = CR (
- Link,
- TERMINAL_CONSOLE_IN_EX_NOTIFY,
- NotifyEntry,
+ Link,
+ TERMINAL_CONSOLE_IN_EX_NOTIFY,
+ NotifyEntry,
TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
- if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
+ if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
- *NotifyHandle = CurrentNotify->NotifyHandle;
+ *NotifyHandle = CurrentNotify;
return EFI_SUCCESS;
}
}
@@ -437,124 +363,101 @@ TerminalConInRegisterKeyNotify (
//
// Allocate resource to save the notification function
- //
+ //
NewNotify = (TERMINAL_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (TERMINAL_CONSOLE_IN_EX_NOTIFY));
if (NewNotify == NULL) {
return EFI_OUT_OF_RESOURCES;
- }
+ }
- NewNotify->Signature = TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE;
+ NewNotify->Signature = TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE;
NewNotify->KeyNotificationFn = KeyNotificationFunction;
- CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));
+ CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));
InsertTailList (&TerminalDevice->NotifyList, &NewNotify->NotifyEntry);
- //
- // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE
- //
- Status = gBS->InstallMultipleProtocolInterfaces (
- &NewNotify->NotifyHandle,
- &gSimpleTextInExNotifyGuid,
- NULL,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
- *NotifyHandle = NewNotify->NotifyHandle;
+
+ *NotifyHandle = NewNotify;
return EFI_SUCCESS;
}
+
+/**
+ Remove a registered notification function from a particular keystroke.
+
+ @param This Protocol instance pointer.
+ @param NotificationHandle The handle of the notification function being
+ unregistered.
+
+ @retval EFI_SUCCESS The notification function was unregistered
+ successfully.
+ @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
+
+**/
EFI_STATUS
EFIAPI
TerminalConInUnregisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- IN EFI_HANDLE NotificationHandle
+ IN VOID *NotificationHandle
)
-/*++
-
- Routine Description:
- Remove a registered notification function from a particular keystroke.
-
- Arguments:
- This - Protocol instance pointer.
- NotificationHandle - The handle of the notification function being unregistered.
-
- Returns:
- EFI_SUCCESS - The notification function was unregistered successfully.
- EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
- EFI_NOT_FOUND - Can not find the matching entry in database.
-
---*/
{
- EFI_STATUS Status;
TERMINAL_DEV *TerminalDevice;
LIST_ENTRY *Link;
TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+ LIST_ENTRY *NotifyList;
if (NotificationHandle == NULL) {
return EFI_INVALID_PARAMETER;
- }
-
- Status = gBS->OpenProtocol (
- NotificationHandle,
- &gSimpleTextInExNotifyGuid,
- NULL,
- NULL,
- NULL,
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- return EFI_INVALID_PARAMETER;
}
TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This);
- for (Link = TerminalDevice->NotifyList.ForwardLink; Link != &TerminalDevice->NotifyList; Link = Link->ForwardLink) {
+ NotifyList = &TerminalDevice->NotifyList;
+ for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) {
CurrentNotify = CR (
- Link,
- TERMINAL_CONSOLE_IN_EX_NOTIFY,
- NotifyEntry,
+ Link,
+ TERMINAL_CONSOLE_IN_EX_NOTIFY,
+ NotifyEntry,
TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
- if (CurrentNotify->NotifyHandle == NotificationHandle) {
+ if (CurrentNotify == NotificationHandle) {
//
// Remove the notification function from NotifyList and free resources
//
- RemoveEntryList (&CurrentNotify->NotifyEntry);
- Status = gBS->UninstallMultipleProtocolInterfaces (
- CurrentNotify->NotifyHandle,
- &gSimpleTextInExNotifyGuid,
- NULL,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
- gBS->FreePool (CurrentNotify);
+ RemoveEntryList (&CurrentNotify->NotifyEntry);
+
+ gBS->FreePool (CurrentNotify);
return EFI_SUCCESS;
}
}
-
- return EFI_NOT_FOUND;
+
+ //
+ // Can not find the matching entry in database.
+ //
+ return EFI_INVALID_PARAMETER;
}
+/**
+ Translate raw data into Unicode (according to different encode), and
+ translate Unicode into key information. (according to different standard).
+
+ @param TerminalDevice Terminal driver private structure.
+**/
VOID
TranslateRawDataToEfiKey (
IN TERMINAL_DEV *TerminalDevice
)
-/*++
- Step1: Turn raw data into Unicode (according to different encode).
- Step2: Translate Unicode into key information.
- (according to different terminal standard).
---*/
{
switch (TerminalDevice->TerminalType) {
- case PcAnsiType:
- case VT100Type:
- case VT100PlusType:
+ case TerminalTypePcAnsi:
+ case TerminalTypeVt100:
+ case TerminalTypeVt100Plus:
+ case TerminalTypeTtyTerm:
AnsiRawDataToUnicode (TerminalDevice);
UnicodeToEfiKey (TerminalDevice);
break;
- case VTUTF8Type:
+ case TerminalTypeVtUtf8:
//
// Process all the raw data in the RawFIFO,
// put the processed key into UnicodeFIFO.
@@ -571,66 +474,43 @@ TranslateRawDataToEfiKey (
}
}
+/**
+ Event notification function for EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey event
+ Signal the event if there is key available
+
+ @param Event Indicates the event that invoke this function.
+ @param Context Indicates the calling context.
+
+**/
VOID
EFIAPI
TerminalConInWaitForKey (
IN EFI_EVENT Event,
IN VOID *Context
)
-/*++
- Routine Description:
-
- Event notification function for EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey event
- Signal the event if there is key available
-
- Arguments:
-
- Event - Indicates the event that invoke this function.
-
- Context - Indicates the calling context.
-
- Returns:
-
- N/A
-
---*/
{
//
// Someone is waiting on the keystroke event, if there's
// a key pending, signal the event
//
- // Context is the pointer to EFI_SIMPLE_TEXT_INPUT_PROTOCOL
- //
- if (!EFI_ERROR (TerminalConInCheckForKey (Context))) {
+ if (!IsEfiKeyFiFoEmpty ((TERMINAL_DEV *) Context)) {
gBS->SignalEvent (Event);
}
}
-EFI_STATUS
-TerminalConInCheckForKey (
- IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This
+/**
+ Timer handler to poll the key from serial.
+
+ @param Event Indicates the event that invoke this function.
+ @param Context Indicates the calling context.
+**/
+VOID
+EFIAPI
+TerminalConInTimerHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
)
-/*++
- Routine Description:
-
- Check for a pending key in the Efi Key FIFO or Serial device buffer.
-
- Arguments:
-
- This - Indicates the calling context.
-
- Returns:
-
- EFI_SUCCESS
- There is key pending.
-
- EFI_NOT_READY
- There is no key pending.
-
- EFI_DEVICE_ERROR
-
---*/
{
EFI_STATUS Status;
TERMINAL_DEV *TerminalDevice;
@@ -640,11 +520,11 @@ TerminalConInCheckForKey (
EFI_SERIAL_IO_PROTOCOL *SerialIo;
UINTN SerialInTimeOut;
- TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (This);
+ TerminalDevice = (TERMINAL_DEV *) Context;
SerialIo = TerminalDevice->SerialIo;
if (SerialIo == NULL) {
- return EFI_DEVICE_ERROR;
+ return ;
}
//
// if current timeout value for serial device is not identical with
@@ -656,6 +536,9 @@ TerminalConInCheckForKey (
SerialInTimeOut = 0;
if (Mode->BaudRate != 0) {
+ //
+ // According to BAUD rate to calculate the timeout value.
+ //
SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate;
}
@@ -676,82 +559,123 @@ TerminalConInCheckForKey (
}
}
//
- // check whether serial buffer is empty
+ // Check whether serial buffer is empty.
+ // Skip the key transfer loop only if the SerialIo protocol instance
+ // successfully reports EFI_SERIAL_INPUT_BUFFER_EMPTY.
//
Status = SerialIo->GetControl (SerialIo, &Control);
-
- if (Control & EFI_SERIAL_INPUT_BUFFER_EMPTY) {
- //
- // Translate all the raw data in RawFIFO into EFI Key,
- // according to different terminal type supported.
+ if (EFI_ERROR (Status) || ((Control & EFI_SERIAL_INPUT_BUFFER_EMPTY) == 0)) {
//
- TranslateRawDataToEfiKey (TerminalDevice);
-
- //
- // if there is pre-fetched Efi Key in EfiKeyFIFO buffer,
- // return directly.
+ // Fetch all the keys in the serial buffer,
+ // and insert the byte stream into RawFIFO.
//
- if (!IsEfiKeyFiFoEmpty (TerminalDevice)) {
- return EFI_SUCCESS;
- } else {
- return EFI_NOT_READY;
- }
- }
- //
- // Fetch all the keys in the serial buffer,
- // and insert the byte stream into RawFIFO.
- //
- do {
+ while (!IsRawFiFoFull (TerminalDevice)) {
- Status = GetOneKeyFromSerial (TerminalDevice->SerialIo, &Input);
+ Status = GetOneKeyFromSerial (TerminalDevice->SerialIo, &Input);
- if (EFI_ERROR (Status)) {
- if (Status == EFI_DEVICE_ERROR) {
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- PcdGet32 (PcdStatusCodeValueRemoteConsoleInputError),
- TerminalDevice->DevicePath
- );
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_DEVICE_ERROR) {
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_INPUT_ERROR),
+ TerminalDevice->DevicePath
+ );
+ }
+ break;
}
- break;
- }
- RawFiFoInsertOneKey (TerminalDevice, Input);
- } while (TRUE);
+ RawFiFoInsertOneKey (TerminalDevice, Input);
+ }
+ }
//
// Translate all the raw data in RawFIFO into EFI Key,
// according to different terminal type supported.
//
TranslateRawDataToEfiKey (TerminalDevice);
+}
- if (IsEfiKeyFiFoEmpty (TerminalDevice)) {
- return EFI_NOT_READY;
- }
+/**
+ Process key notify.
- return EFI_SUCCESS;
+ @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
+ )
+{
+ BOOLEAN HasKey;
+ TERMINAL_DEV *TerminalDevice;
+ EFI_INPUT_KEY Key;
+ EFI_KEY_DATA KeyData;
+ LIST_ENTRY *Link;
+ LIST_ENTRY *NotifyList;
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+ EFI_TPL OldTpl;
+
+ TerminalDevice = (TERMINAL_DEV *) Context;
+
+ //
+ // Invoke notification functions.
+ //
+ NotifyList = &TerminalDevice->NotifyList;
+ while (TRUE) {
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+ HasKey = EfiKeyFiFoForNotifyRemoveOneKey (TerminalDevice->EfiKeyFiFoForNotify, &Key);
+ CopyMem (&KeyData.Key, &Key, sizeof (EFI_INPUT_KEY));
+ KeyData.KeyState.KeyShiftState = 0;
+ KeyData.KeyState.KeyToggleState = 0;
+ //
+ // Leave critical section
+ //
+ gBS->RestoreTPL (OldTpl);
+ if (!HasKey) {
+ break;
+ }
+ for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {
+ CurrentNotify = CR (Link, TERMINAL_CONSOLE_IN_EX_NOTIFY, NotifyEntry, TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
+ if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
+ CurrentNotify->KeyNotificationFn (&KeyData);
+ }
+ }
+ }
}
+/**
+ Get one key out of serial buffer.
+
+ @param SerialIo Serial I/O protocol attached to the serial device.
+ @param Output The fetched key.
+
+ @retval EFI_NOT_READY If serial buffer is empty.
+ @retval EFI_DEVICE_ERROR If reading serial buffer encounter error.
+ @retval EFI_SUCCESS If reading serial buffer successfully, put
+ the fetched key to the parameter output.
+
+**/
EFI_STATUS
GetOneKeyFromSerial (
EFI_SERIAL_IO_PROTOCOL *SerialIo,
- UINT8 *Input
+ UINT8 *Output
)
-/*++
- Get one key out of serial buffer.
- If serial buffer is empty, return EFI_NOT_READY;
- if reading serial buffer encounter error, returns EFI_DEVICE_ERROR;
- if reading serial buffer successfully, put the fetched key to
- the parameter "Input", and return EFI_SUCCESS.
---*/
{
EFI_STATUS Status;
UINTN Size;
Size = 1;
- *Input = 0;
+ *Output = 0;
- Status = SerialIo->Read (SerialIo, &Size, Input);
+ //
+ // Read one key from serial I/O device.
+ //
+ Status = SerialIo->Read (SerialIo, &Size, Output);
if (EFI_ERROR (Status)) {
@@ -763,27 +687,33 @@ GetOneKeyFromSerial (
}
- if (*Input == 0) {
+ if (*Output == 0) {
return EFI_NOT_READY;
}
return EFI_SUCCESS;
}
+/**
+ Insert one byte raw data into the Raw Data FIFO.
+
+ @param TerminalDevice Terminal driver private structure.
+ @param Input The key will be input.
+
+ @retval TRUE If insert successfully.
+ @retval FALSE If Raw Data buffer is full before key insertion,
+ and the key is lost.
+
+**/
BOOLEAN
RawFiFoInsertOneKey (
TERMINAL_DEV *TerminalDevice,
UINT8 Input
)
-/*++
- Insert one byte raw data into the Raw Data FIFO.
- If FIFO is FULL before data insertion,
- return FALSE, and the key is lost.
---*/
{
UINT8 Tail;
- Tail = TerminalDevice->RawFiFo.Tail;
+ Tail = TerminalDevice->RawFiFo->Tail;
if (IsRawFiFoFull (TerminalDevice)) {
//
@@ -792,27 +722,32 @@ RawFiFoInsertOneKey (
return FALSE;
}
- TerminalDevice->RawFiFo.Data[Tail] = Input;
+ TerminalDevice->RawFiFo->Data[Tail] = Input;
- TerminalDevice->RawFiFo.Tail = (UINT8) ((Tail + 1) % (RAW_FIFO_MAX_NUMBER + 1));
+ TerminalDevice->RawFiFo->Tail = (UINT8) ((Tail + 1) % (RAW_FIFO_MAX_NUMBER + 1));
return TRUE;
}
+/**
+ Remove one pre-fetched key out of the Raw Data FIFO.
+
+ @param TerminalDevice Terminal driver private structure.
+ @param Output The key will be removed.
+
+ @retval TRUE If insert successfully.
+ @retval FALSE If Raw Data FIFO buffer is empty before remove operation.
+
+**/
BOOLEAN
RawFiFoRemoveOneKey (
TERMINAL_DEV *TerminalDevice,
UINT8 *Output
)
-/*++
- Remove one byte raw data out of the Raw Data FIFO.
- If FIFO buffer is empty before remove operation,
- return FALSE.
---*/
{
UINT8 Head;
- Head = TerminalDevice->RawFiFo.Head;
+ Head = TerminalDevice->RawFiFo->Head;
if (IsRawFiFoEmpty (TerminalDevice)) {
//
@@ -822,41 +757,53 @@ RawFiFoRemoveOneKey (
return FALSE;
}
- *Output = TerminalDevice->RawFiFo.Data[Head];
+ *Output = TerminalDevice->RawFiFo->Data[Head];
- TerminalDevice->RawFiFo.Head = (UINT8) ((Head + 1) % (RAW_FIFO_MAX_NUMBER + 1));
+ TerminalDevice->RawFiFo->Head = (UINT8) ((Head + 1) % (RAW_FIFO_MAX_NUMBER + 1));
return TRUE;
}
+/**
+ Clarify whether Raw Data FIFO buffer is empty.
+
+ @param TerminalDevice Terminal driver private structure
+
+ @retval TRUE If Raw Data FIFO buffer is empty.
+ @retval FALSE If Raw Data FIFO buffer is not empty.
+
+**/
BOOLEAN
IsRawFiFoEmpty (
TERMINAL_DEV *TerminalDevice
)
-/*++
- Clarify whether FIFO buffer is empty.
---*/
{
- if (TerminalDevice->RawFiFo.Head == TerminalDevice->RawFiFo.Tail) {
+ if (TerminalDevice->RawFiFo->Head == TerminalDevice->RawFiFo->Tail) {
return TRUE;
} else {
return FALSE;
}
}
+/**
+ Clarify whether Raw Data FIFO buffer is full.
+
+ @param TerminalDevice Terminal driver private structure
+
+ @retval TRUE If Raw Data FIFO buffer is full.
+ @retval FALSE If Raw Data FIFO buffer is not full.
+
+**/
BOOLEAN
IsRawFiFoFull (
TERMINAL_DEV *TerminalDevice
)
-/*++
- Clarify whether FIFO buffer is full.
---*/
{
UINT8 Tail;
UINT8 Head;
- Tail = TerminalDevice->RawFiFo.Tail;
- Head = TerminalDevice->RawFiFo.Head;
+ Tail = TerminalDevice->RawFiFo->Tail;
+ Head = TerminalDevice->RawFiFo->Head;
if (((Tail + 1) % (RAW_FIFO_MAX_NUMBER + 1)) == Head) {
@@ -866,21 +813,177 @@ IsRawFiFoFull (
return FALSE;
}
+/**
+ Insert one pre-fetched key into the FIFO buffer.
+
+ @param EfiKeyFiFo Pointer to instance of EFI_KEY_FIFO.
+ @param Input The key will be input.
+
+ @retval TRUE If insert successfully.
+ @retval FALSE If FIFO buffer is full before key insertion,
+ and the key is lost.
+
+**/
+BOOLEAN
+EfiKeyFiFoForNotifyInsertOneKey (
+ EFI_KEY_FIFO *EfiKeyFiFo,
+ EFI_INPUT_KEY *Input
+ )
+{
+ UINT8 Tail;
+
+ Tail = EfiKeyFiFo->Tail;
+
+ if (IsEfiKeyFiFoForNotifyFull (EfiKeyFiFo)) {
+ //
+ // FIFO is full
+ //
+ return FALSE;
+ }
+
+ CopyMem (&EfiKeyFiFo->Data[Tail], Input, sizeof (EFI_INPUT_KEY));
+
+ EfiKeyFiFo->Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));
+
+ return TRUE;
+}
+
+/**
+ Remove one pre-fetched key out of the FIFO buffer.
+
+ @param EfiKeyFiFo Pointer to instance of EFI_KEY_FIFO.
+ @param Output The key will be removed.
+
+ @retval TRUE If remove successfully.
+ @retval FALSE If FIFO buffer is empty before remove operation.
+
+**/
+BOOLEAN
+EfiKeyFiFoForNotifyRemoveOneKey (
+ EFI_KEY_FIFO *EfiKeyFiFo,
+ EFI_INPUT_KEY *Output
+ )
+{
+ UINT8 Head;
+
+ Head = EfiKeyFiFo->Head;
+ ASSERT (Head < FIFO_MAX_NUMBER + 1);
+
+ if (IsEfiKeyFiFoForNotifyEmpty (EfiKeyFiFo)) {
+ //
+ // FIFO is empty
+ //
+ Output->ScanCode = SCAN_NULL;
+ Output->UnicodeChar = 0;
+ return FALSE;
+ }
+
+ CopyMem (Output, &EfiKeyFiFo->Data[Head], sizeof (EFI_INPUT_KEY));
+
+ EfiKeyFiFo->Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1));
+
+ return TRUE;
+}
+
+/**
+ Clarify whether FIFO buffer is empty.
+
+ @param EfiKeyFiFo Pointer to instance of EFI_KEY_FIFO.
+
+ @retval TRUE If FIFO buffer is empty.
+ @retval FALSE If FIFO buffer is not empty.
+
+**/
+BOOLEAN
+IsEfiKeyFiFoForNotifyEmpty (
+ EFI_KEY_FIFO *EfiKeyFiFo
+ )
+{
+ if (EfiKeyFiFo->Head == EfiKeyFiFo->Tail) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Clarify whether FIFO buffer is full.
+
+ @param EfiKeyFiFo Pointer to instance of EFI_KEY_FIFO.
+
+ @retval TRUE If FIFO buffer is full.
+ @retval FALSE If FIFO buffer is not full.
+
+**/
+BOOLEAN
+IsEfiKeyFiFoForNotifyFull (
+ EFI_KEY_FIFO *EfiKeyFiFo
+ )
+{
+ UINT8 Tail;
+ UINT8 Head;
+
+ Tail = EfiKeyFiFo->Tail;
+ Head = EfiKeyFiFo->Head;
+
+ if (((Tail + 1) % (FIFO_MAX_NUMBER + 1)) == Head) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Insert one pre-fetched key into the FIFO buffer.
+
+ @param TerminalDevice Terminal driver private structure.
+ @param Key The key will be input.
+
+ @retval TRUE If insert successfully.
+ @retval FALSE If FIFO buffer is full before key insertion,
+ and the key is lost.
+
+**/
BOOLEAN
EfiKeyFiFoInsertOneKey (
- TERMINAL_DEV *TerminalDevice,
- EFI_INPUT_KEY Key
+ TERMINAL_DEV *TerminalDevice,
+ EFI_INPUT_KEY *Key
)
-/*++
- Insert one pre-fetched key into the FIFO buffer.
- If FIFO buffer is FULL before key insertion,
- return FALSE, and the key is lost.
---*/
{
- UINT8 Tail;
+ UINT8 Tail;
+ LIST_ENTRY *Link;
+ LIST_ENTRY *NotifyList;
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+ EFI_KEY_DATA KeyData;
+
+ Tail = TerminalDevice->EfiKeyFiFo->Tail;
- Tail = TerminalDevice->EfiKeyFiFo.Tail;
+ CopyMem (&KeyData.Key, Key, sizeof (EFI_INPUT_KEY));
+ KeyData.KeyState.KeyShiftState = 0;
+ KeyData.KeyState.KeyToggleState = 0;
+ //
+ // Signal KeyNotify process event if this key pressed matches any key registered.
+ //
+ NotifyList = &TerminalDevice->NotifyList;
+ for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) {
+ CurrentNotify = CR (
+ Link,
+ TERMINAL_CONSOLE_IN_EX_NOTIFY,
+ NotifyEntry,
+ TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
+ );
+ 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.
+ //
+ EfiKeyFiFoForNotifyInsertOneKey (TerminalDevice->EfiKeyFiFoForNotify, Key);
+ gBS->SignalEvent (TerminalDevice->KeyNotifyProcessEvent);
+ break;
+ }
+ }
if (IsEfiKeyFiFoFull (TerminalDevice)) {
//
// Efi Key FIFO is full
@@ -888,27 +991,33 @@ EfiKeyFiFoInsertOneKey (
return FALSE;
}
- TerminalDevice->EfiKeyFiFo.Data[Tail] = Key;
+ CopyMem (&TerminalDevice->EfiKeyFiFo->Data[Tail], Key, sizeof (EFI_INPUT_KEY));
- TerminalDevice->EfiKeyFiFo.Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));
+ TerminalDevice->EfiKeyFiFo->Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));
return TRUE;
}
+/**
+ Remove one pre-fetched key out of the FIFO buffer.
+
+ @param TerminalDevice Terminal driver private structure.
+ @param Output The key will be removed.
+
+ @retval TRUE If insert successfully.
+ @retval FALSE If FIFO buffer is empty before remove operation.
+
+**/
BOOLEAN
EfiKeyFiFoRemoveOneKey (
TERMINAL_DEV *TerminalDevice,
EFI_INPUT_KEY *Output
)
-/*++
- Remove one pre-fetched key out of the FIFO buffer.
- If FIFO buffer is empty before remove operation,
- return FALSE.
---*/
{
UINT8 Head;
- Head = TerminalDevice->EfiKeyFiFo.Head;
+ Head = TerminalDevice->EfiKeyFiFo->Head;
+ ASSERT (Head < FIFO_MAX_NUMBER + 1);
if (IsEfiKeyFiFoEmpty (TerminalDevice)) {
//
@@ -919,41 +1028,53 @@ EfiKeyFiFoRemoveOneKey (
return FALSE;
}
- *Output = TerminalDevice->EfiKeyFiFo.Data[Head];
+ CopyMem (Output, &TerminalDevice->EfiKeyFiFo->Data[Head], sizeof (EFI_INPUT_KEY));
- TerminalDevice->EfiKeyFiFo.Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1));
+ TerminalDevice->EfiKeyFiFo->Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1));
return TRUE;
}
+/**
+ Clarify whether FIFO buffer is empty.
+
+ @param TerminalDevice Terminal driver private structure
+
+ @retval TRUE If FIFO buffer is empty.
+ @retval FALSE If FIFO buffer is not empty.
+
+**/
BOOLEAN
IsEfiKeyFiFoEmpty (
TERMINAL_DEV *TerminalDevice
)
-/*++
- Clarify whether FIFO buffer is empty.
---*/
{
- if (TerminalDevice->EfiKeyFiFo.Head == TerminalDevice->EfiKeyFiFo.Tail) {
+ if (TerminalDevice->EfiKeyFiFo->Head == TerminalDevice->EfiKeyFiFo->Tail) {
return TRUE;
} else {
return FALSE;
}
}
+/**
+ Clarify whether FIFO buffer is full.
+
+ @param TerminalDevice Terminal driver private structure
+
+ @retval TRUE If FIFO buffer is full.
+ @retval FALSE If FIFO buffer is not full.
+
+**/
BOOLEAN
IsEfiKeyFiFoFull (
TERMINAL_DEV *TerminalDevice
)
-/*++
- Clarify whether FIFO buffer is full.
---*/
{
UINT8 Tail;
UINT8 Head;
- Tail = TerminalDevice->EfiKeyFiFo.Tail;
- Head = TerminalDevice->EfiKeyFiFo.Head;
+ Tail = TerminalDevice->EfiKeyFiFo->Tail;
+ Head = TerminalDevice->EfiKeyFiFo->Head;
if (((Tail + 1) % (FIFO_MAX_NUMBER + 1)) == Head) {
@@ -963,20 +1084,28 @@ IsEfiKeyFiFoFull (
return FALSE;
}
+/**
+ Insert one pre-fetched key into the Unicode FIFO buffer.
+
+ @param TerminalDevice Terminal driver private structure.
+ @param Input The key will be input.
+
+ @retval TRUE If insert successfully.
+ @retval FALSE If Unicode FIFO buffer is full before key insertion,
+ and the key is lost.
+
+**/
BOOLEAN
UnicodeFiFoInsertOneKey (
TERMINAL_DEV *TerminalDevice,
UINT16 Input
)
-/*++
- Insert one pre-fetched key into the FIFO buffer.
- If FIFO buffer is FULL before key insertion,
- return FALSE, and the key is lost.
---*/
{
UINT8 Tail;
- Tail = TerminalDevice->UnicodeFiFo.Tail;
+ Tail = TerminalDevice->UnicodeFiFo->Tail;
+ ASSERT (Tail < FIFO_MAX_NUMBER + 1);
+
if (IsUnicodeFiFoFull (TerminalDevice)) {
//
@@ -985,71 +1114,78 @@ UnicodeFiFoInsertOneKey (
return FALSE;
}
- TerminalDevice->UnicodeFiFo.Data[Tail] = Input;
+ TerminalDevice->UnicodeFiFo->Data[Tail] = Input;
- TerminalDevice->UnicodeFiFo.Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));
+ TerminalDevice->UnicodeFiFo->Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));
return TRUE;
}
-BOOLEAN
+/**
+ Remove one pre-fetched key out of the Unicode FIFO buffer.
+ The caller should guarantee that Unicode FIFO buffer is not empty
+ by IsUnicodeFiFoEmpty ().
+
+ @param TerminalDevice Terminal driver private structure.
+ @param Output The key will be removed.
+
+**/
+VOID
UnicodeFiFoRemoveOneKey (
TERMINAL_DEV *TerminalDevice,
UINT16 *Output
)
-/*++
- Remove one pre-fetched key out of the FIFO buffer.
- If FIFO buffer is empty before remove operation,
- return FALSE.
---*/
{
UINT8 Head;
- Head = TerminalDevice->UnicodeFiFo.Head;
+ Head = TerminalDevice->UnicodeFiFo->Head;
+ ASSERT (Head < FIFO_MAX_NUMBER + 1);
- if (IsUnicodeFiFoEmpty (TerminalDevice)) {
- //
- // FIFO is empty
- //
- Output = NULL;
- return FALSE;
- }
+ *Output = TerminalDevice->UnicodeFiFo->Data[Head];
- *Output = TerminalDevice->UnicodeFiFo.Data[Head];
+ TerminalDevice->UnicodeFiFo->Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1));
+}
- TerminalDevice->UnicodeFiFo.Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1));
+/**
+ Clarify whether Unicode FIFO buffer is empty.
- return TRUE;
-}
+ @param TerminalDevice Terminal driver private structure
+
+ @retval TRUE If Unicode FIFO buffer is empty.
+ @retval FALSE If Unicode FIFO buffer is not empty.
+**/
BOOLEAN
IsUnicodeFiFoEmpty (
TERMINAL_DEV *TerminalDevice
)
-/*++
- Clarify whether FIFO buffer is empty.
---*/
{
- if (TerminalDevice->UnicodeFiFo.Head == TerminalDevice->UnicodeFiFo.Tail) {
+ if (TerminalDevice->UnicodeFiFo->Head == TerminalDevice->UnicodeFiFo->Tail) {
return TRUE;
} else {
return FALSE;
}
}
+/**
+ Clarify whether Unicode FIFO buffer is full.
+
+ @param TerminalDevice Terminal driver private structure
+
+ @retval TRUE If Unicode FIFO buffer is full.
+ @retval FALSE If Unicode FIFO buffer is not full.
+
+**/
BOOLEAN
IsUnicodeFiFoFull (
TERMINAL_DEV *TerminalDevice
)
-/*++
- Clarify whether FIFO buffer is full.
---*/
{
UINT8 Tail;
UINT8 Head;
- Tail = TerminalDevice->UnicodeFiFo.Tail;
- Head = TerminalDevice->UnicodeFiFo.Head;
+ Tail = TerminalDevice->UnicodeFiFo->Tail;
+ Head = TerminalDevice->UnicodeFiFo->Head;
if (((Tail + 1) % (FIFO_MAX_NUMBER + 1)) == Head) {
@@ -1059,62 +1195,60 @@ IsUnicodeFiFoFull (
return FALSE;
}
-UINT8
-UnicodeFiFoGetKeyCount (
- TERMINAL_DEV *TerminalDevice
- )
-{
- UINT8 Tail;
- UINT8 Head;
- Tail = TerminalDevice->UnicodeFiFo.Tail;
- Head = TerminalDevice->UnicodeFiFo.Head;
+/**
+ Update the Unicode characters from a terminal input device into EFI Keys FIFO.
- if (Tail >= Head) {
- return (UINT8) (Tail - Head);
- } else {
- return (UINT8) (Tail + FIFO_MAX_NUMBER + 1 - Head);
- }
-}
+ @param TerminalDevice The terminal device to use to translate raw input into EFI Keys
-STATIC
+**/
VOID
UnicodeToEfiKeyFlushState (
IN TERMINAL_DEV *TerminalDevice
)
{
EFI_INPUT_KEY Key;
+ UINT32 InputState;
+
+ InputState = TerminalDevice->InputState;
+
+ if (IsEfiKeyFiFoFull (TerminalDevice)) {
+ return;
+ }
- if (TerminalDevice->InputState & INPUT_STATE_ESC) {
+ if ((InputState & INPUT_STATE_ESC) != 0) {
Key.ScanCode = SCAN_ESC;
Key.UnicodeChar = 0;
- EfiKeyFiFoInsertOneKey (TerminalDevice, Key);
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
}
- if (TerminalDevice->InputState & INPUT_STATE_CSI) {
+ if ((InputState & INPUT_STATE_CSI) != 0) {
Key.ScanCode = SCAN_NULL;
Key.UnicodeChar = CSI;
- EfiKeyFiFoInsertOneKey (TerminalDevice, Key);
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
}
- if (TerminalDevice->InputState & INPUT_STATE_LEFTOPENBRACKET) {
+ if ((InputState & INPUT_STATE_LEFTOPENBRACKET) != 0) {
Key.ScanCode = SCAN_NULL;
Key.UnicodeChar = LEFTOPENBRACKET;
- EfiKeyFiFoInsertOneKey (TerminalDevice, Key);
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
}
- if (TerminalDevice->InputState & INPUT_STATE_O) {
+ if ((InputState & INPUT_STATE_O) != 0) {
Key.ScanCode = SCAN_NULL;
Key.UnicodeChar = 'O';
- EfiKeyFiFoInsertOneKey (TerminalDevice, Key);
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
}
- if (TerminalDevice->InputState & INPUT_STATE_2) {
+ if ((InputState & INPUT_STATE_2) != 0) {
Key.ScanCode = SCAN_NULL;
Key.UnicodeChar = '2';
- EfiKeyFiFoInsertOneKey (TerminalDevice, Key);
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
}
+ //
+ // Cancel the timer.
+ //
gBS->SetTimer (
TerminalDevice->TwoSecondTimeOut,
TimerCancel,
@@ -1124,87 +1258,85 @@ UnicodeToEfiKeyFlushState (
TerminalDevice->InputState = INPUT_STATE_DEFAULT;
}
+
+/**
+ Converts a stream of Unicode characters from a terminal input device into EFI Keys that
+ can be read through the Simple Input Protocol.
+
+ The table below shows the keyboard input mappings that this function supports.
+ If the ESC sequence listed in one of the columns is presented, then it is translated
+ into the corresponding EFI Scan Code. If a matching sequence is not found, then the raw
+ key strokes are converted into EFI Keys.
+
+ 2 seconds are allowed for an ESC sequence to be completed. If the ESC sequence is not
+ completed in 2 seconds, then the raw key strokes of the partial ESC sequence are
+ converted into EFI Keys.
+ There is one special input sequence that will force the system to reset.
+ This is ESC R ESC r ESC R.
+
+ Note: current implementation support terminal types include: PC ANSI, VT100+/VTUTF8, VT100.
+ The table below is not same with UEFI Spec 2.3 Appendix B Table 201(not support ANSI X3.64 /
+ DEC VT200-500 and extra support PC ANSI, VT100)since UEFI Table 201 is just an example.
+
+ Symbols used in table below
+ ===========================
+ ESC = 0x1B
+ CSI = 0x9B
+ DEL = 0x7f
+ ^ = CTRL
+
+ +=========+======+===========+==========+==========+
+ | | EFI | UEFI 2.0 | | |
+ | | Scan | | VT100+ | |
+ | KEY | Code | PC ANSI | VTUTF8 | VT100 |
+ +=========+======+===========+==========+==========+
+ | NULL | 0x00 | | | |
+ | UP | 0x01 | ESC [ A | ESC [ A | ESC [ A |
+ | DOWN | 0x02 | ESC [ B | ESC [ B | ESC [ B |
+ | RIGHT | 0x03 | ESC [ C | ESC [ C | ESC [ C |
+ | LEFT | 0x04 | ESC [ D | ESC [ D | ESC [ D |
+ | HOME | 0x05 | ESC [ H | ESC h | ESC [ H |
+ | END | 0x06 | ESC [ F | ESC k | ESC [ K |
+ | INSERT | 0x07 | ESC [ @ | ESC + | ESC [ @ |
+ | | | ESC [ L | | ESC [ L |
+ | DELETE | 0x08 | ESC [ X | ESC - | ESC [ P |
+ | PG UP | 0x09 | ESC [ I | ESC ? | ESC [ V |
+ | | | | | ESC [ ? |
+ | PG DOWN | 0x0A | ESC [ G | ESC / | ESC [ U |
+ | | | | | ESC [ / |
+ | F1 | 0x0B | ESC [ M | ESC 1 | ESC O P |
+ | F2 | 0x0C | ESC [ N | ESC 2 | ESC O Q |
+ | F3 | 0x0D | ESC [ O | ESC 3 | ESC O w |
+ | F4 | 0x0E | ESC [ P | ESC 4 | ESC O x |
+ | F5 | 0x0F | ESC [ Q | ESC 5 | ESC O t |
+ | F6 | 0x10 | ESC [ R | ESC 6 | ESC O u |
+ | F7 | 0x11 | ESC [ S | ESC 7 | ESC O q |
+ | F8 | 0x12 | ESC [ T | ESC 8 | ESC O r |
+ | F9 | 0x13 | ESC [ U | ESC 9 | ESC O p |
+ | F10 | 0x14 | ESC [ V | ESC 0 | ESC O M |
+ | Escape | 0x17 | ESC | ESC | ESC |
+ | F11 | 0x15 | | ESC ! | |
+ | F12 | 0x16 | | ESC @ | |
+ +=========+======+===========+==========+==========+
+
+ Special Mappings
+ ================
+ ESC R ESC r ESC R = Reset System
+
+ @param TerminalDevice The terminal device to use to translate raw input into EFI Keys
+
+**/
VOID
UnicodeToEfiKey (
IN TERMINAL_DEV *TerminalDevice
)
-/*++
- Routine Description:
-
- Converts a stream of Unicode characters from a terminal input device into EFI Keys that
- can be read through the Simple Input Protocol. The table below shows the keyboard
- input mappings that this function supports. If the ESC sequence listed in one of the
- columns is presented, then it is translated into the coorespoding EFI Scan Code. If a
- matching sequence is not found, then the raw key strokes are converted into EFI Keys.
-
- 2 seconds are allowed for an ESC sequence to be completed. If the ESC sequence is not
- completed in 2 seconds, then the raw key strokes of the partial ESC sequence are
- converted into EFI Keys.
-
- There is one special input sequence that will force the system to reset.
- This is ESC R ESC r ESC R.
-
- Arguments:
-
- TerminaDevice : The terminal device to use to translate raw input into EFI Keys
-
- Returns:
-
- None
-
-Symbols used in table below
-===========================
- ESC = 0x1B
- CSI = 0x9B
- DEL = 0x7f
- ^ = CTRL
-
-+=========+======+===========+==========+==========+
-| | EFI | EFI 1.10 | | |
-| | Scan | | VT100+ | |
-| KEY | Code | PC ANSI | VTUTF8 | VT100 |
-+=========+======+===========+==========+==========+
-| NULL | 0x00 | | | |
-| UP | 0x01 | ESC [ A | ESC [ A | ESC [ A |
-| DOWN | 0x02 | ESC [ B | ESC [ B | ESC [ B |
-| RIGHT | 0x03 | ESC [ C | ESC [ C | ESC [ C |
-| LEFT | 0x04 | ESC [ D | ESC [ D | ESC [ D |
-| HOME | 0x05 | ESC [ H | ESC h | ESC [ H |
-| END | 0x06 | ESC [ F | ESC k | ESC [ K |
-| INSERT | 0x07 | ESC [ @ | ESC + | ESC [ @ |
-| | | ESC [ L | | ESC [ L |
-| DELETE | 0x08 | ESC [ X | ESC - | ESC [ P |
-| PG UP | 0x09 | ESC [ I | ESC ? | ESC [ V |
-| | | | | ESC [ ? |
-| PG DOWN | 0x0A | ESC [ G | ESC / | ESC [ U |
-| | | | | ESC [ / |
-| F1 | 0x0B | ESC [ M | ESC 1 | ESC O P |
-| F2 | 0x0C | ESC [ N | ESC 2 | ESC O Q |
-| F3 | 0x0D | ESC [ O | ESC 3 | ESC O w |
-| F4 | 0x0E | ESC [ P | ESC 4 | ESC O x |
-| F5 | 0x0F | ESC [ Q | ESC 5 | ESC O t |
-| F6 | 0x10 | ESC [ R | ESC 6 | ESC O u |
-| F7 | 0x11 | ESC [ S | ESC 7 | ESC O q |
-| F8 | 0x12 | ESC [ T | ESC 8 | ESC O r |
-| F9 | 0x13 | ESC [ U | ESC 9 | ESC O p |
-| F10 | 0x14 | ESC [ V | ESC 0 | ESC O M |
-| Escape | 0x17 | ESC | ESC | ESC |
-| F11 | 0x15 | | ESC ! | |
-| F12 | 0x16 | | ESC @ | |
-+=========+======+===========+==========+==========+
-
-Special Mappings
-================
-ESC R ESC r ESC R = Reset System
-
---*/
{
EFI_STATUS Status;
EFI_STATUS TimerStatus;
UINT16 UnicodeChar;
EFI_INPUT_KEY Key;
BOOLEAN SetDefaultResetState;
-
+
TimerStatus = gBS->CheckEvent (TerminalDevice->TwoSecondTimeOut);
if (!EFI_ERROR (TimerStatus)) {
@@ -1212,11 +1344,11 @@ ESC R ESC r ESC R = Reset System
TerminalDevice->ResetState = RESET_STATE_DEFAULT;
}
- while (!IsUnicodeFiFoEmpty(TerminalDevice)) {
-
+ while (!IsUnicodeFiFoEmpty (TerminalDevice) && !IsEfiKeyFiFoFull (TerminalDevice)) {
+
if (TerminalDevice->InputState != INPUT_STATE_DEFAULT) {
//
- // Check to see if the 2 second timer has expired
+ // Check to see if the 2 seconds timer has expired
//
TimerStatus = gBS->CheckEvent (TerminalDevice->TwoSecondTimeOut);
if (!EFI_ERROR (TimerStatus)) {
@@ -1228,7 +1360,7 @@ ESC R ESC r ESC R = Reset System
//
// Fetch one Unicode character from the Unicode FIFO
//
- UnicodeFiFoRemoveOneKey (TerminalDevice,&UnicodeChar);
+ UnicodeFiFoRemoveOneKey (TerminalDevice, &UnicodeChar);
SetDefaultResetState = TRUE;
@@ -1245,94 +1377,95 @@ ESC R ESC r ESC R = Reset System
continue;
}
- if (UnicodeChar == 'O' && TerminalDevice->TerminalType == VT100Type) {
+ if (UnicodeChar == 'O' && (TerminalDevice->TerminalType == TerminalTypeVt100 ||
+ TerminalDevice->TerminalType == TerminalTypeTtyTerm)) {
TerminalDevice->InputState |= INPUT_STATE_O;
TerminalDevice->ResetState = RESET_STATE_DEFAULT;
continue;
}
Key.ScanCode = SCAN_NULL;
-
- if (TerminalDevice->TerminalType == VT100PlusType ||
- TerminalDevice->TerminalType == VTUTF8Type) {
+
+ if (TerminalDevice->TerminalType == TerminalTypeVt100Plus ||
+ TerminalDevice->TerminalType == TerminalTypeVtUtf8) {
switch (UnicodeChar) {
- case '1':
- Key.ScanCode = SCAN_F1;
+ case '1':
+ Key.ScanCode = SCAN_F1;
break;
- case '2':
- Key.ScanCode = SCAN_F2;
+ case '2':
+ Key.ScanCode = SCAN_F2;
break;
- case '3':
- Key.ScanCode = SCAN_F3;
+ case '3':
+ Key.ScanCode = SCAN_F3;
break;
- case '4':
- Key.ScanCode = SCAN_F4;
+ case '4':
+ Key.ScanCode = SCAN_F4;
break;
- case '5':
- Key.ScanCode = SCAN_F5;
+ case '5':
+ Key.ScanCode = SCAN_F5;
break;
- case '6':
- Key.ScanCode = SCAN_F6;
+ case '6':
+ Key.ScanCode = SCAN_F6;
break;
- case '7':
- Key.ScanCode = SCAN_F7;
+ case '7':
+ Key.ScanCode = SCAN_F7;
break;
- case '8':
- Key.ScanCode = SCAN_F8;
+ case '8':
+ Key.ScanCode = SCAN_F8;
break;
- case '9':
- Key.ScanCode = SCAN_F9;
+ case '9':
+ Key.ScanCode = SCAN_F9;
break;
- case '0':
- Key.ScanCode = SCAN_F10;
+ case '0':
+ Key.ScanCode = SCAN_F10;
break;
case '!':
Key.ScanCode = SCAN_F11;
break;
case '@':
Key.ScanCode = SCAN_F12;
- break;
- case 'h':
- Key.ScanCode = SCAN_HOME;
break;
- case 'k':
- Key.ScanCode = SCAN_END;
+ case 'h':
+ Key.ScanCode = SCAN_HOME;
break;
- case '+':
- Key.ScanCode = SCAN_INSERT;
+ case 'k':
+ Key.ScanCode = SCAN_END;
break;
- case '-':
- Key.ScanCode = SCAN_DELETE;
+ case '+':
+ Key.ScanCode = SCAN_INSERT;
break;
- case '/':
- Key.ScanCode = SCAN_PAGE_DOWN;
+ case '-':
+ Key.ScanCode = SCAN_DELETE;
break;
- case '?':
- Key.ScanCode = SCAN_PAGE_UP;
- break;
- default :
+ case '/':
+ Key.ScanCode = SCAN_PAGE_DOWN;
+ break;
+ case '?':
+ Key.ScanCode = SCAN_PAGE_UP;
+ break;
+ default :
break;
}
}
-
+
switch (UnicodeChar) {
- case 'R':
+ case 'R':
if (TerminalDevice->ResetState == RESET_STATE_DEFAULT) {
TerminalDevice->ResetState = RESET_STATE_ESC_R;
SetDefaultResetState = FALSE;
- } else if (TerminalDevice->ResetState == RESET_STATE_ESC_R_ESC_r) {
+ } else if (TerminalDevice->ResetState == RESET_STATE_ESC_R_ESC_R) {
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
}
Key.ScanCode = SCAN_NULL;
break;
- case 'r':
+ case 'r':
if (TerminalDevice->ResetState == RESET_STATE_ESC_R) {
- TerminalDevice->ResetState = RESET_STATE_ESC_R_ESC_r;
+ TerminalDevice->ResetState = RESET_STATE_ESC_R_ESC_R;
SetDefaultResetState = FALSE;
}
Key.ScanCode = SCAN_NULL;
break;
- default :
+ default :
break;
}
@@ -1342,7 +1475,7 @@ ESC R ESC r ESC R = Reset System
if (Key.ScanCode != SCAN_NULL) {
Key.UnicodeChar = 0;
- EfiKeyFiFoInsertOneKey (TerminalDevice,Key);
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
TerminalDevice->InputState = INPUT_STATE_DEFAULT;
UnicodeToEfiKeyFlushState (TerminalDevice);
continue;
@@ -1357,47 +1490,69 @@ ESC R ESC r ESC R = Reset System
TerminalDevice->ResetState = RESET_STATE_DEFAULT;
Key.ScanCode = SCAN_NULL;
-
- if (TerminalDevice->TerminalType == VT100Type) {
+
+ if (TerminalDevice->TerminalType == TerminalTypeVt100) {
switch (UnicodeChar) {
- case 'P':
- Key.ScanCode = SCAN_F1;
+ case 'P':
+ Key.ScanCode = SCAN_F1;
+ break;
+ case 'Q':
+ Key.ScanCode = SCAN_F2;
+ break;
+ case 'w':
+ Key.ScanCode = SCAN_F3;
+ break;
+ case 'x':
+ Key.ScanCode = SCAN_F4;
+ break;
+ case 't':
+ Key.ScanCode = SCAN_F5;
+ break;
+ case 'u':
+ Key.ScanCode = SCAN_F6;
break;
- case 'Q':
- Key.ScanCode = SCAN_F2;
+ case 'q':
+ Key.ScanCode = SCAN_F7;
break;
- case 'w':
- Key.ScanCode = SCAN_F3;
+ case 'r':
+ Key.ScanCode = SCAN_F8;
break;
- case 'x':
- Key.ScanCode = SCAN_F4;
+ case 'p':
+ Key.ScanCode = SCAN_F9;
break;
- case 't':
- Key.ScanCode = SCAN_F5;
+ case 'M':
+ Key.ScanCode = SCAN_F10;
break;
- case 'u':
- Key.ScanCode = SCAN_F6;
+ default :
break;
- case 'q':
- Key.ScanCode = SCAN_F7;
+ }
+ } else if (TerminalDevice->TerminalType == TerminalTypeTtyTerm) {
+ /* Also accept VT100 escape codes for F1-F4, HOME and END for TTY term */
+ switch (UnicodeChar) {
+ case 'P':
+ Key.ScanCode = SCAN_F1;
+ break;
+ case 'Q':
+ Key.ScanCode = SCAN_F2;
break;
- case 'r':
- Key.ScanCode = SCAN_F8;
+ case 'R':
+ Key.ScanCode = SCAN_F3;
break;
- case 'p':
- Key.ScanCode = SCAN_F9;
+ case 'S':
+ Key.ScanCode = SCAN_F4;
break;
- case 'M':
- Key.ScanCode = SCAN_F10;
+ case 'H':
+ Key.ScanCode = SCAN_HOME;
break;
- default :
+ case 'F':
+ Key.ScanCode = SCAN_END;
break;
}
}
if (Key.ScanCode != SCAN_NULL) {
Key.UnicodeChar = 0;
- EfiKeyFiFoInsertOneKey (TerminalDevice,Key);
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
TerminalDevice->InputState = INPUT_STATE_DEFAULT;
UnicodeToEfiKeyFlushState (TerminalDevice);
continue;
@@ -1408,134 +1563,154 @@ ESC R ESC r ESC R = Reset System
break;
case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET:
-
+
TerminalDevice->ResetState = RESET_STATE_DEFAULT;
-
+
Key.ScanCode = SCAN_NULL;
-
- if (TerminalDevice->TerminalType == PcAnsiType ||
- TerminalDevice->TerminalType == VT100Type ||
- TerminalDevice->TerminalType == VT100PlusType ||
- TerminalDevice->TerminalType == VTUTF8Type) {
+
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||
+ TerminalDevice->TerminalType == TerminalTypeVt100 ||
+ TerminalDevice->TerminalType == TerminalTypeVt100Plus ||
+ TerminalDevice->TerminalType == TerminalTypeVtUtf8 ||
+ TerminalDevice->TerminalType == TerminalTypeTtyTerm) {
switch (UnicodeChar) {
- case 'A':
- Key.ScanCode = SCAN_UP;
+ case 'A':
+ Key.ScanCode = SCAN_UP;
break;
- case 'B':
- Key.ScanCode = SCAN_DOWN;
+ case 'B':
+ Key.ScanCode = SCAN_DOWN;
break;
- case 'C':
- Key.ScanCode = SCAN_RIGHT;
+ case 'C':
+ Key.ScanCode = SCAN_RIGHT;
break;
- case 'D':
- Key.ScanCode = SCAN_LEFT;
+ case 'D':
+ Key.ScanCode = SCAN_LEFT;
break;
- case 'H':
- if (TerminalDevice->TerminalType == PcAnsiType ||
- TerminalDevice->TerminalType == VT100Type) {
- Key.ScanCode = SCAN_HOME;
+ case 'H':
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||
+ TerminalDevice->TerminalType == TerminalTypeVt100 ||
+ TerminalDevice->TerminalType == TerminalTypeTtyTerm) {
+ Key.ScanCode = SCAN_HOME;
}
break;
- case 'F':
- if (TerminalDevice->TerminalType == PcAnsiType) {
+ case 'F':
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||
+ TerminalDevice->TerminalType == TerminalTypeTtyTerm) {
Key.ScanCode = SCAN_END;
}
break;
- case 'K':
- if (TerminalDevice->TerminalType == VT100Type) {
- Key.ScanCode = SCAN_END;
+ case 'K':
+ if (TerminalDevice->TerminalType == TerminalTypeVt100) {
+ Key.ScanCode = SCAN_END;
}
break;
- case 'L':
- case '@':
- if (TerminalDevice->TerminalType == PcAnsiType ||
- TerminalDevice->TerminalType == VT100Type) {
- Key.ScanCode = SCAN_INSERT;
+ case 'L':
+ case '@':
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||
+ TerminalDevice->TerminalType == TerminalTypeVt100) {
+ Key.ScanCode = SCAN_INSERT;
}
break;
- case 'X':
- if (TerminalDevice->TerminalType == PcAnsiType) {
+ case 'X':
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
Key.ScanCode = SCAN_DELETE;
}
break;
- case 'P':
- if (TerminalDevice->TerminalType == VT100Type) {
- Key.ScanCode = SCAN_DELETE;
- } else if (TerminalDevice->TerminalType == PcAnsiType) {
+ case 'P':
+ if (TerminalDevice->TerminalType == TerminalTypeVt100) {
+ Key.ScanCode = SCAN_DELETE;
+ } else if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
Key.ScanCode = SCAN_F4;
}
break;
- case 'I':
- if (TerminalDevice->TerminalType == PcAnsiType) {
+ case 'I':
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
Key.ScanCode = SCAN_PAGE_UP;
}
- break;
- case 'V':
- if (TerminalDevice->TerminalType == PcAnsiType) {
+ break;
+ case 'V':
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
Key.ScanCode = SCAN_F10;
- }
- case '?':
- if (TerminalDevice->TerminalType == VT100Type) {
- Key.ScanCode = SCAN_PAGE_UP;
}
break;
- case 'G':
- if (TerminalDevice->TerminalType == PcAnsiType) {
+ case '?':
+ if (TerminalDevice->TerminalType == TerminalTypeVt100) {
+ Key.ScanCode = SCAN_PAGE_UP;
+ }
+ break;
+ case 'G':
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
Key.ScanCode = SCAN_PAGE_DOWN;
}
- break;
- case 'U':
- if (TerminalDevice->TerminalType == PcAnsiType) {
+ break;
+ case 'U':
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
Key.ScanCode = SCAN_F9;
}
- case '/':
- if (TerminalDevice->TerminalType == VT100Type) {
- Key.ScanCode = SCAN_PAGE_DOWN;
+ break;
+ case '/':
+ if (TerminalDevice->TerminalType == TerminalTypeVt100) {
+ Key.ScanCode = SCAN_PAGE_DOWN;
}
break;
- case 'M':
- if (TerminalDevice->TerminalType == PcAnsiType) {
+ case 'M':
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
Key.ScanCode = SCAN_F1;
}
- break;
- case 'N':
- if (TerminalDevice->TerminalType == PcAnsiType) {
+ break;
+ case 'N':
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
Key.ScanCode = SCAN_F2;
}
- break;
- case 'O':
- if (TerminalDevice->TerminalType == PcAnsiType) {
+ break;
+ case 'O':
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
Key.ScanCode = SCAN_F3;
}
- break;
- case 'Q':
- if (TerminalDevice->TerminalType == PcAnsiType) {
+ break;
+ case 'Q':
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
Key.ScanCode = SCAN_F5;
}
- break;
- case 'R':
- if (TerminalDevice->TerminalType == PcAnsiType) {
+ break;
+ case 'R':
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
Key.ScanCode = SCAN_F6;
}
- break;
- case 'S':
- if (TerminalDevice->TerminalType == PcAnsiType) {
+ break;
+ case 'S':
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
Key.ScanCode = SCAN_F7;
}
- break;
- case 'T':
- if (TerminalDevice->TerminalType == PcAnsiType) {
+ break;
+ case 'T':
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {
Key.ScanCode = SCAN_F8;
}
- break;
- default :
+ break;
+ default :
break;
}
}
+ /*
+ * The VT220 escape codes that the TTY terminal accepts all have
+ * numeric codes, and there are no ambiguous prefixes shared with
+ * other terminal types.
+ */
+ if (TerminalDevice->TerminalType == TerminalTypeTtyTerm &&
+ Key.ScanCode == SCAN_NULL &&
+ UnicodeChar >= '0' &&
+ UnicodeChar <= '9') {
+ TerminalDevice->TtyEscapeStr[0] = UnicodeChar;
+ TerminalDevice->TtyEscapeIndex = 1;
+ TerminalDevice->InputState |= INPUT_STATE_LEFTOPENBRACKET_2;
+ continue;
+ }
+
if (Key.ScanCode != SCAN_NULL) {
Key.UnicodeChar = 0;
- EfiKeyFiFoInsertOneKey (TerminalDevice,Key);
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
TerminalDevice->InputState = INPUT_STATE_DEFAULT;
UnicodeToEfiKeyFlushState (TerminalDevice);
continue;
@@ -1545,7 +1720,75 @@ ESC R ESC r ESC R = Reset System
break;
-
+
+ case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET | INPUT_STATE_LEFTOPENBRACKET_2:
+ /*
+ * Here we handle the VT220 escape codes that we accept. This
+ * state is only used by the TTY terminal type.
+ */
+ Key.ScanCode = SCAN_NULL;
+ if (TerminalDevice->TerminalType == TerminalTypeTtyTerm) {
+
+ if (UnicodeChar == '~' && TerminalDevice->TtyEscapeIndex <= 2) {
+ UINT16 EscCode;
+ TerminalDevice->TtyEscapeStr[TerminalDevice->TtyEscapeIndex] = 0; /* Terminate string */
+ EscCode = (UINT16) StrDecimalToUintn(TerminalDevice->TtyEscapeStr);
+ switch (EscCode) {
+ case 2:
+ Key.ScanCode = SCAN_INSERT;
+ break;
+ case 3:
+ Key.ScanCode = SCAN_DELETE;
+ break;
+ case 5:
+ Key.ScanCode = SCAN_PAGE_UP;
+ break;
+ case 6:
+ Key.ScanCode = SCAN_PAGE_DOWN;
+ break;
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ Key.ScanCode = SCAN_F1 + EscCode - 11;
+ break;
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ Key.ScanCode = SCAN_F6 + EscCode - 17;
+ break;
+ case 23:
+ case 24:
+ Key.ScanCode = SCAN_F11 + EscCode - 23;
+ break;
+ default:
+ break;
+ }
+ } else if (TerminalDevice->TtyEscapeIndex == 1){
+ /* 2 character escape code */
+ TerminalDevice->TtyEscapeStr[TerminalDevice->TtyEscapeIndex++] = UnicodeChar;
+ continue;
+ }
+ else {
+ DEBUG ((EFI_D_ERROR, "Unexpected state in escape2\n"));
+ }
+ }
+ TerminalDevice->ResetState = RESET_STATE_DEFAULT;
+
+ if (Key.ScanCode != SCAN_NULL) {
+ Key.UnicodeChar = 0;
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
+ TerminalDevice->InputState = INPUT_STATE_DEFAULT;
+ UnicodeToEfiKeyFlushState (TerminalDevice);
+ continue;
+ }
+
+ UnicodeToEfiKeyFlushState (TerminalDevice);
+ break;
+
default:
//
// Invalid state. This should never happen.
@@ -1564,7 +1807,7 @@ ESC R ESC r ESC R = Reset System
if (UnicodeChar == CSI) {
TerminalDevice->InputState = INPUT_STATE_CSI;
}
-
+
if (TerminalDevice->InputState != INPUT_STATE_DEFAULT) {
Status = gBS->SetTimer(
TerminalDevice->TwoSecondTimeOut,
@@ -1580,13 +1823,19 @@ ESC R ESC r ESC R = Reset System
}
if (UnicodeChar == DEL) {
- Key.ScanCode = SCAN_DELETE;
- Key.UnicodeChar = 0;
+ if (TerminalDevice->TerminalType == TerminalTypeTtyTerm) {
+ Key.ScanCode = SCAN_NULL;
+ Key.UnicodeChar = CHAR_BACKSPACE;
+ }
+ else {
+ Key.ScanCode = SCAN_DELETE;
+ Key.UnicodeChar = 0;
+ }
} else {
Key.ScanCode = SCAN_NULL;
Key.UnicodeChar = UnicodeChar;
}
- EfiKeyFiFoInsertOneKey (TerminalDevice,Key);
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
}
}