mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-28 16:14:04 +02:00
OvmfPkg: QemuBootOrderLib: OFW-to-UEFI translation for virtio-mmio
The TranslateMmioOfwNodes() function recognizes the following OpenFirmware device paths: virtio-blk: /virtio-mmio@000000000a003c00/disk@0,0 virtio-scsi disk: /virtio-mmio@000000000a003a00/channel@0/disk@2,3 virtio-net NIC: /virtio-mmio@000000000a003e00/ethernet-phy@0 The new translation can be enabled with the "PcdQemuBootOrderMmioTranslation" Feature PCD. This PCD also controls if the "survival policy" covers unselected boot options that start with the virtio-mmio VenHw() node. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Acked-by: Jordan Justen <jordan.l.justen@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16575 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
ca0d7c98f2
commit
4333691690
@ -23,7 +23,9 @@
|
|||||||
#include <Library/PrintLib.h>
|
#include <Library/PrintLib.h>
|
||||||
#include <Library/DevicePathLib.h>
|
#include <Library/DevicePathLib.h>
|
||||||
#include <Library/QemuBootOrderLib.h>
|
#include <Library/QemuBootOrderLib.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
#include <Guid/GlobalVariable.h>
|
#include <Guid/GlobalVariable.h>
|
||||||
|
#include <Guid/VirtioMmioTransport.h>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,6 +38,7 @@
|
|||||||
Numbers of nodes in OpenFirmware device paths that are required and examined.
|
Numbers of nodes in OpenFirmware device paths that are required and examined.
|
||||||
**/
|
**/
|
||||||
#define REQUIRED_PCI_OFW_NODES 2
|
#define REQUIRED_PCI_OFW_NODES 2
|
||||||
|
#define REQUIRED_MMIO_OFW_NODES 1
|
||||||
#define EXAMINED_OFW_NODES 4
|
#define EXAMINED_OFW_NODES 4
|
||||||
|
|
||||||
|
|
||||||
@ -801,6 +804,182 @@ TranslatePciOfwNodes (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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
|
Translate an array of OpenFirmware device nodes to a UEFI device path
|
||||||
@ -850,6 +1029,11 @@ TranslateOfwNodes (
|
|||||||
Status = TranslatePciOfwNodes (OfwNode, NumNodes, Translated,
|
Status = TranslatePciOfwNodes (OfwNode, NumNodes, Translated,
|
||||||
TranslatedSize);
|
TranslatedSize);
|
||||||
}
|
}
|
||||||
|
if (Status == RETURN_UNSUPPORTED &&
|
||||||
|
FeaturePcdGet (PcdQemuBootOrderMmioTranslation)) {
|
||||||
|
Status = TranslateMmioOfwNodes (OfwNode, NumNodes, Translated,
|
||||||
|
TranslatedSize);
|
||||||
|
}
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1069,7 +1253,7 @@ Exit:
|
|||||||
|
|
||||||
This function should accommodate any further policy changes in "boot option
|
This function should accommodate any further policy changes in "boot option
|
||||||
survival". Currently we're adding back everything that starts with neither
|
survival". Currently we're adding back everything that starts with neither
|
||||||
PciRoot() nor HD().
|
PciRoot() nor HD() nor a virtio-mmio VenHw() node.
|
||||||
|
|
||||||
@param[in,out] BootOrder The structure holding the boot order to
|
@param[in,out] BootOrder The structure holding the boot order to
|
||||||
complete. The caller is responsible for
|
complete. The caller is responsible for
|
||||||
@ -1141,6 +1325,18 @@ BootOrderComplete (
|
|||||||
//
|
//
|
||||||
Keep = !FeaturePcdGet (PcdQemuBootOrderPciTranslation);
|
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) {
|
if (Keep) {
|
||||||
|
@ -48,9 +48,12 @@
|
|||||||
BaseLib
|
BaseLib
|
||||||
PrintLib
|
PrintLib
|
||||||
DevicePathLib
|
DevicePathLib
|
||||||
|
BaseMemoryLib
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gEfiGlobalVariableGuid
|
gEfiGlobalVariableGuid
|
||||||
|
gVirtioMmioTransportGuid
|
||||||
|
|
||||||
[FeaturePcd]
|
[FeaturePcd]
|
||||||
gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation
|
gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation
|
||||||
|
@ -105,3 +105,4 @@
|
|||||||
[PcdsFeatureFlag]
|
[PcdsFeatureFlag]
|
||||||
gUefiOvmfPkgTokenSpaceGuid.PcdSecureBootEnable|FALSE|BOOLEAN|3
|
gUefiOvmfPkgTokenSpaceGuid.PcdSecureBootEnable|FALSE|BOOLEAN|3
|
||||||
gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|TRUE|BOOLEAN|0x1c
|
gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|TRUE|BOOLEAN|0x1c
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation|FALSE|BOOLEAN|0x1d
|
||||||
|
Loading…
x
Reference in New Issue
Block a user