3 Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
15 This file include all platform action which can be customized
20 #include "BdsPlatform.h"
21 #include "SetupMode.h"
22 #include <Guid/SetupVariable.h>
23 #include <Library/TcgPhysicalPresenceLib.h>
24 #include <Library/Tcg2PhysicalPresenceLib.h>
25 #include <Protocol/I2cMasterMcg.h>
27 #include <PlatformBaseAddresses.h>
28 #include <Protocol/GlobalNvsArea.h>
29 #include <Library/DxeServicesTableLib.h>
30 #include <Protocol/BlockIo.h>
31 #include <PchRegs/PchRegsPcu.h>
32 #include <Library/S3BootScriptLib.h>
33 #include "PchAccess.h"
34 #include "PchRegs/PchRegsSata.h"
35 #include <Library/SerialPortLib.h>
36 #include <Library/DebugLib.h>
38 #include <Library/GenericBdsLib/InternalBdsLib.h>
39 #include <Library/GenericBdsLib/String.h>
40 #include <Library/NetLib.h>
42 #include <Library/CapsuleLib.h>
43 #include <Protocol/EsrtManagement.h>
45 EFI_GUID
*ConnectDriverTable
[] = {
46 &gEfiMmioDeviceProtocolGuid
,
47 &gEfiI2cMasterProtocolGuid
,
48 &gEfiI2cHostProtocolGuid
51 #define SHELL_ENVIRONMENT_INTERFACE_PROTOCOL \
53 0x47c7b221, 0xc42a, 0x11d2, 0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b \
55 VOID
*mShellImageCallbackReg
= NULL
;
59 EFI_USER_PROFILE_HANDLE mCurrentUser
= NULL
;
60 EFI_EVENT mHotKeyTimerEvent
= NULL
;
61 EFI_EVENT mHitHotkeyEvent
= NULL
;
62 EFI_EVENT mUsbKeyboardConnectEvent
= NULL
;
63 BOOLEAN mHotKeyPressed
= FALSE
;
64 VOID
*mHitHotkeyRegistration
;
65 #define KEYBOARD_TIMER_INTERVAL 20000 // 0.02s
68 ConnectUSBController (
73 PlatformBdsConnectSimpleConsole (
74 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
78 BootIntoFirmwareInterface(
84 PlatformBdsInitHotKeyEvent (
95 UINT32 PmcDisableAddress
;
96 UINT8 SataStorageAmount
;
98 UINT16 SataPortStatus
;
101 DEBUG ((EFI_D_INFO
, "Disable AHCI event is signalled\n"));
102 SataStorageAmount
= 0;
103 SataBase
= *(UINT32
*) Context
;
106 // BayTrail-M EDS chapter 16 ---- PCI IO Register Offset 92 (SATA Port Control and Status)
108 SataPortStatus
= MmioRead16 (SataBase
+ R_PCH_SATA_PCS
);
111 // Bit 8 EN: Port 0 Present
113 if ((SataPortStatus
& 0x100) == 0x100) {
118 // Bit 9 EN: Port 1 Present
120 if ((SataPortStatus
& 0x200) == 0x200) {
125 // Disable SATA controller when it sets to AHCI mode without carrying any devices
126 // in order to prevent AHCI yellow bang under Win device manager.
128 if (SataStorageAmount
== 0) {
129 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
;
130 MmioOr32 (PmcDisableAddress
, B_PCH_PMC_FUNC_DIS_SATA
);
131 S3BootScriptSaveMemWrite (
132 EfiBootScriptWidthUint32
,
133 (UINTN
) PmcDisableAddress
,
135 (VOID
*) (UINTN
) PmcDisableAddress
147 EFI_SMM_ACCESS2_PROTOCOL
*SmmAccess
;
148 EFI_ACPI_S3_SAVE_PROTOCOL
*AcpiS3Save
;
151 // Install DxeSmmReadyToLock protocol prior to the processing of boot options
153 Status
= gBS
->LocateProtocol (
154 &gEfiSmmAccess2ProtocolGuid
,
158 if (!EFI_ERROR (Status
)) {
161 // Prepare S3 information, this MUST be done before DxeSmmReadyToLock
163 Status
= gBS
->LocateProtocol (
164 &gEfiAcpiS3SaveProtocolGuid
,
168 if (!EFI_ERROR (Status
)) {
169 AcpiS3Save
->S3Save (AcpiS3Save
, NULL
);
173 Status
= gBS
->InstallProtocolInterface (
175 &gExitPmAuthProtocolGuid
,
176 EFI_NATIVE_INTERFACE
,
179 ASSERT_EFI_ERROR (Status
);
182 // Signal EndOfDxe PI Event
184 EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid
);
187 Status
= gBS
->InstallProtocolInterface (
189 &gEfiDxeSmmReadyToLockProtocolGuid
,
190 EFI_NATIVE_INTERFACE
,
193 ASSERT_EFI_ERROR (Status
);
206 BdsSetConsoleMode (TRUE
);
207 DEBUG ((EFI_D_INFO
, "BdsEntry ShellImageCallback \n"));
211 // BDS Platform Functions
214 Platform Bds init. Include the platform firmware vendor, revision
229 EFI_EVENT ShellImageEvent
;
230 EFI_GUID ShellEnvProtocol
= SHELL_ENVIRONMENT_INTERFACE_PROTOCOL
;
233 SerialPortWrite((UINT8
*)">>>>BdsEntry[GCC]\r\n", 19);
235 SerialPortWrite((UINT8
*)">>>>BdsEntry\r\n", 14);
237 BdsLibSaveMemoryTypeInformation ();
240 // Before user authentication, the user identification devices need be connected
241 // from the platform customized device paths
243 PlatformBdsConnectAuthDevice ();
246 // As console is not ready, the auto logon user will be identified.
248 BdsLibUserIdentify (&mCurrentUser
);
251 // Change Gop mode when boot into Shell
253 if (mShellImageCallbackReg
== NULL
) {
254 Status
= gBS
->CreateEvent (
255 EFI_EVENT_NOTIFY_SIGNAL
,
261 if (!EFI_ERROR (Status
)) {
262 Status
= gBS
->RegisterProtocolNotify (
265 &mShellImageCallbackReg
268 DEBUG ((EFI_D_INFO
, "BdsEntry ShellImageCallback \n"));
275 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
276 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
281 EFI_HANDLE PciDeviceHandle
;
282 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
283 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
284 UINTN GopHandleCount
;
285 EFI_HANDLE
*GopHandleBuffer
;
288 SYSTEM_CONFIGURATION mSystemConfiguration
;
290 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
291 return EFI_INVALID_PARAMETER
;
295 // Initialize the GopDevicePath to be PciDevicePath
297 *GopDevicePath
= PciDevicePath
;
298 TempPciDevicePath
= PciDevicePath
;
300 Status
= gBS
->LocateDevicePath (
301 &gEfiDevicePathProtocolGuid
,
305 if (EFI_ERROR (Status
)) {
310 // Try to connect this handle, so that GOP driver could start on this
311 // device and create child handles with GraphicsOutput Protocol installed
312 // on them, then we get device paths of these child handles and select
313 // them as possible console device.
317 // Select display devices
319 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
320 Status
= gRT
->GetVariable(
322 &gEfiNormalSetupGuid
,
325 &mSystemConfiguration
327 if (EFI_ERROR (Status
) || VarSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
328 //The setup variable is corrupted
329 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
330 Status
= gRT
->GetVariable(
332 &gEfiNormalSetupGuid
,
335 &mSystemConfiguration
337 ASSERT_EFI_ERROR (Status
);
340 if(mSystemConfiguration
.BootDisplayDevice
!= 0x0)
342 ACPI_ADR_DEVICE_PATH AcpiAdr
;
343 EFI_DEVICE_PATH_PROTOCOL
*MyDevicePath
= NULL
;
345 AcpiAdr
.Header
.Type
= ACPI_DEVICE_PATH
;
346 AcpiAdr
.Header
.SubType
= ACPI_ADR_DP
;
348 switch (mSystemConfiguration
.BootDisplayDevice
) {
350 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA
, PORT_CRT
, 0); //CRT Device
353 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL
, PORT_B_HDMI
, 0); //HDMI Device Port B
356 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL
, PORT_B_DP
, 0); //DP PortB
359 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL
, PORT_C_DP
, 0); //DP PortC
362 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL
, PORT_C_DP
, 0); //eDP Port C
365 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL
, PORT_MIPI_A
, 0); //DSI Port A
368 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL
, PORT_MIPI_C
, 0); //DSI Port C
371 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA
, PORT_CRT
, 0);
375 SetDevicePathNodeLength (&AcpiAdr
.Header
, sizeof (ACPI_ADR_DEVICE_PATH
));
377 MyDevicePath
= AppendDevicePathNode(MyDevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&AcpiAdr
);
379 gBS
->ConnectController (
386 FreePool(MyDevicePath
);
390 gBS
->ConnectController (
398 Status
= gBS
->LocateHandleBuffer (
400 &gEfiGraphicsOutputProtocolGuid
,
405 if (!EFI_ERROR (Status
)) {
407 // Add all the child handles as possible Console Device
409 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
410 Status
= gBS
->HandleProtocol (
411 GopHandleBuffer
[Index
],
412 &gEfiDevicePathProtocolGuid
,
413 (VOID
**)&TempDevicePath
415 if (EFI_ERROR (Status
)) {
421 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
424 // In current implementation, we only enable one of the child handles
425 // as console device, i.e. sotre one of the child handle's device
426 // path to variable "ConOut"
427 // In future, we could select all child handles to be console device
429 *GopDevicePath
= TempDevicePath
;
432 gBS
->FreePool (GopHandleBuffer
);
440 Search out all the platform pci or agp video device. The function may will
441 find multiple video device, and return all enabled device path.
443 @param PlugInPciVgaDevicePath Return the platform plug in pci video device
444 path if the system have plug in pci video device.
445 @param OnboardPciVgaDevicePath Return the platform active agp video device path
446 if the system have plug in agp video device or on
449 @retval EFI_SUCCSS Get all platform active video device path.
450 @retval EFI_STATUS Return the status of gBS->LocateDevicePath (),
451 gBS->ConnectController (),
452 and gBS->LocateHandleBuffer ().
456 GetPlugInPciVgaDevicePath (
457 IN OUT EFI_DEVICE_PATH_PROTOCOL
**PlugInPciVgaDevicePath
,
458 IN OUT EFI_DEVICE_PATH_PROTOCOL
**OnboardPciVgaDevicePath
462 EFI_HANDLE RootHandle
;
464 EFI_HANDLE
*HandleBuffer
;
467 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
468 BOOLEAN PlugInPciVga
;
469 EFI_PCI_IO_PROTOCOL
*PciIo
;
478 // Make all the PCI_IO protocols on PCI Seg 0 show up
480 BdsLibConnectDevicePath (gPlatformRootBridges
[0]);
482 Status
= gBS
->LocateDevicePath (
483 &gEfiDevicePathProtocolGuid
,
484 &gPlatformRootBridges
[0],
487 if (EFI_ERROR (Status
)) {
491 Status
= gBS
->ConnectController (
497 if (EFI_ERROR (Status
)) {
502 // Start to check all the pci io to find all possible VGA device
506 Status
= gBS
->LocateHandleBuffer (
508 &gEfiPciIoProtocolGuid
,
513 if (EFI_ERROR (Status
)) {
517 for (Index
= 0; Index
< HandleCount
; Index
++) {
518 Status
= gBS
->HandleProtocol (
520 &gEfiPciIoProtocolGuid
,
523 if (!EFI_ERROR (Status
)) {
526 // Check for all VGA device
528 Status
= PciIo
->Pci
.Read (
532 sizeof (Pci
) / sizeof (UINT32
),
535 if (EFI_ERROR (Status
)) {
540 // Here we decide which VGA device to enable in PCI bus
542 // The first plugin PCI VGA card device will be present as PCI VGA
543 // The onchip AGP or AGP card will be present as AGP VGA
545 if (!IS_PCI_VGA (&Pci
)) {
550 // Set the device as the possible console out device,
552 // Below code will make every VGA device to be one
553 // of the possibe console out device
556 gBS
->HandleProtocol (
558 &gEfiDevicePathProtocolGuid
,
564 while (gPlatformAllPossiblePciVgaConsole
[Index1
] != NULL
) {
567 gPlatformAllPossiblePciVgaConsole
[Index1
],
568 GetDevicePathSize (gPlatformAllPossiblePciVgaConsole
[Index1
])
572 // This device is an AGP device
574 *OnboardPciVgaDevicePath
= DevicePath
;
575 PlugInPciVga
= FALSE
;
583 *PlugInPciVgaDevicePath
= DevicePath
;
588 FreePool (HandleBuffer
);
595 Find the platform active vga, and base on the policy to enable the vga as
596 the console out device. The policy is driven by one setup variable "VBIOS".
600 @param EFI_UNSUPPORTED There is no active vga device
602 @retval EFI_STATUS Return the status of BdsLibGetVariableAndSize ()
606 PlatformBdsForceActiveVga (
611 EFI_DEVICE_PATH_PROTOCOL
*PlugInPciVgaDevicePath
;
612 EFI_DEVICE_PATH_PROTOCOL
*OnboardPciVgaDevicePath
;
613 EFI_DEVICE_PATH_PROTOCOL
*DevicePathFirst
;
614 EFI_DEVICE_PATH_PROTOCOL
*DevicePathSecond
;
615 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
617 SYSTEM_CONFIGURATION mSystemConfiguration
;
619 Status
= EFI_SUCCESS
;
620 PlugInPciVgaDevicePath
= NULL
;
621 OnboardPciVgaDevicePath
= NULL
;
624 // Check the policy which is the first enabled VGA
626 GetPlugInPciVgaDevicePath (&PlugInPciVgaDevicePath
, &OnboardPciVgaDevicePath
);
628 if (PlugInPciVgaDevicePath
== NULL
&& OnboardPciVgaDevicePath
== NULL
) {
629 return EFI_UNSUPPORTED
;
632 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
633 Status
= gRT
->GetVariable(
635 &gEfiNormalSetupGuid
,
638 &mSystemConfiguration
640 if (EFI_ERROR (Status
) || VarSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
641 //The setup variable is corrupted
642 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
643 Status
= gRT
->GetVariable(
645 &gEfiNormalSetupGuid
,
648 &mSystemConfiguration
650 ASSERT_EFI_ERROR (Status
);
654 if ((PlugInPciVgaDevicePath
== NULL
&& OnboardPciVgaDevicePath
!= NULL
) ) {
655 DEBUG ((EFI_D_ERROR
,"Update onboard PCI VGA ...\n"));
656 DevicePathFirst
= OnboardPciVgaDevicePath
;
657 DevicePathSecond
= PlugInPciVgaDevicePath
;
660 if(OnboardPciVgaDevicePath
!= NULL
&& mSystemConfiguration
.PrimaryVideoAdaptor
== 0) {
661 DEBUG ((EFI_D_ERROR
,"Update onboard PCI VGA When set primary!!!...\n"));
662 DevicePathFirst
= OnboardPciVgaDevicePath
;
663 DevicePathSecond
= PlugInPciVgaDevicePath
;
667 DEBUG ((EFI_D_ERROR
,"Update plug in PCI VGA ...\n"));
668 DevicePathFirst
= PlugInPciVgaDevicePath
;
669 DevicePathSecond
= OnboardPciVgaDevicePath
;
672 GetGopDevicePath (DevicePathFirst
, &GopDevicePath
);
673 DevicePathFirst
= GopDevicePath
;
675 Status
= BdsLibUpdateConsoleVariable (
685 UpdateConsoleResolution(
689 UINT32 HorizontalResolution
;
690 UINT32 VerticalResolution
;
691 SYSTEM_CONFIGURATION SystemConfiguration
;
696 HorizontalResolution
= PcdGet32 (PcdSetupVideoHorizontalResolution
);
697 VerticalResolution
= PcdGet32 (PcdSetupVideoVerticalResolution
);
699 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
700 Status
= gRT
->GetVariable(
702 &gEfiNormalSetupGuid
,
707 if (EFI_ERROR (Status
) || VarSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
708 //The setup variable is corrupted
709 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
710 Status
= gRT
->GetVariable(
712 &gEfiNormalSetupGuid
,
717 ASSERT_EFI_ERROR (Status
);
720 switch (SystemConfiguration
.IgdFlatPanel
) {
724 // Use the detault PCD values.
729 HorizontalResolution
= 640;
730 VerticalResolution
= 480;
734 HorizontalResolution
= 800;
735 VerticalResolution
= 600;
739 HorizontalResolution
= 1024;
740 VerticalResolution
= 768;
744 HorizontalResolution
= 1280;
745 VerticalResolution
= 1024;
749 HorizontalResolution
= 1366;
750 VerticalResolution
= 768;
754 HorizontalResolution
= 1680;
755 VerticalResolution
= 1050;
759 HorizontalResolution
= 1920;
760 VerticalResolution
= 1200;
764 HorizontalResolution
= 1280;
765 VerticalResolution
= 800;
769 PcdSet32 (PcdSetupVideoHorizontalResolution
, HorizontalResolution
);
770 PcdSet32 (PcdSetupVideoVerticalResolution
, VerticalResolution
);
771 DEBUG ((EFI_D_ERROR
, "HorizontalResolution = %x; VerticalResolution = %x", HorizontalResolution
, VerticalResolution
));
777 Connect the predefined platform default console device. Always try to find
778 and enable the vga device if have.
780 @param PlatformConsole Predefined platform default console device array.
782 @retval EFI_SUCCESS Success connect at least one ConIn and ConOut
783 device, there must have one ConOut device is
786 @retval EFI_STATUS Return the status of
787 BdsLibConnectAllDefaultConsoles ()
791 PlatformBdsConnectConsole (
792 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
797 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
798 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
799 UINTN DevicePathSize
;
801 UpdateConsoleResolution();
804 Status
= EFI_SUCCESS
;
806 VarConout
= BdsLibGetVariableAndSize (
808 &gEfiGlobalVariableGuid
,
811 VarConin
= BdsLibGetVariableAndSize (
813 &gEfiGlobalVariableGuid
,
816 if (VarConout
== NULL
|| VarConin
== NULL
) {
818 // Have chance to connect the platform default console,
819 // the platform default console is the minimum device group
820 // the platform should support
822 while (PlatformConsole
[Index
].DevicePath
!= NULL
) {
825 // Update the console variable with the connect type
827 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
828 BdsLibUpdateConsoleVariable (L
"ConIn", PlatformConsole
[Index
].DevicePath
, NULL
);
831 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
832 BdsLibUpdateConsoleVariable (L
"ConOut", PlatformConsole
[Index
].DevicePath
, NULL
);
835 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
836 BdsLibUpdateConsoleVariable (L
"ErrOut", PlatformConsole
[Index
].DevicePath
, NULL
);
844 // Make sure we have at least one active VGA, and have the right
845 // active VGA in console variable
847 Status
= PlatformBdsForceActiveVga ();
848 if (EFI_ERROR (Status
)) {
852 DEBUG ((EFI_D_INFO
, "DISPLAY INIT DONE\n"));
855 // Connect the all the default console with current console variable
857 Status
= BdsLibConnectAllDefaultConsoles ();
858 if (EFI_ERROR (Status
)) {
866 Connect with predefined platform connect sequence,
867 the OEM/IBV can customize with their own connect sequence.
875 PlatformBdsConnectSequence (
884 // Here we can get the customized platform connect sequence
885 // Notes: we can connect with new variable which record the
886 // last time boots connect device path sequence
888 while (gPlatformConnectSequence
[Index
] != NULL
) {
891 // Build the platform boot option
893 BdsLibConnectDevicePath (gPlatformConnectSequence
[Index
]);
898 // Just use the simple policy to connect all devices
899 // There should be no difference between debug tip and release tip, or it will be extremely hard to debug.
901 // There is case that IdeController driver will write boot script in driver model Start() function. It will be rejected by boot script save.
902 // It is only found when DEBUG disabled, because we are using BdsLibConnectAll() when DEBUG enabled.
904 // So we use BdsLibConnectAll() here to make sure IdeController.Start() is invoked before InstallReadyToLock().
905 // We may also consider to connect SataController only later if needed.
912 Load the predefined driver option, OEM/IBV can customize this
913 to load their own drivers
915 @param BdsDriverLists The header of the driver option link list.
921 PlatformBdsGetDriverOption (
922 IN OUT LIST_ENTRY
*BdsDriverLists
930 // Here we can get the customized platform driver option
932 while (gPlatformDriverOption
[Index
] != NULL
) {
935 // Build the platform boot option
937 BdsLibRegisterNewOption (BdsDriverLists
, gPlatformDriverOption
[Index
], NULL
, L
"DriverOrder");
944 This function is used for some critical time if the the system
945 have no any boot option, and there is no time out for user to add
946 the new boot option. This can also treat as the platform default
949 @param BdsBootOptionList The header of the boot option link list.
955 PlatformBdsPredictBootOption (
956 IN OUT LIST_ENTRY
*BdsBootOptionList
964 // Here give chance to get platform boot option data
966 while (gPlatformBootOption
[Index
] != NULL
) {
969 // Build the platform boot option
971 BdsLibRegisterNewOption (BdsBootOptionList
, gPlatformBootOption
[Index
], NULL
, L
"BootOrder");
977 Perform the platform diagnostic, such like test memory. OEM/IBV also
978 can customize this fuction to support specific platform diagnostic.
980 @param MemoryTestLevel The memory test intensive level
981 @param QuietBoot Indicate if need to enable the quiet boot
982 @param BaseMemoryTest A pointer to BdsMemoryTest()
988 PlatformBdsDiagnostics (
989 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
990 IN BOOLEAN QuietBoot
,
991 IN BASEM_MEMORY_TEST BaseMemoryTest
997 // Here we can decide if we need to show
998 // the diagnostics screen
999 // Notes: this quiet boot code should be remove
1000 // from the graphic lib
1003 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
1006 // Perform system diagnostic
1008 Status
= BaseMemoryTest (MemoryTestLevel
);
1009 if (EFI_ERROR (Status
)) {
1010 DisableQuietBoot ();
1017 // Perform system diagnostic
1019 Status
= BaseMemoryTest (MemoryTestLevel
);
1024 For EFI boot option, BDS separate them as six types:
1025 1. Network - The boot option points to the SimpleNetworkProtocol device.
1026 Bds will try to automatically create this type boot option when enumerate.
1027 2. Shell - The boot option points to internal flash shell.
1028 Bds will try to automatically create this type boot option when enumerate.
1029 3. Removable BlockIo - The boot option only points to the removable media
1030 device, like USB flash disk, DVD, Floppy etc.
1031 These device should contain a *removable* blockIo
1032 protocol in their device handle.
1033 Bds will try to automatically create this type boot option
1035 4. Fixed BlockIo - The boot option only points to a Fixed blockIo device,
1037 These device should contain a *fixed* blockIo
1038 protocol in their device handle.
1039 BDS will skip fixed blockIo devices, and NOT
1040 automatically create boot option for them. But BDS
1041 will help to delete those fixed blockIo boot option,
1042 whose description rule conflict with other auto-created
1044 5. Non-BlockIo Simplefile - The boot option points to a device whose handle
1045 has SimpleFileSystem Protocol, but has no blockio
1046 protocol. These devices do not offer blockIo
1047 protocol, but BDS still can get the
1048 \EFI\BOOT\boot{machinename}.EFI by SimpleFileSystem
1050 6. File - The boot option points to a file. These boot options are usually
1051 created by user manually or OS loader. BDS will not delete or modify
1054 This function will enumerate all possible boot device in the system, and
1055 automatically create boot options for Network, Shell, Removable BlockIo,
1056 and Non-BlockIo Simplefile devices.
1057 It will only execute once of every boot.
1059 @param BdsBootOptionList The header of the link list which indexed all
1060 current boot options
1062 @retval EFI_SUCCESS Finished all the boot device enumerate and create
1063 the boot option base on that boot device
1065 @retval EFI_OUT_OF_RESOURCES Failed to enumerate the boot device and create the boot option list
1069 PlatformBdsLibEnumerateAllBootOption (
1070 IN OUT LIST_ENTRY
*BdsBootOptionList
1074 UINT16 FloppyNumber
;
1075 UINT16 HarddriveNumber
;
1080 UINT16 NonBlockNumber
;
1081 UINTN NumberBlockIoHandles
;
1082 EFI_HANDLE
*BlockIoHandles
;
1083 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
1084 BOOLEAN Removable
[2];
1085 UINTN RemovableIndex
;
1087 UINTN NumOfLoadFileHandles
;
1088 EFI_HANDLE
*LoadFileHandles
;
1089 UINTN FvHandleCount
;
1090 EFI_HANDLE
*FvHandleBuffer
;
1091 EFI_FV_FILETYPE Type
;
1093 EFI_FV_FILE_ATTRIBUTES Attributes
;
1094 UINT32 AuthenticationStatus
;
1095 EFI_FIRMWARE_VOLUME2_PROTOCOL
*Fv
;
1096 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1097 UINTN DevicePathType
;
1099 EFI_HANDLE
*FileSystemHandles
;
1100 UINTN NumberFileSystemHandles
;
1102 EFI_IMAGE_DOS_HEADER DosHeader
;
1105 EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData
;
1106 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
1109 EFI_HANDLE
*NetworkHandles
;
1113 HarddriveNumber
= 0;
1120 ZeroMem (Buffer
, sizeof (Buffer
));
1123 // If the boot device enumerate happened, just get the boot
1124 // device from the boot order variable
1126 if (mEnumBootDevice
) {
1127 GetVariable2 (LAST_ENUM_LANGUAGE_VARIABLE_NAME
, &gLastEnumLangGuid
, (VOID
**)&LastLang
, NULL
);
1128 GetEfiGlobalVariable2 (L
"PlatformLang", (VOID
**)&PlatLang
, NULL
);
1129 ASSERT (PlatLang
!= NULL
);
1130 if ((LastLang
!= NULL
) && (AsciiStrCmp (LastLang
, PlatLang
) == 0)) {
1131 Status
= BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
1132 FreePool (LastLang
);
1133 FreePool (PlatLang
);
1136 Status
= gRT
->SetVariable (
1137 LAST_ENUM_LANGUAGE_VARIABLE_NAME
,
1139 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1140 AsciiStrSize (PlatLang
),
1144 // Failure to set the variable only impacts the performance next time enumerating the boot options.
1147 if (LastLang
!= NULL
) {
1148 FreePool (LastLang
);
1150 FreePool (PlatLang
);
1155 // Notes: this dirty code is to get the legacy boot option from the
1156 // BBS table and create to variable as the EFI boot option, it should
1157 // be removed after the CSM can provide legacy boot option directly
1159 REFRESH_LEGACY_BOOT_OPTIONS
;
1162 // Delete invalid boot option
1164 BdsDeleteAllInvalidEfiBootOption ();
1167 // Parse removable media followed by fixed media.
1168 // The Removable[] array is used by the for-loop below to create removable media boot options
1169 // at first, and then to create fixed media boot options.
1171 Removable
[0] = FALSE
;
1172 Removable
[1] = TRUE
;
1174 gBS
->LocateHandleBuffer (
1176 &gEfiBlockIoProtocolGuid
,
1178 &NumberBlockIoHandles
,
1182 for (RemovableIndex
= 0; RemovableIndex
< 2; RemovableIndex
++) {
1183 for (Index
= 0; Index
< NumberBlockIoHandles
; Index
++) {
1184 Status
= gBS
->HandleProtocol (
1185 BlockIoHandles
[Index
],
1186 &gEfiBlockIoProtocolGuid
,
1190 // skip the logical partition
1192 if (EFI_ERROR (Status
) || BlkIo
->Media
->LogicalPartition
) {
1197 // firstly fixed block io then the removable block io
1199 if (BlkIo
->Media
->RemovableMedia
== Removable
[RemovableIndex
]) {
1202 DevicePath
= DevicePathFromHandle (BlockIoHandles
[Index
]);
1203 DevicePathType
= BdsGetBootTypeFromDevicePath (DevicePath
);
1205 switch (DevicePathType
) {
1206 case BDS_EFI_ACPI_FLOPPY_BOOT
:
1207 if (FloppyNumber
!= 0) {
1208 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY
)), FloppyNumber
);
1210 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY
)));
1212 BdsLibBuildOptionFromHandle (BlockIoHandles
[Index
], BdsBootOptionList
, Buffer
);
1217 // Assume a removable SATA device should be the DVD/CD device, a fixed SATA device should be the Hard Drive device.
1219 case BDS_EFI_MESSAGE_ATAPI_BOOT
:
1220 case BDS_EFI_MESSAGE_SATA_BOOT
:
1221 if (BlkIo
->Media
->RemovableMedia
) {
1222 if (CdromNumber
!= 0) {
1223 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD
)), CdromNumber
);
1225 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD
)));
1229 if (HarddriveNumber
!= 0) {
1230 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE
)), HarddriveNumber
);
1232 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE
)));
1236 DEBUG ((DEBUG_INFO
| DEBUG_LOAD
, "Buffer: %S\n", Buffer
));
1237 BdsLibBuildOptionFromHandle (BlockIoHandles
[Index
], BdsBootOptionList
, Buffer
);
1240 case BDS_EFI_MESSAGE_USB_DEVICE_BOOT
:
1241 if (UsbNumber
!= 0) {
1242 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB
)), UsbNumber
);
1244 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB
)));
1246 BdsLibBuildOptionFromHandle (BlockIoHandles
[Index
], BdsBootOptionList
, Buffer
);
1250 case BDS_EFI_MESSAGE_SCSI_BOOT
:
1251 if (ScsiNumber
!= 0) {
1252 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI
)), ScsiNumber
);
1254 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI
)));
1256 BdsLibBuildOptionFromHandle (BlockIoHandles
[Index
], BdsBootOptionList
, Buffer
);
1260 case BDS_EFI_MESSAGE_MISC_BOOT
:
1262 if (MiscNumber
!= 0) {
1263 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC
)), MiscNumber
);
1265 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC
)));
1267 BdsLibBuildOptionFromHandle (BlockIoHandles
[Index
], BdsBootOptionList
, Buffer
);
1274 if (NumberBlockIoHandles
!= 0) {
1275 FreePool (BlockIoHandles
);
1279 // If there is simple file protocol which does not consume block Io protocol, create a boot option for it here.
1282 gBS
->LocateHandleBuffer (
1284 &gEfiSimpleFileSystemProtocolGuid
,
1286 &NumberFileSystemHandles
,
1289 for (Index
= 0; Index
< NumberFileSystemHandles
; Index
++) {
1290 Status
= gBS
->HandleProtocol (
1291 FileSystemHandles
[Index
],
1292 &gEfiBlockIoProtocolGuid
,
1295 if (!EFI_ERROR (Status
)) {
1297 // Skip if the file system handle supports a BlkIo protocol,
1303 // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
1304 // machinename is ia32, ia64, x64, ...
1306 Hdr
.Union
= &HdrData
;
1308 Status
= BdsLibGetImageHeader (
1309 FileSystemHandles
[Index
],
1310 EFI_REMOVABLE_MEDIA_FILE_NAME
,
1314 if (!EFI_ERROR (Status
) &&
1315 EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr
.Pe32
->FileHeader
.Machine
) &&
1316 Hdr
.Pe32
->OptionalHeader
.Subsystem
== EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION
) {
1322 // No such file or the file is not a EFI application, delete this boot option
1324 BdsLibDeleteOptionFromHandle (FileSystemHandles
[Index
]);
1326 if (NonBlockNumber
!= 0) {
1327 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK
)), NonBlockNumber
);
1329 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK
)));
1331 BdsLibBuildOptionFromHandle (FileSystemHandles
[Index
], BdsBootOptionList
, Buffer
);
1336 if (NumberFileSystemHandles
!= 0) {
1337 FreePool (FileSystemHandles
);
1341 // Check if we have on flash shell
1343 gBS
->LocateHandleBuffer (
1345 &gEfiFirmwareVolume2ProtocolGuid
,
1350 for (Index
= 0; Index
< FvHandleCount
; Index
++) {
1351 gBS
->HandleProtocol (
1352 FvHandleBuffer
[Index
],
1353 &gEfiFirmwareVolume2ProtocolGuid
,
1357 Status
= Fv
->ReadFile (
1359 &gUefiShellFileGuid
,
1364 &AuthenticationStatus
1366 if (EFI_ERROR (Status
)) {
1368 // Skip if no shell file in the FV
1373 // Build the shell boot option
1375 BdsLibBuildOptionFromShell (FvHandleBuffer
[Index
], BdsBootOptionList
);
1378 if (FvHandleCount
!= 0) {
1379 FreePool (FvHandleBuffer
);
1383 // Parse Network Boot Device
1385 NumOfLoadFileHandles
= 0;
1387 // Search Load File protocol for PXE boot option.
1389 gBS
->LocateHandleBuffer (
1391 &gEfiLoadFileProtocolGuid
,
1393 &NumOfLoadFileHandles
,
1397 for (Index
= 0; Index
< NumOfLoadFileHandles
; Index
++) {
1400 //Locate EFI_DEVICE_PATH_PROTOCOL to dynamically get IPv4/IPv6 protocol information.
1403 Status
= gBS
->HandleProtocol (
1404 LoadFileHandles
[Index
],
1405 &gEfiDevicePathProtocolGuid
,
1406 (VOID
**) &DevicePath
1409 ASSERT_EFI_ERROR (Status
);
1411 while (!IsDevicePathEnd (DevicePath
)) {
1412 if ((DevicePath
->Type
== MESSAGING_DEVICE_PATH
) &&
1413 (DevicePath
->SubType
== MSG_IPv4_DP
)) {
1416 //Get handle infomation
1419 NetworkHandles
= NULL
;
1420 Status
= gBS
->LocateHandle (
1422 &gEfiSimpleNetworkProtocolGuid
,
1428 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1429 NetworkHandles
= AllocateZeroPool(BufferSize
);
1430 if (NetworkHandles
== NULL
) {
1431 return (EFI_OUT_OF_RESOURCES
);
1433 Status
= gBS
->LocateHandle(
1435 &gEfiSimpleNetworkProtocolGuid
,
1443 //Get the MAC string
1445 Status
= NetLibGetMacString (
1450 if (EFI_ERROR (Status
)) {
1453 IPverStr
= L
" IPv4";
1454 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s%s%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK
)),MacStr
,IPverStr
);
1457 if((DevicePath
->Type
== MESSAGING_DEVICE_PATH
) &&
1458 (DevicePath
->SubType
== MSG_IPv6_DP
)) {
1461 //Get handle infomation
1464 NetworkHandles
= NULL
;
1465 Status
= gBS
->LocateHandle (
1467 &gEfiSimpleNetworkProtocolGuid
,
1473 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1474 NetworkHandles
= AllocateZeroPool(BufferSize
);
1475 if (NetworkHandles
== NULL
) {
1476 return (EFI_OUT_OF_RESOURCES
);
1478 Status
= gBS
->LocateHandle(
1480 &gEfiSimpleNetworkProtocolGuid
,
1488 //Get the MAC string
1490 Status
= NetLibGetMacString (
1495 if (EFI_ERROR (Status
)) {
1498 IPverStr
= L
" IPv6";
1499 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%s%s%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK
)),MacStr
,IPverStr
);
1502 DevicePath
= NextDevicePathNode (DevicePath
);
1505 BdsLibBuildOptionFromHandle (LoadFileHandles
[Index
], BdsBootOptionList
, Buffer
);
1508 if (NumOfLoadFileHandles
!= 0) {
1509 FreePool (LoadFileHandles
);
1513 // Check if we have on flash shell
1515 /* gBS->LocateHandleBuffer (
1517 &gEfiFirmwareVolume2ProtocolGuid,
1522 for (Index = 0; Index < FvHandleCount; Index++) {
1523 gBS->HandleProtocol (
1524 FvHandleBuffer[Index],
1525 &gEfiFirmwareVolume2ProtocolGuid,
1529 Status = Fv->ReadFile (
1531 &gUefiShellFileGuid,
1536 &AuthenticationStatus
1538 if (EFI_ERROR (Status)) {
1540 // Skip if no shell file in the FV
1545 // Build the shell boot option
1547 BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);
1550 if (FvHandleCount != 0) {
1551 FreePool (FvHandleBuffer);
1555 // Make sure every boot only have one time
1556 // boot device enumerate
1558 Status
= BdsLibBuildOptionFromVar (BdsBootOptionList
, L
"BootOrder");
1559 mEnumBootDevice
= TRUE
;
1568 The function will execute with as the platform policy, current policy
1569 is driven by boot mode. IBV/OEM can customize this code for their specific
1572 @param DriverOptionList - The header of the driver option link list
1573 @param BootOptionList - The header of the boot option link list
1574 @param ProcessCapsules - A pointer to ProcessCapsules()
1575 @param BaseMemoryTest - A pointer to BaseMemoryTest()
1582 PlatformBdsPolicyBehavior (
1583 IN OUT LIST_ENTRY
*DriverOptionList
,
1584 IN OUT LIST_ENTRY
*BootOptionList
,
1585 IN PROCESS_CAPSULES BdsProcessCapsules
,
1586 IN BASEM_MEMORY_TEST BaseMemoryTest
1591 EFI_BOOT_MODE BootMode
;
1592 BOOLEAN DeferredImageExist
;
1594 SYSTEM_CONFIGURATION SystemConfiguration
;
1596 PLATFORM_PCI_DEVICE_PATH
*EmmcBootDevPath
;
1597 EFI_GLOBAL_NVS_AREA_PROTOCOL
*GlobalNvsArea
;
1598 EFI_HANDLE FvProtocolHandle
;
1600 EFI_HANDLE
*HandleBuffer
;
1602 UINTN SataPciRegBase
= 0;
1603 UINT16 SataModeSelect
= 0;
1604 VOID
*RegistrationExitPmAuth
= NULL
;
1606 BOOLEAN IsFirstBoot
;
1608 UINTN BootOrderSize
;
1609 ESRT_MANAGEMENT_PROTOCOL
*EsrtManagement
;
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 // No deferred images exist by default
1652 DeferredImageExist
= FALSE
;
1653 if ((BootMode
!= BOOT_WITH_MINIMAL_CONFIGURATION
) && (PcdGet32(PcdFlashFvShellSize
) > 0)){
1654 gDS
->ProcessFirmwareVolume (
1655 (VOID
*)(UINTN
)PcdGet32(PcdFlashFvShellBase
),
1656 PcdGet32(PcdFlashFvShellSize
),
1661 if (SystemConfiguration
.FastBoot
== 1) {
1662 BootOrder
= BdsLibGetVariableAndSize (
1664 &gEfiGlobalVariableGuid
,
1667 if ((BootOrder
!= NULL
) && (BootMode
!= BOOT_ON_FLASH_UPDATE
)) {
1669 // BootOrder exist, it means system has boot before. We can do fast boot.
1671 BootMode
= BOOT_WITH_MINIMAL_CONFIGURATION
;
1677 // Use eMMC to boot OS and turn on AHCI, when SATA HDD is diconnected,
1678 // SATA AHCI CTLR device will show yellow bang, implement this solution to solve it.
1680 SataPciRegBase
= MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA
, 0, 0);
1681 SataModeSelect
= MmioRead16 (SataPciRegBase
+ R_PCH_SATA_MAP
) & B_PCH_SATA_MAP_SMS_MASK
;
1682 Status
= EFI_SUCCESS
;
1683 if (SataModeSelect
!= V_PCH_SATA_MAP_SMS_IDE
) {
1684 Status
= gBS
->CreateEvent (
1691 if (!EFI_ERROR (Status
)) {
1692 Status
= gBS
->RegisterProtocolNotify (
1693 &gExitPmAuthProtocolGuid
,
1695 &RegistrationExitPmAuth
1700 Status
= gBS
->LocateProtocol(&gEsrtManagementProtocolGuid
, NULL
, (VOID
**)&EsrtManagement
);
1701 if (EFI_ERROR(Status
)) {
1702 EsrtManagement
= NULL
;
1705 DEBUG ((DEBUG_INFO
, "BDS: BootMode=%02x\n", BootMode
));
1709 case BOOT_WITH_MINIMAL_CONFIGURATION
:
1710 PlatformBdsInitHotKeyEvent ();
1711 PlatformBdsConnectSimpleConsole (gPlatformSimpleConsole
);
1715 // Check to see if it's needed to dispatch more DXE drivers.
1717 for (Index
= 0; Index
< sizeof(ConnectDriverTable
)/sizeof(EFI_GUID
*); Index
++) {
1718 Status
= gBS
->LocateHandleBuffer (
1720 ConnectDriverTable
[Index
],
1725 if (!EFI_ERROR (Status
)) {
1726 for (Index1
= 0; Index1
< HandleCount
; Index1
++) {
1727 gBS
->ConnectController (
1728 HandleBuffer
[Index1
],
1736 if (HandleBuffer
!= NULL
) {
1737 FreePool (HandleBuffer
);
1744 // Locate the Global NVS Protocol.
1746 Status
= gBS
->LocateProtocol (
1747 &gEfiGlobalNvsAreaProtocolGuid
,
1749 (void **)&GlobalNvsArea
1751 if (GlobalNvsArea
->Area
->emmcVersion
== 0){
1752 EmmcBootDevPath
= (PLATFORM_PCI_DEVICE_PATH
*)gPlatformSimpleBootOption
[0];
1753 EmmcBootDevPath
->PciDevice
.Device
= 0x10;
1757 // Connect boot device here to give time to read keyboard.
1759 BdsLibConnectDevicePath (gPlatformSimpleBootOption
[0]);
1762 // This is a workround for dectecting hotkey from USB keyboard.
1764 gBS
->Stall(KEYBOARD_TIMER_INTERVAL
);
1766 if (mHotKeyTimerEvent
!= NULL
) {
1772 gBS
->CloseEvent (mHotKeyTimerEvent
);
1773 mHotKeyTimerEvent
= NULL
;
1775 if (mHotKeyPressed
) {
1777 // Skip show progress count down
1780 goto FULL_CONFIGURATION
;
1783 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
1784 if (!SystemConfiguration
.QuietBoot
) {
1785 PlatformBdsDiagnostics (IGNORE
, FALSE
, BaseMemoryTest
);
1790 TcgPhysicalPresenceLibProcessRequest();
1793 Tcg2PhysicalPresenceLibProcessRequest(NULL
);
1796 if (EsrtManagement
!= NULL
) {
1797 EsrtManagement
->LockEsrtRepository();
1801 // Close boot script and install ready to lock
1803 InstallReadyToLock ();
1806 // Give one chance to enter the setup if we
1807 // select Gummiboot "Reboot Into Firmware Interface" and Fast Boot is enabled.
1809 BootIntoFirmwareInterface();
1812 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES
:
1815 // In no-configuration boot mode, we can connect the
1816 // console directly.
1818 BdsLibConnectAllDefaultConsoles ();
1819 PlatformBdsDiagnostics (IGNORE
, TRUE
, BaseMemoryTest
);
1822 // Perform some platform specific connect sequence
1824 PlatformBdsConnectSequence ();
1827 // As console is ready, perform user identification again.
1829 if (mCurrentUser
== NULL
) {
1830 PlatformBdsUserIdentify (&mCurrentUser
, &DeferredImageExist
);
1831 if (DeferredImageExist
) {
1833 // After user authentication, the deferred drivers was loaded again.
1834 // Here, need to ensure the deferred images are connected.
1836 BdsLibConnectAllDefaultConsoles ();
1837 PlatformBdsConnectSequence ();
1841 if (EsrtManagement
!= NULL
) {
1842 EsrtManagement
->LockEsrtRepository();
1846 // Close boot script and install ready to lock
1848 InstallReadyToLock ();
1851 // Notes: current time out = 0 can not enter the
1854 PlatformBdsEnterFrontPageWithHotKey (Timeout
, FALSE
);
1857 // Check the boot option with the boot option list
1859 BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
1862 case BOOT_ON_FLASH_UPDATE
:
1865 // Boot with the specific configuration
1867 PlatformBdsConnectConsole (gPlatformConsole
);
1868 PlatformBdsDiagnostics (EXTENSIVE
, TRUE
, BaseMemoryTest
);
1870 DEBUG((DEBUG_INFO
, "ProcessCapsules Before EndOfDxe......\n"));
1872 DEBUG((DEBUG_INFO
, "ProcessCapsules Done\n"));
1875 // Close boot script and install ready to lock
1877 InstallReadyToLock ();
1879 BdsLibConnectAll ();
1882 // Perform user identification
1884 if (mCurrentUser
== NULL
) {
1885 PlatformBdsUserIdentify (&mCurrentUser
, &DeferredImageExist
);
1886 if (DeferredImageExist
) {
1888 // After user authentication, the deferred drivers was loaded again.
1889 // Here, need to ensure the deferred images are connected.
1891 BdsLibConnectAll ();
1895 if (EsrtManagement
!= NULL
) {
1896 EsrtManagement
->SyncEsrtFmp();
1899 DEBUG((DEBUG_INFO
, "ProcessCapsules After ConnectAll......\n"));
1901 DEBUG((DEBUG_INFO
, "ProcessCapsules Done\n"));
1904 case BOOT_IN_RECOVERY_MODE
:
1907 // In recovery mode, just connect platform console
1908 // and show up the front page
1910 PlatformBdsConnectConsole (gPlatformConsole
);
1911 PlatformBdsDiagnostics (EXTENSIVE
, FALSE
, BaseMemoryTest
);
1912 BdsLibConnectAll ();
1915 // Perform user identification
1917 if (mCurrentUser
== NULL
) {
1918 PlatformBdsUserIdentify (&mCurrentUser
, &DeferredImageExist
);
1919 if (DeferredImageExist
) {
1921 // After user authentication, the deferred drivers was loaded again.
1922 // Here, need to ensure the deferred drivers are connected.
1924 BdsLibConnectAll ();
1929 // Close boot script and install ready to lock
1931 InstallReadyToLock ();
1934 // In recovery boot mode, we still enter to the
1937 PlatformBdsEnterFrontPageWithHotKey (Timeout
, FALSE
);
1941 case BOOT_WITH_FULL_CONFIGURATION
:
1942 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS
:
1943 case BOOT_WITH_DEFAULT_SETTINGS
:
1947 // Connect platform console
1949 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
1950 if (EFI_ERROR (Status
)) {
1953 // Here OEM/IBV can customize with defined action
1955 PlatformBdsNoConsoleAction ();
1959 // Chenyunh[TODO]: This is Workgroud to show the fs for uSDcard,
1960 // Need to root cause this issue.
1962 DEBUG ((DEBUG_ERROR
, "Start to reconnect all driver.\n"));
1963 BdsLibDisconnectAllEfi();
1964 BdsLibConnectAll ();
1965 DEBUG ((DEBUG_ERROR
, "End to reconnect all driver.\n"));
1968 // Perform some platform specific connect sequence
1970 PlatformBdsConnectSequence ();
1971 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
1972 if (!SystemConfiguration
.QuietBoot
) {
1973 PlatformBdsDiagnostics (IGNORE
, FALSE
, BaseMemoryTest
);
1977 // Do a pre-delay so Hard Disk can spin up and see more logo.
1979 gBS
->Stall(SystemConfiguration
.HddPredelay
* 1000000);
1982 // Perform user identification
1984 if (mCurrentUser
== NULL
) {
1985 PlatformBdsUserIdentify (&mCurrentUser
, &DeferredImageExist
);
1986 if (DeferredImageExist
) {
1988 // After user authentication, the deferred drivers was loaded again.
1989 // Here, need to ensure the deferred drivers are connected.
1991 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
1992 if (EFI_ERROR (Status
)) {
1993 PlatformBdsNoConsoleAction ();
1995 PlatformBdsConnectSequence ();
1999 TcgPhysicalPresenceLibProcessRequest();
2002 Tcg2PhysicalPresenceLibProcessRequest(NULL
);
2005 if (EsrtManagement
!= NULL
) {
2006 EsrtManagement
->SyncEsrtFmp();
2009 // Close boot script and install ready to lock
2011 InstallReadyToLock ();
2014 // Here we have enough time to do the enumeration of boot device
2016 PlatformBdsLibEnumerateAllBootOption (BootOptionList
);
2019 // Give one chance to enter the setup if we
2020 // have the time out
2022 PlatformBdsEnterFrontPageWithHotKey (Timeout
, FALSE
);
2025 // Give one chance to enter the setup if we
2026 // select Gummiboot "Reboot Into Firmware Interface"
2028 BootIntoFirmwareInterface();
2031 // In default boot mode, always find all boot
2032 // option and do enumerate all the default boot option
2035 BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
2036 if (IsListEmpty(BootOptionList
)) {
2037 PlatformBdsPredictBootOption (BootOptionList
);
2048 IsFirstBoot
= PcdGetBool(PcdBootState
);
2050 PcdSetBool(PcdBootState
, FALSE
);
2057 Hook point after a boot attempt succeeds. We don't expect a boot option to
2058 return, so the UEFI 2.0 specification defines that you will default to an
2059 interactive mode and stop processing the BootOrder list in this case. This
2060 is alos a platform implementation and can be customized by IBV/OEM.
2062 @param Option Pointer to Boot Option that succeeded to boot.
2069 PlatformBdsBootSuccess (
2070 IN BDS_COMMON_OPTION
*Option
2076 // If Boot returned with EFI_SUCCESS and there is not in the boot device
2077 // select loop then we need to pop up a UI and wait for user input.
2079 TmpStr
= Option
->StatusString
;
2080 if (TmpStr
!= NULL
) {
2081 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
2087 Hook point after a boot attempt fails.
2089 @param Option - Pointer to Boot Option that failed to boot.
2090 @param Status - Status returned from failed boot.
2091 @param ExitData - Exit data returned from failed boot.
2092 @param ExitDataSize - Exit data size returned from failed boot.
2099 PlatformBdsBootFail (
2100 IN BDS_COMMON_OPTION
*Option
,
2101 IN EFI_STATUS Status
,
2102 IN CHAR16
*ExitData
,
2103 IN UINTN ExitDataSize
2107 EFI_HANDLE FvProtocolHandle
;
2110 // If Boot returned with failed status then we need to pop up a UI and wait
2113 TmpStr
= Option
->StatusString
;
2114 if (TmpStr
!= NULL
) {
2115 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
2118 if (PcdGet32(PcdFlashFvShellSize
) > 0){
2119 gDS
->ProcessFirmwareVolume (
2120 (VOID
*)(UINTN
)PcdGet32(PcdFlashFvShellBase
),
2121 PcdGet32(PcdFlashFvShellSize
),
2125 PlatformBdsConnectSequence ();
2129 This function is remained for IBV/OEM to do some platform action,
2130 if there no console device can be connected.
2134 @retval EFI_SUCCESS Direct return success now.
2138 PlatformBdsNoConsoleAction (
2146 This function locks the block
2148 @param Base The base address flash region to be locked.
2153 IN EFI_PHYSICAL_ADDRESS Base
2156 EFI_FV_BLOCK_MAP_ENTRY
*BlockMap
;
2157 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
2158 EFI_PHYSICAL_ADDRESS BaseAddress
;
2162 BaseAddress
= Base
- 0x400000 + 2;
2163 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINTN
) (Base
));
2164 BlockMap
= &(FvHeader
->BlockMap
[0]);
2166 while ((BlockMap
->NumBlocks
!= 0) && (BlockMap
->Length
!= 0)) {
2167 BlockLength
= BlockMap
->Length
;
2168 for (Index
= 0; Index
< BlockMap
->NumBlocks
; Index
++) {
2169 MmioOr8 ((UINTN
) BaseAddress
, 0x03);
2170 BaseAddress
+= BlockLength
;
2178 PlatformBdsLockNonUpdatableFlash (
2182 EFI_PHYSICAL_ADDRESS Base
;
2184 Base
= (EFI_PHYSICAL_ADDRESS
) PcdGet32 (PcdFlashFvMainBase
);
2189 Base
= (EFI_PHYSICAL_ADDRESS
) PcdGet32 (PcdFlashFvRecoveryBase
);
2196 Lock the ConsoleIn device in system table. All key
2197 presses will be ignored until the Password is typed in. The only way to
2198 disable the password is to type it in to a ConIn device.
2200 @param Password Password used to lock ConIn device.
2202 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
2203 @retval EFI_UNSUPPORTED Password not found
2212 return EFI_UNSUPPORTED
;
2216 Connect the predefined platform default authentication devices.
2218 This function connects the predefined device path for authentication device,
2219 and if the predefined device path has child device path, the child handle will
2220 be connected too. But the child handle of the child will not be connected.
2225 PlatformBdsConnectAuthDevice (
2233 EFI_HANDLE
*HandleBuffer
;
2234 EFI_DEVICE_PATH_PROTOCOL
*ChildDevicePath
;
2235 EFI_USER_MANAGER_PROTOCOL
*Manager
;
2237 Status
= gBS
->LocateProtocol (
2238 &gEfiUserManagerProtocolGuid
,
2242 if (EFI_ERROR (Status
)) {
2244 // As user manager protocol is not installed, the authentication devices
2245 // should not be connected.
2251 while (gUserAuthenticationDevice
[Index
] != NULL
) {
2253 // Connect the platform customized device paths
2255 BdsLibConnectDevicePath (gUserAuthenticationDevice
[Index
]);
2260 // Find and connect the child device paths of the platform customized device paths
2262 HandleBuffer
= NULL
;
2263 for (Index
= 0; gUserAuthenticationDevice
[Index
] != NULL
; Index
++) {
2265 Status
= gBS
->LocateHandleBuffer (
2272 ASSERT (!EFI_ERROR (Status
));
2275 // Find and connect the child device paths of gUserIdentificationDevice[Index]
2277 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
2278 ChildDevicePath
= NULL
;
2279 Status
= gBS
->HandleProtocol (
2280 HandleBuffer
[HandleIndex
],
2281 &gEfiDevicePathProtocolGuid
,
2282 (VOID
**) &ChildDevicePath
2284 if (EFI_ERROR (Status
) || ChildDevicePath
== NULL
) {
2290 gUserAuthenticationDevice
[Index
],
2291 (GetDevicePathSize (gUserAuthenticationDevice
[Index
]) - sizeof (EFI_DEVICE_PATH_PROTOCOL
))
2295 gBS
->ConnectController (
2296 HandleBuffer
[HandleIndex
],
2304 if (HandleBuffer
!= NULL
) {
2305 FreePool (HandleBuffer
);
2310 This function is to identify a user, and return whether deferred images exist.
2312 @param[out] User Point to user profile handle.
2313 @param[out] DeferredImageExist On return, points to TRUE if the deferred image
2314 exist or FALSE if it did not exist.
2319 PlatformBdsUserIdentify (
2320 OUT EFI_USER_PROFILE_HANDLE
*User
,
2321 OUT BOOLEAN
*DeferredImageExist
2325 EFI_DEFERRED_IMAGE_LOAD_PROTOCOL
*DeferredImage
;
2327 EFI_HANDLE
*HandleBuf
;
2330 EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
;
2336 // Perform user identification
2339 Status
= BdsLibUserIdentify (User
);
2340 } while (EFI_ERROR (Status
));
2343 // After user authentication now, try to find whether deferred image exists
2347 *DeferredImageExist
= FALSE
;
2348 Status
= gBS
->LocateHandleBuffer (
2350 &gEfiDeferredImageLoadProtocolGuid
,
2355 if (EFI_ERROR (Status
)) {
2359 for (Index
= 0; Index
< HandleCount
; Index
++) {
2360 Status
= gBS
->HandleProtocol (
2362 &gEfiDeferredImageLoadProtocolGuid
,
2363 (VOID
**) &DeferredImage
2365 if (!EFI_ERROR (Status
)) {
2367 // Find whether deferred image exists in this instance.
2370 Status
= DeferredImage
->GetImageInfo(
2374 (VOID
**) &DriverImage
,
2378 if (!EFI_ERROR (Status
)) {
2380 // The deferred image is found.
2382 FreePool (HandleBuf
);
2383 *DeferredImageExist
= TRUE
;
2389 FreePool (HandleBuf
);
2396 ShowProgressHotKey (
2397 IN UINT16 TimeoutDefault
2401 UINT16 TimeoutRemain
;
2404 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
2405 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
2406 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
2415 if (TimeoutDefault
== 0) {
2419 gST
->ConOut
->SetAttribute(gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
2421 if (DebugAssertEnabled())
2423 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"));
2428 SerialPortWrite((UINT8
*)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)[GCC]", 76);
2430 SerialPortWrite((UINT8
*)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)", 71);
2433 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
2434 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
2435 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
2441 // Check if the platform is using test key.
2443 Status
= GetSectionFromAnyFv(
2444 PcdGetPtr(PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid
),
2450 if (!EFI_ERROR(Status
)) {
2451 if ((Size
== PcdGetSize(PcdRsa2048Sha256PublicKeyBuffer
)) &&
2452 (CompareMem(Buffer
, PcdGetPtr(PcdRsa2048Sha256PublicKeyBuffer
), Size
) == 0)) {
2453 TmpStr2
= L
"WARNING: Recovery Test Key is used.\r\n";
2454 if (DebugAssertEnabled()) {
2455 DEBUG ((DEBUG_INFO
, "\n\nWARNING: Recovery Test Key is used.\n"));
2457 SerialPortWrite((UINT8
*)"\n\nWARNING: Recovery Test Key is used.", sizeof("\n\nWARNING: Recovery Test Key is used."));
2459 PcdSetBoolS(PcdTestKeyUsed
, TRUE
);
2463 Status
= GetSectionFromAnyFv(
2464 PcdGetPtr(PcdEdkiiPkcs7TestPublicKeyFileGuid
),
2470 if (!EFI_ERROR(Status
)) {
2471 if ((Size
== PcdGetSize(PcdPkcs7CertBuffer
)) &&
2472 (CompareMem(Buffer
, PcdGetPtr(PcdPkcs7CertBuffer
), Size
) == 0)) {
2473 TmpStr3
= L
"WARNING: Capsule Test Key is used.\r\n";
2474 if (DebugAssertEnabled()) {
2475 DEBUG ((DEBUG_INFO
, "\n\nWARNING: Capsule Test Key is used.\r\n"));
2477 SerialPortWrite((UINT8
*)"\n\nWARNING: Capsule Test Key is used.", sizeof("\n\nWARNING: Capsule Test Key is used."));
2479 PcdSetBoolS(PcdTestKeyUsed
, TRUE
);
2485 // Clear the progress status bar first
2487 TmpStr1
= L
"Start boot option, Press <F2> or <DEL> to enter setup page.\r\n";
2488 TmpStrSize
= StrSize(TmpStr1
);
2489 if (TmpStr2
!= NULL
) {
2490 TmpStrSize
+= StrSize(TmpStr2
);
2492 if (TmpStr3
!= NULL
) {
2493 TmpStrSize
+= StrSize(TmpStr3
);
2495 TmpStr
= AllocatePool (TmpStrSize
);
2496 if (TmpStr
== NULL
) {
2499 StrCpyS(TmpStr
, TmpStrSize
/sizeof(CHAR16
), TmpStr1
);
2500 if (TmpStr2
!= NULL
) {
2501 StrCatS(TmpStr
, TmpStrSize
/sizeof(CHAR16
), TmpStr2
);
2503 if (TmpStr3
!= NULL
) {
2504 StrCatS(TmpStr
, TmpStrSize
/sizeof(CHAR16
), TmpStr3
);
2507 PlatformBdsShowProgress (Foreground
, Background
, TmpStr
, Color
, 0, 0);
2509 TimeoutRemain
= TimeoutDefault
;
2510 while (TimeoutRemain
!= 0) {
2511 if (DebugAssertEnabled())
2513 DEBUG ((EFI_D_INFO
, "Showing progress bar...Remaining %d second!\n", TimeoutRemain
));
2517 SerialPortWrite ((UINT8
*)".", 1);
2519 Status
= WaitForSingleEvent (gST
->ConIn
->WaitForKey
, ONE_SECOND
);
2520 if (Status
!= EFI_TIMEOUT
) {
2528 if (TmpStr
!= NULL
) {
2529 PlatformBdsShowProgress (
2534 ((TimeoutDefault
- TimeoutRemain
) * 100 / TimeoutDefault
),
2543 if (TimeoutRemain
== 0) {
2544 if (DebugAssertEnabled())
2549 SerialPortWrite ((UINT8
*)"\r\n", 2);
2555 // User pressed some key
2557 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
2558 if (EFI_ERROR (Status
)) {
2563 // Check Volume Up Key to enter Setup
2565 GpioValue
= MmioRead32 (IO_BASE_ADDRESS
+ 0x0668); // The value of GPIOC_5
2566 if (((GpioValue
& BIT0
) == 0) && (Key
.ScanCode
== SCAN_UP
)) {
2571 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
2573 // User pressed enter, equivalent to select "continue"
2580 //F5 -- Device Manager
2581 //F7 -- Boot Manager
2582 // do not use F8. generally people assume it is windows safe mode key.
2585 DEBUG ((EFI_D_INFO
, "[Key Pressed]: ScanCode 0x%x\n", Key
.ScanCode
));
2586 switch(Key
.ScanCode
) {
2596 gHotKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
2600 gHotKey
= FRONT_PAGE_KEY_BOOT_MANAGER
;
2604 gHotKey
= FRONT_PAGE_KEY_BOOT_MAINTAIN
;
2608 //set gHotKey to continue so that flow will not go into CallFrontPage
2609 gHotKey
= FRONT_PAGE_KEY_CONTINUE
;
2620 This function is the main entry of the platform setup entry.
2621 The function will present the main menu of the system setup,
2622 this is the platform reference part and can be customize.
2625 @param TimeoutDefault The fault time out value before the system
2627 @param ConnectAllHappened The indicater to check if the connect all have
2632 PlatformBdsEnterFrontPageWithHotKey (
2633 IN UINT16 TimeoutDefault
,
2634 IN BOOLEAN ConnectAllHappened
2639 EFI_STATUS LogoStatus
;
2640 EFI_BOOT_LOGO_PROTOCOL
*BootLogo
;
2641 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
2642 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOut
;
2643 UINTN BootTextColumn
;
2646 GraphicsOutput
= NULL
;
2647 SimpleTextOut
= NULL
;
2649 PERF_START (NULL
, "BdsTimeOut", "BDS", 0);
2652 // Indicate if we need connect all in the platform setup
2654 if (ConnectAllHappened
) {
2655 gConnectAllHappened
= TRUE
;
2658 if (!mModeInitialized
) {
2660 // After the console is ready, get current video resolution
2661 // and text mode before launching setup at first time.
2663 Status
= gBS
->HandleProtocol (
2664 gST
->ConsoleOutHandle
,
2665 &gEfiGraphicsOutputProtocolGuid
,
2666 (VOID
**)&GraphicsOutput
2668 if (EFI_ERROR (Status
)) {
2669 GraphicsOutput
= NULL
;
2672 Status
= gBS
->HandleProtocol (
2673 gST
->ConsoleOutHandle
,
2674 &gEfiSimpleTextOutProtocolGuid
,
2675 (VOID
**)&SimpleTextOut
2677 if (EFI_ERROR (Status
)) {
2678 SimpleTextOut
= NULL
;
2681 if (GraphicsOutput
!= NULL
) {
2683 // Get current video resolution and text mode.
2685 mBootHorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
2686 mBootVerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
2689 if (SimpleTextOut
!= NULL
) {
2690 Status
= SimpleTextOut
->QueryMode (
2692 SimpleTextOut
->Mode
->Mode
,
2696 mBootTextModeColumn
= (UINT32
)BootTextColumn
;
2697 mBootTextModeRow
= (UINT32
)BootTextRow
;
2701 // Get user defined text mode for setup.
2703 mSetupHorizontalResolution
= PcdGet32 (PcdSetupVideoHorizontalResolution
);
2704 mSetupVerticalResolution
= PcdGet32 (PcdSetupVideoVerticalResolution
);
2705 mSetupTextModeColumn
= PcdGet32 (PcdSetupConOutColumn
);
2706 mSetupTextModeRow
= PcdGet32 (PcdSetupConOutRow
);
2708 mModeInitialized
= TRUE
;
2711 if (TimeoutDefault
!= 0xffff) {
2712 Status
= ShowProgressHotKey (TimeoutDefault
);
2715 // Ensure screen is clear when switch Console from Graphics mode to Text mode
2717 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);
2718 gST
->ConOut
->ClearScreen (gST
->ConOut
);
2721 // Boot Logo is corrupted, report it using Boot Logo protocol.
2723 LogoStatus
= gBS
->LocateProtocol (&gEfiBootLogoProtocolGuid
, NULL
, (VOID
**) &BootLogo
);
2724 if (!EFI_ERROR (LogoStatus
) && (BootLogo
!= NULL
)) {
2725 BootLogo
->SetBootLogo (BootLogo
, NULL
, 0, 0, 0, 0);
2728 if (EFI_ERROR (Status
)) {
2730 // Timeout or user press enter to continue
2737 // Install BM HiiPackages.
2738 // Keep BootMaint HiiPackage, so that it can be covered by global setting.
2743 BdsSetConsoleMode (TRUE
);
2745 InitializeFrontPage (FALSE
);
2748 // Update Front Page strings
2750 UpdateFrontPageStrings ();
2752 Status
= EFI_SUCCESS
;
2755 Status
= CallFrontPage ();
2757 gCallbackKey
= gHotKey
;
2762 // If gCallbackKey is greater than 1 and less or equal to 5,
2763 // it will launch configuration utilities.
2766 // 4 = device manager
2767 // 5 = boot maintenance manager
2769 if (gCallbackKey
!= 0) {
2770 REPORT_STATUS_CODE (
2772 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_USER_SETUP
)
2777 // Based on the key that was set, we can determine what to do
2779 switch (gCallbackKey
) {
2781 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
2782 // describe to their customers in documentation how to find their setup information (namely
2783 // under the device manager and specific buckets)
2785 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
2787 case FRONT_PAGE_KEY_CONTINUE
:
2790 // User hit continue
2794 case FRONT_PAGE_KEY_LANGUAGE
:
2797 // User made a language setting change - display front page again
2801 case FRONT_PAGE_KEY_BOOT_MANAGER
:
2803 // Remove the installed BootMaint HiiPackages when exit.
2808 // User chose to run the Boot Manager
2813 // Reinstall BootMaint HiiPackages after exiting from Boot Manager.
2818 case FRONT_PAGE_KEY_DEVICE_MANAGER
:
2821 // Display the Device Manager
2824 CallDeviceManager ();
2825 } while (gCallbackKey
== FRONT_PAGE_KEY_DEVICE_MANAGER
);
2828 case FRONT_PAGE_KEY_BOOT_MAINTAIN
:
2831 // Display the Boot Maintenance Manager
2833 BdsStartBootMaint ();
2837 } while (((UINTN
)gCallbackKey
) != FRONT_PAGE_KEY_CONTINUE
);
2840 //Will leave browser, check any reset required change is applied? if yes, reset system
2842 SetupResetReminder ();
2844 // Remove the installed BootMaint HiiPackages when exit.
2850 // Automatically load current entry
2851 // Note: The following lines of code only execute when Auto boot
2854 PERF_END (NULL
, "BdsTimeOut", "BDS", 0);
2859 BootIntoFirmwareInterface(
2866 UINT64 OsIndication
;
2870 DataSize
= sizeof(UINT64
);
2871 Status
= gRT
->GetVariable (
2873 &gEfiGlobalVariableGuid
,
2879 DEBUG ((EFI_D_INFO
, "OSIndication Variable Value %d\n", OsIndication
));
2881 //Goto FrontPage directly when bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted.
2883 if (!EFI_ERROR(Status
) && (OsIndication
!= 0)) {
2885 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
2891 PlatformBdsConnectSimpleConsole (
2892 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
2897 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
2898 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
2899 UINTN DevicePathSize
;
2903 Status
= EFI_SUCCESS
;
2905 VarConout
= BdsLibGetVariableAndSize (
2907 &gEfiGlobalVariableGuid
,
2910 VarConin
= BdsLibGetVariableAndSize (
2912 &gEfiGlobalVariableGuid
,
2915 if (VarConout
== NULL
|| VarConin
== NULL
) {
2917 // Have chance to connect the platform default console,
2918 // the platform default console is the minimum device group
2919 // the platform should support
2921 while (PlatformConsole
[Index
].DevicePath
!= NULL
) {
2924 // Update the console variable with the connect type
2926 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
2927 BdsLibUpdateConsoleVariable (L
"ConIn", PlatformConsole
[Index
].DevicePath
, NULL
);
2930 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
2931 BdsLibUpdateConsoleVariable (L
"ConOut", PlatformConsole
[Index
].DevicePath
, NULL
);
2934 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
2935 BdsLibUpdateConsoleVariable (L
"ErrOut", PlatformConsole
[Index
].DevicePath
, NULL
);
2943 // Connect ConIn first to give keyboard time to parse hot key event.
2945 Status
= BdsLibConnectConsoleVariable (L
"ConIn");
2946 if (EFI_ERROR (Status
)) {
2951 // Make sure we have at least one active VGA, and have the right
2952 // active VGA in console variable
2954 Status
= PlatformBdsForceActiveVga ();
2957 // It seems impossible not to have any ConOut device on platform,
2958 // so we check the status here.
2960 Status
= BdsLibConnectConsoleVariable (L
"ConOut");
2961 if (EFI_ERROR (Status
)) {
2970 Timer handler to convert the key from USB.
2972 @param Event Indicates the event that invoke this function.
2973 @param Context Indicates the calling context.
2977 HotKeyTimerHandler (
2985 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
2986 if (EFI_ERROR (Status
)) {
2990 switch(Key
.ScanCode
) {
2993 mHotKeyPressed
= TRUE
;
2997 gHotKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
2998 mHotKeyPressed
= TRUE
;
3002 gHotKey
= FRONT_PAGE_KEY_BOOT_MANAGER
;
3003 mHotKeyPressed
= TRUE
;
3007 gHotKey
= FRONT_PAGE_KEY_BOOT_MAINTAIN
;
3008 mHotKeyPressed
= TRUE
;
3012 if (mHotKeyPressed
) {
3018 gBS
->CloseEvent (mHotKeyTimerEvent
);
3019 mHotKeyTimerEvent
= NULL
;
3027 Callback function for SimpleTextInEx protocol install events
3029 @param Event the event that is signaled.
3030 @param Context not used here.
3042 Status
= gBS
->CloseEvent(mHitHotkeyEvent
);
3043 if (EFI_ERROR (Status
)) {
3046 Status
= gBS
->CreateEvent (
3047 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
3053 if (EFI_ERROR (Status
)) {
3056 Status
= gBS
->SetTimer (
3059 KEYBOARD_TIMER_INTERVAL
3061 if (EFI_ERROR (Status
)) {
3071 PlatformBdsInitHotKeyEvent (
3078 // Register Protocol notify for Hotkey service
3080 Status
= gBS
->CreateEvent (
3087 ASSERT_EFI_ERROR (Status
);
3090 // Register for protocol notifications on this event
3092 Status
= gBS
->RegisterProtocolNotify (
3093 &gEfiSimpleTextInputExProtocolGuid
,
3095 &mHitHotkeyRegistration
3097 ASSERT_EFI_ERROR (Status
);