]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: extract VirtioLib from VirtioBlkDxe
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 12 Oct 2012 18:53:58 +0000 (18:53 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 12 Oct 2012 18:53:58 +0000 (18:53 +0000)
Introduce a new library called VirtioLib, for now only collecting the
following reusable functions with as little changes as possible:

- VirtioWrite()
- VirtioRead()
- VirtioRingInit()
- VirtioRingUninit()
- AppendDesc()

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://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13842 6f19259b-4bc3-4df7-8a09-765794883524

OvmfPkg/Include/Library/VirtioLib.h [new file with mode: 0644]
OvmfPkg/Library/VirtioLib/VirtioLib.c [new file with mode: 0644]
OvmfPkg/Library/VirtioLib/VirtioLib.inf [new file with mode: 0644]
OvmfPkg/OvmfPkgIa32.dsc
OvmfPkg/OvmfPkgIa32X64.dsc
OvmfPkg/OvmfPkgX64.dsc
OvmfPkg/VirtioBlkDxe/VirtioBlk.c
OvmfPkg/VirtioBlkDxe/VirtioBlk.inf

diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h
new file mode 100644 (file)
index 0000000..95657a7
--- /dev/null
@@ -0,0 +1,187 @@
+/** @file\r
+\r
+  Declarations of utility functions used by virtio device drivers.\r
+\r
+  Copyright (C) 2012, Red Hat, Inc.\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
+  distribution. The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
+  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _VIRTIO_LIB_H_\r
+#define _VIRTIO_LIB_H_\r
+\r
+#include <Protocol/PciIo.h>\r
+#include <IndustryStandard/Virtio.h>\r
+\r
+/**\r
+\r
+  Write a word into Region 0 of the device specified by PciIo.\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
+\r
+  @param[in] FieldOffset  Destination offset.\r
+\r
+  @param[in] FieldSize    Destination field size, must be in { 1, 2, 4, 8 }.\r
+\r
+  @param[in] Value        Little endian value to write, converted to UINT64.\r
+                          The least significant FieldSize bytes will be used.\r
+\r
+\r
+  @return  Status code returned by PciIo->Io.Write().\r
+\r
+**/\r
+EFIAPI\r
+EFI_STATUS\r
+VirtioWrite (\r
+  IN EFI_PCI_IO_PROTOCOL *PciIo,\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
+\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
+\r
+  @param[in] FieldOffset  Source offset.\r
+\r
+  @param[in] FieldSize    Source field size, must be in { 1, 2, 4, 8 }.\r
+\r
+  @param[in] BufferSize   Number of bytes available in the target buffer. Must\r
+                          equal FieldSize.\r
+\r
+  @param[out] Buffer      Target buffer.\r
+\r
+\r
+  @return  Status code returned by PciIo->Io.Read().\r
+\r
+**/\r
+EFIAPI\r
+EFI_STATUS\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
+  );\r
+\r
+\r
+/**\r
+\r
+  Configure a virtio ring.\r
+\r
+  This function sets up internal storage (the guest-host communication area)\r
+  and lays out several "navigation" (ie. no-ownership) pointers to parts of\r
+  that storage.\r
+\r
+  Relevant sections from the virtio-0.9.5 spec:\r
+  - 1.1 Virtqueues,\r
+  - 2.3 Virtqueue Configuration.\r
+\r
+  @param[in]                    The number of descriptors to allocate for the\r
+                                virtio ring, as requested by the host.\r
+\r
+  @param[out] Ring              The virtio ring to set up.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  AllocatePages() failed to allocate contiguous\r
+                                pages for the requested QueueSize. Fields of\r
+                                Ring have indeterminate value.\r
+\r
+  @retval EFI_SUCCESS           Allocation and setup successful. Ring->Base\r
+                                (and nothing else) is responsible for\r
+                                deallocation.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtioRingInit (\r
+  IN  UINT16 QueueSize,\r
+  OUT VRING  *Ring\r
+  );\r
+\r
+\r
+/**\r
+\r
+  Tear down the internal resources of a configured virtio ring.\r
+\r
+  The caller is responsible to stop the host from using this ring before\r
+  invoking this function: the VSTAT_DRIVER_OK bit must be clear in\r
+  VhdrDeviceStatus.\r
+\r
+  @param[out] Ring  The virtio ring to clean up.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+VirtioRingUninit (\r
+  IN OUT VRING *Ring\r
+  );\r
+\r
+\r
+/**\r
+\r
+  Append a contiguous buffer for transmission / reception via the virtio ring.\r
+\r
+  This function implements the following sections from virtio-0.9.5:\r
+  - 2.4.1.1 Placing Buffers into the Descriptor Table\r
+  - 2.4.1.2 Updating the Available Ring\r
+\r
+  Free space is taken as granted, since the individual drivers support only\r
+  synchronous requests and host side status is processed in lock-step with\r
+  request submission. It is the calling driver's responsibility to verify the\r
+  ring size in advance.\r
+\r
+  @param[in out] Ring           The virtio ring to append the buffer to, as a\r
+                                descriptor.\r
+\r
+  @param [in] BufferPhysAddr    (Guest pseudo-physical) start address of the\r
+                                transmit / receive buffer.\r
+\r
+  @param [in] BufferSize        Number of bytes to transmit or receive.\r
+\r
+  @param [in] Flags             A bitmask of VRING_DESC_F_* flags. The caller\r
+                                computes this mask dependent on further buffers\r
+                                to append and transfer direction.\r
+                                VRING_DESC_F_INDIRECT is unsupported. The\r
+                                VRING_DESC.Next field is always set, but the\r
+                                host only interprets it dependent on\r
+                                VRING_DESC_F_NEXT.\r
+\r
+  @param [in] HeadIdx           The index identifying the head buffer (first\r
+                                buffer appended) belonging to this same\r
+                                request.\r
+\r
+  @param [in out] NextAvailIdx  On input, the index identifying the next\r
+                                descriptor available to carry the buffer. On\r
+                                output, incremented by one, modulo 2^16.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AppendDesc (\r
+  IN OUT VRING  *Ring,\r
+  IN     UINTN  BufferPhysAddr,\r
+  IN     UINT32 BufferSize,\r
+  IN     UINT16 Flags,\r
+  IN     UINT16 HeadIdx,\r
+  IN OUT UINT16 *NextAvailIdx\r
+  );\r
+\r
+#endif // _VIRTIO_LIB_H_\r
diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c
new file mode 100644 (file)
index 0000000..5808242
--- /dev/null
@@ -0,0 +1,335 @@
+/** @file\r
+\r
+  Utility functions used by virtio device drivers.\r
+\r
+  Copyright (C) 2012, Red Hat, Inc.\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
+  distribution. The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
+  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <IndustryStandard/Pci22.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+#include <Library/VirtioLib.h>\r
+\r
+\r
+/**\r
+\r
+  Write a word into Region 0 of the device specified by PciIo.\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
+\r
+  @param[in] FieldOffset  Destination offset.\r
+\r
+  @param[in] FieldSize    Destination field size, must be in { 1, 2, 4, 8 }.\r
+\r
+  @param[in] Value        Little endian value to write, converted to UINT64.\r
+                          The least significant FieldSize bytes will be used.\r
+\r
+\r
+  @return  Status code returned by PciIo->Io.Write().\r
+\r
+**/\r
+EFIAPI\r
+EFI_STATUS\r
+VirtioWrite (\r
+  IN EFI_PCI_IO_PROTOCOL *PciIo,\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
+  }\r
+\r
+  return PciIo->Io.Write (\r
+                     PciIo,\r
+                     Width,\r
+                     PCI_BAR_IDX0,\r
+                     FieldOffset,\r
+                     Count,\r
+                     &Value\r
+                     );\r
+}\r
+\r
+\r
+/**\r
+\r
+  Read a word from Region 0 of the device specified by PciIo.\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
+\r
+  @param[in] FieldOffset  Source offset.\r
+\r
+  @param[in] FieldSize    Source field size, must be in { 1, 2, 4, 8 }.\r
+\r
+  @param[in] BufferSize   Number of bytes available in the target buffer. Must\r
+                          equal FieldSize.\r
+\r
+  @param[out] Buffer      Target buffer.\r
+\r
+\r
+  @return  Status code returned by PciIo->Io.Read().\r
+\r
+**/\r
+EFIAPI\r
+EFI_STATUS\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
+  )\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
+  }\r
+\r
+  return PciIo->Io.Read (\r
+                     PciIo,\r
+                     Width,\r
+                     PCI_BAR_IDX0,\r
+                     FieldOffset,\r
+                     Count,\r
+                     Buffer\r
+                     );\r
+}\r
+\r
+\r
+/**\r
+\r
+  Configure a virtio ring.\r
+\r
+  This function sets up internal storage (the guest-host communication area)\r
+  and lays out several "navigation" (ie. no-ownership) pointers to parts of\r
+  that storage.\r
+\r
+  Relevant sections from the virtio-0.9.5 spec:\r
+  - 1.1 Virtqueues,\r
+  - 2.3 Virtqueue Configuration.\r
+\r
+  @param[in]                    The number of descriptors to allocate for the\r
+                                virtio ring, as requested by the host.\r
+\r
+  @param[out] Ring              The virtio ring to set up.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  AllocatePages() failed to allocate contiguous\r
+                                pages for the requested QueueSize. Fields of\r
+                                Ring have indeterminate value.\r
+\r
+  @retval EFI_SUCCESS           Allocation and setup successful. Ring->Base\r
+                                (and nothing else) is responsible for\r
+                                deallocation.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VirtioRingInit (\r
+  IN  UINT16 QueueSize,\r
+  OUT VRING  *Ring\r
+  )\r
+{\r
+  UINTN          RingSize;\r
+  volatile UINT8 *RingPagesPtr;\r
+\r
+  RingSize = ALIGN_VALUE (\r
+               sizeof *Ring->Desc            * QueueSize +\r
+               sizeof *Ring->Avail.Flags                 +\r
+               sizeof *Ring->Avail.Idx                   +\r
+               sizeof *Ring->Avail.Ring      * QueueSize +\r
+               sizeof *Ring->Avail.UsedEvent,\r
+               EFI_PAGE_SIZE);\r
+\r
+  RingSize += ALIGN_VALUE (\r
+                sizeof *Ring->Used.Flags                  +\r
+                sizeof *Ring->Used.Idx                    +\r
+                sizeof *Ring->Used.UsedElem   * QueueSize +\r
+                sizeof *Ring->Used.AvailEvent,\r
+                EFI_PAGE_SIZE);\r
+\r
+  Ring->NumPages = EFI_SIZE_TO_PAGES (RingSize);\r
+  Ring->Base = AllocatePages (Ring->NumPages);\r
+  if (Ring->Base == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  SetMem (Ring->Base, RingSize, 0x00);\r
+  RingPagesPtr = Ring->Base;\r
+\r
+  Ring->Desc = (volatile VOID *) RingPagesPtr;\r
+  RingPagesPtr += sizeof *Ring->Desc * QueueSize;\r
+\r
+  Ring->Avail.Flags = (volatile VOID *) RingPagesPtr;\r
+  RingPagesPtr += sizeof *Ring->Avail.Flags;\r
+\r
+  Ring->Avail.Idx = (volatile VOID *) RingPagesPtr;\r
+  RingPagesPtr += sizeof *Ring->Avail.Idx;\r
+\r
+  Ring->Avail.Ring = (volatile VOID *) RingPagesPtr;\r
+  RingPagesPtr += sizeof *Ring->Avail.Ring * QueueSize;\r
+\r
+  Ring->Avail.UsedEvent = (volatile VOID *) RingPagesPtr;\r
+  RingPagesPtr += sizeof *Ring->Avail.UsedEvent;\r
+\r
+  RingPagesPtr = (volatile UINT8 *) Ring->Base +\r
+                 ALIGN_VALUE (RingPagesPtr - (volatile UINT8 *) Ring->Base,\r
+                   EFI_PAGE_SIZE);\r
+\r
+  Ring->Used.Flags = (volatile VOID *) RingPagesPtr;\r
+  RingPagesPtr += sizeof *Ring->Used.Flags;\r
+\r
+  Ring->Used.Idx = (volatile VOID *) RingPagesPtr;\r
+  RingPagesPtr += sizeof *Ring->Used.Idx;\r
+\r
+  Ring->Used.UsedElem = (volatile VOID *) RingPagesPtr;\r
+  RingPagesPtr += sizeof *Ring->Used.UsedElem * QueueSize;\r
+\r
+  Ring->Used.AvailEvent = (volatile VOID *) RingPagesPtr;\r
+  RingPagesPtr += sizeof *Ring->Used.AvailEvent;\r
+\r
+  Ring->QueueSize = QueueSize;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+\r
+  Tear down the internal resources of a configured virtio ring.\r
+\r
+  The caller is responsible to stop the host from using this ring before\r
+  invoking this function: the VSTAT_DRIVER_OK bit must be clear in\r
+  VhdrDeviceStatus.\r
+\r
+  @param[out] Ring  The virtio ring to clean up.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+VirtioRingUninit (\r
+  IN OUT VRING *Ring\r
+  )\r
+{\r
+  FreePages (Ring->Base, Ring->NumPages);\r
+  SetMem (Ring, sizeof *Ring, 0x00);\r
+}\r
+\r
+\r
+/**\r
+\r
+  Append a contiguous buffer for transmission / reception via the virtio ring.\r
+\r
+  This function implements the following sections from virtio-0.9.5:\r
+  - 2.4.1.1 Placing Buffers into the Descriptor Table\r
+  - 2.4.1.2 Updating the Available Ring\r
+\r
+  Free space is taken as granted, since the individual drivers support only\r
+  synchronous requests and host side status is processed in lock-step with\r
+  request submission. It is the calling driver's responsibility to verify the\r
+  ring size in advance.\r
+\r
+  @param[in out] Ring           The virtio ring to append the buffer to, as a\r
+                                descriptor.\r
+\r
+  @param [in] BufferPhysAddr    (Guest pseudo-physical) start address of the\r
+                                transmit / receive buffer.\r
+\r
+  @param [in] BufferSize        Number of bytes to transmit or receive.\r
+\r
+  @param [in] Flags             A bitmask of VRING_DESC_F_* flags. The caller\r
+                                computes this mask dependent on further buffers\r
+                                to append and transfer direction.\r
+                                VRING_DESC_F_INDIRECT is unsupported. The\r
+                                VRING_DESC.Next field is always set, but the\r
+                                host only interprets it dependent on\r
+                                VRING_DESC_F_NEXT.\r
+\r
+  @param [in] HeadIdx           The index identifying the head buffer (first\r
+                                buffer appended) belonging to this same\r
+                                request.\r
+\r
+  @param [in out] NextAvailIdx  On input, the index identifying the next\r
+                                descriptor available to carry the buffer. On\r
+                                output, incremented by one, modulo 2^16.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AppendDesc (\r
+  IN OUT VRING  *Ring,\r
+  IN     UINTN  BufferPhysAddr,\r
+  IN     UINT32 BufferSize,\r
+  IN     UINT16 Flags,\r
+  IN     UINT16 HeadIdx,\r
+  IN OUT UINT16 *NextAvailIdx\r
+  )\r
+{\r
+  volatile VRING_DESC *Desc;\r
+\r
+  Desc        = &Ring->Desc[*NextAvailIdx % Ring->QueueSize];\r
+  Desc->Addr  = BufferPhysAddr;\r
+  Desc->Len   = BufferSize;\r
+  Desc->Flags = Flags;\r
+  Ring->Avail.Ring[(*NextAvailIdx)++ % Ring->QueueSize] =\r
+    HeadIdx % Ring->QueueSize;\r
+  Desc->Next  = *NextAvailIdx % Ring->QueueSize;\r
+}\r
diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.inf b/OvmfPkg/Library/VirtioLib/VirtioLib.inf
new file mode 100644 (file)
index 0000000..cfd93a2
--- /dev/null
@@ -0,0 +1,34 @@
+## @file\r
+# Library of virtio utility functions.\r
+#\r
+# Copyright (C) 2012, Red Hat, Inc.\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
+# distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
+# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = VirtioLib\r
+  FILE_GUID                      = 90CED1D9-18F2-47CC-BF24-41EC29406637\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = VirtioLib\r
+\r
+[Sources]\r
+  VirtioLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  OvmfPkg/OvmfPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  DebugLib\r
+  MemoryAllocationLib\r
index 16037b37721d24647f98e691cf65d0cf6bd11338..d0c632979dbd1fd34361c29621e83b8dc7c340f5 100644 (file)
@@ -97,6 +97,7 @@
   UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf\r
   SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf\r
   QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf\r
+  VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf\r
   LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf\r
 \r
 !ifdef $(SOURCE_DEBUG_ENABLE)\r
index f73f079d07fcbc029e64983a87196f944da0d367..b442314680bda50585bee41140ca2c4aae2325c7 100644 (file)
   UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf\r
   SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf\r
   QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf\r
+  VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf\r
   LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf\r
 \r
 !ifdef $(SOURCE_DEBUG_ENABLE)\r
index 97d4ec8a9368176e832ef86a2c4598955f3c87ba..11f90a481866cfedee853a9bf704e742b44303cc 100644 (file)
   UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf\r
   SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf\r
   QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf\r
+  VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf\r
   LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf\r
 \r
 !ifdef $(SOURCE_DEBUG_ENABLE)\r
index ead98272a52800654460ff8ebeaae12e1aeaf7b2..eeeb4bef6e21ec7ef6434b066552030ae5f1a411 100644 (file)
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/UefiLib.h>\r
+#include <Library/VirtioLib.h>\r
 \r
 #include "VirtioBlk.h"\r
 \r
-/**\r
-\r
-  Write a word into Region 0 of the device specified by PciIo.\r
-\r
-  Region 0 must be an iomem region. This is an internal function for the\r
-  VIRTIO_CFG_WRITE() macro below.\r
-\r
-  @param[in] PciIo        Target PCI device.\r
-\r
-  @param[in] FieldOffset  Destination offset.\r
-\r
-  @param[in] FieldSize    Destination field size, must be in { 1, 2, 4, 8 }.\r
-\r
-  @param[in] Value        Little endian value to write, converted to UINT64.\r
-                          The least significant FieldSize bytes will be used.\r
-\r
-\r
-  @return  Status code returned by PciIo->Io.Write().\r
-\r
-**/\r
-STATIC\r
-EFIAPI\r
-EFI_STATUS\r
-VirtioWrite (\r
-  IN EFI_PCI_IO_PROTOCOL *PciIo,\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
-  }\r
-\r
-  return PciIo->Io.Write (\r
-                     PciIo,\r
-                     Width,\r
-                     PCI_BAR_IDX0,\r
-                     FieldOffset,\r
-                     Count,\r
-                     &Value\r
-                     );\r
-}\r
-\r
-\r
-/**\r
-\r
-  Read a word from Region 0 of the device specified by PciIo.\r
-\r
-  Region 0 must be an iomem region. This is an internal function for the\r
-  VIRTIO_CFG_READ() macro below.\r
-\r
-  @param[in] PciIo        Source PCI device.\r
-\r
-  @param[in] FieldOffset  Source offset.\r
-\r
-  @param[in] FieldSize    Source field size, must be in { 1, 2, 4, 8 }.\r
-\r
-  @param[in] BufferSize   Number of bytes available in the target buffer. Must\r
-                          equal FieldSize.\r
-\r
-  @param[out] Buffer      Target buffer.\r
-\r
-\r
-  @return  Status code returned by PciIo->Io.Read().\r
-\r
-**/\r
-STATIC\r
-EFIAPI\r
-EFI_STATUS\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
-  )\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
-  }\r
-\r
-  return PciIo->Io.Read (\r
-                     PciIo,\r
-                     Width,\r
-                     PCI_BAR_IDX0,\r
-                     FieldOffset,\r
-                     Count,\r
-                     Buffer\r
-                     );\r
-}\r
-\r
-\r
 /**\r
 \r
   Convenience macros to read and write region 0 IO space elements of the\r
@@ -314,66 +178,6 @@ VerifyReadWriteRequest (
 }\r
 \r
 \r
-/**\r
-\r
-  Append a contiguous buffer for transmission / reception via the virtio ring.\r
-\r
-  This function implements the following sections from virtio-0.9.5:\r
-  - 2.4.1.1 Placing Buffers into the Descriptor Table\r
-  - 2.4.1.2 Updating the Available Ring\r
-\r
-  Free space is taken as granted, since this driver supports only synchronous\r
-  requests and host side status is processed in lock-step with request\r
-  submission. VirtioBlkInit() verifies the ring size in advance.\r
-\r
-  @param[in out] Ring           The virtio ring to append the buffer to, as a\r
-                                descriptor.\r
-\r
-  @param [in] BufferPhysAddr    (Guest pseudo-physical) start address of the\r
-                                transmit / receive buffer\r
-\r
-  @param [in] BufferSize        Number of bytes to transmit or receive.\r
-\r
-  @param [in] Flags             A bitmask of VRING_DESC_F_* flags. The caller\r
-                                computes this mask dependent on further buffers\r
-                                to append and transfer direction.\r
-                                VRING_DESC_F_INDIRECT is unsupported. The\r
-                                VRING_DESC.Next field is always set, but the\r
-                                host only interprets it dependent on\r
-                                VRING_DESC_F_NEXT.\r
-\r
-  @param [in] HeadIdx           The index identifying the head buffer (first\r
-                                buffer appended) belonging to this same\r
-                                request.\r
-\r
-  @param [in out] NextAvailIdx  On input, the index identifying the next\r
-                                descriptor available to carry the buffer. On\r
-                                output, incremented by one, modulo 2^16.\r
-\r
-**/\r
-\r
-STATIC\r
-VOID\r
-EFIAPI\r
-AppendDesc (\r
-  IN OUT          VRING  *Ring,\r
-  IN              UINTN  BufferPhysAddr,\r
-  IN              UINT32 BufferSize,\r
-  IN              UINT16 Flags,\r
-  IN              UINT16 HeadIdx,\r
-  IN OUT          UINT16 *NextAvailIdx\r
-  )\r
-{\r
-  volatile VRING_DESC *Desc;\r
-\r
-  Desc        = &Ring->Desc[*NextAvailIdx % Ring->QueueSize];\r
-  Desc->Addr  = BufferPhysAddr;\r
-  Desc->Len   = BufferSize;\r
-  Desc->Flags = Flags;\r
-  Ring->Avail.Ring[(*NextAvailIdx)++ % Ring->QueueSize] =\r
-    HeadIdx % Ring->QueueSize;\r
-  Desc->Next  = *NextAvailIdx % Ring->QueueSize;\r
-}\r
 \r
 \r
 /**\r
@@ -825,128 +629,6 @@ VirtioBlkDriverBindingSupported (
 }\r
 \r
 \r
-/**\r
-\r
-  Configure a virtio ring.\r
-\r
-  This function sets up internal storage (the guest-host communication area)\r
-  and lays out several "navigation" (ie. no-ownership) pointers to parts of\r
-  that storage.\r
-\r
-  Relevant sections from the virtio-0.9.5 spec:\r
-  - 1.1 Virtqueues,\r
-  - 2.3 Virtqueue Configuration.\r
-\r
-  @param[in]                    The number of descriptors to allocate for the\r
-                                virtio ring, as requested by the host.\r
-\r
-  @param[out] Ring              The virtio ring to set up.\r
-\r
-  @retval EFI_OUT_OF_RESOURCES  AllocatePages() failed to allocate contiguous\r
-                                pages for the requested QueueSize. Fields of\r
-                                Ring have indeterminate value.\r
-\r
-  @retval EFI_SUCCESS           Allocation and setup successful. Ring->Base\r
-                                (and nothing else) is responsible for\r
-                                deallocation.\r
-\r
-**/\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-VirtioRingInit (\r
-  IN  UINT16 QueueSize,\r
-  OUT VRING  *Ring\r
-  )\r
-{\r
-  UINTN          RingSize;\r
-  volatile UINT8 *RingPagesPtr;\r
-\r
-  RingSize = ALIGN_VALUE (\r
-               sizeof *Ring->Desc            * QueueSize +\r
-               sizeof *Ring->Avail.Flags                 +\r
-               sizeof *Ring->Avail.Idx                   +\r
-               sizeof *Ring->Avail.Ring      * QueueSize +\r
-               sizeof *Ring->Avail.UsedEvent,\r
-               EFI_PAGE_SIZE);\r
-\r
-  RingSize += ALIGN_VALUE (\r
-                sizeof *Ring->Used.Flags                  +\r
-                sizeof *Ring->Used.Idx                    +\r
-                sizeof *Ring->Used.UsedElem   * QueueSize +\r
-                sizeof *Ring->Used.AvailEvent,\r
-                EFI_PAGE_SIZE);\r
-\r
-  Ring->NumPages = EFI_SIZE_TO_PAGES (RingSize);\r
-  Ring->Base = AllocatePages (Ring->NumPages);\r
-  if (Ring->Base == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  SetMem (Ring->Base, RingSize, 0x00);\r
-  RingPagesPtr = Ring->Base;\r
-\r
-  Ring->Desc = (volatile VOID *) RingPagesPtr;\r
-  RingPagesPtr += sizeof *Ring->Desc * QueueSize;\r
-\r
-  Ring->Avail.Flags = (volatile VOID *) RingPagesPtr;\r
-  RingPagesPtr += sizeof *Ring->Avail.Flags;\r
-\r
-  Ring->Avail.Idx = (volatile VOID *) RingPagesPtr;\r
-  RingPagesPtr += sizeof *Ring->Avail.Idx;\r
-\r
-  Ring->Avail.Ring = (volatile VOID *) RingPagesPtr;\r
-  RingPagesPtr += sizeof *Ring->Avail.Ring * QueueSize;\r
-\r
-  Ring->Avail.UsedEvent = (volatile VOID *) RingPagesPtr;\r
-  RingPagesPtr += sizeof *Ring->Avail.UsedEvent;\r
-\r
-  RingPagesPtr = (volatile UINT8 *) Ring->Base +\r
-                 ALIGN_VALUE (RingPagesPtr - (volatile UINT8 *) Ring->Base,\r
-                   EFI_PAGE_SIZE);\r
-\r
-  Ring->Used.Flags = (volatile VOID *) RingPagesPtr;\r
-  RingPagesPtr += sizeof *Ring->Used.Flags;\r
-\r
-  Ring->Used.Idx = (volatile VOID *) RingPagesPtr;\r
-  RingPagesPtr += sizeof *Ring->Used.Idx;\r
-\r
-  Ring->Used.UsedElem = (volatile VOID *) RingPagesPtr;\r
-  RingPagesPtr += sizeof *Ring->Used.UsedElem * QueueSize;\r
-\r
-  Ring->Used.AvailEvent = (volatile VOID *) RingPagesPtr;\r
-  RingPagesPtr += sizeof *Ring->Used.AvailEvent;\r
-\r
-  Ring->QueueSize = QueueSize;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-\r
-  Tear down the internal resources of a configured virtio ring.\r
-\r
-  The caller is responsible to stop the host from using this ring before\r
-  invoking this function: the VSTAT_DRIVER_OK bit must be clear in\r
-  VhdrDeviceStatus.\r
-\r
-  @param[out] Ring  The virtio ring to clean up.\r
-\r
-**/\r
-\r
-\r
-STATIC\r
-VOID\r
-EFIAPI\r
-VirtioRingUninit (\r
-  IN OUT VRING *Ring\r
-  )\r
-{\r
-  FreePages (Ring->Base, Ring->NumPages);\r
-  SetMem (Ring, sizeof *Ring, 0x00);\r
-}\r
-\r
-\r
 /**\r
 \r
   Set up all BlockIo and virtio-blk aspects of this driver for the specified\r
index 730903d55e7c1086cef648d5c097ad32f2c29c93..6dffc3a22a6dd0953972e7162af6604be4b68d6c 100644 (file)
@@ -35,6 +35,7 @@
   UefiBootServicesTableLib\r
   UefiDriverEntryPoint\r
   UefiLib\r
+  VirtioLib\r
 \r
 [Protocols]\r
   gEfiBlockIoProtocolGuid  ## BY_START\r