OvmfPkg/QemuNewBootOrderLib: Build with UefiBootManagerLib
NOTE: SetBootOrderFromQemu() interface is not changed. But when the old IntelFrameworkModulePkg/BDS is no longer used in OVMF and ArmVirtPkg, additional patch will be submitted to change this interface to remove parameter BootOptionList. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Tested-by: Laszlo Ersek <lersek@redhat.com>
This commit is contained in:
@ -2,7 +2,7 @@
|
|||||||
Rewrite the BootOrder NvVar based on QEMU's "bootorder" fw_cfg file.
|
Rewrite the BootOrder NvVar based on QEMU's "bootorder" fw_cfg file.
|
||||||
|
|
||||||
Copyright (C) 2012 - 2014, Red Hat, Inc.
|
Copyright (C) 2012 - 2014, Red Hat, Inc.
|
||||||
Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
|
|
||||||
This program and the accompanying materials are licensed and made available
|
This program and the accompanying materials are licensed and made available
|
||||||
under the terms and conditions of the BSD License which accompanies this
|
under the terms and conditions of the BSD License which accompanies this
|
||||||
@ -16,7 +16,7 @@
|
|||||||
#include <Library/QemuFwCfgLib.h>
|
#include <Library/QemuFwCfgLib.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/MemoryAllocationLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
||||||
#include <Library/GenericBdsLib.h>
|
#include <Library/UefiBootManagerLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
@ -253,8 +253,10 @@ typedef struct {
|
|||||||
LOAD_OPTION_ACTIVE attribute.
|
LOAD_OPTION_ACTIVE attribute.
|
||||||
**/
|
**/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CONST BDS_COMMON_OPTION *BootOption; // reference only, no ownership
|
CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOption; // reference only, no
|
||||||
BOOLEAN Appended; // has been added to a BOOT_ORDER?
|
// ownership
|
||||||
|
BOOLEAN Appended; // has been added to a
|
||||||
|
// BOOT_ORDER?
|
||||||
} ACTIVE_OPTION;
|
} ACTIVE_OPTION;
|
||||||
|
|
||||||
|
|
||||||
@ -300,7 +302,7 @@ BootOrderAppend (
|
|||||||
}
|
}
|
||||||
|
|
||||||
BootOrder->Data[BootOrder->Produced++] =
|
BootOrder->Data[BootOrder->Produced++] =
|
||||||
ActiveOption->BootOption->BootCurrent;
|
(UINT16) ActiveOption->BootOption->OptionNumber;
|
||||||
ActiveOption->Appended = TRUE;
|
ActiveOption->Appended = TRUE;
|
||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -308,22 +310,25 @@ BootOrderAppend (
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
Create an array of ACTIVE_OPTION elements for a boot option list.
|
Create an array of ACTIVE_OPTION elements for a boot option array.
|
||||||
|
|
||||||
@param[in] BootOptionList A boot option list, created with
|
@param[in] BootOptions A boot option array, created with
|
||||||
BdsLibEnumerateAllBootOption().
|
EfiBootManagerRefreshAllBootOption () and
|
||||||
|
EfiBootManagerGetLoadOptions ().
|
||||||
|
|
||||||
@param[out] ActiveOption Pointer to the first element in the new array.
|
@param[in] BootOptionCount The number of elements in BootOptions.
|
||||||
The caller is responsible for freeing the array
|
|
||||||
with FreePool() after use.
|
|
||||||
|
|
||||||
@param[out] Count Number of elements in the new array.
|
@param[out] ActiveOption Pointer to the first element in the new array.
|
||||||
|
The caller is responsible for freeing the array
|
||||||
|
with FreePool() after use.
|
||||||
|
|
||||||
|
@param[out] Count Number of elements in the new array.
|
||||||
|
|
||||||
|
|
||||||
@retval RETURN_SUCCESS The ActiveOption array has been created.
|
@retval RETURN_SUCCESS The ActiveOption array has been created.
|
||||||
|
|
||||||
@retval RETURN_NOT_FOUND No active entry has been found in
|
@retval RETURN_NOT_FOUND No active entry has been found in
|
||||||
BootOptionList.
|
BootOptions.
|
||||||
|
|
||||||
@retval RETURN_OUT_OF_RESOURCES Memory allocation failed.
|
@retval RETURN_OUT_OF_RESOURCES Memory allocation failed.
|
||||||
|
|
||||||
@ -331,11 +336,13 @@ BootOrderAppend (
|
|||||||
STATIC
|
STATIC
|
||||||
RETURN_STATUS
|
RETURN_STATUS
|
||||||
CollectActiveOptions (
|
CollectActiveOptions (
|
||||||
IN CONST LIST_ENTRY *BootOptionList,
|
IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions,
|
||||||
OUT ACTIVE_OPTION **ActiveOption,
|
IN UINTN BootOptionCount,
|
||||||
OUT UINTN *Count
|
OUT ACTIVE_OPTION **ActiveOption,
|
||||||
|
OUT UINTN *Count
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
UINTN Index;
|
||||||
UINTN ScanMode;
|
UINTN ScanMode;
|
||||||
|
|
||||||
*ActiveOption = NULL;
|
*ActiveOption = NULL;
|
||||||
@ -346,22 +353,15 @@ CollectActiveOptions (
|
|||||||
// - store links to active entries.
|
// - store links to active entries.
|
||||||
//
|
//
|
||||||
for (ScanMode = 0; ScanMode < 2; ++ScanMode) {
|
for (ScanMode = 0; ScanMode < 2; ++ScanMode) {
|
||||||
CONST LIST_ENTRY *Link;
|
|
||||||
|
|
||||||
Link = BootOptionList->ForwardLink;
|
|
||||||
*Count = 0;
|
*Count = 0;
|
||||||
while (Link != BootOptionList) {
|
for (Index = 0; Index < BootOptionCount; Index++) {
|
||||||
CONST BDS_COMMON_OPTION *Current;
|
if ((BootOptions[Index].Attributes & LOAD_OPTION_ACTIVE) != 0) {
|
||||||
|
|
||||||
Current = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
|
|
||||||
if (IS_LOAD_OPTION_TYPE (Current->Attribute, LOAD_OPTION_ACTIVE)) {
|
|
||||||
if (ScanMode == 1) {
|
if (ScanMode == 1) {
|
||||||
(*ActiveOption)[*Count].BootOption = Current;
|
(*ActiveOption)[*Count].BootOption = &BootOptions[Index];
|
||||||
(*ActiveOption)[*Count].Appended = FALSE;
|
(*ActiveOption)[*Count].Appended = FALSE;
|
||||||
}
|
}
|
||||||
++*Count;
|
++*Count;
|
||||||
}
|
}
|
||||||
Link = Link->ForwardLink;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ScanMode == 0) {
|
if (ScanMode == 0) {
|
||||||
@ -1437,11 +1437,17 @@ BOOLEAN
|
|||||||
Match (
|
Match (
|
||||||
IN CONST CHAR16 *Translated,
|
IN CONST CHAR16 *Translated,
|
||||||
IN UINTN TranslatedLength,
|
IN UINTN TranslatedLength,
|
||||||
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
CHAR16 *Converted;
|
CHAR16 *Converted;
|
||||||
BOOLEAN Result;
|
BOOLEAN Result;
|
||||||
|
VOID *FileBuffer;
|
||||||
|
UINTN FileSize;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *AbsDevicePath;
|
||||||
|
CHAR16 *AbsConverted;
|
||||||
|
BOOLEAN Shortform;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *Node;
|
||||||
|
|
||||||
Converted = ConvertDevicePathToText (
|
Converted = ConvertDevicePathToText (
|
||||||
DevicePath,
|
DevicePath,
|
||||||
@ -1452,24 +1458,57 @@ Match (
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Attempt to expand any relative UEFI device path starting with HD() to an
|
|
||||||
// absolute device path first. The logic imitates BdsLibBootViaBootOption().
|
|
||||||
// We don't have to free the absolute device path,
|
|
||||||
// BdsExpandPartitionPartialDevicePathToFull() has internal caching.
|
|
||||||
//
|
|
||||||
Result = FALSE;
|
Result = FALSE;
|
||||||
if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH &&
|
Shortform = FALSE;
|
||||||
DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP) {
|
//
|
||||||
EFI_DEVICE_PATH_PROTOCOL *AbsDevicePath;
|
// Expand the short-form device path to full device path
|
||||||
CHAR16 *AbsConverted;
|
//
|
||||||
|
if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
|
||||||
|
(DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)) {
|
||||||
|
//
|
||||||
|
// Harddrive shortform device path
|
||||||
|
//
|
||||||
|
Shortform = TRUE;
|
||||||
|
} else if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
|
||||||
|
(DevicePathSubType (DevicePath) == MEDIA_FILEPATH_DP)) {
|
||||||
|
//
|
||||||
|
// File-path shortform device path
|
||||||
|
//
|
||||||
|
Shortform = TRUE;
|
||||||
|
} else if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
|
||||||
|
(DevicePathSubType (DevicePath) == MSG_URI_DP)) {
|
||||||
|
//
|
||||||
|
// URI shortform device path
|
||||||
|
//
|
||||||
|
Shortform = TRUE;
|
||||||
|
} else {
|
||||||
|
for ( Node = DevicePath
|
||||||
|
; !IsDevicePathEnd (Node)
|
||||||
|
; Node = NextDevicePathNode (Node)
|
||||||
|
) {
|
||||||
|
if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) &&
|
||||||
|
((DevicePathSubType (Node) == MSG_USB_CLASS_DP) ||
|
||||||
|
(DevicePathSubType (Node) == MSG_USB_WWID_DP))) {
|
||||||
|
Shortform = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AbsDevicePath = BdsExpandPartitionPartialDevicePathToFull (
|
//
|
||||||
(HARDDRIVE_DEVICE_PATH *) DevicePath);
|
// Attempt to expand any relative UEFI device path to
|
||||||
if (AbsDevicePath == NULL) {
|
// an absolute device path first.
|
||||||
|
//
|
||||||
|
if (Shortform) {
|
||||||
|
FileBuffer = EfiBootManagerGetLoadOptionBuffer (
|
||||||
|
DevicePath, &AbsDevicePath, &FileSize
|
||||||
|
);
|
||||||
|
if (FileBuffer == NULL) {
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
FreePool (FileBuffer);
|
||||||
AbsConverted = ConvertDevicePathToText (AbsDevicePath, FALSE, FALSE);
|
AbsConverted = ConvertDevicePathToText (AbsDevicePath, FALSE, FALSE);
|
||||||
|
FreePool (AbsDevicePath);
|
||||||
if (AbsConverted == NULL) {
|
if (AbsConverted == NULL) {
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
@ -1538,11 +1577,11 @@ BootOrderComplete (
|
|||||||
Idx = 0;
|
Idx = 0;
|
||||||
while (!RETURN_ERROR (Status) && Idx < ActiveCount) {
|
while (!RETURN_ERROR (Status) && Idx < ActiveCount) {
|
||||||
if (!ActiveOption[Idx].Appended) {
|
if (!ActiveOption[Idx].Appended) {
|
||||||
CONST BDS_COMMON_OPTION *Current;
|
CONST EFI_BOOT_MANAGER_LOAD_OPTION *Current;
|
||||||
CONST EFI_DEVICE_PATH_PROTOCOL *FirstNode;
|
CONST EFI_DEVICE_PATH_PROTOCOL *FirstNode;
|
||||||
|
|
||||||
Current = ActiveOption[Idx].BootOption;
|
Current = ActiveOption[Idx].BootOption;
|
||||||
FirstNode = Current->DevicePath;
|
FirstNode = Current->FilePath;
|
||||||
if (FirstNode != NULL) {
|
if (FirstNode != NULL) {
|
||||||
CHAR16 *Converted;
|
CHAR16 *Converted;
|
||||||
STATIC CHAR16 ConvFallBack[] = L"<unable to convert>";
|
STATIC CHAR16 ConvFallBack[] = L"<unable to convert>";
|
||||||
@ -1635,7 +1674,7 @@ PruneBootVariables (
|
|||||||
CHAR16 VariableName[9];
|
CHAR16 VariableName[9];
|
||||||
|
|
||||||
UnicodeSPrintAsciiFormat (VariableName, sizeof VariableName, "Boot%04x",
|
UnicodeSPrintAsciiFormat (VariableName, sizeof VariableName, "Boot%04x",
|
||||||
ActiveOption[Idx].BootOption->BootCurrent);
|
ActiveOption[Idx].BootOption->OptionNumber);
|
||||||
|
|
||||||
//
|
//
|
||||||
// "The space consumed by the deleted variable may not be available until
|
// "The space consumed by the deleted variable may not be available until
|
||||||
@ -1699,6 +1738,17 @@ SetBootOrderFromQemu (
|
|||||||
|
|
||||||
UINTN TranslatedSize;
|
UINTN TranslatedSize;
|
||||||
CHAR16 Translated[TRANSLATION_OUTPUT_SIZE];
|
CHAR16 Translated[TRANSLATION_OUTPUT_SIZE];
|
||||||
|
EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
|
||||||
|
UINTN BootOptionCount;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The QemuBootOrderLib is linked by OvmfPkg and ArmVirtPkg.
|
||||||
|
// OvmfPkg was changed to use the new BDS @ MdeModulePkg, so boot options
|
||||||
|
// are no longer stored in linked list.
|
||||||
|
// But we don't change the QemuBootOrderLib class interface because
|
||||||
|
// ArmVirtPkg are still using old BDS @ IntelFrameworkModulePkg.
|
||||||
|
//
|
||||||
|
ASSERT (BootOptionList == NULL);
|
||||||
|
|
||||||
Status = QemuFwCfgFindFile ("bootorder", &FwCfgItem, &FwCfgSize);
|
Status = QemuFwCfgFindFile ("bootorder", &FwCfgItem, &FwCfgSize);
|
||||||
if (Status != RETURN_SUCCESS) {
|
if (Status != RETURN_SUCCESS) {
|
||||||
@ -1736,11 +1786,21 @@ SetBootOrderFromQemu (
|
|||||||
goto ErrorFreeFwCfg;
|
goto ErrorFreeFwCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = CollectActiveOptions (BootOptionList, &ActiveOption, &ActiveCount);
|
BootOptions = EfiBootManagerGetLoadOptions (
|
||||||
if (RETURN_ERROR (Status)) {
|
&BootOptionCount, LoadOptionTypeBoot
|
||||||
|
);
|
||||||
|
if (BootOptions == NULL) {
|
||||||
|
Status = RETURN_NOT_FOUND;
|
||||||
goto ErrorFreeBootOrder;
|
goto ErrorFreeBootOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status = CollectActiveOptions (
|
||||||
|
BootOptions, BootOptionCount, &ActiveOption, &ActiveCount
|
||||||
|
);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
goto ErrorFreeBootOptions;
|
||||||
|
}
|
||||||
|
|
||||||
if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) {
|
if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) {
|
||||||
Status = CreateExtraRootBusMap (&ExtraPciRoots);
|
Status = CreateExtraRootBusMap (&ExtraPciRoots);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
@ -1770,7 +1830,7 @@ SetBootOrderFromQemu (
|
|||||||
if (Match (
|
if (Match (
|
||||||
Translated,
|
Translated,
|
||||||
TranslatedSize, // contains length, not size, in CHAR16's here
|
TranslatedSize, // contains length, not size, in CHAR16's here
|
||||||
ActiveOption[Idx].BootOption->DevicePath
|
ActiveOption[Idx].BootOption->FilePath
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
//
|
//
|
||||||
@ -1831,6 +1891,9 @@ ErrorFreeExtraPciRoots:
|
|||||||
ErrorFreeActiveOption:
|
ErrorFreeActiveOption:
|
||||||
FreePool (ActiveOption);
|
FreePool (ActiveOption);
|
||||||
|
|
||||||
|
ErrorFreeBootOptions:
|
||||||
|
EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
|
||||||
|
|
||||||
ErrorFreeBootOrder:
|
ErrorFreeBootOrder:
|
||||||
FreePool (BootOrder.Data);
|
FreePool (BootOrder.Data);
|
||||||
|
|
||||||
|
@ -36,14 +36,14 @@
|
|||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
OvmfPkg/OvmfPkg.dec
|
OvmfPkg/OvmfPkg.dec
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
QemuFwCfgLib
|
QemuFwCfgLib
|
||||||
DebugLib
|
DebugLib
|
||||||
MemoryAllocationLib
|
MemoryAllocationLib
|
||||||
GenericBdsLib
|
UefiBootManagerLib
|
||||||
UefiBootServicesTableLib
|
UefiBootServicesTableLib
|
||||||
UefiRuntimeServicesTableLib
|
UefiRuntimeServicesTableLib
|
||||||
BaseLib
|
BaseLib
|
||||||
|
Reference in New Issue
Block a user