OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress()
[mirror_edk2.git] / OvmfPkg / Virtio10Dxe / Virtio10.c
index d7ea4432bcb696e1ffc3383ce2cc5a20f007427b..ef9a00710668daf041b011224a1a9cbc1ba69e7c 100644 (file)
@@ -2,6 +2,7 @@
   A non-transitional driver for VirtIo 1.0 PCI devices.\r
 \r
   Copyright (C) 2016, Red Hat, Inc.\r
+  Copyright (C) 2017, AMD Inc, All rights reserved.<BR>\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
@@ -15,6 +16,7 @@
 #include <IndustryStandard/Pci.h>\r
 #include <IndustryStandard/Virtio.h>\r
 #include <Protocol/PciIo.h>\r
+#include <Protocol/PciRootBridgeIo.h>\r
 #include <Protocol/VirtioDevice.h>\r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/DebugLib.h>\r
@@ -487,7 +489,8 @@ EFI_STATUS
 EFIAPI\r
 Virtio10SetQueueAddress (\r
   IN VIRTIO_DEVICE_PROTOCOL  *This,\r
-  IN VRING                   *Ring\r
+  IN VRING                   *Ring,\r
+  IN UINT64                  RingBaseShift\r
   )\r
 {\r
   VIRTIO_1_0_DEV *Dev;\r
@@ -495,6 +498,8 @@ Virtio10SetQueueAddress (
   UINT64         Address;\r
   UINT16         Enable;\r
 \r
+  ASSERT (RingBaseShift == 0);\r
+\r
   Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);\r
 \r
   Address = (UINTN)Ring->Desc;\r
@@ -772,6 +777,117 @@ Virtio10ReadDevice (
   return Status;\r
 }\r
 \r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+Virtio10AllocateSharedPages (\r
+  IN     VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN     UINTN                   Pages,\r
+  IN OUT VOID                    **HostAddress\r
+  )\r
+{\r
+  VIRTIO_1_0_DEV *Dev;\r
+  EFI_STATUS     Status;\r
+\r
+  Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);\r
+\r
+  Status = Dev->PciIo->AllocateBuffer (\r
+                         Dev->PciIo,\r
+                         AllocateAnyPages,\r
+                         EfiBootServicesData,\r
+                         Pages,\r
+                         HostAddress,\r
+                         EFI_PCI_ATTRIBUTE_MEMORY_CACHED\r
+                         );\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+Virtio10FreeSharedPages (\r
+  IN  VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN  UINTN                   Pages,\r
+  IN  VOID                    *HostAddress\r
+  )\r
+{\r
+  VIRTIO_1_0_DEV *Dev;\r
+\r
+  Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);\r
+\r
+  Dev->PciIo->FreeBuffer (\r
+                Dev->PciIo,\r
+                Pages,\r
+                HostAddress\r
+                );\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+Virtio10MapSharedBuffer (\r
+  IN     VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN     VIRTIO_MAP_OPERATION    Operation,\r
+  IN     VOID                    *HostAddress,\r
+  IN OUT UINTN                   *NumberOfBytes,\r
+  OUT    EFI_PHYSICAL_ADDRESS    *DeviceAddress,\r
+  OUT    VOID                    **Mapping\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  VIRTIO_1_0_DEV                *Dev;\r
+  EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation;\r
+\r
+  Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);\r
+\r
+  //\r
+  // Map VIRTIO_MAP_OPERATION to EFI_PCI_IO_PROTOCOL_OPERATION\r
+  //\r
+  switch (Operation) {\r
+  case VirtioOperationBusMasterRead:\r
+    PciIoOperation = EfiPciIoOperationBusMasterRead;\r
+    break;\r
+  case VirtioOperationBusMasterWrite:\r
+    PciIoOperation = EfiPciIoOperationBusMasterWrite;\r
+    break;\r
+  case VirtioOperationBusMasterCommonBuffer:\r
+    PciIoOperation = EfiPciIoOperationBusMasterCommonBuffer;\r
+    break;\r
+  default:\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = Dev->PciIo->Map (\r
+                         Dev->PciIo,\r
+                         PciIoOperation,\r
+                         HostAddress,\r
+                         NumberOfBytes,\r
+                         DeviceAddress,\r
+                         Mapping\r
+                         );\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+Virtio10UnmapSharedBuffer (\r
+  IN  VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN  VOID                    *Mapping\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  VIRTIO_1_0_DEV  *Dev;\r
+\r
+  Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);\r
+\r
+  Status = Dev->PciIo->Unmap (\r
+                         Dev->PciIo,\r
+                         Mapping\r
+                         );\r
+\r
+  return Status;\r
+}\r
 \r
 STATIC CONST VIRTIO_DEVICE_PROTOCOL mVirtIoTemplate = {\r
   VIRTIO_SPEC_REVISION (1, 0, 0),\r
@@ -788,7 +904,11 @@ STATIC CONST VIRTIO_DEVICE_PROTOCOL mVirtIoTemplate = {
   Virtio10GetDeviceStatus,\r
   Virtio10SetDeviceStatus,\r
   Virtio10WriteDevice,\r
-  Virtio10ReadDevice\r
+  Virtio10ReadDevice,\r
+  Virtio10AllocateSharedPages,\r
+  Virtio10FreeSharedPages,\r
+  Virtio10MapSharedBuffer,\r
+  Virtio10UnmapSharedBuffer\r
 };\r
 \r
 \r
@@ -906,7 +1026,8 @@ Virtio10BindingStart (
     goto ClosePciIo;\r
   }\r
 \r
-  SetAttributes = EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;\r
+  SetAttributes = (EFI_PCI_IO_ATTRIBUTE_BUS_MASTER |\r
+                   EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE);\r
   UpdateAttributes (&Device->CommonConfig, &SetAttributes);\r
   UpdateAttributes (&Device->NotifyConfig, &SetAttributes);\r
   UpdateAttributes (&Device->SpecificConfig, &SetAttributes);\r