/** @file\r
Library functions which relates with booting.\r
\r
-Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>\r
-(C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.\r
+Copyright (c) 2011 - 2021, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2015-2021 Hewlett Packard Enterprise Development LP<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
//\r
FileBuffer = AllocateReservedPages (EFI_SIZE_TO_PAGES (BufferSize));\r
if (FileBuffer == NULL) {\r
+ DEBUG_CODE (\r
+ EFI_DEVICE_PATH *LoadFilePath;\r
+ CHAR16 *LoadFileText;\r
+ CHAR16 *FileText;\r
+\r
+ LoadFilePath = DevicePathFromHandle (LoadFileHandle);\r
+ if (LoadFilePath == NULL) {\r
+ LoadFileText = NULL;\r
+ } else {\r
+ LoadFileText = ConvertDevicePathToText (LoadFilePath, FALSE, FALSE);\r
+ }\r
+ FileText = ConvertDevicePathToText (FilePath, FALSE, FALSE);\r
+\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a:%a: failed to allocate reserved pages: "\r
+ "BufferSize=%Lu LoadFile=\"%s\" FilePath=\"%s\"\n",\r
+ gEfiCallerBaseName,\r
+ __FUNCTION__,\r
+ (UINT64)BufferSize,\r
+ LoadFileText,\r
+ FileText\r
+ ));\r
+\r
+ if (FileText != NULL) {\r
+ FreePool (FileText);\r
+ }\r
+ if (LoadFileText != NULL) {\r
+ FreePool (LoadFileText);\r
+ }\r
+ );\r
return NULL;\r
}\r
\r
\r
if (EFI_ERROR (Status)) {\r
//\r
- // Report Status Code with the failure status to indicate that the failure to load boot option\r
+ // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created\r
+ // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now.\r
+ // If the caller doesn't have the option to defer the execution of an image, we should\r
+ // unload image for the EFI_SECURITY_VIOLATION to avoid resource leak.\r
//\r
- BmReportLoadFailure (EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR, Status);\r
- BootOption->Status = Status;\r
+ if (Status == EFI_SECURITY_VIOLATION) {\r
+ gBS->UnloadImage (ImageHandle);\r
+ }\r
//\r
// Destroy the RAM disk\r
//\r
BmDestroyRamDisk (RamDiskDevicePath);\r
FreePool (RamDiskDevicePath);\r
}\r
+ //\r
+ // Report Status Code with the failure status to indicate that the failure to load boot option\r
+ //\r
+ BmReportLoadFailure (EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR, Status);\r
+ BootOption->Status = Status;\r
return;\r
}\r
}\r
Status = gBS->StartImage (ImageHandle, &BootOption->ExitDataSize, &BootOption->ExitData);\r
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Image Return Status = %r\n", Status));\r
BootOption->Status = Status;\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Report Status Code with the failure status to indicate that boot failure\r
- //\r
- BmReportLoadFailure (EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED, Status);\r
- }\r
- PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32) OptionNumber);\r
\r
//\r
// Destroy the RAM disk\r
FreePool (RamDiskDevicePath);\r
}\r
\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Report Status Code with the failure status to indicate that boot failure\r
+ //\r
+ BmReportLoadFailure (EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED, Status);\r
+ }\r
+ PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32) OptionNumber);\r
+\r
+\r
//\r
// Clear the Watchdog Timer after the image returns\r
//\r
VOID\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_BOOT_MANAGER_LOAD_OPTION *NvBootOptions;\r
- UINTN NvBootOptionCount;\r
- EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
- UINTN BootOptionCount;\r
- UINTN Index;\r
+ EFI_STATUS Status;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION *NvBootOptions;\r
+ UINTN NvBootOptionCount;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
+ UINTN BootOptionCount;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION *UpdatedBootOptions;\r
+ UINTN UpdatedBootOptionCount;\r
+ UINTN Index;\r
+ EDKII_PLATFORM_BOOT_MANAGER_PROTOCOL *PlatformBootManager;\r
\r
//\r
// Optionally refresh the legacy boot option\r
}\r
\r
BootOptions = BmEnumerateBootOptions (&BootOptionCount);\r
- NvBootOptions = EfiBootManagerGetLoadOptions (&NvBootOptionCount, LoadOptionTypeBoot);\r
\r
//\r
// Mark the boot option as added by BDS by setting OptionalData to a special GUID\r
BootOptions[Index].OptionalDataSize = sizeof (EFI_GUID);\r
}\r
\r
+ //\r
+ // Locate Platform Boot Options Protocol\r
+ //\r
+ Status = gBS->LocateProtocol (&gEdkiiPlatformBootManagerProtocolGuid,\r
+ NULL,\r
+ (VOID **)&PlatformBootManager);\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // If found, call platform specific refresh to all auto enumerated and NV\r
+ // boot options.\r
+ //\r
+ Status = PlatformBootManager->RefreshAllBootOptions ((CONST EFI_BOOT_MANAGER_LOAD_OPTION *)BootOptions,\r
+ (CONST UINTN)BootOptionCount,\r
+ &UpdatedBootOptions,\r
+ &UpdatedBootOptionCount);\r
+ if (!EFI_ERROR (Status)) {\r
+ EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
+ BootOptions = UpdatedBootOptions;\r
+ BootOptionCount = UpdatedBootOptionCount;\r
+ }\r
+ }\r
+\r
+ NvBootOptions = EfiBootManagerGetLoadOptions (&NvBootOptionCount, LoadOptionTypeBoot);\r
+\r
//\r
// Remove invalid EFI boot options from NV\r
//\r
This function is called to get or create the boot option for the Boot Manager Menu.\r
\r
The Boot Manager Menu is shown after successfully booting a boot option.\r
- Assume the BootManagerMenuFile is in the same FV as the module links to this library.\r
+ This function will first try to search the BootManagerMenuFile is in the same FV as\r
+ the module links to this library. If fails, it will search in all FVs.\r
\r
@param BootOption Return the boot option of the Boot Manager Menu\r
\r
CHAR16 *Description;\r
UINTN DescriptionLength;\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
- EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
- MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;\r
UINTN HandleCount;\r
EFI_HANDLE *Handles;\r
UINTN Index;\r
- VOID *Data;\r
- UINTN DataSize;\r
\r
DevicePath = NULL;\r
Description = NULL;\r
}\r
\r
if (DevicePath == NULL) {\r
- Data = NULL;\r
- Status = GetSectionFromFv (\r
+ Status = GetFileDevicePathFromAnyFv (\r
PcdGetPtr (PcdBootManagerMenuFile),\r
EFI_SECTION_PE32,\r
0,\r
- (VOID **) &Data,\r
- &DataSize\r
+ &DevicePath\r
);\r
- if (Data != NULL) {\r
- FreePool (Data);\r
- }\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_WARN, "[Bds]BootManagerMenu FFS section can not be found, skip its boot option registration\n"));\r
return EFI_NOT_FOUND;\r
}\r
-\r
+ ASSERT (DevicePath != NULL);\r
//\r
// Get BootManagerMenu application's description from EFI User Interface Section.\r
//\r
- Status = GetSectionFromFv (\r
+ Status = GetSectionFromAnyFv (\r
PcdGetPtr (PcdBootManagerMenuFile),\r
EFI_SECTION_USER_INTERFACE,\r
0,\r
if (EFI_ERROR (Status)) {\r
Description = NULL;\r
}\r
-\r
- EfiInitializeFwVolDevicepathNode (&FileNode, PcdGetPtr (PcdBootManagerMenuFile));\r
- Status = gBS->HandleProtocol (\r
- gImageHandle,\r
- &gEfiLoadedImageProtocolGuid,\r
- (VOID **) &LoadedImage\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- DevicePath = AppendDevicePathNode (\r
- DevicePathFromHandle (LoadedImage->DeviceHandle),\r
- (EFI_DEVICE_PATH_PROTOCOL *) &FileNode\r
- );\r
- ASSERT (DevicePath != NULL);\r
}\r
\r
Status = EfiBootManagerInitializeLoadOption (\r
EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
);\r
\r
- return EfiBootManagerAddLoadOptionVariable (BootOption, 0);\r
+ return EfiBootManagerAddLoadOptionVariable (BootOption, (UINTN) -1);\r
}\r
\r
/**\r