[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [edk2 PATCH 10/12] OvmfPkg: QemuBootOrderLib: OFW-to-UEFI t
From: |
Laszlo Ersek |
Subject: |
[Qemu-devel] [edk2 PATCH 10/12] OvmfPkg: QemuBootOrderLib: OFW-to-UEFI translation for virtio-mmio |
Date: |
Fri, 28 Nov 2014 00:19:25 +0100 |
The TranslateMmioOfwNodes() function recognizes the following OpenFirmware
device paths:
virtio-blk: /address@hidden/address@hidden,0
virtio-scsi disk: /address@hidden/address@hidden/address@hidden,3
virtio-net NIC: /address@hidden/address@hidden
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 <address@hidden>
---
OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf | 3 ++
OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c | 198
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
OvmfPkg/OvmfPkg.dec | 1 +
3 files changed, 201 insertions(+), 1 deletion(-)
diff --git a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
index 5aa4e6e..6289e6a 100644
--- a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
+++ b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
@@ -48,9 +48,12 @@
BaseLib
PrintLib
DevicePathLib
+ BaseMemoryLib
[Guids]
gEfiGlobalVariableGuid
+ gVirtioMmioTransportGuid
[FeaturePcd]
gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation
diff --git a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
index 3599437..bc2fb56 100644
--- a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
+++ b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
@@ -23,7 +23,9 @@
#include <Library/PrintLib.h>
#include <Library/DevicePathLib.h>
#include <Library/QemuBootOrderLib.h>
+#include <Library/BaseMemoryLib.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.
**/
#define REQUIRED_PCI_OFW_NODES 2
+#define REQUIRED_MMIO_OFW_NODES 1
#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):
+ //
+ // /address@hidden/address@hidden,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):
+ //
+ // /address@hidden/address@hidden/address@hidden,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):
+ //
+ // /address@hidden/address@hidden
+ // ^ ^
+ // | 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
@@ -850,6 +1029,11 @@ TranslateOfwNodes (
Status = TranslatePciOfwNodes (OfwNode, NumNodes, Translated,
TranslatedSize);
}
+ if (Status == RETURN_UNSUPPORTED &&
+ FeaturePcdGet (PcdQemuBootOrderMmioTranslation)) {
+ Status = TranslateMmioOfwNodes (OfwNode, NumNodes, Translated,
+ TranslatedSize);
+ }
return Status;
}
@@ -1069,7 +1253,7 @@ Exit:
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().
+ 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
@@ -1141,6 +1325,18 @@ BootOrderComplete (
//
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) {
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 41db92d..e3a09cf 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -109,3 +109,4 @@
[PcdsFeatureFlag]
gUefiOvmfPkgTokenSpaceGuid.PcdSecureBootEnable|FALSE|BOOLEAN|3
gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|TRUE|BOOLEAN|0x1c
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation|FALSE|BOOLEAN|0x1d
--
1.8.3.1
- Re: [Qemu-devel] [qemu PATCH 2/2] arm: add fw_cfg to "virt" board, (continued)
- [Qemu-devel] [edk2 PATCH 00/12] consume fw_cfg boot order in ArmVirtualizationQemu, Laszlo Ersek, 2014/11/27
- [Qemu-devel] [edk2 PATCH 01/12] ArmVirtualizationPkg: VirtFdtDxe: forward FwCfg addresses from DTB to PCDs, Laszlo Ersek, 2014/11/27
- [Qemu-devel] [edk2 PATCH 02/12] ArmVirtualizationPkg: introduce QemuFwCfgLib instance for DXE drivers, Laszlo Ersek, 2014/11/27
- [Qemu-devel] [edk2 PATCH 03/12] ArmVirtualizationPkg: clone PlatformIntelBdsLib from ArmPlatformPkg, Laszlo Ersek, 2014/11/27
- [Qemu-devel] [edk2 PATCH 04/12] ArmVirtualizationPkg: PlatformIntelBdsLib: add basic policy, Laszlo Ersek, 2014/11/27
- [Qemu-devel] [edk2 PATCH 05/12] OvmfPkg: extract QemuBootOrderLib, Laszlo Ersek, 2014/11/27
- [Qemu-devel] [edk2 PATCH 07/12] OvmfPkg: introduce VIRTIO_MMIO_TRANSPORT_GUID, Laszlo Ersek, 2014/11/27
- [Qemu-devel] [edk2 PATCH 08/12] ArmVirtualizationPkg: VirtFdtDxe: use dedicated VIRTIO_MMIO_TRANSPORT_GUID, Laszlo Ersek, 2014/11/27
- [Qemu-devel] [edk2 PATCH 09/12] OvmfPkg: QemuBootOrderLib: widen ParseUnitAddressHexList() to UINT64, Laszlo Ersek, 2014/11/27
- [Qemu-devel] [edk2 PATCH 10/12] OvmfPkg: QemuBootOrderLib: OFW-to-UEFI translation for virtio-mmio,
Laszlo Ersek <=
- [Qemu-devel] [edk2 PATCH 11/12] ArmVirtualizationPkg: PlatformIntelBdsLib: adhere to QEMU's boot order, Laszlo Ersek, 2014/11/27
- [Qemu-devel] [edk2 PATCH 12/12] ArmVirtualizationPkg: identify "new shell" as builtin shell for Intel BDS, Laszlo Ersek, 2014/11/27
- [Qemu-devel] [edk2 PATCH 06/12] OvmfPkg: QemuBootOrderLib: featurize PCI-like device path translation, Laszlo Ersek, 2014/11/27