Home | History | Annotate | Download | only in PlatformBootManagerLib
      1 /** @file
      2   Implementation for PlatformBootManagerLib library class interfaces.
      3 
      4   Copyright (C) 2015-2016, Red Hat, Inc.
      5   Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
      6   Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
      7   Copyright (c) 2016-2017, Linaro Ltd. All rights reserved.<BR>
      8 
      9   This program and the accompanying materials are licensed and made available
     10   under the terms and conditions of the BSD License which accompanies this
     11   distribution. The full text of the license may be found at
     12   http://opensource.org/licenses/bsd-license.php
     13 
     14   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
     15   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     16 
     17 **/
     18 
     19 #include <Library/DevicePathLib.h>
     20 #include <Library/PcdLib.h>
     21 #include <Library/UefiBootManagerLib.h>
     22 #include <Library/UefiLib.h>
     23 #include <Protocol/BlockIo.h>
     24 #include <Protocol/DevicePath.h>
     25 #include <Protocol/DevicePathFromText.h>
     26 #include <Protocol/DevicePathToText.h>
     27 #include <Protocol/GraphicsOutput.h>
     28 #include <Protocol/LoadedImage.h>
     29 #include <Guid/EventGroup.h>
     30 #include <Guid/TtyTerm.h>
     31 
     32 #include "PlatformBm.h"
     33 
     34 #define DP_NODE_LEN(Type) { (UINT8)sizeof (Type), (UINT8)(sizeof (Type) >> 8) }
     35 
     36 #define GRUB_FILE_NAME       L"\\EFI\\BOOT\\GRUBAA64.EFI"
     37 #define SD_FILE_NAME         L"\\EFI\\BOOT\\BOOTAA64.EFI"
     38 
     39 
     40 #pragma pack (1)
     41 typedef struct {
     42   VENDOR_DEVICE_PATH         SerialDxe;
     43   UART_DEVICE_PATH           Uart;
     44   VENDOR_DEFINED_DEVICE_PATH TermType;
     45   EFI_DEVICE_PATH_PROTOCOL   End;
     46 } PLATFORM_SERIAL_CONSOLE;
     47 #pragma pack ()
     48 
     49 #define SERIAL_DXE_FILE_GUID { \
     50           0xD3987D4B, 0x971A, 0x435F, \
     51           { 0x8C, 0xAF, 0x49, 0x67, 0xEB, 0x62, 0x72, 0x41 } \
     52           }
     53 
     54 STATIC PLATFORM_SERIAL_CONSOLE mSerialConsole = {
     55   //
     56   // VENDOR_DEVICE_PATH SerialDxe
     57   //
     58   {
     59     { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DP_NODE_LEN (VENDOR_DEVICE_PATH) },
     60     SERIAL_DXE_FILE_GUID
     61   },
     62 
     63   //
     64   // UART_DEVICE_PATH Uart
     65   //
     66   {
     67     { MESSAGING_DEVICE_PATH, MSG_UART_DP, DP_NODE_LEN (UART_DEVICE_PATH) },
     68     0,                                      // Reserved
     69     FixedPcdGet64 (PcdUartDefaultBaudRate), // BaudRate
     70     FixedPcdGet8 (PcdUartDefaultDataBits),  // DataBits
     71     FixedPcdGet8 (PcdUartDefaultParity),    // Parity
     72     FixedPcdGet8 (PcdUartDefaultStopBits)   // StopBits
     73   },
     74 
     75   //
     76   // VENDOR_DEFINED_DEVICE_PATH TermType
     77   //
     78   {
     79     {
     80       MESSAGING_DEVICE_PATH, MSG_VENDOR_DP,
     81       DP_NODE_LEN (VENDOR_DEFINED_DEVICE_PATH)
     82     }
     83     //
     84     // Guid to be filled in dynamically
     85     //
     86   },
     87 
     88   //
     89   // EFI_DEVICE_PATH_PROTOCOL End
     90   //
     91   {
     92     END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
     93     DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL)
     94   }
     95 };
     96 
     97 
     98 #pragma pack (1)
     99 typedef struct {
    100   USB_CLASS_DEVICE_PATH    Keyboard;
    101   EFI_DEVICE_PATH_PROTOCOL End;
    102 } PLATFORM_USB_KEYBOARD;
    103 #pragma pack ()
    104 
    105 STATIC PLATFORM_USB_KEYBOARD mUsbKeyboard = {
    106   //
    107   // USB_CLASS_DEVICE_PATH Keyboard
    108   //
    109   {
    110     {
    111       MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP,
    112       DP_NODE_LEN (USB_CLASS_DEVICE_PATH)
    113     },
    114     0xFFFF, // VendorId: any
    115     0xFFFF, // ProductId: any
    116     3,      // DeviceClass: HID
    117     1,      // DeviceSubClass: boot
    118     1       // DeviceProtocol: keyboard
    119   },
    120 
    121   //
    122   // EFI_DEVICE_PATH_PROTOCOL End
    123   //
    124   {
    125     END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
    126     DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL)
    127   }
    128 };
    129 
    130 
    131 /**
    132   Check if the handle satisfies a particular condition.
    133 
    134   @param[in] Handle      The handle to check.
    135   @param[in] ReportText  A caller-allocated string passed in for reporting
    136                          purposes. It must never be NULL.
    137 
    138   @retval TRUE   The condition is satisfied.
    139   @retval FALSE  Otherwise. This includes the case when the condition could not
    140                  be fully evaluated due to an error.
    141 **/
    142 typedef
    143 BOOLEAN
    144 (EFIAPI *FILTER_FUNCTION) (
    145   IN EFI_HANDLE   Handle,
    146   IN CONST CHAR16 *ReportText
    147   );
    148 
    149 
    150 /**
    151   Process a handle.
    152 
    153   @param[in] Handle      The handle to process.
    154   @param[in] ReportText  A caller-allocated string passed in for reporting
    155                          purposes. It must never be NULL.
    156 **/
    157 typedef
    158 VOID
    159 (EFIAPI *CALLBACK_FUNCTION)  (
    160   IN EFI_HANDLE   Handle,
    161   IN CONST CHAR16 *ReportText
    162   );
    163 
    164 /**
    165   Locate all handles that carry the specified protocol, filter them with a
    166   callback function, and pass each handle that passes the filter to another
    167   callback.
    168 
    169   @param[in] ProtocolGuid  The protocol to look for.
    170 
    171   @param[in] Filter        The filter function to pass each handle to. If this
    172                            parameter is NULL, then all handles are processed.
    173 
    174   @param[in] Process       The callback function to pass each handle to that
    175                            clears the filter.
    176 **/
    177 STATIC
    178 VOID
    179 FilterAndProcess (
    180   IN EFI_GUID          *ProtocolGuid,
    181   IN FILTER_FUNCTION   Filter         OPTIONAL,
    182   IN CALLBACK_FUNCTION Process
    183   )
    184 {
    185   EFI_STATUS Status;
    186   EFI_HANDLE *Handles;
    187   UINTN      NoHandles;
    188   UINTN      Idx;
    189 
    190   Status = gBS->LocateHandleBuffer (ByProtocol, ProtocolGuid,
    191                   NULL /* SearchKey */, &NoHandles, &Handles);
    192   if (EFI_ERROR (Status)) {
    193     //
    194     // This is not an error, just an informative condition.
    195     //
    196     DEBUG ((DEBUG_VERBOSE, "%a: %g: %r\n", __FUNCTION__, ProtocolGuid,
    197       Status));
    198     return;
    199   }
    200 
    201   ASSERT (NoHandles > 0);
    202   for (Idx = 0; Idx < NoHandles; ++Idx) {
    203     CHAR16        *DevicePathText;
    204     STATIC CHAR16 Fallback[] = L"<device path unavailable>";
    205 
    206     //
    207     // The ConvertDevicePathToText() function handles NULL input transparently.
    208     //
    209     DevicePathText = ConvertDevicePathToText (
    210                        DevicePathFromHandle (Handles[Idx]),
    211                        FALSE, // DisplayOnly
    212                        FALSE  // AllowShortcuts
    213                        );
    214     if (DevicePathText == NULL) {
    215       DevicePathText = Fallback;
    216     }
    217 
    218     if (Filter == NULL || Filter (Handles[Idx], DevicePathText)) {
    219       Process (Handles[Idx], DevicePathText);
    220     }
    221 
    222     if (DevicePathText != Fallback) {
    223       FreePool (DevicePathText);
    224     }
    225   }
    226   gBS->FreePool (Handles);
    227 }
    228 
    229 
    230 /**
    231   This CALLBACK_FUNCTION retrieves the EFI_DEVICE_PATH_PROTOCOL from the
    232   handle, and adds it to ConOut and ErrOut.
    233 **/
    234 STATIC
    235 VOID
    236 EFIAPI
    237 AddOutput (
    238   IN EFI_HANDLE   Handle,
    239   IN CONST CHAR16 *ReportText
    240   )
    241 {
    242   EFI_STATUS               Status;
    243   EFI_DEVICE_PATH_PROTOCOL *DevicePath;
    244 
    245   DevicePath = DevicePathFromHandle (Handle);
    246   if (DevicePath == NULL) {
    247     DEBUG ((DEBUG_ERROR, "%a: %s: handle %p: device path not found\n",
    248       __FUNCTION__, ReportText, Handle));
    249     return;
    250   }
    251 
    252   Status = EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
    253   if (EFI_ERROR (Status)) {
    254     DEBUG ((DEBUG_ERROR, "%a: %s: adding to ConOut: %r\n", __FUNCTION__,
    255       ReportText, Status));
    256     return;
    257   }
    258 
    259   Status = EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
    260   if (EFI_ERROR (Status)) {
    261     DEBUG ((DEBUG_ERROR, "%a: %s: adding to ErrOut: %r\n", __FUNCTION__,
    262       ReportText, Status));
    263     return;
    264   }
    265 
    266   DEBUG ((DEBUG_VERBOSE, "%a: %s: added to ConOut and ErrOut\n", __FUNCTION__,
    267     ReportText));
    268 }
    269 
    270 STATIC
    271 VOID
    272 PlatformRegisterFvBootOption (
    273   EFI_GUID                         *FileGuid,
    274   CHAR16                           *Description,
    275   UINT32                           Attributes
    276   )
    277 {
    278   EFI_STATUS                        Status;
    279   INTN                              OptionIndex;
    280   EFI_BOOT_MANAGER_LOAD_OPTION      NewOption;
    281   EFI_BOOT_MANAGER_LOAD_OPTION      *BootOptions;
    282   UINTN                             BootOptionCount;
    283   MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
    284   EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;
    285   EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
    286 
    287   Status = gBS->HandleProtocol (
    288                   gImageHandle,
    289                   &gEfiLoadedImageProtocolGuid,
    290                   (VOID **) &LoadedImage
    291                   );
    292   ASSERT_EFI_ERROR (Status);
    293 
    294   EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
    295   DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
    296   ASSERT (DevicePath != NULL);
    297   DevicePath = AppendDevicePathNode (
    298                  DevicePath,
    299                  (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
    300                  );
    301   ASSERT (DevicePath != NULL);
    302 
    303   Status = EfiBootManagerInitializeLoadOption (
    304              &NewOption,
    305              LoadOptionNumberUnassigned,
    306              LoadOptionTypeBoot,
    307              Attributes,
    308              Description,
    309              DevicePath,
    310              NULL,
    311              0
    312              );
    313   ASSERT_EFI_ERROR (Status);
    314   FreePool (DevicePath);
    315 
    316   BootOptions = EfiBootManagerGetLoadOptions (
    317                   &BootOptionCount, LoadOptionTypeBoot
    318                   );
    319 
    320   OptionIndex = EfiBootManagerFindLoadOption (
    321                   &NewOption, BootOptions, BootOptionCount
    322                   );
    323 
    324   if (OptionIndex == -1) {
    325     Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
    326     ASSERT_EFI_ERROR (Status);
    327   }
    328 
    329   EfiBootManagerFreeLoadOption (&NewOption);
    330   EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
    331 }
    332 
    333 
    334 STATIC
    335 VOID
    336 PlatformRegisterBootSd (
    337   VOID
    338   )
    339 {
    340   EFI_STATUS                           Status;
    341   CHAR16                              *BootPathStr;
    342   EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL  *EfiDevicePathFromTextProtocol;
    343   EFI_DEVICE_PATH                     *DevicePath;
    344   EFI_DEVICE_PATH                     *FileDevicePath;
    345   FILEPATH_DEVICE_PATH                *FilePath;
    346   UINTN                                Size;
    347   EFI_BOOT_MANAGER_LOAD_OPTION         NewOption;
    348   EFI_BOOT_MANAGER_LOAD_OPTION        *BootOptions;
    349   UINTN                                BootOptionCount;
    350   INTN                                 OptionIndex;
    351 
    352   //
    353   // Get PcdSdBootDevicePath
    354   //
    355   BootPathStr = (CHAR16 *)PcdGetPtr (PcdSdBootDevicePath);
    356   ASSERT (BootPathStr != NULL);
    357   Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
    358   ASSERT_EFI_ERROR(Status);
    359   DevicePath = (EFI_DEVICE_PATH *)EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (BootPathStr);
    360   ASSERT (DevicePath != NULL);
    361 
    362   Size = StrSize (SD_FILE_NAME);
    363   FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH);
    364   if (FileDevicePath != NULL) {
    365     FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath;
    366     FilePath->Header.Type    = MEDIA_DEVICE_PATH;
    367     FilePath->Header.SubType = MEDIA_FILEPATH_DP;
    368     CopyMem (&FilePath->PathName, SD_FILE_NAME, Size);
    369     SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
    370     SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));
    371 
    372     DevicePath = AppendDevicePath (DevicePath, FileDevicePath);
    373     FreePool (FileDevicePath);
    374   }
    375   Status = EfiBootManagerInitializeLoadOption (
    376              &NewOption,
    377              LoadOptionNumberUnassigned,
    378              LoadOptionTypeBoot,
    379              LOAD_OPTION_ACTIVE,
    380              L"Boot from SD",
    381              DevicePath,
    382              NULL,
    383              0
    384              );
    385   ASSERT_EFI_ERROR (Status);
    386   FreePool (DevicePath);
    387 
    388   BootOptions = EfiBootManagerGetLoadOptions (
    389                   &BootOptionCount, LoadOptionTypeBoot
    390                   );
    391 
    392   OptionIndex = EfiBootManagerFindLoadOption (
    393                   &NewOption, BootOptions, BootOptionCount
    394                   );
    395 
    396   if (OptionIndex == -1) {
    397     Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
    398     ASSERT_EFI_ERROR (Status);
    399   }
    400 
    401   EfiBootManagerFreeLoadOption (&NewOption);
    402   EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
    403 }
    404 
    405 STATIC
    406 VOID
    407 PlatformRegisterBootGrub (
    408   VOID
    409   )
    410 {
    411   EFI_STATUS                           Status;
    412   CHAR16                              *BootPathStr;
    413   EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL  *EfiDevicePathFromTextProtocol;
    414   EFI_DEVICE_PATH                     *DevicePath;
    415   EFI_DEVICE_PATH                     *FileDevicePath;
    416   FILEPATH_DEVICE_PATH                *FilePath;
    417   UINTN                                Size;
    418   EFI_BOOT_MANAGER_LOAD_OPTION         NewOption;
    419   EFI_BOOT_MANAGER_LOAD_OPTION        *BootOptions;
    420   UINTN                                BootOptionCount;
    421   INTN                                 OptionIndex;
    422 
    423   //
    424   // Get PcdAndroidBootDevicePath
    425   //
    426   BootPathStr = (CHAR16 *)PcdGetPtr (PcdAndroidBootDevicePath);
    427   ASSERT (BootPathStr != NULL);
    428   Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
    429   ASSERT_EFI_ERROR(Status);
    430   DevicePath = (EFI_DEVICE_PATH *)EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (BootPathStr);
    431   ASSERT (DevicePath != NULL);
    432 
    433   Size = StrSize (GRUB_FILE_NAME);
    434   FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH);
    435   if (FileDevicePath != NULL) {
    436     FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath;
    437     FilePath->Header.Type    = MEDIA_DEVICE_PATH;
    438     FilePath->Header.SubType = MEDIA_FILEPATH_DP;
    439     CopyMem (&FilePath->PathName, GRUB_FILE_NAME, Size);
    440     SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
    441     SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));
    442 
    443     DevicePath = AppendDevicePath (DevicePath, FileDevicePath);
    444     FreePool (FileDevicePath);
    445   }
    446   Status = EfiBootManagerInitializeLoadOption (
    447              &NewOption,
    448              LoadOptionNumberUnassigned,
    449              LoadOptionTypeBoot,
    450              LOAD_OPTION_ACTIVE,
    451              L"Grub",
    452              DevicePath,
    453              NULL,
    454              0
    455              );
    456   ASSERT_EFI_ERROR (Status);
    457   FreePool (DevicePath);
    458 
    459   BootOptions = EfiBootManagerGetLoadOptions (
    460                   &BootOptionCount, LoadOptionTypeBoot
    461                   );
    462 
    463   OptionIndex = EfiBootManagerFindLoadOption (
    464                   &NewOption, BootOptions, BootOptionCount
    465                   );
    466 
    467   if (OptionIndex == -1) {
    468     Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
    469     ASSERT_EFI_ERROR (Status);
    470   }
    471 
    472   EfiBootManagerFreeLoadOption (&NewOption);
    473   EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
    474 
    475 }
    476 
    477 STATIC
    478 VOID
    479 PlatformRegisterOptionsAndKeys (
    480   VOID
    481   )
    482 {
    483   EFI_STATUS                           Status;
    484   EFI_INPUT_KEY                        Enter;
    485   EFI_INPUT_KEY                        Esc;
    486   EFI_INPUT_KEY                        KeyF;
    487   EFI_BOOT_MANAGER_LOAD_OPTION         BootOption;
    488 
    489   //
    490   // Register Boot on SD. OptionNumber is 1.
    491   //
    492   PlatformRegisterBootSd ();
    493 
    494   //
    495   // Register Boot. OptionNumber is 2.
    496   //
    497   PlatformRegisterBootGrub ();
    498 
    499   //
    500   // Register Android Boot. OptionNumber is 3.
    501   //
    502   PlatformRegisterFvBootOption (
    503     PcdGetPtr (PcdAndroidBootFile), L"Android Boot", LOAD_OPTION_ACTIVE
    504     );
    505 
    506   //
    507   // Register Android Fastboot. OptionNumber is 4.
    508   //
    509   PlatformRegisterFvBootOption (
    510     PcdGetPtr (PcdAndroidFastbootFile), L"Android Fastboot", LOAD_OPTION_ACTIVE
    511     );
    512 
    513   //
    514   // Register ENTER as CONTINUE key
    515   //
    516   Enter.ScanCode    = SCAN_NULL;
    517   Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
    518   Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
    519   ASSERT_EFI_ERROR (Status);
    520 
    521   //
    522   // Map ESC to Boot Manager Menu
    523   //
    524   Esc.ScanCode    = SCAN_ESC;
    525   Esc.UnicodeChar = CHAR_NULL;
    526   Status = EfiBootManagerGetBootManagerMenu (&BootOption);
    527   ASSERT_EFI_ERROR (Status);
    528   Status = EfiBootManagerAddKeyOptionVariable (
    529              NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL
    530              );
    531   ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
    532 
    533   //
    534   // Map KeyF to Android Fastboot
    535   //
    536   KeyF.ScanCode    = SCAN_NULL;
    537   KeyF.UnicodeChar = 'f';
    538   Status = EfiBootManagerAddKeyOptionVariable (
    539              NULL, 4, 0, &KeyF, NULL
    540              );
    541   ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
    542 }
    543 
    544 
    545 //
    546 // BDS Platform Functions
    547 //
    548 /**
    549   Do the platform init, can be customized by OEM/IBV
    550   Possible things that can be done in PlatformBootManagerBeforeConsole:
    551   > Update console variable: 1. include hot-plug devices;
    552   >                          2. Clear ConIn and add SOL for AMT
    553   > Register new Driver#### or Boot####
    554   > Register new Key####: e.g.: F12
    555   > Signal ReadyToLock event
    556   > Authentication action: 1. connect Auth devices;
    557   >                        2. Identify auto logon user.
    558 **/
    559 VOID
    560 EFIAPI
    561 PlatformBootManagerBeforeConsole (
    562   VOID
    563   )
    564 {
    565   //
    566   // Signal EndOfDxe PI Event
    567   //
    568   EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
    569 
    570   //
    571   // Now add the device path of all handles with GOP on them to ConOut and
    572   // ErrOut.
    573   //
    574   FilterAndProcess (&gEfiGraphicsOutputProtocolGuid, NULL, AddOutput);
    575 
    576   //
    577   // Add the hardcoded short-form USB keyboard device path to ConIn.
    578   //
    579   EfiBootManagerUpdateConsoleVariable (ConIn,
    580     (EFI_DEVICE_PATH_PROTOCOL *)&mUsbKeyboard, NULL);
    581 
    582   //
    583   // Add the hardcoded serial console device path to ConIn, ConOut, ErrOut.
    584   //
    585   ASSERT (FixedPcdGet8 (PcdDefaultTerminalType) == 4);
    586   CopyGuid (&mSerialConsole.TermType.Guid, &gEfiTtyTermGuid);
    587 
    588   EfiBootManagerUpdateConsoleVariable (ConIn,
    589     (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);
    590   EfiBootManagerUpdateConsoleVariable (ConOut,
    591     (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);
    592   EfiBootManagerUpdateConsoleVariable (ErrOut,
    593     (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);
    594 
    595   //
    596   // Register platform-specific boot options and keyboard shortcuts.
    597   //
    598   PlatformRegisterOptionsAndKeys ();
    599 }
    600 
    601 /**
    602   Do the platform specific action after the console is ready
    603   Possible things that can be done in PlatformBootManagerAfterConsole:
    604   > Console post action:
    605     > Dynamically switch output mode from 100x31 to 80x25 for certain senarino
    606     > Signal console ready platform customized event
    607   > Run diagnostics like memory testing
    608   > Connect certain devices
    609   > Dispatch aditional option roms
    610   > Special boot: e.g.: USB boot, enter UI
    611 **/
    612 VOID
    613 EFIAPI
    614 PlatformBootManagerAfterConsole (
    615   VOID
    616   )
    617 {
    618   Print (L"Press ESCAPE for boot options ");
    619 
    620   //
    621   // Show the splash screen.
    622   //
    623   EnableQuietBoot (PcdGetPtr (PcdLogoFile));
    624 
    625   //
    626   // Connect the rest of the devices.
    627   //
    628   EfiBootManagerConnectAll ();
    629 
    630   //
    631   // Enumerate all possible boot options.
    632   //
    633   EfiBootManagerRefreshAllBootOption ();
    634 
    635   //
    636   // Register UEFI Shell
    637   //
    638   PlatformRegisterFvBootOption (
    639     PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE
    640     );
    641 }
    642 
    643 /**
    644   This function is called each second during the boot manager waits the
    645   timeout.
    646 
    647   @param TimeoutRemain  The remaining timeout.
    648 **/
    649 VOID
    650 EFIAPI
    651 PlatformBootManagerWaitCallback (
    652   UINT16          TimeoutRemain
    653   )
    654 {
    655   Print (L".");
    656 }
    657