[edk2] [PATCH v2 edk2-platforms 09/20] Platform/Broadcom/RPi3: Add Graphic Console driver

Pete Batard pete at akeo.ie
Mon Dec 10 04:38:42 PST 2018


Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Pete Batard <pete at akeo.ie>
---
 Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/ComponentName.c             |  183 ++
 Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsole.c           | 1836 ++++++++++++++++++++
 Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsole.h           |  591 +++++++
 Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsoleDxe.inf      |   74 +
 Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsoleDxe.uni      |   19 +
 Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsoleDxeExtra.uni |   20 +
 Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/NewFont.c                   |  288 +++
 Platform/Broadcom/Bcm283x/Include/Protocol/ExtendedTextOut.h                     |   36 +
 8 files changed, 3047 insertions(+)

diff --git a/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/ComponentName.c b/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/ComponentName.c
new file mode 100644
index 000000000000..e5935b19a250
--- /dev/null
+++ b/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/ComponentName.c
@@ -0,0 +1,183 @@
+/** @file
+ *
+ *  Copyright (c) 2018, Andrei Warkentin <andrey.warkentin at gmail.com>
+ *  Copyright (c) 2006-2016, 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.
+ *
+ **/
+
+#include "GraphicsConsole.h"
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gGraphicsConsoleComponentName = {
+  GraphicsConsoleComponentNameGetDriverName,
+  GraphicsConsoleComponentNameGetControllerName,
+  "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gGraphicsConsoleComponentName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GraphicsConsoleComponentNameGetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) GraphicsConsoleComponentNameGetControllerName,
+  "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mGraphicsConsoleDriverNameTable[] = {
+  {
+    "eng;en",
+    (CHAR16 *)L"Graphics Console Driver"
+  },
+  {
+    NULL,
+    NULL
+  }
+};
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  )
+{
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mGraphicsConsoleDriverNameTable,
+           DriverName,
+           (BOOLEAN)(This == &gGraphicsConsoleComponentName)
+           );
+}
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  )
+{
+  return EFI_UNSUPPORTED;
+}
diff --git a/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsole.c b/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsole.c
new file mode 100644
index 000000000000..4df5b37e5d4f
--- /dev/null
+++ b/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsole.c
@@ -0,0 +1,1836 @@
+/** @file
+ *
+ *  Copyright (c) 2018, Andrei Warkentin <andrey.warkentin at gmail.com>
+ *  Copyright (c) 2006-2016, 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.
+ *
+ **/
+
+#include "GraphicsConsole.h"
+
+//
+// Graphics Console Device Private Data template
+//
+GRAPHICS_CONSOLE_DEV    mGraphicsConsoleDevTemplate = {
+  GRAPHICS_CONSOLE_DEV_SIGNATURE,
+  (EFI_GRAPHICS_OUTPUT_PROTOCOL *) NULL,
+  {
+    GraphicsConsoleConOutReset,
+    GraphicsConsoleConOutOutputString,
+    GraphicsConsoleConOutTestString,
+    GraphicsConsoleConOutQueryMode,
+    GraphicsConsoleConOutSetMode,
+    GraphicsConsoleConOutSetAttribute,
+    GraphicsConsoleConOutClearScreen,
+    GraphicsConsoleConOutSetCursorPosition,
+    GraphicsConsoleConOutEnableCursor,
+    (EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL
+  },
+  {
+    0,
+    -1,
+    EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_BLACK),
+    0,
+    0,
+    TRUE
+  },
+  (GRAPHICS_CONSOLE_MODE_DATA *) NULL,
+  (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,
+  {
+    (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *) NULL,
+    (EFI_GRAPHICS_OUTPUT_PROTOCOL *) NULL,
+    TRUE,
+  }
+};
+
+GRAPHICS_CONSOLE_MODE_DATA mGraphicsConsoleModeData[] = {
+  {100, 31},
+  //
+  // New modes can be added here.
+  // The last entry is specific for full screen mode.
+  //
+  {0, 0}
+};
+
+EFI_HII_DATABASE_PROTOCOL   *mHiiDatabase;
+EFI_HII_FONT_PROTOCOL       *mHiiFont;
+EFI_HII_HANDLE              mHiiHandle;
+VOID                        *mHiiRegistration;
+
+EFI_GUID             mFontPackageListGuid = {0xf5f219d3, 0x7006, 0x4648, {0xac, 0x8d, 0xd6, 0x1d, 0xfb, 0x7b, 0xc6, 0xad}};
+
+CHAR16               mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };
+
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL        mGraphicsEfiColors[16] = {
+  //
+  // B    G    R   reserved
+  //
+  {0x00, 0x00, 0x00, 0x00},  // BLACK
+  {0x98, 0x00, 0x00, 0x00},  // LIGHTBLUE
+  {0x00, 0x98, 0x00, 0x00},  // LIGHGREEN
+  {0x98, 0x98, 0x00, 0x00},  // LIGHCYAN
+  {0x00, 0x00, 0x98, 0x00},  // LIGHRED
+  {0x98, 0x00, 0x98, 0x00},  // MAGENTA
+  {0x00, 0x98, 0x98, 0x00},  // BROWN
+  {0x98, 0x98, 0x98, 0x00},  // LIGHTGRAY
+  {0x30, 0x30, 0x30, 0x00},  // DARKGRAY - BRIGHT BLACK
+  {0xff, 0x00, 0x00, 0x00},  // BLUE
+  {0x00, 0xff, 0x00, 0x00},  // LIME
+  {0xff, 0xff, 0x00, 0x00},  // CYAN
+  {0x00, 0x00, 0xff, 0x00},  // RED
+  {0xff, 0x00, 0xff, 0x00},  // FUCHSIA
+  {0x00, 0xff, 0xff, 0x00},  // YELLOW
+  {0xff, 0xff, 0xff, 0x00}   // WHITE
+};
+
+EFI_NARROW_GLYPH     mCursorGlyph = {
+  0x0000,
+  0x00,
+  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF }
+};
+
+CHAR16       SpaceStr[] = { NARROW_CHAR, ' ', 0 };
+
+EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBinding = {
+  GraphicsConsoleControllerDriverSupported,
+  GraphicsConsoleControllerDriverStart,
+  GraphicsConsoleControllerDriverStop,
+  0xa,
+  NULL,
+  NULL
+};
+
+/**
+  Test to see if Graphics Console could be supported on the Controller.
+
+  Graphics Console could be supported if Graphics Output Protocol
+  exists on the Controller.
+
+  @param  This                Protocol instance pointer.
+  @param  Controller          Handle of device to test.
+  @param  RemainingDevicePath Optional parameter use to pick a specific child
+                              device to start.
+
+  @retval EFI_SUCCESS         This driver supports this device.
+  @retval other               This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleControllerDriverSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  )
+{
+  EFI_STATUS                   Status;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+  EFI_DEVICE_PATH_PROTOCOL     *DevicePath;
+
+  GraphicsOutput = NULL;
+  //
+  // Open the IO Abstraction(s) needed to perform the supported test
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiGraphicsOutputProtocolGuid,
+                  (VOID **) &GraphicsOutput,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (GraphicsOutput != NULL);
+
+  //
+  // We need to ensure that we do not layer on top of a virtual handle.
+  // We need to ensure that the handles produced by the conspliter do not
+  // get used.
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **) &DevicePath,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (!EFI_ERROR (Status)) {
+    gBS->CloseProtocol (
+          Controller,
+          &gEfiDevicePathProtocolGuid,
+          This->DriverBindingHandle,
+          Controller
+          );
+  } else {
+    goto Error;
+  }
+
+  //
+  // Does Hii Exist?  If not, we aren't ready to run
+  //
+  Status = EfiLocateHiiProtocol ();
+
+  //
+  // Close the I/O Abstraction(s) used to perform the supported test
+  //
+Error:
+  gBS->CloseProtocol (
+                      Controller,
+                      &gEfiGraphicsOutputProtocolGuid,
+                      This->DriverBindingHandle,
+                      Controller
+                      );
+  return Status;
+}
+
+/**
+  Initialize all the text modes which the graphics console supports.
+
+  It returns information for available text modes that the graphics can support.
+
+  @param[in]  HorizontalResolution     The size of video screen in pixels in the X dimension.
+  @param[in]  VerticalResolution       The size of video screen in pixels in the Y dimension.
+  @param[in]  GopModeNumber            The graphics mode number which graphis console is based on.
+  @param[out] TextModeCount            The total number of text modes that graphics console supports.
+  @param[out] TextModeData             The buffer to the text modes column and row information.
+                                       Caller is responsible to free it when it's non-NULL.
+
+  @retval EFI_SUCCESS                  The supporting mode information is returned.
+  @retval EFI_INVALID_PARAMETER        The parameters are invalid.
+
+**/
+EFI_STATUS
+InitializeGraphicsConsoleTextMode (
+  IN UINT32                        HorizontalResolution,
+  IN UINT32                        VerticalResolution,
+  IN UINT32                        GopModeNumber,
+  OUT UINTN                        *TextModeCount,
+  OUT GRAPHICS_CONSOLE_MODE_DATA   **TextModeData
+  )
+{
+  UINTN                       Index;
+  UINTN                       Count;
+  GRAPHICS_CONSOLE_MODE_DATA  *ModeBuffer;
+  GRAPHICS_CONSOLE_MODE_DATA  *NewModeBuffer;
+  UINTN                       ValidCount;
+  UINTN                       ValidIndex;
+  UINTN                       MaxColumns;
+  UINTN                       MaxRows;
+
+  if ((TextModeCount == NULL) || (TextModeData == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Count = sizeof (mGraphicsConsoleModeData) / sizeof (GRAPHICS_CONSOLE_MODE_DATA);
+
+  //
+  // Compute the maximum number of text Rows and Columns that this current graphics mode can support.
+  // To make graphics console work well, MaxColumns and MaxRows should not be zero.
+  //
+  MaxColumns = HorizontalResolution / EFI_GLYPH_WIDTH;
+  MaxRows    = VerticalResolution / EFI_GLYPH_HEIGHT;
+
+  //
+  // According to UEFI spec, all output devices support at least 80x25 text mode.
+  //
+  ASSERT ((MaxColumns >= 80) && (MaxRows >= 25));
+
+  //
+  // Add full screen mode to the last entry.
+  //
+  mGraphicsConsoleModeData[Count - 1].Columns = MaxColumns;
+  mGraphicsConsoleModeData[Count - 1].Rows    = MaxRows;
+
+  //
+  // Get defined mode buffer pointer.
+  //
+  ModeBuffer = mGraphicsConsoleModeData;
+
+  //
+  // Here we make sure that the final mode exposed does not include the duplicated modes,
+  // and does not include the invalid modes which exceed the max column and row.
+  // Reserve 2 modes for 80x25, 80x50 of graphics console.
+  //
+  NewModeBuffer = AllocateZeroPool (sizeof (GRAPHICS_CONSOLE_MODE_DATA) * (Count + 2));
+  ASSERT (NewModeBuffer != NULL);
+
+  //
+  // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.
+  //
+  ValidCount = 0;
+
+  NewModeBuffer[ValidCount].Columns       = 80;
+  NewModeBuffer[ValidCount].Rows          = 25;
+  NewModeBuffer[ValidCount].GopWidth      = HorizontalResolution;
+  NewModeBuffer[ValidCount].GopHeight     = VerticalResolution;
+  NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;
+  NewModeBuffer[ValidCount].DeltaX        = (HorizontalResolution - (NewModeBuffer[ValidCount].Columns * EFI_GLYPH_WIDTH)) >> 1;
+  NewModeBuffer[ValidCount].DeltaY        = (VerticalResolution - (NewModeBuffer[ValidCount].Rows * EFI_GLYPH_HEIGHT)) >> 1;
+  ValidCount++;
+
+  if ((MaxColumns >= 80) && (MaxRows >= 50)) {
+    NewModeBuffer[ValidCount].Columns = 80;
+    NewModeBuffer[ValidCount].Rows    = 50;
+    NewModeBuffer[ValidCount].DeltaX  = (HorizontalResolution - (80 * EFI_GLYPH_WIDTH)) >> 1;
+    NewModeBuffer[ValidCount].DeltaY  = (VerticalResolution - (50 * EFI_GLYPH_HEIGHT)) >> 1;
+  }
+  NewModeBuffer[ValidCount].GopWidth      = HorizontalResolution;
+  NewModeBuffer[ValidCount].GopHeight     = VerticalResolution;
+  NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;
+  ValidCount++;
+
+  //
+  // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
+  //
+  for (Index = 0; Index < Count; Index++) {
+    if ((ModeBuffer[Index].Columns == 0) || (ModeBuffer[Index].Rows == 0) ||
+        (ModeBuffer[Index].Columns > MaxColumns) || (ModeBuffer[Index].Rows > MaxRows)) {
+      //
+      // Skip the pre-defined mode which is invalid or exceeds the max column and row.
+      //
+      continue;
+    }
+    for (ValidIndex = 0; ValidIndex < ValidCount; ValidIndex++) {
+      if ((ModeBuffer[Index].Columns == NewModeBuffer[ValidIndex].Columns) &&
+          (ModeBuffer[Index].Rows == NewModeBuffer[ValidIndex].Rows)) {
+        //
+        // Skip the duplicated mode.
+        //
+        break;
+      }
+    }
+    if (ValidIndex == ValidCount) {
+      NewModeBuffer[ValidCount].Columns       = ModeBuffer[Index].Columns;
+      NewModeBuffer[ValidCount].Rows          = ModeBuffer[Index].Rows;
+      NewModeBuffer[ValidCount].GopWidth      = HorizontalResolution;
+      NewModeBuffer[ValidCount].GopHeight     = VerticalResolution;
+      NewModeBuffer[ValidCount].GopModeNumber = GopModeNumber;
+      NewModeBuffer[ValidCount].DeltaX        = (HorizontalResolution - (NewModeBuffer[ValidCount].Columns * EFI_GLYPH_WIDTH)) >> 1;
+      NewModeBuffer[ValidCount].DeltaY        = (VerticalResolution - (NewModeBuffer[ValidCount].Rows * EFI_GLYPH_HEIGHT)) >> 1;
+      ValidCount++;
+    }
+  }
+
+  DEBUG_CODE (
+    for (Index = 0; Index < ValidCount; Index++) {
+      DEBUG ((DEBUG_INFO, "Graphics - Mode %d, Column = %d, Row = %d\n",
+                           Index, NewModeBuffer[Index].Columns, NewModeBuffer[Index].Rows));
+    }
+  );
+
+  //
+  // Return valid mode count and mode information buffer.
+  //
+  *TextModeCount = ValidCount;
+  *TextModeData  = NewModeBuffer;
+  return EFI_SUCCESS;
+}
+
+/**
+  Start this driver on Controller by opening Graphics Output Protocol,
+  and installing Simple Text Out protocol on Controller.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to bind driver to
+  @param  RemainingDevicePath  Optional parameter use to pick a specific child
+                               device to start.
+
+  @retval EFI_SUCCESS          This driver is added to Controller.
+  @retval other                This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleControllerDriverStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  )
+{
+  EFI_STATUS                           Status;
+  GRAPHICS_CONSOLE_DEV                 *Private;
+  UINT32                               HorizontalResolution;
+  UINT32                               VerticalResolution;
+  UINT32                               ModeIndex;
+  UINTN                                MaxMode;
+  UINT32                               ModeNumber;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE    *Mode;
+  UINTN                                SizeOfInfo;
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+
+  ModeNumber = 0;
+
+  //
+  // Initialize the Graphics Console device instance
+  //
+  Private = AllocateCopyPool (
+              sizeof (GRAPHICS_CONSOLE_DEV),
+              &mGraphicsConsoleDevTemplate
+              );
+  if (Private == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Private->SimpleTextOutput.Mode = &(Private->SimpleTextOutputMode);
+
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiGraphicsOutputProtocolGuid,
+                  (VOID **) &Private->GraphicsOutput,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+
+  Private->ExtendedTextOutput.TextOut = &(Private->SimpleTextOutput);
+  Private->ExtendedTextOutput.GraphicsOutput = Private->GraphicsOutput;
+
+  HorizontalResolution  = PcdGet32 (PcdVideoHorizontalResolution);
+  VerticalResolution    = PcdGet32 (PcdVideoVerticalResolution);
+
+  ASSERT (Private->GraphicsOutput != NULL);
+  //
+  // The console is build on top of Graphics Output Protocol, find the mode number
+  // for the user-defined mode; if there are multiple video devices,
+  // graphic console driver will set all the video devices to the same mode.
+  //
+  if ((HorizontalResolution == 0x0) || (VerticalResolution == 0x0)) {
+    //
+    // Find the highest resolution which GOP supports.
+    //
+    MaxMode = Private->GraphicsOutput->Mode->MaxMode;
+
+    for (ModeIndex = 0; ModeIndex < MaxMode; ModeIndex++) {
+      Status = Private->GraphicsOutput->QueryMode (
+                                                   Private->GraphicsOutput,
+                                                   ModeIndex,
+                                                   &SizeOfInfo,
+                                                   &Info
+                                                   );
+      if (!EFI_ERROR (Status)) {
+        if ((Info->HorizontalResolution > HorizontalResolution) ||
+            ((Info->HorizontalResolution == HorizontalResolution) && (Info->VerticalResolution > VerticalResolution))) {
+          HorizontalResolution = Info->HorizontalResolution;
+          VerticalResolution   = Info->VerticalResolution;
+          ModeNumber           = ModeIndex;
+        }
+        FreePool (Info);
+      }
+    }
+    if ((HorizontalResolution == 0x0) || (VerticalResolution == 0x0)) {
+      Status = EFI_UNSUPPORTED;
+      goto Error;
+    }
+  } else {
+    //
+    // Use user-defined resolution
+    //
+    Status = CheckModeSupported (
+                                 Private->GraphicsOutput,
+                                 HorizontalResolution,
+                                 VerticalResolution,
+                                 &ModeNumber
+                                 );
+    if (EFI_ERROR (Status)) {
+      //
+      // if not supporting current mode, try 800x600 which is required by UEFI/EFI spec.
+      //
+      HorizontalResolution = 800;
+      VerticalResolution   = 600;
+      Status = CheckModeSupported (
+                                   Private->GraphicsOutput,
+                                   HorizontalResolution,
+                                   VerticalResolution,
+                                   &ModeNumber
+                                   );
+      Mode = Private->GraphicsOutput->Mode;
+      if (EFI_ERROR (Status) && Mode->MaxMode != 0) {
+        //
+        // Set default mode failed or device don't support default mode, then get the current mode information.
+        //
+        HorizontalResolution = Mode->Info->HorizontalResolution;
+        VerticalResolution = Mode->Info->VerticalResolution;
+        ModeNumber = Mode->Mode;
+        }
+    }
+  }
+  if (ModeNumber != Private->GraphicsOutput->Mode->Mode) {
+    //
+    // Current graphics mode is not set or is not set to the mode which we has found,
+    // set the new graphic mode.
+    //
+    Status = Private->GraphicsOutput->SetMode (Private->GraphicsOutput, ModeNumber);
+    if (EFI_ERROR (Status)) {
+      //
+      // The mode set operation failed
+      //
+      goto Error;
+    }
+  }
+
+  DEBUG ((DEBUG_INFO, "GraphicsConsole video resolution %d x %d\n", HorizontalResolution, VerticalResolution));
+
+  //
+  // Initialize the mode which GraphicsConsole supports.
+  //
+  Status = InitializeGraphicsConsoleTextMode (
+             HorizontalResolution,
+             VerticalResolution,
+             ModeNumber,
+             &MaxMode,
+             &Private->ModeData
+             );
+
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+
+  //
+  // Update the maximum number of modes
+  //
+  Private->SimpleTextOutputMode.MaxMode = (INT32) MaxMode;
+
+  DEBUG_CODE_BEGIN ();
+    Status = GraphicsConsoleConOutSetMode (&Private->SimpleTextOutput, 0);
+    if (EFI_ERROR (Status)) {
+      goto Error;
+    }
+    Status = GraphicsConsoleConOutOutputString (&Private->SimpleTextOutput, (CHAR16 *)L"Graphics Console Started\n\r");
+    if (EFI_ERROR (Status)) {
+      goto Error;
+    }
+  DEBUG_CODE_END ();
+
+  //
+  // Install protocol interfaces for the Graphics Console device.
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Controller,
+                  &gEfiSimpleTextOutProtocolGuid,
+                  &Private->SimpleTextOutput,
+                  &gExtendedTextOutputProtocolGuid,
+                  &Private->ExtendedTextOutput,
+                  NULL
+                  );
+
+Error:
+  if (EFI_ERROR (Status)) {
+    //
+    // Close GOP.
+    //
+    gBS->CloseProtocol (
+                        Controller,
+                        &gEfiGraphicsOutputProtocolGuid,
+                        This->DriverBindingHandle,
+                        Controller
+                        );
+
+    if (Private->LineBuffer != NULL) {
+      FreePool (Private->LineBuffer);
+    }
+
+    if (Private->ModeData != NULL) {
+      FreePool (Private->ModeData);
+    }
+
+    //
+    // Free private data
+    //
+    FreePool (Private);
+  }
+
+  return Status;
+}
+
+/**
+  Stop this driver on Controller by removing Simple Text Out protocol
+  and closing the Graphics Output Protocol on Controller.
+
+
+  @param  This              Protocol instance pointer.
+  @param  Controller        Handle of device to stop driver on
+  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
+                            children is zero stop the entire bus driver.
+  @param  ChildHandleBuffer List of Child Handles to Stop.
+
+  @retval EFI_SUCCESS       This driver is removed Controller.
+  @retval EFI_NOT_STARTED   Simple Text Out protocol could not be found the
+                            Controller.
+  @retval other             This driver was not removed from this device.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleControllerDriverStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
+  IN  EFI_HANDLE                    Controller,
+  IN  UINTN                         NumberOfChildren,
+  IN  EFI_HANDLE                    *ChildHandleBuffer
+  )
+{
+  EFI_STATUS                       Status;
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *SimpleTextOutput;
+  GRAPHICS_CONSOLE_DEV             *Private;
+
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiSimpleTextOutProtocolGuid,
+                  (VOID **) &SimpleTextOutput,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_STARTED;
+  }
+
+  Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);
+
+  Status = gBS->UninstallMultipleProtocolInterfaces (
+                  Controller,
+                  &gEfiSimpleTextOutProtocolGuid,
+                  &Private->SimpleTextOutput,
+                  &gExtendedTextOutputProtocolGuid,
+                  &Private->ExtendedTextOutput,
+                  NULL
+                  );
+
+  if (!EFI_ERROR (Status)) {
+    //
+    // Close GOP.
+    //
+    gBS->CloseProtocol (
+                        Controller,
+                        &gEfiGraphicsOutputProtocolGuid,
+                        This->DriverBindingHandle,
+                        Controller
+                        );
+
+    if (Private->LineBuffer != NULL) {
+      FreePool (Private->LineBuffer);
+    }
+
+    if (Private->ModeData != NULL) {
+      FreePool (Private->ModeData);
+    }
+
+    //
+    // Free our instance data
+    //
+    FreePool (Private);
+  }
+
+  return Status;
+}
+
+/**
+  Check if the current specific mode supported the user defined resolution
+  for the Graphics Console device based on Graphics Output Protocol.
+
+  If yes, set the graphic devcice's current mode to this specific mode.
+
+  @param  GraphicsOutput        Graphics Output Protocol instance pointer.
+  @param  HorizontalResolution  User defined horizontal resolution
+  @param  VerticalResolution    User defined vertical resolution.
+  @param  CurrentModeNumber     Current specific mode to be check.
+
+  @retval EFI_SUCCESS       The mode is supported.
+  @retval EFI_UNSUPPORTED   The specific mode is out of range of graphics
+                            device supported.
+  @retval other             The specific mode does not support user defined
+                            resolution or failed to set the current mode to the
+                            specific mode on graphics device.
+
+**/
+EFI_STATUS
+CheckModeSupported (
+  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput,
+  IN  UINT32                    HorizontalResolution,
+  IN  UINT32                    VerticalResolution,
+  OUT UINT32                    *CurrentModeNumber
+  )
+{
+  UINT32     ModeNumber;
+  EFI_STATUS Status;
+  UINTN      SizeOfInfo;
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+  UINT32     MaxMode;
+
+  Status  = EFI_SUCCESS;
+  MaxMode = GraphicsOutput->Mode->MaxMode;
+
+  for (ModeNumber = 0; ModeNumber < MaxMode; ModeNumber++) {
+    Status = GraphicsOutput->QueryMode (
+                       GraphicsOutput,
+                       ModeNumber,
+                       &SizeOfInfo,
+                       &Info
+                       );
+    if (!EFI_ERROR (Status)) {
+      if ((Info->HorizontalResolution == HorizontalResolution) &&
+          (Info->VerticalResolution == VerticalResolution)) {
+        if ((GraphicsOutput->Mode->Info->HorizontalResolution == HorizontalResolution) &&
+            (GraphicsOutput->Mode->Info->VerticalResolution == VerticalResolution)) {
+          //
+          // If video device has been set to this mode, we do not need to SetMode again
+          //
+          FreePool (Info);
+          break;
+        } else {
+          Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
+          if (!EFI_ERROR (Status)) {
+            FreePool (Info);
+            break;
+          }
+        }
+      }
+      FreePool (Info);
+    }
+  }
+
+  if (ModeNumber == GraphicsOutput->Mode->MaxMode) {
+    Status = EFI_UNSUPPORTED;
+  }
+
+  *CurrentModeNumber = ModeNumber;
+  return Status;
+}
+
+
+/**
+  Locate HII Database protocol and HII Font protocol.
+
+  @retval  EFI_SUCCESS     HII Database protocol and HII Font protocol
+                           are located successfully.
+  @return  other           Failed to locate HII Database protocol or
+                           HII Font protocol.
+
+**/
+EFI_STATUS
+EfiLocateHiiProtocol (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &mHiiDatabase);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **) &mHiiFont);
+  return Status;
+}
+
+//
+// Body of the STO functions
+//
+
+/**
+  Reset the text output device hardware and optionally run diagnostics.
+
+  Implements SIMPLE_TEXT_OUTPUT.Reset().
+  If ExtendeVerification is TRUE, then perform dependent Graphics Console
+  device reset, and set display mode to mode 0.
+  If ExtendedVerification is FALSE, only set display mode to mode 0.
+
+  @param  This                  Protocol instance pointer.
+  @param  ExtendedVerification  Indicates that the driver may perform a more
+                                exhaustive verification operation of the device
+                                during reset.
+
+  @retval EFI_SUCCESS          The text output device was reset.
+  @retval EFI_DEVICE_ERROR     The text output device is not functioning correctly and
+                               could not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutReset (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  BOOLEAN                          ExtendedVerification
+  )
+{
+  EFI_STATUS    Status;
+  Status = This->SetMode (This, 0);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Status = This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));
+  return Status;
+}
+
+
+/**
+  Write a Unicode string to the output device.
+
+  Implements SIMPLE_TEXT_OUTPUT.OutputString().
+  The Unicode string will be converted to Glyphs and will be
+  sent to the Graphics Console.
+
+  @param  This                    Protocol instance pointer.
+  @param  WString                 The NULL-terminated Unicode string to be displayed
+                                  on the output device(s). All output devices must
+                                  also support the Unicode drawing defined in this file.
+
+  @retval EFI_SUCCESS             The string was output to the device.
+  @retval EFI_DEVICE_ERROR        The device reported an error while attempting to output
+                                  the text.
+  @retval EFI_UNSUPPORTED         The output device's mode is not currently in a
+                                  defined text mode.
+  @retval EFI_WARN_UNKNOWN_GLYPH  This warning code indicates that some of the
+                                  characters in the Unicode string could not be
+                                  rendered and were skipped.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutOutputString (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  CHAR16                           *WString
+  )
+{
+  GRAPHICS_CONSOLE_DEV  *Private;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL   *GraphicsOutput;
+  INTN                  Mode;
+  UINTN                 MaxColumn;
+  UINTN                 MaxRow;
+  UINTN                 Width;
+  UINTN                 Height;
+  UINTN                 Delta;
+  EFI_STATUS            Status;
+  BOOLEAN               Warning;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Foreground;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Background;
+  UINTN                 DeltaX;
+  UINTN                 DeltaY;
+  UINTN                 Count;
+  UINTN                 Index;
+  INT32                 OriginAttribute;
+  EFI_TPL               OldTpl;
+
+  if (This->Mode->Mode == -1) {
+    //
+    // If current mode is not valid, return error.
+    //
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = EFI_SUCCESS;
+
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+  //
+  // Current mode
+  //
+  Mode      = This->Mode->Mode;
+  Private   = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
+  GraphicsOutput = Private->GraphicsOutput;
+
+  MaxColumn = Private->ModeData[Mode].Columns;
+  MaxRow    = Private->ModeData[Mode].Rows;
+  DeltaX    = (UINTN) Private->ModeData[Mode].DeltaX;
+  DeltaY    = (UINTN) Private->ModeData[Mode].DeltaY;
+  Width     = MaxColumn * EFI_GLYPH_WIDTH;
+  Height    = (MaxRow - 1) * EFI_GLYPH_HEIGHT;
+  Delta     = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+
+  //
+  // The Attributes won't change when during the time OutputString is called
+  //
+  GetTextColors (This, &Foreground, &Background);
+
+  FlushCursor (This);
+
+  Warning = FALSE;
+
+  //
+  // Backup attribute
+  //
+  OriginAttribute = This->Mode->Attribute;
+
+  while (*WString != L'\0') {
+
+    if (*WString == CHAR_BACKSPACE) {
+      //
+      // If the cursor is at the left edge of the display, then move the cursor
+      // one row up.
+      //
+      if (This->Mode->CursorColumn == 0 && This->Mode->CursorRow > 0) {
+        This->Mode->CursorRow--;
+        This->Mode->CursorColumn = (INT32) (MaxColumn - 1);
+        This->OutputString (This, SpaceStr);
+        FlushCursor (This);
+        This->Mode->CursorRow--;
+        This->Mode->CursorColumn = (INT32) (MaxColumn - 1);
+      } else if (This->Mode->CursorColumn > 0) {
+        //
+        // If the cursor is not at the left edge of the display, then move the cursor
+        // left one column.
+        //
+        This->Mode->CursorColumn--;
+        This->OutputString (This, SpaceStr);
+        FlushCursor (This);
+        This->Mode->CursorColumn--;
+      }
+
+      WString++;
+
+    } else if (*WString == CHAR_LINEFEED) {
+      //
+      // If the cursor is at the bottom of the display, then scroll the display one
+      // row, and do not update the cursor position. Otherwise, move the cursor
+      // down one row.
+      //
+      if (This->Mode->CursorRow == (INT32) (MaxRow - 1)) {
+        //
+        // Scroll Screen Up One Row
+        //
+        GraphicsOutput->Blt (
+                             GraphicsOutput,
+                             NULL,
+                             EfiBltVideoToVideo,
+                             DeltaX,
+                             DeltaY + EFI_GLYPH_HEIGHT,
+                             DeltaX,
+                             DeltaY,
+                             Width,
+                             Height,
+                             Delta
+                             );
+
+        //
+        // Print Blank Line at last line
+        //
+        GraphicsOutput->Blt (
+                             GraphicsOutput,
+                             &Background,
+                             EfiBltVideoFill,
+                             0,
+                             0,
+                             DeltaX,
+                             DeltaY + Height,
+                             Width,
+                             EFI_GLYPH_HEIGHT,
+                             Delta
+                             );
+      } else {
+        This->Mode->CursorRow++;
+      }
+
+      WString++;
+
+    } else if (*WString == CHAR_CARRIAGE_RETURN) {
+      //
+      // Move the cursor to the beginning of the current row.
+      //
+      This->Mode->CursorColumn = 0;
+      WString++;
+
+    } else if (*WString == WIDE_CHAR) {
+
+      This->Mode->Attribute |= EFI_WIDE_ATTRIBUTE;
+      WString++;
+
+    } else if (*WString == NARROW_CHAR) {
+
+      This->Mode->Attribute &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);
+      WString++;
+
+    } else {
+      //
+      // Print the character at the current cursor position and move the cursor
+      // right one column. If this moves the cursor past the right edge of the
+      // display, then the line should wrap to the beginning of the next line. This
+      // is equivalent to inserting a CR and an LF. Note that if the cursor is at the
+      // bottom of the display, and the line wraps, then the display will be scrolled
+      // one line.
+      // If wide char is going to be displayed, need to display one character at a time
+      // Or, need to know the display length of a certain string.
+      //
+      // Index is used to determine how many character width units (wide = 2, narrow = 1)
+      // Count is used to determine how many characters are used regardless of their attributes
+      //
+      for (Count = 0, Index = 0; (This->Mode->CursorColumn + Index) < MaxColumn; Count++, Index++) {
+        if (WString[Count] == CHAR_NULL ||
+            WString[Count] == CHAR_BACKSPACE ||
+            WString[Count] == CHAR_LINEFEED ||
+            WString[Count] == CHAR_CARRIAGE_RETURN ||
+            WString[Count] == WIDE_CHAR ||
+            WString[Count] == NARROW_CHAR) {
+          break;
+        }
+        //
+        // Is the wide attribute on?
+        //
+        if ((This->Mode->Attribute & EFI_WIDE_ATTRIBUTE) != 0) {
+          //
+          // If wide, add one more width unit than normal since we are going to increment at the end of the for loop
+          //
+          Index++;
+          //
+          // This is the end-case where if we are at column 79 and about to print a wide character
+          // We should prevent this from happening because we will wrap inappropriately.  We should
+          // not print this character until the next line.
+          //
+          if ((This->Mode->CursorColumn + Index + 1) > MaxColumn) {
+            Index++;
+            break;
+          }
+        }
+      }
+
+      Status = DrawUnicodeWeightAtCursorN (This, WString, Count);
+      if (EFI_ERROR (Status)) {
+        Warning = TRUE;
+      }
+      //
+      // At the end of line, output carriage return and line feed
+      //
+      WString += Count;
+      This->Mode->CursorColumn += (INT32) Index;
+      if (This->Mode->CursorColumn > (INT32) MaxColumn) {
+        This->Mode->CursorColumn -= 2;
+        This->OutputString (This, SpaceStr);
+      }
+
+      if (This->Mode->CursorColumn >= (INT32) MaxColumn) {
+        FlushCursor (This);
+        if (!Private->ExtendedTextOutput.AutoWrap) {
+          This->Mode->CursorColumn = MaxColumn - 1;
+        } else {
+          This->OutputString (This, mCrLfString);
+        }
+        FlushCursor (This);
+      }
+    }
+  }
+
+  This->Mode->Attribute = OriginAttribute;
+
+  FlushCursor (This);
+
+  if (Warning) {
+    Status = EFI_WARN_UNKNOWN_GLYPH;
+  }
+
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+
+}
+
+/**
+  Verifies that all characters in a Unicode string can be output to the
+  target device.
+
+  Implements SIMPLE_TEXT_OUTPUT.TestString().
+  If one of the characters in the *Wstring is neither valid valid Unicode
+  drawing characters, not ASCII code, then this function will return
+  EFI_UNSUPPORTED
+
+  @param  This    Protocol instance pointer.
+  @param  WString The NULL-terminated Unicode string to be examined for the output
+                  device(s).
+
+  @retval EFI_SUCCESS      The device(s) are capable of rendering the output string.
+  @retval EFI_UNSUPPORTED  Some of the characters in the Unicode string cannot be
+                           rendered by one or more of the output devices mapped
+                           by the EFI handle.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutTestString (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  CHAR16                           *WString
+  )
+{
+  EFI_STATUS            Status;
+  UINT16                Count;
+
+  EFI_IMAGE_OUTPUT      *Blt;
+
+  Blt   = NULL;
+  Count = 0;
+
+  while (WString[Count] != 0) {
+    Status = mHiiFont->GetGlyph (
+                         mHiiFont,
+                         WString[Count],
+                         NULL,
+                         &Blt,
+                         NULL
+                         );
+    if (Blt != NULL) {
+      FreePool (Blt);
+      Blt = NULL;
+    }
+    Count++;
+
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Returns information for an available text mode that the output device(s)
+  supports
+
+  Implements SIMPLE_TEXT_OUTPUT.QueryMode().
+  It returnes information for an available text mode that the Graphics Console supports.
+  In this driver,we only support text mode 80x25, which is defined as mode 0.
+
+  @param  This                  Protocol instance pointer.
+  @param  ModeNumber            The mode number to return information on.
+  @param  Columns               The returned columns of the requested mode.
+  @param  Rows                  The returned rows of the requested mode.
+
+  @retval EFI_SUCCESS           The requested mode information is returned.
+  @retval EFI_UNSUPPORTED       The mode number is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutQueryMode (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  UINTN                            ModeNumber,
+  OUT UINTN                            *Columns,
+  OUT UINTN                            *Rows
+  )
+{
+  GRAPHICS_CONSOLE_DEV  *Private;
+  EFI_STATUS            Status;
+  EFI_TPL               OldTpl;
+
+  if (ModeNumber >= (UINTN) This->Mode->MaxMode) {
+    return EFI_UNSUPPORTED;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+  Status = EFI_SUCCESS;
+
+  Private   = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
+
+  *Columns  = Private->ModeData[ModeNumber].Columns;
+  *Rows     = Private->ModeData[ModeNumber].Rows;
+
+  if (*Columns <= 0 || *Rows <= 0) {
+    Status = EFI_UNSUPPORTED;
+    goto Done;
+
+  }
+
+Done:
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
+
+
+/**
+  Sets the output device(s) to a specified mode.
+
+  Implements SIMPLE_TEXT_OUTPUT.SetMode().
+  Set the Graphics Console to a specified mode. In this driver, we only support mode 0.
+
+  @param  This                  Protocol instance pointer.
+  @param  ModeNumber            The text mode to set.
+
+  @retval EFI_SUCCESS           The requested text mode is set.
+  @retval EFI_DEVICE_ERROR      The requested text mode cannot be set because of
+                                Graphics Console device error.
+  @retval EFI_UNSUPPORTED       The text mode number is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutSetMode (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  UINTN                            ModeNumber
+  )
+{
+  EFI_STATUS                      Status;
+  GRAPHICS_CONSOLE_DEV            *Private;
+  GRAPHICS_CONSOLE_MODE_DATA      *ModeData;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *NewLineBuffer;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;
+  EFI_TPL                         OldTpl;
+
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+  Private   = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
+  GraphicsOutput = Private->GraphicsOutput;
+
+  //
+  // Make sure the requested mode number is supported
+  //
+  if (ModeNumber >= (UINTN) This->Mode->MaxMode) {
+    Status = EFI_UNSUPPORTED;
+    goto Done;
+  }
+
+  ModeData  = &(Private->ModeData[ModeNumber]);
+
+  if (ModeData->Columns <= 0 && ModeData->Rows <= 0) {
+    Status = EFI_UNSUPPORTED;
+    goto Done;
+  }
+
+  //
+  // If the mode has been set at least one other time, then LineBuffer will not be NULL
+  //
+  if (Private->LineBuffer != NULL) {
+    //
+    // If the new mode is the same as the old mode, then just return EFI_SUCCESS
+    //
+    if ((INT32) ModeNumber == This->Mode->Mode) {
+      //
+      // Clear the current text window on the current graphics console
+      //
+      This->ClearScreen (This);
+      Status = EFI_SUCCESS;
+      goto Done;
+    }
+    //
+    // Otherwise, the size of the text console and/or the GOP mode will
+    // be changed, so erase the cursor, and free the LineBuffer for the
+    // current mode
+    //
+    FlushCursor (This);
+
+    FreePool (Private->LineBuffer);
+  }
+
+  //
+  // Attempt to allocate a line buffer for the requested mode number
+  //
+  NewLineBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ModeData->Columns * EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT);
+
+  if (NewLineBuffer == NULL) {
+    //
+    // The new line buffer could not be allocated, so return an error.
+    // No changes to the state of the current console have been made, so the current console is still valid
+    //
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Done;
+  }
+
+  //
+  // Assign the current line buffer to the newly allocated line buffer
+  //
+  Private->LineBuffer = NewLineBuffer;
+
+  if (ModeData->GopModeNumber != GraphicsOutput->Mode->Mode) {
+    //
+    // Either no graphics mode is currently set, or it is set
+    // to the wrong resolution, so set the new graphics mode
+    //
+    Status = GraphicsOutput->SetMode (GraphicsOutput, ModeData->GopModeNumber);
+    if (EFI_ERROR (Status)) {
+      //
+      // The mode set operation failed
+      //
+      goto Done;
+    }
+  } else {
+    //
+    // The current graphics mode is correct, so simply clear the entire display
+    //
+    Status = GraphicsOutput->Blt (
+                                  GraphicsOutput,
+                                  &mGraphicsEfiColors[0],
+                                  EfiBltVideoFill,
+                                  0,
+                                  0,
+                                  0,
+                                  0,
+                                  ModeData->GopWidth,
+                                  ModeData->GopHeight,
+                                  0
+                                  );
+  }
+
+  //
+  // The new mode is valid, so commit the mode change
+  //
+  This->Mode->Mode = (INT32) ModeNumber;
+
+  //
+  // Move the text cursor to the upper left hand corner of the display and flush it
+  //
+  This->Mode->CursorColumn  = 0;
+  This->Mode->CursorRow     = 0;
+
+  FlushCursor (This);
+
+  Status = EFI_SUCCESS;
+
+Done:
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
+
+
+/**
+  Sets the background and foreground colors for the OutputString () and
+  ClearScreen () functions.
+
+  Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
+
+  @param  This                  Protocol instance pointer.
+  @param  Attribute             The attribute to set. Bits 0..3 are the foreground
+                                color, and bits 4..6 are the background color.
+                                All other bits are undefined and must be zero.
+
+  @retval EFI_SUCCESS           The requested attribute is set.
+  @retval EFI_DEVICE_ERROR      The requested attribute cannot be set due to Graphics Console port error.
+  @retval EFI_UNSUPPORTED       The attribute requested is not defined.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutSetAttribute (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  UINTN                            Attribute
+  )
+{
+  EFI_TPL               OldTpl;
+
+  if ((Attribute | 0x7F) != 0x7F) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if ((INT32) Attribute == This->Mode->Attribute) {
+    return EFI_SUCCESS;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+  FlushCursor (This);
+
+  This->Mode->Attribute = (INT32) Attribute;
+
+  FlushCursor (This);
+
+  gBS->RestoreTPL (OldTpl);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Clears the output device(s) display to the currently selected background
+  color.
+
+  Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
+
+  @param  This                  Protocol instance pointer.
+
+  @retval  EFI_SUCCESS      The operation completed successfully.
+  @retval  EFI_DEVICE_ERROR The device had an error and could not complete the request.
+  @retval  EFI_UNSUPPORTED  The output device is not in a valid text mode.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutClearScreen (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This
+  )
+{
+  EFI_STATUS                    Status;
+  GRAPHICS_CONSOLE_DEV          *Private;
+  GRAPHICS_CONSOLE_MODE_DATA    *ModeData;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
+  EFI_TPL                       OldTpl;
+
+  if (This->Mode->Mode == -1) {
+    //
+    // If current mode is not valid, return error.
+    //
+    return EFI_UNSUPPORTED;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+  Private   = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
+  GraphicsOutput = Private->GraphicsOutput;
+  ModeData  = &(Private->ModeData[This->Mode->Mode]);
+
+  GetTextColors (This, &Foreground, &Background);
+  Status = GraphicsOutput->Blt (
+                                GraphicsOutput,
+                                &Background,
+                                EfiBltVideoFill,
+                                0,
+                                0,
+                                0,
+                                0,
+                                ModeData->GopWidth,
+                                ModeData->GopHeight,
+                                0
+                                );
+
+  This->Mode->CursorColumn  = 0;
+  This->Mode->CursorRow     = 0;
+
+  FlushCursor (This);
+
+  gBS->RestoreTPL (OldTpl);
+
+  return Status;
+}
+
+
+/**
+  Sets the current coordinates of the cursor position.
+
+  Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
+
+  @param  This        Protocol instance pointer.
+  @param  Column      The position to set the cursor to. Must be greater than or
+                      equal to zero and less than the number of columns and rows
+                      by QueryMode ().
+  @param  Row         The position to set the cursor to. Must be greater than or
+                      equal to zero and less than the number of columns and rows
+                      by QueryMode ().
+
+  @retval EFI_SUCCESS      The operation completed successfully.
+  @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
+  @retval EFI_UNSUPPORTED  The output device is not in a valid text mode, or the
+                           cursor position is invalid for the current mode.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutSetCursorPosition (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  UINTN                            Column,
+  IN  UINTN                            Row
+  )
+{
+  GRAPHICS_CONSOLE_DEV        *Private;
+  GRAPHICS_CONSOLE_MODE_DATA  *ModeData;
+  EFI_STATUS                  Status;
+  EFI_TPL                     OldTpl;
+
+  if (This->Mode->Mode == -1) {
+    //
+    // If current mode is not valid, return error.
+    //
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = EFI_SUCCESS;
+
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+  Private   = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
+  ModeData  = &(Private->ModeData[This->Mode->Mode]);
+
+  if ((Column >= ModeData->Columns) || (Row >= ModeData->Rows)) {
+    Status = EFI_UNSUPPORTED;
+    goto Done;
+  }
+
+  if ((This->Mode->CursorColumn == (INT32) Column) && (This->Mode->CursorRow == (INT32) Row)) {
+    Status = EFI_SUCCESS;
+    goto Done;
+  }
+
+  FlushCursor (This);
+
+  This->Mode->CursorColumn  = (INT32) Column;
+  This->Mode->CursorRow     = (INT32) Row;
+
+  FlushCursor (This);
+
+Done:
+  gBS->RestoreTPL (OldTpl);
+
+  return Status;
+}
+
+
+/**
+  Makes the cursor visible or invisible.
+
+  Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
+
+  @param  This                  Protocol instance pointer.
+  @param  Visible               If TRUE, the cursor is set to be visible, If FALSE,
+                                the cursor is set to be invisible.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_UNSUPPORTED       The output device's mode is not currently in a
+                                defined text mode.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutEnableCursor (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  BOOLEAN                          Visible
+  )
+{
+  EFI_TPL               OldTpl;
+
+  if (This->Mode->Mode == -1) {
+    //
+    // If current mode is not valid, return error.
+    //
+    return EFI_UNSUPPORTED;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+  FlushCursor (This);
+
+  This->Mode->CursorVisible = Visible;
+
+  FlushCursor (This);
+
+  gBS->RestoreTPL (OldTpl);
+  return EFI_SUCCESS;
+}
+
+/**
+  Gets Graphics Console devcie's foreground color and background color.
+
+  @param  This                  Protocol instance pointer.
+  @param  Foreground            Returned text foreground color.
+  @param  Background            Returned text background color.
+
+  @retval EFI_SUCCESS           It returned always.
+
+**/
+EFI_STATUS
+GetTextColors (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *Foreground,
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *Background
+  )
+{
+  INTN  Attribute;
+
+  Attribute   = This->Mode->Attribute & 0x7F;
+
+  *Foreground = mGraphicsEfiColors[Attribute & 0x0f];
+  *Background = mGraphicsEfiColors[Attribute >> 4];
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Draw Unicode string on the Graphics Console device's screen.
+
+  @param  This                  Protocol instance pointer.
+  @param  UnicodeWeight         One Unicode string to be displayed.
+  @param  Count                 The count of Unicode string.
+
+  @retval EFI_OUT_OF_RESOURCES  If no memory resource to use.
+  @retval EFI_UNSUPPORTED       If no Graphics Output Protocol exists.
+  @retval EFI_SUCCESS           Drawing Unicode string implemented successfully.
+
+**/
+EFI_STATUS
+DrawUnicodeWeightAtCursorN (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  CHAR16                           *UnicodeWeight,
+  IN  UINTN                            Count
+  )
+{
+  EFI_STATUS                        Status;
+  GRAPHICS_CONSOLE_DEV              *Private;
+  EFI_IMAGE_OUTPUT                  *Blt;
+  EFI_STRING                        String;
+  EFI_FONT_DISPLAY_INFO             *FontInfo;
+
+  Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
+  Blt = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
+  if (Blt == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Blt->Width        = (UINT16) (Private->ModeData[This->Mode->Mode].GopWidth);
+  Blt->Height       = (UINT16) (Private->ModeData[This->Mode->Mode].GopHeight);
+
+  String = AllocateCopyPool ((Count + 1) * sizeof (CHAR16), UnicodeWeight);
+  if (String == NULL) {
+    FreePool (Blt);
+    return EFI_OUT_OF_RESOURCES;
+  }
+  //
+  // Set the end character
+  //
+  *(String + Count) = L'\0';
+
+  FontInfo = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));
+  if (FontInfo == NULL) {
+    FreePool (Blt);
+    FreePool (String);
+    return EFI_OUT_OF_RESOURCES;
+  }
+  //
+  // Get current foreground and background colors.
+  //
+  GetTextColors (This, &FontInfo->ForegroundColor, &FontInfo->BackgroundColor);
+
+  //
+  // If Graphics Output protocol exists, using HII Font protocol to draw.
+  //
+  Blt->Image.Screen = Private->GraphicsOutput;
+
+  Status = mHiiFont->StringToImage (
+                                    mHiiFont,
+                                    EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN | EFI_HII_IGNORE_LINE_BREAK,
+                                    String,
+                                    FontInfo,
+                                    &Blt,
+                                    This->Mode->CursorColumn * EFI_GLYPH_WIDTH + Private->ModeData[This->Mode->Mode].DeltaX,
+                                    This->Mode->CursorRow * EFI_GLYPH_HEIGHT + Private->ModeData[This->Mode->Mode].DeltaY,
+                                    NULL,
+                                    NULL,
+                                    NULL
+                                    );
+
+  if (Blt != NULL) {
+    FreePool (Blt);
+  }
+  if (String != NULL) {
+    FreePool (String);
+  }
+  if (FontInfo != NULL) {
+    FreePool (FontInfo);
+  }
+  return Status;
+}
+
+/**
+  Flush the cursor on the screen.
+
+  If CursorVisible is FALSE, nothing to do and return directly.
+  If CursorVisible is TRUE,
+     i) If the cursor shows on screen, it will be erased.
+    ii) If the cursor does not show on screen, it will be shown.
+
+  @param  This                  Protocol instance pointer.
+
+  @retval EFI_SUCCESS           The cursor is erased successfully.
+
+**/
+EFI_STATUS
+FlushCursor (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This
+  )
+{
+  GRAPHICS_CONSOLE_DEV                *Private;
+  EFI_SIMPLE_TEXT_OUTPUT_MODE         *CurrentMode;
+  INTN                                GlyphX;
+  INTN                                GlyphY;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL        *GraphicsOutput;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Foreground;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Background;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION BltChar[EFI_GLYPH_HEIGHT][EFI_GLYPH_WIDTH];
+  UINTN                               PosX;
+  UINTN                               PosY;
+
+  CurrentMode = This->Mode;
+
+  if (!CurrentMode->CursorVisible) {
+    return EFI_SUCCESS;
+  }
+
+  Private = GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS (This);
+  GraphicsOutput = Private->GraphicsOutput;
+
+  //
+  // In this driver, only narrow character was supported.
+  //
+  //
+  // Blt a character to the screen
+  //
+  GlyphX  = (CurrentMode->CursorColumn * EFI_GLYPH_WIDTH) + Private->ModeData[CurrentMode->Mode].DeltaX;
+  GlyphY  = (CurrentMode->CursorRow * EFI_GLYPH_HEIGHT) + Private->ModeData[CurrentMode->Mode].DeltaY;
+
+  GraphicsOutput->Blt (
+                       GraphicsOutput,
+                       (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,
+                       EfiBltVideoToBltBuffer,
+                       GlyphX,
+                       GlyphY,
+                       0,
+                       0,
+                       EFI_GLYPH_WIDTH,
+                       EFI_GLYPH_HEIGHT,
+                       EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+                       );
+
+  GetTextColors (This, &Foreground.Pixel, &Background.Pixel);
+
+  //
+  // Convert Monochrome bitmap of the Glyph to BltBuffer structure
+  //
+  for (PosY = 0; PosY < EFI_GLYPH_HEIGHT; PosY++) {
+    for (PosX = 0; PosX < EFI_GLYPH_WIDTH; PosX++) {
+      if ((mCursorGlyph.GlyphCol1[PosY] & (BIT0 << PosX)) != 0) {
+        BltChar[PosY][EFI_GLYPH_WIDTH - PosX - 1].Raw ^= Foreground.Raw;
+      }
+    }
+  }
+
+  GraphicsOutput->Blt (
+                       GraphicsOutput,
+                       (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltChar,
+                       EfiBltBufferToVideo,
+                       0,
+                       0,
+                       GlyphX,
+                       GlyphY,
+                       EFI_GLYPH_WIDTH,
+                       EFI_GLYPH_HEIGHT,
+                       EFI_GLYPH_WIDTH * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+                       );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  HII Database Protocol notification event handler.
+
+  Register font package when HII Database Protocol has been installed.
+
+  @param[in] Event    Event whose notification function is being invoked.
+  @param[in] Context  Pointer to the notification function's context.
+**/
+VOID
+EFIAPI
+RegisterFontPackage (
+  IN  EFI_EVENT       Event,
+  IN  VOID            *Context
+  )
+{
+  EFI_STATUS                           Status;
+  EFI_HII_SIMPLE_FONT_PACKAGE_HDR      *SimplifiedFont;
+  UINT32                               PackageLength;
+  UINT8                                *Package;
+  UINT8                                *Location;
+  EFI_HII_DATABASE_PROTOCOL            *HiiDatabase;
+
+  //
+  // Locate HII Database Protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiHiiDatabaseProtocolGuid,
+                  NULL,
+                  (VOID **) &HiiDatabase
+                  );
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  //
+  // Add 4 bytes to the header for entire length for HiiAddPackages use only.
+  //
+  //    +--------------------------------+ <-- Package
+  //    |                                |
+  //    |    PackageLength(4 bytes)      |
+  //    |                                |
+  //    |--------------------------------| <-- SimplifiedFont
+  //    |                                |
+  //    |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |
+  //    |                                |
+  //    |--------------------------------| <-- Location
+  //    |                                |
+  //    |     gUsStdNarrowGlyphData      |
+  //    |                                |
+  //    +--------------------------------+
+
+  PackageLength   = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + mNarrowFontSize + 4;
+  Package = AllocateZeroPool (PackageLength);
+  ASSERT (Package != NULL);
+
+  WriteUnaligned32((UINT32 *) Package,PackageLength);
+  SimplifiedFont = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR *) (Package + 4);
+  SimplifiedFont->Header.Length        = (UINT32) (PackageLength - 4);
+  SimplifiedFont->Header.Type          = EFI_HII_PACKAGE_SIMPLE_FONTS;
+  SimplifiedFont->NumberOfNarrowGlyphs = (UINT16) (mNarrowFontSize / sizeof (EFI_NARROW_GLYPH));
+
+  Location = (UINT8 *) (&SimplifiedFont->NumberOfWideGlyphs + 1);
+  CopyMem (Location, gUsStdNarrowGlyphData, mNarrowFontSize);
+
+  //
+  // Add this simplified font package to a package list then install it.
+  //
+  mHiiHandle = HiiAddPackages (
+                 &mFontPackageListGuid,
+                 NULL,
+                 Package,
+                 NULL
+                 );
+  ASSERT (mHiiHandle != NULL);
+  FreePool (Package);
+}
+
+/**
+  The user Entry Point for module GraphicsConsole. The user code starts with this function.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval  EFI_SUCCESS       The entry point is executed successfully.
+  @return  other             Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeGraphicsConsole (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  EFI_STATUS              Status;
+
+  //
+  // Register notify function on HII Database Protocol to add font package.
+  //
+  EfiCreateProtocolNotifyEvent (
+    &gEfiHiiDatabaseProtocolGuid,
+    TPL_CALLBACK,
+    RegisterFontPackage,
+    NULL,
+    &mHiiRegistration
+    );
+
+  //
+  // Install driver model protocol(s).
+  //
+  Status = EfiLibInstallDriverBindingComponentName2 (
+             ImageHandle,
+             SystemTable,
+             &gGraphicsConsoleDriverBinding,
+             ImageHandle,
+             &gGraphicsConsoleComponentName,
+             &gGraphicsConsoleComponentName2
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsole.h b/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsole.h
new file mode 100644
index 000000000000..ba93cab86bf3
--- /dev/null
+++ b/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsole.h
@@ -0,0 +1,591 @@
+/** @file
+ *
+ *  Copyright (c) 2018, Andrei Warkentin <andrey.warkentin at gmail.com>
+ *  Copyright (c) 2006-2016, 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.
+ *
+ **/
+
+#ifndef _GRAPHICS_CONSOLE_H_
+#define _GRAPHICS_CONSOLE_H_
+
+#include <Uefi.h>
+#include <Protocol/ExtendedTextOut.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/HiiFont.h>
+#include <Protocol/HiiDatabase.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/HiiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Guid/MdeModuleHii.h>
+
+extern EFI_COMPONENT_NAME_PROTOCOL   gGraphicsConsoleComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL  gGraphicsConsoleComponentName2;
+extern EFI_DRIVER_BINDING_PROTOCOL   gGraphicsConsoleDriverBinding;
+extern EFI_NARROW_GLYPH              gUsStdNarrowGlyphData[];
+
+extern UINT32 mNarrowFontSize;
+
+typedef union {
+  EFI_NARROW_GLYPH  NarrowGlyph;
+  EFI_WIDE_GLYPH    WideGlyph;
+} GLYPH_UNION;
+
+//
+// Device Structure
+//
+#define GRAPHICS_CONSOLE_DEV_SIGNATURE  SIGNATURE_32 ('g', 's', 't', 'o')
+
+typedef struct {
+  UINTN   Columns;
+  UINTN   Rows;
+  INTN    DeltaX;
+  INTN    DeltaY;
+  UINT32  GopWidth;
+  UINT32  GopHeight;
+  UINT32  GopModeNumber;
+} GRAPHICS_CONSOLE_MODE_DATA;
+
+typedef struct {
+  UINTN                            Signature;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL     *GraphicsOutput;
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  SimpleTextOutput;
+  EFI_SIMPLE_TEXT_OUTPUT_MODE      SimpleTextOutputMode;
+  GRAPHICS_CONSOLE_MODE_DATA       *ModeData;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *LineBuffer;
+  EXTENDED_TEXT_OUTPUT_PROTOCOL    ExtendedTextOutput;
+} GRAPHICS_CONSOLE_DEV;
+
+#define GRAPHICS_CONSOLE_CON_OUT_DEV_FROM_THIS(a) \
+  CR (a, GRAPHICS_CONSOLE_DEV, SimpleTextOutput, GRAPHICS_CONSOLE_DEV_SIGNATURE)
+
+
+//
+// EFI Component Name Functions
+//
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  );
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  );
+
+
+/**
+  Reset the text output device hardware and optionally run diagnostics.
+
+  Implements SIMPLE_TEXT_OUTPUT.Reset().
+  If ExtendeVerification is TRUE, then perform dependent Graphics Console
+  device reset, and set display mode to mode 0.
+  If ExtendedVerification is FALSE, only set display mode to mode 0.
+
+  @param  This                  Protocol instance pointer.
+  @param  ExtendedVerification  Indicates that the driver may perform a more
+                                exhaustive verification operation of the device
+                                during reset.
+
+  @retval EFI_SUCCESS          The text output device was reset.
+  @retval EFI_DEVICE_ERROR     The text output device is not functioning correctly and
+                               could not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutReset (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *This,
+  IN  BOOLEAN                            ExtendedVerification
+  );
+
+/**
+  Write a Unicode string to the output device.
+
+  Implements SIMPLE_TEXT_OUTPUT.OutputString().
+  The Unicode string will be converted to Glyphs and will be
+  sent to the Graphics Console.
+
+  @param  This                    Protocol instance pointer.
+  @param  WString                 The NULL-terminated Unicode string to be displayed
+                                  on the output device(s). All output devices must
+                                  also support the Unicode drawing defined in this file.
+
+  @retval EFI_SUCCESS             The string was output to the device.
+  @retval EFI_DEVICE_ERROR        The device reported an error while attempting to output
+                                  the text.
+  @retval EFI_UNSUPPORTED         The output device's mode is not currently in a
+                                  defined text mode.
+  @retval EFI_WARN_UNKNOWN_GLYPH  This warning code indicates that some of the
+                                  characters in the Unicode string could not be
+                                  rendered and were skipped.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutOutputString (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  CHAR16                           *WString
+  );
+
+/**
+  Verifies that all characters in a Unicode string can be output to the
+  target device.
+
+  Implements SIMPLE_TEXT_OUTPUT.TestString().
+  If one of the characters in the *Wstring is neither valid valid Unicode
+  drawing characters, not ASCII code, then this function will return
+  EFI_UNSUPPORTED
+
+  @param  This    Protocol instance pointer.
+  @param  WString The NULL-terminated Unicode string to be examined for the output
+                  device(s).
+
+  @retval EFI_SUCCESS      The device(s) are capable of rendering the output string.
+  @retval EFI_UNSUPPORTED  Some of the characters in the Unicode string cannot be
+                           rendered by one or more of the output devices mapped
+                           by the EFI handle.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutTestString (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  CHAR16                           *WString
+  );
+
+/**
+  Returns information for an available text mode that the output device(s)
+  supports
+
+  Implements SIMPLE_TEXT_OUTPUT.QueryMode().
+  It returnes information for an available text mode that the Graphics Console supports.
+  In this driver,we only support text mode 80x25, which is defined as mode 0.
+
+  @param  This                  Protocol instance pointer.
+  @param  ModeNumber            The mode number to return information on.
+  @param  Columns               The returned columns of the requested mode.
+  @param  Rows                  The returned rows of the requested mode.
+
+  @retval EFI_SUCCESS           The requested mode information is returned.
+  @retval EFI_UNSUPPORTED       The mode number is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutQueryMode (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  UINTN                            ModeNumber,
+  OUT UINTN                            *Columns,
+  OUT UINTN                            *Rows
+  );
+
+
+/**
+  Sets the output device(s) to a specified mode.
+
+  Implements SIMPLE_TEXT_OUTPUT.SetMode().
+  Set the Graphics Console to a specified mode. In this driver, we only support mode 0.
+
+  @param  This                  Protocol instance pointer.
+  @param  ModeNumber            The text mode to set.
+
+  @retval EFI_SUCCESS           The requested text mode is set.
+  @retval EFI_DEVICE_ERROR      The requested text mode cannot be set because of
+                                Graphics Console device error.
+  @retval EFI_UNSUPPORTED       The text mode number is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutSetMode (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  UINTN                            ModeNumber
+  );
+
+/**
+  Sets the background and foreground colors for the OutputString () and
+  ClearScreen () functions.
+
+  Implements SIMPLE_TEXT_OUTPUT.SetAttribute().
+
+  @param  This                  Protocol instance pointer.
+  @param  Attribute             The attribute to set. Bits 0..3 are the foreground
+                                color, and bits 4..6 are the background color.
+                                All other bits are undefined and must be zero.
+
+  @retval EFI_SUCCESS           The requested attribute is set.
+  @retval EFI_DEVICE_ERROR      The requested attribute cannot be set due to Graphics Console port error.
+  @retval EFI_UNSUPPORTED       The attribute requested is not defined.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutSetAttribute (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  UINTN                            Attribute
+  );
+
+/**
+  Clears the output device(s) display to the currently selected background
+  color.
+
+  Implements SIMPLE_TEXT_OUTPUT.ClearScreen().
+
+  @param  This                  Protocol instance pointer.
+
+  @retval  EFI_SUCCESS      The operation completed successfully.
+  @retval  EFI_DEVICE_ERROR The device had an error and could not complete the request.
+  @retval  EFI_UNSUPPORTED  The output device is not in a valid text mode.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutClearScreen (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This
+  );
+
+/**
+  Sets the current coordinates of the cursor position.
+
+  Implements SIMPLE_TEXT_OUTPUT.SetCursorPosition().
+
+  @param  This        Protocol instance pointer.
+  @param  Column      The position to set the cursor to. Must be greater than or
+                      equal to zero and less than the number of columns and rows
+                      by QueryMode ().
+  @param  Row         The position to set the cursor to. Must be greater than or
+                      equal to zero and less than the number of columns and rows
+                      by QueryMode ().
+
+  @retval EFI_SUCCESS      The operation completed successfully.
+  @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
+  @retval EFI_UNSUPPORTED  The output device is not in a valid text mode, or the
+                           cursor position is invalid for the current mode.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutSetCursorPosition (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  UINTN                            Column,
+  IN  UINTN                            Row
+  );
+
+
+/**
+  Makes the cursor visible or invisible.
+
+  Implements SIMPLE_TEXT_OUTPUT.EnableCursor().
+
+  @param  This                  Protocol instance pointer.
+  @param  Visible               If TRUE, the cursor is set to be visible, If FALSE,
+                                the cursor is set to be invisible.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleConOutEnableCursor (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  BOOLEAN                          Visible
+  );
+
+/**
+  Test to see if Graphics Console could be supported on the Controller.
+
+  Graphics Console could be supported if Graphics Output Protocol exists
+  on the Controller.
+
+  @param  This                Protocol instance pointer.
+  @param  Controller          Handle of device to test.
+  @param  RemainingDevicePath Optional parameter use to pick a specific child
+                              device to start.
+
+  @retval EFI_SUCCESS         This driver supports this device.
+  @retval other               This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleControllerDriverSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  );
+
+
+/**
+  Start this driver on Controller by opening the Graphics Output Protocol,
+  and installing Simple Text Out protocol on Controller.
+
+  @param  This                 Protocol instance pointer.
+  @param  Controller           Handle of device to bind driver to
+  @param  RemainingDevicePath  Optional parameter use to pick a specific child
+                               device to start.
+
+  @retval EFI_SUCCESS          This driver is added to Controller.
+  @retval other                This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleControllerDriverStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN EFI_HANDLE                     Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
+  );
+
+/**
+  Stop this driver on Controller by removing Simple Text Out protocol
+  and closing the Graphics Output Protocol on Controller.
+
+  @param  This              Protocol instance pointer.
+  @param  Controller        Handle of device to stop driver on
+  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
+                            children is zero stop the entire bus driver.
+  @param  ChildHandleBuffer List of Child Handles to Stop.
+
+  @retval EFI_SUCCESS       This driver is removed Controller.
+  @retval EFI_NOT_STARTED   Simple Text Out protocol could not be found the
+                            Controller.
+  @retval other             This driver was not removed from this device.
+
+**/
+EFI_STATUS
+EFIAPI
+GraphicsConsoleControllerDriverStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
+  IN  EFI_HANDLE                     Controller,
+  IN  UINTN                          NumberOfChildren,
+  IN  EFI_HANDLE                     *ChildHandleBuffer
+  );
+
+
+/**
+  Locate HII Database protocol and HII Font protocol.
+
+  @retval  EFI_SUCCESS     HII Database protocol and HII Font protocol
+                           are located successfully.
+  @return  other           Failed to locate HII Database protocol or
+                           HII Font protocol.
+
+**/
+EFI_STATUS
+EfiLocateHiiProtocol (
+  VOID
+  );
+
+
+/**
+  Gets Graphics Console devcie's foreground color and background color.
+
+  @param  This                  Protocol instance pointer.
+  @param  Foreground            Returned text foreground color.
+  @param  Background            Returned text background color.
+
+  @retval EFI_SUCCESS           It returned always.
+
+**/
+EFI_STATUS
+GetTextColors (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *Foreground,
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *Background
+  );
+
+/**
+  Draw Unicode string on the Graphics Console device's screen.
+
+  @param  This                  Protocol instance pointer.
+  @param  UnicodeWeight         One Unicode string to be displayed.
+  @param  Count                 The count of Unicode string.
+
+  @retval EFI_OUT_OF_RESOURCES  If no memory resource to use.
+  @retval EFI_UNSUPPORTED       If no Graphics Output Protocol exists.
+  @retval EFI_SUCCESS           Drawing Unicode string implemented successfully.
+
+**/
+EFI_STATUS
+DrawUnicodeWeightAtCursorN (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
+  IN  CHAR16                           *UnicodeWeight,
+  IN  UINTN                            Count
+  );
+
+/**
+  Flush the cursor on the screen.
+
+  If CursorVisible is FALSE, nothing to do and return directly.
+  If CursorVisible is TRUE,
+     i) If the cursor shows on screen, it will be erased.
+    ii) If the cursor does not show on screen, it will be shown.
+
+  @param  This                  Protocol instance pointer.
+
+  @retval EFI_SUCCESS           The cursor is erased successfully.
+
+**/
+EFI_STATUS
+FlushCursor (
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This
+  );
+
+/**
+  Check if the current specific mode supported the user defined resolution
+  for the Graphics Console device based on Graphics Output Protocol.
+
+  If yes, set the graphic device's current mode to this specific mode.
+
+  @param  GraphicsOutput        Graphics Output Protocol instance pointer.
+  @param  HorizontalResolution  User defined horizontal resolution
+  @param  VerticalResolution    User defined vertical resolution.
+  @param  CurrentModeNumber     Current specific mode to be check.
+
+  @retval EFI_SUCCESS       The mode is supported.
+  @retval EFI_UNSUPPORTED   The specific mode is out of range of graphics
+                            device supported.
+  @retval other             The specific mode does not support user defined
+                            resolution or failed to set the current mode to the
+                            specific mode on graphics device.
+
+**/
+EFI_STATUS
+CheckModeSupported (
+  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput,
+  IN  UINT32  HorizontalResolution,
+  IN  UINT32  VerticalResolution,
+  OUT UINT32  *CurrentModeNumber
+  );
+
+#endif
diff --git a/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsoleDxe.inf b/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
new file mode 100644
index 000000000000..cf359b414682
--- /dev/null
+++ b/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
@@ -0,0 +1,74 @@
+#/** @file
+#
+#  Copyright (c) 2006-2014, Intel Corporation. All rights reserved.
+#  Copyright (c) 2018, Andrei Warkentin <andrey.warkentin at gmail.com>
+#
+#  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                      = GraphicsConsoleDxe
+  MODULE_UNI_FILE                = GraphicsConsoleDxe.uni
+  FILE_GUID                      = CCCB0C28-4B24-11d5-9A5A-0090273FC14D
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.1
+  ENTRY_POINT                    = InitializeGraphicsConsole
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC AARCH64
+#
+#  DRIVER_BINDING                =  gGraphicsConsoleDriverBinding
+#  COMPONENT_NAME                =  gGraphicsConsoleComponentName
+#  COMPONENT_NAME2               =  gGraphicsConsoleComponentName2
+#
+
+[Sources]
+  ComponentName.c
+  NewFont.c
+  GraphicsConsole.c
+  GraphicsConsole.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Platform/Broadcom/Bcm283x/RaspberryPiPkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  MemoryAllocationLib
+  BmpSupportLib
+  BaseMemoryLib
+  UefiLib
+  UefiDriverEntryPoint
+  DebugLib
+  HiiLib
+  PcdLib
+
+[Protocols]
+  gEfiDevicePathProtocolGuid
+  gEfiSimpleTextOutProtocolGuid
+  gEfiGraphicsOutputProtocolGuid
+  gEfiHiiFontProtocolGuid
+  gEfiHiiDatabaseProtocolGuid
+  gExtendedTextOutputProtocolGuid
+
+[FeaturePcd]
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution ## SOMETIMES_CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution   ## SOMETIMES_CONSUMES
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  GraphicsConsoleDxeExtra.uni
diff --git a/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsoleDxe.uni b/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsoleDxe.uni
new file mode 100644
index 000000000000..09336b5cae36
--- /dev/null
+++ b/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsoleDxe.uni
@@ -0,0 +1,19 @@
+/** @file
+ *
+ *  Copyright (c) 2006-2014, Intel Corporation. All rights reserved.
+ *  Copyright (c) 2018, Andrei Warkentin <andrey.warkentin at gmail.com>
+ *
+ *  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.
+ *
+ **/
+
+#string STR_MODULE_ABSTRACT             #language en-US "Console support on graphic devices"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "Install SimpleTextOutputProtocol on GraphicsOutputProtocol devices\n"
+
diff --git a/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsoleDxeExtra.uni b/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsoleDxeExtra.uni
new file mode 100644
index 000000000000..cb8a6e0dbb5e
--- /dev/null
+++ b/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/GraphicsConsoleDxeExtra.uni
@@ -0,0 +1,20 @@
+/** @file
+ *
+ *  Copyright (c) 2006-2014, Intel Corporation. All rights reserved.
+ *  Copyright (c) 2018, Andrei Warkentin <andrey.warkentin at gmail.com>
+ *
+ *  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.
+ *
+ **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Graphics Console DXE Driver"
+
+
diff --git a/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/NewFont.c b/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/NewFont.c
new file mode 100644
index 000000000000..6331b89b10dd
--- /dev/null
+++ b/Platform/Broadcom/Bcm283x/Drivers/GraphicsConsoleDxe/NewFont.c
@@ -0,0 +1,288 @@
+/** @file
+ *
+ *  Copyright (c) 2018, Andrei Warkentin <andrey.warkentin at gmail.com>
+ *
+ *  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.
+ *
+ **/
+
+/*
+ * Based on ftp://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP437.TXT and
+ * https://en.wikipedia.org/wiki/Code_page_437 for the cp437 Unicode equivalents
+ * and the cp437 8x19 font from that_editor.
+ *
+ * https://github.com/bisqwit/that_editor/blob/master/8x19.inc
+ * https://github.com/bisqwit/that_editor/blob/master/sourcematerial/vga8x19.bdf
+ * https://github.com/stsp/dosemu2/blob/master/COPYING.DOSEMU
+ */
+
+#include "GraphicsConsole.h"
+
+EFI_NARROW_GLYPH  gUsStdNarrowGlyphData[] = {
+  { 0x263a, 0x00, {0x00,0x00,0x7E,0x81,0xA5,0xA5,0x81,0x81,0xA5,0xA5,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,0x00}},
+  { 0x263b, 0x00, {0x00,0x00,0x7E,0xFF,0xDB,0xFF,0xFF,0xFF,0xDB,0xE7,0xFF,0xFF,0xFF,0x7E,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2665, 0x00, {0x00,0x00,0x00,0x00,0x00,0x6C,0xFE,0xFE,0xFE,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2666, 0x00, {0x00,0x00,0x00,0x00,0x00,0x10,0x38,0x7C,0xFE,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2663, 0x00, {0x00,0x00,0x00,0x18,0x3C,0x3C,0xFF,0xE7,0xE7,0xE7,0xFF,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2660, 0x00, {0x00,0x00,0x00,0x18,0x3C,0x7E,0xFF,0xFF,0xFF,0x7E,0x7E,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2022, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x25d8, 0x00, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},
+  { 0x25cb, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x66,0x42,0x66,0x66,0x3C,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x25d9, 0x00, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDB,0x99,0xBD,0xBD,0x99,0xDB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},
+  { 0x2642, 0x00, {0x00,0x00,0x1E,0x06,0x0E,0x0A,0x1A,0x78,0xCC,0xCC,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2640, 0x00, {0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00}},
+  { 0x266a, 0x00, {0x00,0x00,0x3F,0x33,0x33,0x3F,0x30,0x30,0x30,0x30,0x30,0x70,0xF0,0xE0,0x00,0x00,0x00,0x00,0x00}},
+  { 0x266b, 0x00, {0x00,0x00,0x7F,0x63,0x63,0x7F,0x63,0x63,0x63,0x63,0x63,0x67,0xE7,0xE6,0xC0,0x00,0x00,0x00,0x00}},
+  { 0x263c, 0x00, {0x00,0x00,0x00,0x18,0x18,0xDB,0xFF,0x3C,0xE7,0x3C,0xFF,0xDB,0x18,0x18,0x00,0x00,0x00,0x00,0x00}},
+  { 0x25ba, 0x00, {0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00}},
+  { 0x25c4, 0x00, {0x00,0x02,0x06,0x0E,0x1E,0x3E,0x7E,0xFE,0x7E,0x3E,0x1E,0x0E,0x06,0x02,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2195, 0x00, {0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x203c, 0x00, {0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00b6, 0x00, {0x00,0x00,0x7F,0xDB,0xDB,0xDB,0xDB,0x7B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00a7, 0x00, {0x00,0x00,0x7C,0xC6,0x62,0x30,0x78,0x4C,0x64,0x3C,0x18,0x8C,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x25ac, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00}},
+  { 0x21a8, 0x00, {0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2191, 0x00, {0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2193, 0x00, {0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2192, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2190, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xFE,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x221f, 0x00, {0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2194, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x6C,0xFE,0x6C,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x25b2, 0x00, {0x00,0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7C,0x7C,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x25bc, 0x00, {0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0x7C,0x7C,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0020, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0021, 0x00, {0x00,0x00,0x18,0x3C,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0022, 0x00, {0x66,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0023, 0x00, {0x00,0x00,0x00,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0024, 0x00, {0x10,0x10,0x7C,0xD6,0xD6,0xD2,0x70,0x38,0x1C,0x16,0x96,0xD6,0xD6,0x7C,0x10,0x10,0x00,0x00,0x00}},
+  { 0x0025, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0026, 0x00, {0x00,0x00,0x38,0x6C,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0027, 0x00, {0x30,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0028, 0x00, {0x00,0x00,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0029, 0x00, {0x00,0x00,0x30,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00,0x00,0x00}},
+  { 0x002a, 0x00, {0x00,0x00,0x00,0x00,0x00,0x66,0x24,0x3C,0xFF,0x3C,0x24,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x002b, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x002c, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x30,0x00,0x00,0x00,0x00}},
+  { 0x002d, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x002e, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00}},
+  { 0x002f, 0x00, {0x00,0x00,0x00,0x00,0x00,0x02,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0030, 0x00, {0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0xD6,0xD6,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0031, 0x00, {0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0032, 0x00, {0x00,0x00,0x7C,0xC6,0x06,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0033, 0x00, {0x00,0x00,0x7C,0xC6,0x06,0x06,0x06,0x3C,0x06,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0034, 0x00, {0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0035, 0x00, {0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0036, 0x00, {0x00,0x00,0x38,0x60,0xC0,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0037, 0x00, {0x00,0x00,0xFE,0xC6,0x06,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0038, 0x00, {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0039, 0x00, {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00,0x00}},
+  { 0x003a, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x003b, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,0x00}},
+  { 0x003c, 0x00, {0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0xC0,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00,0x00}},
+  { 0x003d, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x003e, 0x00, {0x00,0x00,0x00,0xC0,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0xC0,0x00,0x00,0x00,0x00,0x00}},
+  { 0x003f, 0x00, {0x00,0x00,0x7C,0xC6,0x86,0x06,0x0C,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0040, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xCE,0xDE,0xDE,0xDE,0xDE,0xCC,0xC0,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0041, 0x00, {0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0042, 0x00, {0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0043, 0x00, {0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0044, 0x00, {0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0045, 0x00, {0x00,0x00,0xFE,0x66,0x62,0x62,0x68,0x78,0x68,0x60,0x62,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0046, 0x00, {0x00,0x00,0xFE,0x66,0x62,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0047, 0x00, {0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xDE,0xC6,0xC6,0x66,0x3A,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0048, 0x00, {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0049, 0x00, {0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x004a, 0x00, {0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00,0x00}},
+  { 0x004b, 0x00, {0x00,0x00,0xE6,0x66,0x66,0x66,0x6C,0x78,0x78,0x6C,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,0x00}},
+  { 0x004c, 0x00, {0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,0x00}},
+  { 0x004d, 0x00, {0x00,0x00,0xC6,0xEE,0xFE,0xD6,0xD6,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,0x00}},
+  { 0x004e, 0x00, {0x00,0x00,0xC6,0xE6,0xF6,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,0x00}},
+  { 0x004f, 0x00, {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0050, 0x00, {0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0051, 0x00, {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xDE,0x7C,0x0C,0x0E,0x00,0x00,0x00}},
+  { 0x0052, 0x00, {0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x7C,0x6C,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0053, 0x00, {0x00,0x00,0x7C,0xC6,0xC6,0xC2,0x60,0x38,0x0C,0x06,0x86,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0054, 0x00, {0x00,0x00,0x7E,0x7E,0x5A,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0055, 0x00, {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0056, 0x00, {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0057, 0x00, {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0058, 0x00, {0x00,0x00,0xC6,0xC6,0x6C,0x6C,0x38,0x38,0x38,0x38,0x6C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0059, 0x00, {0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x005a, 0x00, {0x00,0x00,0xFE,0xC6,0x86,0x86,0x0C,0x18,0x30,0x60,0xC2,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00,0x00}},
+  { 0x005b, 0x00, {0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x005c, 0x00, {0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x60,0x30,0x18,0x0C,0x06,0x02,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x005d, 0x00, {0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x005e, 0x00, {0x00,0x10,0x38,0x6C,0xC6,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x005f, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00}},
+  { 0x0060, 0x00, {0x30,0x30,0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0061, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0062, 0x00, {0x00,0x00,0xE0,0x60,0x60,0x60,0x78,0x6C,0x66,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0063, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0064, 0x00, {0x00,0x00,0x1C,0x0C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0065, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0066, 0x00, {0x00,0x00,0x1C,0x36,0x32,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0067, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0xCC,0x78,0x00}},
+  { 0x0068, 0x00, {0x00,0x00,0xE0,0x60,0x60,0x60,0x6C,0x76,0x66,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0069, 0x00, {0x00,0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x006a, 0x00, {0x00,0x00,0x00,0x0C,0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0x78,0x00}},
+  { 0x006b, 0x00, {0x00,0x00,0xE0,0x60,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,0x00}},
+  { 0x006c, 0x00, {0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x006d, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0xFE,0xD6,0xD6,0xD6,0xD6,0xC6,0xC6,0x00,0x00,0x00,0x00,0x00}},
+  { 0x006e, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,0x00}},
+  { 0x006f, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0070, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0xF0,0x00}},
+  { 0x0071, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x0C,0x1E,0x00}},
+  { 0x0072, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x76,0x66,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0073, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC2,0x78,0x0C,0x86,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0074, 0x00, {0x00,0x00,0x10,0x30,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0075, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0076, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0077, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0x6C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0078, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x10,0x38,0x6C,0xC6,0x82,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0079, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x0C,0xF8,0x00}},
+  { 0x007a, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xCC,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00,0x00}},
+  { 0x007b, 0x00, {0x00,0x00,0x0E,0x18,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00,0x00}},
+  { 0x007c, 0x00, {0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00}},
+  { 0x007d, 0x00, {0x00,0x00,0x70,0x18,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,0x00}},
+  { 0x007e, 0x00, {0x00,0x76,0xD4,0x9C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2302, 0x00, {0x00,0x00,0x00,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xC6,0xFE,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00c7, 0x00, {0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x0C,0x06,0x7C,0x00,0x00,0x00}},
+  { 0x00fc, 0x00, {0x00,0x00,0x00,0xCC,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00e9, 0x00, {0x00,0x0C,0x18,0x30,0x00,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00e2, 0x00, {0x00,0x10,0x38,0x6C,0x00,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00e4, 0x00, {0x00,0x00,0x00,0xCC,0xCC,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00e0, 0x00, {0x00,0x60,0x30,0x18,0x0C,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00e5, 0x00, {0x00,0x38,0x6C,0x6C,0x38,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00e7, 0x00, {0x00,0x00,0x00,0x00,0x3C,0x66,0x62,0x60,0x60,0x66,0x64,0x3C,0x0C,0x06,0x3C,0x00,0x00,0x00,0x00}},
+  { 0x00ea, 0x00, {0x00,0x10,0x38,0x6C,0x44,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00eb, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00e8, 0x00, {0x00,0x60,0x30,0x18,0x0C,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00ef, 0x00, {0x00,0x00,0x00,0x66,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00ee, 0x00, {0x00,0x18,0x3C,0x66,0x42,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00ec, 0x00, {0x00,0x60,0x30,0x18,0x08,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00c4, 0x00, {0xC6,0xC6,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00c5, 0x00, {0x38,0x28,0x38,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00c9, 0x00, {0x18,0x30,0x60,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00e6, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0x76,0x36,0x36,0x7E,0xD8,0xD8,0x6E,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00c6, 0x00, {0x00,0x00,0x3E,0x6C,0xCC,0xCC,0xFE,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCE,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00f4, 0x00, {0x00,0x10,0x38,0x6C,0x44,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00f6, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00f2, 0x00, {0x00,0x60,0x30,0x18,0x0C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00fb, 0x00, {0x00,0x30,0x78,0xCC,0x84,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00f9, 0x00, {0x00,0x60,0x30,0x18,0x0C,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00ff, 0x00, {0x00,0x00,0x00,0xC6,0xC6,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x0C,0x78,0x00}},
+  { 0x00d6, 0x00, {0xC6,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00dc, 0x00, {0xC6,0xC6,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00a2, 0x00, {0x08,0x08,0x3C,0x6E,0xCA,0xC8,0xC8,0xC8,0xC8,0xC8,0xC8,0xCA,0x6E,0x3C,0x08,0x08,0x00,0x00,0x00}},
+  { 0x00a3, 0x00, {0x00,0x38,0x6C,0x64,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0x62,0xE6,0xFC,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00a5, 0x00, {0x00,0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x18,0x7E,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00}},
+  { 0x20a7, 0x00, {0x00,0xF8,0xCC,0xCC,0xFC,0xF8,0xC4,0xCC,0xDE,0xCC,0xCC,0xCC,0xCC,0xC6,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0192, 0x00, {0x00,0x0E,0x1B,0x19,0x18,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x18,0x98,0xD8,0x70,0x00,0x00,0x00}},
+  { 0x00e1, 0x00, {0x00,0x18,0x30,0x60,0xC0,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00ed, 0x00, {0x00,0x0C,0x18,0x30,0x20,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00f3, 0x00, {0x00,0x18,0x30,0x60,0x40,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00fa, 0x00, {0x00,0x18,0x30,0x60,0x40,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00f1, 0x00, {0x00,0x00,0x36,0xD4,0x88,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00d1, 0x00, {0x36,0xCC,0x00,0xC6,0xE6,0xF6,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00aa, 0x00, {0x00,0x3C,0x6C,0x6C,0x6C,0x3E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00ba, 0x00, {0x00,0x38,0x6C,0x6C,0x6C,0x38,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00bf, 0x00, {0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x30,0x60,0xC0,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2310, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00ac, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00bd, 0x00, {0x00,0xC0,0xC0,0xC0,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC0,0x9C,0x06,0x0C,0x18,0x3E,0x00,0x00,0x00}},
+  { 0x00bc, 0x00, {0x00,0xC0,0xC0,0xC0,0xC2,0xC6,0x0C,0x18,0x30,0x66,0xCE,0x9A,0x32,0x3E,0x06,0x06,0x00,0x00,0x00}},
+  { 0x00a1, 0x00, {0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x3C,0x3C,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00ab, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x6C,0xD8,0xD8,0x6C,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00bb, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0xD8,0x6C,0x36,0x36,0x6C,0xD8,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2591, 0x00, {0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11}},
+  { 0x2592, 0x00, {0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55}},
+  { 0x2593, 0x00, {0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD}},
+  { 0x2502, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+  { 0x2524, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+  { 0x2561, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+  { 0x2562, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
+  { 0x2556, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
+  { 0x2555, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+  { 0x2563, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
+  { 0x2551, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
+  { 0x2557, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
+  { 0x255d, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x255c, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x255b, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2510, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+  { 0x2514, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2534, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x252c, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+  { 0x251c, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+  { 0x2500, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x253c, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+  { 0x255e, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+  { 0x255f, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
+  { 0x255a, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2554, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
+  { 0x2569, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2566, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
+  { 0x2560, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
+  { 0x2550, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x256c, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
+  { 0x2567, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2568, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2564, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+  { 0x2565, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
+  { 0x2559, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2558, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2552, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+  { 0x2553, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
+  { 0x256b, 0x00, {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36}},
+  { 0x256a, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+  { 0x2518, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x250c, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+  { 0x2588, 0x00, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},
+  { 0x2584, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},
+  { 0x258c, 0x00, {0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0}},
+  { 0x2590, 0x00, {0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F}},
+  { 0x2580, 0x00, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x03b1, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0xD8,0xD8,0xD8,0xD8,0xDC,0x76,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00df, 0x00, {0x00,0x00,0x78,0xCC,0xCC,0xCC,0xCC,0xD8,0xCC,0xC6,0xC6,0xC6,0xC6,0xCC,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0393, 0x00, {0x00,0x00,0xFE,0xC6,0xC6,0xC6,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00}},
+  { 0x03c0, 0x00, {0x00,0x00,0x00,0x00,0xFE,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x03a3, 0x00, {0x00,0x00,0x00,0xFE,0xC6,0xC2,0x60,0x30,0x18,0x30,0x60,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00,0x00}},
+  { 0x03c3, 0x00, {0x00,0x00,0x00,0x00,0x00,0x7E,0xD8,0xD8,0xD8,0xD8,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00b5, 0x00, {0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xC0,0x00,0x00,0x00,0x00}},
+  { 0x03c4, 0x00, {0x00,0x00,0x00,0x00,0x76,0xDC,0x98,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00}},
+  { 0x03a6, 0x00, {0x00,0x00,0x00,0x7E,0x18,0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0398, 0x00, {0x00,0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00,0x00}},
+  { 0x03a9, 0x00, {0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0xC6,0x6C,0x6C,0x6C,0x6C,0x6C,0xEE,0x00,0x00,0x00,0x00,0x00}},
+  { 0x03b4, 0x00, {0x00,0x00,0x1E,0x20,0x30,0x18,0x0C,0x3E,0x66,0x66,0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x221e, 0x00, {0x00,0x00,0x00,0x00,0x00,0x7E,0xDB,0xDB,0xDB,0xDB,0xDB,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x03c6, 0x00, {0x00,0x00,0x00,0x03,0x06,0x7E,0xDB,0xDB,0xDB,0xDB,0xD3,0x7E,0x60,0xC0,0x00,0x00,0x00,0x00,0x00}},
+  { 0x03b5, 0x00, {0x00,0x00,0x1C,0x30,0x60,0x60,0x60,0x7C,0x60,0x60,0x60,0x60,0x30,0x1C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2229, 0x00, {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2261, 0x00, {0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00b1, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2265, 0x00, {0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x7E,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2264, 0x00, {0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x7E,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2320, 0x00, {0x00,0x00,0x0E,0x1B,0x1B,0x1B,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}},
+  { 0x2321, 0x00, {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xD8,0xD8,0x70,0x00,0x00}},
+  { 0x00f7, 0x00, {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7E,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2248, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00b0, 0x00, {0x00,0x38,0x6C,0x6C,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x2219, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00b7, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x221a, 0x00, {0x00,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xEC,0x6C,0x6C,0x6C,0x3C,0x1C,0x00,0x00,0x00,0x00,0x00}},
+  { 0x207f, 0x00, {0x00,0xD8,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00b2, 0x00, {0x00,0x70,0xD8,0x10,0x30,0x60,0xC8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x25a0, 0x00, {0x00,0x00,0x00,0x00,0x00,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x00a0, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  { 0x0000, 0x00, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} //EOL
+};
+
+// Get available Unicode glyphs narrow fonts(8*19 pixels) size.
+UINT32 mNarrowFontSize =  sizeof (gUsStdNarrowGlyphData);
+
diff --git a/Platform/Broadcom/Bcm283x/Include/Protocol/ExtendedTextOut.h b/Platform/Broadcom/Bcm283x/Include/Protocol/ExtendedTextOut.h
new file mode 100644
index 000000000000..35e82a17e922
--- /dev/null
+++ b/Platform/Broadcom/Bcm283x/Include/Protocol/ExtendedTextOut.h
@@ -0,0 +1,36 @@
+/** @file
+ *
+ *  Copyright (c) 2018, Andrei Warkentin <andrey.warkentin at gmail.com>
+ *
+ *  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.
+ *
+ **/
+
+#ifndef __EXTENDED_TEXT_OUT_H__
+#define __EXTENDED_TEXT_OUT_H__
+
+#include <Protocol/SimpleTextOut.h>
+#include <Protocol/GraphicsOutput.h>
+
+#define EXTENDED_TEXT_OUTPUT_PROTOCOL_GUID \
+  { \
+    0x387477ff, 0xffc7, 0xffd2, {0x8e, 0x39, 0x0, 0xff, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+typedef struct _EXTENDED_TEXT_OUTPUT_PROTOCOL EXTENDED_TEXT_OUTPUT_PROTOCOL;
+
+struct _EXTENDED_TEXT_OUTPUT_PROTOCOL {
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;
+  BOOLEAN                         AutoWrap;
+};
+
+extern EFI_GUID gExtendedTextOutputProtocolGuid;
+
+#endif /* __EXTENDED_TEXT_OUT__ */
-- 
2.17.0.windows.1



More information about the edk2-devel mailing list