deleted file mode 100644
@@ -1,68 +0,0 @@
-## @file
-# Rewrite the BootOrder NvVar based on QEMU's "bootorder" fw_cfg file.
-#
-# Copyright (C) 2012 - 2014, Red Hat, Inc.
-# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
-#
-# This program and the accompanying materials are licensed and made available
-# under the terms and conditions of the BSD License which accompanies this
-# distribution. The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
-# IMPLIED.
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = QemuBootOrderLib
- FILE_GUID = 4FFFA9E1-103D-4CF2-9C06-563BDD03050E
- MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
- LIBRARY_CLASS = QemuBootOrderLib|DXE_DRIVER
-
-#
-# The following information is for reference only and not required by the build
-# tools.
-#
-# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM AARCH64
-#
-
-[Sources]
- QemuBootOrderLib.c
- ExtraRootBusMap.c
-
-[Packages]
- MdePkg/MdePkg.dec
- IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
- OvmfPkg/OvmfPkg.dec
-
-[LibraryClasses]
- QemuFwCfgLib
- DebugLib
- MemoryAllocationLib
- GenericBdsLib
- UefiBootServicesTableLib
- UefiRuntimeServicesTableLib
- BaseLib
- PrintLib
- DevicePathLib
- BaseMemoryLib
- OrderedCollectionLib
-
-[Guids]
- gEfiGlobalVariableGuid
- gVirtioMmioTransportGuid
-
-[FeaturePcd]
- gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation
- gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation
-
-[Pcd]
- gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
-
-[Protocols]
- gEfiDevicePathProtocolGuid ## CONSUMES
- gEfiPciRootBridgeIoProtocolGuid ## CONSUMES
deleted file mode 100644
@@ -1,40 +0,0 @@
-/** @file
- Map positions of extra PCI root buses to bus numbers.
-
- Copyright (C) 2015, Red Hat, Inc.
-
- This program and the accompanying materials are licensed and made available
- under the terms and conditions of the BSD License which accompanies this
- distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
- WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-**/
-
-#ifndef __EXTRA_ROOT_BUS_MAP_H__
-#define __EXTRA_ROOT_BUS_MAP_H__
-
-/**
- Incomplete ("opaque") data type implementing the map.
-**/
-typedef struct EXTRA_ROOT_BUS_MAP_STRUCT EXTRA_ROOT_BUS_MAP;
-
-EFI_STATUS
-CreateExtraRootBusMap (
- OUT EXTRA_ROOT_BUS_MAP **ExtraRootBusMap
- );
-
-VOID
-DestroyExtraRootBusMap (
- IN EXTRA_ROOT_BUS_MAP *ExtraRootBusMap
- );
-
-EFI_STATUS
-MapRootBusPosToBusNr (
- IN CONST EXTRA_ROOT_BUS_MAP *ExtraRootBusMap,
- IN UINT64 RootBusPos,
- OUT UINT32 *RootBusNr
- );
-
-#endif
deleted file mode 100644
@@ -1,313 +0,0 @@
-/** @file
- Map positions of extra PCI root buses to bus numbers.
-
- Copyright (C) 2015, Red Hat, Inc.
-
- This program and the accompanying materials are licensed and made available
- under the terms and conditions of the BSD License which accompanies this
- distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
- WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-**/
-
-#include <Library/DebugLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/OrderedCollectionLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Protocol/DevicePath.h>
-#include <Protocol/PciRootBridgeIo.h>
-
-#include "ExtraRootBusMap.h"
-
-//
-// The BusNumbers field is an array with Count elements. The elements increase
-// strictry monotonically. Zero is not an element (because the zero bus number
-// belongs to the "main" root bus, never to an extra root bus). Offset N in the
-// array maps the extra root bus with position (N+1) to its bus number (because
-// the root bus with position 0 is always the main root bus, therefore we don't
-// store it).
-//
-// If there are no extra root buses in the system, then Count is 0, and
-// BusNumbers is NULL.
-//
-struct EXTRA_ROOT_BUS_MAP_STRUCT {
- UINT32 *BusNumbers;
- UINTN Count;
-};
-
-
-/**
- An ORDERED_COLLECTION_USER_COMPARE function that compares root bridge
- protocol device paths based on UID.
-
- @param[in] UserStruct1 Pointer to the first ACPI_HID_DEVICE_PATH.
-
- @param[in] UserStruct2 Pointer to the second ACPI_HID_DEVICE_PATH.
-
- @retval <0 If UserStruct1 compares less than UserStruct2.
-
- @retval 0 If UserStruct1 compares equal to UserStruct2.
-
- @retval >0 If UserStruct1 compares greater than UserStruct2.
-**/
-STATIC
-INTN
-EFIAPI
-RootBridgePathCompare (
- IN CONST VOID *UserStruct1,
- IN CONST VOID *UserStruct2
- )
-{
- CONST ACPI_HID_DEVICE_PATH *Acpi1;
- CONST ACPI_HID_DEVICE_PATH *Acpi2;
-
- Acpi1 = UserStruct1;
- Acpi2 = UserStruct2;
-
- return Acpi1->UID < Acpi2->UID ? -1 :
- Acpi1->UID > Acpi2->UID ? 1 :
- 0;
-}
-
-
-/**
- An ORDERED_COLLECTION_KEY_COMPARE function that compares a root bridge
- protocol device path against a UID.
-
- @param[in] StandaloneKey Pointer to the bare UINT32 UID.
-
- @param[in] UserStruct Pointer to the ACPI_HID_DEVICE_PATH with the
- embedded UINT32 UID.
-
- @retval <0 If StandaloneKey compares less than UserStruct's key.
-
- @retval 0 If StandaloneKey compares equal to UserStruct's key.
-
- @retval >0 If StandaloneKey compares greater than UserStruct's key.
-**/
-STATIC
-INTN
-EFIAPI
-RootBridgePathKeyCompare (
- IN CONST VOID *StandaloneKey,
- IN CONST VOID *UserStruct
- )
-{
- CONST UINT32 *Uid;
- CONST ACPI_HID_DEVICE_PATH *Acpi;
-
- Uid = StandaloneKey;
- Acpi = UserStruct;
-
- return *Uid < Acpi->UID ? -1 :
- *Uid > Acpi->UID ? 1 :
- 0;
-}
-
-
-/**
- Create a structure that maps the relative positions of PCI root buses to bus
- numbers.
-
- In the "bootorder" fw_cfg file, QEMU refers to extra PCI root buses by their
- positions, in relative root bus number order, not by their actual PCI bus
- numbers. The ACPI HID device path nodes however that are associated with
- PciRootBridgeIo protocol instances in the system have their UID fields set to
- the bus numbers. Create a map that gives, for each extra PCI root bus's
- position (ie. "serial number") its actual PCI bus number.
-
- @param[out] ExtraRootBusMap The data structure implementing the map.
-
- @retval EFI_SUCCESS ExtraRootBusMap has been populated.
-
- @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
-
- @retval EFI_ALREADY_STARTED A duplicate root bus number has been found in
- the system. (This should never happen.)
-
- @return Error codes returned by
- gBS->LocateHandleBuffer() and
- gBS->HandleProtocol().
-
-**/
-EFI_STATUS
-CreateExtraRootBusMap (
- OUT EXTRA_ROOT_BUS_MAP **ExtraRootBusMap
- )
-{
- EFI_STATUS Status;
- UINTN NumHandles;
- EFI_HANDLE *Handles;
- ORDERED_COLLECTION *Collection;
- EXTRA_ROOT_BUS_MAP *Map;
- UINTN Idx;
- ORDERED_COLLECTION_ENTRY *Entry, *Entry2;
-
- //
- // Handles and Collection are temporary / helper variables, while in Map we
- // build the return value.
- //
-
- Status = gBS->LocateHandleBuffer (ByProtocol,
- &gEfiPciRootBridgeIoProtocolGuid, NULL /* SearchKey */,
- &NumHandles, &Handles);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- Collection = OrderedCollectionInit (RootBridgePathCompare,
- RootBridgePathKeyCompare);
- if (Collection == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto FreeHandles;
- }
-
- Map = AllocateZeroPool (sizeof *Map);
- if (Map == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto FreeCollection;
- }
-
- //
- // Collect the ACPI device path protocols of the root bridges.
- //
- for (Idx = 0; Idx < NumHandles; ++Idx) {
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
-
- Status = gBS->HandleProtocol (Handles[Idx], &gEfiDevicePathProtocolGuid,
- (VOID**)&DevicePath);
- if (EFI_ERROR (Status)) {
- goto FreeMap;
- }
-
- //
- // Examine if the device path is an ACPI HID one, and if so, if UID is
- // nonzero (ie. the root bridge that the bus number belongs to is "extra",
- // not the main one). In that case, link the device path into Collection.
- //
- if (DevicePathType (DevicePath) == ACPI_DEVICE_PATH &&
- DevicePathSubType (DevicePath) == ACPI_DP &&
- ((ACPI_HID_DEVICE_PATH *)DevicePath)->HID == EISA_PNP_ID(0x0A03) &&
- ((ACPI_HID_DEVICE_PATH *)DevicePath)->UID > 0) {
- Status = OrderedCollectionInsert (Collection, NULL, DevicePath);
- if (EFI_ERROR (Status)) {
- goto FreeMap;
- }
- ++Map->Count;
- }
- }
-
- if (Map->Count > 0) {
- //
- // At least one extra PCI root bus exists.
- //
- Map->BusNumbers = AllocatePool (Map->Count * sizeof *Map->BusNumbers);
- if (Map->BusNumbers == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto FreeMap;
- }
- }
-
- //
- // Now collect the bus numbers of the extra PCI root buses into Map.
- //
- Idx = 0;
- Entry = OrderedCollectionMin (Collection);
- while (Idx < Map->Count) {
- ACPI_HID_DEVICE_PATH *Acpi;
-
- ASSERT (Entry != NULL);
- Acpi = OrderedCollectionUserStruct (Entry);
- Map->BusNumbers[Idx] = Acpi->UID;
- DEBUG ((EFI_D_VERBOSE,
- "%a: extra bus position 0x%Lx maps to bus number (UID) 0x%x\n",
- __FUNCTION__, (UINT64)(Idx + 1), Acpi->UID));
- ++Idx;
- Entry = OrderedCollectionNext (Entry);
- }
- ASSERT (Entry == NULL);
-
- *ExtraRootBusMap = Map;
- Status = EFI_SUCCESS;
-
- //
- // Fall through in order to release temporaries.
- //
-
-FreeMap:
- if (EFI_ERROR (Status)) {
- if (Map->BusNumbers != NULL) {
- FreePool (Map->BusNumbers);
- }
- FreePool (Map);
- }
-
-FreeCollection:
- for (Entry = OrderedCollectionMin (Collection); Entry != NULL;
- Entry = Entry2) {
- Entry2 = OrderedCollectionNext (Entry);
- OrderedCollectionDelete (Collection, Entry, NULL);
- }
- OrderedCollectionUninit (Collection);
-
-FreeHandles:
- FreePool (Handles);
-
- return Status;
-}
-
-
-/**
- Release a map created with CreateExtraRootBusMap().
-
- @param[in] ExtraRootBusMap The map to release.
-*/
-VOID
-DestroyExtraRootBusMap (
- IN EXTRA_ROOT_BUS_MAP *ExtraRootBusMap
- )
-{
- if (ExtraRootBusMap->BusNumbers != NULL) {
- FreePool (ExtraRootBusMap->BusNumbers);
- }
- FreePool (ExtraRootBusMap);
-}
-
-/**
- Map the position (serial number) of an extra PCI root bus to its bus number.
-
- @param[in] ExtraRootBusMap The map created with CreateExtraRootBusMap();
-
- @param[in] RootBusPos The extra PCI root bus position to map.
-
- @param[out] RootBusNr The bus number belonging to the extra PCI root
- bus identified by RootBusPos.
-
- @retval EFI_INVALID_PARAMETER RootBusPos is zero. The zero position
- identifies the main root bus, whose bus number
- is always zero, and is therefore never
- maintained in ExtraRootBusMap.
-
- @retval EFI_NOT_FOUND RootBusPos is not found in ExtraRootBusMap.
-
- @retval EFI_SUCCESS Mapping successful.
-**/
-EFI_STATUS
-MapRootBusPosToBusNr (
- IN CONST EXTRA_ROOT_BUS_MAP *ExtraRootBusMap,
- IN UINT64 RootBusPos,
- OUT UINT32 *RootBusNr
- )
-{
- if (RootBusPos == 0) {
- return EFI_INVALID_PARAMETER;
- }
- if (RootBusPos > ExtraRootBusMap->Count) {
- return EFI_NOT_FOUND;
- }
- *RootBusNr = ExtraRootBusMap->BusNumbers[RootBusPos - 1];
- return EFI_SUCCESS;
-}
deleted file mode 100644
@@ -1,1891 +0,0 @@
-/** @file
- Rewrite the BootOrder NvVar based on QEMU's "bootorder" fw_cfg file.
-
- Copyright (C) 2012 - 2014, Red Hat, Inc.
- Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
-
- This program and the accompanying materials are licensed and made available
- under the terms and conditions of the BSD License which accompanies this
- distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
- WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-**/
-
-#include <Library/QemuFwCfgLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/GenericBdsLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/BaseLib.h>
-#include <Library/PrintLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/QemuBootOrderLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Guid/GlobalVariable.h>
-#include <Guid/VirtioMmioTransport.h>
-
-#include "ExtraRootBusMap.h"
-
-/**
- OpenFirmware to UEFI device path translation output buffer size in CHAR16's.
-**/
-#define TRANSLATION_OUTPUT_SIZE 0x100
-
-/**
- Output buffer size for OpenFirmware to UEFI device path fragment translation,
- in CHAR16's, for a sequence of PCI bridges.
-**/
-#define BRIDGE_TRANSLATION_OUTPUT_SIZE 0x40
-
-/**
- Numbers of nodes in OpenFirmware device paths that are required and examined.
-**/
-#define REQUIRED_PCI_OFW_NODES 2
-#define REQUIRED_MMIO_OFW_NODES 1
-#define EXAMINED_OFW_NODES 6
-
-
-/**
- Simple character classification routines, corresponding to POSIX class names
- and ASCII encoding.
-**/
-STATIC
-BOOLEAN
-IsAlnum (
- IN CHAR8 Chr
- )
-{
- return (('0' <= Chr && Chr <= '9') ||
- ('A' <= Chr && Chr <= 'Z') ||
- ('a' <= Chr && Chr <= 'z')
- );
-}
-
-
-STATIC
-BOOLEAN
-IsDriverNamePunct (
- IN CHAR8 Chr
- )
-{
- return (Chr == ',' || Chr == '.' || Chr == '_' ||
- Chr == '+' || Chr == '-'
- );
-}
-
-
-STATIC
-BOOLEAN
-IsPrintNotDelim (
- IN CHAR8 Chr
- )
-{
- return (32 <= Chr && Chr <= 126 &&
- Chr != '/' && Chr != '@' && Chr != ':');
-}
-
-
-/**
- Utility types and functions.
-**/
-typedef struct {
- CONST CHAR8 *Ptr; // not necessarily NUL-terminated
- UINTN Len; // number of non-NUL characters
-} SUBSTRING;
-
-
-/**
-
- Check if Substring and String have identical contents.
-
- The function relies on the restriction that a SUBSTRING cannot have embedded
- NULs either.
-
- @param[in] Substring The SUBSTRING input to the comparison.
-
- @param[in] String The ASCII string input to the comparison.
-
-
- @return Whether the inputs have identical contents.
-
-**/
-STATIC
-BOOLEAN
-SubstringEq (
- IN SUBSTRING Substring,
- IN CONST CHAR8 *String
- )
-{
- UINTN Pos;
- CONST CHAR8 *Chr;
-
- Pos = 0;
- Chr = String;
-
- while (Pos < Substring.Len && Substring.Ptr[Pos] == *Chr) {
- ++Pos;
- ++Chr;
- }
-
- return (BOOLEAN)(Pos == Substring.Len && *Chr == '\0');
-}
-
-
-/**
-
- Parse a comma-separated list of hexadecimal integers into the elements of an
- UINT64 array.
-
- Whitespace, "0x" prefixes, leading or trailing commas, sequences of commas,
- or an empty string are not allowed; they are rejected.
-
- The function relies on ASCII encoding.
-
- @param[in] UnitAddress The substring to parse.
-
- @param[out] Result The array, allocated by the caller, to receive
- the parsed values. This parameter may be NULL if
- NumResults is zero on input.
-
- @param[in out] NumResults On input, the number of elements allocated for
- Result. On output, the number of elements it has
- taken (or would have taken) to parse the string
- fully.
-
-
- @retval RETURN_SUCCESS UnitAddress has been fully parsed.
- NumResults is set to the number of parsed
- values; the corresponding elements have
- been set in Result. The rest of Result's
- elements are unchanged.
-
- @retval RETURN_BUFFER_TOO_SMALL UnitAddress has been fully parsed.
- NumResults is set to the number of parsed
- values, but elements have been stored only
- up to the input value of NumResults, which
- is less than what has been parsed.
-
- @retval RETURN_INVALID_PARAMETER Parse error. The contents of Results is
- indeterminate. NumResults has not been
- changed.
-
-**/
-STATIC
-RETURN_STATUS
-ParseUnitAddressHexList (
- IN SUBSTRING UnitAddress,
- OUT UINT64 *Result,
- IN OUT UINTN *NumResults
- )
-{
- UINTN Entry; // number of entry currently being parsed
- UINT64 EntryVal; // value being constructed for current entry
- CHAR8 PrevChr; // UnitAddress character previously checked
- UINTN Pos; // current position within UnitAddress
- RETURN_STATUS Status;
-
- Entry = 0;
- EntryVal = 0;
- PrevChr = ',';
-
- for (Pos = 0; Pos < UnitAddress.Len; ++Pos) {
- CHAR8 Chr;
- INT8 Val;
-
- Chr = UnitAddress.Ptr[Pos];
- Val = ('a' <= Chr && Chr <= 'f') ? (Chr - 'a' + 10) :
- ('A' <= Chr && Chr <= 'F') ? (Chr - 'A' + 10) :
- ('0' <= Chr && Chr <= '9') ? (Chr - '0' ) :
- -1;
-
- if (Val >= 0) {
- if (EntryVal > 0xFFFFFFFFFFFFFFFull) {
- return RETURN_INVALID_PARAMETER;
- }
- EntryVal = LShiftU64 (EntryVal, 4) | Val;
- } else if (Chr == ',') {
- if (PrevChr == ',') {
- return RETURN_INVALID_PARAMETER;
- }
- if (Entry < *NumResults) {
- Result[Entry] = EntryVal;
- }
- ++Entry;
- EntryVal = 0;
- } else {
- return RETURN_INVALID_PARAMETER;
- }
-
- PrevChr = Chr;
- }
-
- if (PrevChr == ',') {
- return RETURN_INVALID_PARAMETER;
- }
- if (Entry < *NumResults) {
- Result[Entry] = EntryVal;
- Status = RETURN_SUCCESS;
- } else {
- Status = RETURN_BUFFER_TOO_SMALL;
- }
- ++Entry;
-
- *NumResults = Entry;
- return Status;
-}
-
-
-/**
- A simple array of Boot Option ID's.
-**/
-typedef struct {
- UINT16 *Data;
- UINTN Allocated;
- UINTN Produced;
-} 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
- BOOLEAN Appended; // has been added to a BOOT_ORDER?
-} ACTIVE_OPTION;
-
-
-/**
-
- Append an active boot option to BootOrder, reallocating the latter if needed.
-
- @param[in out] BootOrder The structure pointing to the array and holding
- allocation and usage counters.
-
- @param[in] ActiveOption The active boot option whose ID should be
- appended to the array.
-
-
- @retval RETURN_SUCCESS ID of ActiveOption appended.
-
- @retval RETURN_OUT_OF_RESOURCES Memory reallocation failed.
-
-**/
-STATIC
-RETURN_STATUS
-BootOrderAppend (
- IN OUT BOOT_ORDER *BootOrder,
- IN OUT ACTIVE_OPTION *ActiveOption
- )
-{
- if (BootOrder->Produced == BootOrder->Allocated) {
- UINTN AllocatedNew;
- UINT16 *DataNew;
-
- ASSERT (BootOrder->Allocated > 0);
- AllocatedNew = BootOrder->Allocated * 2;
- DataNew = ReallocatePool (
- BootOrder->Allocated * sizeof (*BootOrder->Data),
- AllocatedNew * sizeof (*DataNew),
- BootOrder->Data
- );
- if (DataNew == NULL) {
- return RETURN_OUT_OF_RESOURCES;
- }
- BootOrder->Allocated = AllocatedNew;
- BootOrder->Data = DataNew;
- }
-
- BootOrder->Data[BootOrder->Produced++] =
- ActiveOption->BootOption->BootCurrent;
- ActiveOption->Appended = TRUE;
- return RETURN_SUCCESS;
-}
-
-
-/**
-
- 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;
- (*ActiveOption)[*Count].Appended = FALSE;
- }
- ++*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
-**/
-typedef struct {
- SUBSTRING DriverName;
- SUBSTRING UnitAddress;
- SUBSTRING DeviceArguments;
-} OFW_NODE;
-
-
-/**
-
- Parse an OpenFirmware device path node into the caller-allocated OFW_NODE
- structure, and advance in the input string.
-
- The node format is mostly parsed after IEEE 1275-1994, 3.2.1.1 "Node names"
- (a leading slash is expected and not returned):
-
- /driver-name@unit-address[:device-arguments][<LF>]
-
- A single trailing <LF> character is consumed but not returned. A trailing
- <LF> or NUL character terminates the device path.
-
- The function relies on ASCII encoding.
-
- @param[in out] Ptr Address of the pointer pointing to the start of the
- node string. After successful parsing *Ptr is set to
- the byte immediately following the consumed
- characters. On error it points to the byte that
- caused the error. The input string is never modified.
-
- @param[out] OfwNode The members of this structure point into the input
- string, designating components of the node.
- Separators are never included. If "device-arguments"
- is missing, then DeviceArguments.Ptr is set to NULL.
- All components that are present have nonzero length.
-
- If the call doesn't succeed, the contents of this
- structure is indeterminate.
-
- @param[out] IsFinal In case of successul parsing, this parameter signals
- whether the node just parsed is the final node in the
- device path. The call after a final node will attempt
- to start parsing the next path. If the call doesn't
- succeed, then this parameter is not changed.
-
-
- @retval RETURN_SUCCESS Parsing successful.
-
- @retval RETURN_NOT_FOUND Parsing terminated. *Ptr was (and is)
- pointing to an empty string.
-
- @retval RETURN_INVALID_PARAMETER Parse error.
-
-**/
-STATIC
-RETURN_STATUS
-ParseOfwNode (
- IN OUT CONST CHAR8 **Ptr,
- OUT OFW_NODE *OfwNode,
- OUT BOOLEAN *IsFinal
- )
-{
- //
- // A leading slash is expected. End of string is tolerated.
- //
- switch (**Ptr) {
- case '\0':
- return RETURN_NOT_FOUND;
-
- case '/':
- ++*Ptr;
- break;
-
- default:
- return RETURN_INVALID_PARAMETER;
- }
-
- //
- // driver-name
- //
- OfwNode->DriverName.Ptr = *Ptr;
- OfwNode->DriverName.Len = 0;
- while (OfwNode->DriverName.Len < 32 &&
- (IsAlnum (**Ptr) || IsDriverNamePunct (**Ptr))
- ) {
- ++*Ptr;
- ++OfwNode->DriverName.Len;
- }
-
- if (OfwNode->DriverName.Len == 0 || OfwNode->DriverName.Len == 32) {
- return RETURN_INVALID_PARAMETER;
- }
-
-
- //
- // unit-address
- //
- if (**Ptr != '@') {
- return RETURN_INVALID_PARAMETER;
- }
- ++*Ptr;
-
- OfwNode->UnitAddress.Ptr = *Ptr;
- OfwNode->UnitAddress.Len = 0;
- while (IsPrintNotDelim (**Ptr)) {
- ++*Ptr;
- ++OfwNode->UnitAddress.Len;
- }
-
- if (OfwNode->UnitAddress.Len == 0) {
- return RETURN_INVALID_PARAMETER;
- }
-
-
- //
- // device-arguments, may be omitted
- //
- OfwNode->DeviceArguments.Len = 0;
- if (**Ptr == ':') {
- ++*Ptr;
- OfwNode->DeviceArguments.Ptr = *Ptr;
-
- while (IsPrintNotDelim (**Ptr)) {
- ++*Ptr;
- ++OfwNode->DeviceArguments.Len;
- }
-
- if (OfwNode->DeviceArguments.Len == 0) {
- return RETURN_INVALID_PARAMETER;
- }
- }
- else {
- OfwNode->DeviceArguments.Ptr = NULL;
- }
-
- switch (**Ptr) {
- case '\n':
- ++*Ptr;
- //
- // fall through
- //
-
- case '\0':
- *IsFinal = TRUE;
- break;
-
- case '/':
- *IsFinal = FALSE;
- break;
-
- default:
- return RETURN_INVALID_PARAMETER;
- }
-
- DEBUG ((
- DEBUG_VERBOSE,
- "%a: DriverName=\"%.*a\" UnitAddress=\"%.*a\" DeviceArguments=\"%.*a\"\n",
- __FUNCTION__,
- OfwNode->DriverName.Len, OfwNode->DriverName.Ptr,
- OfwNode->UnitAddress.Len, OfwNode->UnitAddress.Ptr,
- OfwNode->DeviceArguments.Len,
- OfwNode->DeviceArguments.Ptr == NULL ? "" : OfwNode->DeviceArguments.Ptr
- ));
- return RETURN_SUCCESS;
-}
-
-
-/**
-
- Translate a PCI-like array of OpenFirmware device nodes to a UEFI device path
- fragment.
-
- @param[in] OfwNode Array of OpenFirmware device nodes to
- translate, constituting the beginning of an
- OpenFirmware device path.
-
- @param[in] NumNodes Number of elements in OfwNode.
-
- @param[in] ExtraPciRoots An EXTRA_ROOT_BUS_MAP object created with
- CreateExtraRootBusMap(), to be used for
- translating positions of extra root buses to
- bus numbers.
-
- @param[out] Translated Destination array receiving the UEFI path
- fragment, allocated by the caller. If the
- return value differs from RETURN_SUCCESS, its
- contents is indeterminate.
-
- @param[in out] TranslatedSize On input, the number of CHAR16's in
- Translated. On RETURN_SUCCESS this parameter
- is assigned the number of non-NUL CHAR16's
- written to Translated. In case of other return
- values, TranslatedSize is indeterminate.
-
-
- @retval RETURN_SUCCESS Translation successful.
-
- @retval RETURN_BUFFER_TOO_SMALL The translation does not fit into the number
- of bytes provided.
-
- @retval RETURN_UNSUPPORTED The array of OpenFirmware device nodes can't
- be translated in the current implementation.
-
- @retval RETURN_PROTOCOL_ERROR The initial OpenFirmware node refers to an
- extra PCI root bus (by serial number) that
- is invalid according to ExtraPciRoots.
-
-**/
-STATIC
-RETURN_STATUS
-TranslatePciOfwNodes (
- IN CONST OFW_NODE *OfwNode,
- IN UINTN NumNodes,
- IN CONST EXTRA_ROOT_BUS_MAP *ExtraPciRoots,
- OUT CHAR16 *Translated,
- IN OUT UINTN *TranslatedSize
- )
-{
- UINT32 PciRoot;
- CHAR8 *Comma;
- UINTN FirstNonBridge;
- CHAR16 Bridges[BRIDGE_TRANSLATION_OUTPUT_SIZE];
- UINTN BridgesLen;
- UINT64 PciDevFun[2];
- UINTN NumEntries;
- UINTN Written;
-
- //
- // Resolve the PCI root bus number.
- //
- // The initial OFW node for the main root bus (ie. bus number 0) is:
- //
- // /pci@i0cf8
- //
- // For extra root buses, the initial OFW node is
- //
- // /pci@i0cf8,4
- // ^
- // root bus serial number (not PCI bus number)
- //
- if (NumNodes < REQUIRED_PCI_OFW_NODES ||
- !SubstringEq (OfwNode[0].DriverName, "pci")
- ) {
- return RETURN_UNSUPPORTED;
- }
-
- PciRoot = 0;
- Comma = ScanMem8 (OfwNode[0].UnitAddress.Ptr, OfwNode[0].UnitAddress.Len,
- ',');
- if (Comma != NULL) {
- SUBSTRING PciRootSerialSubString;
- UINT64 PciRootSerial;
-
- //
- // Parse the root bus serial number from the unit address after the comma.
- //
- PciRootSerialSubString.Ptr = Comma + 1;
- PciRootSerialSubString.Len = OfwNode[0].UnitAddress.Len -
- (PciRootSerialSubString.Ptr -
- OfwNode[0].UnitAddress.Ptr);
- NumEntries = 1;
- if (RETURN_ERROR (ParseUnitAddressHexList (PciRootSerialSubString,
- &PciRootSerial, &NumEntries))) {
- return RETURN_UNSUPPORTED;
- }
-
- //
- // Map the extra root bus's serial number to its actual bus number.
- //
- if (EFI_ERROR (MapRootBusPosToBusNr (ExtraPciRoots, PciRootSerial,
- &PciRoot))) {
- return RETURN_PROTOCOL_ERROR;
- }
- }
-
- //
- // Translate a sequence of PCI bridges. For each bridge, the OFW node is:
- //
- // pci-bridge@1e[,0]
- // ^ ^
- // PCI slot & function on the parent, holding the bridge
- //
- // and the UEFI device path node is:
- //
- // Pci(0x1E,0x0)
- //
- FirstNonBridge = 1;
- Bridges[0] = L'\0';
- BridgesLen = 0;
- do {
- UINT64 BridgeDevFun[2];
- UINTN BridgesFreeBytes;
-
- if (!SubstringEq (OfwNode[FirstNonBridge].DriverName, "pci-bridge")) {
- break;
- }
-
- BridgeDevFun[1] = 0;
- NumEntries = sizeof BridgeDevFun / sizeof BridgeDevFun[0];
- if (ParseUnitAddressHexList (OfwNode[FirstNonBridge].UnitAddress,
- BridgeDevFun, &NumEntries) != RETURN_SUCCESS) {
- return RETURN_UNSUPPORTED;
- }
-
- BridgesFreeBytes = sizeof Bridges - BridgesLen * sizeof Bridges[0];
- Written = UnicodeSPrintAsciiFormat (Bridges + BridgesLen, BridgesFreeBytes,
- "/Pci(0x%Lx,0x%Lx)", BridgeDevFun[0], BridgeDevFun[1]);
- BridgesLen += Written;
-
- //
- // There's no way to differentiate between "completely used up without
- // truncation" and "truncated", so treat the former as the latter.
- //
- if (BridgesLen + 1 == BRIDGE_TRANSLATION_OUTPUT_SIZE) {
- return RETURN_UNSUPPORTED;
- }
-
- ++FirstNonBridge;
- } while (FirstNonBridge < NumNodes);
-
- if (FirstNonBridge == NumNodes) {
- return RETURN_UNSUPPORTED;
- }
-
- //
- // Parse the OFW nodes starting with the first non-bridge node.
- //
- PciDevFun[1] = 0;
- NumEntries = sizeof (PciDevFun) / sizeof (PciDevFun[0]);
- if (ParseUnitAddressHexList (
- OfwNode[FirstNonBridge].UnitAddress,
- PciDevFun,
- &NumEntries
- ) != RETURN_SUCCESS
- ) {
- return RETURN_UNSUPPORTED;
- }
-
- if (NumNodes >= FirstNonBridge + 3 &&
- SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "ide") &&
- SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "drive") &&
- SubstringEq (OfwNode[FirstNonBridge + 2].DriverName, "disk")
- ) {
- //
- // OpenFirmware device path (IDE disk, IDE CD-ROM):
- //
- // /pci@i0cf8/ide@1,1/drive@0/disk@0
- // ^ ^ ^ ^ ^
- // | | | | master or slave
- // | | | primary or secondary
- // | PCI slot & function holding IDE controller
- // PCI root at system bus port, PIO
- //
- // UEFI device path:
- //
- // PciRoot(0x0)/Pci(0x1,0x1)/Ata(Primary,Master,0x0)
- // ^
- // fixed LUN
- //
- UINT64 Secondary;
- UINT64 Slave;
-
- NumEntries = 1;
- if (ParseUnitAddressHexList (
- OfwNode[FirstNonBridge + 1].UnitAddress,
- &Secondary,
- &NumEntries
- ) != RETURN_SUCCESS ||
- Secondary > 1 ||
- ParseUnitAddressHexList (
- OfwNode[FirstNonBridge + 2].UnitAddress,
- &Slave,
- &NumEntries // reuse after previous single-element call
- ) != RETURN_SUCCESS ||
- Slave > 1
- ) {
- return RETURN_UNSUPPORTED;
- }
-
- Written = UnicodeSPrintAsciiFormat (
- Translated,
- *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/Ata(%a,%a,0x0)",
- PciRoot,
- Bridges,
- PciDevFun[0],
- PciDevFun[1],
- Secondary ? "Secondary" : "Primary",
- Slave ? "Slave" : "Master"
- );
- } else if (NumNodes >= FirstNonBridge + 3 &&
- SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "pci8086,2922") &&
- SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "drive") &&
- SubstringEq (OfwNode[FirstNonBridge + 2].DriverName, "disk")
- ) {
- //
- // OpenFirmware device path (Q35 SATA disk and CD-ROM):
- //
- // /pci@i0cf8/pci8086,2922@1f,2/drive@1/disk@0
- // ^ ^ ^ ^ ^
- // | | | | device number (fixed 0)
- // | | | channel (port) number
- // | PCI slot & function holding SATA HBA
- // PCI root at system bus port, PIO
- //
- // UEFI device path:
- //
- // PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0xFFFF,0x0)
- // ^ ^ ^
- // | | LUN (always 0 on Q35)
- // | port multiplier port number,
- // | always 0xFFFF on Q35
- // channel (port) number
- //
- UINT64 Channel;
-
- NumEntries = 1;
- if (RETURN_ERROR (ParseUnitAddressHexList (
- OfwNode[FirstNonBridge + 1].UnitAddress, &Channel,
- &NumEntries))) {
- return RETURN_UNSUPPORTED;
- }
-
- Written = UnicodeSPrintAsciiFormat (
- Translated,
- *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/Sata(0x%Lx,0xFFFF,0x0)",
- PciRoot,
- Bridges,
- PciDevFun[0],
- PciDevFun[1],
- Channel
- );
- } else if (NumNodes >= FirstNonBridge + 3 &&
- SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "isa") &&
- SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "fdc") &&
- SubstringEq (OfwNode[FirstNonBridge + 2].DriverName, "floppy")
- ) {
- //
- // OpenFirmware device path (floppy disk):
- //
- // /pci@i0cf8/isa@1/fdc@03f0/floppy@0
- // ^ ^ ^ ^
- // | | | A: or B:
- // | | ISA controller io-port (hex)
- // | PCI slot holding ISA controller
- // PCI root at system bus port, PIO
- //
- // UEFI device path:
- //
- // PciRoot(0x0)/Pci(0x1,0x0)/Floppy(0x0)
- // ^
- // ACPI UID
- //
- UINT64 AcpiUid;
-
- NumEntries = 1;
- if (ParseUnitAddressHexList (
- OfwNode[FirstNonBridge + 2].UnitAddress,
- &AcpiUid,
- &NumEntries
- ) != RETURN_SUCCESS ||
- AcpiUid > 1
- ) {
- return RETURN_UNSUPPORTED;
- }
-
- Written = UnicodeSPrintAsciiFormat (
- Translated,
- *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/Floppy(0x%Lx)",
- PciRoot,
- Bridges,
- PciDevFun[0],
- PciDevFun[1],
- AcpiUid
- );
- } else if (NumNodes >= FirstNonBridge + 2 &&
- SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "scsi") &&
- SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "disk")
- ) {
- //
- // OpenFirmware device path (virtio-blk disk):
- //
- // /pci@i0cf8/scsi@6[,3]/disk@0,0
- // ^ ^ ^ ^ ^
- // | | | fixed
- // | | PCI function corresponding to disk (optional)
- // | PCI slot holding disk
- // PCI root at system bus port, PIO
- //
- // UEFI device path prefix:
- //
- // PciRoot(0x0)/Pci(0x6,0x0)/HD( -- if PCI function is 0 or absent
- // PciRoot(0x0)/Pci(0x6,0x3)/HD( -- if PCI function is present and nonzero
- //
- Written = UnicodeSPrintAsciiFormat (
- Translated,
- *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/HD(",
- PciRoot,
- Bridges,
- PciDevFun[0],
- PciDevFun[1]
- );
- } else if (NumNodes >= FirstNonBridge + 3 &&
- SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "scsi") &&
- SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "channel") &&
- SubstringEq (OfwNode[FirstNonBridge + 2].DriverName, "disk")
- ) {
- //
- // OpenFirmware device path (virtio-scsi disk):
- //
- // /pci@i0cf8/scsi@7[,3]/channel@0/disk@2,3
- // ^ ^ ^ ^ ^
- // | | | | LUN
- // | | | target
- // | | channel (unused, fixed 0)
- // | PCI slot[, function] holding SCSI controller
- // PCI root at system bus port, PIO
- //
- // UEFI device path prefix:
- //
- // PciRoot(0x0)/Pci(0x7,0x0)/Scsi(0x2,0x3)
- // -- if PCI function is 0 or absent
- // PciRoot(0x0)/Pci(0x7,0x3)/Scsi(0x2,0x3)
- // -- if PCI function is present and nonzero
- //
- UINT64 TargetLun[2];
-
- TargetLun[1] = 0;
- NumEntries = sizeof (TargetLun) / sizeof (TargetLun[0]);
- if (ParseUnitAddressHexList (
- OfwNode[FirstNonBridge + 2].UnitAddress,
- TargetLun,
- &NumEntries
- ) != RETURN_SUCCESS
- ) {
- return RETURN_UNSUPPORTED;
- }
-
- Written = UnicodeSPrintAsciiFormat (
- Translated,
- *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/Scsi(0x%Lx,0x%Lx)",
- PciRoot,
- Bridges,
- PciDevFun[0],
- PciDevFun[1],
- TargetLun[0],
- TargetLun[1]
- );
- } else if (NumNodes >= FirstNonBridge + 2 &&
- SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "pci8086,5845") &&
- SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "namespace")
- ) {
- //
- // OpenFirmware device path (NVMe device):
- //
- // /pci@i0cf8/pci8086,5845@6[,1]/namespace@1,0
- // ^ ^ ^ ^ ^
- // | | | | Extended Unique Identifier
- // | | | | (EUI-64), big endian interp.
- // | | | namespace ID
- // | PCI slot & function holding NVMe controller
- // PCI root at system bus port, PIO
- //
- // UEFI device path:
- //
- // PciRoot(0x0)/Pci(0x6,0x1)/NVMe(0x1,00-00-00-00-00-00-00-00)
- // ^ ^
- // | octets of the EUI-64
- // | in address order
- // namespace ID
- //
- UINT64 Namespace[2];
- UINTN RequiredEntries;
- UINT8 *Eui64;
-
- RequiredEntries = sizeof (Namespace) / sizeof (Namespace[0]);
- NumEntries = RequiredEntries;
- if (ParseUnitAddressHexList (
- OfwNode[FirstNonBridge + 1].UnitAddress,
- Namespace,
- &NumEntries
- ) != RETURN_SUCCESS ||
- NumEntries != RequiredEntries ||
- Namespace[0] == 0 ||
- Namespace[0] >= MAX_UINT32
- ) {
- return RETURN_UNSUPPORTED;
- }
-
- Eui64 = (UINT8 *)&Namespace[1];
- Written = UnicodeSPrintAsciiFormat (
- Translated,
- *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/"
- "NVMe(0x%Lx,%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)",
- PciRoot,
- Bridges,
- PciDevFun[0],
- PciDevFun[1],
- Namespace[0],
- Eui64[7], Eui64[6], Eui64[5], Eui64[4],
- Eui64[3], Eui64[2], Eui64[1], Eui64[0]
- );
- } else {
- //
- // Generic OpenFirmware device path for PCI devices:
- //
- // /pci@i0cf8/ethernet@3[,2]
- // ^ ^
- // | PCI slot[, function] holding Ethernet card
- // PCI root at system bus port, PIO
- //
- // UEFI device path prefix (dependent on presence of nonzero PCI function):
- //
- // PciRoot(0x0)/Pci(0x3,0x0)
- // PciRoot(0x0)/Pci(0x3,0x2)
- //
- Written = UnicodeSPrintAsciiFormat (
- Translated,
- *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)",
- PciRoot,
- Bridges,
- PciDevFun[0],
- PciDevFun[1]
- );
- }
-
- //
- // There's no way to differentiate between "completely used up without
- // truncation" and "truncated", so treat the former as the latter, and return
- // success only for "some room left unused".
- //
- if (Written + 1 < *TranslatedSize) {
- *TranslatedSize = Written;
- return RETURN_SUCCESS;
- }
-
- return RETURN_BUFFER_TOO_SMALL;
-}
-
-
-//
-// A type providing easy raw access to the base address of a virtio-mmio
-// transport.
-//
-typedef union {
- UINT64 Uint64;
- UINT8 Raw[8];
-} VIRTIO_MMIO_BASE_ADDRESS;
-
-
-/**
-
- Translate an MMIO-like array of OpenFirmware device nodes to a UEFI device
- path fragment.
-
- @param[in] OfwNode Array of OpenFirmware device nodes to
- translate, constituting the beginning of an
- OpenFirmware device path.
-
- @param[in] NumNodes Number of elements in OfwNode.
-
- @param[out] Translated Destination array receiving the UEFI path
- fragment, allocated by the caller. If the
- return value differs from RETURN_SUCCESS, its
- contents is indeterminate.
-
- @param[in out] TranslatedSize On input, the number of CHAR16's in
- Translated. On RETURN_SUCCESS this parameter
- is assigned the number of non-NUL CHAR16's
- written to Translated. In case of other return
- values, TranslatedSize is indeterminate.
-
-
- @retval RETURN_SUCCESS Translation successful.
-
- @retval RETURN_BUFFER_TOO_SMALL The translation does not fit into the number
- of bytes provided.
-
- @retval RETURN_UNSUPPORTED The array of OpenFirmware device nodes can't
- be translated in the current implementation.
-
-**/
-STATIC
-RETURN_STATUS
-TranslateMmioOfwNodes (
- IN CONST OFW_NODE *OfwNode,
- IN UINTN NumNodes,
- OUT CHAR16 *Translated,
- IN OUT UINTN *TranslatedSize
- )
-{
- VIRTIO_MMIO_BASE_ADDRESS VirtioMmioBase;
- CHAR16 VenHwString[60 + 1];
- UINTN NumEntries;
- UINTN Written;
-
- //
- // Get the base address of the virtio-mmio transport.
- //
- if (NumNodes < REQUIRED_MMIO_OFW_NODES ||
- !SubstringEq (OfwNode[0].DriverName, "virtio-mmio")
- ) {
- return RETURN_UNSUPPORTED;
- }
- NumEntries = 1;
- if (ParseUnitAddressHexList (
- OfwNode[0].UnitAddress,
- &VirtioMmioBase.Uint64,
- &NumEntries
- ) != RETURN_SUCCESS
- ) {
- return RETURN_UNSUPPORTED;
- }
-
- UnicodeSPrintAsciiFormat (VenHwString, sizeof VenHwString,
- "VenHw(%g,%02X%02X%02X%02X%02X%02X%02X%02X)", &gVirtioMmioTransportGuid,
- VirtioMmioBase.Raw[0], VirtioMmioBase.Raw[1], VirtioMmioBase.Raw[2],
- VirtioMmioBase.Raw[3], VirtioMmioBase.Raw[4], VirtioMmioBase.Raw[5],
- VirtioMmioBase.Raw[6], VirtioMmioBase.Raw[7]);
-
- if (NumNodes >= 2 &&
- SubstringEq (OfwNode[1].DriverName, "disk")) {
- //
- // OpenFirmware device path (virtio-blk disk):
- //
- // /virtio-mmio@000000000a003c00/disk@0,0
- // ^ ^ ^
- // | fixed
- // base address of virtio-mmio register block
- //
- // UEFI device path prefix:
- //
- // <VenHwString>/HD(
- //
- Written = UnicodeSPrintAsciiFormat (
- Translated,
- *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "%s/HD(",
- VenHwString
- );
- } else if (NumNodes >= 3 &&
- SubstringEq (OfwNode[1].DriverName, "channel") &&
- SubstringEq (OfwNode[2].DriverName, "disk")) {
- //
- // OpenFirmware device path (virtio-scsi disk):
- //
- // /virtio-mmio@000000000a003a00/channel@0/disk@2,3
- // ^ ^ ^ ^
- // | | | LUN
- // | | target
- // | channel (unused, fixed 0)
- // base address of virtio-mmio register block
- //
- // UEFI device path prefix:
- //
- // <VenHwString>/Scsi(0x2,0x3)
- //
- UINT64 TargetLun[2];
-
- TargetLun[1] = 0;
- NumEntries = sizeof (TargetLun) / sizeof (TargetLun[0]);
- if (ParseUnitAddressHexList (
- OfwNode[2].UnitAddress,
- TargetLun,
- &NumEntries
- ) != RETURN_SUCCESS
- ) {
- return RETURN_UNSUPPORTED;
- }
-
- Written = UnicodeSPrintAsciiFormat (
- Translated,
- *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "%s/Scsi(0x%Lx,0x%Lx)",
- VenHwString,
- TargetLun[0],
- TargetLun[1]
- );
- } else if (NumNodes >= 2 &&
- SubstringEq (OfwNode[1].DriverName, "ethernet-phy")) {
- //
- // OpenFirmware device path (virtio-net NIC):
- //
- // /virtio-mmio@000000000a003e00/ethernet-phy@0
- // ^ ^
- // | fixed
- // base address of virtio-mmio register block
- //
- // UEFI device path prefix (dependent on presence of nonzero PCI function):
- //
- // <VenHwString>/MAC(
- //
- Written = UnicodeSPrintAsciiFormat (
- Translated,
- *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "%s/MAC(",
- VenHwString
- );
- } else {
- return RETURN_UNSUPPORTED;
- }
-
- //
- // There's no way to differentiate between "completely used up without
- // truncation" and "truncated", so treat the former as the latter, and return
- // success only for "some room left unused".
- //
- if (Written + 1 < *TranslatedSize) {
- *TranslatedSize = Written;
- return RETURN_SUCCESS;
- }
-
- return RETURN_BUFFER_TOO_SMALL;
-}
-
-
-/**
-
- Translate an array of OpenFirmware device nodes to a UEFI device path
- fragment.
-
- @param[in] OfwNode Array of OpenFirmware device nodes to
- translate, constituting the beginning of an
- OpenFirmware device path.
-
- @param[in] NumNodes Number of elements in OfwNode.
-
- @param[in] ExtraPciRoots An EXTRA_ROOT_BUS_MAP object created with
- CreateExtraRootBusMap(), to be used for
- translating positions of extra root buses to
- bus numbers.
-
- @param[out] Translated Destination array receiving the UEFI path
- fragment, allocated by the caller. If the
- return value differs from RETURN_SUCCESS, its
- contents is indeterminate.
-
- @param[in out] TranslatedSize On input, the number of CHAR16's in
- Translated. On RETURN_SUCCESS this parameter
- is assigned the number of non-NUL CHAR16's
- written to Translated. In case of other return
- values, TranslatedSize is indeterminate.
-
-
- @retval RETURN_SUCCESS Translation successful.
-
- @retval RETURN_BUFFER_TOO_SMALL The translation does not fit into the number
- of bytes provided.
-
- @retval RETURN_UNSUPPORTED The array of OpenFirmware device nodes can't
- be translated in the current implementation.
-
- @retval RETURN_PROTOCOL_ERROR The array of OpenFirmware device nodes has
- been (partially) recognized, but it contains
- a logic error / doesn't match system state.
-
-**/
-STATIC
-RETURN_STATUS
-TranslateOfwNodes (
- IN CONST OFW_NODE *OfwNode,
- IN UINTN NumNodes,
- IN CONST EXTRA_ROOT_BUS_MAP *ExtraPciRoots,
- OUT CHAR16 *Translated,
- IN OUT UINTN *TranslatedSize
- )
-{
- RETURN_STATUS Status;
-
- Status = RETURN_UNSUPPORTED;
-
- if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) {
- Status = TranslatePciOfwNodes (OfwNode, NumNodes, ExtraPciRoots,
- Translated, TranslatedSize);
- }
- if (Status == RETURN_UNSUPPORTED &&
- FeaturePcdGet (PcdQemuBootOrderMmioTranslation)) {
- Status = TranslateMmioOfwNodes (OfwNode, NumNodes, Translated,
- TranslatedSize);
- }
- return Status;
-}
-
-/**
-
- Translate an OpenFirmware device path fragment to a UEFI device path
- fragment, and advance in the input string.
-
- @param[in out] Ptr Address of the pointer pointing to the start
- of the path string. After successful
- translation (RETURN_SUCCESS) or at least
- successful parsing (RETURN_UNSUPPORTED,
- RETURN_BUFFER_TOO_SMALL), *Ptr is set to the
- byte immediately following the consumed
- characters. In other error cases, it points to
- the byte that caused the error.
-
- @param[in] ExtraPciRoots An EXTRA_ROOT_BUS_MAP object created with
- CreateExtraRootBusMap(), to be used for
- translating positions of extra root buses to
- bus numbers.
-
- @param[out] Translated Destination array receiving the UEFI path
- fragment, allocated by the caller. If the
- return value differs from RETURN_SUCCESS, its
- contents is indeterminate.
-
- @param[in out] TranslatedSize On input, the number of CHAR16's in
- Translated. On RETURN_SUCCESS this parameter
- is assigned the number of non-NUL CHAR16's
- written to Translated. In case of other return
- values, TranslatedSize is indeterminate.
-
-
- @retval RETURN_SUCCESS Translation successful.
-
- @retval RETURN_BUFFER_TOO_SMALL The OpenFirmware device path was parsed
- successfully, but its translation did not
- fit into the number of bytes provided.
- Further calls to this function are
- possible.
-
- @retval RETURN_UNSUPPORTED The OpenFirmware device path was parsed
- successfully, but it can't be translated in
- the current implementation. Further calls
- to this function are possible.
-
- @retval RETURN_PROTOCOL_ERROR The OpenFirmware device path has been
- (partially) recognized, but it contains a
- logic error / doesn't match system state.
- Further calls to this function are
- possible.
-
- @retval RETURN_NOT_FOUND Translation terminated. On input, *Ptr was
- pointing to the empty string or "HALT". On
- output, *Ptr points to the empty string
- (ie. "HALT" is consumed transparently when
- present).
-
- @retval RETURN_INVALID_PARAMETER Parse error. This is a permanent error.
-
-**/
-STATIC
-RETURN_STATUS
-TranslateOfwPath (
- IN OUT CONST CHAR8 **Ptr,
- IN CONST EXTRA_ROOT_BUS_MAP *ExtraPciRoots,
- OUT CHAR16 *Translated,
- IN OUT UINTN *TranslatedSize
- )
-{
- UINTN NumNodes;
- RETURN_STATUS Status;
- OFW_NODE Node[EXAMINED_OFW_NODES];
- BOOLEAN IsFinal;
- OFW_NODE Skip;
-
- IsFinal = FALSE;
- NumNodes = 0;
- if (AsciiStrCmp (*Ptr, "HALT") == 0) {
- *Ptr += 4;
- Status = RETURN_NOT_FOUND;
- } else {
- Status = ParseOfwNode (Ptr, &Node[NumNodes], &IsFinal);
- }
-
- if (Status == RETURN_NOT_FOUND) {
- DEBUG ((DEBUG_VERBOSE, "%a: no more nodes\n", __FUNCTION__));
- return RETURN_NOT_FOUND;
- }
-
- while (Status == RETURN_SUCCESS && !IsFinal) {
- ++NumNodes;
- Status = ParseOfwNode (
- Ptr,
- (NumNodes < EXAMINED_OFW_NODES) ? &Node[NumNodes] : &Skip,
- &IsFinal
- );
- }
-
- switch (Status) {
- case RETURN_SUCCESS:
- ++NumNodes;
- break;
-
- case RETURN_INVALID_PARAMETER:
- DEBUG ((DEBUG_VERBOSE, "%a: parse error\n", __FUNCTION__));
- return RETURN_INVALID_PARAMETER;
-
- default:
- ASSERT (0);
- }
-
- Status = TranslateOfwNodes (
- Node,
- NumNodes < EXAMINED_OFW_NODES ? NumNodes : EXAMINED_OFW_NODES,
- ExtraPciRoots,
- Translated,
- TranslatedSize);
- switch (Status) {
- case RETURN_SUCCESS:
- DEBUG ((DEBUG_VERBOSE, "%a: success: \"%s\"\n", __FUNCTION__, Translated));
- break;
-
- case RETURN_BUFFER_TOO_SMALL:
- DEBUG ((DEBUG_VERBOSE, "%a: buffer too small\n", __FUNCTION__));
- break;
-
- case RETURN_UNSUPPORTED:
- DEBUG ((DEBUG_VERBOSE, "%a: unsupported\n", __FUNCTION__));
- break;
-
- case RETURN_PROTOCOL_ERROR:
- DEBUG ((DEBUG_VERBOSE, "%a: logic error / system state mismatch\n",
- __FUNCTION__));
- break;
-
- default:
- ASSERT (0);
- }
- return Status;
-}
-
-
-/**
-
- Convert the UEFI DevicePath to full text representation with DevPathToText,
- then match the UEFI device path fragment in Translated against it.
-
- @param[in] Translated UEFI device path fragment, translated from
- OpenFirmware format, to search for.
-
- @param[in] TranslatedLength The length of Translated in CHAR16's.
-
- @param[in] DevicePath Boot option device path whose textual rendering
- to search in.
-
- @param[in] DevPathToText Binary-to-text conversion protocol for DevicePath.
-
-
- @retval TRUE If Translated was found at the beginning of DevicePath after
- converting the latter to text.
-
- @retval FALSE If DevicePath was NULL, or it could not be converted, or there
- was no match.
-
-**/
-STATIC
-BOOLEAN
-Match (
- IN CONST CHAR16 *Translated,
- IN UINTN TranslatedLength,
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
-{
- CHAR16 *Converted;
- BOOLEAN Result;
-
- Converted = ConvertDevicePathToText (
- DevicePath,
- FALSE, // DisplayOnly
- FALSE // AllowShortcuts
- );
- if (Converted == NULL) {
- 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;
- if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH &&
- DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP) {
- EFI_DEVICE_PATH_PROTOCOL *AbsDevicePath;
- CHAR16 *AbsConverted;
-
- AbsDevicePath = BdsExpandPartitionPartialDevicePathToFull (
- (HARDDRIVE_DEVICE_PATH *) DevicePath);
- if (AbsDevicePath == NULL) {
- goto Exit;
- }
- AbsConverted = ConvertDevicePathToText (AbsDevicePath, FALSE, FALSE);
- if (AbsConverted == NULL) {
- goto Exit;
- }
- DEBUG ((DEBUG_VERBOSE,
- "%a: expanded relative device path \"%s\" for prefix matching\n",
- __FUNCTION__, Converted));
- FreePool (Converted);
- Converted = AbsConverted;
- }
-
- //
- // Is Translated a prefix of Converted?
- //
- Result = (BOOLEAN)(StrnCmp (Converted, Translated, TranslatedLength) == 0);
- DEBUG ((
- DEBUG_VERBOSE,
- "%a: against \"%s\": %a\n",
- __FUNCTION__,
- Converted,
- Result ? "match" : "no match"
- ));
-Exit:
- FreePool (Converted);
- return Result;
-}
-
-
-/**
- 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() nor a virtio-mmio VenHw() node.
-
- @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() if we enabled the user to select PCI-like boot
- // options, by providing translation for such OFW device path
- // fragments
- //
- Keep = !FeaturePcdGet (PcdQemuBootOrderPciTranslation);
- }
- } else if (DevicePathType(FirstNode) == HARDWARE_DEVICE_PATH &&
- DevicePathSubType(FirstNode) == HW_VENDOR_DP) {
- VENDOR_DEVICE_PATH *VenHw;
-
- VenHw = (VENDOR_DEVICE_PATH *)FirstNode;
- if (CompareGuid (&VenHw->Guid, &gVirtioMmioTransportGuid)) {
- //
- // drop virtio-mmio if we enabled the user to select boot options
- // referencing such device paths
- //
- Keep = !FeaturePcdGet (PcdQemuBootOrderMmioTranslation);
- }
- }
-
- 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;
-}
-
-
-/**
- Delete Boot#### variables that stand for such active boot options that have
- been dropped (ie. have not been selected by either matching or "survival
- policy").
-
- @param[in] ActiveOption The array of active boot options to scan. Each
- entry not marked as appended will trigger the
- deletion of the matching Boot#### variable.
-
- @param[in] ActiveCount Number of elements in ActiveOption.
-**/
-STATIC
-VOID
-PruneBootVariables (
- IN CONST ACTIVE_OPTION *ActiveOption,
- IN UINTN ActiveCount
- )
-{
- UINTN Idx;
-
- for (Idx = 0; Idx < ActiveCount; ++Idx) {
- if (!ActiveOption[Idx].Appended) {
- CHAR16 VariableName[9];
-
- UnicodeSPrintAsciiFormat (VariableName, sizeof VariableName, "Boot%04x",
- ActiveOption[Idx].BootOption->BootCurrent);
-
- //
- // "The space consumed by the deleted variable may not be available until
- // the next power cycle", but that's good enough.
- //
- gRT->SetVariable (VariableName, &gEfiGlobalVariableGuid,
- 0, // Attributes, 0 means deletion
- 0, // DataSize, 0 means deletion
- NULL // Data
- );
- }
- }
-}
-
-
-/**
-
- Set the boot order based on configuration retrieved from QEMU.
-
- Attempt to retrieve the "bootorder" fw_cfg file from QEMU. Translate the
- OpenFirmware device paths therein to UEFI device path fragments. Match the
- translated fragments against BootOptionList, and rewrite the BootOrder NvVar
- so that it corresponds to the order described in fw_cfg.
-
- @param[in] BootOptionList A boot option list, created with
- BdsLibEnumerateAllBootOption ().
-
-
- @retval RETURN_SUCCESS BootOrder NvVar rewritten.
-
- @retval RETURN_UNSUPPORTED QEMU's fw_cfg is not supported.
-
- @retval RETURN_NOT_FOUND Empty or nonexistent "bootorder" fw_cfg
- file, or no match found between the
- "bootorder" fw_cfg file and BootOptionList.
-
- @retval RETURN_INVALID_PARAMETER Parse error in the "bootorder" fw_cfg file.
-
- @retval RETURN_OUT_OF_RESOURCES Memory allocation failed.
-
- @return Values returned by gBS->LocateProtocol ()
- or gRT->SetVariable ().
-
-**/
-RETURN_STATUS
-SetBootOrderFromQemu (
- IN CONST LIST_ENTRY *BootOptionList
- )
-{
- RETURN_STATUS Status;
- FIRMWARE_CONFIG_ITEM FwCfgItem;
- UINTN FwCfgSize;
- CHAR8 *FwCfg;
- CONST CHAR8 *FwCfgPtr;
-
- BOOT_ORDER BootOrder;
- ACTIVE_OPTION *ActiveOption;
- UINTN ActiveCount;
-
- EXTRA_ROOT_BUS_MAP *ExtraPciRoots;
-
- UINTN TranslatedSize;
- CHAR16 Translated[TRANSLATION_OUTPUT_SIZE];
-
- Status = QemuFwCfgFindFile ("bootorder", &FwCfgItem, &FwCfgSize);
- if (Status != RETURN_SUCCESS) {
- return Status;
- }
-
- if (FwCfgSize == 0) {
- return RETURN_NOT_FOUND;
- }
-
- FwCfg = AllocatePool (FwCfgSize);
- if (FwCfg == NULL) {
- return RETURN_OUT_OF_RESOURCES;
- }
-
- QemuFwCfgSelectItem (FwCfgItem);
- QemuFwCfgReadBytes (FwCfgSize, FwCfg);
- if (FwCfg[FwCfgSize - 1] != '\0') {
- Status = RETURN_INVALID_PARAMETER;
- goto ErrorFreeFwCfg;
- }
-
- DEBUG ((DEBUG_VERBOSE, "%a: FwCfg:\n", __FUNCTION__));
- DEBUG ((DEBUG_VERBOSE, "%a\n", FwCfg));
- DEBUG ((DEBUG_VERBOSE, "%a: FwCfg: <end>\n", __FUNCTION__));
- FwCfgPtr = FwCfg;
-
- BootOrder.Produced = 0;
- BootOrder.Allocated = 1;
- BootOrder.Data = AllocatePool (
- BootOrder.Allocated * sizeof (*BootOrder.Data)
- );
- if (BootOrder.Data == NULL) {
- Status = RETURN_OUT_OF_RESOURCES;
- goto ErrorFreeFwCfg;
- }
-
- Status = CollectActiveOptions (BootOptionList, &ActiveOption, &ActiveCount);
- if (RETURN_ERROR (Status)) {
- goto ErrorFreeBootOrder;
- }
-
- if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) {
- Status = CreateExtraRootBusMap (&ExtraPciRoots);
- if (EFI_ERROR (Status)) {
- goto ErrorFreeActiveOption;
- }
- } else {
- ExtraPciRoots = NULL;
- }
-
- //
- // translate each OpenFirmware path
- //
- TranslatedSize = sizeof (Translated) / sizeof (Translated[0]);
- Status = TranslateOfwPath (&FwCfgPtr, ExtraPciRoots, Translated,
- &TranslatedSize);
- while (Status == RETURN_SUCCESS ||
- Status == RETURN_UNSUPPORTED ||
- Status == RETURN_PROTOCOL_ERROR ||
- Status == RETURN_BUFFER_TOO_SMALL) {
- if (Status == RETURN_SUCCESS) {
- UINTN Idx;
-
- //
- // match translated OpenFirmware path against all active boot options
- //
- for (Idx = 0; Idx < ActiveCount; ++Idx) {
- if (Match (
- Translated,
- TranslatedSize, // contains length, not size, in CHAR16's here
- ActiveOption[Idx].BootOption->DevicePath
- )
- ) {
- //
- // match found, store ID and continue with next OpenFirmware path
- //
- Status = BootOrderAppend (&BootOrder, &ActiveOption[Idx]);
- if (Status != RETURN_SUCCESS) {
- goto ErrorFreeExtraPciRoots;
- }
- break;
- }
- } // scanned all active boot options
- } // translation successful
-
- TranslatedSize = sizeof (Translated) / sizeof (Translated[0]);
- Status = TranslateOfwPath (&FwCfgPtr, ExtraPciRoots, Translated,
- &TranslatedSize);
- } // scanning of OpenFirmware paths done
-
- 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 ErrorFreeExtraPciRoots;
- }
-
- //
- // See Table 10 in the UEFI Spec 2.3.1 with Errata C for the required
- // attributes.
- //
- Status = gRT->SetVariable (
- L"BootOrder",
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_NON_VOLATILE |
- EFI_VARIABLE_BOOTSERVICE_ACCESS |
- EFI_VARIABLE_RUNTIME_ACCESS,
- BootOrder.Produced * sizeof (*BootOrder.Data),
- BootOrder.Data
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: setting BootOrder: %r\n", __FUNCTION__, Status));
- goto ErrorFreeExtraPciRoots;
- }
-
- DEBUG ((DEBUG_INFO, "%a: setting BootOrder: success\n", __FUNCTION__));
- PruneBootVariables (ActiveOption, ActiveCount);
- }
-
-ErrorFreeExtraPciRoots:
- if (ExtraPciRoots != NULL) {
- DestroyExtraRootBusMap (ExtraPciRoots);
- }
-
-ErrorFreeActiveOption:
- FreePool (ActiveOption);
-
-ErrorFreeBootOrder:
- FreePool (BootOrder.Data);
-
-ErrorFreeFwCfg:
- FreePool (FwCfg);
-
- return Status;
-}
-
-
-/**
- Calculate the number of seconds we should be showing the FrontPage progress
- bar for.
-
- @return The TimeoutDefault argument for PlatformBdsEnterFrontPage().
-**/
-UINT16
-GetFrontPageTimeoutFromQemu (
- VOID
- )
-{
- FIRMWARE_CONFIG_ITEM BootMenuWaitItem;
- UINTN BootMenuWaitSize;
-
- QemuFwCfgSelectItem (QemuFwCfgItemBootMenu);
- if (QemuFwCfgRead16 () == 0) {
- //
- // The user specified "-boot menu=off", or didn't specify "-boot
- // menu=(on|off)" at all. Return the platform default.
- //
- return PcdGet16 (PcdPlatformBootTimeOut);
- }
-
- if (RETURN_ERROR (QemuFwCfgFindFile ("etc/boot-menu-wait", &BootMenuWaitItem,
- &BootMenuWaitSize)) ||
- BootMenuWaitSize != sizeof (UINT16)) {
- //
- // "-boot menu=on" was specified without "splash-time=N". In this case,
- // return three seconds if the platform default would cause us to skip the
- // front page, and return the platform default otherwise.
- //
- UINT16 Timeout;
-
- Timeout = PcdGet16 (PcdPlatformBootTimeOut);
- if (Timeout == 0) {
- Timeout = 3;
- }
- return Timeout;
- }
-
- //
- // "-boot menu=on,splash-time=N" was specified, where N is in units of
- // milliseconds. The Intel BDS Front Page progress bar only supports whole
- // seconds, round N up.
- //
- QemuFwCfgSelectItem (BootMenuWaitItem);
- return (UINT16)((QemuFwCfgRead16 () + 999) / 1000);
-}
This library instance is no longer referenced. Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Gary Ching-Pang Lin <glin@suse.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> --- OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf | 68 - OvmfPkg/Library/QemuBootOrderLib/ExtraRootBusMap.h | 40 - OvmfPkg/Library/QemuBootOrderLib/ExtraRootBusMap.c | 313 ---- OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c | 1891 -------------------- 4 files changed, 2312 deletions(-) -- 1.8.3.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel