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 VirtioMmioGetQueueAddress (
44 IN VIRTIO_DEVICE_PROTOCOL
*This
,
45 OUT UINT32
*QueueAddress
48 VIRTIO_MMIO_DEVICE
*Device
;
50 if (QueueAddress
== NULL
) {
51 return EFI_INVALID_PARAMETER
;
54 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
56 *QueueAddress
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_QUEUE_PFN
);
63 VirtioMmioGetQueueSize (
64 IN VIRTIO_DEVICE_PROTOCOL
*This
,
65 OUT UINT16
*QueueNumMax
68 VIRTIO_MMIO_DEVICE
*Device
;
70 if (QueueNumMax
== NULL
) {
71 return EFI_INVALID_PARAMETER
;
74 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
76 *QueueNumMax
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_QUEUE_NUM_MAX
) & 0xFFFF;
83 VirtioMmioGetDeviceStatus (
84 IN VIRTIO_DEVICE_PROTOCOL
*This
,
85 OUT UINT8
*DeviceStatus
88 VIRTIO_MMIO_DEVICE
*Device
;
90 if (DeviceStatus
== NULL
) {
91 return EFI_INVALID_PARAMETER
;
94 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
96 *DeviceStatus
= VIRTIO_CFG_READ (Device
, VIRTIO_MMIO_OFFSET_STATUS
) & 0xFF;
103 VirtioMmioSetQueueSize (
104 VIRTIO_DEVICE_PROTOCOL
*This
,
108 VIRTIO_MMIO_DEVICE
*Device
;
110 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
112 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_QUEUE_NUM
, QueueSize
);
119 VirtioMmioSetDeviceStatus (
120 VIRTIO_DEVICE_PROTOCOL
*This
,
124 VIRTIO_MMIO_DEVICE
*Device
;
126 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
128 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_STATUS
, DeviceStatus
);
135 VirtioMmioSetQueueNotify (
136 VIRTIO_DEVICE_PROTOCOL
*This
,
140 VIRTIO_MMIO_DEVICE
*Device
;
142 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
144 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_QUEUE_NOTIFY
, QueueNotify
);
151 VirtioMmioSetQueueAlignment (
152 VIRTIO_DEVICE_PROTOCOL
*This
,
156 VIRTIO_MMIO_DEVICE
*Device
;
158 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
160 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_QUEUE_ALIGN
, Alignment
);
167 VirtioMmioSetPageSize (
168 VIRTIO_DEVICE_PROTOCOL
*This
,
172 VIRTIO_MMIO_DEVICE
*Device
;
174 if (PageSize
!= EFI_PAGE_SIZE
) {
175 return EFI_UNSUPPORTED
;
178 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
180 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_GUEST_PAGE_SIZE
, PageSize
);
187 VirtioMmioSetQueueSel (
188 VIRTIO_DEVICE_PROTOCOL
*This
,
192 VIRTIO_MMIO_DEVICE
*Device
;
194 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
196 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_QUEUE_SEL
, Sel
);
202 VirtioMmioSetQueueAddress (
203 VIRTIO_DEVICE_PROTOCOL
*This
,
207 VIRTIO_MMIO_DEVICE
*Device
;
209 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
211 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_QUEUE_PFN
, Address
);
218 VirtioMmioSetGuestFeatures (
219 VIRTIO_DEVICE_PROTOCOL
*This
,
223 VIRTIO_MMIO_DEVICE
*Device
;
225 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
227 if (Features
> MAX_UINT32
) {
228 return EFI_UNSUPPORTED
;
230 VIRTIO_CFG_WRITE (Device
, VIRTIO_MMIO_OFFSET_GUEST_FEATURES
,
238 VirtioMmioDeviceWrite (
239 IN VIRTIO_DEVICE_PROTOCOL
*This
,
240 IN UINTN FieldOffset
,
245 UINTN DstBaseAddress
;
246 VIRTIO_MMIO_DEVICE
*Device
;
248 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
251 // Double-check fieldsize
253 if ((FieldSize
!= 1) && (FieldSize
!= 2) &&
254 (FieldSize
!= 4) && (FieldSize
!= 8)) {
255 return EFI_INVALID_PARAMETER
;
259 // Compute base address
261 DstBaseAddress
= Device
->BaseAddress
+
262 VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO
+ FieldOffset
;
265 // The device-specific memory area of Virtio-MMIO can only be written in
266 // byte accesses. This is not currently in the Virtio spec.
268 MmioWriteBuffer8 (DstBaseAddress
, FieldSize
, (UINT8
*)&Value
);
275 VirtioMmioDeviceRead (
276 IN VIRTIO_DEVICE_PROTOCOL
*This
,
277 IN UINTN FieldOffset
,
283 UINTN SrcBaseAddress
;
284 VIRTIO_MMIO_DEVICE
*Device
;
286 Device
= VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This
);
289 // Parameter validation
291 ASSERT (FieldSize
== BufferSize
);
294 // Double-check fieldsize
296 if ((FieldSize
!= 1) && (FieldSize
!= 2) &&
297 (FieldSize
!= 4) && (FieldSize
!= 8)) {
298 return EFI_INVALID_PARAMETER
;
302 // Compute base address
304 SrcBaseAddress
= Device
->BaseAddress
+
305 VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO
+ FieldOffset
;
308 // The device-specific memory area of Virtio-MMIO can only be read in
309 // byte reads. This is not currently in the Virtio spec.
311 MmioReadBuffer8 (SrcBaseAddress
, BufferSize
, Buffer
);