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 UINT64 *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
\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
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
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
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
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
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
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
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
\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
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
EFI_STATUS\r
EFIAPI\r
VirtioMmioSetGuestFeatures (\r
- VIRTIO_DEVICE_PROTOCOL *This,\r
- UINT64 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
- if (Features > MAX_UINT32) {\r
- return EFI_UNSUPPORTED;\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
- VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_FEATURES,\r
- (UINT32)Features);\r
\r
return EFI_SUCCESS;\r
}\r
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
// 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
// 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
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
// 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
// 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
\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