3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 This file include all platform action which can be customized
26 #include "BdsPlatform.h"
27 #include "SetupMode.h"
28 #include <Guid/SetupVariable.h>
29 #include <Library/TcgPhysicalPresenceLib.h>
30 #include <Library/TrEEPhysicalPresenceLib.h>
31 #include <Protocol/I2cMasterMcg.h>
33 #include <PlatformBaseAddresses.h>
34 #include <Protocol/GlobalNvsArea.h>
35 #include <Library/DxeServicesTableLib.h>
36 #include <Protocol/BlockIo.h>
37 #include <PchRegs/PchRegsPcu.h>
38 #include <Library/S3BootScriptLib.h>
39 #include "PchAccess.h"
40 #include "PchRegs/PchRegsSata.h"
41 #include <Library/SerialPortLib.h>
42 #include <Library/DebugLib.h>
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 Status
= gBS
->InstallProtocolInterface (
184 &gEfiDxeSmmReadyToLockProtocolGuid
,
185 EFI_NATIVE_INTERFACE
,
188 ASSERT_EFI_ERROR (Status
);
201 BdsSetConsoleMode (TRUE
);
202 DEBUG ((EFI_D_INFO
, "BdsEntry ShellImageCallback \n"));
206 // BDS Platform Functions
209 Platform Bds init. Incude the platform firmware vendor, revision
224 EFI_EVENT ShellImageEvent
;
225 EFI_GUID ShellEnvProtocol
= SHELL_ENVIRONMENT_INTERFACE_PROTOCOL
;
228 SerialPortWrite((UINT8
*)">>>>BdsEntry[GCC]\r\n", 19);
230 SerialPortWrite((UINT8
*)">>>>BdsEntry\r\n", 14);
232 BdsLibSaveMemoryTypeInformation ();
235 // Before user authentication, the user identification devices need be connected
236 // from the platform customized device paths
238 PlatformBdsConnectAuthDevice ();
241 // As console is not ready, the auto logon user will be identified.
243 BdsLibUserIdentify (&mCurrentUser
);
246 // Change Gop mode when boot into Shell
248 if (mShellImageCallbackReg
== NULL
) {
249 Status
= gBS
->CreateEvent (
250 EFI_EVENT_NOTIFY_SIGNAL
,
256 if (!EFI_ERROR (Status
)) {
257 Status
= gBS
->RegisterProtocolNotify (
260 &mShellImageCallbackReg
263 DEBUG ((EFI_D_INFO
, "BdsEntry ShellImageCallback \n"));
270 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
271 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
276 EFI_HANDLE PciDeviceHandle
;
277 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
278 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
279 UINTN GopHandleCount
;
280 EFI_HANDLE
*GopHandleBuffer
;
283 SYSTEM_CONFIGURATION mSystemConfiguration
;
285 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
286 return EFI_INVALID_PARAMETER
;
290 // Initialize the GopDevicePath to be PciDevicePath
292 *GopDevicePath
= PciDevicePath
;
293 TempPciDevicePath
= PciDevicePath
;
295 Status
= gBS
->LocateDevicePath (
296 &gEfiDevicePathProtocolGuid
,
300 if (EFI_ERROR (Status
)) {
305 // Try to connect this handle, so that GOP dirver could start on this
306 // device and create child handles with GraphicsOutput Protocol installed
307 // on them, then we get device paths of these child handles and select
308 // them as possible console device.
312 // Select display devices
314 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
315 Status
= gRT
->GetVariable(
317 &gEfiNormalSetupGuid
,
320 &mSystemConfiguration
322 ASSERT_EFI_ERROR (Status
);
324 if(mSystemConfiguration
.BootDisplayDevice
!= 0x0)
326 ACPI_ADR_DEVICE_PATH AcpiAdr
;
327 EFI_DEVICE_PATH_PROTOCOL
*MyDevicePath
= NULL
;
329 AcpiAdr
.Header
.Type
= ACPI_DEVICE_PATH
;
330 AcpiAdr
.Header
.SubType
= ACPI_ADR_DP
;
332 switch (mSystemConfiguration
.BootDisplayDevice
) {
334 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA
, PORT_CRT
, 0); //CRT Device
337 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL
, PORT_B_HDMI
, 0); //HDMI Device Port B
340 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL
, PORT_B_DP
, 0); //DP PortB
343 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL
, PORT_C_DP
, 0); //DP PortC
346 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL
, PORT_C_DP
, 0); //eDP Port C
349 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL
, PORT_MIPI_A
, 0); //DSI Port A
352 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL
, PORT_MIPI_C
, 0); //DSI Port C
355 AcpiAdr
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA
, PORT_CRT
, 0);
359 SetDevicePathNodeLength (&AcpiAdr
.Header
, sizeof (ACPI_ADR_DEVICE_PATH
));
361 MyDevicePath
= AppendDevicePathNode(MyDevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&AcpiAdr
);
363 gBS
->ConnectController (
370 FreePool(MyDevicePath
);
374 gBS
->ConnectController (
382 Status
= gBS
->LocateHandleBuffer (
384 &gEfiGraphicsOutputProtocolGuid
,
389 if (!EFI_ERROR (Status
)) {
391 // Add all the child handles as possible Console Device
393 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
394 Status
= gBS
->HandleProtocol (
395 GopHandleBuffer
[Index
],
396 &gEfiDevicePathProtocolGuid
,
397 (VOID
**)&TempDevicePath
399 if (EFI_ERROR (Status
)) {
405 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
408 // In current implementation, we only enable one of the child handles
409 // as console device, i.e. sotre one of the child handle's device
410 // path to variable "ConOut"
411 // In futhure, we could select all child handles to be console device
413 *GopDevicePath
= TempDevicePath
;
416 gBS
->FreePool (GopHandleBuffer
);
424 Search out all the platform pci or agp video device. The function may will
425 find multiple video device, and return all enabled device path.
427 @param PlugInPciVgaDevicePath Return the platform plug in pci video device
428 path if the system have plug in pci video device.
429 @param OnboardPciVgaDevicePath Return the platform active agp video device path
430 if the system have plug in agp video device or on
433 @retval EFI_SUCCSS Get all platform active video device path.
434 @retval EFI_STATUS Return the status of gBS->LocateDevicePath (),
435 gBS->ConnectController (),
436 and gBS->LocateHandleBuffer ().
440 GetPlugInPciVgaDevicePath (
441 IN OUT EFI_DEVICE_PATH_PROTOCOL
**PlugInPciVgaDevicePath
,
442 IN OUT EFI_DEVICE_PATH_PROTOCOL
**OnboardPciVgaDevicePath
446 EFI_HANDLE RootHandle
;
448 EFI_HANDLE
*HandleBuffer
;
451 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
452 BOOLEAN PlugInPciVga
;
453 EFI_PCI_IO_PROTOCOL
*PciIo
;
462 // Make all the PCI_IO protocols on PCI Seg 0 show up
464 BdsLibConnectDevicePath (gPlatformRootBridges
[0]);
466 Status
= gBS
->LocateDevicePath (
467 &gEfiDevicePathProtocolGuid
,
468 &gPlatformRootBridges
[0],
471 if (EFI_ERROR (Status
)) {
475 Status
= gBS
->ConnectController (
481 if (EFI_ERROR (Status
)) {
486 // Start to check all the pci io to find all possible VGA device
490 Status
= gBS
->LocateHandleBuffer (
492 &gEfiPciIoProtocolGuid
,
497 if (EFI_ERROR (Status
)) {
501 for (Index
= 0; Index
< HandleCount
; Index
++) {
502 Status
= gBS
->HandleProtocol (
504 &gEfiPciIoProtocolGuid
,
507 if (!EFI_ERROR (Status
)) {
510 // Check for all VGA device
512 Status
= PciIo
->Pci
.Read (
516 sizeof (Pci
) / sizeof (UINT32
),
519 if (EFI_ERROR (Status
)) {
524 // Here we decide which VGA device to enable in PCI bus
526 // The first plugin PCI VGA card device will be present as PCI VGA
527 // The onchip AGP or AGP card will be present as AGP VGA
529 if (!IS_PCI_VGA (&Pci
)) {
534 // Set the device as the possible console out device,
536 // Below code will make every VGA device to be one
537 // of the possibe console out device
540 gBS
->HandleProtocol (
542 &gEfiDevicePathProtocolGuid
,
548 while (gPlatformAllPossiblePciVgaConsole
[Index1
] != NULL
) {
551 gPlatformAllPossiblePciVgaConsole
[Index1
],
552 GetDevicePathSize (gPlatformAllPossiblePciVgaConsole
[Index1
])
556 // This device is an AGP device
558 *OnboardPciVgaDevicePath
= DevicePath
;
559 PlugInPciVga
= FALSE
;
567 *PlugInPciVgaDevicePath
= DevicePath
;
572 FreePool (HandleBuffer
);
579 Find the platform active vga, and base on the policy to enable the vga as
580 the console out device. The policy is driven by one setup variable "VBIOS".
584 @param EFI_UNSUPPORTED There is no active vga device
586 @retval EFI_STATUS Return the status of BdsLibGetVariableAndSize ()
590 PlatformBdsForceActiveVga (
595 EFI_DEVICE_PATH_PROTOCOL
*PlugInPciVgaDevicePath
;
596 EFI_DEVICE_PATH_PROTOCOL
*OnboardPciVgaDevicePath
;
597 EFI_DEVICE_PATH_PROTOCOL
*DevicePathFirst
;
598 EFI_DEVICE_PATH_PROTOCOL
*DevicePathSecond
;
599 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
601 SYSTEM_CONFIGURATION mSystemConfiguration
;
603 Status
= EFI_SUCCESS
;
604 PlugInPciVgaDevicePath
= NULL
;
605 OnboardPciVgaDevicePath
= NULL
;
608 // Check the policy which is the first enabled VGA
610 GetPlugInPciVgaDevicePath (&PlugInPciVgaDevicePath
, &OnboardPciVgaDevicePath
);
612 if (PlugInPciVgaDevicePath
== NULL
&& OnboardPciVgaDevicePath
== NULL
) {
613 return EFI_UNSUPPORTED
;
616 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
617 Status
= gRT
->GetVariable(
619 &gEfiNormalSetupGuid
,
622 &mSystemConfiguration
624 ASSERT_EFI_ERROR (Status
);
627 if ((PlugInPciVgaDevicePath
== NULL
&& OnboardPciVgaDevicePath
!= NULL
) ) {
628 DEBUG ((EFI_D_ERROR
,"Update onboard PCI VGA ...\n"));
629 DevicePathFirst
= OnboardPciVgaDevicePath
;
630 DevicePathSecond
= PlugInPciVgaDevicePath
;
633 if(OnboardPciVgaDevicePath
!= NULL
&& mSystemConfiguration
.PrimaryVideoAdaptor
== 0) {
634 DEBUG ((EFI_D_ERROR
,"Update onboard PCI VGA When set primary!!!...\n"));
635 DevicePathFirst
= OnboardPciVgaDevicePath
;
636 DevicePathSecond
= PlugInPciVgaDevicePath
;
640 DEBUG ((EFI_D_ERROR
,"Update plug in PCI VGA ...\n"));
641 DevicePathFirst
= PlugInPciVgaDevicePath
;
642 DevicePathSecond
= OnboardPciVgaDevicePath
;
645 GetGopDevicePath (DevicePathFirst
, &GopDevicePath
);
646 DevicePathFirst
= GopDevicePath
;
648 Status
= BdsLibUpdateConsoleVariable (
658 UpdateConsoleResolution(
662 UINT32 HorizontalResolution
;
663 UINT32 VerticalResolution
;
664 SYSTEM_CONFIGURATION SystemConfiguration
;
669 HorizontalResolution
= PcdGet32 (PcdSetupVideoHorizontalResolution
);
670 VerticalResolution
= PcdGet32 (PcdSetupVideoVerticalResolution
);
672 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
673 Status
= gRT
->GetVariable(
675 &gEfiNormalSetupGuid
,
680 ASSERT_EFI_ERROR (Status
);
682 switch (SystemConfiguration
.IgdFlatPanel
) {
686 // Use the detault PCD values.
691 HorizontalResolution
= 640;
692 VerticalResolution
= 480;
696 HorizontalResolution
= 800;
697 VerticalResolution
= 600;
701 HorizontalResolution
= 1024;
702 VerticalResolution
= 768;
706 HorizontalResolution
= 1280;
707 VerticalResolution
= 1024;
711 HorizontalResolution
= 1366;
712 VerticalResolution
= 768;
716 HorizontalResolution
= 1680;
717 VerticalResolution
= 1050;
721 HorizontalResolution
= 1920;
722 VerticalResolution
= 1200;
726 HorizontalResolution
= 1280;
727 VerticalResolution
= 800;
731 PcdSet32 (PcdSetupVideoHorizontalResolution
, HorizontalResolution
);
732 PcdSet32 (PcdSetupVideoVerticalResolution
, VerticalResolution
);
733 DEBUG ((EFI_D_ERROR
, "HorizontalResolution = %x; VerticalResolution = %x", HorizontalResolution
, VerticalResolution
));
739 Connect the predefined platform default console device. Always try to find
740 and enable the vga device if have.
742 @param PlatformConsole Predfined platform default console device array.
744 @retval EFI_SUCCESS Success connect at least one ConIn and ConOut
745 device, there must have one ConOut device is
748 @retval EFI_STATUS Return the status of
749 BdsLibConnectAllDefaultConsoles ()
753 PlatformBdsConnectConsole (
754 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
759 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
760 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
761 UINTN DevicePathSize
;
763 UpdateConsoleResolution();
766 Status
= EFI_SUCCESS
;
768 VarConout
= BdsLibGetVariableAndSize (
770 &gEfiGlobalVariableGuid
,
773 VarConin
= BdsLibGetVariableAndSize (
775 &gEfiGlobalVariableGuid
,
778 if (VarConout
== NULL
|| VarConin
== NULL
) {
780 // Have chance to connect the platform default console,
781 // the platform default console is the minimue device group
782 // the platform should support
784 while (PlatformConsole
[Index
].DevicePath
!= NULL
) {
787 // Update the console variable with the connect type
789 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
790 BdsLibUpdateConsoleVariable (L
"ConIn", PlatformConsole
[Index
].DevicePath
, NULL
);
793 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
794 BdsLibUpdateConsoleVariable (L
"ConOut", PlatformConsole
[Index
].DevicePath
, NULL
);
797 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
798 BdsLibUpdateConsoleVariable (L
"ErrOut", PlatformConsole
[Index
].DevicePath
, NULL
);
806 // Make sure we have at least one active VGA, and have the right
807 // active VGA in console variable
809 Status
= PlatformBdsForceActiveVga ();
810 if (EFI_ERROR (Status
)) {
814 DEBUG ((EFI_D_INFO
, "DISPLAY INIT DONE\n"));
817 // Connect the all the default console with current console variable
819 Status
= BdsLibConnectAllDefaultConsoles ();
820 if (EFI_ERROR (Status
)) {
828 Connect with predeined platform connect sequence,
829 the OEM/IBV can customize with their own connect sequence.
837 PlatformBdsConnectSequence (
846 // Here we can get the customized platform connect sequence
847 // Notes: we can connect with new variable which record the
848 // last time boots connect device path sequence
850 while (gPlatformConnectSequence
[Index
] != NULL
) {
853 // Build the platform boot option
855 BdsLibConnectDevicePath (gPlatformConnectSequence
[Index
]);
860 // Just use the simple policy to connect all devices
861 // There should be no difference between debug tip and release tip, or it will be extremely hard to debug.
863 // There is case that IdeController driver will write boot script in driver model Start() function. It will be rejected by boot script save.
864 // It is only found when DEBUG disabled, because we are using BdsLibConnectAll() when DEBUG enabled.
866 // So we use BdsLibConnectAll() here to make sure IdeController.Start() is invoked before InstallReadyToLock().
867 // We may also consider to connect SataController only later if needed.
874 Load the predefined driver option, OEM/IBV can customize this
875 to load their own drivers
877 @param BdsDriverLists The header of the driver option link list.
883 PlatformBdsGetDriverOption (
884 IN OUT LIST_ENTRY
*BdsDriverLists
892 // Here we can get the customized platform driver option
894 while (gPlatformDriverOption
[Index
] != NULL
) {
897 // Build the platform boot option
899 BdsLibRegisterNewOption (BdsDriverLists
, gPlatformDriverOption
[Index
], NULL
, L
"DriverOrder");
906 This function is used for some critical time if the the system
907 have no any boot option, and there is no time out for user to add
908 the new boot option. This can also treat as the platform default
911 @param BdsBootOptionList The header of the boot option link list.
917 PlatformBdsPredictBootOption (
918 IN OUT LIST_ENTRY
*BdsBootOptionList
926 // Here give chance to get platform boot option data
928 while (gPlatformBootOption
[Index
] != NULL
) {
931 // Build the platform boot option
933 BdsLibRegisterNewOption (BdsBootOptionList
, gPlatformBootOption
[Index
], NULL
, L
"BootOrder");
939 Perform the platform diagnostic, such like test memory. OEM/IBV also
940 can customize this fuction to support specific platform diagnostic.
942 @param MemoryTestLevel The memory test intensive level
943 @param QuietBoot Indicate if need to enable the quiet boot
944 @param BaseMemoryTest A pointer to BdsMemoryTest()
950 PlatformBdsDiagnostics (
951 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
952 IN BOOLEAN QuietBoot
,
953 IN BASEM_MEMORY_TEST BaseMemoryTest
959 // Here we can decide if we need to show
960 // the diagnostics screen
961 // Notes: this quiet boot code should be remove
962 // from the graphic lib
965 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
968 // Perform system diagnostic
970 Status
= BaseMemoryTest (MemoryTestLevel
);
971 if (EFI_ERROR (Status
)) {
979 // Perform system diagnostic
981 Status
= BaseMemoryTest (MemoryTestLevel
);
987 The function will excute with as the platform policy, current policy
988 is driven by boot mode. IBV/OEM can customize this code for their specific
991 @param DriverOptionList - The header of the driver option link list
992 @param BootOptionList - The header of the boot option link list
993 @param ProcessCapsules - A pointer to ProcessCapsules()
994 @param BaseMemoryTest - A pointer to BaseMemoryTest()
1001 PlatformBdsPolicyBehavior (
1002 IN OUT LIST_ENTRY
*DriverOptionList
,
1003 IN OUT LIST_ENTRY
*BootOptionList
,
1004 IN PROCESS_CAPSULES ProcessCapsules
,
1005 IN BASEM_MEMORY_TEST BaseMemoryTest
1010 EFI_BOOT_MODE BootMode
;
1011 BOOLEAN DeferredImageExist
;
1013 CHAR16 CapsuleVarName
[36];
1014 CHAR16
*TempVarName
;
1015 SYSTEM_CONFIGURATION SystemConfiguration
;
1017 BOOLEAN SetVariableFlag
;
1018 PLATFORM_PCI_DEVICE_PATH
*EmmcBootDevPath
;
1019 EFI_GLOBAL_NVS_AREA_PROTOCOL
*GlobalNvsArea
;
1020 EFI_HANDLE FvProtocolHandle
;
1022 EFI_HANDLE
*HandleBuffer
;
1024 UINTN SataPciRegBase
= 0;
1025 UINT16 SataModeSelect
= 0;
1026 VOID
*RegistrationExitPmAuth
= NULL
;
1028 BOOLEAN IsFirstBoot
;
1030 UINTN BootOrderSize
;
1032 Timeout
= PcdGet16 (PcdPlatformBootTimeOut
);
1033 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
1034 Status
= gRT
->GetVariable(
1036 &gEfiNormalSetupGuid
,
1039 &SystemConfiguration
1041 if (EFI_ERROR (Status
)) {
1046 // Load the driver option as the driver option list
1048 PlatformBdsGetDriverOption (DriverOptionList
);
1051 // Get current Boot Mode
1053 BootMode
= GetBootModeHob();
1056 // Clear all the capsule variables CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...
1057 // as early as possible which will avoid the next time boot after the capsule update
1058 // will still into the capsule loop
1060 StrCpy (CapsuleVarName
, EFI_CAPSULE_VARIABLE_NAME
);
1061 TempVarName
= CapsuleVarName
+ StrLen (CapsuleVarName
);
1063 SetVariableFlag
= TRUE
;
1064 while (SetVariableFlag
) {
1066 UnicodeValueToString (TempVarName
, 0, Index
, 0);
1068 Status
= gRT
->SetVariable (
1070 &gEfiCapsuleVendorGuid
,
1071 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_RUNTIME_ACCESS
|
1072 EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1076 if (EFI_ERROR (Status
)) {
1078 // There is no capsule variables, quit
1080 SetVariableFlag
= FALSE
;
1087 // No deferred images exist by default
1089 DeferredImageExist
= FALSE
;
1090 if ((BootMode
!= BOOT_WITH_MINIMAL_CONFIGURATION
) && (PcdGet32(PcdFlashFvShellSize
) > 0)){
1091 gDS
->ProcessFirmwareVolume (
1092 (VOID
*)(UINTN
)PcdGet32(PcdFlashFvShellBase
),
1093 PcdGet32(PcdFlashFvShellSize
),
1098 if (SystemConfiguration
.FastBoot
== 1) {
1099 BootOrder
= BdsLibGetVariableAndSize (
1101 &gEfiGlobalVariableGuid
,
1104 if ((BootOrder
!= NULL
) && (BootMode
!= BOOT_ON_FLASH_UPDATE
)) {
1106 // BootOrder exist, it means system has boot before. We can do fast boot.
1108 BootMode
= BOOT_WITH_MINIMAL_CONFIGURATION
;
1114 // Use eMMC to boot OS and turn on AHCI, when SATA HDD is diconnected,
1115 // SATA AHCI CTLR device will show yellow bang, implement this solution to solve it.
1117 SataPciRegBase
= MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA
, 0, 0);
1118 SataModeSelect
= MmioRead16 (SataPciRegBase
+ R_PCH_SATA_MAP
) & B_PCH_SATA_MAP_SMS_MASK
;
1119 Status
= EFI_SUCCESS
;
1120 if (SataModeSelect
!= V_PCH_SATA_MAP_SMS_IDE
) {
1121 Status
= gBS
->CreateEvent (
1128 if (!EFI_ERROR (Status
)) {
1129 Status
= gBS
->RegisterProtocolNotify (
1130 &gExitPmAuthProtocolGuid
,
1132 &RegistrationExitPmAuth
1139 case BOOT_WITH_MINIMAL_CONFIGURATION
:
1140 PlatformBdsInitHotKeyEvent ();
1141 PlatformBdsConnectSimpleConsole (gPlatformSimpleConsole
);
1145 // Check to see if it's needed to dispatch more DXE drivers.
1147 for (Index
= 0; Index
< sizeof(ConnectDriverTable
)/sizeof(EFI_GUID
*); Index
++) {
1148 Status
= gBS
->LocateHandleBuffer (
1150 ConnectDriverTable
[Index
],
1155 if (!EFI_ERROR (Status
)) {
1156 for (Index1
= 0; Index1
< HandleCount
; Index1
++) {
1157 gBS
->ConnectController (
1158 HandleBuffer
[Index1
],
1166 if (HandleBuffer
!= NULL
) {
1167 FreePool (HandleBuffer
);
1174 // Locate the Global NVS Protocol.
1176 Status
= gBS
->LocateProtocol (
1177 &gEfiGlobalNvsAreaProtocolGuid
,
1179 (void **)&GlobalNvsArea
1181 if (GlobalNvsArea
->Area
->emmcVersion
== 0){
1182 EmmcBootDevPath
= (PLATFORM_PCI_DEVICE_PATH
*)gPlatformSimpleBootOption
[0];
1183 EmmcBootDevPath
->PciDevice
.Device
= 0x10;
1187 // Connect boot device here to give time to read keyboard.
1189 BdsLibConnectDevicePath (gPlatformSimpleBootOption
[0]);
1192 // This is a workround for dectecting hotkey from USB keyboard.
1194 gBS
->Stall(KEYBOARD_TIMER_INTERVAL
);
1196 if (mHotKeyTimerEvent
!= NULL
) {
1202 gBS
->CloseEvent (mHotKeyTimerEvent
);
1203 mHotKeyTimerEvent
= NULL
;
1205 if (mHotKeyPressed
) {
1207 // Skip show progress count down
1210 goto FULL_CONFIGURATION
;
1213 if (SystemConfiguration
.QuietBoot
) {
1214 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
1216 PlatformBdsDiagnostics (IGNORE
, FALSE
, BaseMemoryTest
);
1221 TcgPhysicalPresenceLibProcessRequest();
1225 // Close boot script and install ready to lock
1227 InstallReadyToLock ();
1230 // Give one chance to enter the setup if we
1231 // select Gummiboot "Reboot Into Firmware Interface" and Fast Boot is enabled.
1233 BootIntoFirmwareInterface();
1236 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES
:
1239 // In no-configuration boot mode, we can connect the
1240 // console directly.
1242 BdsLibConnectAllDefaultConsoles ();
1243 PlatformBdsDiagnostics (IGNORE
, TRUE
, BaseMemoryTest
);
1246 // Perform some platform specific connect sequence
1248 PlatformBdsConnectSequence ();
1251 // As console is ready, perform user identification again.
1253 if (mCurrentUser
== NULL
) {
1254 PlatformBdsUserIdentify (&mCurrentUser
, &DeferredImageExist
);
1255 if (DeferredImageExist
) {
1257 // After user authentication, the deferred drivers was loaded again.
1258 // Here, need to ensure the deferred images are connected.
1260 BdsLibConnectAllDefaultConsoles ();
1261 PlatformBdsConnectSequence ();
1266 // Close boot script and install ready to lock
1268 InstallReadyToLock ();
1271 // Notes: current time out = 0 can not enter the
1274 PlatformBdsEnterFrontPageWithHotKey (Timeout
, FALSE
);
1277 // Check the boot option with the boot option list
1279 BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
1282 case BOOT_ON_FLASH_UPDATE
:
1285 // Boot with the specific configuration
1287 PlatformBdsConnectConsole (gPlatformConsole
);
1288 PlatformBdsDiagnostics (EXTENSIVE
, FALSE
, BaseMemoryTest
);
1289 BdsLibConnectAll ();
1292 // Perform user identification
1294 if (mCurrentUser
== NULL
) {
1295 PlatformBdsUserIdentify (&mCurrentUser
, &DeferredImageExist
);
1296 if (DeferredImageExist
) {
1298 // After user authentication, the deferred drivers was loaded again.
1299 // Here, need to ensure the deferred images are connected.
1301 BdsLibConnectAll ();
1306 // Close boot script and install ready to lock
1308 InstallReadyToLock ();
1310 ProcessCapsules (BOOT_ON_FLASH_UPDATE
);
1313 case BOOT_IN_RECOVERY_MODE
:
1316 // In recovery mode, just connect platform console
1317 // and show up the front page
1319 PlatformBdsConnectConsole (gPlatformConsole
);
1320 PlatformBdsDiagnostics (EXTENSIVE
, FALSE
, BaseMemoryTest
);
1321 BdsLibConnectAll ();
1324 // Perform user identification
1326 if (mCurrentUser
== NULL
) {
1327 PlatformBdsUserIdentify (&mCurrentUser
, &DeferredImageExist
);
1328 if (DeferredImageExist
) {
1330 // After user authentication, the deferred drivers was loaded again.
1331 // Here, need to ensure the deferred drivers are connected.
1333 BdsLibConnectAll ();
1338 // Close boot script and install ready to lock
1340 InstallReadyToLock ();
1343 // In recovery boot mode, we still enter to the
1346 PlatformBdsEnterFrontPageWithHotKey (Timeout
, FALSE
);
1350 case BOOT_WITH_FULL_CONFIGURATION
:
1351 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS
:
1352 case BOOT_WITH_DEFAULT_SETTINGS
:
1356 // Connect platform console
1358 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
1359 if (EFI_ERROR (Status
)) {
1362 // Here OEM/IBV can customize with defined action
1364 PlatformBdsNoConsoleAction ();
1368 // Chenyunh[TODO]: This is Workgroud to show the fs for uSDcard,
1369 // Need to root cause this issue.
1371 DEBUG ((DEBUG_ERROR
, "Start to reconnect all driver.\n"));
1372 BdsLibDisconnectAllEfi();
1373 BdsLibConnectAll ();
1374 DEBUG ((DEBUG_ERROR
, "End to reconnect all driver.\n"));
1377 // Perform some platform specific connect sequence
1379 PlatformBdsConnectSequence ();
1380 if (SystemConfiguration
.QuietBoot
) {
1381 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
1383 PlatformBdsDiagnostics (IGNORE
, FALSE
, BaseMemoryTest
);
1387 // Do a pre-delay so Hard Disk can spin up and see more logo.
1389 gBS
->Stall(SystemConfiguration
.HddPredelay
* 1000000);
1392 // Perform user identification
1394 if (mCurrentUser
== NULL
) {
1395 PlatformBdsUserIdentify (&mCurrentUser
, &DeferredImageExist
);
1396 if (DeferredImageExist
) {
1398 // After user authentication, the deferred drivers was loaded again.
1399 // Here, need to ensure the deferred drivers are connected.
1401 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
1402 if (EFI_ERROR (Status
)) {
1403 PlatformBdsNoConsoleAction ();
1405 PlatformBdsConnectSequence ();
1409 TcgPhysicalPresenceLibProcessRequest();
1413 // Close boot script and install ready to lock
1415 InstallReadyToLock ();
1418 // Give one chance to enter the setup if we
1419 // have the time out
1421 PlatformBdsEnterFrontPageWithHotKey (Timeout
, FALSE
);
1424 // Give one chance to enter the setup if we
1425 // select Gummiboot "Reboot Into Firmware Interface"
1427 BootIntoFirmwareInterface();
1430 // In default boot mode, always find all boot
1431 // option and do enumerate all the default boot option
1434 BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
1435 if (IsListEmpty(BootOptionList
)) {
1436 PlatformBdsPredictBootOption (BootOptionList
);
1443 // Here we have enough time to do the enumeration of boot device
1445 BdsLibEnumerateAllBootOption (BootOptionList
);
1450 IsFirstBoot
= PcdGetBool(PcdBootState
);
1452 PcdSetBool(PcdBootState
, FALSE
);
1459 Hook point after a boot attempt succeeds. We don't expect a boot option to
1460 return, so the UEFI 2.0 specification defines that you will default to an
1461 interactive mode and stop processing the BootOrder list in this case. This
1462 is alos a platform implementation and can be customized by IBV/OEM.
1464 @param Option Pointer to Boot Option that succeeded to boot.
1471 PlatformBdsBootSuccess (
1472 IN BDS_COMMON_OPTION
*Option
1478 // If Boot returned with EFI_SUCCESS and there is not in the boot device
1479 // select loop then we need to pop up a UI and wait for user input.
1481 TmpStr
= Option
->StatusString
;
1482 if (TmpStr
!= NULL
) {
1483 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1489 Hook point after a boot attempt fails.
1491 @param Option - Pointer to Boot Option that failed to boot.
1492 @param Status - Status returned from failed boot.
1493 @param ExitData - Exit data returned from failed boot.
1494 @param ExitDataSize - Exit data size returned from failed boot.
1501 PlatformBdsBootFail (
1502 IN BDS_COMMON_OPTION
*Option
,
1503 IN EFI_STATUS Status
,
1504 IN CHAR16
*ExitData
,
1505 IN UINTN ExitDataSize
1509 EFI_HANDLE FvProtocolHandle
;
1512 // If Boot returned with failed status then we need to pop up a UI and wait
1515 TmpStr
= Option
->StatusString
;
1516 if (TmpStr
!= NULL
) {
1517 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1520 if (PcdGet32(PcdFlashFvShellSize
) > 0){
1521 gDS
->ProcessFirmwareVolume (
1522 (VOID
*)(UINTN
)PcdGet32(PcdFlashFvShellBase
),
1523 PcdGet32(PcdFlashFvShellSize
),
1527 PlatformBdsConnectSequence ();
1531 This function is remained for IBV/OEM to do some platform action,
1532 if there no console device can be connected.
1536 @retval EFI_SUCCESS Direct return success now.
1540 PlatformBdsNoConsoleAction (
1548 This function locks the block
1550 @param Base The base address flash region to be locked.
1555 IN EFI_PHYSICAL_ADDRESS Base
1558 EFI_FV_BLOCK_MAP_ENTRY
*BlockMap
;
1559 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
1560 EFI_PHYSICAL_ADDRESS BaseAddress
;
1565 BaseAddress
= Base
- 0x400000 + 2;
1566 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINTN
) (Base
));
1567 BlockMap
= &(FvHeader
->BlockMap
[0]);
1569 while ((BlockMap
->NumBlocks
!= 0) && (BlockMap
->Length
!= 0)) {
1570 BlockLength
= BlockMap
->Length
;
1571 for (Index
= 0; Index
< BlockMap
->NumBlocks
; Index
++) {
1572 Data
= MmioOr8 ((UINTN
) BaseAddress
, 0x03);
1573 BaseAddress
+= BlockLength
;
1581 PlatformBdsLockNonUpdatableFlash (
1585 EFI_PHYSICAL_ADDRESS Base
;
1587 Base
= (EFI_PHYSICAL_ADDRESS
) PcdGet32 (PcdFlashFvMainBase
);
1592 Base
= (EFI_PHYSICAL_ADDRESS
) PcdGet32 (PcdFlashFvRecoveryBase
);
1599 Lock the ConsoleIn device in system table. All key
1600 presses will be ignored until the Password is typed in. The only way to
1601 disable the password is to type it in to a ConIn device.
1603 @param Password Password used to lock ConIn device.
1605 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
1606 @retval EFI_UNSUPPORTED Password not found
1615 return EFI_UNSUPPORTED
;
1619 Connect the predefined platform default authentication devices.
1621 This function connects the predefined device path for authentication device,
1622 and if the predefined device path has child device path, the child handle will
1623 be connected too. But the child handle of the child will not be connected.
1628 PlatformBdsConnectAuthDevice (
1636 EFI_HANDLE
*HandleBuffer
;
1637 EFI_DEVICE_PATH_PROTOCOL
*ChildDevicePath
;
1638 EFI_USER_MANAGER_PROTOCOL
*Manager
;
1640 Status
= gBS
->LocateProtocol (
1641 &gEfiUserManagerProtocolGuid
,
1645 if (EFI_ERROR (Status
)) {
1647 // As user manager protocol is not installed, the authentication devices
1648 // should not be connected.
1654 while (gUserAuthenticationDevice
[Index
] != NULL
) {
1656 // Connect the platform customized device paths
1658 BdsLibConnectDevicePath (gUserAuthenticationDevice
[Index
]);
1663 // Find and connect the child device paths of the platform customized device paths
1665 HandleBuffer
= NULL
;
1666 for (Index
= 0; gUserAuthenticationDevice
[Index
] != NULL
; Index
++) {
1668 Status
= gBS
->LocateHandleBuffer (
1675 ASSERT (!EFI_ERROR (Status
));
1678 // Find and connect the child device paths of gUserIdentificationDevice[Index]
1680 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
1681 ChildDevicePath
= NULL
;
1682 Status
= gBS
->HandleProtocol (
1683 HandleBuffer
[HandleIndex
],
1684 &gEfiDevicePathProtocolGuid
,
1685 (VOID
**) &ChildDevicePath
1687 if (EFI_ERROR (Status
) || ChildDevicePath
== NULL
) {
1693 gUserAuthenticationDevice
[Index
],
1694 (GetDevicePathSize (gUserAuthenticationDevice
[Index
]) - sizeof (EFI_DEVICE_PATH_PROTOCOL
))
1698 gBS
->ConnectController (
1699 HandleBuffer
[HandleIndex
],
1707 if (HandleBuffer
!= NULL
) {
1708 FreePool (HandleBuffer
);
1713 This function is to identify a user, and return whether deferred images exist.
1715 @param[out] User Point to user profile handle.
1716 @param[out] DeferredImageExist On return, points to TRUE if the deferred image
1717 exist or FALSE if it did not exist.
1722 PlatformBdsUserIdentify (
1723 OUT EFI_USER_PROFILE_HANDLE
*User
,
1724 OUT BOOLEAN
*DeferredImageExist
1728 EFI_DEFERRED_IMAGE_LOAD_PROTOCOL
*DeferredImage
;
1730 EFI_HANDLE
*HandleBuf
;
1733 EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
;
1739 // Perform user identification
1742 Status
= BdsLibUserIdentify (User
);
1743 } while (EFI_ERROR (Status
));
1746 // After user authentication now, try to find whether deferred image exists
1750 *DeferredImageExist
= FALSE
;
1751 Status
= gBS
->LocateHandleBuffer (
1753 &gEfiDeferredImageLoadProtocolGuid
,
1758 if (EFI_ERROR (Status
)) {
1762 for (Index
= 0; Index
< HandleCount
; Index
++) {
1763 Status
= gBS
->HandleProtocol (
1765 &gEfiDeferredImageLoadProtocolGuid
,
1766 (VOID
**) &DeferredImage
1768 if (!EFI_ERROR (Status
)) {
1770 // Find whether deferred image exists in this instance.
1773 Status
= DeferredImage
->GetImageInfo(
1777 (VOID
**) &DriverImage
,
1781 if (!EFI_ERROR (Status
)) {
1783 // The deferred image is found.
1785 FreePool (HandleBuf
);
1786 *DeferredImageExist
= TRUE
;
1792 FreePool (HandleBuf
);
1799 ShowProgressHotKey (
1800 IN UINT16 TimeoutDefault
1804 UINT16 TimeoutRemain
;
1807 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
1808 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
1809 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
1812 if (TimeoutDefault
== 0) {
1816 if (DebugAssertEnabled())
1818 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"));
1823 SerialPortWrite((UINT8
*)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)[GCC]", 76);
1825 SerialPortWrite((UINT8
*)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)", 71);
1828 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
1829 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
1830 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
1833 // Clear the progress status bar first
1835 TmpStr
= L
"Start boot option, Press <F2> or <DEL> to enter setup page.";
1836 PlatformBdsShowProgress (Foreground
, Background
, TmpStr
, Color
, 0, 0);
1838 TimeoutRemain
= TimeoutDefault
;
1839 while (TimeoutRemain
!= 0) {
1840 if (DebugAssertEnabled())
1842 DEBUG ((EFI_D_INFO
, "Showing progress bar...Remaining %d second!\n", TimeoutRemain
));
1846 SerialPortWrite ((UINT8
*)".", 1);
1848 Status
= WaitForSingleEvent (gST
->ConIn
->WaitForKey
, ONE_SECOND
);
1849 if (Status
!= EFI_TIMEOUT
) {
1857 if (TmpStr
!= NULL
) {
1858 PlatformBdsShowProgress (
1863 ((TimeoutDefault
- TimeoutRemain
) * 100 / TimeoutDefault
),
1872 if (TimeoutRemain
== 0) {
1873 if (DebugAssertEnabled())
1878 SerialPortWrite ((UINT8
*)"\r\n", 2);
1884 // User pressed some key
1886 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
1887 if (EFI_ERROR (Status
)) {
1892 // Check Volume Up Key to enter Setup
1894 GpioValue
= MmioRead32 (IO_BASE_ADDRESS
+ 0x0668); // The value of GPIOC_5
1895 if (((GpioValue
& BIT0
) == 0) && (Key
.ScanCode
== SCAN_UP
)) {
1900 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1902 // User pressed enter, equivalent to select "continue"
1909 //F5 -- Device Manager
1910 //F7 -- Boot Manager
1911 // do not use F8. generally people assume it is windows safe mode key.
1914 DEBUG ((EFI_D_INFO
, "[Key Pressed]: ScanCode 0x%x\n", Key
.ScanCode
));
1915 switch(Key
.ScanCode
) {
1925 gHotKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
1929 gHotKey
= FRONT_PAGE_KEY_BOOT_MANAGER
;
1933 gHotKey
= FRONT_PAGE_KEY_BOOT_MAINTAIN
;
1937 //set gHotKey to continue so that flow will not go into CallFrontPage
1938 gHotKey
= FRONT_PAGE_KEY_CONTINUE
;
1949 This function is the main entry of the platform setup entry.
1950 The function will present the main menu of the system setup,
1951 this is the platform reference part and can be customize.
1954 @param TimeoutDefault The fault time out value before the system
1956 @param ConnectAllHappened The indicater to check if the connect all have
1961 PlatformBdsEnterFrontPageWithHotKey (
1962 IN UINT16 TimeoutDefault
,
1963 IN BOOLEAN ConnectAllHappened
1968 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1969 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOut
;
1970 UINTN BootTextColumn
;
1973 GraphicsOutput
= NULL
;
1974 SimpleTextOut
= NULL
;
1976 PERF_START (NULL
, "BdsTimeOut", "BDS", 0);
1979 // Indicate if we need connect all in the platform setup
1981 if (ConnectAllHappened
) {
1982 gConnectAllHappened
= TRUE
;
1985 if (!mModeInitialized
) {
1987 // After the console is ready, get current video resolution
1988 // and text mode before launching setup at first time.
1990 Status
= gBS
->HandleProtocol (
1991 gST
->ConsoleOutHandle
,
1992 &gEfiGraphicsOutputProtocolGuid
,
1993 (VOID
**)&GraphicsOutput
1995 if (EFI_ERROR (Status
)) {
1996 GraphicsOutput
= NULL
;
1999 Status
= gBS
->HandleProtocol (
2000 gST
->ConsoleOutHandle
,
2001 &gEfiSimpleTextOutProtocolGuid
,
2002 (VOID
**)&SimpleTextOut
2004 if (EFI_ERROR (Status
)) {
2005 SimpleTextOut
= NULL
;
2008 if (GraphicsOutput
!= NULL
) {
2010 // Get current video resolution and text mode.
2012 mBootHorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
2013 mBootVerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
2016 if (SimpleTextOut
!= NULL
) {
2017 Status
= SimpleTextOut
->QueryMode (
2019 SimpleTextOut
->Mode
->Mode
,
2023 mBootTextModeColumn
= (UINT32
)BootTextColumn
;
2024 mBootTextModeRow
= (UINT32
)BootTextRow
;
2028 // Get user defined text mode for setup.
2030 mSetupHorizontalResolution
= PcdGet32 (PcdSetupVideoHorizontalResolution
);
2031 mSetupVerticalResolution
= PcdGet32 (PcdSetupVideoVerticalResolution
);
2032 mSetupTextModeColumn
= PcdGet32 (PcdSetupConOutColumn
);
2033 mSetupTextModeRow
= PcdGet32 (PcdSetupConOutRow
);
2035 mModeInitialized
= TRUE
;
2038 if (TimeoutDefault
!= 0xffff) {
2039 Status
= ShowProgressHotKey (TimeoutDefault
);
2042 // Ensure screen is clear when switch Console from Graphics mode to Text mode
2044 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);
2045 gST
->ConOut
->ClearScreen (gST
->ConOut
);
2047 if (EFI_ERROR (Status
)) {
2049 // Timeout or user press enter to continue
2055 // Install BM HiiPackages.
2056 // Keep BootMaint HiiPackage, so that it can be covered by global setting.
2061 BdsSetConsoleMode (TRUE
);
2063 InitializeFrontPage (FALSE
);
2066 // Update Front Page strings
2068 UpdateFrontPageStrings ();
2070 Status
= EFI_SUCCESS
;
2073 Status
= CallFrontPage ();
2075 gCallbackKey
= gHotKey
;
2080 // If gCallbackKey is greater than 1 and less or equal to 5,
2081 // it will launch configuration utilities.
2084 // 4 = device manager
2085 // 5 = boot maintenance manager
2087 if (gCallbackKey
!= 0) {
2088 REPORT_STATUS_CODE (
2090 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_USER_SETUP
)
2095 // Based on the key that was set, we can determine what to do
2097 switch (gCallbackKey
) {
2099 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
2100 // describe to their customers in documentation how to find their setup information (namely
2101 // under the device manager and specific buckets)
2103 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
2105 case FRONT_PAGE_KEY_CONTINUE
:
2108 // User hit continue
2112 case FRONT_PAGE_KEY_LANGUAGE
:
2115 // User made a language setting change - display front page again
2119 case FRONT_PAGE_KEY_BOOT_MANAGER
:
2121 // Remove the installed BootMaint HiiPackages when exit.
2126 // User chose to run the Boot Manager
2131 // Reinstall BootMaint HiiPackages after exiting from Boot Manager.
2136 case FRONT_PAGE_KEY_DEVICE_MANAGER
:
2139 // Display the Device Manager
2142 CallDeviceManager ();
2143 } while (gCallbackKey
== FRONT_PAGE_KEY_DEVICE_MANAGER
);
2146 case FRONT_PAGE_KEY_BOOT_MAINTAIN
:
2149 // Display the Boot Maintenance Manager
2151 BdsStartBootMaint ();
2155 } while (((UINTN
)gCallbackKey
) != FRONT_PAGE_KEY_CONTINUE
);
2158 //Will leave browser, check any reset required change is applied? if yes, reset system
2160 SetupResetReminder ();
2162 // Remove the installed BootMaint HiiPackages when exit.
2168 // Automatically load current entry
2169 // Note: The following lines of code only execute when Auto boot
2172 PERF_END (NULL
, "BdsTimeOut", "BDS", 0);
2177 BootIntoFirmwareInterface(
2184 UINT64 OsIndication
;
2188 DataSize
= sizeof(UINT64
);
2189 Status
= gRT
->GetVariable (
2191 &gEfiGlobalVariableGuid
,
2197 DEBUG ((EFI_D_INFO
, "OSIndication Variable Value %d\n", OsIndication
));
2199 //Goto FrontPage directly when bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted.
2201 if (!EFI_ERROR(Status
) && (OsIndication
!= 0)) {
2203 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
2209 PlatformBdsConnectSimpleConsole (
2210 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
2215 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
2216 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
2217 UINTN DevicePathSize
;
2221 Status
= EFI_SUCCESS
;
2223 VarConout
= BdsLibGetVariableAndSize (
2225 &gEfiGlobalVariableGuid
,
2228 VarConin
= BdsLibGetVariableAndSize (
2230 &gEfiGlobalVariableGuid
,
2233 if (VarConout
== NULL
|| VarConin
== NULL
) {
2235 // Have chance to connect the platform default console,
2236 // the platform default console is the minimue device group
2237 // the platform should support
2239 while (PlatformConsole
[Index
].DevicePath
!= NULL
) {
2242 // Update the console variable with the connect type
2244 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
2245 BdsLibUpdateConsoleVariable (L
"ConIn", PlatformConsole
[Index
].DevicePath
, NULL
);
2248 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
2249 BdsLibUpdateConsoleVariable (L
"ConOut", PlatformConsole
[Index
].DevicePath
, NULL
);
2252 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
2253 BdsLibUpdateConsoleVariable (L
"ErrOut", PlatformConsole
[Index
].DevicePath
, NULL
);
2261 // Connect ConIn first to give keyboard time to parse hot key event.
2263 Status
= BdsLibConnectConsoleVariable (L
"ConIn");
2264 if (EFI_ERROR (Status
)) {
2269 // Make sure we have at least one active VGA, and have the right
2270 // active VGA in console variable
2272 Status
= PlatformBdsForceActiveVga ();
2275 // It seems impossible not to have any ConOut device on platform,
2276 // so we check the status here.
2278 Status
= BdsLibConnectConsoleVariable (L
"ConOut");
2279 if (EFI_ERROR (Status
)) {
2288 Timer handler to convert the key from USB.
2290 @param Event Indicates the event that invoke this function.
2291 @param Context Indicates the calling context.
2295 HotKeyTimerHandler (
2303 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
2304 if (EFI_ERROR (Status
)) {
2308 switch(Key
.ScanCode
) {
2311 mHotKeyPressed
= TRUE
;
2315 gHotKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
2316 mHotKeyPressed
= TRUE
;
2320 gHotKey
= FRONT_PAGE_KEY_BOOT_MANAGER
;
2321 mHotKeyPressed
= TRUE
;
2325 gHotKey
= FRONT_PAGE_KEY_BOOT_MAINTAIN
;
2326 mHotKeyPressed
= TRUE
;
2330 if (mHotKeyPressed
) {
2336 gBS
->CloseEvent (mHotKeyTimerEvent
);
2337 mHotKeyTimerEvent
= NULL
;
2345 Callback function for SimpleTextInEx protocol install events
2347 @param Event the event that is signaled.
2348 @param Context not used here.
2360 Status
= gBS
->CloseEvent(mHitHotkeyEvent
);
2361 if (EFI_ERROR (Status
)) {
2364 Status
= gBS
->CreateEvent (
2365 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
2371 if (EFI_ERROR (Status
)) {
2374 Status
= gBS
->SetTimer (
2377 KEYBOARD_TIMER_INTERVAL
2379 if (EFI_ERROR (Status
)) {
2389 PlatformBdsInitHotKeyEvent (
2396 // Register Protocol notify for Hotkey service
2398 Status
= gBS
->CreateEvent (
2405 ASSERT_EFI_ERROR (Status
);
2408 // Register for protocol notifications on this event
2410 Status
= gBS
->RegisterProtocolNotify (
2411 &gEfiSimpleTextInputExProtocolGuid
,
2413 &mHitHotkeyRegistration
2415 ASSERT_EFI_ERROR (Status
);