2 This file include all platform action which can be customized
5 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "PlatformBootManager.h"
18 EFI_GUID mUefiShellFileGuid
= {0x7C04A583, 0x9E3E, 0x4f1c, {0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }};
21 Return the index of the load option in the load option array.
23 The function consider two load options are equal when the
24 OptionType, Attributes, Description, FilePath and OptionalData are equal.
26 @param Key Pointer to the load option to be found.
27 @param Array Pointer to the array of load options to be found.
28 @param Count Number of entries in the Array.
30 @retval -1 Key wasn't found in the Array.
31 @retval 0 ~ Count-1 The index of the Key in the Array.
34 PlatformFindLoadOption (
35 IN CONST EFI_BOOT_MANAGER_LOAD_OPTION
*Key
,
36 IN CONST EFI_BOOT_MANAGER_LOAD_OPTION
*Array
,
42 for (Index
= 0; Index
< Count
; Index
++) {
43 if ((Key
->OptionType
== Array
[Index
].OptionType
) &&
44 (Key
->Attributes
== Array
[Index
].Attributes
) &&
45 (StrCmp (Key
->Description
, Array
[Index
].Description
) == 0) &&
46 (CompareMem (Key
->FilePath
, Array
[Index
].FilePath
, GetDevicePathSize (Key
->FilePath
)) == 0) &&
47 (Key
->OptionalDataSize
== Array
[Index
].OptionalDataSize
) &&
48 (CompareMem (Key
->OptionalData
, Array
[Index
].OptionalData
, Key
->OptionalDataSize
) == 0)) {
57 PlatformRegisterFvBootOption (
64 EFI_HANDLE
*HandleBuffer
;
67 EFI_FIRMWARE_VOLUME2_PROTOCOL
*Fv
;
69 UINTN UiSectionLength
;
70 UINT32 AuthenticationStatus
;
72 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode
;
73 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
74 EFI_BOOT_MANAGER_LOAD_OPTION
*BootOptions
;
75 UINTN BootOptionCount
;
77 EFI_BOOT_MANAGER_LOAD_OPTION NewOption
;
80 // Locate all available FVs.
83 Status
= gBS
->LocateHandleBuffer (
85 &gEfiFirmwareVolume2ProtocolGuid
,
90 if (EFI_ERROR (Status
)) {
95 // Go through FVs one by one to find the required FFS file
97 for (IndexFv
= 0, FvHandle
= NULL
; IndexFv
< HandleCount
&& FvHandle
== NULL
; IndexFv
++) {
98 Status
= gBS
->HandleProtocol (
99 HandleBuffer
[IndexFv
],
100 &gEfiFirmwareVolume2ProtocolGuid
,
103 if (EFI_ERROR (Status
)) {
108 // Attempt to read a EFI_SECTION_USER_INTERFACE section from the required FFS file
111 Status
= Fv
->ReadSection (
114 EFI_SECTION_USER_INTERFACE
,
116 (VOID
**) &UiSection
,
118 &AuthenticationStatus
120 if (EFI_ERROR (Status
)) {
123 FreePool (UiSection
);
126 // Save the handle of the FV where the FFS file was found
128 FvHandle
= HandleBuffer
[IndexFv
];
132 // Free the buffer of FV handles
134 FreePool (HandleBuffer
);
137 // If the FFS file was not found, then return
139 if (FvHandle
== NULL
) {
144 // Create a device path for the FFS file that was found
146 EfiInitializeFwVolDevicepathNode (&FileNode
, FileGuid
);
147 DevicePath
= AppendDevicePathNode (
148 DevicePathFromHandle (FvHandle
),
149 (EFI_DEVICE_PATH_PROTOCOL
*) &FileNode
153 // Create and add a new load option for the FFS file that was found
155 Status
= EfiBootManagerInitializeLoadOption (
157 LoadOptionNumberUnassigned
,
165 if (!EFI_ERROR (Status
)) {
166 BootOptions
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
168 OptionIndex
= PlatformFindLoadOption (&NewOption
, BootOptions
, BootOptionCount
);
170 if (OptionIndex
== -1) {
171 Status
= EfiBootManagerAddLoadOptionVariable (&NewOption
, (UINTN
) -1);
172 ASSERT_EFI_ERROR (Status
);
174 EfiBootManagerFreeLoadOption (&NewOption
);
175 EfiBootManagerFreeLoadOptions (BootOptions
, BootOptionCount
);
181 InternalBdsEmptyCallbackFuntion (
190 Do the platform specific action before the console is connected.
193 Update console variable;
194 Register new Driver#### or Boot####;
195 Signal ReadyToLock event.
199 PlatformBootManagerBeforeConsole (
207 EFI_BOOT_MANAGER_LOAD_OPTION BootOption
;
208 EFI_ACPI_S3_SAVE_PROTOCOL
*AcpiS3Save
;
210 EFI_EVENT EndOfDxeEvent
;
213 // Update the console variables.
215 for (Index
= 0; gPlatformConsole
[Index
].DevicePath
!= NULL
; Index
++) {
216 if ((gPlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
217 EfiBootManagerUpdateConsoleVariable (ConIn
, gPlatformConsole
[Index
].DevicePath
, NULL
);
220 if ((gPlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
221 EfiBootManagerUpdateConsoleVariable (ConOut
, gPlatformConsole
[Index
].DevicePath
, NULL
);
224 if ((gPlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
225 EfiBootManagerUpdateConsoleVariable (ErrOut
, gPlatformConsole
[Index
].DevicePath
, NULL
);
230 // Register ENTER as CONTINUE key
232 Enter
.ScanCode
= SCAN_NULL
;
233 Enter
.UnicodeChar
= CHAR_CARRIAGE_RETURN
;
234 EfiBootManagerRegisterContinueKeyOption (0, &Enter
, NULL
);
237 // Map F2 to Boot Manager Menu
239 F2
.ScanCode
= SCAN_F2
;
240 F2
.UnicodeChar
= CHAR_NULL
;
241 EfiBootManagerGetBootManagerMenu (&BootOption
);
242 EfiBootManagerAddKeyOptionVariable (NULL
, (UINT16
) BootOption
.OptionNumber
, 0, &F2
, NULL
);
245 // Register UEFI Shell
247 PlatformRegisterFvBootOption (&mUefiShellFileGuid
, L
"UEFI Shell", LOAD_OPTION_ACTIVE
);
252 Status
= gBS
->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid
, NULL
, (VOID
**)&AcpiS3Save
);
253 if (!EFI_ERROR (Status
)) {
254 AcpiS3Save
->S3Save (AcpiS3Save
, NULL
);
258 // Inform PI SMM drivers that BDS may run 3rd party code
259 // Create and signal End of DXE event group
261 Status
= gBS
->CreateEventEx (
264 InternalBdsEmptyCallbackFuntion
,
266 &gEfiEndOfDxeEventGroupGuid
,
269 ASSERT_EFI_ERROR (Status
);
270 gBS
->SignalEvent (EndOfDxeEvent
);
271 gBS
->CloseEvent (EndOfDxeEvent
);
273 DEBUG((EFI_D_INFO
,"All EndOfDxe callbacks have returned successfully\n"));
276 // Install SMM Ready To Lock protocol so all resources can be locked down
277 // before BDS runs 3rd party code. This action must be done last so all
278 // other SMM driver signals are processed before this final lock down action.
281 Status
= gBS
->InstallProtocolInterface (
283 &gEfiDxeSmmReadyToLockProtocolGuid
,
284 EFI_NATIVE_INTERFACE
,
287 ASSERT_EFI_ERROR (Status
);
291 Do the platform specific action after the console is connected.
294 Dynamically switch output mode;
295 Signal console ready platform customized event;
296 Run diagnostics like memory testing;
297 Connect certain devices;
298 Dispatch additional option ROMs
302 PlatformBootManagerAfterConsole (
310 L
"F2 to enter Boot Manager Menu.\n"
311 L
"ENTER to boot directly.\n"
316 // Use a DynamicHii type pcd to save the boot status, which is used to
317 // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration.
319 if (PcdGetBool(PcdBootState
)) {
320 Status
= PcdSetBoolS (PcdBootState
, FALSE
);
321 ASSERT_EFI_ERROR (Status
);
326 This function is called each second during the boot manager waits the timeout.
328 @param TimeoutRemain The remaining timeout.
332 PlatformBootManagerWaitCallback (
336 Print (L
"\r%-2d seconds remained...", TimeoutRemain
);