3 This driver produces Virtio Device Protocol instances for Virtio PCI 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.
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/MemoryAllocationLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/UefiLib.h>
23 #include "VirtioPciDevice.h"
27 Read a word from Region 0 of the device specified by VirtIo Device protocol.
29 The function implements the ReadDevice protocol member of
30 VIRTIO_DEVICE_PROTOCOL.
32 @param[in] This VirtIo Device protocol.
34 @param[in] FieldOffset Source offset.
36 @param[in] FieldSize Source field size, must be in { 1, 2, 4, 8 }.
38 @param[in] BufferSize Number of bytes available in the target buffer. Must
41 @param[out] Buffer Target buffer.
44 @return Status code returned by PciIo->Io.Read().
50 IN VIRTIO_DEVICE_PROTOCOL
*This
,
57 VIRTIO_PCI_DEVICE
*Dev
;
59 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
61 return VirtioPciIoRead (Dev
,
62 Dev
->DeviceSpecificConfigurationOffset
+ FieldOffset
,
63 FieldSize
, BufferSize
, Buffer
);
68 Write a word into Region 0 of the device specified by VirtIo Device protocol.
70 @param[in] This VirtIo Device protocol.
72 @param[in] FieldOffset Destination offset.
74 @param[in] FieldSize Destination field size, must be in { 1, 2, 4, 8 }.
76 @param[in] Value Little endian value to write, converted to UINT64.
77 The least significant FieldSize bytes will be used.
80 @return Status code returned by PciIo->Io.Write().
85 VirtioPciDeviceWrite (
86 IN VIRTIO_DEVICE_PROTOCOL
*This
,
92 VIRTIO_PCI_DEVICE
*Dev
;
94 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
96 return VirtioPciIoWrite (Dev
,
97 Dev
->DeviceSpecificConfigurationOffset
+ FieldOffset
, FieldSize
, Value
);
102 VirtioPciGetDeviceFeatures (
103 IN VIRTIO_DEVICE_PROTOCOL
*This
,
104 OUT UINT64
*DeviceFeatures
107 VIRTIO_PCI_DEVICE
*Dev
;
111 if (DeviceFeatures
== NULL
) {
112 return EFI_INVALID_PARAMETER
;
115 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
117 Status
= VirtioPciIoRead (Dev
, VIRTIO_PCI_OFFSET_DEVICE_FEATURES
,
118 sizeof (UINT32
), sizeof (UINT32
), &Features32
);
119 if (!EFI_ERROR (Status
)) {
120 *DeviceFeatures
= Features32
;
127 VirtioPciGetQueueAddress (
128 IN VIRTIO_DEVICE_PROTOCOL
*This
,
129 OUT UINT32
*QueueAddress
132 VIRTIO_PCI_DEVICE
*Dev
;
134 if (QueueAddress
== NULL
) {
135 return EFI_INVALID_PARAMETER
;
138 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
140 return VirtioPciIoRead (Dev
, VIRTIO_PCI_OFFSET_QUEUE_ADDRESS
, sizeof (UINT32
),
141 sizeof (UINT32
), QueueAddress
);
146 VirtioPciGetQueueSize (
147 IN VIRTIO_DEVICE_PROTOCOL
*This
,
148 OUT UINT16
*QueueNumMax
151 VIRTIO_PCI_DEVICE
*Dev
;
153 if (QueueNumMax
== NULL
) {
154 return EFI_INVALID_PARAMETER
;
157 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
159 return VirtioPciIoRead (Dev
, VIRTIO_PCI_OFFSET_QUEUE_SIZE
, sizeof (UINT16
),
160 sizeof (UINT16
), QueueNumMax
);
165 VirtioPciGetDeviceStatus (
166 IN VIRTIO_DEVICE_PROTOCOL
*This
,
167 OUT UINT8
*DeviceStatus
170 VIRTIO_PCI_DEVICE
*Dev
;
172 if (DeviceStatus
== NULL
) {
173 return EFI_INVALID_PARAMETER
;
176 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
178 return VirtioPciIoRead (Dev
, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS
,
179 sizeof (UINT8
), sizeof (UINT8
), DeviceStatus
);
184 VirtioPciSetGuestFeatures (
185 IN VIRTIO_DEVICE_PROTOCOL
*This
,
189 VIRTIO_PCI_DEVICE
*Dev
;
191 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
193 if (Features
> MAX_UINT32
) {
194 return EFI_UNSUPPORTED
;
196 return VirtioPciIoWrite (Dev
, VIRTIO_PCI_OFFSET_GUEST_FEATURES
,
197 sizeof (UINT32
), Features
);
202 VirtioPciSetQueueAddress (
203 VIRTIO_DEVICE_PROTOCOL
*This
,
207 VIRTIO_PCI_DEVICE
*Dev
;
209 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
211 return VirtioPciIoWrite (Dev
, VIRTIO_PCI_OFFSET_QUEUE_ADDRESS
, sizeof (UINT32
),
217 VirtioPciSetQueueSel (
218 VIRTIO_DEVICE_PROTOCOL
*This
,
222 VIRTIO_PCI_DEVICE
*Dev
;
224 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
226 return VirtioPciIoWrite (Dev
, VIRTIO_PCI_OFFSET_QUEUE_SELECT
, sizeof (UINT16
),
232 VirtioPciSetQueueAlignment (
233 VIRTIO_DEVICE_PROTOCOL
*This
,
242 VirtioPciSetPageSize (
243 VIRTIO_DEVICE_PROTOCOL
*This
,
247 return (PageSize
== EFI_PAGE_SIZE
) ? EFI_SUCCESS
: EFI_UNSUPPORTED
;
252 VirtioPciSetQueueNotify (
253 VIRTIO_DEVICE_PROTOCOL
*This
,
257 VIRTIO_PCI_DEVICE
*Dev
;
259 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
261 return VirtioPciIoWrite (Dev
, VIRTIO_PCI_OFFSET_QUEUE_NOTIFY
, sizeof (UINT16
),
267 VirtioPciSetQueueSize (
268 VIRTIO_DEVICE_PROTOCOL
*This
,
273 // This function is only applicable in Virtio-MMIO.
274 // (The QueueSize field is read-only in Virtio proper (PCI))
281 VirtioPciSetDeviceStatus (
282 VIRTIO_DEVICE_PROTOCOL
*This
,
286 VIRTIO_PCI_DEVICE
*Dev
;
288 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
290 return VirtioPciIoWrite (Dev
, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS
,
291 sizeof (UINT8
), DeviceStatus
);