OvmfPkg: QemuBootOrder: keep some boot options that have not been selected

Some of the active boot options that have not been selected over fw_cfg
should be preserved at the end of the boot order. For now we're adding
back everything that starts with neither PciRoot() nor HD(). This includes
the UEFI shell, memory-mapped from the firmware image.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Michael Chang <mchang@suse.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14668 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Laszlo Ersek 2013-09-13 08:14:57 +00:00 committed by jljusten
parent e13be08edc
commit 838b5b00f4
1 changed files with 108 additions and 0 deletions

View File

@ -1012,6 +1012,105 @@ Exit:
}
/**
Append some of the unselected active boot options to the boot order.
This function should accommodate any further policy changes in "boot option
survival". Currently we're adding back everything that starts with neither
PciRoot() nor HD().
@param[in,out] BootOrder The structure holding the boot order to
complete. The caller is responsible for
initializing (and potentially populating) it
before calling this function.
@param[in,out] ActiveOption The array of active boot options to scan.
Entries marked as Appended will be skipped.
Those of the rest that satisfy the survival
policy will be added to BootOrder with
BootOrderAppend().
@param[in] ActiveCount Number of elements in ActiveOption.
@retval RETURN_SUCCESS BootOrder has been extended with any eligible boot
options.
@return Error codes returned by BootOrderAppend().
**/
STATIC
RETURN_STATUS
BootOrderComplete (
IN OUT BOOT_ORDER *BootOrder,
IN OUT ACTIVE_OPTION *ActiveOption,
IN UINTN ActiveCount
)
{
RETURN_STATUS Status;
UINTN Idx;
Status = RETURN_SUCCESS;
Idx = 0;
while (!RETURN_ERROR (Status) && Idx < ActiveCount) {
if (!ActiveOption[Idx].Appended) {
CONST BDS_COMMON_OPTION *Current;
CONST EFI_DEVICE_PATH_PROTOCOL *FirstNode;
Current = ActiveOption[Idx].BootOption;
FirstNode = Current->DevicePath;
if (FirstNode != NULL) {
CHAR16 *Converted;
STATIC CHAR16 ConvFallBack[] = L"<unable to convert>";
BOOLEAN Keep;
Converted = ConvertDevicePathToText (FirstNode, FALSE, FALSE);
if (Converted == NULL) {
Converted = ConvFallBack;
}
Keep = TRUE;
if (DevicePathType(FirstNode) == MEDIA_DEVICE_PATH &&
DevicePathSubType(FirstNode) == MEDIA_HARDDRIVE_DP) {
//
// drop HD()
//
Keep = FALSE;
} else if (DevicePathType(FirstNode) == ACPI_DEVICE_PATH &&
DevicePathSubType(FirstNode) == ACPI_DP) {
ACPI_HID_DEVICE_PATH *Acpi;
Acpi = (ACPI_HID_DEVICE_PATH *) FirstNode;
if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST &&
EISA_ID_TO_NUM (Acpi->HID) == 0x0a03) {
//
// drop PciRoot()
//
Keep = FALSE;
}
}
if (Keep) {
Status = BootOrderAppend (BootOrder, &ActiveOption[Idx]);
if (!RETURN_ERROR (Status)) {
DEBUG ((DEBUG_VERBOSE, "%a: keeping \"%s\"\n", __FUNCTION__,
Converted));
}
} else {
DEBUG ((DEBUG_VERBOSE, "%a: dropping \"%s\"\n", __FUNCTION__,
Converted));
}
if (Converted != ConvFallBack) {
FreePool (Converted);
}
}
}
++Idx;
}
return Status;
}
/**
Set the boot order based on configuration retrieved from QEMU.
@ -1140,6 +1239,15 @@ SetBootOrderFromQemu (
if (Status == RETURN_NOT_FOUND && BootOrder.Produced > 0) {
//
// No more OpenFirmware paths, some matches found: rewrite BootOrder NvVar.
// Some of the active boot options that have not been selected over fw_cfg
// should be preserved at the end of the boot order.
//
Status = BootOrderComplete (&BootOrder, ActiveOption, ActiveCount);
if (RETURN_ERROR (Status)) {
goto ErrorFreeActiveOption;
}
//
// See Table 10 in the UEFI Spec 2.3.1 with Errata C for the required
// attributes.
//