From: Laszlo Ersek <lersek@redhat.com>
To: qemu-devel@nongnu.org, edk2-devel@lists.sourceforge.net,
drjones@redhat.com, ard.biesheuvel@linaro.org,
peter.maydell@linaro.org, imammedo@redhat.com, mst@redhat.com
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 [thread overview]
Message-ID: <1417130367-17777-11-git-send-email-lersek@redhat.com> (raw)
In-Reply-To: <1417130367-17777-1-git-send-email-lersek@redhat.com>
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>
---
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):
+ //
+ // /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
@@ -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
next prev parent reply other threads:[~2014-11-27 23:20 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-27 23:17 [Qemu-devel] expose QEMU's fw_cfg boot order to ARM guest firmware (Intel BDS) Laszlo Ersek
2014-11-27 23:18 ` [Qemu-devel] [qemu PATCH 0/2] DTB- and MMIO-based fw_cfg for hw/arm/virt Laszlo Ersek
2014-11-27 23:18 ` [Qemu-devel] [qemu PATCH 1/2] fw_cfg: make the FW_CFG_SIZE and FW_CFG_DATA_SIZE macros public Laszlo Ersek
2014-11-27 23:18 ` [Qemu-devel] [qemu PATCH 2/2] arm: add fw_cfg to "virt" board Laszlo Ersek
2014-11-27 23:28 ` Peter Maydell
2014-11-27 23:34 ` Laszlo Ersek
2014-11-27 23:37 ` Peter Maydell
2014-11-28 10:38 ` Andrew Jones
2014-11-28 10:43 ` Laszlo Ersek
2014-11-28 10:49 ` Laszlo Ersek
2014-11-28 11:17 ` Andrew Jones
2014-11-28 10:51 ` Andrew Jones
2014-11-27 23:19 ` [Qemu-devel] [edk2 PATCH 00/12] consume fw_cfg boot order in ArmVirtualizationQemu Laszlo Ersek
2014-11-27 23:19 ` [Qemu-devel] [edk2 PATCH 01/12] ArmVirtualizationPkg: VirtFdtDxe: forward FwCfg addresses from DTB to PCDs Laszlo Ersek
2014-12-05 17:39 ` [Qemu-devel] [edk2] " Laszlo Ersek
2014-11-27 23:19 ` [Qemu-devel] [edk2 PATCH 02/12] ArmVirtualizationPkg: introduce QemuFwCfgLib instance for DXE drivers Laszlo Ersek
2014-11-27 23:19 ` [Qemu-devel] [edk2 PATCH 03/12] ArmVirtualizationPkg: clone PlatformIntelBdsLib from ArmPlatformPkg Laszlo Ersek
2014-11-27 23:19 ` [Qemu-devel] [edk2 PATCH 04/12] ArmVirtualizationPkg: PlatformIntelBdsLib: add basic policy Laszlo Ersek
2014-11-27 23:19 ` [Qemu-devel] [edk2 PATCH 05/12] OvmfPkg: extract QemuBootOrderLib Laszlo Ersek
2014-11-27 23:19 ` [Qemu-devel] [edk2 PATCH 06/12] OvmfPkg: QemuBootOrderLib: featurize PCI-like device path translation Laszlo Ersek
2014-11-27 23:19 ` [Qemu-devel] [edk2 PATCH 07/12] OvmfPkg: introduce VIRTIO_MMIO_TRANSPORT_GUID Laszlo Ersek
2014-11-27 23:19 ` [Qemu-devel] [edk2 PATCH 08/12] ArmVirtualizationPkg: VirtFdtDxe: use dedicated VIRTIO_MMIO_TRANSPORT_GUID Laszlo Ersek
2014-11-27 23:19 ` [Qemu-devel] [edk2 PATCH 09/12] OvmfPkg: QemuBootOrderLib: widen ParseUnitAddressHexList() to UINT64 Laszlo Ersek
2014-11-27 23:19 ` Laszlo Ersek [this message]
2014-11-27 23:19 ` [Qemu-devel] [edk2 PATCH 11/12] ArmVirtualizationPkg: PlatformIntelBdsLib: adhere to QEMU's boot order Laszlo Ersek
2014-11-27 23:19 ` [Qemu-devel] [edk2 PATCH 12/12] ArmVirtualizationPkg: identify "new shell" as builtin shell for Intel BDS Laszlo Ersek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1417130367-17777-11-git-send-email-lersek@redhat.com \
--to=lersek@redhat.com \
--cc=ard.biesheuvel@linaro.org \
--cc=drjones@redhat.com \
--cc=edk2-devel@lists.sourceforge.net \
--cc=imammedo@redhat.com \
--cc=mst@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).