2 This file include all platform action which can be customized
5 Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "PlatformBootManager.h"
11 #include "PlatformConsole.h"
12 #include <Guid/BootManagerMenu.h>
13 #include <Library/HobLib.h>
16 Signal EndOfDxe event and install SMM Ready to lock protocol.
26 EFI_SMM_ACCESS2_PROTOCOL
*SmmAccess
;
28 DEBUG ((DEBUG_INFO
, "InstallReadyToLock entering......\n"));
30 // Inform the SMM infrastructure that we're entering BDS and may run 3rd party code hereafter
31 // Since PI1.2.1, we need signal EndOfDxe as ExitPmAuth
33 EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid
);
34 DEBUG ((DEBUG_INFO
, "All EndOfDxe callbacks have returned successfully\n"));
37 // Install DxeSmmReadyToLock protocol in order to lock SMM
39 Status
= gBS
->LocateProtocol (&gEfiSmmAccess2ProtocolGuid
, NULL
, (VOID
**)&SmmAccess
);
40 if (!EFI_ERROR (Status
)) {
42 Status
= gBS
->InstallProtocolInterface (
44 &gEfiDxeSmmReadyToLockProtocolGuid
,
48 ASSERT_EFI_ERROR (Status
);
51 DEBUG ((DEBUG_INFO
, "InstallReadyToLock end\n"));
56 Return the index of the load option in the load option array.
58 The function consider two load options are equal when the
59 OptionType, Attributes, Description, FilePath and OptionalData are equal.
61 @param Key Pointer to the load option to be found.
62 @param Array Pointer to the array of load options to be found.
63 @param Count Number of entries in the Array.
65 @retval -1 Key wasn't found in the Array.
66 @retval 0 ~ Count-1 The index of the Key in the Array.
69 PlatformFindLoadOption (
70 IN CONST EFI_BOOT_MANAGER_LOAD_OPTION
*Key
,
71 IN CONST EFI_BOOT_MANAGER_LOAD_OPTION
*Array
,
77 for (Index
= 0; Index
< Count
; Index
++) {
78 if ((Key
->OptionType
== Array
[Index
].OptionType
) &&
79 (Key
->Attributes
== Array
[Index
].Attributes
) &&
80 (StrCmp (Key
->Description
, Array
[Index
].Description
) == 0) &&
81 (CompareMem (Key
->FilePath
, Array
[Index
].FilePath
, GetDevicePathSize (Key
->FilePath
)) == 0) &&
82 (Key
->OptionalDataSize
== Array
[Index
].OptionalDataSize
) &&
83 (CompareMem (Key
->OptionalData
, Array
[Index
].OptionalData
, Key
->OptionalDataSize
) == 0))
93 Register a boot option using a file GUID in the FV.
95 @param FileGuid The file GUID name in FV.
96 @param Description The boot option description.
97 @param Attributes The attributes used for the boot option loading.
100 PlatformRegisterFvBootOption (
108 EFI_BOOT_MANAGER_LOAD_OPTION NewOption
;
109 EFI_BOOT_MANAGER_LOAD_OPTION
*BootOptions
;
110 UINTN BootOptionCount
;
111 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode
;
112 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
113 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
115 Status
= gBS
->HandleProtocol (gImageHandle
, &gEfiLoadedImageProtocolGuid
, (VOID
**)&LoadedImage
);
116 ASSERT_EFI_ERROR (Status
);
118 EfiInitializeFwVolDevicepathNode (&FileNode
, FileGuid
);
119 DevicePath
= AppendDevicePathNode (
120 DevicePathFromHandle (LoadedImage
->DeviceHandle
),
121 (EFI_DEVICE_PATH_PROTOCOL
*)&FileNode
124 Status
= EfiBootManagerInitializeLoadOption (
126 LoadOptionNumberUnassigned
,
134 if (!EFI_ERROR (Status
)) {
135 BootOptions
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
137 OptionIndex
= PlatformFindLoadOption (&NewOption
, BootOptions
, BootOptionCount
);
139 if (OptionIndex
== -1) {
140 Status
= EfiBootManagerAddLoadOptionVariable (&NewOption
, (UINTN
)-1);
141 ASSERT_EFI_ERROR (Status
);
144 EfiBootManagerFreeLoadOption (&NewOption
);
145 EfiBootManagerFreeLoadOptions (BootOptions
, BootOptionCount
);
150 Do the platform specific action before the console is connected.
153 Update console variable;
154 Register new Driver#### or Boot####;
155 Signal ReadyToLock event.
159 PlatformBootManagerBeforeConsole (
164 EFI_INPUT_KEY CustomKey
;
166 EFI_BOOT_MANAGER_LOAD_OPTION BootOption
;
169 // Register ENTER as CONTINUE key
171 Enter
.ScanCode
= SCAN_NULL
;
172 Enter
.UnicodeChar
= CHAR_CARRIAGE_RETURN
;
173 EfiBootManagerRegisterContinueKeyOption (0, &Enter
, NULL
);
175 if (FixedPcdGetBool (PcdBootManagerEscape
)) {
177 // Map Esc to Boot Manager Menu
179 CustomKey
.ScanCode
= SCAN_ESC
;
180 CustomKey
.UnicodeChar
= CHAR_NULL
;
183 // Map Esc to Boot Manager Menu
185 CustomKey
.ScanCode
= SCAN_F2
;
186 CustomKey
.UnicodeChar
= CHAR_NULL
;
189 EfiBootManagerGetBootManagerMenu (&BootOption
);
190 EfiBootManagerAddKeyOptionVariable (NULL
, (UINT16
)BootOption
.OptionNumber
, 0, &CustomKey
, NULL
);
193 // Also add Down key to Boot Manager Menu since some serial terminals don't support F2 key.
195 Down
.ScanCode
= SCAN_DOWN
;
196 Down
.UnicodeChar
= CHAR_NULL
;
197 EfiBootManagerGetBootManagerMenu (&BootOption
);
198 EfiBootManagerAddKeyOptionVariable (NULL
, (UINT16
)BootOption
.OptionNumber
, 0, &Down
, NULL
);
201 // Install ready to lock.
202 // This needs to be done before option rom dispatched.
204 InstallReadyToLock ();
207 // Dispatch deferred images after EndOfDxe event and ReadyToLock installation.
209 EfiBootManagerDispatchDeferredImages ();
211 PlatformConsoleInit ();
215 Do the platform specific action after the console is connected.
218 Dynamically switch output mode;
219 Signal console ready platform customized event;
220 Run diagnostics like memory testing;
221 Connect certain devices;
222 Dispatch additional option roms.
226 PlatformBootManagerAfterConsole (
230 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black
;
231 EFI_GRAPHICS_OUTPUT_BLT_PIXEL White
;
232 EDKII_PLATFORM_LOGO_PROTOCOL
*PlatformLogo
;
235 Black
.Blue
= Black
.Green
= Black
.Red
= Black
.Reserved
= 0;
236 White
.Blue
= White
.Green
= White
.Red
= White
.Reserved
= 0xFF;
238 Status
= gBS
->LocateProtocol (&gEdkiiPlatformLogoProtocolGuid
, NULL
, (VOID
**)&PlatformLogo
);
240 if (!EFI_ERROR (Status
)) {
241 gST
->ConOut
->ClearScreen (gST
->ConOut
);
242 BootLogoEnableLogo ();
245 EfiBootManagerConnectAll ();
246 EfiBootManagerRefreshAllBootOption ();
249 // Register UEFI Shell
251 PlatformRegisterFvBootOption (PcdGetPtr (PcdShellFile
), L
"UEFI Shell", LOAD_OPTION_ACTIVE
);
253 if (FixedPcdGetBool (PcdBootManagerEscape
)) {
256 L
" Esc or Down to enter Boot Manager Menu.\n"
257 L
" ENTER to boot directly.\n"
263 L
" F2 or Down to enter Boot Manager Menu.\n"
264 L
" ENTER to boot directly.\n"
271 This function is called each second during the boot manager waits the timeout.
273 @param TimeoutRemain The remaining timeout.
277 PlatformBootManagerWaitCallback (
285 The function is called when no boot option could be launched,
286 including platform recovery options and options pointing to applications
287 built into firmware volumes.
289 If this function returns, BDS attempts to enter an infinite loop.
293 PlatformBootManagerUnableToBoot (
301 Get/update PcdBootManagerMenuFile from GUID HOB which will be assigned in bootloader.
303 @param ImageHandle The firmware allocated handle for the EFI image.
304 @param SystemTable A pointer to the EFI System Table.
306 @retval EFI_SUCCESS The entry point is executed successfully.
307 @retval other Some error occurs.
312 PlatformBootManagerLibConstructor (
313 IN EFI_HANDLE ImageHandle
,
314 IN EFI_SYSTEM_TABLE
*SystemTable
320 UNIVERSAL_PAYLOAD_GENERIC_HEADER
*GenericHeader
;
321 UNIVERSAL_PAYLOAD_BOOT_MANAGER_MENU
*BootManagerMenuFile
;
323 GuidHob
= GetFirstGuidHob (&gEdkiiBootManagerMenuFileGuid
);
325 if (GuidHob
== NULL
) {
327 // If the HOB is not create, the default value of PcdBootManagerMenuFile will be used.
332 GenericHeader
= (UNIVERSAL_PAYLOAD_GENERIC_HEADER
*)GET_GUID_HOB_DATA (GuidHob
);
333 if ((sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER
) > GET_GUID_HOB_DATA_SIZE (GuidHob
)) || (GenericHeader
->Length
> GET_GUID_HOB_DATA_SIZE (GuidHob
))) {
334 return EFI_NOT_FOUND
;
337 if (GenericHeader
->Revision
== UNIVERSAL_PAYLOAD_BOOT_MANAGER_MENU_REVISION
) {
338 BootManagerMenuFile
= (UNIVERSAL_PAYLOAD_BOOT_MANAGER_MENU
*)GET_GUID_HOB_DATA (GuidHob
);
339 if (BootManagerMenuFile
->Header
.Length
< UNIVERSAL_PAYLOAD_SIZEOF_THROUGH_FIELD (UNIVERSAL_PAYLOAD_BOOT_MANAGER_MENU
, FileName
)) {
340 return EFI_NOT_FOUND
;
343 Size
= sizeof (BootManagerMenuFile
->FileName
);
344 Status
= PcdSetPtrS (PcdBootManagerMenuFile
, &Size
, &BootManagerMenuFile
->FileName
);
345 ASSERT_EFI_ERROR (Status
);
347 return EFI_NOT_FOUND
;