]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / OvmfPkg / Library / VirtioMmioDeviceLib / VirtioMmioDeviceFunctions.c
index 3950c07f7f5d9a0ef1ab54b461b740e1eec82010..8bdf1e1fc3a64b928ec03caf94e59e254cda7e4a 100644 (file)
@@ -6,13 +6,7 @@
   Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
   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
-  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
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 EFI_STATUS\r
 EFIAPI\r
 VirtioMmioGetDeviceFeatures (\r
-  IN VIRTIO_DEVICE_PROTOCOL *This,\r
-  OUT UINT32                *DeviceFeatures\r
+  IN VIRTIO_DEVICE_PROTOCOL  *This,\r
+  OUT UINT64                 *DeviceFeatures\r
   )\r
 {\r
-  VIRTIO_MMIO_DEVICE *Device;\r
+  VIRTIO_MMIO_DEVICE  *Device;\r
+  UINT32              LowBits, HighBits;\r
 \r
   if (DeviceFeatures == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -33,28 +28,16 @@ VirtioMmioGetDeviceFeatures (
 \r
   Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
 \r
-  *DeviceFeatures = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_HOST_FEATURES);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-VirtioMmioGetQueueAddress (\r
-  IN  VIRTIO_DEVICE_PROTOCOL *This,\r
-  OUT UINT32                 *QueueAddress\r
-  )\r
-{\r
-  VIRTIO_MMIO_DEVICE *Device;\r
-\r
-  if (QueueAddress == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
+  if (Device->Version == VIRTIO_MMIO_DEVICE_VERSION_0_95) {\r
+    *DeviceFeatures = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_HOST_FEATURES);\r
+  } else {\r
+    VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_HOST_FEATURES_SEL, 0);\r
+    LowBits = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_HOST_FEATURES);\r
+    VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_HOST_FEATURES_SEL, 1);\r
+    HighBits        = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_HOST_FEATURES);\r
+    *DeviceFeatures = LShiftU64 (HighBits, 32) | LowBits;\r
   }\r
 \r
-  Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
-\r
-  *QueueAddress = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN);\r
-\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -65,7 +48,7 @@ VirtioMmioGetQueueSize (
   OUT UINT16                  *QueueNumMax\r
   )\r
 {\r
-  VIRTIO_MMIO_DEVICE *Device;\r
+  VIRTIO_MMIO_DEVICE  *Device;\r
 \r
   if (QueueNumMax == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -85,7 +68,7 @@ VirtioMmioGetDeviceStatus (
   OUT UINT8                   *DeviceStatus\r
   )\r
 {\r
-  VIRTIO_MMIO_DEVICE *Device;\r
+  VIRTIO_MMIO_DEVICE  *Device;\r
 \r
   if (DeviceStatus == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -101,15 +84,19 @@ VirtioMmioGetDeviceStatus (
 EFI_STATUS\r
 EFIAPI\r
 VirtioMmioSetQueueSize (\r
-  VIRTIO_DEVICE_PROTOCOL *This,\r
-  UINT16                  QueueSize\r
+  IN VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN UINT16                  QueueSize\r
   )\r
 {\r
-  VIRTIO_MMIO_DEVICE *Device;\r
+  VIRTIO_MMIO_DEVICE  *Device;\r
 \r
   Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
 \r
-  VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM, QueueSize);\r
+  if (Device->Version == VIRTIO_MMIO_DEVICE_VERSION_0_95) {\r
+    VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM, QueueSize);\r
+  } else {\r
+    Device->QueueNum = QueueSize;\r
+  }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -117,11 +104,11 @@ VirtioMmioSetQueueSize (
 EFI_STATUS\r
 EFIAPI\r
 VirtioMmioSetDeviceStatus (\r
-  VIRTIO_DEVICE_PROTOCOL *This,\r
-  UINT8                   DeviceStatus\r
+  IN VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN UINT8                   DeviceStatus\r
   )\r
 {\r
-  VIRTIO_MMIO_DEVICE *Device;\r
+  VIRTIO_MMIO_DEVICE  *Device;\r
 \r
   Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
 \r
@@ -133,11 +120,11 @@ VirtioMmioSetDeviceStatus (
 EFI_STATUS\r
 EFIAPI\r
 VirtioMmioSetQueueNotify (\r
-  VIRTIO_DEVICE_PROTOCOL *This,\r
-  UINT16                  QueueNotify\r
+  IN VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN UINT16                  QueueNotify\r
   )\r
 {\r
-  VIRTIO_MMIO_DEVICE *Device;\r
+  VIRTIO_MMIO_DEVICE  *Device;\r
 \r
   Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
 \r
@@ -149,11 +136,11 @@ VirtioMmioSetQueueNotify (
 EFI_STATUS\r
 EFIAPI\r
 VirtioMmioSetQueueAlignment (\r
-  VIRTIO_DEVICE_PROTOCOL *This,\r
-  UINT32                  Alignment\r
+  IN VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN UINT32                  Alignment\r
   )\r
 {\r
-  VIRTIO_MMIO_DEVICE *Device;\r
+  VIRTIO_MMIO_DEVICE  *Device;\r
 \r
   Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
 \r
@@ -165,11 +152,11 @@ VirtioMmioSetQueueAlignment (
 EFI_STATUS\r
 EFIAPI\r
 VirtioMmioSetPageSize (\r
-  VIRTIO_DEVICE_PROTOCOL *This,\r
-  UINT32                  PageSize\r
+  IN VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN UINT32                  PageSize\r
   )\r
 {\r
-  VIRTIO_MMIO_DEVICE *Device;\r
+  VIRTIO_MMIO_DEVICE  *Device;\r
 \r
   if (PageSize != EFI_PAGE_SIZE) {\r
     return EFI_UNSUPPORTED;\r
@@ -177,7 +164,9 @@ VirtioMmioSetPageSize (
 \r
   Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
 \r
-  VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_PAGE_SIZE, PageSize);\r
+  if (Device->Version == VIRTIO_MMIO_DEVICE_VERSION_0_95) {\r
+    VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_PAGE_SIZE, PageSize);\r
+  }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -185,30 +174,85 @@ VirtioMmioSetPageSize (
 EFI_STATUS\r
 EFIAPI\r
 VirtioMmioSetQueueSel (\r
-  VIRTIO_DEVICE_PROTOCOL *This,\r
-  UINT16                  Sel\r
+  IN VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN UINT16                  Sel\r
   )\r
 {\r
-  VIRTIO_MMIO_DEVICE *Device;\r
+  VIRTIO_MMIO_DEVICE  *Device;\r
 \r
   Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
 \r
   VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_SEL, Sel);\r
 \r
+  if (Device->Version == VIRTIO_MMIO_DEVICE_VERSION_0_95) {\r
+    Device->QueueNum = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM_MAX) & 0xFFFF;\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 EFI_STATUS\r
+EFIAPI\r
 VirtioMmioSetQueueAddress (\r
-  VIRTIO_DEVICE_PROTOCOL *This,\r
-  UINT32                  Address\r
+  IN VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN VRING                   *Ring,\r
+  IN UINT64                  RingBaseShift\r
   )\r
 {\r
-  VIRTIO_MMIO_DEVICE *Device;\r
+  VIRTIO_MMIO_DEVICE  *Device;\r
+  UINT64              Address;\r
+\r
+  ASSERT (RingBaseShift == 0);\r
 \r
   Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
 \r
-  VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN, Address);\r
+  if (Device->Version == VIRTIO_MMIO_DEVICE_VERSION_0_95) {\r
+    VIRTIO_CFG_WRITE (\r
+      Device,\r
+      VIRTIO_MMIO_OFFSET_QUEUE_PFN,\r
+      (UINT32)((UINTN)Ring->Base >> EFI_PAGE_SHIFT)\r
+      );\r
+  } else {\r
+    VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM, Device->QueueNum);\r
+\r
+    Address = (UINTN)Ring->Base;\r
+    VIRTIO_CFG_WRITE (\r
+      Device,\r
+      VIRTIO_MMIO_OFFSET_QUEUE_DESC_LO,\r
+      (UINT32)Address\r
+      );\r
+    VIRTIO_CFG_WRITE (\r
+      Device,\r
+      VIRTIO_MMIO_OFFSET_QUEUE_DESC_HI,\r
+      (UINT32)RShiftU64 (Address, 32)\r
+      );\r
+\r
+    Address = (UINTN)Ring->Avail.Flags;\r
+    VIRTIO_CFG_WRITE (\r
+      Device,\r
+      VIRTIO_MMIO_OFFSET_QUEUE_AVAIL_LO,\r
+      (UINT32)Address\r
+      );\r
+    VIRTIO_CFG_WRITE (\r
+      Device,\r
+      VIRTIO_MMIO_OFFSET_QUEUE_AVAIL_HI,\r
+      (UINT32)RShiftU64 (Address, 32)\r
+      );\r
+\r
+    Address = (UINTN)Ring->Used.Flags;\r
+    VIRTIO_CFG_WRITE (\r
+      Device,\r
+      VIRTIO_MMIO_OFFSET_QUEUE_USED_LO,\r
+      (UINT32)Address\r
+      );\r
+    VIRTIO_CFG_WRITE (\r
+      Device,\r
+      VIRTIO_MMIO_OFFSET_QUEUE_USED_HI,\r
+      (UINT32)RShiftU64 (Address, 32)\r
+      );\r
+\r
+    VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_READY, 1);\r
+  }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -216,15 +260,38 @@ VirtioMmioSetQueueAddress (
 EFI_STATUS\r
 EFIAPI\r
 VirtioMmioSetGuestFeatures (\r
-  VIRTIO_DEVICE_PROTOCOL *This,\r
-  UINT32                  Features\r
+  IN VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN UINT64                  Features\r
   )\r
 {\r
-  VIRTIO_MMIO_DEVICE *Device;\r
+  VIRTIO_MMIO_DEVICE  *Device;\r
 \r
   Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
 \r
-  VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_FEATURES, Features);\r
+  if (Device->Version == VIRTIO_MMIO_DEVICE_VERSION_0_95) {\r
+    if (Features > MAX_UINT32) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+\r
+    VIRTIO_CFG_WRITE (\r
+      Device,\r
+      VIRTIO_MMIO_OFFSET_GUEST_FEATURES,\r
+      (UINT32)Features\r
+      );\r
+  } else {\r
+    VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_FEATURES_SEL, 0);\r
+    VIRTIO_CFG_WRITE (\r
+      Device,\r
+      VIRTIO_MMIO_OFFSET_GUEST_FEATURES,\r
+      (UINT32)Features\r
+      );\r
+    VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_FEATURES_SEL, 1);\r
+    VIRTIO_CFG_WRITE (\r
+      Device,\r
+      VIRTIO_MMIO_OFFSET_GUEST_FEATURES,\r
+      (UINT32)RShiftU64 (Features, 32)\r
+      );\r
+  }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -232,14 +299,14 @@ VirtioMmioSetGuestFeatures (
 EFI_STATUS\r
 EFIAPI\r
 VirtioMmioDeviceWrite (\r
-  IN VIRTIO_DEVICE_PROTOCOL *This,\r
-  IN UINTN                  FieldOffset,\r
-  IN UINTN                  FieldSize,\r
-  IN UINT64                 Value\r
+  IN VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN UINTN                   FieldOffset,\r
+  IN UINTN                   FieldSize,\r
+  IN UINT64                  Value\r
   )\r
 {\r
-  UINTN                     DstBaseAddress;\r
-  VIRTIO_MMIO_DEVICE       *Device;\r
+  UINTN               DstBaseAddress;\r
+  VIRTIO_MMIO_DEVICE  *Device;\r
 \r
   Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
 \r
@@ -247,7 +314,8 @@ VirtioMmioDeviceWrite (
   // Double-check fieldsize\r
   //\r
   if ((FieldSize != 1) && (FieldSize != 2) &&\r
-      (FieldSize != 4) && (FieldSize != 8)) {\r
+      (FieldSize != 4) && (FieldSize != 8))\r
+  {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -255,13 +323,13 @@ VirtioMmioDeviceWrite (
   // Compute base address\r
   //\r
   DstBaseAddress = Device->BaseAddress +\r
-      VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset;\r
+                   VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset;\r
 \r
   //\r
   // The device-specific memory area of Virtio-MMIO can only be written in\r
   // byte accesses. This is not currently in the Virtio spec.\r
   //\r
-  MmioWriteBuffer8 (DstBaseAddress, FieldSize, (UINT8*)&Value);\r
+  MmioWriteBuffer8 (DstBaseAddress, FieldSize, (UINT8 *)&Value);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -269,15 +337,15 @@ VirtioMmioDeviceWrite (
 EFI_STATUS\r
 EFIAPI\r
 VirtioMmioDeviceRead (\r
-  IN  VIRTIO_DEVICE_PROTOCOL    *This,\r
-  IN  UINTN                     FieldOffset,\r
-  IN  UINTN                     FieldSize,\r
-  IN  UINTN                     BufferSize,\r
-  OUT VOID                      *Buffer\r
+  IN  VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN  UINTN                   FieldOffset,\r
+  IN  UINTN                   FieldSize,\r
+  IN  UINTN                   BufferSize,\r
+  OUT VOID                    *Buffer\r
   )\r
 {\r
-  UINTN                     SrcBaseAddress;\r
-  VIRTIO_MMIO_DEVICE       *Device;\r
+  UINTN               SrcBaseAddress;\r
+  VIRTIO_MMIO_DEVICE  *Device;\r
 \r
   Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
 \r
@@ -290,7 +358,8 @@ VirtioMmioDeviceRead (
   // Double-check fieldsize\r
   //\r
   if ((FieldSize != 1) && (FieldSize != 2) &&\r
-      (FieldSize != 4) && (FieldSize != 8)) {\r
+      (FieldSize != 4) && (FieldSize != 8))\r
+  {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -298,7 +367,7 @@ VirtioMmioDeviceRead (
   // Compute base address\r
   //\r
   SrcBaseAddress = Device->BaseAddress +\r
-      VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset;\r
+                   VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset;\r
 \r
   //\r
   // The device-specific memory area of Virtio-MMIO can only be read in\r
@@ -308,3 +377,60 @@ VirtioMmioDeviceRead (
 \r
   return EFI_SUCCESS;\r
 }\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+VirtioMmioAllocateSharedPages (\r
+  IN  VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN  UINTN                   NumPages,\r
+  OUT VOID                    **HostAddress\r
+  )\r
+{\r
+  VOID  *Buffer;\r
+\r
+  Buffer = AllocatePages (NumPages);\r
+  if (Buffer == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  *HostAddress = Buffer;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+VirtioMmioFreeSharedPages (\r
+  IN  VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN  UINTN                   NumPages,\r
+  IN  VOID                    *HostAddress\r
+  )\r
+{\r
+  FreePages (HostAddress, NumPages);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+VirtioMmioMapSharedBuffer (\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
+  *DeviceAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress;\r
+  *Mapping       = NULL;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+VirtioMmioUnmapSharedBuffer (\r
+  IN VIRTIO_DEVICE_PROTOCOL  *This,\r
+  IN VOID                    *Mapping\r
+  )\r
+{\r
+  return EFI_SUCCESS;\r
+}\r