3 This driver produces Virtio Device Protocol instances for Virtio MMIO devices.
5 Copyright (C) 2012, Red Hat, Inc.
6 Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
7 Copyright (C) 2013, ARM Ltd.
9 This program and the accompanying materials are licensed and made available
10 under the terms and conditions of the BSD License which accompanies this
11 distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
15 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include "VirtioMmioDevice.h"
23 VirtioMmioGetDeviceFeatures (
24 IN VIRTIO_DEVICE_PROTOCOL
*This
,
25 OUT UINT64
*DeviceFeatures
28 VIRTIO_MMIO_DEVICE
*Device
;
30 if (DeviceFeatures
== NULL
) {
31 return EFI_INVALID_PARAMETER
;
34 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
36 *DeviceFeatures
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_HOST_FEATURES
);
43 VirtioMmioGetQueueSize (
44 IN VIRTIO_DEVICE_PROTOCOL
*This
,
45 OUT UINT16
*QueueNumMax
48 VIRTIO_MMIO_DEVICE
*Device
;
50 if (QueueNumMax
== NULL
) {
51 return EFI_INVALID_PARAMETER
;
54 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
56 *QueueNumMax
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_QUEUE_NUM_MAX
) & 0xFFFF;
63 VirtioMmioGetDeviceStatus (
64 IN VIRTIO_DEVICE_PROTOCOL
*This
,
65 OUT UINT8
*DeviceStatus
68 VIRTIO_MMIO_DEVICE
*Device
;
70 if (DeviceStatus
== NULL
) {
71 return EFI_INVALID_PARAMETER
;
74 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
76 *DeviceStatus
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_STATUS
) & 0xFF;
83 VirtioMmioSetQueueSize (
84 VIRTIO_DEVICE_PROTOCOL
*This
,
88 VIRTIO_MMIO_DEVICE
*Device
;
90 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
92 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_QUEUE_NUM
, QueueSize
);
99 VirtioMmioSetDeviceStatus (
100 VIRTIO_DEVICE_PROTOCOL
*This
,
104 VIRTIO_MMIO_DEVICE
*Device
;
106 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
108 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_STATUS
, DeviceStatus
);
115 VirtioMmioSetQueueNotify (
116 VIRTIO_DEVICE_PROTOCOL
*This
,
120 VIRTIO_MMIO_DEVICE
*Device
;
122 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
124 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_QUEUE_NOTIFY
, QueueNotify
);
131 VirtioMmioSetQueueAlignment (
132 VIRTIO_DEVICE_PROTOCOL
*This
,
136 VIRTIO_MMIO_DEVICE
*Device
;
138 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
140 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_QUEUE_ALIGN
, Alignment
);
147 VirtioMmioSetPageSize (
148 VIRTIO_DEVICE_PROTOCOL
*This
,
152 VIRTIO_MMIO_DEVICE
*Device
;
154 if (PageSize
!= EFI_PAGE_SIZE
) {
155 return EFI_UNSUPPORTED
;
158 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
160 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_GUEST_PAGE_SIZE
, PageSize
);
167 VirtioMmioSetQueueSel (
168 VIRTIO_DEVICE_PROTOCOL
*This
,
172 VIRTIO_MMIO_DEVICE
*Device
;
174 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
176 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_QUEUE_SEL
, Sel
);
182 VirtioMmioSetQueueAddress (
183 VIRTIO_DEVICE_PROTOCOL
*This
,
187 VIRTIO_MMIO_DEVICE
*Device
;
189 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
191 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_QUEUE_PFN
, Address
);
198 VirtioMmioSetGuestFeatures (
199 VIRTIO_DEVICE_PROTOCOL
*This
,
203 VIRTIO_MMIO_DEVICE
*Device
;
205 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
207 if (Features
> MAX_UINT32
) {
208 return EFI_UNSUPPORTED
;
210 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_GUEST_FEATURES
,
218 VirtioMmioDeviceWrite (
219 IN VIRTIO_DEVICE_PROTOCOL
*This
,
220 IN UINTN FieldOffset
,
225 UINTN DstBaseAddress
;
226 VIRTIO_MMIO_DEVICE
*Device
;
228 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
231 // Double-check fieldsize
233 if ((FieldSize
!= 1) && (FieldSize
!= 2) &&
234 (FieldSize
!= 4) && (FieldSize
!= 8)) {
235 return EFI_INVALID_PARAMETER
;
239 // Compute base address
241 DstBaseAddress
= Device
->BaseAddress
+
242 VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO
+ FieldOffset
;
245 // The device-specific memory area of Virtio-MMIO can only be written in
246 // byte accesses. This is not currently in the Virtio spec.
248 MmioWriteBuffer8 (DstBaseAddress
, FieldSize
, (UINT8
*)&Value
);
255 VirtioMmioDeviceRead (
256 IN VIRTIO_DEVICE_PROTOCOL
*This
,
257 IN UINTN FieldOffset
,
263 UINTN SrcBaseAddress
;
264 VIRTIO_MMIO_DEVICE
*Device
;
266 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
269 // Parameter validation
271 ASSERT (FieldSize
== BufferSize
);
274 // Double-check fieldsize
276 if ((FieldSize
!= 1) && (FieldSize
!= 2) &&
277 (FieldSize
!= 4) && (FieldSize
!= 8)) {
278 return EFI_INVALID_PARAMETER
;
282 // Compute base address
284 SrcBaseAddress
= Device
->BaseAddress
+
285 VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO
+ FieldOffset
;
288 // The device-specific memory area of Virtio-MMIO can only be read in
289 // byte reads. This is not currently in the Virtio spec.
291 MmioReadBuffer8 (SrcBaseAddress
, BufferSize
, Buffer
);