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_BOOT_MANAGER_LOAD_OPTION         NewOption;
    345   EFI_BOOT_MANAGER_LOAD_OPTION        *BootOptions;
    346   UINTN                                BootOptionCount;
    347   INTN                                 OptionIndex;
    348 
    349   //
    350   // Get PcdSdBootDevicePath
    351   //
    352   BootPathStr = (CHAR16 *)PcdGetPtr (PcdSdBootDevicePath);
    353   ASSERT (BootPathStr != NULL);
    354   Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
    355   ASSERT_EFI_ERROR(Status);
    356   DevicePath = (EFI_DEVICE_PATH *)EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (BootPathStr);
    357   ASSERT (DevicePath != NULL);
    358 
    359   Status = EfiBootManagerInitializeLoadOption (
    360              &NewOption,
    361              LoadOptionNumberUnassigned,
    362              LoadOptionTypeBoot,
    363              LOAD_OPTION_ACTIVE,
    364              L"Boot from SD",
    365              DevicePath,
    366              NULL,
    367              0
    368              );
    369   ASSERT_EFI_ERROR (Status);
    370   FreePool (DevicePath);
    371 
    372   BootOptions = EfiBootManagerGetLoadOptions (
    373                   &BootOptionCount, LoadOptionTypeBoot
    374                   );
    375 
    376   OptionIndex = EfiBootManagerFindLoadOption (
    377                   &NewOption, BootOptions, BootOptionCount
    378                   );
    379 
    380   if (OptionIndex == -1) {
    381     Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
    382     ASSERT_EFI_ERROR (Status);
    383   }
    384 
    385   EfiBootManagerFreeLoadOption (&NewOption);
    386   EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
    387 }
    388 
    389 STATIC
    390 VOID
    391 PlatformRegisterBootGrub (
    392   VOID
    393   )
    394 {
    395   EFI_STATUS                           Status;
    396   CHAR16                              *BootPathStr;
    397   EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL  *EfiDevicePathFromTextProtocol;
    398   EFI_DEVICE_PATH                     *DevicePath;
    399   EFI_DEVICE_PATH                     *FileDevicePath;
    400   FILEPATH_DEVICE_PATH                *FilePath;
    401   UINTN                                Size;
    402   EFI_BOOT_MANAGER_LOAD_OPTION         NewOption;
    403   EFI_BOOT_MANAGER_LOAD_OPTION        *BootOptions;
    404   UINTN                                BootOptionCount;
    405   INTN                                 OptionIndex;
    406 
    407   //
    408   // Get PcdAndroidBootDevicePath
    409   //
    410   BootPathStr = (CHAR16 *)PcdGetPtr (PcdAndroidBootDevicePath);
    411   ASSERT (BootPathStr != NULL);
    412   Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
    413   ASSERT_EFI_ERROR(Status);
    414   DevicePath = (EFI_DEVICE_PATH *)EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (BootPathStr);
    415   ASSERT (DevicePath != NULL);
    416 
    417   Size = StrSize (GRUB_FILE_NAME);
    418   FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH);
    419   if (FileDevicePath != NULL) {
    420     FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath;
    421     FilePath->Header.Type    = MEDIA_DEVICE_PATH;
    422     FilePath->Header.SubType = MEDIA_FILEPATH_DP;
    423     CopyMem (&FilePath->PathName, GRUB_FILE_NAME, Size);
    424     SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
    425     SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));
    426 
    427     DevicePath = AppendDevicePath (DevicePath, FileDevicePath);
    428     FreePool (FileDevicePath);
    429   }
    430   Status = EfiBootManagerInitializeLoadOption (
    431              &NewOption,
    432              LoadOptionNumberUnassigned,
    433              LoadOptionTypeBoot,
    434              LOAD_OPTION_ACTIVE,
    435              L"Grub",
    436              DevicePath,
    437              NULL,
    438              0
    439              );
    440   ASSERT_EFI_ERROR (Status);
    441   FreePool (DevicePath);
    442 
    443   BootOptions = EfiBootManagerGetLoadOptions (
    444                   &BootOptionCount, LoadOptionTypeBoot
    445                   );
    446 
    447   OptionIndex = EfiBootManagerFindLoadOption (
    448                   &NewOption, BootOptions, BootOptionCount
    449                   );
    450 
    451   if (OptionIndex == -1) {
    452     Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
    453     ASSERT_EFI_ERROR (Status);
    454   }
    455 
    456   EfiBootManagerFreeLoadOption (&NewOption);
    457   EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
    458 
    459 }
    460 
    461 STATIC
    462 VOID
    463 PlatformRegisterOptionsAndKeys (
    464   VOID
    465   )
    466 {
    467   EFI_STATUS                           Status;
    468   EFI_INPUT_KEY                        Enter;
    469   EFI_INPUT_KEY                        Esc;
    470   EFI_INPUT_KEY                        KeyF;
    471   EFI_BOOT_MANAGER_LOAD_OPTION         BootOption;
    472 
    473   //
    474   // Register Boot on SD. OptionNumber is 1.
    475   //
    476   PlatformRegisterBootSd ();
    477 
    478   //
    479   // Register Boot. OptionNumber is 2.
    480   //
    481   PlatformRegisterBootGrub ();
    482 
    483   //
    484   // Register Android Boot. OptionNumber is 3.
    485   //
    486   PlatformRegisterFvBootOption (
    487     PcdGetPtr (PcdAndroidBootFile), L"Android Boot", LOAD_OPTION_ACTIVE
    488     );
    489 
    490   //
    491   // Register Android Fastboot. OptionNumber is 4.
    492   //
    493   PlatformRegisterFvBootOption (
    494     PcdGetPtr (PcdAndroidFastbootFile), L"Android Fastboot", LOAD_OPTION_ACTIVE
    495     );
    496 
    497   //
    498   // Register ENTER as CONTINUE key
    499   //
    500   Enter.ScanCode    = SCAN_NULL;
    501   Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
    502   Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
    503   ASSERT_EFI_ERROR (Status);
    504 
    505   //
    506   // Map ESC to Boot Manager Menu
    507   //
    508   Esc.ScanCode    = SCAN_ESC;
    509   Esc.UnicodeChar = CHAR_NULL;
    510   Status = EfiBootManagerGetBootManagerMenu (&BootOption);
    511   ASSERT_EFI_ERROR (Status);
    512   Status = EfiBootManagerAddKeyOptionVariable (
    513              NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL
    514              );
    515   ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
    516 
    517   //
    518   // Map KeyF to Android Fastboot
    519   //
    520   KeyF.ScanCode    = SCAN_NULL;
    521   KeyF.UnicodeChar = 'f';
    522   Status = EfiBootManagerAddKeyOptionVariable (
    523              NULL, 4, 0, &KeyF, NULL
    524              );
    525   ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
    526 }
    527 
    528 
    529 //
    530 // BDS Platform Functions
    531 //
    532 /**
    533   Do the platform init, can be customized by OEM/IBV
    534   Possible things that can be done in PlatformBootManagerBeforeConsole:
    535   > Update console variable: 1. include hot-plug devices;
    536   >                          2. Clear ConIn and add SOL for AMT
    537   > Register new Driver#### or Boot####
    538   > Register new Key####: e.g.: F12
    539   > Signal ReadyToLock event
    540   > Authentication action: 1. connect Auth devices;
    541   >                        2. Identify auto logon user.
    542 **/
    543 VOID
    544 EFIAPI
    545 PlatformBootManagerBeforeConsole (
    546   VOID
    547   )
    548 {
    549   //
    550   // Signal EndOfDxe PI Event
    551   //
    552   EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
    553 
    554   //
    555   // Now add the device path of all handles with GOP on them to ConOut and
    556   // ErrOut.
    557   //
    558   FilterAndProcess (&gEfiGraphicsOutputProtocolGuid, NULL, AddOutput);
    559 
    560   //
    561   // Add the hardcoded short-form USB keyboard device path to ConIn.
    562   //
    563   EfiBootManagerUpdateConsoleVariable (ConIn,
    564     (EFI_DEVICE_PATH_PROTOCOL *)&mUsbKeyboard, NULL);
    565 
    566   //
    567   // Add the hardcoded serial console device path to ConIn, ConOut, ErrOut.
    568   //
    569   ASSERT (FixedPcdGet8 (PcdDefaultTerminalType) == 4);
    570   CopyGuid (&mSerialConsole.TermType.Guid, &gEfiTtyTermGuid);
    571 
    572   EfiBootManagerUpdateConsoleVariable (ConIn,
    573     (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);
    574   EfiBootManagerUpdateConsoleVariable (ConOut,
    575     (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);
    576   EfiBootManagerUpdateConsoleVariable (ErrOut,
    577     (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);
    578 
    579   //
    580   // Register platform-specific boot options and keyboard shortcuts.
    581   //
    582   PlatformRegisterOptionsAndKeys ();
    583 }
    584 
    585 /**
    586   Do the platform specific action after the console is ready
    587   Possible things that can be done in PlatformBootManagerAfterConsole:
    588   > Console post action:
    589     > Dynamically switch output mode from 100x31 to 80x25 for certain senarino
    590     > Signal console ready platform customized event
    591   > Run diagnostics like memory testing
    592   > Connect certain devices
    593   > Dispatch aditional option roms
    594   > Special boot: e.g.: USB boot, enter UI
    595 **/
    596 VOID
    597 EFIAPI
    598 PlatformBootManagerAfterConsole (
    599   VOID
    600   )
    601 {
    602   Print (L"Press ESCAPE for boot options ");
    603 
    604   //
    605   // Show the splash screen.
    606   //
    607   EnableQuietBoot (PcdGetPtr (PcdLogoFile));
    608 
    609   //
    610   // Connect the rest of the devices.
    611   //
    612   EfiBootManagerConnectAll ();
    613 
    614   //
    615   // Enumerate all possible boot options.
    616   //
    617   EfiBootManagerRefreshAllBootOption ();
    618 
    619   //
    620   // Register UEFI Shell
    621   //
    622   PlatformRegisterFvBootOption (
    623     PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE
    624     );
    625 }
    626 
    627 /**
    628   This function is called each second during the boot manager waits the
    629   timeout.
    630 
    631   @param TimeoutRemain  The remaining timeout.
    632 **/
    633 VOID
    634 EFIAPI
    635 PlatformBootManagerWaitCallback (
    636   UINT16          TimeoutRemain
    637   )
    638 {
    639   Print (L".");
    640 }
    641