Rewrite the BootOrder NvVar based on QEMU's "bootorder" fw_cfg file.\r
\r
Copyright (C) 2012 - 2014, Red Hat, Inc.\r
- Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2013 - 2016, 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
#include <Library/QemuFwCfgLib.h>\r
#include <Library/DebugLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
-#include <Library/GenericBdsLib.h>\r
+#include <Library/UefiBootManagerLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/UefiRuntimeServicesTableLib.h>\r
#include <Library/BaseLib.h>\r
LOAD_OPTION_ACTIVE attribute.\r
**/\r
typedef struct {\r
- CONST BDS_COMMON_OPTION *BootOption; // reference only, no ownership\r
- BOOLEAN Appended; // has been added to a BOOT_ORDER?\r
+ CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOption; // reference only, no\r
+ // ownership\r
+ BOOLEAN Appended; // has been added to a\r
+ // BOOT_ORDER?\r
} ACTIVE_OPTION;\r
\r
\r
}\r
\r
BootOrder->Data[BootOrder->Produced++] =\r
- ActiveOption->BootOption->BootCurrent;\r
+ (UINT16) ActiveOption->BootOption->OptionNumber;\r
ActiveOption->Appended = TRUE;\r
return RETURN_SUCCESS;\r
}\r
\r
/**\r
\r
- Create an array of ACTIVE_OPTION elements for a boot option list.\r
+ Create an array of ACTIVE_OPTION elements for a boot option array.\r
\r
- @param[in] BootOptionList A boot option list, created with\r
- BdsLibEnumerateAllBootOption().\r
+ @param[in] BootOptions A boot option array, created with\r
+ EfiBootManagerRefreshAllBootOption () and\r
+ EfiBootManagerGetLoadOptions ().\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
+ @param[in] BootOptionCount The number of elements in BootOptions.\r
\r
- @param[out] Count Number of elements in the new array.\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
+ BootOptions.\r
\r
@retval RETURN_OUT_OF_RESOURCES Memory allocation failed.\r
\r
STATIC\r
RETURN_STATUS\r
CollectActiveOptions (\r
- IN CONST LIST_ENTRY *BootOptionList,\r
- OUT ACTIVE_OPTION **ActiveOption,\r
- OUT UINTN *Count\r
+ IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions,\r
+ IN UINTN BootOptionCount,\r
+ OUT ACTIVE_OPTION **ActiveOption,\r
+ OUT UINTN *Count\r
)\r
{\r
+ UINTN Index;\r
UINTN ScanMode;\r
\r
*ActiveOption = NULL;\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
+ for (Index = 0; Index < BootOptionCount; Index++) {\r
+ if ((BootOptions[Index].Attributes & LOAD_OPTION_ACTIVE) != 0) {\r
if (ScanMode == 1) {\r
- (*ActiveOption)[*Count].BootOption = Current;\r
+ (*ActiveOption)[*Count].BootOption = &BootOptions[Index];\r
(*ActiveOption)[*Count].Appended = FALSE;\r
}\r
++*Count;\r
}\r
- Link = Link->ForwardLink;\r
}\r
\r
if (ScanMode == 0) {\r
Match (\r
IN CONST CHAR16 *Translated,\r
IN UINTN TranslatedLength,\r
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
)\r
{\r
- CHAR16 *Converted;\r
- BOOLEAN Result;\r
+ CHAR16 *Converted;\r
+ BOOLEAN Result;\r
+ VOID *FileBuffer;\r
+ UINTN FileSize;\r
+ EFI_DEVICE_PATH_PROTOCOL *AbsDevicePath;\r
+ CHAR16 *AbsConverted;\r
+ BOOLEAN Shortform;\r
+ EFI_DEVICE_PATH_PROTOCOL *Node;\r
\r
Converted = ConvertDevicePathToText (\r
DevicePath,\r
return FALSE;\r
}\r
\r
+ Result = FALSE;\r
+ Shortform = FALSE;\r
//\r
- // Attempt to expand any relative UEFI device path starting with HD() to an\r
- // absolute device path first. The logic imitates BdsLibBootViaBootOption().\r
- // We don't have to free the absolute device path,\r
- // BdsExpandPartitionPartialDevicePathToFull() has internal caching.\r
+ // Expand the short-form device path to full device path\r
//\r
- Result = FALSE;\r
- if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH &&\r
- DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP) {\r
- EFI_DEVICE_PATH_PROTOCOL *AbsDevicePath;\r
- CHAR16 *AbsConverted;\r
-\r
- AbsDevicePath = BdsExpandPartitionPartialDevicePathToFull (\r
- (HARDDRIVE_DEVICE_PATH *) DevicePath);\r
- if (AbsDevicePath == NULL) {\r
+ if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&\r
+ (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)) {\r
+ //\r
+ // Harddrive shortform device path\r
+ //\r
+ Shortform = TRUE;\r
+ } else if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&\r
+ (DevicePathSubType (DevicePath) == MEDIA_FILEPATH_DP)) {\r
+ //\r
+ // File-path shortform device path\r
+ //\r
+ Shortform = TRUE;\r
+ } else if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&\r
+ (DevicePathSubType (DevicePath) == MSG_URI_DP)) {\r
+ //\r
+ // URI shortform device path\r
+ //\r
+ Shortform = TRUE;\r
+ } else {\r
+ for ( Node = DevicePath\r
+ ; !IsDevicePathEnd (Node)\r
+ ; Node = NextDevicePathNode (Node)\r
+ ) {\r
+ if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) &&\r
+ ((DevicePathSubType (Node) == MSG_USB_CLASS_DP) ||\r
+ (DevicePathSubType (Node) == MSG_USB_WWID_DP))) {\r
+ Shortform = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Attempt to expand any relative UEFI device path to\r
+ // an absolute device path first.\r
+ //\r
+ if (Shortform) {\r
+ FileBuffer = EfiBootManagerGetLoadOptionBuffer (\r
+ DevicePath, &AbsDevicePath, &FileSize\r
+ );\r
+ if (FileBuffer == NULL) {\r
goto Exit;\r
}\r
+ FreePool (FileBuffer);\r
AbsConverted = ConvertDevicePathToText (AbsDevicePath, FALSE, FALSE);\r
+ FreePool (AbsDevicePath);\r
if (AbsConverted == NULL) {\r
goto Exit;\r
}\r
Idx = 0;\r
while (!RETURN_ERROR (Status) && Idx < ActiveCount) {\r
if (!ActiveOption[Idx].Appended) {\r
- CONST BDS_COMMON_OPTION *Current;\r
- CONST EFI_DEVICE_PATH_PROTOCOL *FirstNode;\r
+ CONST EFI_BOOT_MANAGER_LOAD_OPTION *Current;\r
+ CONST EFI_DEVICE_PATH_PROTOCOL *FirstNode;\r
\r
Current = ActiveOption[Idx].BootOption;\r
- FirstNode = Current->DevicePath;\r
+ FirstNode = Current->FilePath;\r
if (FirstNode != NULL) {\r
CHAR16 *Converted;\r
STATIC CHAR16 ConvFallBack[] = L"<unable to convert>";\r
CHAR16 VariableName[9];\r
\r
UnicodeSPrintAsciiFormat (VariableName, sizeof VariableName, "Boot%04x",\r
- ActiveOption[Idx].BootOption->BootCurrent);\r
+ ActiveOption[Idx].BootOption->OptionNumber);\r
\r
//\r
// "The space consumed by the deleted variable may not be available until\r
\r
UINTN TranslatedSize;\r
CHAR16 Translated[TRANSLATION_OUTPUT_SIZE];\r
+ EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
+ UINTN BootOptionCount;\r
+\r
+ //\r
+ // The QemuBootOrderLib is linked by OvmfPkg and ArmVirtPkg.\r
+ // OvmfPkg was changed to use the new BDS @ MdeModulePkg, so boot options\r
+ // are no longer stored in linked list.\r
+ // But we don't change the QemuBootOrderLib class interface because\r
+ // ArmVirtPkg are still using old BDS @ IntelFrameworkModulePkg.\r
+ //\r
+ ASSERT (BootOptionList == NULL);\r
\r
Status = QemuFwCfgFindFile ("bootorder", &FwCfgItem, &FwCfgSize);\r
if (Status != RETURN_SUCCESS) {\r
goto ErrorFreeFwCfg;\r
}\r
\r
- Status = CollectActiveOptions (BootOptionList, &ActiveOption, &ActiveCount);\r
- if (RETURN_ERROR (Status)) {\r
+ BootOptions = EfiBootManagerGetLoadOptions (\r
+ &BootOptionCount, LoadOptionTypeBoot\r
+ );\r
+ if (BootOptions == NULL) {\r
+ Status = RETURN_NOT_FOUND;\r
goto ErrorFreeBootOrder;\r
}\r
\r
+ Status = CollectActiveOptions (\r
+ BootOptions, BootOptionCount, &ActiveOption, &ActiveCount\r
+ );\r
+ if (RETURN_ERROR (Status)) {\r
+ goto ErrorFreeBootOptions;\r
+ }\r
+\r
if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) {\r
Status = CreateExtraRootBusMap (&ExtraPciRoots);\r
if (EFI_ERROR (Status)) {\r
if (Match (\r
Translated,\r
TranslatedSize, // contains length, not size, in CHAR16's here\r
- ActiveOption[Idx].BootOption->DevicePath\r
+ ActiveOption[Idx].BootOption->FilePath\r
)\r
) {\r
//\r
ErrorFreeActiveOption:\r
FreePool (ActiveOption);\r
\r
+ErrorFreeBootOptions:\r
+ EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
+\r
ErrorFreeBootOrder:\r
FreePool (BootOrder.Data);\r
\r