2 This file include all platform action which can be customized
5 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
6 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "PlatformBootManager.h"
19 EFI_GUID mBootMenuFile
= {
20 0xEEC25BDC, 0x67F2, 0x4D95, { 0xB1, 0xD5, 0xF8, 0x1B, 0x20, 0x39, 0xD1, 0x1D }
24 Perform the platform diagnostic, such like test memory. OEM/IBV also
25 can customize this function to support specific platform diagnostic.
27 @param MemoryTestLevel The memory test intensive level
28 @param QuietBoot Indicate if need to enable the quiet boot
32 PlatformBootManagerDiagnostics (
33 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
40 // Here we can decide if we need to show
41 // the diagnostics screen
42 // Notes: this quiet boot code should be remove
43 // from the graphic lib
46 BootLogoEnableLogo ();
49 // Perform system diagnostic
51 Status
= PlatformBootManagerMemoryTest (MemoryTestLevel
);
52 if (EFI_ERROR (Status
)) {
53 BootLogoDisableLogo ();
60 // Perform system diagnostic
62 Status
= PlatformBootManagerMemoryTest (MemoryTestLevel
);
66 Do the platform specific action before the console is connected.
69 Update console variable;
70 Register new Driver#### or Boot####;
71 Signal ReadyToLock event.
75 PlatformBootManagerBeforeConsole (
81 WIN_NT_SYSTEM_CONFIGURATION
*Configuration
;
83 GetVariable2 (L
"Setup", &gEfiWinNtSystemConfigGuid
, (VOID
**) &Configuration
, NULL
);
84 if (Configuration
!= NULL
) {
86 // SetupVariable is corrupt
88 Configuration
->ConOutRow
= PcdGet32 (PcdConOutColumn
);
89 Configuration
->ConOutColumn
= PcdGet32 (PcdConOutRow
);
91 Status
= gRT
->SetVariable (
93 &gEfiWinNtSystemConfigGuid
,
94 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
95 sizeof (WIN_NT_SYSTEM_CONFIGURATION
),
98 if (EFI_ERROR (Status
)) {
99 DEBUG ((EFI_D_ERROR
, "Failed to save Setup Variable to non-volatile storage, Status = %r\n", Status
));
101 FreePool (Configuration
);
105 // Update the ocnsole variables.
107 for (Index
= 0; gPlatformConsole
[Index
].DevicePath
!= NULL
; Index
++) {
108 if ((gPlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
109 EfiBootManagerUpdateConsoleVariable (ConIn
, gPlatformConsole
[Index
].DevicePath
, NULL
);
112 if ((gPlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
113 EfiBootManagerUpdateConsoleVariable (ConOut
, gPlatformConsole
[Index
].DevicePath
, NULL
);
116 if ((gPlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
117 EfiBootManagerUpdateConsoleVariable (ErrOut
, gPlatformConsole
[Index
].DevicePath
, NULL
);
122 // From PI spec vol2:
123 // Prior to invoking any UEFI drivers, applications, or connecting consoles,
124 // the platform should signal the event EFI_END_OF_DXE_EVENT_GUID
126 EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid
);
129 // Dispatch deferred images after EndOfDxe event.
131 EfiBootManagerDispatchDeferredImages ();
135 Returns the priority number.
141 CONST EFI_BOOT_MANAGER_LOAD_OPTION
*BootOption
145 // Make sure Shell is first
147 if (StrCmp (BootOption
->Description
, L
"UEFI Shell") == 0) {
156 CONST EFI_BOOT_MANAGER_LOAD_OPTION
*Left
,
157 CONST EFI_BOOT_MANAGER_LOAD_OPTION
*Right
160 return BootOptionPriority (Left
) - BootOptionPriority (Right
);
164 Generate device path include the input file guid info.
166 @param FileGuid Input file guid for the BootManagerMenuApp.
168 @retval DevicePath for BootManagerMenuApp.
177 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
178 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode
;
180 EfiInitializeFwVolDevicepathNode (&FileNode
, FileGuid
);
182 Status
= gBS
->HandleProtocol (
184 &gEfiLoadedImageProtocolGuid
,
185 (VOID
**) &LoadedImage
187 ASSERT_EFI_ERROR (Status
);
189 return AppendDevicePathNode (
190 DevicePathFromHandle (LoadedImage
->DeviceHandle
),
191 (EFI_DEVICE_PATH_PROTOCOL
*) &FileNode
196 Create one boot option for BootManagerMenuApp.
198 @param FileGuid Input file guid for the BootManagerMenuApp.
199 @param Description Description of the BootManagerMenuApp boot option.
200 @param Position Position of the new load option to put in the ****Order variable.
201 @param IsBootCategory Whether this is a boot category.
204 @retval OptionNumber Return the option number info.
208 RegisterBootManagerMenuAppBootOption (
212 BOOLEAN IsBootCategory
216 EFI_BOOT_MANAGER_LOAD_OPTION NewOption
;
217 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
220 DevicePath
= FvFilePath (FileGuid
);
221 Status
= EfiBootManagerInitializeLoadOption (
223 LoadOptionNumberUnassigned
,
225 IsBootCategory
? LOAD_OPTION_ACTIVE
: LOAD_OPTION_CATEGORY_APP
,
231 ASSERT_EFI_ERROR (Status
);
232 FreePool (DevicePath
);
234 Status
= EfiBootManagerAddLoadOptionVariable (&NewOption
, Position
);
235 ASSERT_EFI_ERROR (Status
);
237 OptionNumber
= NewOption
.OptionNumber
;
239 EfiBootManagerFreeLoadOption (&NewOption
);
245 Check if it's a Device Path pointing to BootManagerMenuApp.
247 @param DevicePath Input device path.
249 @retval TRUE The device path is BootManagerMenuApp File Device Path.
250 @retval FALSE The device path is NOT BootManagerMenuApp File Device Path.
253 IsBootManagerMenuAppFilePath (
254 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
261 Status
= gBS
->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid
, &DevicePath
, &FvHandle
);
262 if (!EFI_ERROR (Status
)) {
263 NameGuid
= EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) DevicePath
);
264 if (NameGuid
!= NULL
) {
265 return CompareGuid (NameGuid
, &mBootMenuFile
);
273 Return the boot option number to the BootManagerMenuApp.
275 If not found it in the current boot option, create a new one.
277 @retval OptionNumber Return the boot option number to the BootManagerMenuApp.
281 GetBootManagerMenuAppOption (
285 UINTN BootOptionCount
;
286 EFI_BOOT_MANAGER_LOAD_OPTION
*BootOptions
;
292 BootOptions
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
294 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
295 if (IsBootManagerMenuAppFilePath (BootOptions
[Index
].FilePath
)) {
296 OptionNumber
= BootOptions
[Index
].OptionNumber
;
301 EfiBootManagerFreeLoadOptions (BootOptions
, BootOptionCount
);
303 if (Index
>= BootOptionCount
) {
305 // If not found the BootManagerMenuApp, create it.
307 OptionNumber
= (UINT16
) RegisterBootManagerMenuAppBootOption (&mBootMenuFile
, L
"UEFI BootManagerMenuApp", (UINTN
) -1, FALSE
);
314 Do the platform specific action after the console is connected.
317 Dynamically switch output mode;
318 Signal console ready platform customized event;
319 Run diagnostics like memory testing;
320 Connect certain devices;
321 Dispatch aditional option roms.
325 PlatformBootManagerAfterConsole (
329 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black
;
330 EFI_GRAPHICS_OUTPUT_BLT_PIXEL White
;
334 EFI_BOOT_MANAGER_LOAD_OPTION BootOption
;
337 Black
.Blue
= Black
.Green
= Black
.Red
= Black
.Reserved
= 0;
338 White
.Blue
= White
.Green
= White
.Red
= White
.Reserved
= 0xFF;
340 EfiBootManagerConnectAll ();
341 EfiBootManagerRefreshAllBootOption ();
344 // Register ENTER as CONTINUE key
346 Enter
.ScanCode
= SCAN_NULL
;
347 Enter
.UnicodeChar
= CHAR_CARRIAGE_RETURN
;
348 EfiBootManagerRegisterContinueKeyOption (0, &Enter
, NULL
);
350 // Map F2 to Boot Manager Menu
352 F2
.ScanCode
= SCAN_F2
;
353 F2
.UnicodeChar
= CHAR_NULL
;
354 EfiBootManagerGetBootManagerMenu (&BootOption
);
355 EfiBootManagerAddKeyOptionVariable (NULL
, (UINT16
) BootOption
.OptionNumber
, 0, &F2
, NULL
);
358 // 3. Boot Device List menu
360 F7
.ScanCode
= SCAN_F7
;
361 F7
.UnicodeChar
= CHAR_NULL
;
362 OptionNumber
= GetBootManagerMenuAppOption ();
363 EfiBootManagerAddKeyOptionVariable (NULL
, (UINT16
)OptionNumber
, 0, &F7
, NULL
);
366 // Make Shell as the first boot option
368 EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot
, (SORT_COMPARE
) CompareBootOption
);
370 PlatformBootManagerDiagnostics (QUICK
, TRUE
);
372 PrintXY (10, 10, &White
, &Black
, L
"F2 to enter Setup. ");
373 PrintXY (10, 30, &White
, &Black
, L
"F7 to enter Boot Manager Menu.");
374 PrintXY (10, 50, &White
, &Black
, L
"Enter to boot directly.");
378 This function is called each second during the boot manager waits the timeout.
380 @param TimeoutRemain The remaining timeout.
384 PlatformBootManagerWaitCallback (
388 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black
;
389 EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White
;
392 Timeout
= PcdGet16 (PcdPlatformBootTimeOut
);
394 Black
.Raw
= 0x00000000;
395 White
.Raw
= 0x00FFFFFF;
397 BootLogoUpdateProgress (
400 L
"Start boot option",
402 (Timeout
- TimeoutRemain
) * 100 / Timeout
,
408 The function is called when no boot option could be launched,
409 including platform recovery options and options pointing to applications
410 built into firmware volumes.
412 If this function returns, BDS attempts to enter an infinite loop.
416 PlatformBootManagerUnableToBoot (