Rewrite the BootOrder NvVar based on QEMU's "bootorder" fw_cfg file.\r
\r
Copyright (C) 2012 - 2013, Red Hat, Inc.\r
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
\r
This program and the accompanying materials are licensed and made available\r
under the terms and conditions of the BSD License which accompanies this\r
} BOOT_ORDER;\r
\r
\r
+/**\r
+ Array element tracking an enumerated boot option that has the\r
+ LOAD_OPTION_ACTIVE attribute.\r
+**/\r
+typedef struct {\r
+ CONST BDS_COMMON_OPTION *BootOption; // reference only, no ownership\r
+} ACTIVE_OPTION;\r
+\r
+\r
/**\r
\r
Append BootOptionId to BootOrder, reallocating the latter if needed.\r
}\r
\r
\r
+/**\r
+\r
+ Create an array of ACTIVE_OPTION elements for a boot option list.\r
+\r
+ @param[in] BootOptionList A boot option list, created with\r
+ BdsLibEnumerateAllBootOption().\r
+\r
+ @param[out] ActiveOption Pointer to the first element in the new array.\r
+ The caller is responsible for freeing the array\r
+ with FreePool() after use.\r
+\r
+ @param[out] Count Number of elements in the new array.\r
+\r
+\r
+ @retval RETURN_SUCCESS The ActiveOption array has been created.\r
+\r
+ @retval RETURN_NOT_FOUND No active entry has been found in\r
+ BootOptionList.\r
+\r
+ @retval RETURN_OUT_OF_RESOURCES Memory allocation failed.\r
+\r
+**/\r
+STATIC\r
+RETURN_STATUS\r
+CollectActiveOptions (\r
+ IN CONST LIST_ENTRY *BootOptionList,\r
+ OUT ACTIVE_OPTION **ActiveOption,\r
+ OUT UINTN *Count\r
+ )\r
+{\r
+ UINTN ScanMode;\r
+\r
+ *ActiveOption = NULL;\r
+\r
+ //\r
+ // Scan the list twice:\r
+ // - count active entries,\r
+ // - store links to active entries.\r
+ //\r
+ for (ScanMode = 0; ScanMode < 2; ++ScanMode) {\r
+ CONST LIST_ENTRY *Link;\r
+\r
+ Link = BootOptionList->ForwardLink;\r
+ *Count = 0;\r
+ while (Link != BootOptionList) {\r
+ CONST BDS_COMMON_OPTION *Current;\r
+\r
+ Current = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
+ if (IS_LOAD_OPTION_TYPE (Current->Attribute, LOAD_OPTION_ACTIVE)) {\r
+ if (ScanMode == 1) {\r
+ (*ActiveOption)[*Count].BootOption = Current;\r
+ }\r
+ ++*Count;\r
+ }\r
+ Link = Link->ForwardLink;\r
+ }\r
+\r
+ if (ScanMode == 0) {\r
+ if (*Count == 0) {\r
+ return RETURN_NOT_FOUND;\r
+ }\r
+ *ActiveOption = AllocatePool (*Count * sizeof **ActiveOption);\r
+ if (*ActiveOption == NULL) {\r
+ return RETURN_OUT_OF_RESOURCES;\r
+ }\r
+ }\r
+ }\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+\r
/**\r
OpenFirmware device path node\r
**/\r
CONST CHAR8 *FwCfgPtr;\r
\r
BOOT_ORDER BootOrder;\r
+ ACTIVE_OPTION *ActiveOption;\r
+ UINTN ActiveCount;\r
\r
UINTN TranslatedSize;\r
CHAR16 Translated[TRANSLATION_OUTPUT_SIZE];\r
goto ErrorFreeFwCfg;\r
}\r
\r
+ Status = CollectActiveOptions (BootOptionList, &ActiveOption, &ActiveCount);\r
+ if (RETURN_ERROR (Status)) {\r
+ goto ErrorFreeBootOrder;\r
+ }\r
+\r
//\r
// translate each OpenFirmware path\r
//\r
Status == RETURN_UNSUPPORTED ||\r
Status == RETURN_BUFFER_TOO_SMALL) {\r
if (Status == RETURN_SUCCESS) {\r
- CONST LIST_ENTRY *Link;\r
+ UINTN Idx;\r
\r
//\r
- // match translated OpenFirmware path against all enumerated boot options\r
+ // match translated OpenFirmware path against all active boot options\r
//\r
- for (Link = BootOptionList->ForwardLink; Link != BootOptionList;\r
- Link = Link->ForwardLink) {\r
- CONST BDS_COMMON_OPTION *BootOption;\r
-\r
- BootOption = CR (\r
- Link,\r
- BDS_COMMON_OPTION,\r
- Link,\r
- BDS_LOAD_OPTION_SIGNATURE\r
- );\r
- if (IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE) &&\r
- Match (\r
+ for (Idx = 0; Idx < ActiveCount; ++Idx) {\r
+ if (Match (\r
Translated,\r
TranslatedSize, // contains length, not size, in CHAR16's here\r
- BootOption->DevicePath\r
+ ActiveOption[Idx].BootOption->DevicePath\r
)\r
) {\r
//\r
// match found, store ID and continue with next OpenFirmware path\r
//\r
- Status = BootOrderAppend (&BootOrder, BootOption->BootCurrent);\r
+ Status = BootOrderAppend (&BootOrder,\r
+ ActiveOption[Idx].BootOption->BootCurrent);\r
if (Status != RETURN_SUCCESS) {\r
- goto ErrorFreeBootOrder;\r
+ goto ErrorFreeActiveOption;\r
}\r
break;\r
}\r
- } // scanned all enumerated boot options\r
+ } // scanned all active boot options\r
} // translation successful\r
\r
TranslatedSize = sizeof (Translated) / sizeof (Translated[0]);\r
));\r
}\r
\r
+ErrorFreeActiveOption:\r
+ FreePool (ActiveOption);\r
+\r
ErrorFreeBootOrder:\r
FreePool (BootOrder.Data);\r
\r