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 VirtioPciGetQueueSize (
128 IN VIRTIO_DEVICE_PROTOCOL
*This
,
129 OUT UINT16
*QueueNumMax
132 VIRTIO_PCI_DEVICE
*Dev
;
134 if (QueueNumMax
== NULL
) {
135 return EFI_INVALID_PARAMETER
;
138 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
140 return VirtioPciIoRead (Dev
, VIRTIO_PCI_OFFSET_QUEUE_SIZE
, sizeof (UINT16
),
141 sizeof (UINT16
), QueueNumMax
);
146 VirtioPciGetDeviceStatus (
147 IN VIRTIO_DEVICE_PROTOCOL
*This
,
148 OUT UINT8
*DeviceStatus
151 VIRTIO_PCI_DEVICE
*Dev
;
153 if (DeviceStatus
== NULL
) {
154 return EFI_INVALID_PARAMETER
;
157 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
159 return VirtioPciIoRead (Dev
, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS
,
160 sizeof (UINT8
), sizeof (UINT8
), DeviceStatus
);
165 VirtioPciSetGuestFeatures (
166 IN VIRTIO_DEVICE_PROTOCOL
*This
,
170 VIRTIO_PCI_DEVICE
*Dev
;
172 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
174 if (Features
> MAX_UINT32
) {
175 return EFI_UNSUPPORTED
;
177 return VirtioPciIoWrite (Dev
, VIRTIO_PCI_OFFSET_GUEST_FEATURES
,
178 sizeof (UINT32
), Features
);
183 VirtioPciSetQueueAddress (
184 IN VIRTIO_DEVICE_PROTOCOL
*This
,
188 VIRTIO_PCI_DEVICE
*Dev
;
190 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
192 return VirtioPciIoWrite (Dev
, VIRTIO_PCI_OFFSET_QUEUE_ADDRESS
, sizeof (UINT32
),
193 (UINT32
)((UINTN
)Ring
->Base
>> EFI_PAGE_SHIFT
));
198 VirtioPciSetQueueSel (
199 VIRTIO_DEVICE_PROTOCOL
*This
,
203 VIRTIO_PCI_DEVICE
*Dev
;
205 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
207 return VirtioPciIoWrite (Dev
, VIRTIO_PCI_OFFSET_QUEUE_SELECT
, sizeof (UINT16
),
213 VirtioPciSetQueueAlignment (
214 VIRTIO_DEVICE_PROTOCOL
*This
,
223 VirtioPciSetPageSize (
224 VIRTIO_DEVICE_PROTOCOL
*This
,
228 return (PageSize
== EFI_PAGE_SIZE
) ? EFI_SUCCESS
: EFI_UNSUPPORTED
;
233 VirtioPciSetQueueNotify (
234 VIRTIO_DEVICE_PROTOCOL
*This
,
238 VIRTIO_PCI_DEVICE
*Dev
;
240 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
242 return VirtioPciIoWrite (Dev
, VIRTIO_PCI_OFFSET_QUEUE_NOTIFY
, sizeof (UINT16
),
248 VirtioPciSetQueueSize (
249 VIRTIO_DEVICE_PROTOCOL
*This
,
254 // This function is only applicable in Virtio-MMIO.
255 // (The QueueSize field is read-only in Virtio proper (PCI))
262 VirtioPciSetDeviceStatus (
263 VIRTIO_DEVICE_PROTOCOL
*This
,
267 VIRTIO_PCI_DEVICE
*Dev
;
269 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
271 return VirtioPciIoWrite (Dev
, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS
,
272 sizeof (UINT8
), DeviceStatus
);