[edk2] [PATCH v4 07/11] OvmfPkg: Make the VirtIo devices use the new VIRTIO_DEVICE_PROTOCOL

Subject: [edk2] [PATCH v4 07/11] OvmfPkg: Make the VirtIo devices use the new VIRTIO_DEVICE_PROTOCOL

From: Olivier Martin <olivier.martin@arm.com>

To: edk2-devel@lists.sourceforge.net

Date: 2013-10-17 02:29:09

This change replaces the accesses to the PCI bus from the Block, Scsi and Net drivers by
the use of the new VIRTIO_DEVICE_PROTOCOL protocol that abstracts the transport layer.
It means these drivers can be used on PCI and MMIO transport layer.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin 
---
 OvmfPkg/Include/IndustryStandard/VirtioBlk.h  |   21 ++--
 OvmfPkg/Include/IndustryStandard/VirtioNet.h  |   14 +-
 OvmfPkg/Include/IndustryStandard/VirtioScsi.h |   27 ++--
 OvmfPkg/Include/Library/VirtioLib.h           |   59 +++++----
 OvmfPkg/Library/VirtioLib/VirtioLib.c         |  127 ++++--------------
 OvmfPkg/OvmfPkgIa32.dsc                       |    1 +
 OvmfPkg/OvmfPkgIa32.fdf                       |    1 +
 OvmfPkg/OvmfPkgIa32X64.dsc                    |    1 +
 OvmfPkg/OvmfPkgIa32X64.fdf                    |    1 +
 OvmfPkg/OvmfPkgX64.dsc                        |    1 +
 OvmfPkg/OvmfPkgX64.fdf                        |    1 +
 OvmfPkg/VirtioBlkDxe/VirtioBlk.c              |  171 ++++++++++---------------
 OvmfPkg/VirtioBlkDxe/VirtioBlk.h              |   32 ++---
 OvmfPkg/VirtioBlkDxe/VirtioBlk.inf            |    4 +-
 OvmfPkg/VirtioNetDxe/ComponentName.c          |    6 +-
 OvmfPkg/VirtioNetDxe/DriverBinding.c          |  130 ++++++++-----------
 OvmfPkg/VirtioNetDxe/Events.c                 |    2 +-
 OvmfPkg/VirtioNetDxe/SnpGetStatus.c           |    2 +-
 OvmfPkg/VirtioNetDxe/SnpInitialize.c          |   37 ++++--
 OvmfPkg/VirtioNetDxe/SnpReceive.c             |   12 +-
 OvmfPkg/VirtioNetDxe/SnpShutdown.c            |    2 +-
 OvmfPkg/VirtioNetDxe/SnpTransmit.c            |   12 +-
 OvmfPkg/VirtioNetDxe/VirtioNet.h              |   12 +-
 OvmfPkg/VirtioNetDxe/VirtioNet.inf            |    2 +-
 OvmfPkg/VirtioScsiDxe/VirtioScsi.c            |  159 ++++++++---------------
 OvmfPkg/VirtioScsiDxe/VirtioScsi.h            |   24 ++--
 OvmfPkg/VirtioScsiDxe/VirtioScsi.inf          |    2 +-
 27 files changed, 344 insertions(+), 519 deletions(-)

diff --git a/OvmfPkg/Include/IndustryStandard/VirtioBlk.h b/OvmfPkg/Include/IndustryStandard/VirtioBlk.h
index b71f224..ab11e6c 100644
--- a/OvmfPkg/Include/IndustryStandard/VirtioBlk.h
+++ b/OvmfPkg/Include/IndustryStandard/VirtioBlk.h
@@ -26,19 +26,18 @@
 //
 #pragma pack(1)
 typedef struct {
-  VIRTIO_HDR Generic;
-  UINT64     VhdrCapacity;
-  UINT32     VhdrSizeMax;
-  UINT32     VhdrSegMax;
-  UINT16     VhdrCylinders;
-  UINT8      VhdrHeads;
-  UINT8      VhdrSectors;
-  UINT32     VhdrBlkSize;
-} VBLK_HDR;
+  UINT64     Capacity;
+  UINT32     SizeMax;
+  UINT32     SegMax;
+  UINT16     Cylinders;
+  UINT8      Heads;
+  UINT8      Sectors;
+  UINT32     BlkSize;
+} VIRTIO_BLK_CONFIG;
 #pragma pack()
 
-#define OFFSET_OF_VBLK(Field) OFFSET_OF (VBLK_HDR, Field)
-#define SIZE_OF_VBLK(Field)   (sizeof ((VBLK_HDR *) 0)->Field)
+#define OFFSET_OF_VBLK(Field) OFFSET_OF (VIRTIO_BLK_CONFIG, Field)
+#define SIZE_OF_VBLK(Field)   (sizeof ((VIRTIO_BLK_CONFIG *) 0)->Field)
 
 #define VIRTIO_BLK_F_BARRIER  BIT0
 #define VIRTIO_BLK_F_SIZE_MAX BIT1
diff --git a/OvmfPkg/Include/IndustryStandard/VirtioNet.h b/OvmfPkg/Include/IndustryStandard/VirtioNet.h
index 03dfeb2..34bf15a 100644
--- a/OvmfPkg/Include/IndustryStandard/VirtioNet.h
+++ b/OvmfPkg/Include/IndustryStandard/VirtioNet.h
@@ -1,5 +1,4 @@
 /** @file
-
   Virtio Network Device specific type and macro definitions corresponding to
   the virtio-0.9.5 specification.
 
@@ -25,14 +24,13 @@
 //
 #pragma pack(1)
 typedef struct {
-  VIRTIO_HDR Generic;
-  UINT8      VhdrMac[6];
-  UINT16     VhdrLinkStatus;
-} VNET_HDR;
+  UINT8      Mac[6];
+  UINT16     LinkStatus;
+} VIRTIO_NET_CONFIG;
 #pragma pack()
 
-#define OFFSET_OF_VNET(Field) OFFSET_OF (VNET_HDR, Field)
-#define SIZE_OF_VNET(Field)   (sizeof ((VNET_HDR *) 0)->Field)
+#define OFFSET_OF_VNET(Field) OFFSET_OF (VIRTIO_NET_CONFIG, Field)
+#define SIZE_OF_VNET(Field)   (sizeof ((VIRTIO_NET_CONFIG *) 0)->Field)
 
 //
 // Queue Identifiers
@@ -91,7 +89,7 @@ typedef struct {
 #define VIRTIO_NET_HDR_GSO_ECN   BIT7
 
 //
-// Link Status Bits in VNET_HDR.VhdrLinkStatus
+// Link Status Bits in VIRTIO_NET_CONFIG.LinkStatus
 //
 #define VIRTIO_NET_S_LINK_UP  BIT0
 #define VIRTIO_NET_S_ANNOUNCE BIT1
diff --git a/OvmfPkg/Include/IndustryStandard/VirtioScsi.h b/OvmfPkg/Include/IndustryStandard/VirtioScsi.h
index 59ce97e..0c9b520 100644
--- a/OvmfPkg/Include/IndustryStandard/VirtioScsi.h
+++ b/OvmfPkg/Include/IndustryStandard/VirtioScsi.h
@@ -26,22 +26,21 @@
 //
 #pragma pack(1)
 typedef struct {
-  VIRTIO_HDR Generic;
-  UINT32     VhdrNumQueues;
-  UINT32     VhdrSegMax;
-  UINT32     VhdrMaxSectors;
-  UINT32     VhdrCmdPerLun;
-  UINT32     VhdrEventInfoSize;
-  UINT32     VhdrSenseSize;
-  UINT32     VhdrCdbSize;
-  UINT16     VhdrMaxChannel;
-  UINT16     VhdrMaxTarget;
-  UINT32     VhdrMaxLun;
-} VSCSI_HDR;
+  UINT32     NumQueues;
+  UINT32     SegMax;
+  UINT32     MaxSectors;
+  UINT32     CmdPerLun;
+  UINT32     EventInfoSize;
+  UINT32     SenseSize;
+  UINT32     CdbSize;
+  UINT16     MaxChannel;
+  UINT16     MaxTarget;
+  UINT32     MaxLun;
+} VIRTIO_SCSI_CONFIG;
 #pragma pack()
 
-#define OFFSET_OF_VSCSI(Field) OFFSET_OF (VSCSI_HDR, Field)
-#define SIZE_OF_VSCSI(Field)   (sizeof ((VSCSI_HDR *) 0)->Field)
+#define OFFSET_OF_VSCSI(Field) OFFSET_OF (VIRTIO_SCSI_CONFIG, Field)
+#define SIZE_OF_VSCSI(Field)   (sizeof ((VIRTIO_SCSI_CONFIG *) 0)->Field)
 
 #define VIRTIO_SCSI_F_INOUT   BIT0
 #define VIRTIO_SCSI_F_HOTPLUG BIT1
diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h
index 5130349..1b28f2f 100644
--- a/OvmfPkg/Include/Library/VirtioLib.h
+++ b/OvmfPkg/Include/Library/VirtioLib.h
@@ -17,17 +17,19 @@
 #ifndef _VIRTIO_LIB_H_
 #define _VIRTIO_LIB_H_
 
-#include 
+#include 
+
 #include 
 
 /**
 
-  Write a word into Region 0 of the device specified by PciIo.
+  Write a word into VirtIo Device Specific Region
 
-  Region 0 must be an iomem region. This is an internal function for the
-  driver-specific VIRTIO_CFG_WRITE() macros.
+  The VirtIo Device Specific Region must be an iomem region.
+  This is an internal function for the driver-specific VIRTIO_CFG_WRITE()
+  macros.
 
-  @param[in] PciIo        Target PCI device.
+  @param[in] VirtIo       Target Virtio device.
 
   @param[in] FieldOffset  Destination offset.
 
@@ -37,27 +39,28 @@
                           The least significant FieldSize bytes will be used.
 
 
-  @return  Status code returned by PciIo->Io.Write().
+  @return  Status code returned by VirtIo->WriteDevice().
 
 **/
 EFI_STATUS
 EFIAPI
-VirtioWrite (
-  IN EFI_PCI_IO_PROTOCOL *PciIo,
-  IN UINTN               FieldOffset,
-  IN UINTN               FieldSize,
-  IN UINT64              Value
+VirtioWriteDevice (
+  IN VIRTIO_DEVICE_PROTOCOL *VirtIo,
+  IN UINTN                  FieldOffset,
+  IN UINTN                  FieldSize,
+  IN UINT64                 Value
   );
 
 
 /**
 
-  Read a word from Region 0 of the device specified by PciIo.
+  Read a word from VirtIo Device Specific Region
 
-  Region 0 must be an iomem region. This is an internal function for the
-  driver-specific VIRTIO_CFG_READ() macros.
+  The VirtIo Device Specific Region must be an iomem region.
+  This is an internal function for the driver-specific VIRTIO_CFG_READ()
+  macros.
 
-  @param[in] PciIo        Source PCI device.
+  @param[in] VirtIo       Source Virtio device.
 
   @param[in] FieldOffset  Source offset.
 
@@ -69,17 +72,17 @@ VirtioWrite (
   @param[out] Buffer      Target buffer.
 
 
-  @return  Status code returned by PciIo->Io.Read().
+  @return  Status code returned by VirtIo->ReadDevice().
 
 **/
 EFI_STATUS
 EFIAPI
-VirtioRead (
-  IN  EFI_PCI_IO_PROTOCOL *PciIo,
-  IN  UINTN               FieldOffset,
-  IN  UINTN               FieldSize,
-  IN  UINTN               BufferSize,
-  OUT VOID                *Buffer
+VirtioReadDevice (
+  IN  VIRTIO_DEVICE_PROTOCOL *VirtIo,
+  IN  UINTN                  FieldOffset,
+  IN  UINTN                  FieldSize,
+  IN  UINTN                  BufferSize,
+  OUT VOID                   *Buffer
   );
 
 
@@ -218,7 +221,7 @@ VirtioAppendDesc (
   Notify the host about the descriptor chain just built, and wait until the
   host processes it.
 
-  @param[in] PciIo        The target virtio PCI device to notify.
+  @param[in] VirtIo       The target virtio device to notify.
 
   @param[in] VirtQueueId  Identifies the queue for the target device.
 
@@ -229,7 +232,7 @@ VirtioAppendDesc (
                           of the descriptor chain.
 
 
-  @return              Error code from VirtioWrite() if it fails.
+  @return              Error code from VirtioWriteDevice() if it fails.
 
   @retval EFI_SUCCESS  Otherwise, the host processed all descriptors.
 
@@ -237,10 +240,10 @@ VirtioAppendDesc (
 EFI_STATUS
 EFIAPI
 VirtioFlush (
-  IN     EFI_PCI_IO_PROTOCOL *PciIo,
-  IN     UINT16              VirtQueueId,
-  IN OUT VRING               *Ring,
-  IN     DESC_INDICES        *Indices
+  IN     VIRTIO_DEVICE_PROTOCOL *VirtIo,
+  IN     UINT16                 VirtQueueId,
+  IN OUT VRING                  *Ring,
+  IN     DESC_INDICES           *Indices
   );
 
 #endif // _VIRTIO_LIB_H_
diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c
index 959bc5d..101d698 100644
--- a/OvmfPkg/Library/VirtioLib/VirtioLib.c
+++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c
@@ -3,6 +3,7 @@
   Utility functions used by virtio device drivers.
 
   Copyright (C) 2012, Red Hat, Inc.
+  Portion of Copyright (C) 2013, ARM Ltd.
 
   This program and the accompanying materials are licensed and made available
   under the terms and conditions of the BSD License which accompanies this
@@ -14,7 +15,6 @@
 
 **/
 
-#include 
 #include 
 #include 
 #include 
@@ -26,12 +26,12 @@
 
 /**
 
-  Write a word into Region 0 of the device specified by PciIo.
+  Write a word into Region 0 of the device specified by VirtIo.
 
   Region 0 must be an iomem region. This is an internal function for the
   driver-specific VIRTIO_CFG_WRITE() macros.
 
-  @param[in] PciIo        Target PCI device.
+  @param[in] VirtIo       Target VirtIo device.
 
   @param[in] FieldOffset  Destination offset.
 
@@ -41,63 +41,30 @@
                           The least significant FieldSize bytes will be used.
 
 
-  @return  Status code returned by PciIo->Io.Write().
+  @return  Status code returned by VirtIo->Io.Write().
 
 **/
 EFI_STATUS
 EFIAPI
-VirtioWrite (
-  IN EFI_PCI_IO_PROTOCOL *PciIo,
-  IN UINTN               FieldOffset,
-  IN UINTN               FieldSize,
-  IN UINT64              Value
+VirtioWriteDevice (
+  IN VIRTIO_DEVICE_PROTOCOL *VirtIo,
+  IN UINTN                  FieldOffset,
+  IN UINTN                  FieldSize,
+  IN UINT64                 Value
   )
 {
-  UINTN                     Count;
-  EFI_PCI_IO_PROTOCOL_WIDTH Width;
-
-  Count = 1;
-  switch (FieldSize) {
-    case 1:
-      Width = EfiPciIoWidthUint8;
-      break;
-
-    case 2:
-      Width = EfiPciIoWidthUint16;
-      break;
-
-    case 8:
-      Count = 2;
-      // fall through
-
-    case 4:
-      Width = EfiPciIoWidthUint32;
-      break;
-
-    default:
-      ASSERT (FALSE);
-      return EFI_INVALID_PARAMETER;
-  }
-
-  return PciIo->Io.Write (
-                     PciIo,
-                     Width,
-                     PCI_BAR_IDX0,
-                     FieldOffset,
-                     Count,
-                     &Value
-                     );
+  return VirtIo->WriteDevice (VirtIo, FieldOffset, FieldSize, Value);
 }
 
 
 /**
 
-  Read a word from Region 0 of the device specified by PciIo.
+  Read a word from Region 0 of the device specified by VirtIo.
 
   Region 0 must be an iomem region. This is an internal function for the
   driver-specific VIRTIO_CFG_READ() macros.
 
-  @param[in] PciIo        Source PCI device.
+  @param[in] VirtIo       Source VirtIo device.
 
   @param[in] FieldOffset  Source offset.
 
@@ -109,55 +76,20 @@ VirtioWrite (
   @param[out] Buffer      Target buffer.
 
 
-  @return  Status code returned by PciIo->Io.Read().
+  @return  Status code returned by VirtIo->Io.Read().
 
 **/
 EFI_STATUS
 EFIAPI
-VirtioRead (
-  IN  EFI_PCI_IO_PROTOCOL *PciIo,
-  IN  UINTN               FieldOffset,
-  IN  UINTN               FieldSize,
-  IN  UINTN               BufferSize,
-  OUT VOID                *Buffer
+VirtioReadDevice (
+  IN  VIRTIO_DEVICE_PROTOCOL *VirtIo,
+  IN  UINTN                  FieldOffset,
+  IN  UINTN                  FieldSize,
+  IN  UINTN                  BufferSize,
+  OUT VOID                   *Buffer
   )
 {
-  UINTN                     Count;
-  EFI_PCI_IO_PROTOCOL_WIDTH Width;
-
-  ASSERT (FieldSize == BufferSize);
-
-  Count = 1;
-  switch (FieldSize) {
-    case 1:
-      Width = EfiPciIoWidthUint8;
-      break;
-
-    case 2:
-      Width = EfiPciIoWidthUint16;
-      break;
-
-    case 8:
-      Count = 2;
-      // fall through
-
-    case 4:
-      Width = EfiPciIoWidthUint32;
-      break;
-
-    default:
-      ASSERT (FALSE);
-      return EFI_INVALID_PARAMETER;
-  }
-
-  return PciIo->Io.Read (
-                     PciIo,
-                     Width,
-                     PCI_BAR_IDX0,
-                     FieldOffset,
-                     Count,
-                     Buffer
-                     );
+  return VirtIo->ReadDevice (VirtIo, FieldOffset, FieldSize, BufferSize, Buffer);
 }
 
 
@@ -376,7 +308,7 @@ VirtioAppendDesc (
   Notify the host about the descriptor chain just built, and wait until the
   host processes it.
 
-  @param[in] PciIo        The target virtio PCI device to notify.
+  @param[in] VirtIo       The target virtio device to notify.
 
   @param[in] VirtQueueId  Identifies the queue for the target device.
 
@@ -387,7 +319,7 @@ VirtioAppendDesc (
                           of the descriptor chain.
 
 
-  @return              Error code from VirtioWrite() if it fails.
+  @return              Error code from VirtioWriteDevice() if it fails.
 
   @retval EFI_SUCCESS  Otherwise, the host processed all descriptors.
 
@@ -395,10 +327,10 @@ VirtioAppendDesc (
 EFI_STATUS
 EFIAPI
 VirtioFlush (
-  IN     EFI_PCI_IO_PROTOCOL *PciIo,
-  IN     UINT16              VirtQueueId,
-  IN OUT VRING               *Ring,
-  IN     DESC_INDICES        *Indices
+  IN     VIRTIO_DEVICE_PROTOCOL *VirtIo,
+  IN     UINT16                 VirtQueueId,
+  IN OUT VRING                  *Ring,
+  IN     DESC_INDICES           *Indices
   )
 {
   UINT16     NextAvailIdx;
@@ -427,12 +359,7 @@ VirtioFlush (
   // OK.
   //
   MemoryFence();
-  Status = VirtioWrite (
-             PciIo,
-             OFFSET_OF (VIRTIO_HDR, VhdrQueueNotify),
-             sizeof (UINT16),
-             VirtQueueId
-             );
+  Status = VirtIo->SetQueueNotify (VirtIo, VirtQueueId);
   if (EFI_ERROR (Status)) {
     return Status;
   }
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index dd8270b..ae49562 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -408,6 +408,7 @@
   }
 
   OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
+  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
   OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
   OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
   OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf {
diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf
index df4f227..1965e99 100644
--- a/OvmfPkg/OvmfPkgIa32.fdf
+++ b/OvmfPkg/OvmfPkgIa32.fdf
@@ -181,6 +181,7 @@ INF  MdeModulePkg/Universal/Metronome/Metronome.inf
 INF  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
 
 INF  OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
+INF  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
 INF  OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
 INF  OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
 INF  OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 8c66550..35a4ec6 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -415,6 +415,7 @@
   }
 
   OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
+  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
   OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
   OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
   OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf {
diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf
index d93a7ff..323e431 100644
--- a/OvmfPkg/OvmfPkgIa32X64.fdf
+++ b/OvmfPkg/OvmfPkgIa32X64.fdf
@@ -181,6 +181,7 @@ INF  MdeModulePkg/Universal/Metronome/Metronome.inf
 INF  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
 
 INF  OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
+INF  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
 INF  OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
 INF  OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
 INF  OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 5ab3d63..2464da4 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -413,6 +413,7 @@
   }
 
   OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
+  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
   OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
   OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
   OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf {
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index deee977..d02783e 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -181,6 +181,7 @@ INF  MdeModulePkg/Universal/Metronome/Metronome.inf
 INF  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
 
 INF  OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
+INF  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
 INF  OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
 INF  OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
 INF  OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
index 17b9f71..9b7d971 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
@@ -23,7 +23,6 @@
 
 **/
 
-#include 
 #include 
 #include 
 #include 
@@ -37,14 +36,14 @@
 /**
 
   Convenience macros to read and write region 0 IO space elements of the
-  virtio-blk PCI device, for configuration purposes.
+  virtio-blk device, for configuration purposes.
 
   The following macros make it possible to specify only the "core parameters"
   for such accesses and to derive the rest. By the time VIRTIO_CFG_WRITE()
   returns, the transaction will have been completed.
 
-  @param[in] Dev       Pointer to the VBLK_DEV structure whose PCI IO space
-                       we're accessing. Dev->PciIo must be valid.
+  @param[in] Dev       Pointer to the VBLK_DEV structure whose VirtIo space
+                       we're accessing. Dev->VirtIo must be valid.
 
   @param[in] Field     A field name from VBLK_HDR, identifying the virtio-blk
                        configuration item to access.
@@ -57,19 +56,19 @@
                        one of UINT8, UINT16, UINT32, UINT64.
 
 
-  @return  Status code returned by VirtioWrite() / VirtioRead().
+  @return  Status code returned by VirtioWriteDevice() / VirtioReadDevice().
 
 **/
 
-#define VIRTIO_CFG_WRITE(Dev, Field, Value)  (VirtioWrite (             \
-                                                (Dev)->PciIo,           \
+#define VIRTIO_CFG_WRITE(Dev, Field, Value)  (VirtioWriteDevice (       \
+                                                (Dev)->VirtIo,          \
                                                 OFFSET_OF_VBLK (Field), \
                                                 SIZE_OF_VBLK (Field),   \
                                                 (Value)                 \
                                                 ))
 
-#define VIRTIO_CFG_READ(Dev, Field, Pointer) (VirtioRead (              \
-                                                (Dev)->PciIo,           \
+#define VIRTIO_CFG_READ(Dev, Field, Pointer) (VirtioReadDevice (        \
+                                                (Dev)->VirtIo,          \
                                                 OFFSET_OF_VBLK (Field), \
                                                 SIZE_OF_VBLK (Field),   \
                                                 sizeof *(Pointer),      \
@@ -229,7 +228,7 @@ VerifyReadWriteRequest (
 
   @retval EFI_SUCCESS          Transfer complete.
 
-  @retval EFI_DEVICE_ERROR     Failed to notify host side via PCI write, or
+  @retval EFI_DEVICE_ERROR     Failed to notify host side via VirtIo write, or
                                unable to parse host response, or host response
                                is not VIRTIO_BLK_S_OK.
 
@@ -324,7 +323,7 @@ SynchronousRequest (
   //
   // virtio-blk's only virtqueue is #0, called "requestq" (see Appendix D).
   //
-  if (VirtioFlush (Dev->PciIo, 0, &Dev->Ring, &Indices) == EFI_SUCCESS &&
+  if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices) == EFI_SUCCESS &&
       HostStatus == VIRTIO_BLK_S_OK) {
     return EFI_SUCCESS;
   }
@@ -500,11 +499,6 @@ VirtioBlkFlushBlocks (
       underlying device
     - 9 Driver Binding Protocol -- for exporting ourselves
 
-  Specs relevant in the specific sense:
-  - UEFI Spec 2.3.1 + Errata C, 13.4 EFI PCI I/O Protocol
-  - Driver Writer's Guide for UEFI 2.3.1 v1.01, 18 PCI Driver Design
-    Guidelines, 18.3 PCI drivers.
-
   @param[in]  This                The EFI_DRIVER_BINDING_PROTOCOL object
                                   incorporating this driver (independently of
                                   any device).
@@ -516,11 +510,11 @@ VirtioBlkFlushBlocks (
 
   @retval EFI_SUCCESS      The driver supports the device being probed.
 
-  @retval EFI_UNSUPPORTED  Based on virtio-blk PCI discovery, we do not support
+  @retval EFI_UNSUPPORTED  Based on virtio-blk discovery, we do not support
                            the device.
 
   @return                  Error codes from the OpenProtocol() boot service or
-                           the PciIo protocol.
+                           the VirtIo protocol.
 
 **/
 
@@ -533,56 +527,36 @@ VirtioBlkDriverBindingSupported (
   )
 {
   EFI_STATUS          Status;
-  EFI_PCI_IO_PROTOCOL *PciIo;
-  PCI_TYPE00          Pci;
+  VIRTIO_DEVICE_PROTOCOL *VirtIo;
 
   //
-  // Attempt to open the device with the PciIo set of interfaces. On success,
-  // the protocol is "instantiated" for the PCI device. Covers duplicate open
+  // Attempt to open the device with the VirtIo set of interfaces. On success,
+  // the protocol is "instantiated" for the VirtIo device. Covers duplicate open
   // attempts (EFI_ALREADY_STARTED).
   //
   Status = gBS->OpenProtocol (
                   DeviceHandle,               // candidate device
-                  &gEfiPciIoProtocolGuid,     // for generic PCI access
-                  (VOID **)&PciIo,            // handle to instantiate
+                  &gVirtioDeviceProtocolGuid, // for generic VirtIo access
+                  (VOID **)&VirtIo,           // handle to instantiate
                   This->DriverBindingHandle,  // requestor driver identity
                   DeviceHandle,               // ControllerHandle, according to
                                               // the UEFI Driver Model
-                  EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive PciIo access to
+                  EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive VirtIo access to
                                               // the device; to be released
                   );
   if (EFI_ERROR (Status)) {
     return Status;
   }
 
-  //
-  // Read entire PCI configuration header for more extensive check ahead.
-  //
-  Status = PciIo->Pci.Read (
-                        PciIo,                        // (protocol, device)
-                                                      // handle
-                        EfiPciIoWidthUint32,          // access width & copy
-                                                      // mode
-                        0,                            // Offset
-                        sizeof Pci / sizeof (UINT32), // Count
-                        &Pci                          // target buffer
-                        );
-
-  if (Status == EFI_SUCCESS) {
-    //
-    // virtio-0.9.5, 2.1 PCI Discovery
-    //
-    Status = (Pci.Hdr.VendorId == 0x1AF4 &&
-              Pci.Hdr.DeviceId >= 0x1000 && Pci.Hdr.DeviceId <= 0x103F &&
-              Pci.Hdr.RevisionID == 0x00 &&
-              Pci.Device.SubsystemID == VIRTIO_SUBSYSTEM_BLOCK_DEVICE) ? EFI_SUCCESS : EFI_UNSUPPORTED;
+  if (VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_BLOCK_DEVICE) {
+    Status = EFI_UNSUPPORTED;
   }
 
   //
-  // We needed PCI IO access only transitorily, to see whether we support the
+  // We needed VirtIo access only transitorily, to see whether we support the
   // device or not.
   //
-  gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
+  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
          This->DriverBindingHandle, DeviceHandle);
   return Status;
 }
@@ -594,8 +568,8 @@ VirtioBlkDriverBindingSupported (
   device.
 
   @param[in out] Dev  The driver instance to configure. The caller is
-                      responsible for Dev->PciIo's validity (ie. working IO
-                      access to the underlying virtio-blk PCI device).
+                      responsible for Dev->VirtIo's validity (ie. working IO
+                      access to the underlying virtio-blk device).
 
   @retval EFI_SUCCESS      Setup complete.
 
@@ -626,31 +600,40 @@ VirtioBlkInit (
   // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
   //
   NextDevStat = 0;             // step 1 -- reset device
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
 
   NextDevStat |= VSTAT_ACK;    // step 2 -- acknowledge device presence
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
 
   NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
 
   //
+  // Set Page Size - MMIO VirtIo Specific
+  //
+  Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE);
+  if (EFI_ERROR (Status)) {
+    goto ReleaseQueue;
+  }
+
+  //
   // step 4a -- retrieve and validate features
   //
-  Status = VIRTIO_CFG_READ (Dev, Generic.VhdrDeviceFeatureBits, &Features);
+  Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
-  Status = VIRTIO_CFG_READ (Dev, VhdrCapacity, &NumSectors);
+
+  Status = VIRTIO_CFG_READ (Dev, Capacity, &NumSectors);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
@@ -660,7 +643,7 @@ VirtioBlkInit (
   }
 
   if (Features & VIRTIO_BLK_F_BLK_SIZE) {
-    Status = VIRTIO_CFG_READ (Dev, VhdrBlkSize, &BlockSize);
+    Status = VIRTIO_CFG_READ (Dev, BlkSize, &BlockSize);
     if (EFI_ERROR (Status)) {
       goto Failed;
     }
@@ -681,11 +664,11 @@ VirtioBlkInit (
   //
   // step 4b -- allocate virtqueue
   //
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueSelect, 0);
+  Status = Dev->VirtIo->SetQueueSel (Dev->VirtIo, 0);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
-  Status = VIRTIO_CFG_READ (Dev, Generic.VhdrQueueSize, &QueueSize);
+  Status = Dev->VirtIo->GetQueueNumMax (Dev->VirtIo, &QueueSize);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
@@ -700,22 +683,31 @@ VirtioBlkInit (
   }
 
   //
+  // Additional steps for MMIO: align the queue appropriately, and set the size
+  Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
+  Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
+  if (EFI_ERROR (Status)) {
+    goto ReleaseQueue;
+  }
+
+  //
   // step 4c -- Report GPFN (guest-physical frame number) of queue. If anything
   // fails from here on, we must release the ring resources.
   //
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueAddress,
-             (UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT);
+  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,
+      (UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT);
   if (EFI_ERROR (Status)) {
     goto ReleaseQueue;
   }
 
+
   //
   // step 5 -- Report understood features. There are no virtio-blk specific
   // features to negotiate in virtio-0.9.5, plus we do not want any of the
   // device-independent (known or unknown) VIRTIO_F_* capabilities (see
   // Appendix B).
   //
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrGuestFeatureBits, 0);
+  Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, 0);
   if (EFI_ERROR (Status)) {
     goto ReleaseQueue;
   }
@@ -724,7 +716,7 @@ VirtioBlkInit (
   // step 6 -- initialization complete
   //
   NextDevStat |= VSTAT_DRIVER_OK;
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
     goto ReleaseQueue;
   }
@@ -758,10 +750,10 @@ ReleaseQueue:
 Failed:
   //
   // Notify the host about our failure to setup: virtio-0.9.5, 2.2.2.1 Device
-  // Status. PCI IO access failure here should not mask the original error.
+  // Status. VirtIo access failure here should not mask the original error.
   //
   NextDevStat |= VSTAT_FAILED;
-  VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
 
   return Status; // reached only via Failed above
 }
@@ -788,7 +780,7 @@ VirtioBlkUninit (
   // VIRTIO_CFG_WRITE() returns, the host will have learned to stay away from
   // the old comms area.
   //
-  VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, 0);
+  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
 
   VirtioRingUninit (&Dev->Ring);
 
@@ -815,13 +807,13 @@ VirtioBlkUninit (
 
 
   @retval EFI_SUCCESS           Driver instance has been created and
-                                initialized  for the virtio-blk PCI device, it
+                                initialized  for the virtio-blk device, it
                                 is now accessibla via EFI_BLOCK_IO_PROTOCOL.
 
   @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
 
   @return                       Error codes from the OpenProtocol() boot
-                                service, the PciIo protocol, VirtioBlkInit(),
+                                service, the VirtIo protocol, VirtioBlkInit(),
                                 or the InstallProtocolInterface() boot service.
 
 **/
@@ -842,43 +834,23 @@ VirtioBlkDriverBindingStart (
     return EFI_OUT_OF_RESOURCES;
   }
 
-  Status = gBS->OpenProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
-                  (VOID **)&Dev->PciIo, This->DriverBindingHandle,
+  Status = gBS->OpenProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
+                  (VOID **)&Dev->VirtIo, This->DriverBindingHandle,
                   DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
   if (EFI_ERROR (Status)) {
     goto FreeVirtioBlk;
   }
 
-  //
-  // We must retain and ultimately restore the original PCI attributes of the
-  // device. See Driver Writer's Guide for UEFI 2.3.1 v1.01, 18.3 PCI drivers /
-  // 18.3.2 Start() and Stop().
-  //
-  // The third parameter ("Attributes", input) is ignored by the Get operation.
-  // The fourth parameter ("Result", output) is ignored by the Enable and Set
-  // operations.
-  //
-  // For virtio-blk we only need IO space access.
-  //
-  Status = Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationGet,
-                         0, &Dev->OriginalPciAttributes);
-  if (EFI_ERROR (Status)) {
-    goto ClosePciIo;
-  }
-
-  Status = Dev->PciIo->Attributes (Dev->PciIo,
-                         EfiPciIoAttributeOperationEnable,
-                         EFI_PCI_IO_ATTRIBUTE_IO, NULL);
-  if (EFI_ERROR (Status)) {
-    goto ClosePciIo;
+  if (Dev->VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_BLOCK_DEVICE) {
+    return EFI_UNSUPPORTED;
   }
 
   //
-  // PCI IO access granted, configure virtio-blk device.
+  // VirtIo access granted, configure virtio-blk device.
   //
   Status = VirtioBlkInit (Dev);
   if (EFI_ERROR (Status)) {
-    goto RestorePciAttributes;
+    goto CloseVirtIo;
   }
 
   //
@@ -897,12 +869,8 @@ VirtioBlkDriverBindingStart (
 UninitDev:
   VirtioBlkUninit (Dev);
 
-RestorePciAttributes:
-  Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationSet,
-                Dev->OriginalPciAttributes, NULL);
-
-ClosePciIo:
-  gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
+CloseVirtIo:
+  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
          This->DriverBindingHandle, DeviceHandle);
 
 FreeVirtioBlk:
@@ -973,10 +941,7 @@ VirtioBlkDriverBindingStop (
 
   VirtioBlkUninit (Dev);
 
-  Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationSet,
-                Dev->OriginalPciAttributes, NULL);
-
-  gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
+  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
          This->DriverBindingHandle, DeviceHandle);
 
   FreePool (Dev);
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.h b/OvmfPkg/VirtioBlkDxe/VirtioBlk.h
index d22570d..789caf9 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.h
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.h
@@ -21,7 +21,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include 
 
@@ -34,14 +33,13 @@ typedef struct {
   // at various call depths. The table to the right should make it easier to
   // track them.
   //
-  //                    field                     init function       init dpth
-  //                    ----------------------    ------------------  ---------
-  UINT32                Signature;             // DriverBindingStart  0
-  EFI_PCI_IO_PROTOCOL   *PciIo;                // DriverBindingStart  0
-  UINT64                OriginalPciAttributes; // DriverBindingStart  0
-  VRING                 Ring;                  // VirtioRingInit      2
-  EFI_BLOCK_IO_PROTOCOL BlockIo;               // VirtioBlkInit       1
-  EFI_BLOCK_IO_MEDIA    BlockIoMedia;          // VirtioBlkInit       1
+  //                     field                    init function       init dpth
+  //                     ---------------------    ------------------  ---------
+  UINT32                 Signature;            // DriverBindingStart  0
+  VIRTIO_DEVICE_PROTOCOL *VirtIo;              // DriverBindingStart  0
+  VRING                  Ring;                 // VirtioRingInit      2
+  EFI_BLOCK_IO_PROTOCOL  BlockIo;              // VirtioBlkInit       1
+  EFI_BLOCK_IO_MEDIA     BlockIoMedia;         // VirtioBlkInit       1
 } VBLK_DEV;
 
 #define VIRTIO_BLK_FROM_BLOCK_IO(BlockIoPointer) \
@@ -66,11 +64,6 @@ typedef struct {
       underlying device
     - 9 Driver Binding Protocol -- for exporting ourselves
 
-  Specs relevant in the specific sense:
-  - UEFI Spec 2.3.1 + Errata C, 13.4 EFI PCI I/O Protocol
-  - Driver Writer's Guide for UEFI 2.3.1 v1.01, 18 PCI Driver Design
-    Guidelines, 18.3 PCI drivers.
-
   @param[in]  This                The EFI_DRIVER_BINDING_PROTOCOL object
                                   incorporating this driver (independently of
                                   any device).
@@ -82,11 +75,10 @@ typedef struct {
 
   @retval EFI_SUCCESS      The driver supports the device being probed.
 
-  @retval EFI_UNSUPPORTED  Based on virtio-blk PCI discovery, we do not support
+  @retval EFI_UNSUPPORTED  Based on virtio-blk discovery, we do not support
                            the device.
 
-  @return                  Error codes from the OpenProtocol() boot service or
-                           the PciIo protocol.
+  @return                  Error codes from the OpenProtocol() boot service.
 
 **/
 
@@ -117,14 +109,14 @@ VirtioBlkDriverBindingSupported (
 
 
   @retval EFI_SUCCESS           Driver instance has been created and
-                                initialized  for the virtio-blk PCI device, it
+                                initialized  for the virtio-blk device, it
                                 is now accessibla via EFI_BLOCK_IO_PROTOCOL.
 
   @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
 
   @return                       Error codes from the OpenProtocol() boot
-                                service, the PciIo protocol, VirtioBlkInit(),
-                                or the InstallProtocolInterface() boot service.
+                                service, VirtioBlkInit(), or the
+                                InstallProtocolInterface() boot service.
 
 **/
 
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf b/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
index 6dffc3a..d5975b7 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
@@ -38,5 +38,5 @@
   VirtioLib
 
 [Protocols]
-  gEfiBlockIoProtocolGuid  ## BY_START
-  gEfiPciIoProtocolGuid    ## TO_START
+  gEfiBlockIoProtocolGuid   ## BY_START
+  gVirtioDeviceProtocolGuid ## TO_START
diff --git a/OvmfPkg/VirtioNetDxe/ComponentName.c b/OvmfPkg/VirtioNetDxe/ComponentName.c
index a291405..2c96adb 100644
--- a/OvmfPkg/VirtioNetDxe/ComponentName.c
+++ b/OvmfPkg/VirtioNetDxe/ComponentName.c
@@ -139,20 +139,20 @@ VirtioNetGetControllerName (
   }
 
   //
-  // confirm that the device is managed by this driver, using the PCI IO
+  // confirm that the device is managed by this driver, using the VirtIo
   // Protocol
   //
   Status = EfiTestManagedDevice (
              ControllerHandle,
              gVirtioNetDriverBinding.DriverBindingHandle,
-             &gEfiPciIoProtocolGuid
+             &gVirtioDeviceProtocolGuid
              );
   if (EFI_ERROR (Status)) {
     return Status;
   }
 
   //
-  // we don't give different names to the bus (= parent, = PCI) handle and the
+  // we don't give different names to the bus (= parent) handle and the
   // child (= MAC) handle
   //
   return LookupUnicodeString2 (
diff --git a/OvmfPkg/VirtioNetDxe/DriverBinding.c b/OvmfPkg/VirtioNetDxe/DriverBinding.c
index c9259ab..330f1f3 100644
--- a/OvmfPkg/VirtioNetDxe/DriverBinding.c
+++ b/OvmfPkg/VirtioNetDxe/DriverBinding.c
@@ -15,7 +15,6 @@
 
 **/
 
-#include 
 #include 
 #include 
 #include 
@@ -50,7 +49,7 @@
                                     unused.
 
   @retval EFI_UNSUPPORTED           The host doesn't supply a MAC address.
-  @return                           Status codes from Dev->PciIo->Io.Read(),
+  @return                           Status codes from Dev->VirtIo->Io.Read(),
                                     VIRTIO_CFG_READ() and VIRTIO_CFG_WRITE().
   @retval EFI_SUCCESS               Configuration values retrieved.
 */
@@ -74,19 +73,19 @@ VirtioNetGetFeatures (
   // Initialization Sequence), but don't complete setting it up.
   //
   NextDevStat = 0;             // step 1 -- reset device
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
     return Status;
   }
 
   NextDevStat |= VSTAT_ACK;    // step 2 -- acknowledge device presence
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
     goto YieldDevice;
   }
 
   NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
     goto YieldDevice;
   }
@@ -94,7 +93,7 @@ VirtioNetGetFeatures (
   //
   // step 4a -- retrieve and validate features
   //
-  Status = VIRTIO_CFG_READ (Dev, Generic.VhdrDeviceFeatureBits, &Features);
+  Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features);
   if (EFI_ERROR (Status)) {
     goto YieldDevice;
   }
@@ -106,13 +105,12 @@ VirtioNetGetFeatures (
     Status = EFI_UNSUPPORTED;
     goto YieldDevice;
   }
-  Status = Dev->PciIo->Io.Read (Dev->PciIo,           // PciIo
-                            EfiPciIoWidthUint8,       // Width
-                            PCI_BAR_IDX0,             // BarIndex
-                            OFFSET_OF_VNET (VhdrMac), // Offset
-                            SIZE_OF_VNET (VhdrMac),   // Count
-                            MacAddress                // Buffer
-                            );
+  Status = Dev->VirtIo->ReadDevice (Dev->VirtIo,
+                                    OFFSET_OF_VNET (Mac), // Offset
+                                    sizeof(UINT8),        // FieldSize
+                                    SIZE_OF_VNET (Mac),   // BufferSize
+                                    MacAddress            // Buffer
+                                    );
 
   if (EFI_ERROR (Status)) {
     goto YieldDevice;
@@ -126,7 +124,7 @@ VirtioNetGetFeatures (
   }
   else {
     *MediaPresentSupported = TRUE;
-    Status = VIRTIO_CFG_READ (Dev, VhdrLinkStatus, &LinkStatus);
+    Status = VIRTIO_CFG_READ (Dev, LinkStatus, &LinkStatus);
     if (EFI_ERROR (Status)) {
       goto YieldDevice;
     }
@@ -134,7 +132,7 @@ VirtioNetGetFeatures (
   }
 
 YieldDevice:
-  VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus,
+  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo,
     EFI_ERROR (Status) ? VSTAT_FAILED : 0);
 
   return Status;
@@ -207,9 +205,9 @@ VirtioNetSnpPopulate (
   Dev->Snp.Mode           = &Dev->Snm;
 
   Dev->Snm.State                 = EfiSimpleNetworkStopped;
-  Dev->Snm.HwAddressSize         = SIZE_OF_VNET (VhdrMac);
-  Dev->Snm.MediaHeaderSize       = SIZE_OF_VNET (VhdrMac) + // dst MAC
-                                   SIZE_OF_VNET (VhdrMac) + // src MAC
+  Dev->Snm.HwAddressSize         = SIZE_OF_VNET (Mac);
+  Dev->Snm.MediaHeaderSize       = SIZE_OF_VNET (Mac) + // dst MAC
+                                   SIZE_OF_VNET (Mac) + // src MAC
                                    2;                       // Ethertype
   Dev->Snm.MaxPacketSize         = 1500;
   Dev->Snm.NvRamSize             = 0;
@@ -222,7 +220,7 @@ VirtioNetSnpPopulate (
   Dev->Snm.MacAddressChangeable  = FALSE;
   Dev->Snm.MultipleTxSupported   = TRUE;
 
-  ASSERT (SIZE_OF_VNET (VhdrMac) <= sizeof (EFI_MAC_ADDRESS));
+  ASSERT (SIZE_OF_VNET (Mac) <= sizeof (EFI_MAC_ADDRESS));
 
   Status = VirtioNetGetFeatures (Dev, &Dev->Snm.CurrentAddress,
              &Dev->Snm.MediaPresentSupported, &Dev->Snm.MediaPresent);
@@ -230,8 +228,8 @@ VirtioNetSnpPopulate (
     goto CloseWaitForPacket;
   }
   CopyMem (&Dev->Snm.PermanentAddress, &Dev->Snm.CurrentAddress,
-    SIZE_OF_VNET (VhdrMac));
-  SetMem (&Dev->Snm.BroadcastAddress, SIZE_OF_VNET (VhdrMac), 0xFF);
+    SIZE_OF_VNET (Mac));
+  SetMem (&Dev->Snm.BroadcastAddress, SIZE_OF_VNET (Mac), 0xFF);
 
   //
   // VirtioNetExitBoot() is queued by ExitBootServices(); its purpose is to
@@ -348,31 +346,36 @@ VirtioNetDriverBindingSupported (
   )
 {
   EFI_STATUS          Status;
-  EFI_PCI_IO_PROTOCOL *PciIo;
-  PCI_TYPE00          Pci;
-
-  Status = gBS->OpenProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
-                  (VOID **)&PciIo, This->DriverBindingHandle, DeviceHandle,
-                  EFI_OPEN_PROTOCOL_BY_DRIVER);
+  VIRTIO_DEVICE_PROTOCOL *VirtIo;
+
+  //
+  // Attempt to open the device with the VirtIo set of interfaces. On success,
+  // the protocol is "instantiated" for the VirtIo device. Covers duplicate open
+  // attempts (EFI_ALREADY_STARTED).
+  //
+  Status = gBS->OpenProtocol (
+                  DeviceHandle,               // candidate device
+                  &gVirtioDeviceProtocolGuid, // for generic VirtIo access
+                  (VOID **)&VirtIo,           // handle to instantiate
+                  This->DriverBindingHandle,  // requestor driver identity
+                  DeviceHandle,               // ControllerHandle, according to
+                                              // the UEFI Driver Model
+                  EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive VirtIo access to
+                                              // the device; to be released
+                  );
   if (EFI_ERROR (Status)) {
     return Status;
   }
 
-  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0,
-                        sizeof Pci / sizeof (UINT32), &Pci);
+  if (VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_NETWORK_CARD) {
+    Status = EFI_UNSUPPORTED;
+  }
 
   //
-  // virtio-0.9.5, 2.1 PCI Discovery:
-  // the network device has Subsystem Device ID 1
+  // We needed VirtIo access only transitorily, to see whether we support the
+  // device or not.
   //
-  if (Status == EFI_SUCCESS) {
-    Status = (Pci.Hdr.VendorId == 0x1AF4 &&
-              Pci.Hdr.DeviceId >= 0x1000 && Pci.Hdr.DeviceId <= 0x103F &&
-              Pci.Hdr.RevisionID == 0x00 &&
-              Pci.Device.SubsystemID == VIRTIO_SUBSYSTEM_NETWORK_CARD) ? EFI_SUCCESS : EFI_UNSUPPORTED;
-  }
-
-  gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
+  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
          This->DriverBindingHandle, DeviceHandle);
   return Status;
 }
@@ -438,7 +441,7 @@ VirtioNetDriverBindingStart (
   VNET_DEV                 *Dev;
   EFI_DEVICE_PATH_PROTOCOL *DevicePath;
   MAC_ADDR_DEVICE_PATH     MacNode;
-  VOID                     *ChildPciIo;
+  VOID                     *ChildVirtIo;
 
   //
   // allocate space for the driver instance
@@ -449,30 +452,15 @@ VirtioNetDriverBindingStart (
   }
   Dev->Signature = VNET_SIG;
 
-  //
-  // get PCI access to the device and keep it open
-  //
-  Status = gBS->OpenProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
-                  (VOID **)&Dev->PciIo, This->DriverBindingHandle,
+  Status = gBS->OpenProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
+                  (VOID **)&Dev->VirtIo, This->DriverBindingHandle,
                   DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
   if (EFI_ERROR (Status)) {
     goto FreeVirtioNet;
   }
 
-  //
-  // save original PCI attributes and enable IO space access
-  //
-  Status = Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationGet,
-                         0, &Dev->OrigPciAttributes);
-  if (EFI_ERROR (Status)) {
-    goto ClosePciIo;
-  }
-
-  Status = Dev->PciIo->Attributes (Dev->PciIo,
-                         EfiPciIoAttributeOperationEnable,
-                         EFI_PCI_IO_ATTRIBUTE_IO, NULL);
-  if (EFI_ERROR (Status)) {
-    goto ClosePciIo;
+  if (Dev->VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_NETWORK_CARD) {
+    return EFI_UNSUPPORTED;
   }
 
   //
@@ -481,11 +469,11 @@ VirtioNetDriverBindingStart (
   //
   Status = VirtioNetSnpPopulate (Dev);
   if (EFI_ERROR (Status)) {
-    goto RestorePciAttributes;
+    goto CloseVirtIo;
   }
 
   //
-  // get the device path of the virtio-net PCI device -- one-shot open
+  // get the device path of the virtio-net device -- one-shot open
   //
   Status = gBS->OpenProtocol (DeviceHandle, &gEfiDevicePathProtocolGuid,
                   (VOID **)&DevicePath, This->DriverBindingHandle,
@@ -523,11 +511,11 @@ VirtioNetDriverBindingStart (
   }
 
   //
-  // make a note that we keep this device open with PciIo for the sake of this
+  // make a note that we keep this device open with VirtIo for the sake of this
   // child
   //
-  Status = gBS->OpenProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
-                  &ChildPciIo, This->DriverBindingHandle,
+  Status = gBS->OpenProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
+                  &ChildVirtIo, This->DriverBindingHandle,
                   Dev->MacHandle, EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER);
   if (EFI_ERROR (Status)) {
     goto UninstallMultiple;
@@ -547,12 +535,8 @@ FreeMacDevicePath:
 Evacuate:
   VirtioNetSnpEvacuate (Dev);
 
-RestorePciAttributes:
-  Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationSet,
-                Dev->OrigPciAttributes, NULL);
-
-ClosePciIo:
-  gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
+CloseVirtIo:
+  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
          This->DriverBindingHandle, DeviceHandle);
 
 FreeVirtioNet:
@@ -637,7 +621,7 @@ VirtioNetDriverBindingStop (
       Status = EFI_DEVICE_ERROR;
     }
     else {
-      gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
+      gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
              This->DriverBindingHandle, Dev->MacHandle);
       gBS->UninstallMultipleProtocolInterfaces (Dev->MacHandle,
              &gEfiDevicePathProtocolGuid,    Dev->MacDevicePath,
@@ -645,8 +629,6 @@ VirtioNetDriverBindingStop (
              NULL);
       FreePool (Dev->MacDevicePath);
       VirtioNetSnpEvacuate (Dev);
-      Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationSet,
-                    Dev->OrigPciAttributes, NULL);
       FreePool (Dev);
     }
 
@@ -657,7 +639,7 @@ VirtioNetDriverBindingStop (
   //
   // release remaining resources, tied directly to the parent handle
   //
-  gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
+  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
          This->DriverBindingHandle, DeviceHandle);
 
   return EFI_SUCCESS;
diff --git a/OvmfPkg/VirtioNetDxe/Events.c b/OvmfPkg/VirtioNetDxe/Events.c
index b9d7bbf..5be1af6 100644
--- a/OvmfPkg/VirtioNetDxe/Events.c
+++ b/OvmfPkg/VirtioNetDxe/Events.c
@@ -86,6 +86,6 @@ VirtioNetExitBoot (
 
   Dev = Context;
   if (Dev->Snm.State == EfiSimpleNetworkInitialized) {
-    VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, 0);
+    Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
   }
 }
diff --git a/OvmfPkg/VirtioNetDxe/SnpGetStatus.c b/OvmfPkg/VirtioNetDxe/SnpGetStatus.c
index adb57cf..4393d24 100644
--- a/OvmfPkg/VirtioNetDxe/SnpGetStatus.c
+++ b/OvmfPkg/VirtioNetDxe/SnpGetStatus.c
@@ -90,7 +90,7 @@ VirtioNetGetStatus (
   if (Dev->Snm.MediaPresentSupported) {
     UINT16 LinkStatus;
 
-    Status = VIRTIO_CFG_READ (Dev, VhdrLinkStatus, &LinkStatus);
+    Status = VIRTIO_CFG_READ (Dev, LinkStatus, &LinkStatus);
     if (EFI_ERROR (Status)) {
       goto Exit;
     }
diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
index 6cee014..56a55db 100644
--- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c
+++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
@@ -57,14 +57,15 @@ VirtioNetInitRing (
   //
   // step 4b -- allocate selected queue
   //
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueSelect, Selector);
+  Status = Dev->VirtIo->SetQueueSel (Dev->VirtIo, Selector);
   if (EFI_ERROR (Status)) {
     return Status;
   }
-  Status = VIRTIO_CFG_READ (Dev, Generic.VhdrQueueSize, &QueueSize);
+  Status = Dev->VirtIo->GetQueueNumMax (Dev->VirtIo, &QueueSize);
   if (EFI_ERROR (Status)) {
     return Status;
   }
+
   //
   // For each packet (RX and TX alike), we need two descriptors:
   // one for the virtio-net request header, and another one for the data
@@ -80,8 +81,8 @@ VirtioNetInitRing (
   //
   // step 4c -- report GPFN (guest-physical frame number) of queue
   //
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueAddress,
-             (UINTN) Ring->Base >> EFI_PAGE_SHIFT);
+  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,
+      (UINTN) Ring->Base >> EFI_PAGE_SHIFT);
   if (EFI_ERROR (Status)) {
     VirtioRingUninit (Ring);
   }
@@ -287,10 +288,9 @@ VirtioNetInitRx (
   // virtio-0.9.5, 2.4.1.4 Notifying the Device
   //
   MemoryFence ();
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueNotify, VIRTIO_NET_Q_RX);
-
+  Status = Dev->VirtIo->SetQueueNotify (Dev->VirtIo, VIRTIO_NET_Q_RX);
   if (EFI_ERROR (Status)) {
-    VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, 0);
+    Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
     FreePool (Dev->RxBuf);
   }
 
@@ -366,25 +366,34 @@ VirtioNetInitialize (
   // virtio-0.9.5 spec, 2.2.1 Device Initialization Sequence.
   //
   NextDevStat = VSTAT_ACK;    // step 2 -- acknowledge device presence
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
     goto InitFailed;
   }
 
   NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
     goto DeviceFailed;
   }
 
   //
+  // Set Page Size - MMIO VirtIo Specific
+  //
+  Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE);
+  if (EFI_ERROR (Status)) {
+    goto ReleaseTxRing;
+  }
+
+  //
   // step 4a -- retrieve features. Note that we're past validating required
   // features in VirtioNetGetFeatures().
   //
-  Status = VIRTIO_CFG_READ (Dev, Generic.VhdrDeviceFeatureBits, &Features);
+  Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features);
   if (EFI_ERROR (Status)) {
     goto DeviceFailed;
   }
+
   ASSERT (Features & VIRTIO_NET_F_MAC);
   ASSERT (Dev->Snm.MediaPresentSupported ==
     !!(Features & VIRTIO_NET_F_STATUS));
@@ -406,7 +415,7 @@ VirtioNetInitialize (
   // step 5 -- keep only the features we want
   //
   Features &= VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS;
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrGuestFeatureBits, Features);
+  Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
   if (EFI_ERROR (Status)) {
     goto ReleaseTxRing;
   }
@@ -415,7 +424,7 @@ VirtioNetInitialize (
   // step 6 -- virtio-net initialization complete
   //
   NextDevStat |= VSTAT_DRIVER_OK;
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
     goto ReleaseTxRing;
   }
@@ -441,7 +450,7 @@ ReleaseTxAux:
   VirtioNetShutdownTx (Dev);
 
 AbortDevice:
-  VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, 0);
+  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
 
 ReleaseTxRing:
   VirtioRingUninit (&Dev->TxRing);
@@ -453,7 +462,7 @@ DeviceFailed:
   //
   // restore device status invariant for the EfiSimpleNetworkStarted state
   //
-  VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, 0);
+  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
 
 InitFailed:
   gBS->RestoreTPL (OldTpl);
diff --git a/OvmfPkg/VirtioNetDxe/SnpReceive.c b/OvmfPkg/VirtioNetDxe/SnpReceive.c
index 87c6ca9..99abd7e 100644
--- a/OvmfPkg/VirtioNetDxe/SnpReceive.c
+++ b/OvmfPkg/VirtioNetDxe/SnpReceive.c
@@ -147,14 +147,14 @@ VirtioNetReceive (
   CopyMem (Buffer, RxPtr, RxLen);
 
   if (DestAddr != NULL) {
-    CopyMem (DestAddr, RxPtr, SIZE_OF_VNET (VhdrMac));
+    CopyMem (DestAddr, RxPtr, SIZE_OF_VNET (Mac));
   }
-  RxPtr += SIZE_OF_VNET (VhdrMac);
+  RxPtr += SIZE_OF_VNET (Mac);
 
   if (SrcAddr != NULL) {
-    CopyMem (SrcAddr, RxPtr, SIZE_OF_VNET (VhdrMac));
+    CopyMem (SrcAddr, RxPtr, SIZE_OF_VNET (Mac));
   }
-  RxPtr += SIZE_OF_VNET (VhdrMac);
+  RxPtr += SIZE_OF_VNET (Mac);
 
   if (Protocol != NULL) {
     *Protocol = (UINT16) ((RxPtr[0] << 8) | RxPtr[1]);
@@ -177,9 +177,7 @@ RecycleDesc:
   *Dev->RxRing.Avail.Idx = AvailIdx;
 
   MemoryFence ();
-  NotifyStatus = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueNotify,
-                   VIRTIO_NET_Q_RX);
-
+  NotifyStatus = Dev->VirtIo->SetQueueNotify (Dev->VirtIo, VIRTIO_NET_Q_RX);
   if (!EFI_ERROR (Status)) { // earlier error takes precedence
     Status = NotifyStatus;
   }
diff --git a/OvmfPkg/VirtioNetDxe/SnpShutdown.c b/OvmfPkg/VirtioNetDxe/SnpShutdown.c
index 42aeca1..01409c0 100644
--- a/OvmfPkg/VirtioNetDxe/SnpShutdown.c
+++ b/OvmfPkg/VirtioNetDxe/SnpShutdown.c
@@ -63,7 +63,7 @@ VirtioNetShutdown (
     break;
   }
 
-  VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, 0);
+  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
   VirtioNetShutdownRx (Dev);
   VirtioNetShutdownTx (Dev);
   VirtioRingUninit (&Dev->TxRing);
diff --git a/OvmfPkg/VirtioNetDxe/SnpTransmit.c b/OvmfPkg/VirtioNetDxe/SnpTransmit.c
index ff922ca..7ca40d5 100644
--- a/OvmfPkg/VirtioNetDxe/SnpTransmit.c
+++ b/OvmfPkg/VirtioNetDxe/SnpTransmit.c
@@ -127,15 +127,15 @@ VirtioNetTransmit (
       goto Exit;
     }
     Ptr = Buffer;
-    ASSERT (SIZE_OF_VNET (VhdrMac) <= sizeof (EFI_MAC_ADDRESS));
+    ASSERT (SIZE_OF_VNET (Mac) <= sizeof (EFI_MAC_ADDRESS));
 
-    CopyMem (Ptr, DestAddr, SIZE_OF_VNET (VhdrMac));
-    Ptr += SIZE_OF_VNET (VhdrMac);
+    CopyMem (Ptr, DestAddr, SIZE_OF_VNET (Mac));
+    Ptr += SIZE_OF_VNET (Mac);
 
     CopyMem (Ptr,
       (SrcAddr == NULL) ? &Dev->Snm.CurrentAddress : SrcAddr,
-      SIZE_OF_VNET (VhdrMac));
-    Ptr += SIZE_OF_VNET (VhdrMac);
+      SIZE_OF_VNET (Mac));
+    Ptr += SIZE_OF_VNET (Mac);
 
     *Ptr++ = (UINT8) (*Protocol >> 8);
     *Ptr++ = (UINT8) *Protocol;
@@ -161,7 +161,7 @@ VirtioNetTransmit (
   *Dev->TxRing.Avail.Idx = AvailIdx;
 
   MemoryFence ();
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueNotify, VIRTIO_NET_Q_TX);
+  Status = Dev->VirtIo->SetQueueNotify (Dev->VirtIo, VIRTIO_NET_Q_TX);
 
 Exit:
   gBS->RestoreTPL (OldTpl);
diff --git a/OvmfPkg/VirtioNetDxe/VirtioNet.h b/OvmfPkg/VirtioNetDxe/VirtioNet.h
index 8c21bcd..31fca79 100644
--- a/OvmfPkg/VirtioNetDxe/VirtioNet.h
+++ b/OvmfPkg/VirtioNetDxe/VirtioNet.h
@@ -24,7 +24,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #define VNET_SIG SIGNATURE_32 ('V', 'N', 'E', 'T')
@@ -75,8 +74,7 @@ typedef struct {
   //                          field              init function
   //                          ------------------ ------------------------------
   UINT32                      Signature;         // VirtioNetDriverBindingStart
-  EFI_PCI_IO_PROTOCOL         *PciIo;            // VirtioNetDriverBindingStart
-  UINT64                      OrigPciAttributes; // VirtioNetDriverBindingStart
+  VIRTIO_DEVICE_PROTOCOL      *VirtIo;           // VirtioNetDriverBindingStart
   EFI_SIMPLE_NETWORK_PROTOCOL Snp;               // VirtioNetSnpPopulate
   EFI_SIMPLE_NETWORK_MODE     Snm;               // VirtioNetSnpPopulate
   EFI_EVENT                   ExitBoot;          // VirtioNetSnpPopulate
@@ -109,15 +107,15 @@ typedef struct {
 #define VIRTIO_NET_FROM_SNP(SnpPointer) \
         CR (SnpPointer, VNET_DEV, Snp, VNET_SIG)
 
-#define VIRTIO_CFG_WRITE(Dev, Field, Value)  (VirtioWrite (             \
-                                                (Dev)->PciIo,           \
+#define VIRTIO_CFG_WRITE(Dev, Field, Value)  (VirtioWriteDevice (       \
+                                                (Dev)->VirtIo,          \
                                                 OFFSET_OF_VNET (Field), \
                                                 SIZE_OF_VNET (Field),   \
                                                 (Value)                 \
                                                 ))
 
-#define VIRTIO_CFG_READ(Dev, Field, Pointer) (VirtioRead (              \
-                                                (Dev)->PciIo,           \
+#define VIRTIO_CFG_READ(Dev, Field, Pointer) (VirtioReadDevice (        \
+                                                (Dev)->VirtIo,          \
                                                 OFFSET_OF_VNET (Field), \
                                                 SIZE_OF_VNET (Field),   \
                                                 sizeof *(Pointer),      \
diff --git a/OvmfPkg/VirtioNetDxe/VirtioNet.inf b/OvmfPkg/VirtioNetDxe/VirtioNet.inf
index 408a541..a855ad4 100644
--- a/OvmfPkg/VirtioNetDxe/VirtioNet.inf
+++ b/OvmfPkg/VirtioNetDxe/VirtioNet.inf
@@ -57,4 +57,4 @@
 [Protocols]
   gEfiSimpleNetworkProtocolGuid  ## BY_START
   gEfiDevicePathProtocolGuid     ## BY_START
-  gEfiPciIoProtocolGuid          ## TO_START
+  gVirtioDeviceProtocolGuid      ## TO_START
diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
index b836fb3..006ba2d 100644
--- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
+++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
@@ -38,7 +38,6 @@
 
 **/
 
-#include 
 #include 
 #include 
 #include 
@@ -52,14 +51,13 @@
 /**
 
   Convenience macros to read and write region 0 IO space elements of the
-  virtio-scsi PCI device, for configuration purposes.
+  virtio-scsi VirtIo device, for configuration purposes.
 
   The following macros make it possible to specify only the "core parameters"
   for such accesses and to derive the rest. By the time VIRTIO_CFG_WRITE()
   returns, the transaction will have been completed.
 
-  @param[in] Dev       Pointer to the VSCSI_DEV structure whose PCI IO space
-                       we're accessing. Dev->PciIo must be valid.
+  @param[in] Dev       Pointer to the VirtIo Device Protocol
 
   @param[in] Field     A field name from VSCSI_HDR, identifying the virtio-scsi
                        configuration item to access.
@@ -72,19 +70,19 @@
                        one of UINT8, UINT16, UINT32, UINT64.
 
 
-  @return  Status codes returned by VirtioWrite() / VirtioRead().
+  @return  Status codes returned by VirtioWriteDevice() / VirtioReadDevice().
 
 **/
 
-#define VIRTIO_CFG_WRITE(Dev, Field, Value)  (VirtioWrite (              \
-                                                (Dev)->PciIo,            \
+#define VIRTIO_CFG_WRITE(Dev, Field, Value)  (VirtioWriteDevice (        \
+                                                (Dev)->VirtIo,           \
                                                 OFFSET_OF_VSCSI (Field), \
                                                 SIZE_OF_VSCSI (Field),   \
                                                 (Value)                  \
                                                 ))
 
-#define VIRTIO_CFG_READ(Dev, Field, Pointer) (VirtioRead (               \
-                                                (Dev)->PciIo,            \
+#define VIRTIO_CFG_READ(Dev, Field, Pointer) (VirtioReadDevice (         \
+                                                (Dev)->VirtIo,           \
                                                 OFFSET_OF_VSCSI (Field), \
                                                 SIZE_OF_VSCSI (Field),   \
                                                 sizeof *(Pointer),       \
@@ -471,7 +469,7 @@ VirtioScsiPassThru (
   // EFI_NOT_READY would save us the effort, but it would also suggest that the
   // caller retry.
   //
-  if (VirtioFlush (Dev->PciIo, VIRTIO_SCSI_REQUEST_QUEUE, &Dev->Ring,
+  if (VirtioFlush (Dev->VirtIo, VIRTIO_SCSI_REQUEST_QUEUE, &Dev->Ring,
         &Indices) != EFI_SUCCESS) {
     Packet->InTransferLength  = 0;
     Packet->OutTransferLength = 0;
@@ -718,33 +716,41 @@ VirtioScsiInit (
   // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
   //
   NextDevStat = 0;             // step 1 -- reset device
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
 
   NextDevStat |= VSTAT_ACK;    // step 2 -- acknowledge device presence
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
 
   NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
 
   //
+  // Set Page Size - MMIO VirtIo Specific
+  //
+  Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE);
+  if (EFI_ERROR (Status)) {
+    goto ReleaseQueue;
+  }
+
+  //
   // step 4a -- retrieve and validate features
   //
-  Status = VIRTIO_CFG_READ (Dev, Generic.VhdrDeviceFeatureBits, &Features);
+  Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
   Dev->InOutSupported = !!(Features & VIRTIO_SCSI_F_INOUT);
 
-  Status = VIRTIO_CFG_READ (Dev, VhdrMaxChannel, &MaxChannel);
+  Status = VIRTIO_CFG_READ (Dev, MaxChannel, &MaxChannel);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
@@ -756,7 +762,7 @@ VirtioScsiInit (
     goto Failed;
   }
 
-  Status = VIRTIO_CFG_READ (Dev, VhdrNumQueues, &NumQueues);
+  Status = VIRTIO_CFG_READ (Dev, NumQueues, &NumQueues);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
@@ -765,7 +771,7 @@ VirtioScsiInit (
     goto Failed;
   }
 
-  Status = VIRTIO_CFG_READ (Dev, VhdrMaxTarget, &Dev->MaxTarget);
+  Status = VIRTIO_CFG_READ (Dev, MaxTarget, &Dev->MaxTarget);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
@@ -773,7 +779,7 @@ VirtioScsiInit (
     Dev->MaxTarget = PcdGet16 (PcdVirtioScsiMaxTargetLimit);
   }
 
-  Status = VIRTIO_CFG_READ (Dev, VhdrMaxLun, &Dev->MaxLun);
+  Status = VIRTIO_CFG_READ (Dev, MaxLun, &Dev->MaxLun);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
@@ -781,7 +787,7 @@ VirtioScsiInit (
     Dev->MaxLun = PcdGet32 (PcdVirtioScsiMaxLunLimit);
   }
 
-  Status = VIRTIO_CFG_READ (Dev, VhdrMaxSectors, &Dev->MaxSectors);
+  Status = VIRTIO_CFG_READ (Dev, MaxSectors, &Dev->MaxSectors);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
@@ -797,12 +803,11 @@ VirtioScsiInit (
   //
   // step 4b -- allocate request virtqueue
   //
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueSelect,
-             VIRTIO_SCSI_REQUEST_QUEUE);
+  Status = Dev->VirtIo->SetQueueSel (Dev->VirtIo, VIRTIO_SCSI_REQUEST_QUEUE);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
-  Status = VIRTIO_CFG_READ (Dev, Generic.VhdrQueueSize, &QueueSize);
+  Status = Dev->VirtIo->GetQueueNumMax (Dev->VirtIo, &QueueSize);
   if (EFI_ERROR (Status)) {
     goto Failed;
   }
@@ -823,8 +828,8 @@ VirtioScsiInit (
   // step 4c -- Report GPFN (guest-physical frame number) of queue. If anything
   // fails from here on, we must release the ring resources.
   //
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueAddress,
-             (UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT);
+  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,
+      (UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT);
   if (EFI_ERROR (Status)) {
     goto ReleaseQueue;
   }
@@ -834,8 +839,8 @@ VirtioScsiInit (
   // the known (or unknown) VIRTIO_SCSI_F_* or VIRTIO_F_* capabilities (see
   // virtio-0.9.5, Appendices B and I), except bidirectional transfers.
   //
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrGuestFeatureBits,
-             Features & VIRTIO_SCSI_F_INOUT);
+  Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo,
+      Features & VIRTIO_SCSI_F_INOUT);
   if (EFI_ERROR (Status)) {
     goto ReleaseQueue;
   }
@@ -844,11 +849,11 @@ VirtioScsiInit (
   // We expect these maximum sizes from the host. Since they are
   // guest-negotiable, ask for them rather than just checking them.
   //
-  Status = VIRTIO_CFG_WRITE (Dev, VhdrCdbSize, VIRTIO_SCSI_CDB_SIZE);
+  Status = VIRTIO_CFG_WRITE (Dev, CdbSize, VIRTIO_SCSI_CDB_SIZE);
   if (EFI_ERROR (Status)) {
     goto ReleaseQueue;
   }
-  Status = VIRTIO_CFG_WRITE (Dev, VhdrSenseSize, VIRTIO_SCSI_SENSE_SIZE);
+  Status = VIRTIO_CFG_WRITE (Dev, SenseSize, VIRTIO_SCSI_SENSE_SIZE);
   if (EFI_ERROR (Status)) {
     goto ReleaseQueue;
   }
@@ -857,7 +862,7 @@ VirtioScsiInit (
   // step 6 -- initialization complete
   //
   NextDevStat |= VSTAT_DRIVER_OK;
-  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
     goto ReleaseQueue;
   }
@@ -901,10 +906,10 @@ ReleaseQueue:
 Failed:
   //
   // Notify the host about our failure to setup: virtio-0.9.5, 2.2.2.1 Device
-  // Status. PCI IO access failure here should not mask the original error.
+  // Status. VirtIo access failure here should not mask the original error.
   //
   NextDevStat |= VSTAT_FAILED;
-  VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
+  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
 
   Dev->InOutSupported = FALSE;
   Dev->MaxTarget      = 0;
@@ -928,7 +933,7 @@ VirtioScsiUninit (
   // VIRTIO_CFG_WRITE() returns, the host will have learned to stay away from
   // the old comms area.
   //
-  VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, 0);
+  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
 
   Dev->InOutSupported = FALSE;
   Dev->MaxTarget      = 0;
@@ -953,11 +958,8 @@ VirtioScsiUninit (
 // The implementation follows:
 // - Driver Writer's Guide for UEFI 2.3.1 v1.01
 //   - 5.1.3.4 OpenProtocol() and CloseProtocol()
-//   - 18      PCI Driver Design Guidelines
-//   - 18.3    PCI drivers
 // - UEFI Spec 2.3.1 + Errata C
 //   -  6.3 Protocol Handler Services
-//   - 13.4 EFI PCI I/O Protocol
 //
 
 EFI_STATUS
@@ -968,57 +970,37 @@ VirtioScsiDriverBindingSupported (
   IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
   )
 {
-  EFI_STATUS          Status;
-  EFI_PCI_IO_PROTOCOL *PciIo;
-  PCI_TYPE00          Pci;
+  EFI_STATUS             Status;
+  VIRTIO_DEVICE_PROTOCOL *VirtIo;
 
   //
-  // Attempt to open the device with the PciIo set of interfaces. On success,
-  // the protocol is "instantiated" for the PCI device. Covers duplicate open
+  // Attempt to open the device with the VirtIo set of interfaces. On success,
+  // the protocol is "instantiated" for the VirtIo device. Covers duplicate open
   // attempts (EFI_ALREADY_STARTED).
   //
   Status = gBS->OpenProtocol (
                   DeviceHandle,               // candidate device
-                  &gEfiPciIoProtocolGuid,     // for generic PCI access
-                  (VOID **)&PciIo,            // handle to instantiate
+                  &gVirtioDeviceProtocolGuid, // for generic VirtIo access
+                  (VOID **)&VirtIo,           // handle to instantiate
                   This->DriverBindingHandle,  // requestor driver identity
                   DeviceHandle,               // ControllerHandle, according to
                                               // the UEFI Driver Model
-                  EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive PciIo access to
+                  EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive VirtIo access to
                                               // the device; to be released
                   );
   if (EFI_ERROR (Status)) {
     return Status;
   }
 
-  //
-  // Read entire PCI configuration header for more extensive check ahead.
-  //
-  Status = PciIo->Pci.Read (
-                        PciIo,                        // (protocol, device)
-                                                      // handle
-                        EfiPciIoWidthUint32,          // access width & copy
-                                                      // mode
-                        0,                            // Offset
-                        sizeof Pci / sizeof (UINT32), // Count
-                        &Pci                          // target buffer
-                        );
-
-  if (Status == EFI_SUCCESS) {
-    //
-    // virtio-0.9.5, 2.1 PCI Discovery
-    //
-    Status = (Pci.Hdr.VendorId == 0x1AF4 &&
-              Pci.Hdr.DeviceId >= 0x1000 && Pci.Hdr.DeviceId <= 0x103F &&
-              Pci.Hdr.RevisionID == 0x00 &&
-              Pci.Device.SubsystemID == VIRTIO_SUBSYSTEM_SCSI_HOST) ? EFI_SUCCESS : EFI_UNSUPPORTED;
+  if (VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_SCSI_HOST) {
+    Status = EFI_UNSUPPORTED;
   }
 
   //
-  // We needed PCI IO access only transitorily, to see whether we support the
+  // We needed VirtIo access only transitorily, to see whether we support the
   // device or not.
   //
-  gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
+  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
          This->DriverBindingHandle, DeviceHandle);
   return Status;
 }
@@ -1040,43 +1022,19 @@ VirtioScsiDriverBindingStart (
     return EFI_OUT_OF_RESOURCES;
   }
 
-  Status = gBS->OpenProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
-                  (VOID **)&Dev->PciIo, This->DriverBindingHandle,
+  Status = gBS->OpenProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
+                  (VOID **)&Dev->VirtIo, This->DriverBindingHandle,
                   DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
   if (EFI_ERROR (Status)) {
     goto FreeVirtioScsi;
   }
 
   //
-  // We must retain and ultimately restore the original PCI attributes of the
-  // device. See Driver Writer's Guide for UEFI 2.3.1 v1.01, 18.3 PCI drivers /
-  // 18.3.2 Start() and Stop().
-  //
-  // The third parameter ("Attributes", input) is ignored by the Get operation.
-  // The fourth parameter ("Result", output) is ignored by the Enable and Set
-  // operations.
-  //
-  // For virtio-scsi we only need IO space access.
-  //
-  Status = Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationGet,
-                         0, &Dev->OriginalPciAttributes);
-  if (EFI_ERROR (Status)) {
-    goto ClosePciIo;
-  }
-
-  Status = Dev->PciIo->Attributes (Dev->PciIo,
-                         EfiPciIoAttributeOperationEnable,
-                         EFI_PCI_IO_ATTRIBUTE_IO, NULL);
-  if (EFI_ERROR (Status)) {
-    goto ClosePciIo;
-  }
-
-  //
-  // PCI IO access granted, configure virtio-scsi device.
+  // VirtIo access granted, configure virtio-scsi device.
   //
   Status = VirtioScsiInit (Dev);
   if (EFI_ERROR (Status)) {
-    goto RestorePciAttributes;
+    goto CloseVirtIo;
   }
 
   //
@@ -1096,12 +1054,8 @@ VirtioScsiDriverBindingStart (
 UninitDev:
   VirtioScsiUninit (Dev);
 
-RestorePciAttributes:
-  Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationSet,
-                Dev->OriginalPciAttributes, NULL);
-
-ClosePciIo:
-  gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
+CloseVirtIo:
+  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
          This->DriverBindingHandle, DeviceHandle);
 
 FreeVirtioScsi:
@@ -1149,10 +1103,7 @@ VirtioScsiDriverBindingStop (
 
   VirtioScsiUninit (Dev);
 
-  Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationSet,
-                Dev->OriginalPciAttributes, NULL);
-
-  gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
+  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
          This->DriverBindingHandle, DeviceHandle);
 
   FreePool (Dev);
diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.h b/OvmfPkg/VirtioScsiDxe/VirtioScsi.h
index f5220b2..0d3181d 100644
--- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.h
+++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.h
@@ -20,7 +20,6 @@
 
 #include 
 #include 
-#include 
 #include 
 
 #include 
@@ -49,18 +48,17 @@ typedef struct {
   // at various call depths. The table to the right should make it easier to
   // track them.
   //
-  //                              field                     init function       init depth
-  //                              ----------------------    ------------------  ----------
-  UINT32                          Signature;             // DriverBindingStart  0
-  EFI_PCI_IO_PROTOCOL             *PciIo;                // DriverBindingStart  0
-  UINT64                          OriginalPciAttributes; // DriverBindingStart  0
-  BOOLEAN                         InOutSupported;        // VirtioScsiInit      1
-  UINT16                          MaxTarget;             // VirtioScsiInit      1
-  UINT32                          MaxLun;                // VirtioScsiInit      1
-  UINT32                          MaxSectors;            // VirtioScsiInit      1
-  VRING                           Ring;                  // VirtioRingInit      2
-  EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;              // VirtioScsiInit      1
-  EFI_EXT_SCSI_PASS_THRU_MODE     PassThruMode;          // VirtioScsiInit      1
+  //                              field              init function       init depth
+  //                              ----------------   ------------------  ----------
+  UINT32                          Signature;      // DriverBindingStart  0
+  VIRTIO_DEVICE_PROTOCOL          *VirtIo;        // DriverBindingStart  0
+  BOOLEAN                         InOutSupported; // VirtioScsiInit      1
+  UINT16                          MaxTarget;      // VirtioScsiInit      1
+  UINT32                          MaxLun;         // VirtioScsiInit      1
+  UINT32                          MaxSectors;     // VirtioScsiInit      1
+  VRING                           Ring;           // VirtioRingInit      2
+  EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;       // VirtioScsiInit      1
+  EFI_EXT_SCSI_PASS_THRU_MODE     PassThruMode;   // VirtioScsiInit      1
 } VSCSI_DEV;
 
 #define VIRTIO_SCSI_FROM_PASS_THRU(PassThruPointer) \
diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.inf b/OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
index 8209c50..7558112 100644
--- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
@@ -40,7 +40,7 @@
 
 [Protocols]
   gEfiExtScsiPassThruProtocolGuid  ## BY_START
-  gEfiPciIoProtocolGuid            ## TO_START
+  gVirtioDeviceProtocolGuid        ## TO_START
 
 [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdVirtioScsiMaxTargetLimit ## CONSUMES
-- 
1.7.0.4


------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from 
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60135031&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel