OvmfPkg: QemuBootOrder: collect active UEFI boot options in advance

In preparation for the next patch, collect active UEFI boot options in
advance into a new array. Rebase the current inner loop (the matching
loop) to this array.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Michael Chang <mchang@suse.com>
[jordan.l.justen@intel.com: initialize *ActiveOption for GCC IA32 warning]
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14666 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Laszlo Ersek 2013-09-13 08:14:45 +00:00 committed by jljusten
parent 64378ce170
commit 32a22f09d7

View File

@ -2,6 +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 - 2013, Red Hat, Inc. Copyright (C) 2012 - 2013, Red Hat, Inc.
Copyright (c) 2013, 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
@ -237,6 +238,15 @@ typedef struct {
} BOOT_ORDER; } BOOT_ORDER;
/**
Array element tracking an enumerated boot option that has the
LOAD_OPTION_ACTIVE attribute.
**/
typedef struct {
CONST BDS_COMMON_OPTION *BootOption; // reference only, no ownership
} ACTIVE_OPTION;
/** /**
Append BootOptionId to BootOrder, reallocating the latter if needed. Append BootOptionId to BootOrder, reallocating the latter if needed.
@ -282,6 +292,77 @@ BootOrderAppend (
} }
/**
Create an array of ACTIVE_OPTION elements for a boot option list.
@param[in] BootOptionList A boot option list, created with
BdsLibEnumerateAllBootOption().
@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_NOT_FOUND No active entry has been found in
BootOptionList.
@retval RETURN_OUT_OF_RESOURCES Memory allocation failed.
**/
STATIC
RETURN_STATUS
CollectActiveOptions (
IN CONST LIST_ENTRY *BootOptionList,
OUT ACTIVE_OPTION **ActiveOption,
OUT UINTN *Count
)
{
UINTN ScanMode;
*ActiveOption = NULL;
//
// Scan the list twice:
// - count active entries,
// - store links to active entries.
//
for (ScanMode = 0; ScanMode < 2; ++ScanMode) {
CONST LIST_ENTRY *Link;
Link = BootOptionList->ForwardLink;
*Count = 0;
while (Link != BootOptionList) {
CONST BDS_COMMON_OPTION *Current;
Current = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
if (IS_LOAD_OPTION_TYPE (Current->Attribute, LOAD_OPTION_ACTIVE)) {
if (ScanMode == 1) {
(*ActiveOption)[*Count].BootOption = Current;
}
++*Count;
}
Link = Link->ForwardLink;
}
if (ScanMode == 0) {
if (*Count == 0) {
return RETURN_NOT_FOUND;
}
*ActiveOption = AllocatePool (*Count * sizeof **ActiveOption);
if (*ActiveOption == NULL) {
return RETURN_OUT_OF_RESOURCES;
}
}
}
return RETURN_SUCCESS;
}
/** /**
OpenFirmware device path node OpenFirmware device path node
**/ **/
@ -967,6 +1048,8 @@ SetBootOrderFromQemu (
CONST CHAR8 *FwCfgPtr; CONST CHAR8 *FwCfgPtr;
BOOT_ORDER BootOrder; BOOT_ORDER BootOrder;
ACTIVE_OPTION *ActiveOption;
UINTN ActiveCount;
UINTN TranslatedSize; UINTN TranslatedSize;
CHAR16 Translated[TRANSLATION_OUTPUT_SIZE]; CHAR16 Translated[TRANSLATION_OUTPUT_SIZE];
@ -1007,6 +1090,11 @@ SetBootOrderFromQemu (
goto ErrorFreeFwCfg; goto ErrorFreeFwCfg;
} }
Status = CollectActiveOptions (BootOptionList, &ActiveOption, &ActiveCount);
if (RETURN_ERROR (Status)) {
goto ErrorFreeBootOrder;
}
// //
// translate each OpenFirmware path // translate each OpenFirmware path
// //
@ -1016,38 +1104,29 @@ SetBootOrderFromQemu (
Status == RETURN_UNSUPPORTED || Status == RETURN_UNSUPPORTED ||
Status == RETURN_BUFFER_TOO_SMALL) { Status == RETURN_BUFFER_TOO_SMALL) {
if (Status == RETURN_SUCCESS) { if (Status == RETURN_SUCCESS) {
CONST LIST_ENTRY *Link; UINTN Idx;
// //
// match translated OpenFirmware path against all enumerated boot options // match translated OpenFirmware path against all active boot options
// //
for (Link = BootOptionList->ForwardLink; Link != BootOptionList; for (Idx = 0; Idx < ActiveCount; ++Idx) {
Link = Link->ForwardLink) { if (Match (
CONST BDS_COMMON_OPTION *BootOption;
BootOption = CR (
Link,
BDS_COMMON_OPTION,
Link,
BDS_LOAD_OPTION_SIGNATURE
);
if (IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE) &&
Match (
Translated, Translated,
TranslatedSize, // contains length, not size, in CHAR16's here TranslatedSize, // contains length, not size, in CHAR16's here
BootOption->DevicePath ActiveOption[Idx].BootOption->DevicePath
) )
) { ) {
// //
// match found, store ID and continue with next OpenFirmware path // match found, store ID and continue with next OpenFirmware path
// //
Status = BootOrderAppend (&BootOrder, BootOption->BootCurrent); Status = BootOrderAppend (&BootOrder,
ActiveOption[Idx].BootOption->BootCurrent);
if (Status != RETURN_SUCCESS) { if (Status != RETURN_SUCCESS) {
goto ErrorFreeBootOrder; goto ErrorFreeActiveOption;
} }
break; break;
} }
} // scanned all enumerated boot options } // scanned all active boot options
} // translation successful } // translation successful
TranslatedSize = sizeof (Translated) / sizeof (Translated[0]); TranslatedSize = sizeof (Translated) / sizeof (Translated[0]);
@ -1077,6 +1156,9 @@ SetBootOrderFromQemu (
)); ));
} }
ErrorFreeActiveOption:
FreePool (ActiveOption);
ErrorFreeBootOrder: ErrorFreeBootOrder:
FreePool (BootOrder.Data); FreePool (BootOrder.Data);