]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: Make the VirtIo devices use the new VIRTIO_DEVICE_PROTOCOL
authorOlivier Martin <olivier.martin@arm.com>
Wed, 11 Dec 2013 16:58:22 +0000 (16:58 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 11 Dec 2013 16:58:22 +0000 (16:58 +0000)
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 <olivier.martin@arm.com>
v5:
- VirtioFlush(): update comment block in VirtioLib.[hc]; error code is
  propagated from VirtIo->SetQueueNotify().
- VirtioBlkInit(): jump to Failed label if SetPageSize() fails
- VirtioBlkInit(): fixup comment, and add error handling, near
  SetQueueNum() call
- VirtioBlkDriverBindingStart(): remove redundant (always false) check for
  a subsystem device ID different from VIRTIO_SUBSYSTEM_BLOCK_DEVICE;
  VirtioBlkDriverBindingSupported() handles it already
- VirtioNetGetFeatures(): update stale comment block
- VirtioNetGetFeatures(): retrieve MAC address byte for byte (open-coded
  loop)
- VirtioNetDriverBindingStart(): remove redundant (always false) check for
  a subsystem device ID different from VIRTIO_SUBSYSTEM_NETWORK_CARD;
  VirtioNetDriverBindingSupported() handles it already
- VirtioNetInitRing(): call SetQueueNum() and SetQueueAlign() for proper
  MMIO operation
- VirtioNetInitialize(): fix destination error label for when
  SetPageSize() fails
- VirtioScsi.c: fix comment block of VIRTIO_CFG_WRITE()/VIRTIO_CFG_READ()
- VirtioScsiInit(): fix destination error label for when SetPageSize()
  fails
- VirtioScsiInit(): call SetQueueNum() and SetQueueAlign() for proper MMIO
  operation

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14966 6f19259b-4bc3-4df7-8a09-765794883524

27 files changed:
OvmfPkg/Include/IndustryStandard/VirtioBlk.h
OvmfPkg/Include/IndustryStandard/VirtioNet.h
OvmfPkg/Include/IndustryStandard/VirtioScsi.h
OvmfPkg/Include/Library/VirtioLib.h
OvmfPkg/Library/VirtioLib/VirtioLib.c
OvmfPkg/OvmfPkgIa32.dsc
OvmfPkg/OvmfPkgIa32.fdf
OvmfPkg/OvmfPkgIa32X64.dsc
OvmfPkg/OvmfPkgIa32X64.fdf
OvmfPkg/OvmfPkgX64.dsc
OvmfPkg/OvmfPkgX64.fdf
OvmfPkg/VirtioBlkDxe/VirtioBlk.c
OvmfPkg/VirtioBlkDxe/VirtioBlk.h
OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
OvmfPkg/VirtioNetDxe/ComponentName.c
OvmfPkg/VirtioNetDxe/DriverBinding.c
OvmfPkg/VirtioNetDxe/Events.c
OvmfPkg/VirtioNetDxe/SnpGetStatus.c
OvmfPkg/VirtioNetDxe/SnpInitialize.c
OvmfPkg/VirtioNetDxe/SnpReceive.c
OvmfPkg/VirtioNetDxe/SnpShutdown.c
OvmfPkg/VirtioNetDxe/SnpTransmit.c
OvmfPkg/VirtioNetDxe/VirtioNet.h
OvmfPkg/VirtioNetDxe/VirtioNet.inf
OvmfPkg/VirtioScsiDxe/VirtioScsi.c
OvmfPkg/VirtioScsiDxe/VirtioScsi.h
OvmfPkg/VirtioScsiDxe/VirtioScsi.inf

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