Home | History | Annotate | Download | only in PlatformBdsLib
      1 /** @file
      2 
      3   Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
      4 
      5   This program and the accompanying materials are licensed and made available under
      6   the terms and conditions of the BSD License that accompanies this distribution.
      7   The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php.
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 
     14 
     15 Module Name:
     16 
     17   BdsPlatform.c
     18 
     19 Abstract:
     20 
     21   This file include all platform action which can be customized
     22   by IBV/OEM.
     23 
     24 --*/
     25 
     26 #include "BdsPlatform.h"
     27 #include "SetupMode.h"
     28 #include <Guid/SetupVariable.h>
     29 #include <Library/TcgPhysicalPresenceLib.h>
     30 #include <Library/TrEEPhysicalPresenceLib.h>
     31 #include <Protocol/I2cMasterMcg.h>
     32 #include <TianoApi.h>
     33 #include <PlatformBaseAddresses.h>
     34 #include <Protocol/GlobalNvsArea.h>
     35 #include <Library/DxeServicesTableLib.h>
     36 #include <Protocol/BlockIo.h>
     37 #include <PchRegs/PchRegsPcu.h>
     38 #include <Library/S3BootScriptLib.h>
     39 #include "PchAccess.h"
     40 #include "PchRegs/PchRegsSata.h"
     41 #include <Library/SerialPortLib.h>
     42 #include <Library/DebugLib.h>
     43 
     44 #include <Library/GenericBdsLib/InternalBdsLib.h>
     45 #include <Library/GenericBdsLib/String.h>
     46 #include <Library/NetLib.h>
     47 
     48 #include <Library/CapsuleLib.h>
     49 #include <Protocol/EsrtManagement.h>
     50 
     51 EFI_GUID *ConnectDriverTable[] = {
     52   &gEfiMmioDeviceProtocolGuid,
     53   &gEfiI2cMasterProtocolGuid,
     54   &gEfiI2cHostProtocolGuid
     55 };
     56 
     57 #define SHELL_ENVIRONMENT_INTERFACE_PROTOCOL \
     58   { \
     59     0x47c7b221, 0xc42a, 0x11d2, 0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b \
     60   }
     61 VOID               *mShellImageCallbackReg = NULL;
     62 
     63 
     64 
     65 EFI_USER_PROFILE_HANDLE                           mCurrentUser = NULL;
     66 EFI_EVENT                                         mHotKeyTimerEvent = NULL;
     67 EFI_EVENT                                         mHitHotkeyEvent = NULL;
     68 EFI_EVENT                                         mUsbKeyboardConnectEvent = NULL;
     69 BOOLEAN                                           mHotKeyPressed = FALSE;
     70 VOID                                              *mHitHotkeyRegistration;
     71 #define KEYBOARD_TIMER_INTERVAL                   20000 // 0.02s
     72 
     73 VOID
     74 ConnectUSBController (
     75   VOID
     76   );
     77 
     78 EFI_STATUS
     79 PlatformBdsConnectSimpleConsole (
     80   IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole
     81 );
     82 
     83 VOID
     84 BootIntoFirmwareInterface(
     85   VOID
     86   );
     87 
     88 VOID
     89 EFIAPI
     90 PlatformBdsInitHotKeyEvent (
     91   VOID
     92   );
     93 
     94 VOID
     95 EFIAPI
     96 DisableAhciCtlr (
     97   IN EFI_EVENT                          Event,
     98   IN VOID                               *Context
     99   )
    100 {
    101   UINT32                    PmcDisableAddress;
    102   UINT8                     SataStorageAmount;
    103   UINT32                    SataBase;
    104   UINT16                    SataPortStatus;
    105 
    106 
    107   DEBUG ((EFI_D_INFO, "Disable AHCI event is signalled\n"));
    108   SataStorageAmount = 0;
    109   SataBase = *(UINT32*) Context;
    110 
    111   //
    112   // BayTrail-M EDS chapter 16 ---- PCI IO Register Offset 92 (SATA Port Control and Status)
    113   //
    114   SataPortStatus = MmioRead16 (SataBase + R_PCH_SATA_PCS);
    115 
    116   //
    117   // Bit 8 EN: Port 0 Present
    118   //
    119   if ((SataPortStatus & 0x100) == 0x100) {
    120     SataStorageAmount++;
    121   }
    122 
    123   //
    124   // Bit 9 EN: Port 1 Present
    125   //
    126   if ((SataPortStatus & 0x200) == 0x200) {
    127     SataStorageAmount++;
    128   }
    129 
    130   //
    131   // Disable SATA controller when it sets to AHCI mode without carrying any devices
    132   // in order to prevent AHCI yellow bang under Win device manager.
    133   //
    134   if (SataStorageAmount == 0) {
    135     PmcDisableAddress = (MmioRead32 ((PCH_PCI_EXPRESS_BASE_ADDRESS + (UINT32) (31 << 15)) + R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR) + R_PCH_PMC_FUNC_DIS;
    136     MmioOr32 (PmcDisableAddress, B_PCH_PMC_FUNC_DIS_SATA);
    137     S3BootScriptSaveMemWrite (
    138       EfiBootScriptWidthUint32,
    139       (UINTN) PmcDisableAddress,
    140       1,
    141       (VOID *) (UINTN) PmcDisableAddress
    142       );
    143   }
    144 }
    145 
    146 VOID
    147 InstallReadyToLock (
    148   VOID
    149   )
    150 {
    151   EFI_STATUS                Status;
    152   EFI_HANDLE                Handle;
    153   EFI_SMM_ACCESS2_PROTOCOL  *SmmAccess;
    154   EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;
    155 
    156   //
    157   // Install DxeSmmReadyToLock protocol prior to the processing of boot options
    158   //
    159   Status = gBS->LocateProtocol (
    160                   &gEfiSmmAccess2ProtocolGuid,
    161                   NULL,
    162                   (VOID **) &SmmAccess
    163                   );
    164   if (!EFI_ERROR (Status)) {
    165 
    166     //
    167     // Prepare S3 information, this MUST be done before DxeSmmReadyToLock
    168     //
    169     Status = gBS->LocateProtocol (
    170                     &gEfiAcpiS3SaveProtocolGuid,
    171                     NULL,
    172                     (VOID **)&AcpiS3Save
    173                     );
    174     if (!EFI_ERROR (Status)) {
    175       AcpiS3Save->S3Save (AcpiS3Save, NULL);
    176     }
    177 
    178     Handle = NULL;
    179     Status = gBS->InstallProtocolInterface (
    180                     &Handle,
    181                     &gExitPmAuthProtocolGuid,
    182                     EFI_NATIVE_INTERFACE,
    183                     NULL
    184                     );
    185     ASSERT_EFI_ERROR (Status);
    186 
    187     //
    188     // Signal EndOfDxe PI Event
    189     //
    190     EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
    191 
    192     Handle = NULL;
    193     Status = gBS->InstallProtocolInterface (
    194                     &Handle,
    195                     &gEfiDxeSmmReadyToLockProtocolGuid,
    196                     EFI_NATIVE_INTERFACE,
    197                     NULL
    198                     );
    199     ASSERT_EFI_ERROR (Status);
    200   }
    201 
    202   return ;
    203 }
    204 
    205 VOID
    206 EFIAPI
    207 ShellImageCallback (
    208   IN EFI_EVENT                          Event,
    209   IN VOID                               *Context
    210   )
    211 {
    212  BdsSetConsoleMode (TRUE);
    213  DEBUG ((EFI_D_INFO, "BdsEntry ShellImageCallback \n"));
    214 }
    215 
    216 //
    217 // BDS Platform Functions
    218 //
    219 /**
    220   Platform Bds init. Include the platform firmware vendor, revision
    221   and so crc check.
    222 
    223   @param VOID
    224 
    225   @retval  None.
    226 
    227 **/
    228 VOID
    229 EFIAPI
    230 PlatformBdsInit (
    231   VOID
    232   )
    233 {
    234   EFI_STATUS  Status;
    235   EFI_EVENT   ShellImageEvent;
    236   EFI_GUID    ShellEnvProtocol = SHELL_ENVIRONMENT_INTERFACE_PROTOCOL;
    237 
    238   #ifdef __GNUC__
    239   SerialPortWrite((UINT8 *)">>>>BdsEntry[GCC]\r\n", 19);
    240   #else
    241   SerialPortWrite((UINT8 *)">>>>BdsEntry\r\n", 14);
    242   #endif
    243   BdsLibSaveMemoryTypeInformation ();
    244 
    245   //
    246   // Before user authentication, the user identification devices need be connected
    247   // from the platform customized device paths
    248   //
    249   PlatformBdsConnectAuthDevice ();
    250 
    251   //
    252   // As console is not ready, the auto logon user will be identified.
    253   //
    254   BdsLibUserIdentify (&mCurrentUser);
    255 
    256   //
    257   // Change Gop mode when boot into Shell
    258   //
    259   if (mShellImageCallbackReg == NULL) {
    260     Status = gBS->CreateEvent (
    261                     EFI_EVENT_NOTIFY_SIGNAL,
    262                     EFI_TPL_CALLBACK,
    263                     ShellImageCallback,
    264                     NULL,
    265                     &ShellImageEvent
    266                     );
    267     if (!EFI_ERROR (Status)) {
    268       Status = gBS->RegisterProtocolNotify (
    269                       &ShellEnvProtocol,
    270                       ShellImageEvent,
    271                       &mShellImageCallbackReg
    272                       );
    273 
    274       DEBUG ((EFI_D_INFO, "BdsEntry ShellImageCallback \n"));
    275     }
    276   }
    277 }
    278 
    279 EFI_STATUS
    280 GetGopDevicePath (
    281    IN  EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,
    282    OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath
    283    )
    284 {
    285   UINTN                           Index;
    286   EFI_STATUS                      Status;
    287   EFI_HANDLE                      PciDeviceHandle;
    288   EFI_DEVICE_PATH_PROTOCOL        *TempDevicePath;
    289   EFI_DEVICE_PATH_PROTOCOL        *TempPciDevicePath;
    290   UINTN                           GopHandleCount;
    291   EFI_HANDLE                      *GopHandleBuffer;
    292 
    293   UINTN                                 VarSize;
    294   SYSTEM_CONFIGURATION  mSystemConfiguration;
    295 
    296   if (PciDevicePath == NULL || GopDevicePath == NULL) {
    297     return EFI_INVALID_PARAMETER;
    298   }
    299 
    300   //
    301   // Initialize the GopDevicePath to be PciDevicePath
    302   //
    303   *GopDevicePath    = PciDevicePath;
    304   TempPciDevicePath = PciDevicePath;
    305 
    306   Status = gBS->LocateDevicePath (
    307                   &gEfiDevicePathProtocolGuid,
    308                   &TempPciDevicePath,
    309                   &PciDeviceHandle
    310                   );
    311   if (EFI_ERROR (Status)) {
    312     return Status;
    313   }
    314 
    315   //
    316   // Try to connect this handle, so that GOP driver could start on this
    317   // device and create child handles with GraphicsOutput Protocol installed
    318   // on them, then we get device paths of these child handles and select
    319   // them as possible console device.
    320   //
    321 
    322   //
    323   // Select display devices
    324   //
    325   VarSize = sizeof(SYSTEM_CONFIGURATION);
    326   Status = gRT->GetVariable(
    327                   L"Setup",
    328                   &gEfiNormalSetupGuid,
    329                   NULL,
    330                   &VarSize,
    331                   &mSystemConfiguration
    332                   );
    333   if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
    334     //The setup variable is corrupted
    335     VarSize = sizeof(SYSTEM_CONFIGURATION);
    336     Status = gRT->GetVariable(
    337               L"SetupRecovery",
    338               &gEfiNormalSetupGuid,
    339               NULL,
    340               &VarSize,
    341               &mSystemConfiguration
    342               );
    343     ASSERT_EFI_ERROR (Status);
    344   }
    345 
    346   if(mSystemConfiguration.BootDisplayDevice != 0x0)
    347   {
    348     ACPI_ADR_DEVICE_PATH         AcpiAdr;
    349     EFI_DEVICE_PATH_PROTOCOL  *MyDevicePath = NULL;
    350 
    351     AcpiAdr.Header.Type     = ACPI_DEVICE_PATH;
    352     AcpiAdr.Header.SubType  = ACPI_ADR_DP;
    353 
    354     switch (mSystemConfiguration.BootDisplayDevice) {
    355     case 1:
    356       AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0);    //CRT Device
    357       break;
    358     case 2:
    359       AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_HDMI, 0);  //HDMI Device Port B
    360       break;
    361     case 3:
    362       AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_DP, 0);    //DP PortB
    363       break;
    364     case 4:
    365       AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_C_DP, 0);    //DP PortC
    366       break;
    367     case 5:
    368       AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_C_DP, 0);    //eDP Port C
    369       break;
    370     case 6:
    371       AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_A, 0);  //DSI Port A
    372       break;
    373     case 7:
    374       AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_C, 0);  //DSI Port C
    375       break;
    376     default:
    377       AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0);
    378       break;
    379     }
    380 
    381     SetDevicePathNodeLength (&AcpiAdr.Header, sizeof (ACPI_ADR_DEVICE_PATH));
    382 
    383     MyDevicePath = AppendDevicePathNode(MyDevicePath, (EFI_DEVICE_PATH_PROTOCOL*)&AcpiAdr);
    384 
    385     gBS->ConnectController (
    386            PciDeviceHandle,
    387            NULL,
    388            MyDevicePath,
    389            FALSE
    390            );
    391 
    392     FreePool(MyDevicePath);
    393   }
    394   else
    395   {
    396     gBS->ConnectController (
    397            PciDeviceHandle,
    398            NULL,
    399            NULL,
    400            FALSE
    401            );
    402   }
    403 
    404   Status = gBS->LocateHandleBuffer (
    405                   ByProtocol,
    406                   &gEfiGraphicsOutputProtocolGuid,
    407                   NULL,
    408                   &GopHandleCount,
    409                   &GopHandleBuffer
    410                   );
    411   if (!EFI_ERROR (Status)) {
    412     //
    413     // Add all the child handles as possible Console Device
    414     //
    415     for (Index = 0; Index < GopHandleCount; Index++) {
    416       Status = gBS->HandleProtocol (
    417                       GopHandleBuffer[Index],
    418                       &gEfiDevicePathProtocolGuid,
    419                       (VOID**)&TempDevicePath
    420                       );
    421       if (EFI_ERROR (Status)) {
    422         continue;
    423       }
    424       if (CompareMem (
    425             PciDevicePath,
    426             TempDevicePath,
    427             GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH
    428             ) == 0) {
    429         //
    430         // In current implementation, we only enable one of the child handles
    431         // as console device, i.e. sotre one of the child handle's device
    432         // path to variable "ConOut"
    433         // In future, we could select all child handles to be console device
    434         //
    435         *GopDevicePath = TempDevicePath;
    436       }
    437     }
    438     gBS->FreePool (GopHandleBuffer);
    439   }
    440 
    441   return EFI_SUCCESS;
    442 }
    443 
    444 /**
    445 
    446   Search out all the platform pci or agp video device. The function may will
    447   find multiple video device, and return all enabled device path.
    448 
    449   @param PlugInPciVgaDevicePath    Return the platform plug in pci video device
    450                                    path if the system have plug in pci video device.
    451   @param OnboardPciVgaDevicePath   Return the platform active agp video device path
    452                                    if the system have plug in agp video device or on
    453                                    chip agp device.
    454 
    455   @retval EFI_SUCCSS               Get all platform active video device path.
    456   @retval EFI_STATUS               Return the status of gBS->LocateDevicePath (),
    457                                    gBS->ConnectController (),
    458                                    and gBS->LocateHandleBuffer ().
    459 
    460 **/
    461 EFI_STATUS
    462 GetPlugInPciVgaDevicePath (
    463   IN OUT EFI_DEVICE_PATH_PROTOCOL     **PlugInPciVgaDevicePath,
    464   IN OUT EFI_DEVICE_PATH_PROTOCOL     **OnboardPciVgaDevicePath
    465   )
    466 {
    467   EFI_STATUS                Status;
    468   EFI_HANDLE                RootHandle;
    469   UINTN                     HandleCount;
    470   EFI_HANDLE                *HandleBuffer;
    471   UINTN                     Index;
    472   UINTN                     Index1;
    473   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
    474   BOOLEAN                   PlugInPciVga;
    475   EFI_PCI_IO_PROTOCOL       *PciIo;
    476   PCI_TYPE00                Pci;
    477 
    478   DevicePath = NULL;
    479   PlugInPciVga = TRUE;
    480   HandleCount = 0;
    481   HandleBuffer = NULL;
    482 
    483   //
    484   // Make all the PCI_IO protocols on PCI Seg 0 show up
    485   //
    486   BdsLibConnectDevicePath (gPlatformRootBridges[0]);
    487 
    488   Status = gBS->LocateDevicePath (
    489                   &gEfiDevicePathProtocolGuid,
    490                   &gPlatformRootBridges[0],
    491                   &RootHandle
    492                   );
    493   if (EFI_ERROR (Status)) {
    494     return Status;
    495   }
    496 
    497   Status = gBS->ConnectController (
    498                   RootHandle,
    499                   NULL,
    500                   NULL,
    501                   FALSE
    502                   );
    503   if (EFI_ERROR (Status)) {
    504     return Status;
    505   }
    506 
    507   //
    508   // Start to check all the pci io to find all possible VGA device
    509   //
    510   HandleCount = 0;
    511   HandleBuffer = NULL;
    512   Status = gBS->LocateHandleBuffer (
    513                   ByProtocol,
    514                   &gEfiPciIoProtocolGuid,
    515                   NULL,
    516                   &HandleCount,
    517                   &HandleBuffer
    518                   );
    519   if (EFI_ERROR (Status)) {
    520     return Status;
    521   }
    522 
    523   for (Index = 0; Index < HandleCount; Index++) {
    524     Status = gBS->HandleProtocol (
    525                     HandleBuffer[Index],
    526                     &gEfiPciIoProtocolGuid,
    527                     (VOID**)&PciIo
    528                     );
    529     if (!EFI_ERROR (Status)) {
    530 
    531       //
    532       // Check for all VGA device
    533       //
    534       Status = PciIo->Pci.Read (
    535                         PciIo,
    536                         EfiPciIoWidthUint32,
    537                         0,
    538                         sizeof (Pci) / sizeof (UINT32),
    539                         &Pci
    540                         );
    541       if (EFI_ERROR (Status)) {
    542         continue;
    543       }
    544 
    545       //
    546       // Here we decide which VGA device to enable in PCI bus
    547       //
    548       // The first plugin PCI VGA card device will be present as PCI VGA
    549       // The onchip AGP or AGP card will be present as AGP VGA
    550       //
    551       if (!IS_PCI_VGA (&Pci)) {
    552         continue;
    553       }
    554 
    555       //
    556       // Set the device as the possible console out device,
    557       //
    558       // Below code will make every VGA device to be one
    559       // of the possibe console out device
    560       //
    561       PlugInPciVga = TRUE;
    562       gBS->HandleProtocol (
    563              HandleBuffer[Index],
    564              &gEfiDevicePathProtocolGuid,
    565              (VOID**)&DevicePath
    566              );
    567 
    568       Index1 = 0;
    569 
    570       while (gPlatformAllPossiblePciVgaConsole[Index1] != NULL) {
    571         if (CompareMem (
    572               DevicePath,
    573               gPlatformAllPossiblePciVgaConsole[Index1],
    574               GetDevicePathSize (gPlatformAllPossiblePciVgaConsole[Index1])
    575               ) == 0) {
    576 
    577           //
    578           // This device is an AGP device
    579           //
    580           *OnboardPciVgaDevicePath = DevicePath;
    581           PlugInPciVga = FALSE;
    582           break;
    583         }
    584 
    585         Index1 ++;
    586       }
    587 
    588       if (PlugInPciVga) {
    589         *PlugInPciVgaDevicePath = DevicePath;
    590       }
    591     }
    592   }
    593 
    594   FreePool (HandleBuffer);
    595 
    596   return EFI_SUCCESS;
    597 }
    598 
    599 /**
    600 
    601   Find the platform  active vga, and base on the policy to enable the vga as
    602   the console out device. The policy is driven by one setup variable "VBIOS".
    603 
    604   None.
    605 
    606   @param EFI_UNSUPPORTED         There is no active vga device
    607 
    608   @retval EFI_STATUS             Return the status of BdsLibGetVariableAndSize ()
    609 
    610 **/
    611 EFI_STATUS
    612 PlatformBdsForceActiveVga (
    613   VOID
    614   )
    615 {
    616   EFI_STATUS                Status;
    617   EFI_DEVICE_PATH_PROTOCOL  *PlugInPciVgaDevicePath;
    618   EFI_DEVICE_PATH_PROTOCOL  *OnboardPciVgaDevicePath;
    619   EFI_DEVICE_PATH_PROTOCOL  *DevicePathFirst;
    620   EFI_DEVICE_PATH_PROTOCOL  *DevicePathSecond;
    621   EFI_DEVICE_PATH_PROTOCOL  *GopDevicePath;
    622   UINTN                VarSize;
    623   SYSTEM_CONFIGURATION  mSystemConfiguration;
    624 
    625   Status = EFI_SUCCESS;
    626   PlugInPciVgaDevicePath = NULL;
    627   OnboardPciVgaDevicePath = NULL;
    628 
    629   //
    630   // Check the policy which is the first enabled VGA
    631   //
    632   GetPlugInPciVgaDevicePath (&PlugInPciVgaDevicePath, &OnboardPciVgaDevicePath);
    633 
    634   if (PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath == NULL) {
    635     return EFI_UNSUPPORTED;
    636   }
    637 
    638   VarSize = sizeof(SYSTEM_CONFIGURATION);
    639   Status = gRT->GetVariable(
    640                   L"Setup",
    641                   &gEfiNormalSetupGuid,
    642                   NULL,
    643                   &VarSize,
    644                   &mSystemConfiguration
    645                   );
    646   if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
    647     //The setup variable is corrupted
    648     VarSize = sizeof(SYSTEM_CONFIGURATION);
    649     Status = gRT->GetVariable(
    650               L"SetupRecovery",
    651               &gEfiNormalSetupGuid,
    652               NULL,
    653               &VarSize,
    654               &mSystemConfiguration
    655               );
    656     ASSERT_EFI_ERROR (Status);
    657   }
    658 
    659 
    660   if ((PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath != NULL) ) {
    661     DEBUG ((EFI_D_ERROR,"Update onboard PCI VGA ...\n"));
    662     DevicePathFirst  = OnboardPciVgaDevicePath;
    663     DevicePathSecond = PlugInPciVgaDevicePath;
    664     goto UpdateConOut;
    665   }
    666   if(OnboardPciVgaDevicePath != NULL && mSystemConfiguration.PrimaryVideoAdaptor == 0) {
    667     DEBUG ((EFI_D_ERROR,"Update onboard PCI VGA When set primary!!!...\n"));
    668     DevicePathFirst  = OnboardPciVgaDevicePath;
    669     DevicePathSecond = PlugInPciVgaDevicePath;
    670     goto UpdateConOut;
    671   }
    672 
    673   DEBUG ((EFI_D_ERROR,"Update plug in PCI VGA ...\n"));
    674   DevicePathFirst  = PlugInPciVgaDevicePath;
    675   DevicePathSecond = OnboardPciVgaDevicePath;
    676 
    677 UpdateConOut:
    678   GetGopDevicePath (DevicePathFirst, &GopDevicePath);
    679   DevicePathFirst = GopDevicePath;
    680 
    681   Status = BdsLibUpdateConsoleVariable (
    682              L"ConOut",
    683              DevicePathFirst,
    684              DevicePathSecond
    685              );
    686 
    687   return Status;
    688 }
    689 
    690 VOID
    691 UpdateConsoleResolution(
    692   VOID
    693   )
    694 {
    695   UINT32                 HorizontalResolution;
    696   UINT32                 VerticalResolution;
    697   SYSTEM_CONFIGURATION   SystemConfiguration;
    698   UINTN                  VarSize;
    699   EFI_STATUS             Status;
    700 
    701 
    702   HorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
    703   VerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
    704 
    705   VarSize = sizeof(SYSTEM_CONFIGURATION);
    706   Status = gRT->GetVariable(
    707                   L"Setup",
    708                   &gEfiNormalSetupGuid,
    709                   NULL,
    710                   &VarSize,
    711                   &SystemConfiguration
    712                   );
    713   if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
    714     //The setup variable is corrupted
    715     VarSize = sizeof(SYSTEM_CONFIGURATION);
    716     Status = gRT->GetVariable(
    717               L"SetupRecovery",
    718               &gEfiNormalSetupGuid,
    719               NULL,
    720               &VarSize,
    721               &SystemConfiguration
    722               );
    723     ASSERT_EFI_ERROR (Status);
    724   }
    725 
    726   switch (SystemConfiguration.IgdFlatPanel) {
    727 
    728   case 0:
    729     //
    730     // Use the detault PCD values.
    731     //
    732     break;
    733 
    734   case 1:
    735     HorizontalResolution = 640;
    736     VerticalResolution = 480;
    737     break;
    738 
    739   case 2:
    740     HorizontalResolution = 800;
    741     VerticalResolution = 600;
    742     break;
    743 
    744   case 3:
    745     HorizontalResolution = 1024;
    746     VerticalResolution = 768;
    747     break;
    748 
    749   case 4:
    750   HorizontalResolution = 1280;
    751   VerticalResolution = 1024;
    752   break;
    753 
    754   case 5:
    755   HorizontalResolution = 1366;
    756   VerticalResolution = 768;
    757   break;
    758 
    759   case 6:
    760   HorizontalResolution = 1680;
    761   VerticalResolution = 1050;
    762   break;
    763 
    764   case 7:
    765   HorizontalResolution = 1920;
    766   VerticalResolution = 1200;
    767   break;
    768 
    769   case 8:
    770   HorizontalResolution = 1280;
    771   VerticalResolution = 800;
    772   break;
    773   }
    774 
    775   PcdSet32 (PcdSetupVideoHorizontalResolution, HorizontalResolution);
    776   PcdSet32 (PcdSetupVideoVerticalResolution, VerticalResolution);
    777   DEBUG ((EFI_D_ERROR, "HorizontalResolution = %x; VerticalResolution = %x", HorizontalResolution, VerticalResolution));
    778 
    779   return;
    780 }
    781 
    782 /**
    783   Connect the predefined platform default console device. Always try to find
    784   and enable the vga device if have.
    785 
    786   @param PlatformConsole    Predefined platform default console device array.
    787 
    788   @retval EFI_SUCCESS       Success connect at least one ConIn and ConOut
    789                             device, there must have one ConOut device is
    790                             active vga device.
    791 
    792   @retval EFI_STATUS        Return the status of
    793                             BdsLibConnectAllDefaultConsoles ()
    794 
    795 **/
    796 EFI_STATUS
    797 PlatformBdsConnectConsole (
    798   IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole
    799 )
    800 {
    801   EFI_STATUS                         Status;
    802   UINTN                              Index;
    803   EFI_DEVICE_PATH_PROTOCOL           *VarConout;
    804   EFI_DEVICE_PATH_PROTOCOL           *VarConin;
    805   UINTN                              DevicePathSize;
    806 
    807   UpdateConsoleResolution();
    808 
    809   Index = 0;
    810   Status = EFI_SUCCESS;
    811   DevicePathSize = 0;
    812   VarConout = BdsLibGetVariableAndSize (
    813                 L"ConOut",
    814                 &gEfiGlobalVariableGuid,
    815                 &DevicePathSize
    816                 );
    817   VarConin = BdsLibGetVariableAndSize (
    818                L"ConIn",
    819                &gEfiGlobalVariableGuid,
    820                &DevicePathSize
    821                );
    822   if (VarConout == NULL || VarConin == NULL) {
    823     //
    824     // Have chance to connect the platform default console,
    825     // the platform default console is the minimum device group
    826     // the platform should support
    827     //
    828     while (PlatformConsole[Index].DevicePath != NULL) {
    829 
    830       //
    831       // Update the console variable with the connect type
    832       //
    833       if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
    834         BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);
    835       }
    836 
    837       if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
    838         BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);
    839       }
    840 
    841       if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
    842         BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);
    843       }
    844 
    845       Index ++;
    846     }
    847   }
    848 
    849   //
    850   // Make sure we have at least one active VGA, and have the right
    851   // active VGA in console variable
    852   //
    853   Status = PlatformBdsForceActiveVga ();
    854   if (EFI_ERROR (Status)) {
    855     return Status;
    856   }
    857 
    858   DEBUG ((EFI_D_INFO, "DISPLAY INIT DONE\n"));
    859 
    860   //
    861   // Connect the all the default console with current console variable
    862   //
    863   Status = BdsLibConnectAllDefaultConsoles ();
    864   if (EFI_ERROR (Status)) {
    865     return Status;
    866   }
    867 
    868   return EFI_SUCCESS;
    869 }
    870 
    871 /**
    872   Connect with predefined platform connect sequence,
    873   the OEM/IBV can customize with their own connect sequence.
    874 
    875   @param None.
    876 
    877   @retval None.
    878 
    879 **/
    880 VOID
    881 PlatformBdsConnectSequence (
    882   VOID
    883   )
    884 {
    885   UINTN                     Index;
    886 
    887   Index = 0;
    888 
    889   //
    890   // Here we can get the customized platform connect sequence
    891   // Notes: we can connect with new variable which record the
    892   // last time boots connect device path sequence
    893   //
    894   while (gPlatformConnectSequence[Index] != NULL) {
    895 
    896     //
    897     // Build the platform boot option
    898     //
    899     BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);
    900     Index ++;
    901   }
    902 
    903   //
    904   // Just use the simple policy to connect all devices
    905   // There should be no difference between debug tip and release tip, or it will be extremely hard to debug.
    906   //
    907   // There is case that IdeController driver will write boot script in driver model Start() function. It will be rejected by boot script save.
    908   // It is only found when DEBUG disabled, because we are using BdsLibConnectAll() when DEBUG enabled.
    909   //
    910   // So we use BdsLibConnectAll() here to make sure IdeController.Start() is invoked before InstallReadyToLock().
    911   // We may also consider to connect SataController only later if needed.
    912   //
    913   BdsLibConnectAll ();
    914 }
    915 
    916 /**
    917 
    918   Load the predefined driver option, OEM/IBV can customize this
    919   to load their own drivers
    920 
    921   @param BdsDriverLists  The header of the driver option link list.
    922 
    923   @retval None.
    924 
    925 **/
    926 VOID
    927 PlatformBdsGetDriverOption (
    928   IN OUT LIST_ENTRY                  *BdsDriverLists
    929   )
    930 {
    931   UINTN                              Index;
    932 
    933   Index = 0;
    934 
    935   //
    936   // Here we can get the customized platform driver option
    937   //
    938   while (gPlatformDriverOption[Index] != NULL) {
    939 
    940     //
    941     // Build the platform boot option
    942     //
    943     BdsLibRegisterNewOption (BdsDriverLists, gPlatformDriverOption[Index], NULL, L"DriverOrder");
    944     Index ++;
    945   }
    946 
    947 }
    948 
    949 /**
    950   This function is used for some critical time if the the system
    951   have no any boot option, and there is no time out for user to add
    952   the new boot option. This can also treat as the platform default
    953   boot option.
    954 
    955   @param BdsBootOptionList   The header of the boot option link list.
    956 
    957   @retval None.
    958 
    959 **/
    960 VOID
    961 PlatformBdsPredictBootOption (
    962   IN OUT LIST_ENTRY                  *BdsBootOptionList
    963   )
    964 {
    965   UINTN                              Index;
    966 
    967   Index = 0;
    968 
    969   //
    970   // Here give chance to get platform boot option data
    971   //
    972   while (gPlatformBootOption[Index] != NULL) {
    973 
    974     //
    975     // Build the platform boot option
    976     //
    977     BdsLibRegisterNewOption (BdsBootOptionList, gPlatformBootOption[Index], NULL, L"BootOrder");
    978     Index ++;
    979   }
    980 }
    981 
    982 /**
    983   Perform the platform diagnostic, such like test memory. OEM/IBV also
    984   can customize this fuction to support specific platform diagnostic.
    985 
    986   @param MemoryTestLevel   The memory test intensive level
    987   @param QuietBoot         Indicate if need to enable the quiet boot
    988   @param BaseMemoryTest    A pointer to BdsMemoryTest()
    989 
    990   @retval  None.
    991 
    992 **/
    993 VOID
    994 PlatformBdsDiagnostics (
    995   IN EXTENDMEM_COVERAGE_LEVEL    MemoryTestLevel,
    996   IN BOOLEAN                     QuietBoot,
    997   IN BASEM_MEMORY_TEST           BaseMemoryTest
    998   )
    999 {
   1000   EFI_STATUS                     Status;
   1001 
   1002   //
   1003   // Here we can decide if we need to show
   1004   // the diagnostics screen
   1005   // Notes: this quiet boot code should be remove
   1006   // from the graphic lib
   1007   //
   1008   if (QuietBoot) {
   1009     EnableQuietBoot (PcdGetPtr(PcdLogoFile));
   1010 
   1011     //
   1012     // Perform system diagnostic
   1013     //
   1014     Status = BaseMemoryTest (MemoryTestLevel);
   1015     if (EFI_ERROR (Status)) {
   1016       DisableQuietBoot ();
   1017     }
   1018 
   1019     return;
   1020   }
   1021 
   1022   //
   1023   // Perform system diagnostic
   1024   //
   1025   Status = BaseMemoryTest (MemoryTestLevel);
   1026 }
   1027 
   1028 
   1029 /**
   1030   For EFI boot option, BDS separate them as six types:
   1031   1. Network - The boot option points to the SimpleNetworkProtocol device.
   1032                Bds will try to automatically create this type boot option when enumerate.
   1033   2. Shell   - The boot option points to internal flash shell.
   1034                Bds will try to automatically create this type boot option when enumerate.
   1035   3. Removable BlockIo      - The boot option only points to the removable media
   1036                               device, like USB flash disk, DVD, Floppy etc.
   1037                               These device should contain a *removable* blockIo
   1038                               protocol in their device handle.
   1039                               Bds will try to automatically create this type boot option
   1040                               when enumerate.
   1041   4. Fixed BlockIo          - The boot option only points to a Fixed blockIo device,
   1042                               like HardDisk.
   1043                               These device should contain a *fixed* blockIo
   1044                               protocol in their device handle.
   1045                               BDS will skip fixed blockIo devices, and NOT
   1046                               automatically create boot option for them. But BDS
   1047                               will help to delete those fixed blockIo boot option,
   1048                               whose description rule conflict with other auto-created
   1049                               boot options.
   1050   5. Non-BlockIo Simplefile - The boot option points to a device whose handle
   1051                               has SimpleFileSystem Protocol, but has no blockio
   1052                               protocol. These devices do not offer blockIo
   1053                               protocol, but BDS still can get the
   1054                               \EFI\BOOT\boot{machinename}.EFI by SimpleFileSystem
   1055                               Protocol.
   1056   6. File    - The boot option points to a file. These boot options are usually
   1057                created by user manually or OS loader. BDS will not delete or modify
   1058                these boot options.
   1059 
   1060   This function will enumerate all possible boot device in the system, and
   1061   automatically create boot options for Network, Shell, Removable BlockIo,
   1062   and Non-BlockIo Simplefile devices.
   1063   It will only execute once of every boot.
   1064 
   1065   @param  BdsBootOptionList      The header of the link list which indexed all
   1066                                  current boot options
   1067 
   1068   @retval EFI_SUCCESS            Finished all the boot device enumerate and create
   1069                                  the boot option base on that boot device
   1070 
   1071   @retval EFI_OUT_OF_RESOURCES   Failed to enumerate the boot device and create the boot option list
   1072 **/
   1073 EFI_STATUS
   1074 EFIAPI
   1075 PlatformBdsLibEnumerateAllBootOption (
   1076   IN OUT LIST_ENTRY          *BdsBootOptionList
   1077   )
   1078 {
   1079   EFI_STATUS                    Status;
   1080   UINT16                        FloppyNumber;
   1081   UINT16                        HarddriveNumber;
   1082   UINT16                        CdromNumber;
   1083   UINT16                        UsbNumber;
   1084   UINT16                        MiscNumber;
   1085   UINT16                        ScsiNumber;
   1086   UINT16                        NonBlockNumber;
   1087   UINTN                         NumberBlockIoHandles;
   1088   EFI_HANDLE                    *BlockIoHandles;
   1089   EFI_BLOCK_IO_PROTOCOL         *BlkIo;
   1090   BOOLEAN                       Removable[2];
   1091   UINTN                         RemovableIndex;
   1092   UINTN                         Index;
   1093   UINTN                         NumOfLoadFileHandles;
   1094   EFI_HANDLE                    *LoadFileHandles;
   1095   UINTN                         FvHandleCount;
   1096   EFI_HANDLE                    *FvHandleBuffer;
   1097   EFI_FV_FILETYPE               Type;
   1098   UINTN                         Size;
   1099   EFI_FV_FILE_ATTRIBUTES        Attributes;
   1100   UINT32                        AuthenticationStatus;
   1101   EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
   1102   EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
   1103   UINTN                         DevicePathType;
   1104   CHAR16                        Buffer[40];
   1105   EFI_HANDLE                    *FileSystemHandles;
   1106   UINTN                         NumberFileSystemHandles;
   1107   BOOLEAN                       NeedDelete;
   1108   EFI_IMAGE_DOS_HEADER          DosHeader;
   1109   CHAR8                         *PlatLang;
   1110   CHAR8                         *LastLang;
   1111   EFI_IMAGE_OPTIONAL_HEADER_UNION       HdrData;
   1112   EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;
   1113   CHAR16                        *MacStr;
   1114   CHAR16                        *IPverStr;
   1115   EFI_HANDLE                    *NetworkHandles;
   1116   UINTN                         BufferSize;
   1117 
   1118   FloppyNumber    = 0;
   1119   HarddriveNumber = 0;
   1120   CdromNumber     = 0;
   1121   UsbNumber       = 0;
   1122   MiscNumber      = 0;
   1123   ScsiNumber      = 0;
   1124   PlatLang        = NULL;
   1125   LastLang        = NULL;
   1126   ZeroMem (Buffer, sizeof (Buffer));
   1127 
   1128   //
   1129   // If the boot device enumerate happened, just get the boot
   1130   // device from the boot order variable
   1131   //
   1132   if (mEnumBootDevice) {
   1133     GetVariable2 (LAST_ENUM_LANGUAGE_VARIABLE_NAME, &gLastEnumLangGuid, (VOID**)&LastLang, NULL);
   1134     GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&PlatLang, NULL);
   1135     ASSERT (PlatLang != NULL);
   1136     if ((LastLang != NULL) && (AsciiStrCmp (LastLang, PlatLang) == 0)) {
   1137       Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
   1138       FreePool (LastLang);
   1139       FreePool (PlatLang);
   1140       return Status;
   1141     } else {
   1142       Status = gRT->SetVariable (
   1143         LAST_ENUM_LANGUAGE_VARIABLE_NAME,
   1144         &gLastEnumLangGuid,
   1145         EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
   1146         AsciiStrSize (PlatLang),
   1147         PlatLang
   1148         );
   1149       //
   1150       // Failure to set the variable only impacts the performance next time enumerating the boot options.
   1151       //
   1152 
   1153       if (LastLang != NULL) {
   1154         FreePool (LastLang);
   1155       }
   1156       FreePool (PlatLang);
   1157     }
   1158   }
   1159 
   1160   //
   1161   // Notes: this dirty code is to get the legacy boot option from the
   1162   // BBS table and create to variable as the EFI boot option, it should
   1163   // be removed after the CSM can provide legacy boot option directly
   1164   //
   1165   REFRESH_LEGACY_BOOT_OPTIONS;
   1166 
   1167   //
   1168   // Delete invalid boot option
   1169   //
   1170   BdsDeleteAllInvalidEfiBootOption ();
   1171 
   1172   //
   1173   // Parse removable media followed by fixed media.
   1174   // The Removable[] array is used by the for-loop below to create removable media boot options
   1175   // at first, and then to create fixed media boot options.
   1176   //
   1177   Removable[0]  = FALSE;
   1178   Removable[1]  = TRUE;
   1179 
   1180   gBS->LocateHandleBuffer (
   1181         ByProtocol,
   1182         &gEfiBlockIoProtocolGuid,
   1183         NULL,
   1184         &NumberBlockIoHandles,
   1185         &BlockIoHandles
   1186         );
   1187 
   1188   for (RemovableIndex = 0; RemovableIndex < 2; RemovableIndex++) {
   1189     for (Index = 0; Index < NumberBlockIoHandles; Index++) {
   1190       Status = gBS->HandleProtocol (
   1191                       BlockIoHandles[Index],
   1192                       &gEfiBlockIoProtocolGuid,
   1193                       (VOID **) &BlkIo
   1194                       );
   1195       //
   1196       // skip the logical partition
   1197       //
   1198       if (EFI_ERROR (Status) || BlkIo->Media->LogicalPartition) {
   1199         continue;
   1200       }
   1201 
   1202       //
   1203       // firstly fixed block io then the removable block io
   1204       //
   1205       if (BlkIo->Media->RemovableMedia == Removable[RemovableIndex]) {
   1206         continue;
   1207       }
   1208       DevicePath  = DevicePathFromHandle (BlockIoHandles[Index]);
   1209       DevicePathType = BdsGetBootTypeFromDevicePath (DevicePath);
   1210 
   1211       switch (DevicePathType) {
   1212       case BDS_EFI_ACPI_FLOPPY_BOOT:
   1213         if (FloppyNumber != 0) {
   1214           UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)), FloppyNumber);
   1215         } else {
   1216           UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)));
   1217         }
   1218         BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
   1219         FloppyNumber++;
   1220         break;
   1221 
   1222       //
   1223       // Assume a removable SATA device should be the DVD/CD device, a fixed SATA device should be the Hard Drive device.
   1224       //
   1225       case BDS_EFI_MESSAGE_ATAPI_BOOT:
   1226       case BDS_EFI_MESSAGE_SATA_BOOT:
   1227         if (BlkIo->Media->RemovableMedia) {
   1228           if (CdromNumber != 0) {
   1229             UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)), CdromNumber);
   1230           } else {
   1231             UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)));
   1232           }
   1233           CdromNumber++;
   1234         } else {
   1235           if (HarddriveNumber != 0) {
   1236             UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)), HarddriveNumber);
   1237           } else {
   1238             UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)));
   1239           }
   1240           HarddriveNumber++;
   1241         }
   1242         DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Buffer: %S\n", Buffer));
   1243         BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
   1244         break;
   1245 
   1246       case BDS_EFI_MESSAGE_USB_DEVICE_BOOT:
   1247         if (UsbNumber != 0) {
   1248           UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)), UsbNumber);
   1249         } else {
   1250           UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)));
   1251         }
   1252         BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
   1253         UsbNumber++;
   1254         break;
   1255 
   1256       case BDS_EFI_MESSAGE_SCSI_BOOT:
   1257         if (ScsiNumber != 0) {
   1258           UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)), ScsiNumber);
   1259         } else {
   1260           UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)));
   1261         }
   1262         BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
   1263         ScsiNumber++;
   1264         break;
   1265 
   1266       case BDS_EFI_MESSAGE_MISC_BOOT:
   1267       default:
   1268         if (MiscNumber != 0) {
   1269           UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)), MiscNumber);
   1270         } else {
   1271           UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)));
   1272         }
   1273         BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
   1274         MiscNumber++;
   1275         break;
   1276       }
   1277     }
   1278   }
   1279 
   1280   if (NumberBlockIoHandles != 0) {
   1281     FreePool (BlockIoHandles);
   1282   }
   1283 
   1284   //
   1285   // If there is simple file protocol which does not consume block Io protocol, create a boot option for it here.
   1286   //
   1287   NonBlockNumber = 0;
   1288   gBS->LocateHandleBuffer (
   1289         ByProtocol,
   1290         &gEfiSimpleFileSystemProtocolGuid,
   1291         NULL,
   1292         &NumberFileSystemHandles,
   1293         &FileSystemHandles
   1294         );
   1295   for (Index = 0; Index < NumberFileSystemHandles; Index++) {
   1296     Status = gBS->HandleProtocol (
   1297                     FileSystemHandles[Index],
   1298                     &gEfiBlockIoProtocolGuid,
   1299                     (VOID **) &BlkIo
   1300                     );
   1301      if (!EFI_ERROR (Status)) {
   1302       //
   1303       //  Skip if the file system handle supports a BlkIo protocol,
   1304       //
   1305       continue;
   1306     }
   1307 
   1308     //
   1309     // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
   1310     //  machinename is ia32, ia64, x64, ...
   1311     //
   1312     Hdr.Union  = &HdrData;
   1313     NeedDelete = TRUE;
   1314     Status     = BdsLibGetImageHeader (
   1315                    FileSystemHandles[Index],
   1316                    EFI_REMOVABLE_MEDIA_FILE_NAME,
   1317                    &DosHeader,
   1318                    Hdr
   1319                    );
   1320     if (!EFI_ERROR (Status) &&
   1321         EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) &&
   1322         Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
   1323       NeedDelete = FALSE;
   1324     }
   1325 
   1326     if (NeedDelete) {
   1327       //
   1328       // No such file or the file is not a EFI application, delete this boot option
   1329       //
   1330       BdsLibDeleteOptionFromHandle (FileSystemHandles[Index]);
   1331     } else {
   1332       if (NonBlockNumber != 0) {
   1333         UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)), NonBlockNumber);
   1334       } else {
   1335         UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)));
   1336       }
   1337       BdsLibBuildOptionFromHandle (FileSystemHandles[Index], BdsBootOptionList, Buffer);
   1338       NonBlockNumber++;
   1339     }
   1340   }
   1341 
   1342   if (NumberFileSystemHandles != 0) {
   1343     FreePool (FileSystemHandles);
   1344   }
   1345 
   1346   //
   1347   // Check if we have on flash shell
   1348   //
   1349   gBS->LocateHandleBuffer (
   1350         ByProtocol,
   1351         &gEfiFirmwareVolume2ProtocolGuid,
   1352         NULL,
   1353         &FvHandleCount,
   1354         &FvHandleBuffer
   1355         );
   1356   for (Index = 0; Index < FvHandleCount; Index++) {
   1357     gBS->HandleProtocol (
   1358           FvHandleBuffer[Index],
   1359           &gEfiFirmwareVolume2ProtocolGuid,
   1360           (VOID **) &Fv
   1361           );
   1362 
   1363     Status = Fv->ReadFile (
   1364                   Fv,
   1365                   PcdGetPtr(PcdShellFile),
   1366                   NULL,
   1367                   &Size,
   1368                   &Type,
   1369                   &Attributes,
   1370                   &AuthenticationStatus
   1371                   );
   1372     if (EFI_ERROR (Status)) {
   1373       //
   1374       // Skip if no shell file in the FV
   1375       //
   1376       continue;
   1377     }
   1378     //
   1379     // Build the shell boot option
   1380     //
   1381     BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);
   1382   }
   1383 
   1384   if (FvHandleCount != 0) {
   1385     FreePool (FvHandleBuffer);
   1386   }
   1387 
   1388   //
   1389   // Parse Network Boot Device
   1390   //
   1391   NumOfLoadFileHandles = 0;
   1392   //
   1393   // Search Load File protocol for PXE boot option.
   1394   //
   1395   gBS->LocateHandleBuffer (
   1396         ByProtocol,
   1397         &gEfiLoadFileProtocolGuid,
   1398         NULL,
   1399         &NumOfLoadFileHandles,
   1400         &LoadFileHandles
   1401         );
   1402 
   1403   for (Index = 0; Index < NumOfLoadFileHandles; Index++) {
   1404 
   1405 //
   1406 //Locate EFI_DEVICE_PATH_PROTOCOL to dynamically get IPv4/IPv6 protocol information.
   1407 //
   1408 
   1409  Status = gBS->HandleProtocol (
   1410                   LoadFileHandles[Index],
   1411                   &gEfiDevicePathProtocolGuid,
   1412                   (VOID **) &DevicePath
   1413                   );
   1414 
   1415  ASSERT_EFI_ERROR (Status);
   1416 
   1417   while (!IsDevicePathEnd (DevicePath)) {
   1418     if ((DevicePath->Type == MESSAGING_DEVICE_PATH) &&
   1419         (DevicePath->SubType == MSG_IPv4_DP)) {
   1420 
   1421   //
   1422   //Get handle infomation
   1423   //
   1424   BufferSize = 0;
   1425   NetworkHandles = NULL;
   1426   Status = gBS->LocateHandle (
   1427                   ByProtocol,
   1428                   &gEfiSimpleNetworkProtocolGuid,
   1429                   NULL,
   1430                   &BufferSize,
   1431                   NetworkHandles
   1432                   );
   1433 
   1434   if (Status == EFI_BUFFER_TOO_SMALL) {
   1435     NetworkHandles = AllocateZeroPool(BufferSize);
   1436     if (NetworkHandles == NULL) {
   1437       return (EFI_OUT_OF_RESOURCES);
   1438     }
   1439     Status = gBS->LocateHandle(
   1440                     ByProtocol,
   1441                     &gEfiSimpleNetworkProtocolGuid,
   1442                     NULL,
   1443                     &BufferSize,
   1444                     NetworkHandles
   1445                     );
   1446  }
   1447 
   1448   //
   1449   //Get the MAC string
   1450   //
   1451   Status = NetLibGetMacString (
   1452              *NetworkHandles,
   1453              NULL,
   1454              &MacStr
   1455              );
   1456   if (EFI_ERROR (Status)) {
   1457     return Status;
   1458   }
   1459   IPverStr = L" IPv4";
   1460   UnicodeSPrint (Buffer, sizeof (Buffer), L"%s%s%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK)),MacStr,IPverStr);
   1461   break;
   1462   }
   1463     if((DevicePath->Type == MESSAGING_DEVICE_PATH) &&
   1464         (DevicePath->SubType == MSG_IPv6_DP)) {
   1465 
   1466   //
   1467   //Get handle infomation
   1468   //
   1469   BufferSize = 0;
   1470   NetworkHandles = NULL;
   1471   Status = gBS->LocateHandle (
   1472                   ByProtocol,
   1473                   &gEfiSimpleNetworkProtocolGuid,
   1474                   NULL,
   1475                   &BufferSize,
   1476                   NetworkHandles
   1477                   );
   1478 
   1479   if (Status == EFI_BUFFER_TOO_SMALL) {
   1480     NetworkHandles = AllocateZeroPool(BufferSize);
   1481     if (NetworkHandles == NULL) {
   1482        return (EFI_OUT_OF_RESOURCES);
   1483     }
   1484     Status = gBS->LocateHandle(
   1485                     ByProtocol,
   1486                     &gEfiSimpleNetworkProtocolGuid,
   1487                     NULL,
   1488                     &BufferSize,
   1489                     NetworkHandles
   1490                     );
   1491  }
   1492 
   1493   //
   1494   //Get the MAC string
   1495   //
   1496   Status = NetLibGetMacString (
   1497              *NetworkHandles,
   1498              NULL,
   1499              &MacStr
   1500              );
   1501   if (EFI_ERROR (Status)) {
   1502     return Status;
   1503   }
   1504       IPverStr = L" IPv6";
   1505       UnicodeSPrint (Buffer, sizeof (Buffer), L"%s%s%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK)),MacStr,IPverStr);
   1506       break;
   1507     }
   1508     DevicePath = NextDevicePathNode (DevicePath);
   1509   }
   1510 
   1511     BdsLibBuildOptionFromHandle (LoadFileHandles[Index], BdsBootOptionList, Buffer);
   1512   }
   1513 
   1514   if (NumOfLoadFileHandles != 0) {
   1515     FreePool (LoadFileHandles);
   1516   }
   1517 
   1518   //
   1519   // Check if we have on flash shell
   1520   //
   1521  /* gBS->LocateHandleBuffer (
   1522         ByProtocol,
   1523         &gEfiFirmwareVolume2ProtocolGuid,
   1524         NULL,
   1525         &FvHandleCount,
   1526         &FvHandleBuffer
   1527         );
   1528   for (Index = 0; Index < FvHandleCount; Index++) {
   1529     gBS->HandleProtocol (
   1530           FvHandleBuffer[Index],
   1531           &gEfiFirmwareVolume2ProtocolGuid,
   1532           (VOID **) &Fv
   1533           );
   1534 
   1535     Status = Fv->ReadFile (
   1536                   Fv,
   1537                   PcdGetPtr(PcdShellFile),
   1538                   NULL,
   1539                   &Size,
   1540                   &Type,
   1541                   &Attributes,
   1542                   &AuthenticationStatus
   1543                   );
   1544     if (EFI_ERROR (Status)) {
   1545       //
   1546       // Skip if no shell file in the FV
   1547       //
   1548       continue;
   1549     }
   1550     //
   1551     // Build the shell boot option
   1552     //
   1553     BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);
   1554   }
   1555 
   1556   if (FvHandleCount != 0) {
   1557     FreePool (FvHandleBuffer);
   1558   } */
   1559 
   1560   //
   1561   // Make sure every boot only have one time
   1562   // boot device enumerate
   1563   //
   1564   Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
   1565   mEnumBootDevice = TRUE;
   1566 
   1567   return Status;
   1568 }
   1569 
   1570 
   1571 
   1572 /**
   1573 
   1574   The function will execute with as the platform policy, current policy
   1575   is driven by boot mode. IBV/OEM can customize this code for their specific
   1576   policy action.
   1577 
   1578   @param DriverOptionList - The header of the driver option link list
   1579   @param  BootOptionList   - The header of the boot option link list
   1580   @param ProcessCapsules  - A pointer to ProcessCapsules()
   1581   @param BaseMemoryTest   - A pointer to BaseMemoryTest()
   1582 
   1583   @retval None.
   1584 
   1585 **/
   1586 VOID
   1587 EFIAPI
   1588 PlatformBdsPolicyBehavior (
   1589   IN OUT LIST_ENTRY                  *DriverOptionList,
   1590   IN OUT LIST_ENTRY                  *BootOptionList,
   1591   IN PROCESS_CAPSULES                BdsProcessCapsules,
   1592   IN BASEM_MEMORY_TEST               BaseMemoryTest
   1593   )
   1594 {
   1595   EFI_STATUS                         Status;
   1596   UINT16                             Timeout;
   1597   EFI_BOOT_MODE                      BootMode;
   1598   BOOLEAN                            DeferredImageExist;
   1599   UINTN                              Index;
   1600   SYSTEM_CONFIGURATION               SystemConfiguration;
   1601   UINTN                              VarSize;
   1602   PLATFORM_PCI_DEVICE_PATH           *EmmcBootDevPath;
   1603   EFI_GLOBAL_NVS_AREA_PROTOCOL       *GlobalNvsArea;
   1604   EFI_HANDLE                         FvProtocolHandle;
   1605   UINTN                              HandleCount;
   1606   EFI_HANDLE                         *HandleBuffer;
   1607   UINTN                              Index1;
   1608   UINTN                              SataPciRegBase = 0;
   1609   UINT16                             SataModeSelect = 0;
   1610   VOID                               *RegistrationExitPmAuth = NULL;
   1611   EFI_EVENT                          Event;
   1612   BOOLEAN                            IsFirstBoot;
   1613   UINT16                             *BootOrder;
   1614   UINTN                              BootOrderSize;
   1615   ESRT_MANAGEMENT_PROTOCOL           *EsrtManagement;
   1616 
   1617   Timeout = PcdGet16 (PcdPlatformBootTimeOut);
   1618   if (Timeout > 10 ) {
   1619     //we think the Timeout variable is corrupted
   1620     Timeout = 10;
   1621   }
   1622 
   1623   VarSize = sizeof(SYSTEM_CONFIGURATION);
   1624   Status = gRT->GetVariable(
   1625                   NORMAL_SETUP_NAME,
   1626                   &gEfiNormalSetupGuid,
   1627                   NULL,
   1628                   &VarSize,
   1629                   &SystemConfiguration
   1630                   );
   1631 
   1632   if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
   1633     //The setup variable is corrupted
   1634     VarSize = sizeof(SYSTEM_CONFIGURATION);
   1635     Status = gRT->GetVariable(
   1636               L"SetupRecovery",
   1637               &gEfiNormalSetupGuid,
   1638               NULL,
   1639               &VarSize,
   1640               &SystemConfiguration
   1641               );
   1642     ASSERT_EFI_ERROR (Status);
   1643   }
   1644 
   1645   //
   1646   // Load the driver option as the driver option list
   1647   //
   1648   PlatformBdsGetDriverOption (DriverOptionList);
   1649 
   1650   //
   1651   // Get current Boot Mode
   1652   //
   1653   BootMode = GetBootModeHob();
   1654 
   1655   //
   1656   // No deferred images exist by default
   1657   //
   1658   DeferredImageExist = FALSE;
   1659   if ((BootMode != BOOT_WITH_MINIMAL_CONFIGURATION) && (PcdGet32(PcdFlashFvShellSize) > 0)){
   1660     gDS->ProcessFirmwareVolume (
   1661            (VOID *)(UINTN)PcdGet32(PcdFlashFvShellBase),
   1662            PcdGet32(PcdFlashFvShellSize),
   1663            &FvProtocolHandle
   1664            );
   1665   }
   1666 
   1667   if (SystemConfiguration.FastBoot == 1) {
   1668     BootOrder = BdsLibGetVariableAndSize (
   1669                   L"BootOrder",
   1670                   &gEfiGlobalVariableGuid,
   1671                   &BootOrderSize
   1672                   );
   1673     if ((BootOrder != NULL) && (BootMode != BOOT_ON_FLASH_UPDATE)) {
   1674       //
   1675       // BootOrder exist, it means system has boot before. We can do fast boot.
   1676       //
   1677       BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;
   1678     }
   1679   }
   1680 
   1681 
   1682   //
   1683   // Use eMMC to boot OS and turn on AHCI, when SATA HDD is diconnected,
   1684   // SATA AHCI CTLR device will show yellow bang, implement this solution to solve it.
   1685   //
   1686   SataPciRegBase  = MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, 0, 0);
   1687   SataModeSelect  = MmioRead16 (SataPciRegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK;
   1688   Status          = EFI_SUCCESS;
   1689   if (SataModeSelect != V_PCH_SATA_MAP_SMS_IDE) {
   1690     Status = gBS->CreateEvent (
   1691                     EVT_NOTIFY_SIGNAL,
   1692                     TPL_CALLBACK,
   1693                     DisableAhciCtlr,
   1694                     &SataPciRegBase,
   1695                     &Event
   1696                      );
   1697     if (!EFI_ERROR (Status)) {
   1698       Status = gBS->RegisterProtocolNotify (
   1699                       &gExitPmAuthProtocolGuid,
   1700                       Event,
   1701                       &RegistrationExitPmAuth
   1702                       );
   1703     }
   1704   }
   1705 
   1706   Status = gBS->LocateProtocol(&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtManagement);
   1707   if (EFI_ERROR(Status)) {
   1708     EsrtManagement = NULL;
   1709   }
   1710 
   1711   switch (BootMode) {
   1712 
   1713   case BOOT_WITH_MINIMAL_CONFIGURATION:
   1714     PlatformBdsInitHotKeyEvent ();
   1715     PlatformBdsConnectSimpleConsole (gPlatformSimpleConsole);
   1716 
   1717 
   1718     //
   1719     // Check to see if it's needed to dispatch more DXE drivers.
   1720     //
   1721     for (Index = 0; Index < sizeof(ConnectDriverTable)/sizeof(EFI_GUID *); Index++) {
   1722       Status = gBS->LocateHandleBuffer (
   1723                       ByProtocol,
   1724                       ConnectDriverTable[Index],
   1725                       NULL,
   1726                       &HandleCount,
   1727                       &HandleBuffer
   1728                       );
   1729       if (!EFI_ERROR (Status)) {
   1730         for (Index1 = 0; Index1 < HandleCount; Index1++) {
   1731           gBS->ConnectController (
   1732                  HandleBuffer[Index1],
   1733                  NULL,
   1734                  NULL,
   1735                  TRUE
   1736                  );
   1737         }
   1738       }
   1739 
   1740       if (HandleBuffer != NULL) {
   1741         FreePool (HandleBuffer);
   1742       }
   1743 
   1744       gDS->Dispatch ();
   1745     }
   1746 
   1747     //
   1748     //  Locate the Global NVS Protocol.
   1749     //
   1750     Status = gBS->LocateProtocol (
   1751                     &gEfiGlobalNvsAreaProtocolGuid,
   1752                     NULL,
   1753                     (void **)&GlobalNvsArea
   1754                     );
   1755     if (GlobalNvsArea->Area->emmcVersion == 0){
   1756       EmmcBootDevPath = (PLATFORM_PCI_DEVICE_PATH *)gPlatformSimpleBootOption[0];
   1757       EmmcBootDevPath->PciDevice.Device = 0x10;
   1758     }
   1759 
   1760     //
   1761     // Connect boot device here to give time to read keyboard.
   1762     //
   1763     BdsLibConnectDevicePath (gPlatformSimpleBootOption[0]);
   1764 
   1765     //
   1766     // This is a workround for dectecting hotkey from USB keyboard.
   1767     //
   1768     gBS->Stall(KEYBOARD_TIMER_INTERVAL);
   1769 
   1770     if (mHotKeyTimerEvent != NULL) {
   1771       gBS->SetTimer (
   1772              mHotKeyTimerEvent,
   1773              TimerCancel,
   1774              0
   1775              );
   1776       gBS->CloseEvent (mHotKeyTimerEvent);
   1777       mHotKeyTimerEvent = NULL;
   1778     }
   1779     if (mHotKeyPressed) {
   1780       //
   1781       // Skip show progress count down
   1782       //
   1783       Timeout = 0xFFFF;
   1784       goto FULL_CONFIGURATION;
   1785     }
   1786 
   1787     if (SystemConfiguration.QuietBoot) {
   1788       EnableQuietBoot (PcdGetPtr(PcdLogoFile));
   1789     } else {
   1790       PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest);
   1791     }
   1792 
   1793 
   1794     #ifdef TPM_ENABLED
   1795     TcgPhysicalPresenceLibProcessRequest();
   1796     #endif
   1797     #ifdef FTPM_ENABLE
   1798     TrEEPhysicalPresenceLibProcessRequest(NULL);
   1799     #endif
   1800 
   1801     if (EsrtManagement != NULL) {
   1802       EsrtManagement->LockEsrtRepository();
   1803     }
   1804 
   1805     //
   1806     // Close boot script and install ready to lock
   1807     //
   1808     InstallReadyToLock ();
   1809 
   1810     //
   1811     // Give one chance to enter the setup if we
   1812     // select Gummiboot "Reboot Into Firmware Interface" and Fast Boot is enabled.
   1813     //
   1814     BootIntoFirmwareInterface();
   1815     break;
   1816 
   1817   case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
   1818 
   1819     //
   1820     // In no-configuration boot mode, we can connect the
   1821     // console directly.
   1822     //
   1823     BdsLibConnectAllDefaultConsoles ();
   1824     PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);
   1825 
   1826     //
   1827     // Perform some platform specific connect sequence
   1828     //
   1829     PlatformBdsConnectSequence ();
   1830 
   1831     //
   1832     // As console is ready, perform user identification again.
   1833     //
   1834     if (mCurrentUser == NULL) {
   1835       PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
   1836       if (DeferredImageExist) {
   1837         //
   1838         // After user authentication, the deferred drivers was loaded again.
   1839         // Here, need to ensure the deferred images are connected.
   1840         //
   1841         BdsLibConnectAllDefaultConsoles ();
   1842         PlatformBdsConnectSequence ();
   1843       }
   1844     }
   1845 
   1846     if (EsrtManagement != NULL) {
   1847       EsrtManagement->LockEsrtRepository();
   1848     }
   1849 
   1850     //
   1851     // Close boot script and install ready to lock
   1852     //
   1853     InstallReadyToLock ();
   1854 
   1855     //
   1856     // Notes: current time out = 0 can not enter the
   1857     // front page
   1858     //
   1859     PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
   1860 
   1861     //
   1862     // Check the boot option with the boot option list
   1863     //
   1864     BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
   1865     break;
   1866 
   1867   case BOOT_ON_FLASH_UPDATE:
   1868 
   1869     //
   1870     // Boot with the specific configuration
   1871     //
   1872     PlatformBdsConnectConsole (gPlatformConsole);
   1873     PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest);
   1874 
   1875     DEBUG((DEBUG_INFO, "ProcessCapsules Before EndOfDxe......\n"));
   1876     ProcessCapsules ();
   1877     DEBUG((DEBUG_INFO, "ProcessCapsules Done\n"));
   1878 
   1879     //
   1880     // Close boot script and install ready to lock
   1881     //
   1882     InstallReadyToLock ();
   1883 
   1884     BdsLibConnectAll ();
   1885 
   1886     //
   1887     // Perform user identification
   1888     //
   1889     if (mCurrentUser == NULL) {
   1890       PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
   1891       if (DeferredImageExist) {
   1892         //
   1893         // After user authentication, the deferred drivers was loaded again.
   1894         // Here, need to ensure the deferred images are connected.
   1895         //
   1896         BdsLibConnectAll ();
   1897       }
   1898     }
   1899 
   1900     if (EsrtManagement != NULL) {
   1901       EsrtManagement->SyncEsrtFmp();
   1902     }
   1903 
   1904     DEBUG((DEBUG_INFO, "ProcessCapsules After ConnectAll......\n"));
   1905     ProcessCapsules();
   1906     DEBUG((DEBUG_INFO, "ProcessCapsules Done\n"));
   1907     break;
   1908 
   1909   case BOOT_IN_RECOVERY_MODE:
   1910 
   1911     //
   1912     // In recovery mode, just connect platform console
   1913     // and show up the front page
   1914     //
   1915     PlatformBdsConnectConsole (gPlatformConsole);
   1916     PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest);
   1917     BdsLibConnectAll ();
   1918 
   1919     //
   1920     // Perform user identification
   1921     //
   1922     if (mCurrentUser == NULL) {
   1923       PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
   1924       if (DeferredImageExist) {
   1925         //
   1926         // After user authentication, the deferred drivers was loaded again.
   1927         // Here, need to ensure the deferred drivers are connected.
   1928         //
   1929         BdsLibConnectAll ();
   1930       }
   1931     }
   1932 
   1933     //
   1934     // Close boot script and install ready to lock
   1935     //
   1936     InstallReadyToLock ();
   1937 
   1938     //
   1939     // In recovery boot mode, we still enter to the
   1940     // frong page now
   1941     //
   1942     PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
   1943     break;
   1944 
   1945 FULL_CONFIGURATION:
   1946   case BOOT_WITH_FULL_CONFIGURATION:
   1947   case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
   1948   case BOOT_WITH_DEFAULT_SETTINGS:
   1949   default:
   1950 
   1951     //
   1952     // Connect platform console
   1953     //
   1954     Status = PlatformBdsConnectConsole (gPlatformConsole);
   1955     if (EFI_ERROR (Status)) {
   1956 
   1957       //
   1958       // Here OEM/IBV can customize with defined action
   1959       //
   1960       PlatformBdsNoConsoleAction ();
   1961     }
   1962 
   1963     //
   1964     // Chenyunh[TODO]: This is Workgroud to show the fs for uSDcard,
   1965     // Need to root cause this issue.
   1966     //
   1967     DEBUG ((DEBUG_ERROR, "Start to reconnect all driver.\n"));
   1968     BdsLibDisconnectAllEfi();
   1969     BdsLibConnectAll ();
   1970     DEBUG ((DEBUG_ERROR, "End to reconnect all driver.\n"));
   1971 
   1972     //
   1973     // Perform some platform specific connect sequence
   1974     //
   1975     PlatformBdsConnectSequence ();
   1976     if (SystemConfiguration.QuietBoot) {
   1977         EnableQuietBoot (PcdGetPtr(PcdLogoFile));
   1978     } else {
   1979         PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest);
   1980     }
   1981 
   1982     //
   1983     // Do a pre-delay so Hard Disk can spin up and see more logo.
   1984     //
   1985     gBS->Stall(SystemConfiguration.HddPredelay * 1000000);
   1986 
   1987     //
   1988     // Perform user identification
   1989     //
   1990     if (mCurrentUser == NULL) {
   1991       PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
   1992       if (DeferredImageExist) {
   1993         //
   1994         // After user authentication, the deferred drivers was loaded again.
   1995         // Here, need to ensure the deferred drivers are connected.
   1996         //
   1997         Status = PlatformBdsConnectConsole (gPlatformConsole);
   1998         if (EFI_ERROR (Status)) {
   1999           PlatformBdsNoConsoleAction ();
   2000         }
   2001         PlatformBdsConnectSequence ();
   2002       }
   2003     }
   2004    #ifdef TPM_ENABLED
   2005    TcgPhysicalPresenceLibProcessRequest();
   2006    #endif
   2007    #ifdef FTPM_ENABLE
   2008    TrEEPhysicalPresenceLibProcessRequest(NULL);
   2009    #endif
   2010 
   2011     if (EsrtManagement != NULL) {
   2012       EsrtManagement->SyncEsrtFmp();
   2013     }
   2014     //
   2015     // Close boot script and install ready to lock
   2016     //
   2017     InstallReadyToLock ();
   2018 
   2019     //
   2020     // Here we have enough time to do the enumeration of boot device
   2021     //
   2022     PlatformBdsLibEnumerateAllBootOption (BootOptionList);
   2023 
   2024     //
   2025     // Give one chance to enter the setup if we
   2026     // have the time out
   2027     //
   2028     PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
   2029 
   2030 	//
   2031 	// Give one chance to enter the setup if we
   2032 	// select Gummiboot "Reboot Into Firmware Interface"
   2033 	//
   2034 	BootIntoFirmwareInterface();
   2035 
   2036     //
   2037     // In default boot mode, always find all boot
   2038     // option and do enumerate all the default boot option
   2039     //
   2040     if (Timeout == 0) {
   2041       BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
   2042       if (IsListEmpty(BootOptionList)) {
   2043         PlatformBdsPredictBootOption (BootOptionList);
   2044       }
   2045 
   2046       return;
   2047     }
   2048 
   2049 
   2050     break;
   2051   }
   2052 
   2053 
   2054   IsFirstBoot = PcdGetBool(PcdBootState);
   2055   if (IsFirstBoot) {
   2056     PcdSetBool(PcdBootState, FALSE);
   2057   }
   2058   return;
   2059 
   2060 }
   2061 
   2062 /**
   2063   Hook point after a boot attempt succeeds. We don't expect a boot option to
   2064   return, so the UEFI 2.0 specification defines that you will default to an
   2065   interactive mode and stop processing the BootOrder list in this case. This
   2066   is alos a platform implementation and can be customized by IBV/OEM.
   2067 
   2068   @param Option  Pointer to Boot Option that succeeded to boot.
   2069 
   2070   @retval None.
   2071 
   2072 **/
   2073 VOID
   2074 EFIAPI
   2075 PlatformBdsBootSuccess (
   2076   IN  BDS_COMMON_OPTION *Option
   2077   )
   2078 {
   2079   CHAR16  *TmpStr;
   2080 
   2081   //
   2082   // If Boot returned with EFI_SUCCESS and there is not in the boot device
   2083   // select loop then we need to pop up a UI and wait for user input.
   2084   //
   2085   TmpStr =  Option->StatusString;
   2086   if (TmpStr != NULL) {
   2087     BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
   2088     FreePool(TmpStr);
   2089   }
   2090 }
   2091 
   2092 /**
   2093   Hook point after a boot attempt fails.
   2094 
   2095   @param Option - Pointer to Boot Option that failed to boot.
   2096   @param Status - Status returned from failed boot.
   2097   @param ExitData - Exit data returned from failed boot.
   2098   @param ExitDataSize - Exit data size returned from failed boot.
   2099 
   2100   @retval None.
   2101 
   2102 **/
   2103 VOID
   2104 EFIAPI
   2105 PlatformBdsBootFail (
   2106   IN  BDS_COMMON_OPTION  *Option,
   2107   IN  EFI_STATUS         Status,
   2108   IN  CHAR16             *ExitData,
   2109   IN  UINTN              ExitDataSize
   2110   )
   2111 {
   2112   CHAR16          *TmpStr;
   2113   EFI_HANDLE      FvProtocolHandle;
   2114 
   2115   //
   2116   // If Boot returned with failed status then we need to pop up a UI and wait
   2117   // for user input.
   2118   //
   2119   TmpStr = Option->StatusString;
   2120   if (TmpStr != NULL) {
   2121     BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
   2122     FreePool(TmpStr);
   2123   }
   2124   if (PcdGet32(PcdFlashFvShellSize) > 0){
   2125     gDS->ProcessFirmwareVolume (
   2126            (VOID *)(UINTN)PcdGet32(PcdFlashFvShellBase),
   2127            PcdGet32(PcdFlashFvShellSize),
   2128            &FvProtocolHandle
   2129            );
   2130   }
   2131   PlatformBdsConnectSequence ();
   2132 }
   2133 
   2134 /**
   2135   This function is remained for IBV/OEM to do some platform action,
   2136   if there no console device can be connected.
   2137 
   2138   @param  None.
   2139 
   2140   @retval EFI_SUCCESS       Direct return success now.
   2141 
   2142 **/
   2143 EFI_STATUS
   2144 PlatformBdsNoConsoleAction (
   2145   VOID
   2146   )
   2147 {
   2148   return EFI_SUCCESS;
   2149 }
   2150 
   2151 /**
   2152   This function locks the block
   2153 
   2154   @param Base            The base address flash region to be locked.
   2155 
   2156 **/
   2157 VOID
   2158 BdsLockFv (
   2159   IN EFI_PHYSICAL_ADDRESS  Base
   2160   )
   2161 {
   2162   EFI_FV_BLOCK_MAP_ENTRY      *BlockMap;
   2163   EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;
   2164   EFI_PHYSICAL_ADDRESS        BaseAddress;
   2165   UINT32                      BlockLength;
   2166   UINTN                       Index;
   2167 
   2168   BaseAddress = Base - 0x400000 + 2;
   2169   FvHeader    = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (Base));
   2170   BlockMap    = &(FvHeader->BlockMap[0]);
   2171 
   2172   while ((BlockMap->NumBlocks != 0) && (BlockMap->Length != 0)) {
   2173     BlockLength = BlockMap->Length;
   2174     for (Index = 0; Index < BlockMap->NumBlocks; Index++) {
   2175       MmioOr8 ((UINTN) BaseAddress, 0x03);
   2176       BaseAddress += BlockLength;
   2177     }
   2178     BlockMap++;
   2179   }
   2180 }
   2181 
   2182 VOID
   2183 EFIAPI
   2184 PlatformBdsLockNonUpdatableFlash (
   2185   VOID
   2186   )
   2187 {
   2188   EFI_PHYSICAL_ADDRESS  Base;
   2189 
   2190   Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvMainBase);
   2191   if (Base > 0) {
   2192     BdsLockFv (Base);
   2193   }
   2194 
   2195   Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvRecoveryBase);
   2196   if (Base > 0) {
   2197     BdsLockFv (Base);
   2198   }
   2199 }
   2200 
   2201 /**
   2202   Lock the ConsoleIn device in system table. All key
   2203   presses will be ignored until the Password is typed in. The only way to
   2204   disable the password is to type it in to a ConIn device.
   2205 
   2206   @param  Password        Password used to lock ConIn device.
   2207 
   2208   @retval EFI_SUCCESS     lock the Console In Spliter virtual handle successfully.
   2209   @retval EFI_UNSUPPORTED Password not found
   2210 
   2211 **/
   2212 EFI_STATUS
   2213 EFIAPI
   2214 LockKeyboards (
   2215   IN  CHAR16    *Password
   2216   )
   2217 {
   2218     return EFI_UNSUPPORTED;
   2219 }
   2220 
   2221 /**
   2222   Connect the predefined platform default authentication devices.
   2223 
   2224   This function connects the predefined device path for authentication device,
   2225   and if the predefined device path has child device path, the child handle will
   2226   be connected too. But the child handle of the child will not be connected.
   2227 
   2228 **/
   2229 VOID
   2230 EFIAPI
   2231 PlatformBdsConnectAuthDevice (
   2232   VOID
   2233   )
   2234 {
   2235   EFI_STATUS                   Status;
   2236   UINTN                        Index;
   2237   UINTN                        HandleIndex;
   2238   UINTN                        HandleCount;
   2239   EFI_HANDLE                   *HandleBuffer;
   2240   EFI_DEVICE_PATH_PROTOCOL     *ChildDevicePath;
   2241   EFI_USER_MANAGER_PROTOCOL    *Manager;
   2242 
   2243   Status = gBS->LocateProtocol (
   2244                   &gEfiUserManagerProtocolGuid,
   2245                   NULL,
   2246                   (VOID **) &Manager
   2247                   );
   2248   if (EFI_ERROR (Status)) {
   2249     //
   2250     // As user manager protocol is not installed, the authentication devices
   2251     // should not be connected.
   2252     //
   2253     return ;
   2254   }
   2255 
   2256   Index = 0;
   2257   while (gUserAuthenticationDevice[Index] != NULL) {
   2258     //
   2259     // Connect the platform customized device paths
   2260     //
   2261     BdsLibConnectDevicePath (gUserAuthenticationDevice[Index]);
   2262     Index++;
   2263   }
   2264 
   2265   //
   2266   // Find and connect the child device paths of the platform customized device paths
   2267   //
   2268   HandleBuffer = NULL;
   2269   for (Index = 0; gUserAuthenticationDevice[Index] != NULL; Index++) {
   2270     HandleCount = 0;
   2271     Status = gBS->LocateHandleBuffer (
   2272                     AllHandles,
   2273                     NULL,
   2274                     NULL,
   2275                     &HandleCount,
   2276                     &HandleBuffer
   2277                     );
   2278     ASSERT (!EFI_ERROR (Status));
   2279 
   2280     //
   2281     // Find and connect the child device paths of gUserIdentificationDevice[Index]
   2282     //
   2283     for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
   2284       ChildDevicePath = NULL;
   2285       Status = gBS->HandleProtocol (
   2286                       HandleBuffer[HandleIndex],
   2287                       &gEfiDevicePathProtocolGuid,
   2288                       (VOID **) &ChildDevicePath
   2289                       );
   2290       if (EFI_ERROR (Status) || ChildDevicePath == NULL) {
   2291         continue;
   2292       }
   2293 
   2294       if (CompareMem (
   2295             ChildDevicePath,
   2296             gUserAuthenticationDevice[Index],
   2297             (GetDevicePathSize (gUserAuthenticationDevice[Index]) - sizeof (EFI_DEVICE_PATH_PROTOCOL))
   2298             ) != 0) {
   2299         continue;
   2300       }
   2301       gBS->ConnectController (
   2302              HandleBuffer[HandleIndex],
   2303              NULL,
   2304              NULL,
   2305              TRUE
   2306              );
   2307     }
   2308   }
   2309 
   2310   if (HandleBuffer != NULL) {
   2311     FreePool (HandleBuffer);
   2312   }
   2313 }
   2314 
   2315 /**
   2316   This function is to identify a user, and return whether deferred images exist.
   2317 
   2318   @param[out]  User               Point to user profile handle.
   2319   @param[out]  DeferredImageExist On return, points to TRUE if the deferred image
   2320                                   exist or FALSE if it did not exist.
   2321 
   2322 **/
   2323 VOID
   2324 EFIAPI
   2325 PlatformBdsUserIdentify (
   2326   OUT EFI_USER_PROFILE_HANDLE        *User,
   2327   OUT BOOLEAN                        *DeferredImageExist
   2328   )
   2329 {
   2330   EFI_STATUS                         Status;
   2331   EFI_DEFERRED_IMAGE_LOAD_PROTOCOL   *DeferredImage;
   2332   UINTN                              HandleCount;
   2333   EFI_HANDLE                         *HandleBuf;
   2334   UINTN                              Index;
   2335   UINTN                              DriverIndex;
   2336   EFI_DEVICE_PATH_PROTOCOL           *ImageDevicePath;
   2337   VOID                               *DriverImage;
   2338   UINTN                              ImageSize;
   2339   BOOLEAN                            BootOption;
   2340 
   2341   //
   2342   // Perform user identification
   2343   //
   2344   do {
   2345     Status = BdsLibUserIdentify (User);
   2346   } while (EFI_ERROR (Status));
   2347 
   2348   //
   2349   // After user authentication now, try to find whether deferred image exists
   2350   //
   2351   HandleCount = 0;
   2352   HandleBuf   = NULL;
   2353   *DeferredImageExist = FALSE;
   2354   Status = gBS->LocateHandleBuffer (
   2355                   ByProtocol,
   2356                   &gEfiDeferredImageLoadProtocolGuid,
   2357                   NULL,
   2358                   &HandleCount,
   2359                   &HandleBuf
   2360                   );
   2361   if (EFI_ERROR (Status)) {
   2362     return ;
   2363   }
   2364 
   2365   for (Index = 0; Index < HandleCount; Index++) {
   2366     Status = gBS->HandleProtocol (
   2367                     HandleBuf[Index],
   2368                     &gEfiDeferredImageLoadProtocolGuid,
   2369                     (VOID **) &DeferredImage
   2370                     );
   2371     if (!EFI_ERROR (Status)) {
   2372       //
   2373       // Find whether deferred image exists in this instance.
   2374       //
   2375       DriverIndex = 0;
   2376       Status = DeferredImage->GetImageInfo(
   2377                                 DeferredImage,
   2378                                 DriverIndex,
   2379                                 &ImageDevicePath,
   2380                                 (VOID **) &DriverImage,
   2381                                 &ImageSize,
   2382                                 &BootOption
   2383                                 );
   2384       if (!EFI_ERROR (Status)) {
   2385         //
   2386         // The deferred image is found.
   2387         //
   2388         FreePool (HandleBuf);
   2389         *DeferredImageExist = TRUE;
   2390         return ;
   2391       }
   2392     }
   2393   }
   2394 
   2395   FreePool (HandleBuf);
   2396 }
   2397 
   2398 UINTN gHotKey = 0;
   2399 
   2400 
   2401 EFI_STATUS
   2402 ShowProgressHotKey (
   2403   IN UINT16                       TimeoutDefault
   2404   )
   2405 {
   2406   CHAR16                        *TmpStr;
   2407   UINT16                        TimeoutRemain;
   2408   EFI_STATUS                    Status;
   2409   EFI_INPUT_KEY                 Key;
   2410   EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
   2411   EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
   2412   EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
   2413   UINT32                        GpioValue;
   2414   CHAR16                        *TmpStr1;
   2415   CHAR16                        *TmpStr2;
   2416   CHAR16                        *TmpStr3;
   2417   UINTN                         TmpStrSize;
   2418   VOID                          *Buffer;
   2419   UINTN                         Size;
   2420 
   2421   if (TimeoutDefault == 0) {
   2422     return EFI_TIMEOUT;
   2423   }
   2424 
   2425   gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
   2426 
   2427   if (DebugAssertEnabled())
   2428   {
   2429     DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it, or press <F2> or <DEL> to enter setup page! ...Zzz....\n"));
   2430   }
   2431   else
   2432   {
   2433     #ifdef __GNUC__
   2434     SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)[GCC]", 76);
   2435     #else
   2436     SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)", 71);
   2437     #endif
   2438   }
   2439   SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
   2440   SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
   2441   SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
   2442 
   2443   TmpStr2 = NULL;
   2444   TmpStr3 = NULL;
   2445 
   2446   //
   2447   // Check if the platform is using test key.
   2448   //
   2449   Status = GetSectionFromAnyFv(
   2450              PcdGetPtr(PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid),
   2451              EFI_SECTION_RAW,
   2452              0,
   2453              &Buffer,
   2454              &Size
   2455              );
   2456   if (!EFI_ERROR(Status)) {
   2457     if ((Size == PcdGetSize(PcdRsa2048Sha256PublicKeyBuffer)) &&
   2458         (CompareMem(Buffer, PcdGetPtr(PcdRsa2048Sha256PublicKeyBuffer), Size) == 0)) {
   2459       TmpStr2 = L"WARNING: Recovery Test Key is used.\r\n";
   2460       if (DebugAssertEnabled()) {
   2461         DEBUG ((DEBUG_INFO, "\n\nWARNING: Recovery Test Key is used.\n"));
   2462       } else {
   2463         SerialPortWrite((UINT8 *)"\n\nWARNING: Recovery Test Key is used.", sizeof("\n\nWARNING: Recovery Test Key is used."));
   2464       }
   2465       PcdSetBoolS(PcdTestKeyUsed, TRUE);
   2466     }
   2467     FreePool(Buffer);
   2468   }
   2469   Status = GetSectionFromAnyFv(
   2470              PcdGetPtr(PcdEdkiiPkcs7TestPublicKeyFileGuid),
   2471              EFI_SECTION_RAW,
   2472              0,
   2473              &Buffer,
   2474              &Size
   2475              );
   2476   if (!EFI_ERROR(Status)) {
   2477     if ((Size == PcdGetSize(PcdPkcs7CertBuffer)) &&
   2478         (CompareMem(Buffer, PcdGetPtr(PcdPkcs7CertBuffer), Size) == 0)) {
   2479       TmpStr3 = L"WARNING: Capsule Test Key is used.\r\n";
   2480       if (DebugAssertEnabled()) {
   2481         DEBUG ((DEBUG_INFO, "\n\nWARNING: Capsule Test Key is used.\r\n"));
   2482       } else {
   2483         SerialPortWrite((UINT8 *)"\n\nWARNING: Capsule Test Key is used.", sizeof("\n\nWARNING: Capsule Test Key is used."));
   2484       }
   2485       PcdSetBoolS(PcdTestKeyUsed, TRUE);
   2486     }
   2487     FreePool(Buffer);
   2488   }
   2489 
   2490   //
   2491   // Clear the progress status bar first
   2492   //
   2493   TmpStr1 = L"Start boot option, Press <F2> or <DEL> to enter setup page.\r\n";
   2494   TmpStrSize = StrSize(TmpStr1);
   2495   if (TmpStr2 != NULL) {
   2496     TmpStrSize += StrSize(TmpStr2);
   2497   }
   2498   if (TmpStr3 != NULL) {
   2499     TmpStrSize += StrSize(TmpStr3);
   2500   }
   2501   TmpStr = AllocatePool (TmpStrSize);
   2502   if (TmpStr == NULL) {
   2503     TmpStr = TmpStr1;
   2504   } else {
   2505     StrCpyS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr1);
   2506     if (TmpStr2 != NULL) {
   2507       StrCatS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr2);
   2508     }
   2509     if (TmpStr3 != NULL) {
   2510       StrCatS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr3);
   2511     }
   2512   }
   2513   PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);
   2514 
   2515   TimeoutRemain = TimeoutDefault;
   2516   while (TimeoutRemain != 0) {
   2517     if (DebugAssertEnabled())
   2518     {
   2519     DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));
   2520     }
   2521     else
   2522     {
   2523     SerialPortWrite ((UINT8 *)".", 1);
   2524     }
   2525     Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);
   2526     if (Status != EFI_TIMEOUT) {
   2527       break;
   2528     }
   2529     TimeoutRemain--;
   2530 
   2531     //
   2532     // Show progress
   2533     //
   2534     if (TmpStr != NULL) {
   2535       PlatformBdsShowProgress (
   2536         Foreground,
   2537         Background,
   2538         TmpStr,
   2539         Color,
   2540         ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),
   2541         0
   2542         );
   2543     }
   2544   }
   2545 
   2546   //
   2547   // Timeout expired
   2548   //
   2549   if (TimeoutRemain == 0) {
   2550     if (DebugAssertEnabled())
   2551 	{
   2552 	}
   2553     else
   2554     {
   2555     SerialPortWrite ((UINT8 *)"\r\n", 2);
   2556     }
   2557     return EFI_TIMEOUT;
   2558   }
   2559 
   2560   //
   2561   // User pressed some key
   2562   //
   2563   Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
   2564   if (EFI_ERROR (Status)) {
   2565     return Status;
   2566   }
   2567 
   2568   //
   2569   // Check Volume Up Key to enter Setup
   2570   //
   2571   GpioValue = MmioRead32 (IO_BASE_ADDRESS + 0x0668);  // The value of GPIOC_5
   2572   if (((GpioValue & BIT0) == 0) && (Key.ScanCode == SCAN_UP)) {
   2573     gHotKey = 0;
   2574     return EFI_SUCCESS;
   2575   }
   2576 
   2577   if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
   2578     //
   2579     // User pressed enter, equivalent to select "continue"
   2580     //
   2581     return EFI_TIMEOUT;
   2582   }
   2583 
   2584   //
   2585   //F2 --  Front Page
   2586   //F5 --  Device Manager
   2587   //F7 --  Boot Manager
   2588   // do not use F8. generally people assume it is windows safe mode key.
   2589   //F9 --  Boot order
   2590   //
   2591   DEBUG ((EFI_D_INFO, "[Key Pressed]: ScanCode 0x%x\n", Key.ScanCode));
   2592   switch(Key.ScanCode) {
   2593       case SCAN_F2:
   2594           gHotKey = 0;
   2595           break;
   2596 
   2597       case SCAN_DELETE:
   2598           gHotKey = 0;
   2599           break;
   2600 
   2601       case SCAN_F5:
   2602           gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
   2603           break;
   2604 
   2605       case SCAN_F7:
   2606           gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
   2607           break;
   2608 
   2609       case SCAN_F9:
   2610           gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
   2611           break;
   2612 
   2613       default:
   2614           //set gHotKey to continue so that flow will not go into CallFrontPage
   2615           gHotKey = FRONT_PAGE_KEY_CONTINUE;
   2616           return EFI_TIMEOUT;
   2617           break;
   2618   }
   2619 
   2620   return EFI_SUCCESS;
   2621 }
   2622 
   2623 
   2624 
   2625 /**
   2626   This function is the main entry of the platform setup entry.
   2627   The function will present the main menu of the system setup,
   2628   this is the platform reference part and can be customize.
   2629 
   2630 
   2631   @param TimeoutDefault     The fault time out value before the system
   2632                             continue to boot.
   2633   @param ConnectAllHappened The indicater to check if the connect all have
   2634                             already happened.
   2635 
   2636 **/
   2637 VOID
   2638 PlatformBdsEnterFrontPageWithHotKey (
   2639   IN UINT16                       TimeoutDefault,
   2640   IN BOOLEAN                      ConnectAllHappened
   2641   )
   2642 {
   2643   EFI_STATUS                    Status;
   2644 
   2645   EFI_GRAPHICS_OUTPUT_PROTOCOL       *GraphicsOutput;
   2646   EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *SimpleTextOut;
   2647   UINTN                              BootTextColumn;
   2648   UINTN                              BootTextRow;
   2649 
   2650   GraphicsOutput = NULL;
   2651   SimpleTextOut = NULL;
   2652 
   2653   PERF_START (NULL, "BdsTimeOut", "BDS", 0);
   2654 
   2655   //
   2656   // Indicate if we need connect all in the platform setup
   2657   //
   2658   if (ConnectAllHappened) {
   2659     gConnectAllHappened = TRUE;
   2660   }
   2661 
   2662   if (!mModeInitialized) {
   2663     //
   2664     // After the console is ready, get current video resolution
   2665     // and text mode before launching setup at first time.
   2666     //
   2667     Status = gBS->HandleProtocol (
   2668                     gST->ConsoleOutHandle,
   2669                     &gEfiGraphicsOutputProtocolGuid,
   2670                     (VOID**)&GraphicsOutput
   2671                     );
   2672     if (EFI_ERROR (Status)) {
   2673       GraphicsOutput = NULL;
   2674     }
   2675 
   2676     Status = gBS->HandleProtocol (
   2677                     gST->ConsoleOutHandle,
   2678                     &gEfiSimpleTextOutProtocolGuid,
   2679                     (VOID**)&SimpleTextOut
   2680                     );
   2681     if (EFI_ERROR (Status)) {
   2682       SimpleTextOut = NULL;
   2683     }
   2684 
   2685     if (GraphicsOutput != NULL) {
   2686       //
   2687       // Get current video resolution and text mode.
   2688       //
   2689       mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
   2690       mBootVerticalResolution   = GraphicsOutput->Mode->Info->VerticalResolution;
   2691     }
   2692 
   2693     if (SimpleTextOut != NULL) {
   2694       Status = SimpleTextOut->QueryMode (
   2695                                 SimpleTextOut,
   2696                                 SimpleTextOut->Mode->Mode,
   2697                                 &BootTextColumn,
   2698                                 &BootTextRow
   2699                                 );
   2700       mBootTextModeColumn = (UINT32)BootTextColumn;
   2701       mBootTextModeRow    = (UINT32)BootTextRow;
   2702     }
   2703 
   2704     //
   2705     // Get user defined text mode for setup.
   2706     //
   2707     mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
   2708     mSetupVerticalResolution   = PcdGet32 (PcdSetupVideoVerticalResolution);
   2709     mSetupTextModeColumn       = PcdGet32 (PcdSetupConOutColumn);
   2710     mSetupTextModeRow          = PcdGet32 (PcdSetupConOutRow);
   2711 
   2712     mModeInitialized           = TRUE;
   2713   }
   2714 
   2715   if (TimeoutDefault != 0xffff) {
   2716     Status = ShowProgressHotKey (TimeoutDefault);
   2717 
   2718     //
   2719     // Ensure screen is clear when switch Console from Graphics mode to Text mode
   2720     //
   2721     gST->ConOut->EnableCursor (gST->ConOut, TRUE);
   2722     gST->ConOut->ClearScreen (gST->ConOut);
   2723 
   2724     if (EFI_ERROR (Status)) {
   2725       //
   2726       // Timeout or user press enter to continue
   2727       //
   2728       goto Exit;
   2729     }
   2730   }
   2731   //
   2732   // Install BM HiiPackages.
   2733   // Keep BootMaint HiiPackage, so that it can be covered by global setting.
   2734   //
   2735 	InitBMPackage ();
   2736   do {
   2737 
   2738     BdsSetConsoleMode (TRUE);
   2739 
   2740     InitializeFrontPage (FALSE);
   2741 
   2742     //
   2743     // Update Front Page strings
   2744     //
   2745     UpdateFrontPageStrings ();
   2746 
   2747     Status = EFI_SUCCESS;
   2748     gCallbackKey = 0;
   2749     if (gHotKey == 0) {
   2750       Status = CallFrontPage ();
   2751     } else {
   2752       gCallbackKey = gHotKey;
   2753       gHotKey = 0;
   2754     }
   2755 
   2756     //
   2757     // If gCallbackKey is greater than 1 and less or equal to 5,
   2758     // it will launch configuration utilities.
   2759     // 2 = set language
   2760     // 3 = boot manager
   2761     // 4 = device manager
   2762     // 5 = boot maintenance manager
   2763     //
   2764     if (gCallbackKey != 0) {
   2765       REPORT_STATUS_CODE (
   2766         EFI_PROGRESS_CODE,
   2767         (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
   2768         );
   2769     }
   2770 
   2771     //
   2772     // Based on the key that was set, we can determine what to do
   2773     //
   2774     switch (gCallbackKey) {
   2775     //
   2776     // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
   2777     // describe to their customers in documentation how to find their setup information (namely
   2778     // under the device manager and specific buckets)
   2779     //
   2780     // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
   2781     //
   2782     case FRONT_PAGE_KEY_CONTINUE:
   2783 
   2784       //
   2785       // User hit continue
   2786       //
   2787       break;
   2788 
   2789     case FRONT_PAGE_KEY_LANGUAGE:
   2790 
   2791       //
   2792       // User made a language setting change - display front page again
   2793       //
   2794       break;
   2795 
   2796     case FRONT_PAGE_KEY_BOOT_MANAGER:
   2797       //
   2798 	  // Remove the installed BootMaint HiiPackages when exit.
   2799       //
   2800       FreeBMPackage ();
   2801 
   2802       //
   2803       // User chose to run the Boot Manager
   2804       //
   2805       CallBootManager ();
   2806 
   2807 	  //
   2808       // Reinstall BootMaint HiiPackages after exiting from Boot Manager.
   2809       //
   2810       InitBMPackage ();
   2811       break;
   2812 
   2813     case FRONT_PAGE_KEY_DEVICE_MANAGER:
   2814 
   2815       //
   2816       // Display the Device Manager
   2817       //
   2818       do {
   2819         CallDeviceManager ();
   2820       } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);
   2821       break;
   2822 
   2823     case FRONT_PAGE_KEY_BOOT_MAINTAIN:
   2824 
   2825       //
   2826       // Display the Boot Maintenance Manager
   2827       //
   2828       BdsStartBootMaint ();
   2829       break;
   2830     }
   2831 
   2832   } while (((UINTN)gCallbackKey) != FRONT_PAGE_KEY_CONTINUE);
   2833 
   2834   //
   2835   //Will leave browser, check any reset required change is applied? if yes, reset system
   2836   //
   2837   SetupResetReminder ();
   2838   //
   2839   // Remove the installed BootMaint HiiPackages when exit.
   2840   //
   2841   FreeBMPackage ();
   2842 
   2843 Exit:
   2844   //
   2845   // Automatically load current entry
   2846   // Note: The following lines of code only execute when Auto boot
   2847   // takes affect
   2848   //
   2849   PERF_END (NULL, "BdsTimeOut", "BDS", 0);
   2850 }
   2851 
   2852 
   2853 VOID
   2854 BootIntoFirmwareInterface(
   2855 VOID
   2856 )
   2857 {
   2858   EFI_STATUS        Status;
   2859   UINTN             DataSize;
   2860   UINT16            Timeout;
   2861   UINT64            OsIndication;
   2862 
   2863 
   2864   OsIndication = 0;
   2865   DataSize = sizeof(UINT64);
   2866   Status = gRT->GetVariable (
   2867                   L"OsIndications",
   2868                   &gEfiGlobalVariableGuid,
   2869                   NULL,
   2870                   &DataSize,
   2871                   &OsIndication
   2872                   );
   2873 
   2874   DEBUG ((EFI_D_INFO, "OSIndication Variable Value %d\n", OsIndication));
   2875   //
   2876   //Goto FrontPage directly when bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted.
   2877   //
   2878   if (!EFI_ERROR(Status) && (OsIndication != 0)) {
   2879    Timeout = 0xffff;
   2880    PlatformBdsEnterFrontPage (Timeout, FALSE);
   2881    }
   2882 }
   2883 
   2884 
   2885 EFI_STATUS
   2886 PlatformBdsConnectSimpleConsole (
   2887   IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole
   2888 )
   2889 {
   2890   EFI_STATUS                         Status;
   2891   UINTN                              Index;
   2892   EFI_DEVICE_PATH_PROTOCOL           *VarConout;
   2893   EFI_DEVICE_PATH_PROTOCOL           *VarConin;
   2894   UINTN                              DevicePathSize;
   2895 
   2896 
   2897   Index = 0;
   2898   Status = EFI_SUCCESS;
   2899   DevicePathSize = 0;
   2900   VarConout = BdsLibGetVariableAndSize (
   2901                 L"ConOut",
   2902                 &gEfiGlobalVariableGuid,
   2903                 &DevicePathSize
   2904                 );
   2905   VarConin = BdsLibGetVariableAndSize (
   2906                L"ConIn",
   2907                &gEfiGlobalVariableGuid,
   2908                &DevicePathSize
   2909                );
   2910   if (VarConout == NULL || VarConin == NULL) {
   2911     //
   2912     // Have chance to connect the platform default console,
   2913     // the platform default console is the minimum device group
   2914     // the platform should support
   2915     //
   2916     while (PlatformConsole[Index].DevicePath != NULL) {
   2917 
   2918       //
   2919       // Update the console variable with the connect type
   2920       //
   2921       if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
   2922         BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);
   2923       }
   2924 
   2925       if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
   2926         BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);
   2927       }
   2928 
   2929       if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
   2930         BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);
   2931       }
   2932 
   2933       Index ++;
   2934     }
   2935   }
   2936 
   2937   //
   2938   // Connect ConIn first to give keyboard time to parse hot key event.
   2939   //
   2940   Status = BdsLibConnectConsoleVariable (L"ConIn");
   2941   if (EFI_ERROR (Status)) {
   2942     return Status;
   2943   }
   2944 
   2945   //
   2946   // Make sure we have at least one active VGA, and have the right
   2947   // active VGA in console variable
   2948   //
   2949   Status = PlatformBdsForceActiveVga ();
   2950 
   2951   //
   2952   // It seems impossible not to have any ConOut device on platform,
   2953   // so we check the status here.
   2954   //
   2955   Status = BdsLibConnectConsoleVariable (L"ConOut");
   2956   if (EFI_ERROR (Status)) {
   2957     return Status;
   2958   }
   2959 
   2960   return EFI_SUCCESS;
   2961 }
   2962 
   2963 
   2964 /**
   2965   Timer handler to convert the key from USB.
   2966 
   2967   @param  Event                    Indicates the event that invoke this function.
   2968   @param  Context                  Indicates the calling context.
   2969 **/
   2970 VOID
   2971 EFIAPI
   2972 HotKeyTimerHandler (
   2973   IN  EFI_EVENT                 Event,
   2974   IN  VOID                      *Context
   2975   )
   2976 {
   2977   EFI_STATUS                    Status;
   2978   EFI_INPUT_KEY                 Key;
   2979 
   2980   Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
   2981   if (EFI_ERROR (Status)) {
   2982     return;
   2983   }
   2984 
   2985   switch(Key.ScanCode) {
   2986   case SCAN_F2:
   2987     gHotKey = 0;
   2988     mHotKeyPressed = TRUE;
   2989     break;
   2990 
   2991   case SCAN_F5:
   2992     gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
   2993     mHotKeyPressed = TRUE;
   2994     break;
   2995 
   2996   case SCAN_F7:
   2997     gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
   2998     mHotKeyPressed = TRUE;
   2999     break;
   3000 
   3001   case SCAN_F9:
   3002     gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
   3003     mHotKeyPressed = TRUE;
   3004     break;
   3005   }
   3006 
   3007   if (mHotKeyPressed) {
   3008     gBS->SetTimer (
   3009            mHotKeyTimerEvent,
   3010            TimerCancel,
   3011            0
   3012            );
   3013     gBS->CloseEvent (mHotKeyTimerEvent);
   3014     mHotKeyTimerEvent = NULL;
   3015   }
   3016 
   3017   return;
   3018 }
   3019 
   3020 
   3021 /**
   3022   Callback function for SimpleTextInEx protocol install events
   3023 
   3024   @param Event           the event that is signaled.
   3025   @param Context         not used here.
   3026 
   3027 **/
   3028 VOID
   3029 EFIAPI
   3030 HitHotkeyEvent (
   3031   IN EFI_EVENT    Event,
   3032   IN VOID         *Context
   3033   )
   3034 {
   3035   EFI_STATUS                         Status;
   3036 
   3037   Status = gBS->CloseEvent(mHitHotkeyEvent);
   3038   if (EFI_ERROR (Status)) {
   3039     return;
   3040   }
   3041   Status = gBS->CreateEvent (
   3042                   EVT_TIMER | EVT_NOTIFY_SIGNAL,
   3043                   TPL_NOTIFY,
   3044                   HotKeyTimerHandler,
   3045                   NULL,
   3046                   &mHotKeyTimerEvent
   3047                   );
   3048   if (EFI_ERROR (Status)) {
   3049     return;
   3050   }
   3051   Status = gBS->SetTimer (
   3052                   mHotKeyTimerEvent,
   3053                   TimerPeriodic,
   3054                   KEYBOARD_TIMER_INTERVAL
   3055                   );
   3056   if (EFI_ERROR (Status)) {
   3057     return;
   3058   }
   3059 
   3060   return;
   3061 }
   3062 
   3063 
   3064 VOID
   3065 EFIAPI
   3066 PlatformBdsInitHotKeyEvent (
   3067   VOID
   3068   )
   3069 {
   3070   EFI_STATUS      Status;
   3071 
   3072   //
   3073   // Register Protocol notify for Hotkey service
   3074   //
   3075   Status = gBS->CreateEvent (
   3076                   EVT_NOTIFY_SIGNAL,
   3077                   TPL_CALLBACK,
   3078                   HitHotkeyEvent,
   3079                   NULL,
   3080                   &mHitHotkeyEvent
   3081                   );
   3082   ASSERT_EFI_ERROR (Status);
   3083 
   3084   //
   3085   // Register for protocol notifications on this event
   3086   //
   3087   Status = gBS->RegisterProtocolNotify (
   3088                   &gEfiSimpleTextInputExProtocolGuid,
   3089                   mHitHotkeyEvent,
   3090                   &mHitHotkeyRegistration
   3091                   );
   3092   ASSERT_EFI_ERROR (Status);
   3093 }
   3094