3 Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
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.
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.
21 This file include all platform action which can be customized
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>
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>
44 #include <Library/GenericBdsLib/InternalBdsLib.h>
45 #include <Library/GenericBdsLib/String.h>
46 #include <Library/NetLib.h>
48 EFI_GUID
*ConnectDriverTable
[] = {
49 &gEfiMmioDeviceProtocolGuid
,
50 &gEfiI2cMasterProtocolGuid
,
51 &gEfiI2cHostProtocolGuid
54 #define SHELL_ENVIRONMENT_INTERFACE_PROTOCOL \
56 0x47c7b221, 0xc42a, 0x11d2, 0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b \
58 VOID
*mShellImageCallbackReg
= NULL
;
62 EFI_USER_PROFILE_HANDLE mCurrentUser
= NULL
;
63 EFI_EVENT mHotKeyTimerEvent
= NULL
;
64 EFI_EVENT mHitHotkeyEvent
= NULL
;
65 EFI_EVENT mUsbKeyboardConnectEvent
= NULL
;
66 BOOLEAN mHotKeyPressed
= FALSE
;
67 VOID
*mHitHotkeyRegistration
;
68 #define KEYBOARD_TIMER_INTERVAL 20000 // 0.02s
71 ConnectUSBController (
76 PlatformBdsConnectSimpleConsole (
77 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
81 BootIntoFirmwareInterface(
87 PlatformBdsInitHotKeyEvent (
98 UINT32 PmcDisableAddress
;
99 UINT8 SataStorageAmount
;
101 UINT16 SataPortStatus
;
104 DEBUG ((EFI_D_INFO
, "Disable AHCI event is signalled\n"));
105 SataStorageAmount
= 0;
106 SataBase
= *(UINT32
*) Context
;
109 // BayTrail-M EDS chapter 16 ---- PCI IO Register Offset 92 (SATA Port Control and Status)
111 SataPortStatus
= MmioRead16 (SataBase
+ R_PCH_SATA_PCS
);
114 // Bit 8 EN: Port 0 Present
116 if ((SataPortStatus
& 0x100) == 0x100) {
121 // Bit 9 EN: Port 1 Present
123 if ((SataPortStatus
& 0x200) == 0x200) {
128 // Disable SATA controller when it sets to AHCI mode without carrying any devices
129 // in order to prevent AHCI yellow bang under Win device manager.
131 if (SataStorageAmount
== 0) {
132 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
;
133 MmioOr32 (PmcDisableAddress
, B_PCH_PMC_FUNC_DIS_SATA
);
134 S3BootScriptSaveMemWrite (
135 EfiBootScriptWidthUint32
,
136 (UINTN
) PmcDisableAddress
,
138 (VOID
*) (UINTN
) PmcDisableAddress
150 EFI_SMM_ACCESS2_PROTOCOL
*SmmAccess
;
151 EFI_ACPI_S3_SAVE_PROTOCOL
*AcpiS3Save
;
154 // Install DxeSmmReadyToLock protocol prior to the processing of boot options
156 Status
= gBS
->LocateProtocol (
157 &gEfiSmmAccess2ProtocolGuid
,
161 if (!EFI_ERROR (Status
)) {
164 // Prepare S3 information, this MUST be done before DxeSmmReadyToLock
166 Status
= gBS
->LocateProtocol (
167 &gEfiAcpiS3SaveProtocolGuid
,
171 if (!EFI_ERROR (Status
)) {
172 AcpiS3Save
->S3Save (AcpiS3Save
, NULL
);
176 Status
= gBS
->InstallProtocolInterface (
178 &gExitPmAuthProtocolGuid
,
179 EFI_NATIVE_INTERFACE
,
182 ASSERT_EFI_ERROR (Status
);
185 Status
= gBS
->InstallProtocolInterface (
187 &gEfiDxeSmmReadyToLockProtocolGuid
,
188 EFI_NATIVE_INTERFACE
,
191 ASSERT_EFI_ERROR (Status
);
204 BdsSetConsoleMode (TRUE
);
205 DEBUG ((EFI_D_INFO
, "BdsEntry ShellImageCallback \n"));
209 // BDS Platform Functions
212 Platform Bds init. Incude the platform firmware vendor, revision
227 EFI_EVENT ShellImageEvent
;
228 EFI_GUID ShellEnvProtocol
= SHELL_ENVIRONMENT_INTERFACE_PROTOCOL
;
231 SerialPortWrite((UINT8
*)">>>>BdsEntry[GCC]\r\n", 19);
233 SerialPortWrite((UINT8
*)">>>>BdsEntry\r\n", 14);
235 BdsLibSaveMemoryTypeInformation ();
238 // Before user authentication, the user identification devices need be connected
239 // from the platform customized device paths
241 PlatformBdsConnectAuthDevice ();
244 // As console is not ready, the auto logon user will be identified.
246 BdsLibUserIdentify (&mCurrentUser
);
249 // Change Gop mode when boot into Shell
251 if (mShellImageCallbackReg
== NULL
) {
252 Status
= gBS
->CreateEvent (
253 EFI_EVENT_NOTIFY_SIGNAL
,
259 if (!EFI_ERROR (Status
)) {
260 Status
= gBS
->RegisterProtocolNotify (
263 &mShellImageCallbackReg
266 DEBUG ((EFI_D_INFO
, "BdsEntry ShellImageCallback \n"));
273 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
274 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
279 EFI_HANDLE PciDeviceHandle
;
280 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
281 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
282 UINTN GopHandleCount
;
283 EFI_HANDLE
*GopHandleBuffer
;
286 SYSTEM_CONFIGURATION mSystemConfiguration
;
288 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
289 return EFI_INVALID_PARAMETER
;
293 // Initialize the GopDevicePath to be PciDevicePath
295 *GopDevicePath
= PciDevicePath
;
296 TempPciDevicePath
= PciDevicePath
;
298 Status
= gBS
->LocateDevicePath (
299 &gEfiDevicePathProtocolGuid
,
303 if (EFI_ERROR (Status
)) {
308 // Try to connect this handle, so that GOP dirver could start on this
309 // device and create child handles with GraphicsOutput Protocol installed
310 // on them, then we get device paths of these child handles and select
311 // them as possible console device.
315 // Select display devices
317 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
318 Status
= gRT
->GetVariable(
320 &gEfiNormalSetupGuid
,
323 &mSystemConfiguration
325 if (EFI_ERROR (Status
) || VarSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
326 //The setup variable is corrupted
327 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
328 Status
= gRT
->GetVariable(
330 &gEfiNormalSetupGuid
,
333 &mSystemConfiguration
335 ASSERT_EFI_ERROR (Status
);
338 if(mSystemConfiguration
.BootDisplayDevice
!= 0x0)
340 ACPI_ADR_DEVICE_PATH AcpiAdr
;
341 EFI_DEVICE_PATH_PROTOCOL
*MyDevicePath
= NULL
;
343 AcpiAdr
.Header
.Type
= ACPI_DEVICE_PATH
;
344 AcpiAdr
.Header
.SubType
= ACPI_ADR_DP
;
346 switch (mSystemConfiguration
.BootDisplayDevice
) {
348 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA
, PORT_CRT
, 0); //CRT Device
351 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL
, PORT_B_HDMI
, 0); //HDMI Device Port B
354 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL
, PORT_B_DP
, 0); //DP PortB
357 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL
, PORT_C_DP
, 0); //DP PortC
360 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL
, PORT_C_DP
, 0); //eDP Port C
363 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL
, PORT_MIPI_A
, 0); //DSI Port A
366 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL
, PORT_MIPI_C
, 0); //DSI Port C
369 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA
, PORT_CRT
, 0);
373 SetDevicePathNodeLength (&AcpiAdr
.Header
, sizeof (ACPI_ADR_DEVICE_PATH
));
375 MyDevicePath
= AppendDevicePathNode(MyDevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&AcpiAdr
);
377 gBS
->ConnectController (
384 FreePool(MyDevicePath
);
388 gBS
->ConnectController (
396 Status
= gBS
->LocateHandleBuffer (
398 &gEfiGraphicsOutputProtocolGuid
,
403 if (!EFI_ERROR (Status
)) {
405 // Add all the child handles as possible Console Device
407 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
408 Status
= gBS
->HandleProtocol (
409 GopHandleBuffer
[Index
],
410 &gEfiDevicePathProtocolGuid
,
411 (VOID
**)&TempDevicePath
413 if (EFI_ERROR (Status
)) {
419 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
422 // In current implementation, we only enable one of the child handles
423 // as console device, i.e. sotre one of the child handle's device
424 // path to variable "ConOut"
425 // In futhure, we could select all child handles to be console device
427 *GopDevicePath
= TempDevicePath
;
430 gBS
->FreePool (GopHandleBuffer
);
438 Search out all the platform pci or agp video device. The function may will
439 find multiple video device, and return all enabled device path.
441 @param PlugInPciVgaDevicePath Return the platform plug in pci video device
442 path if the system have plug in pci video device.
443 @param OnboardPciVgaDevicePath Return the platform active agp video device path
444 if the system have plug in agp video device or on
447 @retval EFI_SUCCSS Get all platform active video device path.
448 @retval EFI_STATUS Return the status of gBS->LocateDevicePath (),
449 gBS->ConnectController (),
450 and gBS->LocateHandleBuffer ().
454 GetPlugInPciVgaDevicePath (
455 IN OUT EFI_DEVICE_PATH_PROTOCOL
**PlugInPciVgaDevicePath
,
456 IN OUT EFI_DEVICE_PATH_PROTOCOL
**OnboardPciVgaDevicePath
460 EFI_HANDLE RootHandle
;
462 EFI_HANDLE
*HandleBuffer
;
465 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
466 BOOLEAN PlugInPciVga
;
467 EFI_PCI_IO_PROTOCOL
*PciIo
;
476 // Make all the PCI_IO protocols on PCI Seg 0 show up
478 BdsLibConnectDevicePath (gPlatformRootBridges
[0]);
480 Status
= gBS
->LocateDevicePath (
481 &gEfiDevicePathProtocolGuid
,
482 &gPlatformRootBridges
[0],
485 if (EFI_ERROR (Status
)) {
489 Status
= gBS
->ConnectController (
495 if (EFI_ERROR (Status
)) {
500 // Start to check all the pci io to find all possible VGA device
504 Status
= gBS
->LocateHandleBuffer (
506 &gEfiPciIoProtocolGuid
,
511 if (EFI_ERROR (Status
)) {
515 for (Index
= 0; Index
< HandleCount
; Index
++) {
516 Status
= gBS
->HandleProtocol (
518 &gEfiPciIoProtocolGuid
,
521 if (!EFI_ERROR (Status
)) {
524 // Check for all VGA device
526 Status
= PciIo
->Pci
.Read (
530 sizeof (Pci
) / sizeof (UINT32
),
533 if (EFI_ERROR (Status
)) {
538 // Here we decide which VGA device to enable in PCI bus
540 // The first plugin PCI VGA card device will be present as PCI VGA
541 // The onchip AGP or AGP card will be present as AGP VGA
543 if (!IS_PCI_VGA (&Pci
)) {
548 // Set the device as the possible console out device,
550 // Below code will make every VGA device to be one
551 // of the possibe console out device
554 gBS
->HandleProtocol (
556 &gEfiDevicePathProtocolGuid
,
562 while (gPlatformAllPossiblePciVgaConsole
[Index1
] != NULL
) {
565 gPlatformAllPossiblePciVgaConsole
[Index1
],
566 GetDevicePathSize (gPlatformAllPossiblePciVgaConsole
[Index1
])
570 // This device is an AGP device
572 *OnboardPciVgaDevicePath
= DevicePath
;
573 PlugInPciVga
= FALSE
;
581 *PlugInPciVgaDevicePath
= DevicePath
;
586 FreePool (HandleBuffer
);
593 Find the platform active vga, and base on the policy to enable the vga as
594 the console out device. The policy is driven by one setup variable "VBIOS".
598 @param EFI_UNSUPPORTED There is no active vga device
600 @retval EFI_STATUS Return the status of BdsLibGetVariableAndSize ()
604 PlatformBdsForceActiveVga (
609 EFI_DEVICE_PATH_PROTOCOL
*PlugInPciVgaDevicePath
;
610 EFI_DEVICE_PATH_PROTOCOL
*OnboardPciVgaDevicePath
;
611 EFI_DEVICE_PATH_PROTOCOL
*DevicePathFirst
;
612 EFI_DEVICE_PATH_PROTOCOL
*DevicePathSecond
;
613 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
615 SYSTEM_CONFIGURATION mSystemConfiguration
;
617 Status
= EFI_SUCCESS
;
618 PlugInPciVgaDevicePath
= NULL
;
619 OnboardPciVgaDevicePath
= NULL
;
622 // Check the policy which is the first enabled VGA
624 GetPlugInPciVgaDevicePath (&PlugInPciVgaDevicePath
, &OnboardPciVgaDevicePath
);
626 if (PlugInPciVgaDevicePath
== NULL
&& OnboardPciVgaDevicePath
== NULL
) {
627 return EFI_UNSUPPORTED
;
630 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
631 Status
= gRT
->GetVariable(
633 &gEfiNormalSetupGuid
,
636 &mSystemConfiguration
638 if (EFI_ERROR (Status
) || VarSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
639 //The setup variable is corrupted
640 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
641 Status
= gRT
->GetVariable(
643 &gEfiNormalSetupGuid
,
646 &mSystemConfiguration
648 ASSERT_EFI_ERROR (Status
);
652 if ((PlugInPciVgaDevicePath
== NULL
&& OnboardPciVgaDevicePath
!= NULL
) ) {
653 DEBUG ((EFI_D_ERROR
,"Update onboard PCI VGA ...\n"));
654 DevicePathFirst
= OnboardPciVgaDevicePath
;
655 DevicePathSecond
= PlugInPciVgaDevicePath
;
658 if(OnboardPciVgaDevicePath
!= NULL
&& mSystemConfiguration
.PrimaryVideoAdaptor
== 0) {
659 DEBUG ((EFI_D_ERROR
,"Update onboard PCI VGA When set primary!!!...\n"));
660 DevicePathFirst
= OnboardPciVgaDevicePath
;
661 DevicePathSecond
= PlugInPciVgaDevicePath
;
665 DEBUG ((EFI_D_ERROR
,"Update plug in PCI VGA ...\n"));
666 DevicePathFirst
= PlugInPciVgaDevicePath
;
667 DevicePathSecond
= OnboardPciVgaDevicePath
;
670 GetGopDevicePath (DevicePathFirst
, &GopDevicePath
);
671 DevicePathFirst
= GopDevicePath
;
673 Status
= BdsLibUpdateConsoleVariable (
683 UpdateConsoleResolution(
687 UINT32 HorizontalResolution
;
688 UINT32 VerticalResolution
;
689 SYSTEM_CONFIGURATION SystemConfiguration
;
694 HorizontalResolution
= PcdGet32 (PcdSetupVideoHorizontalResolution
);
695 VerticalResolution
= PcdGet32 (PcdSetupVideoVerticalResolution
);
697 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
698 Status
= gRT
->GetVariable(
700 &gEfiNormalSetupGuid
,
705 if (EFI_ERROR (Status
) || VarSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
706 //The setup variable is corrupted
707 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
708 Status
= gRT
->GetVariable(
710 &gEfiNormalSetupGuid
,
715 ASSERT_EFI_ERROR (Status
);
718 switch (SystemConfiguration
.IgdFlatPanel
) {
722 // Use the detault PCD values.
727 HorizontalResolution
= 640;
728 VerticalResolution
= 480;
732 HorizontalResolution
= 800;
733 VerticalResolution
= 600;
737 HorizontalResolution
= 1024;
738 VerticalResolution
= 768;
742 HorizontalResolution
= 1280;
743 VerticalResolution
= 1024;
747 HorizontalResolution
= 1366;
748 VerticalResolution
= 768;
752 HorizontalResolution
= 1680;
753 VerticalResolution
= 1050;
757 HorizontalResolution
= 1920;
758 VerticalResolution
= 1200;
762 HorizontalResolution
= 1280;
763 VerticalResolution
= 800;
767 PcdSet32 (PcdSetupVideoHorizontalResolution
, HorizontalResolution
);
768 PcdSet32 (PcdSetupVideoVerticalResolution
, VerticalResolution
);
769 DEBUG ((EFI_D_ERROR
, "HorizontalResolution = %x; VerticalResolution = %x", HorizontalResolution
, VerticalResolution
));
775 Connect the predefined platform default console device. Always try to find
776 and enable the vga device if have.
778 @param PlatformConsole Predfined platform default console device array.
780 @retval EFI_SUCCESS Success connect at least one ConIn and ConOut
781 device, there must have one ConOut device is
784 @retval EFI_STATUS Return the status of
785 BdsLibConnectAllDefaultConsoles ()
789 PlatformBdsConnectConsole (
790 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
795 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
796 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
797 UINTN DevicePathSize
;
799 UpdateConsoleResolution();
802 Status
= EFI_SUCCESS
;
804 VarConout
= BdsLibGetVariableAndSize (
806 &gEfiGlobalVariableGuid
,
809 VarConin
= BdsLibGetVariableAndSize (
811 &gEfiGlobalVariableGuid
,
814 if (VarConout
== NULL
|| VarConin
== NULL
) {
816 // Have chance to connect the platform default console,
817 // the platform default console is the minimue device group
818 // the platform should support
820 while (PlatformConsole
[Index
].DevicePath
!= NULL
) {
823 // Update the console variable with the connect type
825 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
826 BdsLibUpdateConsoleVariable (L
"ConIn", PlatformConsole
[Index
].DevicePath
, NULL
);
829 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
830 BdsLibUpdateConsoleVariable (L
"ConOut", PlatformConsole
[Index
].DevicePath
, NULL
);
833 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
834 BdsLibUpdateConsoleVariable (L
"ErrOut", PlatformConsole
[Index
].DevicePath
, NULL
);
842 // Make sure we have at least one active VGA, and have the right
843 // active VGA in console variable
845 Status
= PlatformBdsForceActiveVga ();
846 if (EFI_ERROR (Status
)) {
850 DEBUG ((EFI_D_INFO
, "DISPLAY INIT DONE\n"));
853 // Connect the all the default console with current console variable
855 Status
= BdsLibConnectAllDefaultConsoles ();
856 if (EFI_ERROR (Status
)) {
864 Connect with predeined platform connect sequence,
865 the OEM/IBV can customize with their own connect sequence.
873 PlatformBdsConnectSequence (
882 // Here we can get the customized platform connect sequence
883 // Notes: we can connect with new variable which record the
884 // last time boots connect device path sequence
886 while (gPlatformConnectSequence
[Index
] != NULL
) {
889 // Build the platform boot option
891 BdsLibConnectDevicePath (gPlatformConnectSequence
[Index
]);
896 // Just use the simple policy to connect all devices
897 // There should be no difference between debug tip and release tip, or it will be extremely hard to debug.
899 // There is case that IdeController driver will write boot script in driver model Start() function. It will be rejected by boot script save.
900 // It is only found when DEBUG disabled, because we are using BdsLibConnectAll() when DEBUG enabled.
902 // So we use BdsLibConnectAll() here to make sure IdeController.Start() is invoked before InstallReadyToLock().
903 // We may also consider to connect SataController only later if needed.
910 Load the predefined driver option, OEM/IBV can customize this
911 to load their own drivers
913 @param BdsDriverLists The header of the driver option link list.
919 PlatformBdsGetDriverOption (
920 IN OUT LIST_ENTRY
*BdsDriverLists
928 // Here we can get the customized platform driver option
930 while (gPlatformDriverOption
[Index
] != NULL
) {
933 // Build the platform boot option
935 BdsLibRegisterNewOption (BdsDriverLists
, gPlatformDriverOption
[Index
], NULL
, L
"DriverOrder");
942 This function is used for some critical time if the the system
943 have no any boot option, and there is no time out for user to add
944 the new boot option. This can also treat as the platform default
947 @param BdsBootOptionList The header of the boot option link list.
953 PlatformBdsPredictBootOption (
954 IN OUT LIST_ENTRY
*BdsBootOptionList
962 // Here give chance to get platform boot option data
964 while (gPlatformBootOption
[Index
] != NULL
) {
967 // Build the platform boot option
969 BdsLibRegisterNewOption (BdsBootOptionList
, gPlatformBootOption
[Index
], NULL
, L
"BootOrder");
975 Perform the platform diagnostic, such like test memory. OEM/IBV also
976 can customize this fuction to support specific platform diagnostic.
978 @param MemoryTestLevel The memory test intensive level
979 @param QuietBoot Indicate if need to enable the quiet boot
980 @param BaseMemoryTest A pointer to BdsMemoryTest()
986 PlatformBdsDiagnostics (
987 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
988 IN BOOLEAN QuietBoot
,
989 IN BASEM_MEMORY_TEST BaseMemoryTest
995 // Here we can decide if we need to show
996 // the diagnostics screen
997 // Notes: this quiet boot code should be remove
998 // from the graphic lib
1001 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
1004 // Perform system diagnostic
1006 Status
= BaseMemoryTest (MemoryTestLevel
);
1007 if (EFI_ERROR (Status
)) {
1008 DisableQuietBoot ();
1015 // Perform system diagnostic
1017 Status
= BaseMemoryTest (MemoryTestLevel
);
1022 For EFI boot option, BDS separate them as six types:
1023 1. Network - The boot option points to the SimpleNetworkProtocol device.
1024 Bds will try to automatically create this type boot option when enumerate.
1025 2. Shell - The boot option points to internal flash shell.
1026 Bds will try to automatically create this type boot option when enumerate.
1027 3. Removable BlockIo - The boot option only points to the removable media
1028 device, like USB flash disk, DVD, Floppy etc.
1029 These device should contain a *removable* blockIo
1030 protocol in their device handle.
1031 Bds will try to automatically create this type boot option
1033 4. Fixed BlockIo - The boot option only points to a Fixed blockIo device,
1035 These device should contain a *fixed* blockIo
1036 protocol in their device handle.
1037 BDS will skip fixed blockIo devices, and NOT
1038 automatically create boot option for them. But BDS
1039 will help to delete those fixed blockIo boot option,
1040 whose description rule conflict with other auto-created
1042 5. Non-BlockIo Simplefile - The boot option points to a device whose handle
1043 has SimpleFileSystem Protocol, but has no blockio
1044 protocol. These devices do not offer blockIo
1045 protocol, but BDS still can get the
1046 \EFI\BOOT\boot{machinename}.EFI by SimpleFileSystem
1048 6. File - The boot option points to a file. These boot options are usually
1049 created by user manually or OS loader. BDS will not delete or modify
1052 This function will enumerate all possible boot device in the system, and
1053 automatically create boot options for Network, Shell, Removable BlockIo,
1054 and Non-BlockIo Simplefile devices.
1055 It will only execute once of every boot.
1057 @param BdsBootOptionList The header of the link list which indexed all
1058 current boot options
1060 @retval EFI_SUCCESS Finished all the boot device enumerate and create
1061 the boot option base on that boot device
1063 @retval EFI_OUT_OF_RESOURCES Failed to enumerate the boot device and create the boot option list
1067 PlatformBdsLibEnumerateAllBootOption (
1068 IN OUT LIST_ENTRY
*BdsBootOptionList
1072 UINT16 FloppyNumber
;
1073 UINT16 HarddriveNumber
;
1078 UINT16 NonBlockNumber
;
1079 UINTN NumberBlockIoHandles
;
1080 EFI_HANDLE
*BlockIoHandles
;
1081 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
1082 BOOLEAN Removable
[2];
1083 UINTN RemovableIndex
;
1085 UINTN NumOfLoadFileHandles
;
1086 EFI_HANDLE
*LoadFileHandles
;
1087 UINTN FvHandleCount
;
1088 EFI_HANDLE
*FvHandleBuffer
;
1089 EFI_FV_FILETYPE Type
;
1091 EFI_FV_FILE_ATTRIBUTES Attributes
;
1092 UINT32 AuthenticationStatus
;
1093 EFI_FIRMWARE_VOLUME2_PROTOCOL
*Fv
;
1094 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1095 UINTN DevicePathType
;
1097 EFI_HANDLE
*FileSystemHandles
;
1098 UINTN NumberFileSystemHandles
;
1100 EFI_IMAGE_DOS_HEADER DosHeader
;
1103 EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData
;
1104 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
1107 EFI_HANDLE
*NetworkHandles
;
1111 HarddriveNumber
= 0;
1118 ZeroMem (Buffer
, sizeof (Buffer
));
1121 // If the boot device enumerate happened, just get the boot
1122 // device from the boot order variable
1124 if (mEnumBootDevice
) {
1125 GetVariable2 (LAST_ENUM_LANGUAGE_VARIABLE_NAME
, &gLastEnumLangGuid
, (VOID
**)&LastLang
, NULL
);
1126 GetEfiGlobalVariable2 (L
"PlatformLang", (VOID
**)&PlatLang
, NULL
);
1127 ASSERT (PlatLang
!= NULL
);
1128 if ((LastLang
!= NULL
) && (AsciiStrCmp (LastLang
, PlatLang
) == 0)) {
1129 Status
= BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
1130 FreePool (LastLang
);
1131 FreePool (PlatLang
);
1134 Status
= gRT
->SetVariable (
1135 LAST_ENUM_LANGUAGE_VARIABLE_NAME
,
1137 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1138 AsciiStrSize (PlatLang
),
1142 // Failure to set the variable only impacts the performance next time enumerating the boot options.
1145 if (LastLang
!= NULL
) {
1146 FreePool (LastLang
);
1148 FreePool (PlatLang
);
1153 // Notes: this dirty code is to get the legacy boot option from the
1154 // BBS table and create to variable as the EFI boot option, it should
1155 // be removed after the CSM can provide legacy boot option directly
1157 REFRESH_LEGACY_BOOT_OPTIONS
;
1160 // Delete invalid boot option
1162 BdsDeleteAllInvalidEfiBootOption ();
1165 // Parse removable media followed by fixed media.
1166 // The Removable[] array is used by the for-loop below to create removable media boot options
1167 // at first, and then to create fixed media boot options.
1169 Removable
[0] = FALSE
;
1170 Removable
[1] = TRUE
;
1172 gBS
->LocateHandleBuffer (
1174 &gEfiBlockIoProtocolGuid
,
1176 &NumberBlockIoHandles
,
1180 for (RemovableIndex
= 0; RemovableIndex
< 2; RemovableIndex
++) {
1181 for (Index
= 0; Index
< NumberBlockIoHandles
; Index
++) {
1182 Status
= gBS
->HandleProtocol (
1183 BlockIoHandles
[Index
],
1184 &gEfiBlockIoProtocolGuid
,
1188 // skip the logical partition
1190 if (EFI_ERROR (Status
) || BlkIo
->Media
->LogicalPartition
) {
1195 // firstly fixed block io then the removable block io
1197 if (BlkIo
->Media
->RemovableMedia
== Removable
[RemovableIndex
]) {
1200 DevicePath
= DevicePathFromHandle (BlockIoHandles
[Index
]);
1201 DevicePathType
= BdsGetBootTypeFromDevicePath (DevicePath
);
1203 switch (DevicePathType
) {
1204 case BDS_EFI_ACPI_FLOPPY_BOOT
:
1205 if (FloppyNumber
!= 0) {
1206 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY
)), FloppyNumber
);
1208 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY
)));
1210 BdsLibBuildOptionFromHandle (BlockIoHandles
[Index
], BdsBootOptionList
, Buffer
);
1215 // Assume a removable SATA device should be the DVD/CD device, a fixed SATA device should be the Hard Drive device.
1217 case BDS_EFI_MESSAGE_ATAPI_BOOT
:
1218 case BDS_EFI_MESSAGE_SATA_BOOT
:
1219 if (BlkIo
->Media
->RemovableMedia
) {
1220 if (CdromNumber
!= 0) {
1221 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD
)), CdromNumber
);
1223 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD
)));
1227 if (HarddriveNumber
!= 0) {
1228 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE
)), HarddriveNumber
);
1230 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE
)));
1234 DEBUG ((DEBUG_INFO
| DEBUG_LOAD
, "Buffer: %S\n", Buffer
));
1235 BdsLibBuildOptionFromHandle (BlockIoHandles
[Index
], BdsBootOptionList
, Buffer
);
1238 case BDS_EFI_MESSAGE_USB_DEVICE_BOOT
:
1239 if (UsbNumber
!= 0) {
1240 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB
)), UsbNumber
);
1242 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB
)));
1244 BdsLibBuildOptionFromHandle (BlockIoHandles
[Index
], BdsBootOptionList
, Buffer
);
1248 case BDS_EFI_MESSAGE_SCSI_BOOT
:
1249 if (ScsiNumber
!= 0) {
1250 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI
)), ScsiNumber
);
1252 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI
)));
1254 BdsLibBuildOptionFromHandle (BlockIoHandles
[Index
], BdsBootOptionList
, Buffer
);
1258 case BDS_EFI_MESSAGE_MISC_BOOT
:
1260 if (MiscNumber
!= 0) {
1261 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC
)), MiscNumber
);
1263 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC
)));
1265 BdsLibBuildOptionFromHandle (BlockIoHandles
[Index
], BdsBootOptionList
, Buffer
);
1272 if (NumberBlockIoHandles
!= 0) {
1273 FreePool (BlockIoHandles
);
1277 // If there is simple file protocol which does not consume block Io protocol, create a boot option for it here.
1280 gBS
->LocateHandleBuffer (
1282 &gEfiSimpleFileSystemProtocolGuid
,
1284 &NumberFileSystemHandles
,
1287 for (Index
= 0; Index
< NumberFileSystemHandles
; Index
++) {
1288 Status
= gBS
->HandleProtocol (
1289 FileSystemHandles
[Index
],
1290 &gEfiBlockIoProtocolGuid
,
1293 if (!EFI_ERROR (Status
)) {
1295 // Skip if the file system handle supports a BlkIo protocol,
1301 // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
1302 // machinename is ia32, ia64, x64, ...
1304 Hdr
.Union
= &HdrData
;
1306 Status
= BdsLibGetImageHeader (
1307 FileSystemHandles
[Index
],
1308 EFI_REMOVABLE_MEDIA_FILE_NAME
,
1312 if (!EFI_ERROR (Status
) &&
1313 EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr
.Pe32
->FileHeader
.Machine
) &&
1314 Hdr
.Pe32
->OptionalHeader
.Subsystem
== EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION
) {
1320 // No such file or the file is not a EFI application, delete this boot option
1322 BdsLibDeleteOptionFromHandle (FileSystemHandles
[Index
]);
1324 if (NonBlockNumber
!= 0) {
1325 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK
)), NonBlockNumber
);
1327 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK
)));
1329 BdsLibBuildOptionFromHandle (FileSystemHandles
[Index
], BdsBootOptionList
, Buffer
);
1334 if (NumberFileSystemHandles
!= 0) {
1335 FreePool (FileSystemHandles
);
1339 // Check if we have on flash shell
1341 gBS
->LocateHandleBuffer (
1343 &gEfiFirmwareVolume2ProtocolGuid
,
1348 for (Index
= 0; Index
< FvHandleCount
; Index
++) {
1349 gBS
->HandleProtocol (
1350 FvHandleBuffer
[Index
],
1351 &gEfiFirmwareVolume2ProtocolGuid
,
1355 Status
= Fv
->ReadFile (
1357 PcdGetPtr(PcdShellFile
),
1362 &AuthenticationStatus
1364 if (EFI_ERROR (Status
)) {
1366 // Skip if no shell file in the FV
1371 // Build the shell boot option
1373 BdsLibBuildOptionFromShell (FvHandleBuffer
[Index
], BdsBootOptionList
);
1376 if (FvHandleCount
!= 0) {
1377 FreePool (FvHandleBuffer
);
1381 // Parse Network Boot Device
1383 NumOfLoadFileHandles
= 0;
1385 // Search Load File protocol for PXE boot option.
1387 gBS
->LocateHandleBuffer (
1389 &gEfiLoadFileProtocolGuid
,
1391 &NumOfLoadFileHandles
,
1395 for (Index
= 0; Index
< NumOfLoadFileHandles
; Index
++) {
1398 //Locate EFI_DEVICE_PATH_PROTOCOL to dynamically get IPv4/IPv6 protocol information.
1401 Status
= gBS
->HandleProtocol (
1402 LoadFileHandles
[Index
],
1403 &gEfiDevicePathProtocolGuid
,
1404 (VOID
**) &DevicePath
1407 ASSERT_EFI_ERROR (Status
);
1409 while (!IsDevicePathEnd (DevicePath
)) {
1410 if ((DevicePath
->Type
== MESSAGING_DEVICE_PATH
) &&
1411 (DevicePath
->SubType
== MSG_IPv4_DP
)) {
1414 //Get handle infomation
1417 NetworkHandles
= NULL
;
1418 Status
= gBS
->LocateHandle (
1420 &gEfiSimpleNetworkProtocolGuid
,
1426 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1427 NetworkHandles
= AllocateZeroPool(BufferSize
);
1428 if (NetworkHandles
== NULL
) {
1429 return (EFI_OUT_OF_RESOURCES
);
1431 Status
= gBS
->LocateHandle(
1433 &gEfiSimpleNetworkProtocolGuid
,
1441 //Get the MAC string
1443 Status
= NetLibGetMacString (
1448 if (EFI_ERROR (Status
)) {
1451 IPverStr
= L
" IPv4";
1452 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s%s%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK
)),MacStr
,IPverStr
);
1455 if((DevicePath
->Type
== MESSAGING_DEVICE_PATH
) &&
1456 (DevicePath
->SubType
== MSG_IPv6_DP
)) {
1459 //Get handle infomation
1462 NetworkHandles
= NULL
;
1463 Status
= gBS
->LocateHandle (
1465 &gEfiSimpleNetworkProtocolGuid
,
1471 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1472 NetworkHandles
= AllocateZeroPool(BufferSize
);
1473 if (NetworkHandles
== NULL
) {
1474 return (EFI_OUT_OF_RESOURCES
);
1476 Status
= gBS
->LocateHandle(
1478 &gEfiSimpleNetworkProtocolGuid
,
1486 //Get the MAC string
1488 Status
= NetLibGetMacString (
1493 if (EFI_ERROR (Status
)) {
1496 IPverStr
= L
" IPv6";
1497 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s%s%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK
)),MacStr
,IPverStr
);
1500 DevicePath
= NextDevicePathNode (DevicePath
);
1503 BdsLibBuildOptionFromHandle (LoadFileHandles
[Index
], BdsBootOptionList
, Buffer
);
1506 if (NumOfLoadFileHandles
!= 0) {
1507 FreePool (LoadFileHandles
);
1511 // Check if we have on flash shell
1513 /* gBS->LocateHandleBuffer (
1515 &gEfiFirmwareVolume2ProtocolGuid,
1520 for (Index = 0; Index < FvHandleCount; Index++) {
1521 gBS->HandleProtocol (
1522 FvHandleBuffer[Index],
1523 &gEfiFirmwareVolume2ProtocolGuid,
1527 Status = Fv->ReadFile (
1529 PcdGetPtr(PcdShellFile),
1534 &AuthenticationStatus
1536 if (EFI_ERROR (Status)) {
1538 // Skip if no shell file in the FV
1543 // Build the shell boot option
1545 BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);
1548 if (FvHandleCount != 0) {
1549 FreePool (FvHandleBuffer);
1553 // Make sure every boot only have one time
1554 // boot device enumerate
1556 Status
= BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
1557 mEnumBootDevice
= TRUE
;
1566 The function will excute with as the platform policy, current policy
1567 is driven by boot mode. IBV/OEM can customize this code for their specific
1570 @param DriverOptionList - The header of the driver option link list
1571 @param BootOptionList - The header of the boot option link list
1572 @param ProcessCapsules - A pointer to ProcessCapsules()
1573 @param BaseMemoryTest - A pointer to BaseMemoryTest()
1580 PlatformBdsPolicyBehavior (
1581 IN OUT LIST_ENTRY
*DriverOptionList
,
1582 IN OUT LIST_ENTRY
*BootOptionList
,
1583 IN PROCESS_CAPSULES ProcessCapsules
,
1584 IN BASEM_MEMORY_TEST BaseMemoryTest
1589 EFI_BOOT_MODE BootMode
;
1590 BOOLEAN DeferredImageExist
;
1592 CHAR16 CapsuleVarName
[36];
1593 CHAR16
*TempVarName
;
1594 SYSTEM_CONFIGURATION SystemConfiguration
;
1596 BOOLEAN SetVariableFlag
;
1597 PLATFORM_PCI_DEVICE_PATH
*EmmcBootDevPath
;
1598 EFI_GLOBAL_NVS_AREA_PROTOCOL
*GlobalNvsArea
;
1599 EFI_HANDLE FvProtocolHandle
;
1601 EFI_HANDLE
*HandleBuffer
;
1603 UINTN SataPciRegBase
= 0;
1604 UINT16 SataModeSelect
= 0;
1605 VOID
*RegistrationExitPmAuth
= NULL
;
1607 BOOLEAN IsFirstBoot
;
1609 UINTN BootOrderSize
;
1611 Timeout
= PcdGet16 (PcdPlatformBootTimeOut
);
1612 if (Timeout
> 10 ) {
1613 //we think the Timeout variable is corrupted
1617 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
1618 Status
= gRT
->GetVariable(
1620 &gEfiNormalSetupGuid
,
1623 &SystemConfiguration
1626 if (EFI_ERROR (Status
) || VarSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
1627 //The setup variable is corrupted
1628 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
1629 Status
= gRT
->GetVariable(
1631 &gEfiNormalSetupGuid
,
1634 &SystemConfiguration
1636 ASSERT_EFI_ERROR (Status
);
1640 // Load the driver option as the driver option list
1642 PlatformBdsGetDriverOption (DriverOptionList
);
1645 // Get current Boot Mode
1647 BootMode
= GetBootModeHob();
1650 // Clear all the capsule variables CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...
1651 // as early as possible which will avoid the next time boot after the capsule update
1652 // will still into the capsule loop
1654 StrCpy (CapsuleVarName
, EFI_CAPSULE_VARIABLE_NAME
);
1655 TempVarName
= CapsuleVarName
+ StrLen (CapsuleVarName
);
1657 SetVariableFlag
= TRUE
;
1658 while (SetVariableFlag
) {
1660 UnicodeValueToString (TempVarName
, 0, Index
, 0);
1662 Status
= gRT
->SetVariable (
1664 &gEfiCapsuleVendorGuid
,
1665 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
|
1666 EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1670 if (EFI_ERROR (Status
)) {
1672 // There is no capsule variables, quit
1674 SetVariableFlag
= FALSE
;
1681 // No deferred images exist by default
1683 DeferredImageExist
= FALSE
;
1684 if ((BootMode
!= BOOT_WITH_MINIMAL_CONFIGURATION
) && (PcdGet32(PcdFlashFvShellSize
) > 0)){
1685 gDS
->ProcessFirmwareVolume (
1686 (VOID
*)(UINTN
)PcdGet32(PcdFlashFvShellBase
),
1687 PcdGet32(PcdFlashFvShellSize
),
1692 if (SystemConfiguration
.FastBoot
== 1) {
1693 BootOrder
= BdsLibGetVariableAndSize (
1695 &gEfiGlobalVariableGuid
,
1698 if ((BootOrder
!= NULL
) && (BootMode
!= BOOT_ON_FLASH_UPDATE
)) {
1700 // BootOrder exist, it means system has boot before. We can do fast boot.
1702 BootMode
= BOOT_WITH_MINIMAL_CONFIGURATION
;
1708 // Use eMMC to boot OS and turn on AHCI, when SATA HDD is diconnected,
1709 // SATA AHCI CTLR device will show yellow bang, implement this solution to solve it.
1711 SataPciRegBase
= MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA
, 0, 0);
1712 SataModeSelect
= MmioRead16 (SataPciRegBase
+ R_PCH_SATA_MAP
) & B_PCH_SATA_MAP_SMS_MASK
;
1713 Status
= EFI_SUCCESS
;
1714 if (SataModeSelect
!= V_PCH_SATA_MAP_SMS_IDE
) {
1715 Status
= gBS
->CreateEvent (
1722 if (!EFI_ERROR (Status
)) {
1723 Status
= gBS
->RegisterProtocolNotify (
1724 &gExitPmAuthProtocolGuid
,
1726 &RegistrationExitPmAuth
1733 case BOOT_WITH_MINIMAL_CONFIGURATION
:
1734 PlatformBdsInitHotKeyEvent ();
1735 PlatformBdsConnectSimpleConsole (gPlatformSimpleConsole
);
1739 // Check to see if it's needed to dispatch more DXE drivers.
1741 for (Index
= 0; Index
< sizeof(ConnectDriverTable
)/sizeof(EFI_GUID
*); Index
++) {
1742 Status
= gBS
->LocateHandleBuffer (
1744 ConnectDriverTable
[Index
],
1749 if (!EFI_ERROR (Status
)) {
1750 for (Index1
= 0; Index1
< HandleCount
; Index1
++) {
1751 gBS
->ConnectController (
1752 HandleBuffer
[Index1
],
1760 if (HandleBuffer
!= NULL
) {
1761 FreePool (HandleBuffer
);
1768 // Locate the Global NVS Protocol.
1770 Status
= gBS
->LocateProtocol (
1771 &gEfiGlobalNvsAreaProtocolGuid
,
1773 (void **)&GlobalNvsArea
1775 if (GlobalNvsArea
->Area
->emmcVersion
== 0){
1776 EmmcBootDevPath
= (PLATFORM_PCI_DEVICE_PATH
*)gPlatformSimpleBootOption
[0];
1777 EmmcBootDevPath
->PciDevice
.Device
= 0x10;
1781 // Connect boot device here to give time to read keyboard.
1783 BdsLibConnectDevicePath (gPlatformSimpleBootOption
[0]);
1786 // This is a workround for dectecting hotkey from USB keyboard.
1788 gBS
->Stall(KEYBOARD_TIMER_INTERVAL
);
1790 if (mHotKeyTimerEvent
!= NULL
) {
1796 gBS
->CloseEvent (mHotKeyTimerEvent
);
1797 mHotKeyTimerEvent
= NULL
;
1799 if (mHotKeyPressed
) {
1801 // Skip show progress count down
1804 goto FULL_CONFIGURATION
;
1807 if (SystemConfiguration
.QuietBoot
) {
1808 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
1810 PlatformBdsDiagnostics (IGNORE
, FALSE
, BaseMemoryTest
);
1815 TcgPhysicalPresenceLibProcessRequest();
1818 TrEEPhysicalPresenceLibProcessRequest(NULL
);
1821 // Close boot script and install ready to lock
1823 InstallReadyToLock ();
1826 // Give one chance to enter the setup if we
1827 // select Gummiboot "Reboot Into Firmware Interface" and Fast Boot is enabled.
1829 BootIntoFirmwareInterface();
1832 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES
:
1835 // In no-configuration boot mode, we can connect the
1836 // console directly.
1838 BdsLibConnectAllDefaultConsoles ();
1839 PlatformBdsDiagnostics (IGNORE
, TRUE
, BaseMemoryTest
);
1842 // Perform some platform specific connect sequence
1844 PlatformBdsConnectSequence ();
1847 // As console is ready, perform user identification again.
1849 if (mCurrentUser
== NULL
) {
1850 PlatformBdsUserIdentify (&mCurrentUser
, &DeferredImageExist
);
1851 if (DeferredImageExist
) {
1853 // After user authentication, the deferred drivers was loaded again.
1854 // Here, need to ensure the deferred images are connected.
1856 BdsLibConnectAllDefaultConsoles ();
1857 PlatformBdsConnectSequence ();
1862 // Close boot script and install ready to lock
1864 InstallReadyToLock ();
1867 // Notes: current time out = 0 can not enter the
1870 PlatformBdsEnterFrontPageWithHotKey (Timeout
, FALSE
);
1873 // Check the boot option with the boot option list
1875 BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
1878 case BOOT_ON_FLASH_UPDATE
:
1881 // Boot with the specific configuration
1883 PlatformBdsConnectConsole (gPlatformConsole
);
1884 PlatformBdsDiagnostics (EXTENSIVE
, FALSE
, BaseMemoryTest
);
1885 BdsLibConnectAll ();
1888 // Perform user identification
1890 if (mCurrentUser
== NULL
) {
1891 PlatformBdsUserIdentify (&mCurrentUser
, &DeferredImageExist
);
1892 if (DeferredImageExist
) {
1894 // After user authentication, the deferred drivers was loaded again.
1895 // Here, need to ensure the deferred images are connected.
1897 BdsLibConnectAll ();
1902 // Close boot script and install ready to lock
1904 InstallReadyToLock ();
1906 ProcessCapsules (BOOT_ON_FLASH_UPDATE
);
1909 case BOOT_IN_RECOVERY_MODE
:
1912 // In recovery mode, just connect platform console
1913 // and show up the front page
1915 PlatformBdsConnectConsole (gPlatformConsole
);
1916 PlatformBdsDiagnostics (EXTENSIVE
, FALSE
, BaseMemoryTest
);
1917 BdsLibConnectAll ();
1920 // Perform user identification
1922 if (mCurrentUser
== NULL
) {
1923 PlatformBdsUserIdentify (&mCurrentUser
, &DeferredImageExist
);
1924 if (DeferredImageExist
) {
1926 // After user authentication, the deferred drivers was loaded again.
1927 // Here, need to ensure the deferred drivers are connected.
1929 BdsLibConnectAll ();
1934 // Close boot script and install ready to lock
1936 InstallReadyToLock ();
1939 // In recovery boot mode, we still enter to the
1942 PlatformBdsEnterFrontPageWithHotKey (Timeout
, FALSE
);
1946 case BOOT_WITH_FULL_CONFIGURATION
:
1947 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS
:
1948 case BOOT_WITH_DEFAULT_SETTINGS
:
1952 // Connect platform console
1954 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
1955 if (EFI_ERROR (Status
)) {
1958 // Here OEM/IBV can customize with defined action
1960 PlatformBdsNoConsoleAction ();
1964 // Chenyunh[TODO]: This is Workgroud to show the fs for uSDcard,
1965 // Need to root cause this issue.
1967 DEBUG ((DEBUG_ERROR
, "Start to reconnect all driver.\n"));
1968 BdsLibDisconnectAllEfi();
1969 BdsLibConnectAll ();
1970 DEBUG ((DEBUG_ERROR
, "End to reconnect all driver.\n"));
1973 // Perform some platform specific connect sequence
1975 PlatformBdsConnectSequence ();
1976 if (SystemConfiguration
.QuietBoot
) {
1977 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
1979 PlatformBdsDiagnostics (IGNORE
, FALSE
, BaseMemoryTest
);
1983 // Do a pre-delay so Hard Disk can spin up and see more logo.
1985 gBS
->Stall(SystemConfiguration
.HddPredelay
* 1000000);
1988 // Perform user identification
1990 if (mCurrentUser
== NULL
) {
1991 PlatformBdsUserIdentify (&mCurrentUser
, &DeferredImageExist
);
1992 if (DeferredImageExist
) {
1994 // After user authentication, the deferred drivers was loaded again.
1995 // Here, need to ensure the deferred drivers are connected.
1997 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
1998 if (EFI_ERROR (Status
)) {
1999 PlatformBdsNoConsoleAction ();
2001 PlatformBdsConnectSequence ();
2005 TcgPhysicalPresenceLibProcessRequest();
2008 TrEEPhysicalPresenceLibProcessRequest(NULL
);
2011 // Close boot script and install ready to lock
2013 InstallReadyToLock ();
2016 // Here we have enough time to do the enumeration of boot device
2018 PlatformBdsLibEnumerateAllBootOption (BootOptionList
);
2021 // Give one chance to enter the setup if we
2022 // have the time out
2024 PlatformBdsEnterFrontPageWithHotKey (Timeout
, FALSE
);
2027 // Give one chance to enter the setup if we
2028 // select Gummiboot "Reboot Into Firmware Interface"
2030 BootIntoFirmwareInterface();
2033 // In default boot mode, always find all boot
2034 // option and do enumerate all the default boot option
2037 BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
2038 if (IsListEmpty(BootOptionList
)) {
2039 PlatformBdsPredictBootOption (BootOptionList
);
2050 IsFirstBoot
= PcdGetBool(PcdBootState
);
2052 PcdSetBool(PcdBootState
, FALSE
);
2059 Hook point after a boot attempt succeeds. We don't expect a boot option to
2060 return, so the UEFI 2.0 specification defines that you will default to an
2061 interactive mode and stop processing the BootOrder list in this case. This
2062 is alos a platform implementation and can be customized by IBV/OEM.
2064 @param Option Pointer to Boot Option that succeeded to boot.
2071 PlatformBdsBootSuccess (
2072 IN BDS_COMMON_OPTION
*Option
2078 // If Boot returned with EFI_SUCCESS and there is not in the boot device
2079 // select loop then we need to pop up a UI and wait for user input.
2081 TmpStr
= Option
->StatusString
;
2082 if (TmpStr
!= NULL
) {
2083 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
2089 Hook point after a boot attempt fails.
2091 @param Option - Pointer to Boot Option that failed to boot.
2092 @param Status - Status returned from failed boot.
2093 @param ExitData - Exit data returned from failed boot.
2094 @param ExitDataSize - Exit data size returned from failed boot.
2101 PlatformBdsBootFail (
2102 IN BDS_COMMON_OPTION
*Option
,
2103 IN EFI_STATUS Status
,
2104 IN CHAR16
*ExitData
,
2105 IN UINTN ExitDataSize
2109 EFI_HANDLE FvProtocolHandle
;
2112 // If Boot returned with failed status then we need to pop up a UI and wait
2115 TmpStr
= Option
->StatusString
;
2116 if (TmpStr
!= NULL
) {
2117 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
2120 if (PcdGet32(PcdFlashFvShellSize
) > 0){
2121 gDS
->ProcessFirmwareVolume (
2122 (VOID
*)(UINTN
)PcdGet32(PcdFlashFvShellBase
),
2123 PcdGet32(PcdFlashFvShellSize
),
2127 PlatformBdsConnectSequence ();
2131 This function is remained for IBV/OEM to do some platform action,
2132 if there no console device can be connected.
2136 @retval EFI_SUCCESS Direct return success now.
2140 PlatformBdsNoConsoleAction (
2148 This function locks the block
2150 @param Base The base address flash region to be locked.
2155 IN EFI_PHYSICAL_ADDRESS Base
2158 EFI_FV_BLOCK_MAP_ENTRY
*BlockMap
;
2159 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
2160 EFI_PHYSICAL_ADDRESS BaseAddress
;
2165 BaseAddress
= Base
- 0x400000 + 2;
2166 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINTN
) (Base
));
2167 BlockMap
= &(FvHeader
->BlockMap
[0]);
2169 while ((BlockMap
->NumBlocks
!= 0) && (BlockMap
->Length
!= 0)) {
2170 BlockLength
= BlockMap
->Length
;
2171 for (Index
= 0; Index
< BlockMap
->NumBlocks
; Index
++) {
2172 Data
= MmioOr8 ((UINTN
) BaseAddress
, 0x03);
2173 BaseAddress
+= BlockLength
;
2181 PlatformBdsLockNonUpdatableFlash (
2185 EFI_PHYSICAL_ADDRESS Base
;
2187 Base
= (EFI_PHYSICAL_ADDRESS
) PcdGet32 (PcdFlashFvMainBase
);
2192 Base
= (EFI_PHYSICAL_ADDRESS
) PcdGet32 (PcdFlashFvRecoveryBase
);
2199 Lock the ConsoleIn device in system table. All key
2200 presses will be ignored until the Password is typed in. The only way to
2201 disable the password is to type it in to a ConIn device.
2203 @param Password Password used to lock ConIn device.
2205 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
2206 @retval EFI_UNSUPPORTED Password not found
2215 return EFI_UNSUPPORTED
;
2219 Connect the predefined platform default authentication devices.
2221 This function connects the predefined device path for authentication device,
2222 and if the predefined device path has child device path, the child handle will
2223 be connected too. But the child handle of the child will not be connected.
2228 PlatformBdsConnectAuthDevice (
2236 EFI_HANDLE
*HandleBuffer
;
2237 EFI_DEVICE_PATH_PROTOCOL
*ChildDevicePath
;
2238 EFI_USER_MANAGER_PROTOCOL
*Manager
;
2240 Status
= gBS
->LocateProtocol (
2241 &gEfiUserManagerProtocolGuid
,
2245 if (EFI_ERROR (Status
)) {
2247 // As user manager protocol is not installed, the authentication devices
2248 // should not be connected.
2254 while (gUserAuthenticationDevice
[Index
] != NULL
) {
2256 // Connect the platform customized device paths
2258 BdsLibConnectDevicePath (gUserAuthenticationDevice
[Index
]);
2263 // Find and connect the child device paths of the platform customized device paths
2265 HandleBuffer
= NULL
;
2266 for (Index
= 0; gUserAuthenticationDevice
[Index
] != NULL
; Index
++) {
2268 Status
= gBS
->LocateHandleBuffer (
2275 ASSERT (!EFI_ERROR (Status
));
2278 // Find and connect the child device paths of gUserIdentificationDevice[Index]
2280 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
2281 ChildDevicePath
= NULL
;
2282 Status
= gBS
->HandleProtocol (
2283 HandleBuffer
[HandleIndex
],
2284 &gEfiDevicePathProtocolGuid
,
2285 (VOID
**) &ChildDevicePath
2287 if (EFI_ERROR (Status
) || ChildDevicePath
== NULL
) {
2293 gUserAuthenticationDevice
[Index
],
2294 (GetDevicePathSize (gUserAuthenticationDevice
[Index
]) - sizeof (EFI_DEVICE_PATH_PROTOCOL
))
2298 gBS
->ConnectController (
2299 HandleBuffer
[HandleIndex
],
2307 if (HandleBuffer
!= NULL
) {
2308 FreePool (HandleBuffer
);
2313 This function is to identify a user, and return whether deferred images exist.
2315 @param[out] User Point to user profile handle.
2316 @param[out] DeferredImageExist On return, points to TRUE if the deferred image
2317 exist or FALSE if it did not exist.
2322 PlatformBdsUserIdentify (
2323 OUT EFI_USER_PROFILE_HANDLE
*User
,
2324 OUT BOOLEAN
*DeferredImageExist
2328 EFI_DEFERRED_IMAGE_LOAD_PROTOCOL
*DeferredImage
;
2330 EFI_HANDLE
*HandleBuf
;
2333 EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
;
2339 // Perform user identification
2342 Status
= BdsLibUserIdentify (User
);
2343 } while (EFI_ERROR (Status
));
2346 // After user authentication now, try to find whether deferred image exists
2350 *DeferredImageExist
= FALSE
;
2351 Status
= gBS
->LocateHandleBuffer (
2353 &gEfiDeferredImageLoadProtocolGuid
,
2358 if (EFI_ERROR (Status
)) {
2362 for (Index
= 0; Index
< HandleCount
; Index
++) {
2363 Status
= gBS
->HandleProtocol (
2365 &gEfiDeferredImageLoadProtocolGuid
,
2366 (VOID
**) &DeferredImage
2368 if (!EFI_ERROR (Status
)) {
2370 // Find whether deferred image exists in this instance.
2373 Status
= DeferredImage
->GetImageInfo(
2377 (VOID
**) &DriverImage
,
2381 if (!EFI_ERROR (Status
)) {
2383 // The deferred image is found.
2385 FreePool (HandleBuf
);
2386 *DeferredImageExist
= TRUE
;
2392 FreePool (HandleBuf
);
2399 ShowProgressHotKey (
2400 IN UINT16 TimeoutDefault
2404 UINT16 TimeoutRemain
;
2407 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
2408 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
2409 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
2412 if (TimeoutDefault
== 0) {
2416 gST
->ConOut
->SetAttribute(gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
2418 if (DebugAssertEnabled())
2420 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"));
2425 SerialPortWrite((UINT8
*)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)[GCC]", 76);
2427 SerialPortWrite((UINT8
*)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)", 71);
2430 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
2431 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
2432 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
2435 // Clear the progress status bar first
2437 TmpStr
= L
"Start boot option, Press <F2> or <DEL> to enter setup page.";
2438 PlatformBdsShowProgress (Foreground
, Background
, TmpStr
, Color
, 0, 0);
2440 TimeoutRemain
= TimeoutDefault
;
2441 while (TimeoutRemain
!= 0) {
2442 if (DebugAssertEnabled())
2444 DEBUG ((EFI_D_INFO
, "Showing progress bar...Remaining %d second!\n", TimeoutRemain
));
2448 SerialPortWrite ((UINT8
*)".", 1);
2450 Status
= WaitForSingleEvent (gST
->ConIn
->WaitForKey
, ONE_SECOND
);
2451 if (Status
!= EFI_TIMEOUT
) {
2459 if (TmpStr
!= NULL
) {
2460 PlatformBdsShowProgress (
2465 ((TimeoutDefault
- TimeoutRemain
) * 100 / TimeoutDefault
),
2474 if (TimeoutRemain
== 0) {
2475 if (DebugAssertEnabled())
2480 SerialPortWrite ((UINT8
*)"\r\n", 2);
2486 // User pressed some key
2488 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
2489 if (EFI_ERROR (Status
)) {
2494 // Check Volume Up Key to enter Setup
2496 GpioValue
= MmioRead32 (IO_BASE_ADDRESS
+ 0x0668); // The value of GPIOC_5
2497 if (((GpioValue
& BIT0
) == 0) && (Key
.ScanCode
== SCAN_UP
)) {
2502 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
2504 // User pressed enter, equivalent to select "continue"
2511 //F5 -- Device Manager
2512 //F7 -- Boot Manager
2513 // do not use F8. generally people assume it is windows safe mode key.
2516 DEBUG ((EFI_D_INFO
, "[Key Pressed]: ScanCode 0x%x\n", Key
.ScanCode
));
2517 switch(Key
.ScanCode
) {
2527 gHotKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
2531 gHotKey
= FRONT_PAGE_KEY_BOOT_MANAGER
;
2535 gHotKey
= FRONT_PAGE_KEY_BOOT_MAINTAIN
;
2539 //set gHotKey to continue so that flow will not go into CallFrontPage
2540 gHotKey
= FRONT_PAGE_KEY_CONTINUE
;
2551 This function is the main entry of the platform setup entry.
2552 The function will present the main menu of the system setup,
2553 this is the platform reference part and can be customize.
2556 @param TimeoutDefault The fault time out value before the system
2558 @param ConnectAllHappened The indicater to check if the connect all have
2563 PlatformBdsEnterFrontPageWithHotKey (
2564 IN UINT16 TimeoutDefault
,
2565 IN BOOLEAN ConnectAllHappened
2570 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
2571 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOut
;
2572 UINTN BootTextColumn
;
2575 GraphicsOutput
= NULL
;
2576 SimpleTextOut
= NULL
;
2578 PERF_START (NULL
, "BdsTimeOut", "BDS", 0);
2581 // Indicate if we need connect all in the platform setup
2583 if (ConnectAllHappened
) {
2584 gConnectAllHappened
= TRUE
;
2587 if (!mModeInitialized
) {
2589 // After the console is ready, get current video resolution
2590 // and text mode before launching setup at first time.
2592 Status
= gBS
->HandleProtocol (
2593 gST
->ConsoleOutHandle
,
2594 &gEfiGraphicsOutputProtocolGuid
,
2595 (VOID
**)&GraphicsOutput
2597 if (EFI_ERROR (Status
)) {
2598 GraphicsOutput
= NULL
;
2601 Status
= gBS
->HandleProtocol (
2602 gST
->ConsoleOutHandle
,
2603 &gEfiSimpleTextOutProtocolGuid
,
2604 (VOID
**)&SimpleTextOut
2606 if (EFI_ERROR (Status
)) {
2607 SimpleTextOut
= NULL
;
2610 if (GraphicsOutput
!= NULL
) {
2612 // Get current video resolution and text mode.
2614 mBootHorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
2615 mBootVerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
2618 if (SimpleTextOut
!= NULL
) {
2619 Status
= SimpleTextOut
->QueryMode (
2621 SimpleTextOut
->Mode
->Mode
,
2625 mBootTextModeColumn
= (UINT32
)BootTextColumn
;
2626 mBootTextModeRow
= (UINT32
)BootTextRow
;
2630 // Get user defined text mode for setup.
2632 mSetupHorizontalResolution
= PcdGet32 (PcdSetupVideoHorizontalResolution
);
2633 mSetupVerticalResolution
= PcdGet32 (PcdSetupVideoVerticalResolution
);
2634 mSetupTextModeColumn
= PcdGet32 (PcdSetupConOutColumn
);
2635 mSetupTextModeRow
= PcdGet32 (PcdSetupConOutRow
);
2637 mModeInitialized
= TRUE
;
2640 if (TimeoutDefault
!= 0xffff) {
2641 Status
= ShowProgressHotKey (TimeoutDefault
);
2644 // Ensure screen is clear when switch Console from Graphics mode to Text mode
2646 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);
2647 gST
->ConOut
->ClearScreen (gST
->ConOut
);
2649 if (EFI_ERROR (Status
)) {
2651 // Timeout or user press enter to continue
2657 // Install BM HiiPackages.
2658 // Keep BootMaint HiiPackage, so that it can be covered by global setting.
2663 BdsSetConsoleMode (TRUE
);
2665 InitializeFrontPage (FALSE
);
2668 // Update Front Page strings
2670 UpdateFrontPageStrings ();
2672 Status
= EFI_SUCCESS
;
2675 Status
= CallFrontPage ();
2677 gCallbackKey
= gHotKey
;
2682 // If gCallbackKey is greater than 1 and less or equal to 5,
2683 // it will launch configuration utilities.
2686 // 4 = device manager
2687 // 5 = boot maintenance manager
2689 if (gCallbackKey
!= 0) {
2690 REPORT_STATUS_CODE (
2692 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_USER_SETUP
)
2697 // Based on the key that was set, we can determine what to do
2699 switch (gCallbackKey
) {
2701 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
2702 // describe to their customers in documentation how to find their setup information (namely
2703 // under the device manager and specific buckets)
2705 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
2707 case FRONT_PAGE_KEY_CONTINUE
:
2710 // User hit continue
2714 case FRONT_PAGE_KEY_LANGUAGE
:
2717 // User made a language setting change - display front page again
2721 case FRONT_PAGE_KEY_BOOT_MANAGER
:
2723 // Remove the installed BootMaint HiiPackages when exit.
2728 // User chose to run the Boot Manager
2733 // Reinstall BootMaint HiiPackages after exiting from Boot Manager.
2738 case FRONT_PAGE_KEY_DEVICE_MANAGER
:
2741 // Display the Device Manager
2744 CallDeviceManager ();
2745 } while (gCallbackKey
== FRONT_PAGE_KEY_DEVICE_MANAGER
);
2748 case FRONT_PAGE_KEY_BOOT_MAINTAIN
:
2751 // Display the Boot Maintenance Manager
2753 BdsStartBootMaint ();
2757 } while (((UINTN
)gCallbackKey
) != FRONT_PAGE_KEY_CONTINUE
);
2760 //Will leave browser, check any reset required change is applied? if yes, reset system
2762 SetupResetReminder ();
2764 // Remove the installed BootMaint HiiPackages when exit.
2770 // Automatically load current entry
2771 // Note: The following lines of code only execute when Auto boot
2774 PERF_END (NULL
, "BdsTimeOut", "BDS", 0);
2779 BootIntoFirmwareInterface(
2786 UINT64 OsIndication
;
2790 DataSize
= sizeof(UINT64
);
2791 Status
= gRT
->GetVariable (
2793 &gEfiGlobalVariableGuid
,
2799 DEBUG ((EFI_D_INFO
, "OSIndication Variable Value %d\n", OsIndication
));
2801 //Goto FrontPage directly when bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted.
2803 if (!EFI_ERROR(Status
) && (OsIndication
!= 0)) {
2805 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
2811 PlatformBdsConnectSimpleConsole (
2812 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
2817 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
2818 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
2819 UINTN DevicePathSize
;
2823 Status
= EFI_SUCCESS
;
2825 VarConout
= BdsLibGetVariableAndSize (
2827 &gEfiGlobalVariableGuid
,
2830 VarConin
= BdsLibGetVariableAndSize (
2832 &gEfiGlobalVariableGuid
,
2835 if (VarConout
== NULL
|| VarConin
== NULL
) {
2837 // Have chance to connect the platform default console,
2838 // the platform default console is the minimue device group
2839 // the platform should support
2841 while (PlatformConsole
[Index
].DevicePath
!= NULL
) {
2844 // Update the console variable with the connect type
2846 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
2847 BdsLibUpdateConsoleVariable (L
"ConIn", PlatformConsole
[Index
].DevicePath
, NULL
);
2850 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
2851 BdsLibUpdateConsoleVariable (L
"ConOut", PlatformConsole
[Index
].DevicePath
, NULL
);
2854 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
2855 BdsLibUpdateConsoleVariable (L
"ErrOut", PlatformConsole
[Index
].DevicePath
, NULL
);
2863 // Connect ConIn first to give keyboard time to parse hot key event.
2865 Status
= BdsLibConnectConsoleVariable (L
"ConIn");
2866 if (EFI_ERROR (Status
)) {
2871 // Make sure we have at least one active VGA, and have the right
2872 // active VGA in console variable
2874 Status
= PlatformBdsForceActiveVga ();
2877 // It seems impossible not to have any ConOut device on platform,
2878 // so we check the status here.
2880 Status
= BdsLibConnectConsoleVariable (L
"ConOut");
2881 if (EFI_ERROR (Status
)) {
2890 Timer handler to convert the key from USB.
2892 @param Event Indicates the event that invoke this function.
2893 @param Context Indicates the calling context.
2897 HotKeyTimerHandler (
2905 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
2906 if (EFI_ERROR (Status
)) {
2910 switch(Key
.ScanCode
) {
2913 mHotKeyPressed
= TRUE
;
2917 gHotKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
2918 mHotKeyPressed
= TRUE
;
2922 gHotKey
= FRONT_PAGE_KEY_BOOT_MANAGER
;
2923 mHotKeyPressed
= TRUE
;
2927 gHotKey
= FRONT_PAGE_KEY_BOOT_MAINTAIN
;
2928 mHotKeyPressed
= TRUE
;
2932 if (mHotKeyPressed
) {
2938 gBS
->CloseEvent (mHotKeyTimerEvent
);
2939 mHotKeyTimerEvent
= NULL
;
2947 Callback function for SimpleTextInEx protocol install events
2949 @param Event the event that is signaled.
2950 @param Context not used here.
2962 Status
= gBS
->CloseEvent(mHitHotkeyEvent
);
2963 if (EFI_ERROR (Status
)) {
2966 Status
= gBS
->CreateEvent (
2967 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
2973 if (EFI_ERROR (Status
)) {
2976 Status
= gBS
->SetTimer (
2979 KEYBOARD_TIMER_INTERVAL
2981 if (EFI_ERROR (Status
)) {
2991 PlatformBdsInitHotKeyEvent (
2998 // Register Protocol notify for Hotkey service
3000 Status
= gBS
->CreateEvent (
3007 ASSERT_EFI_ERROR (Status
);
3010 // Register for protocol notifications on this event
3012 Status
= gBS
->RegisterProtocolNotify (
3013 &gEfiSimpleTextInputExProtocolGuid
,
3015 &mHitHotkeyRegistration
3017 ASSERT_EFI_ERROR (Status
);