3 Copyright (c) 2004 - 2018, 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
;
1707 case BOOT_WITH_MINIMAL_CONFIGURATION
:
1708 PlatformBdsInitHotKeyEvent ();
1709 PlatformBdsConnectSimpleConsole (gPlatformSimpleConsole
);
1713 // Check to see if it's needed to dispatch more DXE drivers.
1715 for (Index
= 0; Index
< sizeof(ConnectDriverTable
)/sizeof(EFI_GUID
*); Index
++) {
1716 Status
= gBS
->LocateHandleBuffer (
1718 ConnectDriverTable
[Index
],
1723 if (!EFI_ERROR (Status
)) {
1724 for (Index1
= 0; Index1
< HandleCount
; Index1
++) {
1725 gBS
->ConnectController (
1726 HandleBuffer
[Index1
],
1734 if (HandleBuffer
!= NULL
) {
1735 FreePool (HandleBuffer
);
1742 // Locate the Global NVS Protocol.
1744 Status
= gBS
->LocateProtocol (
1745 &gEfiGlobalNvsAreaProtocolGuid
,
1747 (void **)&GlobalNvsArea
1749 if (GlobalNvsArea
->Area
->emmcVersion
== 0){
1750 EmmcBootDevPath
= (PLATFORM_PCI_DEVICE_PATH
*)gPlatformSimpleBootOption
[0];
1751 EmmcBootDevPath
->PciDevice
.Device
= 0x10;
1755 // Connect boot device here to give time to read keyboard.
1757 BdsLibConnectDevicePath (gPlatformSimpleBootOption
[0]);
1760 // This is a workround for dectecting hotkey from USB keyboard.
1762 gBS
->Stall(KEYBOARD_TIMER_INTERVAL
);
1764 if (mHotKeyTimerEvent
!= NULL
) {
1770 gBS
->CloseEvent (mHotKeyTimerEvent
);
1771 mHotKeyTimerEvent
= NULL
;
1773 if (mHotKeyPressed
) {
1775 // Skip show progress count down
1778 goto FULL_CONFIGURATION
;
1781 if (SystemConfiguration
.QuietBoot
) {
1782 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
1784 PlatformBdsDiagnostics (IGNORE
, FALSE
, BaseMemoryTest
);
1789 TcgPhysicalPresenceLibProcessRequest();
1792 Tcg2PhysicalPresenceLibProcessRequest(NULL
);
1795 if (EsrtManagement
!= NULL
) {
1796 EsrtManagement
->LockEsrtRepository();
1800 // Close boot script and install ready to lock
1802 InstallReadyToLock ();
1805 // Give one chance to enter the setup if we
1806 // select Gummiboot "Reboot Into Firmware Interface" and Fast Boot is enabled.
1808 BootIntoFirmwareInterface();
1811 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES
:
1814 // In no-configuration boot mode, we can connect the
1815 // console directly.
1817 BdsLibConnectAllDefaultConsoles ();
1818 PlatformBdsDiagnostics (IGNORE
, TRUE
, BaseMemoryTest
);
1821 // Perform some platform specific connect sequence
1823 PlatformBdsConnectSequence ();
1826 // As console is ready, perform user identification again.
1828 if (mCurrentUser
== NULL
) {
1829 PlatformBdsUserIdentify (&mCurrentUser
, &DeferredImageExist
);
1830 if (DeferredImageExist
) {
1832 // After user authentication, the deferred drivers was loaded again.
1833 // Here, need to ensure the deferred images are connected.
1835 BdsLibConnectAllDefaultConsoles ();
1836 PlatformBdsConnectSequence ();
1840 if (EsrtManagement
!= NULL
) {
1841 EsrtManagement
->LockEsrtRepository();
1845 // Close boot script and install ready to lock
1847 InstallReadyToLock ();
1850 // Notes: current time out = 0 can not enter the
1853 PlatformBdsEnterFrontPageWithHotKey (Timeout
, FALSE
);
1856 // Check the boot option with the boot option list
1858 BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
1861 case BOOT_ON_FLASH_UPDATE
:
1864 // Boot with the specific configuration
1866 PlatformBdsConnectConsole (gPlatformConsole
);
1867 PlatformBdsDiagnostics (EXTENSIVE
, FALSE
, BaseMemoryTest
);
1868 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
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 if (SystemConfiguration
.QuietBoot
) {
1972 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
1974 PlatformBdsDiagnostics (IGNORE
, FALSE
, BaseMemoryTest
);
1978 // Do a pre-delay so Hard Disk can spin up and see more logo.
1980 gBS
->Stall(SystemConfiguration
.HddPredelay
* 1000000);
1983 // Perform user identification
1985 if (mCurrentUser
== NULL
) {
1986 PlatformBdsUserIdentify (&mCurrentUser
, &DeferredImageExist
);
1987 if (DeferredImageExist
) {
1989 // After user authentication, the deferred drivers was loaded again.
1990 // Here, need to ensure the deferred drivers are connected.
1992 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
1993 if (EFI_ERROR (Status
)) {
1994 PlatformBdsNoConsoleAction ();
1996 PlatformBdsConnectSequence ();
2000 TcgPhysicalPresenceLibProcessRequest();
2003 Tcg2PhysicalPresenceLibProcessRequest(NULL
);
2006 if (EsrtManagement
!= NULL
) {
2007 EsrtManagement
->SyncEsrtFmp();
2010 // Close boot script and install ready to lock
2012 InstallReadyToLock ();
2015 // Here we have enough time to do the enumeration of boot device
2017 PlatformBdsLibEnumerateAllBootOption (BootOptionList
);
2020 // Give one chance to enter the setup if we
2021 // have the time out
2023 PlatformBdsEnterFrontPageWithHotKey (Timeout
, FALSE
);
2026 // Give one chance to enter the setup if we
2027 // select Gummiboot "Reboot Into Firmware Interface"
2029 BootIntoFirmwareInterface();
2032 // In default boot mode, always find all boot
2033 // option and do enumerate all the default boot option
2036 BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
2037 if (IsListEmpty(BootOptionList
)) {
2038 PlatformBdsPredictBootOption (BootOptionList
);
2049 IsFirstBoot
= PcdGetBool(PcdBootState
);
2051 PcdSetBool(PcdBootState
, FALSE
);
2058 Hook point after a boot attempt succeeds. We don't expect a boot option to
2059 return, so the UEFI 2.0 specification defines that you will default to an
2060 interactive mode and stop processing the BootOrder list in this case. This
2061 is alos a platform implementation and can be customized by IBV/OEM.
2063 @param Option Pointer to Boot Option that succeeded to boot.
2070 PlatformBdsBootSuccess (
2071 IN BDS_COMMON_OPTION
*Option
2077 // If Boot returned with EFI_SUCCESS and there is not in the boot device
2078 // select loop then we need to pop up a UI and wait for user input.
2080 TmpStr
= Option
->StatusString
;
2081 if (TmpStr
!= NULL
) {
2082 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
2088 Hook point after a boot attempt fails.
2090 @param Option - Pointer to Boot Option that failed to boot.
2091 @param Status - Status returned from failed boot.
2092 @param ExitData - Exit data returned from failed boot.
2093 @param ExitDataSize - Exit data size returned from failed boot.
2100 PlatformBdsBootFail (
2101 IN BDS_COMMON_OPTION
*Option
,
2102 IN EFI_STATUS Status
,
2103 IN CHAR16
*ExitData
,
2104 IN UINTN ExitDataSize
2108 EFI_HANDLE FvProtocolHandle
;
2111 // If Boot returned with failed status then we need to pop up a UI and wait
2114 TmpStr
= Option
->StatusString
;
2115 if (TmpStr
!= NULL
) {
2116 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
2119 if (PcdGet32(PcdFlashFvShellSize
) > 0){
2120 gDS
->ProcessFirmwareVolume (
2121 (VOID
*)(UINTN
)PcdGet32(PcdFlashFvShellBase
),
2122 PcdGet32(PcdFlashFvShellSize
),
2126 PlatformBdsConnectSequence ();
2130 This function is remained for IBV/OEM to do some platform action,
2131 if there no console device can be connected.
2135 @retval EFI_SUCCESS Direct return success now.
2139 PlatformBdsNoConsoleAction (
2147 This function locks the block
2149 @param Base The base address flash region to be locked.
2154 IN EFI_PHYSICAL_ADDRESS Base
2157 EFI_FV_BLOCK_MAP_ENTRY
*BlockMap
;
2158 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
2159 EFI_PHYSICAL_ADDRESS BaseAddress
;
2163 BaseAddress
= Base
- 0x400000 + 2;
2164 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINTN
) (Base
));
2165 BlockMap
= &(FvHeader
->BlockMap
[0]);
2167 while ((BlockMap
->NumBlocks
!= 0) && (BlockMap
->Length
!= 0)) {
2168 BlockLength
= BlockMap
->Length
;
2169 for (Index
= 0; Index
< BlockMap
->NumBlocks
; Index
++) {
2170 MmioOr8 ((UINTN
) BaseAddress
, 0x03);
2171 BaseAddress
+= BlockLength
;
2179 PlatformBdsLockNonUpdatableFlash (
2183 EFI_PHYSICAL_ADDRESS Base
;
2185 Base
= (EFI_PHYSICAL_ADDRESS
) PcdGet32 (PcdFlashFvMainBase
);
2190 Base
= (EFI_PHYSICAL_ADDRESS
) PcdGet32 (PcdFlashFvRecoveryBase
);
2197 Lock the ConsoleIn device in system table. All key
2198 presses will be ignored until the Password is typed in. The only way to
2199 disable the password is to type it in to a ConIn device.
2201 @param Password Password used to lock ConIn device.
2203 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
2204 @retval EFI_UNSUPPORTED Password not found
2213 return EFI_UNSUPPORTED
;
2217 Connect the predefined platform default authentication devices.
2219 This function connects the predefined device path for authentication device,
2220 and if the predefined device path has child device path, the child handle will
2221 be connected too. But the child handle of the child will not be connected.
2226 PlatformBdsConnectAuthDevice (
2234 EFI_HANDLE
*HandleBuffer
;
2235 EFI_DEVICE_PATH_PROTOCOL
*ChildDevicePath
;
2236 EFI_USER_MANAGER_PROTOCOL
*Manager
;
2238 Status
= gBS
->LocateProtocol (
2239 &gEfiUserManagerProtocolGuid
,
2243 if (EFI_ERROR (Status
)) {
2245 // As user manager protocol is not installed, the authentication devices
2246 // should not be connected.
2252 while (gUserAuthenticationDevice
[Index
] != NULL
) {
2254 // Connect the platform customized device paths
2256 BdsLibConnectDevicePath (gUserAuthenticationDevice
[Index
]);
2261 // Find and connect the child device paths of the platform customized device paths
2263 HandleBuffer
= NULL
;
2264 for (Index
= 0; gUserAuthenticationDevice
[Index
] != NULL
; Index
++) {
2266 Status
= gBS
->LocateHandleBuffer (
2273 ASSERT (!EFI_ERROR (Status
));
2276 // Find and connect the child device paths of gUserIdentificationDevice[Index]
2278 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
2279 ChildDevicePath
= NULL
;
2280 Status
= gBS
->HandleProtocol (
2281 HandleBuffer
[HandleIndex
],
2282 &gEfiDevicePathProtocolGuid
,
2283 (VOID
**) &ChildDevicePath
2285 if (EFI_ERROR (Status
) || ChildDevicePath
== NULL
) {
2291 gUserAuthenticationDevice
[Index
],
2292 (GetDevicePathSize (gUserAuthenticationDevice
[Index
]) - sizeof (EFI_DEVICE_PATH_PROTOCOL
))
2296 gBS
->ConnectController (
2297 HandleBuffer
[HandleIndex
],
2305 if (HandleBuffer
!= NULL
) {
2306 FreePool (HandleBuffer
);
2311 This function is to identify a user, and return whether deferred images exist.
2313 @param[out] User Point to user profile handle.
2314 @param[out] DeferredImageExist On return, points to TRUE if the deferred image
2315 exist or FALSE if it did not exist.
2320 PlatformBdsUserIdentify (
2321 OUT EFI_USER_PROFILE_HANDLE
*User
,
2322 OUT BOOLEAN
*DeferredImageExist
2326 EFI_DEFERRED_IMAGE_LOAD_PROTOCOL
*DeferredImage
;
2328 EFI_HANDLE
*HandleBuf
;
2331 EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
;
2337 // Perform user identification
2340 Status
= BdsLibUserIdentify (User
);
2341 } while (EFI_ERROR (Status
));
2344 // After user authentication now, try to find whether deferred image exists
2348 *DeferredImageExist
= FALSE
;
2349 Status
= gBS
->LocateHandleBuffer (
2351 &gEfiDeferredImageLoadProtocolGuid
,
2356 if (EFI_ERROR (Status
)) {
2360 for (Index
= 0; Index
< HandleCount
; Index
++) {
2361 Status
= gBS
->HandleProtocol (
2363 &gEfiDeferredImageLoadProtocolGuid
,
2364 (VOID
**) &DeferredImage
2366 if (!EFI_ERROR (Status
)) {
2368 // Find whether deferred image exists in this instance.
2371 Status
= DeferredImage
->GetImageInfo(
2375 (VOID
**) &DriverImage
,
2379 if (!EFI_ERROR (Status
)) {
2381 // The deferred image is found.
2383 FreePool (HandleBuf
);
2384 *DeferredImageExist
= TRUE
;
2390 FreePool (HandleBuf
);
2397 ShowProgressHotKey (
2398 IN UINT16 TimeoutDefault
2402 UINT16 TimeoutRemain
;
2405 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
2406 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
2407 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
2416 if (TimeoutDefault
== 0) {
2420 gST
->ConOut
->SetAttribute(gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
2422 if (DebugAssertEnabled())
2424 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"));
2429 SerialPortWrite((UINT8
*)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)[GCC]", 76);
2431 SerialPortWrite((UINT8
*)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)", 71);
2434 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
2435 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
2436 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
2442 // Check if the platform is using test key.
2444 Status
= GetSectionFromAnyFv(
2445 PcdGetPtr(PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid
),
2451 if (!EFI_ERROR(Status
)) {
2452 if ((Size
== PcdGetSize(PcdRsa2048Sha256PublicKeyBuffer
)) &&
2453 (CompareMem(Buffer
, PcdGetPtr(PcdRsa2048Sha256PublicKeyBuffer
), Size
) == 0)) {
2454 TmpStr2
= L
"WARNING: Recovery Test Key is used.\r\n";
2455 if (DebugAssertEnabled()) {
2456 DEBUG ((DEBUG_INFO
, "\n\nWARNING: Recovery Test Key is used.\n"));
2458 SerialPortWrite((UINT8
*)"\n\nWARNING: Recovery Test Key is used.", sizeof("\n\nWARNING: Recovery Test Key is used."));
2460 PcdSetBoolS(PcdTestKeyUsed
, TRUE
);
2464 Status
= GetSectionFromAnyFv(
2465 PcdGetPtr(PcdEdkiiPkcs7TestPublicKeyFileGuid
),
2471 if (!EFI_ERROR(Status
)) {
2472 if ((Size
== PcdGetSize(PcdPkcs7CertBuffer
)) &&
2473 (CompareMem(Buffer
, PcdGetPtr(PcdPkcs7CertBuffer
), Size
) == 0)) {
2474 TmpStr3
= L
"WARNING: Capsule Test Key is used.\r\n";
2475 if (DebugAssertEnabled()) {
2476 DEBUG ((DEBUG_INFO
, "\n\nWARNING: Capsule Test Key is used.\r\n"));
2478 SerialPortWrite((UINT8
*)"\n\nWARNING: Capsule Test Key is used.", sizeof("\n\nWARNING: Capsule Test Key is used."));
2480 PcdSetBoolS(PcdTestKeyUsed
, TRUE
);
2486 // Clear the progress status bar first
2488 TmpStr1
= L
"Start boot option, Press <F2> or <DEL> to enter setup page.\r\n";
2489 TmpStrSize
= StrSize(TmpStr1
);
2490 if (TmpStr2
!= NULL
) {
2491 TmpStrSize
+= StrSize(TmpStr2
);
2493 if (TmpStr3
!= NULL
) {
2494 TmpStrSize
+= StrSize(TmpStr3
);
2496 TmpStr
= AllocatePool (TmpStrSize
);
2497 if (TmpStr
== NULL
) {
2500 StrCpyS(TmpStr
, TmpStrSize
/sizeof(CHAR16
), TmpStr1
);
2501 if (TmpStr2
!= NULL
) {
2502 StrCatS(TmpStr
, TmpStrSize
/sizeof(CHAR16
), TmpStr2
);
2504 if (TmpStr3
!= NULL
) {
2505 StrCatS(TmpStr
, TmpStrSize
/sizeof(CHAR16
), TmpStr3
);
2508 PlatformBdsShowProgress (Foreground
, Background
, TmpStr
, Color
, 0, 0);
2510 TimeoutRemain
= TimeoutDefault
;
2511 while (TimeoutRemain
!= 0) {
2512 if (DebugAssertEnabled())
2514 DEBUG ((EFI_D_INFO
, "Showing progress bar...Remaining %d second!\n", TimeoutRemain
));
2518 SerialPortWrite ((UINT8
*)".", 1);
2520 Status
= WaitForSingleEvent (gST
->ConIn
->WaitForKey
, ONE_SECOND
);
2521 if (Status
!= EFI_TIMEOUT
) {
2529 if (TmpStr
!= NULL
) {
2530 PlatformBdsShowProgress (
2535 ((TimeoutDefault
- TimeoutRemain
) * 100 / TimeoutDefault
),
2544 if (TimeoutRemain
== 0) {
2545 if (DebugAssertEnabled())
2550 SerialPortWrite ((UINT8
*)"\r\n", 2);
2556 // User pressed some key
2558 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
2559 if (EFI_ERROR (Status
)) {
2564 // Check Volume Up Key to enter Setup
2566 GpioValue
= MmioRead32 (IO_BASE_ADDRESS
+ 0x0668); // The value of GPIOC_5
2567 if (((GpioValue
& BIT0
) == 0) && (Key
.ScanCode
== SCAN_UP
)) {
2572 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
2574 // User pressed enter, equivalent to select "continue"
2581 //F5 -- Device Manager
2582 //F7 -- Boot Manager
2583 // do not use F8. generally people assume it is windows safe mode key.
2586 DEBUG ((EFI_D_INFO
, "[Key Pressed]: ScanCode 0x%x\n", Key
.ScanCode
));
2587 switch(Key
.ScanCode
) {
2597 gHotKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
2601 gHotKey
= FRONT_PAGE_KEY_BOOT_MANAGER
;
2605 gHotKey
= FRONT_PAGE_KEY_BOOT_MAINTAIN
;
2609 //set gHotKey to continue so that flow will not go into CallFrontPage
2610 gHotKey
= FRONT_PAGE_KEY_CONTINUE
;
2621 This function is the main entry of the platform setup entry.
2622 The function will present the main menu of the system setup,
2623 this is the platform reference part and can be customize.
2626 @param TimeoutDefault The fault time out value before the system
2628 @param ConnectAllHappened The indicater to check if the connect all have
2633 PlatformBdsEnterFrontPageWithHotKey (
2634 IN UINT16 TimeoutDefault
,
2635 IN BOOLEAN ConnectAllHappened
2640 EFI_STATUS LogoStatus
;
2641 EFI_BOOT_LOGO_PROTOCOL
*BootLogo
;
2642 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
2643 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOut
;
2644 UINTN BootTextColumn
;
2647 GraphicsOutput
= NULL
;
2648 SimpleTextOut
= NULL
;
2650 PERF_START (NULL
, "BdsTimeOut", "BDS", 0);
2653 // Indicate if we need connect all in the platform setup
2655 if (ConnectAllHappened
) {
2656 gConnectAllHappened
= TRUE
;
2659 if (!mModeInitialized
) {
2661 // After the console is ready, get current video resolution
2662 // and text mode before launching setup at first time.
2664 Status
= gBS
->HandleProtocol (
2665 gST
->ConsoleOutHandle
,
2666 &gEfiGraphicsOutputProtocolGuid
,
2667 (VOID
**)&GraphicsOutput
2669 if (EFI_ERROR (Status
)) {
2670 GraphicsOutput
= NULL
;
2673 Status
= gBS
->HandleProtocol (
2674 gST
->ConsoleOutHandle
,
2675 &gEfiSimpleTextOutProtocolGuid
,
2676 (VOID
**)&SimpleTextOut
2678 if (EFI_ERROR (Status
)) {
2679 SimpleTextOut
= NULL
;
2682 if (GraphicsOutput
!= NULL
) {
2684 // Get current video resolution and text mode.
2686 mBootHorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
2687 mBootVerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
2690 if (SimpleTextOut
!= NULL
) {
2691 Status
= SimpleTextOut
->QueryMode (
2693 SimpleTextOut
->Mode
->Mode
,
2697 mBootTextModeColumn
= (UINT32
)BootTextColumn
;
2698 mBootTextModeRow
= (UINT32
)BootTextRow
;
2702 // Get user defined text mode for setup.
2704 mSetupHorizontalResolution
= PcdGet32 (PcdSetupVideoHorizontalResolution
);
2705 mSetupVerticalResolution
= PcdGet32 (PcdSetupVideoVerticalResolution
);
2706 mSetupTextModeColumn
= PcdGet32 (PcdSetupConOutColumn
);
2707 mSetupTextModeRow
= PcdGet32 (PcdSetupConOutRow
);
2709 mModeInitialized
= TRUE
;
2712 if (TimeoutDefault
!= 0xffff) {
2713 Status
= ShowProgressHotKey (TimeoutDefault
);
2716 // Ensure screen is clear when switch Console from Graphics mode to Text mode
2718 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);
2719 gST
->ConOut
->ClearScreen (gST
->ConOut
);
2722 // Boot Logo is corrupted, report it using Boot Logo protocol.
2724 LogoStatus
= gBS
->LocateProtocol (&gEfiBootLogoProtocolGuid
, NULL
, (VOID
**) &BootLogo
);
2725 if (!EFI_ERROR (LogoStatus
) && (BootLogo
!= NULL
)) {
2726 BootLogo
->SetBootLogo (BootLogo
, NULL
, 0, 0, 0, 0);
2729 if (EFI_ERROR (Status
)) {
2731 // Timeout or user press enter to continue
2738 // Install BM HiiPackages.
2739 // Keep BootMaint HiiPackage, so that it can be covered by global setting.
2744 BdsSetConsoleMode (TRUE
);
2746 InitializeFrontPage (FALSE
);
2749 // Update Front Page strings
2751 UpdateFrontPageStrings ();
2753 Status
= EFI_SUCCESS
;
2756 Status
= CallFrontPage ();
2758 gCallbackKey
= gHotKey
;
2763 // If gCallbackKey is greater than 1 and less or equal to 5,
2764 // it will launch configuration utilities.
2767 // 4 = device manager
2768 // 5 = boot maintenance manager
2770 if (gCallbackKey
!= 0) {
2771 REPORT_STATUS_CODE (
2773 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_USER_SETUP
)
2778 // Based on the key that was set, we can determine what to do
2780 switch (gCallbackKey
) {
2782 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
2783 // describe to their customers in documentation how to find their setup information (namely
2784 // under the device manager and specific buckets)
2786 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
2788 case FRONT_PAGE_KEY_CONTINUE
:
2791 // User hit continue
2795 case FRONT_PAGE_KEY_LANGUAGE
:
2798 // User made a language setting change - display front page again
2802 case FRONT_PAGE_KEY_BOOT_MANAGER
:
2804 // Remove the installed BootMaint HiiPackages when exit.
2809 // User chose to run the Boot Manager
2814 // Reinstall BootMaint HiiPackages after exiting from Boot Manager.
2819 case FRONT_PAGE_KEY_DEVICE_MANAGER
:
2822 // Display the Device Manager
2825 CallDeviceManager ();
2826 } while (gCallbackKey
== FRONT_PAGE_KEY_DEVICE_MANAGER
);
2829 case FRONT_PAGE_KEY_BOOT_MAINTAIN
:
2832 // Display the Boot Maintenance Manager
2834 BdsStartBootMaint ();
2838 } while (((UINTN
)gCallbackKey
) != FRONT_PAGE_KEY_CONTINUE
);
2841 //Will leave browser, check any reset required change is applied? if yes, reset system
2843 SetupResetReminder ();
2845 // Remove the installed BootMaint HiiPackages when exit.
2851 // Automatically load current entry
2852 // Note: The following lines of code only execute when Auto boot
2855 PERF_END (NULL
, "BdsTimeOut", "BDS", 0);
2860 BootIntoFirmwareInterface(
2867 UINT64 OsIndication
;
2871 DataSize
= sizeof(UINT64
);
2872 Status
= gRT
->GetVariable (
2874 &gEfiGlobalVariableGuid
,
2880 DEBUG ((EFI_D_INFO
, "OSIndication Variable Value %d\n", OsIndication
));
2882 //Goto FrontPage directly when bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted.
2884 if (!EFI_ERROR(Status
) && (OsIndication
!= 0)) {
2886 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
2892 PlatformBdsConnectSimpleConsole (
2893 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
2898 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
2899 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
2900 UINTN DevicePathSize
;
2904 Status
= EFI_SUCCESS
;
2906 VarConout
= BdsLibGetVariableAndSize (
2908 &gEfiGlobalVariableGuid
,
2911 VarConin
= BdsLibGetVariableAndSize (
2913 &gEfiGlobalVariableGuid
,
2916 if (VarConout
== NULL
|| VarConin
== NULL
) {
2918 // Have chance to connect the platform default console,
2919 // the platform default console is the minimum device group
2920 // the platform should support
2922 while (PlatformConsole
[Index
].DevicePath
!= NULL
) {
2925 // Update the console variable with the connect type
2927 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
2928 BdsLibUpdateConsoleVariable (L
"ConIn", PlatformConsole
[Index
].DevicePath
, NULL
);
2931 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
2932 BdsLibUpdateConsoleVariable (L
"ConOut", PlatformConsole
[Index
].DevicePath
, NULL
);
2935 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
2936 BdsLibUpdateConsoleVariable (L
"ErrOut", PlatformConsole
[Index
].DevicePath
, NULL
);
2944 // Connect ConIn first to give keyboard time to parse hot key event.
2946 Status
= BdsLibConnectConsoleVariable (L
"ConIn");
2947 if (EFI_ERROR (Status
)) {
2952 // Make sure we have at least one active VGA, and have the right
2953 // active VGA in console variable
2955 Status
= PlatformBdsForceActiveVga ();
2958 // It seems impossible not to have any ConOut device on platform,
2959 // so we check the status here.
2961 Status
= BdsLibConnectConsoleVariable (L
"ConOut");
2962 if (EFI_ERROR (Status
)) {
2971 Timer handler to convert the key from USB.
2973 @param Event Indicates the event that invoke this function.
2974 @param Context Indicates the calling context.
2978 HotKeyTimerHandler (
2986 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
2987 if (EFI_ERROR (Status
)) {
2991 switch(Key
.ScanCode
) {
2994 mHotKeyPressed
= TRUE
;
2998 gHotKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
2999 mHotKeyPressed
= TRUE
;
3003 gHotKey
= FRONT_PAGE_KEY_BOOT_MANAGER
;
3004 mHotKeyPressed
= TRUE
;
3008 gHotKey
= FRONT_PAGE_KEY_BOOT_MAINTAIN
;
3009 mHotKeyPressed
= TRUE
;
3013 if (mHotKeyPressed
) {
3019 gBS
->CloseEvent (mHotKeyTimerEvent
);
3020 mHotKeyTimerEvent
= NULL
;
3028 Callback function for SimpleTextInEx protocol install events
3030 @param Event the event that is signaled.
3031 @param Context not used here.
3043 Status
= gBS
->CloseEvent(mHitHotkeyEvent
);
3044 if (EFI_ERROR (Status
)) {
3047 Status
= gBS
->CreateEvent (
3048 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
3054 if (EFI_ERROR (Status
)) {
3057 Status
= gBS
->SetTimer (
3060 KEYBOARD_TIMER_INTERVAL
3062 if (EFI_ERROR (Status
)) {
3072 PlatformBdsInitHotKeyEvent (
3079 // Register Protocol notify for Hotkey service
3081 Status
= gBS
->CreateEvent (
3088 ASSERT_EFI_ERROR (Status
);
3091 // Register for protocol notifications on this event
3093 Status
= gBS
->RegisterProtocolNotify (
3094 &gEfiSimpleTextInputExProtocolGuid
,
3096 &mHitHotkeyRegistration
3098 ASSERT_EFI_ERROR (Status
);