diff options
Diffstat (limited to 'EmbeddedPkg/SimpleTextInOutSerial')
-rw-r--r-- | EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOut.c | 671 | ||||
-rw-r--r-- | EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf | 56 |
2 files changed, 727 insertions, 0 deletions
diff --git a/EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOut.c b/EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOut.c new file mode 100644 index 0000000000..f491de6e95 --- /dev/null +++ b/EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOut.c @@ -0,0 +1,671 @@ +/** @file
+ Simple Console that sits on a SerialLib.
+
+ Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+
+ 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.
+
+**/
+
+/*
+ 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 @ | |
++=========+======+===========+==========+==========+
+
+*/
+
+#include <PiDxe.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/SerialPortLib.h>
+
+#include <Protocol/SerialIo.h>
+#include <Protocol/SimpleTextIn.h>
+#include <Protocol/SimpleTextOut.h>
+
+
+#define MODE0_COLUMN_COUNT 80
+#define MODE0_ROW_COUNT 25
+
+
+EFI_STATUS
+EFIAPI
+TextInReset(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+
+EFI_STATUS
+EFIAPI
+ReadKeyStroke(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+ );
+
+
+EFI_STATUS
+EFIAPI
+TextOutReset(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+CHAR8 *
+EFIAPI
+SafeUnicodeStrToAsciiStr (
+ IN CONST CHAR16 *Source,
+ OUT CHAR8 *Destination
+ );
+
+EFI_STATUS
+EFIAPI
+OutputString (
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String
+ );
+
+
+EFI_STATUS
+EFIAPI
+TestString (
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String
+ );
+
+
+EFI_STATUS
+EFIAPI
+QueryMode (
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNumber,
+ OUT UINTN *Columns,
+ OUT UINTN *Rows
+ );
+
+
+EFI_STATUS
+EFIAPI
+SetMode(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNumber
+ );
+
+
+EFI_STATUS
+EFIAPI
+SetAttribute(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Attribute
+ );
+
+
+EFI_STATUS
+EFIAPI
+ClearScreen (
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
+ );
+
+
+EFI_STATUS
+EFIAPI
+SetCursorPosition (
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Column,
+ IN UINTN Row
+ );
+
+
+EFI_STATUS
+EFIAPI
+EnableCursor (
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN Enable
+ );
+
+
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL mSimpleTextIn = {
+ TextInReset,
+ ReadKeyStroke,
+ NULL
+};
+
+ EFI_SIMPLE_TEXT_OUTPUT_MODE mSimpleTextOutMode = {
+ 1,
+ 0,
+ EFI_TEXT_ATTR( EFI_LIGHTGRAY, EFI_BLACK ),
+ 0,
+ 0,
+ TRUE
+};
+
+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL mSimpleTextOut = {
+ TextOutReset,
+ OutputString,
+ TestString,
+ QueryMode,
+ SetMode,
+ SetAttribute,
+ ClearScreen,
+ SetCursorPosition,
+ EnableCursor,
+ &mSimpleTextOutMode
+};
+
+ EFI_HANDLE mInstallHandle = NULL;
+
+
+
+BOOLEAN
+TextOutIsValidAscii (
+ IN CHAR16 Ascii
+ )
+{
+ //
+ // valid ASCII code lies in the extent of 0x20 - 0x7F
+ //
+ if ((Ascii >= 0x20) && (Ascii <= 0x7F)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+BOOLEAN
+TextOutIsValidEfiCntlChar (
+ IN CHAR16 Char
+ )
+{
+ //
+ // only support four control characters.
+ //
+ if (Char == CHAR_NULL ||
+ Char == CHAR_BACKSPACE ||
+ Char == CHAR_LINEFEED ||
+ Char == CHAR_CARRIAGE_RETURN ||
+ Char == CHAR_TAB ) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+VOID
+EFIAPI
+WaitForKeyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ if (SerialPortPoll ()) {
+ gBS->SignalEvent (Event);
+ }
+}
+
+
+EFI_STATUS
+EFIAPI
+TextInReset (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+ReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+ )
+{
+ CHAR8 Char;
+
+ SerialPortRead ((UINT8 *)&Char, 1);
+
+ //
+ // Check for ESC sequence. This code is not techincally correct VT100 code.
+ // An illegal ESC sequence represents an ESC and the characters that follow.
+ // This code will eat one or two chars after an escape. This is done to
+ // prevent some complex FIFOing of the data. It is good enough to get
+ // the arrow and delete keys working
+ //
+ Key->UnicodeChar = 0;
+ Key->ScanCode = SCAN_NULL;
+ if (Char == 0x1b) {
+ SerialPortRead ((UINT8 *)&Char, 1);
+ if (Char == '[') {
+ SerialPortRead ((UINT8 *)&Char, 1);
+ switch (Char) {
+ case 'A':
+ Key->ScanCode = SCAN_UP;
+ break;
+ case 'B':
+ Key->ScanCode = SCAN_DOWN;
+ break;
+ case 'C':
+ Key->ScanCode = SCAN_RIGHT;
+ break;
+ case 'D':
+ Key->ScanCode = SCAN_LEFT;
+ break;
+ case 'H':
+ Key->ScanCode = SCAN_HOME;
+ break;
+ case 'K':
+ case 'F': // PC ANSI
+ Key->ScanCode = SCAN_END;
+ break;
+ case '@':
+ case 'L':
+ Key->ScanCode = SCAN_INSERT;
+ break;
+ case 'P':
+ case 'X': // PC ANSI
+ Key->ScanCode = SCAN_DELETE;
+ break;
+ case 'U':
+ case '/':
+ case 'G': // PC ANSI
+ Key->ScanCode = SCAN_PAGE_DOWN;
+ break;
+ case 'V':
+ case '?':
+ case 'I': // PC ANSI
+ Key->ScanCode = SCAN_PAGE_UP;
+ break;
+
+ // PCANSI that does not conflict with VT100
+ case 'M':
+ Key->ScanCode = SCAN_F1;
+ break;
+ case 'N':
+ Key->ScanCode = SCAN_F2;
+ break;
+ case 'O':
+ Key->ScanCode = SCAN_F3;
+ break;
+ case 'Q':
+ Key->ScanCode = SCAN_F5;
+ break;
+ case 'R':
+ Key->ScanCode = SCAN_F6;
+ break;
+ case 'S':
+ Key->ScanCode = SCAN_F7;
+ break;
+ case 'T':
+ Key->ScanCode = SCAN_F8;
+ break;
+
+ default:
+ Key->UnicodeChar = Char;
+ break;
+ }
+ } else if (Char == '0') {
+ SerialPortRead ((UINT8 *)&Char, 1);
+ switch (Char) {
+ 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_F7;
+ break;
+ case 'r':
+ Key->ScanCode = SCAN_F8;
+ break;
+ case 'p':
+ Key->ScanCode = SCAN_F9;
+ break;
+ case 'm':
+ Key->ScanCode = SCAN_F10;
+ break;
+ default :
+ break;
+ }
+ }
+ } else if (Char < ' ') {
+ if ((Char == CHAR_BACKSPACE) ||
+ (Char == CHAR_TAB) ||
+ (Char == CHAR_LINEFEED) ||
+ (Char == CHAR_CARRIAGE_RETURN)) {
+ // Only let through EFI required control characters
+ Key->UnicodeChar = (CHAR16)Char;
+ }
+ } else if (Char == 0x7f) {
+ Key->ScanCode = SCAN_DELETE;
+ } else {
+ Key->UnicodeChar = (CHAR16)Char;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+TextOutReset (
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ EFI_STATUS Status;
+
+ This->SetAttribute(
+ This,
+ EFI_TEXT_ATTR(This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK)
+ );
+
+ Status = This->SetMode (This, 0);
+
+ return Status;
+}
+
+CHAR8 *
+EFIAPI
+SafeUnicodeStrToAsciiStr (
+ IN CONST CHAR16 *Source,
+ OUT CHAR8 *Destination
+ )
+{
+ CHAR8 *ReturnValue;
+
+ ASSERT (Destination != NULL);
+
+ //
+ // ASSERT if Source is long than PcdMaximumUnicodeStringLength.
+ // Length tests are performed inside StrLen().
+ //
+ ASSERT (StrSize (Source) != 0);
+
+ //
+ // Source and Destination should not overlap
+ //
+ ASSERT ((UINTN) ((CHAR16 *) Destination - Source) > StrLen (Source));
+ ASSERT ((UINTN) ((CHAR8 *) Source - Destination) > StrLen (Source));
+
+
+ ReturnValue = Destination;
+ while (*Source != '\0') {
+ //
+ // If any non-ascii characters in Source then replace it with '?'.
+ //
+ if (*Source < 0x80) {
+ *Destination = (CHAR8) *Source;
+ } else {
+ *Destination = '?';
+
+ //Surrogate pair check.
+ if ((*Source >= 0xD800) && (*Source <= 0xDFFF)) {
+ Source++;
+ }
+ }
+
+ Destination++;
+ Source++;
+ }
+
+ *Destination = '\0';
+
+ //
+ // ASSERT Original Destination is less long than PcdMaximumAsciiStringLength.
+ // Length tests are performed inside AsciiStrLen().
+ //
+ ASSERT (AsciiStrSize (ReturnValue) != 0);
+
+ return ReturnValue;
+}
+
+EFI_STATUS
+EFIAPI
+OutputString (
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String
+ )
+{
+ UINTN Size = StrLen(String) + 1;
+ CHAR8 *OutputString = AllocatePool(Size);
+
+ //If there is any non-ascii characters in String buffer then replace it with '?'
+ //Eventually, UnicodeStrToAsciiStr API should be fixed.
+ SafeUnicodeStrToAsciiStr(String, OutputString);
+ SerialPortWrite ((UINT8 *)OutputString, Size - 1);
+
+ FreePool(OutputString);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+TestString (
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String
+ )
+{
+ CHAR8 Character;
+
+ for ( ; *String != CHAR_NULL; String++) {
+ Character = (CHAR8)*String;
+ if (!(TextOutIsValidAscii (Character) || TextOutIsValidEfiCntlChar (Character))) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+QueryMode (
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNumber,
+ OUT UINTN *Columns,
+ OUT UINTN *Rows
+ )
+{
+ if (This->Mode->MaxMode > 1) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (ModeNumber == 0) {
+ *Columns = MODE0_COLUMN_COUNT;
+ *Rows = MODE0_ROW_COUNT;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
+EFIAPI
+SetMode (
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNumber
+ )
+{
+ if (ModeNumber != 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ This->Mode->Mode = 0;
+ This->ClearScreen (This);
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+SetAttribute(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Attribute
+ )
+{
+ This->Mode->Attribute = (INT32)Attribute;
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+ClearScreen (
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+
+ Status = This->SetCursorPosition (This, 0, 0);
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+SetCursorPosition (
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Column,
+ IN UINTN Row
+ )
+{
+ EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
+ EFI_STATUS Status;
+ UINTN MaxColumn;
+ UINTN MaxRow;
+
+ Mode = This->Mode;
+
+ Status = This->QueryMode(
+ This,
+ Mode->Mode,
+ &MaxColumn,
+ &MaxRow
+ );
+ if (EFI_ERROR(Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if ((Column >= MaxColumn) || (Row >= MaxRow)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Mode->CursorColumn = (INT32)Column;
+ Mode->CursorRow = (INT32)Row;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+EnableCursor (
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN Enable
+ )
+{
+ if (!Enable) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+SimpleTextInOutEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ WaitForKeyEvent,
+ NULL,
+ &mSimpleTextIn.WaitForKey
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->InstallMultipleProtocolInterfaces(
+ &mInstallHandle,
+ &gEfiSimpleTextInProtocolGuid, &mSimpleTextIn,
+ &gEfiSimpleTextOutProtocolGuid, &mSimpleTextOut,
+ NULL
+ );
+ if (!EFI_ERROR (Status)) {
+ gST->ConOut = &mSimpleTextOut;
+ gST->ConIn = &mSimpleTextIn;
+ }
+
+ return Status;
+}
diff --git a/EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf b/EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf new file mode 100644 index 0000000000..17821d62f7 --- /dev/null +++ b/EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf @@ -0,0 +1,56 @@ +#%HEADER%
+#/** @file
+#
+# Component discription file for Bds module
+#
+# Copyright (c) 2008, Intel Corporation. <BR>
+# 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.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SimpleTextInOutSerial
+ FILE_GUID = 6696936D-3637-467C-87CB-14EA8248948C
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = SimpleTextInOutEntryPoint
+
+
+[Sources.common]
+ SimpleTextInOut.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ ReportStatusCodeLib
+ MemoryAllocationLib
+ UefiLib
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ UefiDriverEntryPoint
+ SerialPortLib
+
+[Guids]
+
+
+[Protocols]
+ gEfiSimpleTextInProtocolGuid
+ gEfiSimpleTextOutProtocolGuid
+ gEfiSerialIoProtocolGuid
+ gEfiDevicePathProtocolGuid
+
+[depex]
+ TRUE
|