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 UINT32
*DeviceFeatures
107 VIRTIO_PCI_DEVICE
*Dev
;
109 if (DeviceFeatures
== NULL
) {
110 return EFI_INVALID_PARAMETER
;
113 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
115 return VirtioPciIoRead (Dev
, VIRTIO_PCI_OFFSET_DEVICE_FEATURES
, sizeof (UINT32
),
116 sizeof (UINT32
), DeviceFeatures
);
121 VirtioPciGetQueueAddress (
122 IN VIRTIO_DEVICE_PROTOCOL
*This
,
123 OUT UINT32
*QueueAddress
126 VIRTIO_PCI_DEVICE
*Dev
;
128 if (QueueAddress
== NULL
) {
129 return EFI_INVALID_PARAMETER
;
132 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
134 return VirtioPciIoRead (Dev
, VIRTIO_PCI_OFFSET_QUEUE_ADDRESS
, sizeof (UINT32
),
135 sizeof (UINT32
), QueueAddress
);
140 VirtioPciGetQueueSize (
141 IN VIRTIO_DEVICE_PROTOCOL
*This
,
142 OUT UINT16
*QueueNumMax
145 VIRTIO_PCI_DEVICE
*Dev
;
147 if (QueueNumMax
== NULL
) {
148 return EFI_INVALID_PARAMETER
;
151 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
153 return VirtioPciIoRead (Dev
, VIRTIO_PCI_OFFSET_QUEUE_SIZE
, sizeof (UINT16
),
154 sizeof (UINT16
), QueueNumMax
);
159 VirtioPciGetDeviceStatus (
160 IN VIRTIO_DEVICE_PROTOCOL
*This
,
161 OUT UINT8
*DeviceStatus
164 VIRTIO_PCI_DEVICE
*Dev
;
166 if (DeviceStatus
== NULL
) {
167 return EFI_INVALID_PARAMETER
;
170 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
172 return VirtioPciIoRead (Dev
, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS
,
173 sizeof (UINT8
), sizeof (UINT8
), DeviceStatus
);
178 VirtioPciSetGuestFeatures (
179 IN VIRTIO_DEVICE_PROTOCOL
*This
,
183 VIRTIO_PCI_DEVICE
*Dev
;
185 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
187 return VirtioPciIoWrite (Dev
, VIRTIO_PCI_OFFSET_GUEST_FEATURES
,
188 sizeof (UINT32
), Features
);
193 VirtioPciSetQueueAddress (
194 VIRTIO_DEVICE_PROTOCOL
*This
,
198 VIRTIO_PCI_DEVICE
*Dev
;
200 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
202 return VirtioPciIoWrite (Dev
, VIRTIO_PCI_OFFSET_QUEUE_ADDRESS
, sizeof (UINT32
),
208 VirtioPciSetQueueSel (
209 VIRTIO_DEVICE_PROTOCOL
*This
,
213 VIRTIO_PCI_DEVICE
*Dev
;
215 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
217 return VirtioPciIoWrite (Dev
, VIRTIO_PCI_OFFSET_QUEUE_SELECT
, sizeof (UINT16
),
223 VirtioPciSetQueueAlignment (
224 VIRTIO_DEVICE_PROTOCOL
*This
,
233 VirtioPciSetPageSize (
234 VIRTIO_DEVICE_PROTOCOL
*This
,
238 return (PageSize
== EFI_PAGE_SIZE
) ? EFI_SUCCESS
: EFI_UNSUPPORTED
;
243 VirtioPciSetQueueNotify (
244 VIRTIO_DEVICE_PROTOCOL
*This
,
248 VIRTIO_PCI_DEVICE
*Dev
;
250 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
252 return VirtioPciIoWrite (Dev
, VIRTIO_PCI_OFFSET_QUEUE_NOTIFY
, sizeof (UINT16
),
258 VirtioPciSetQueueSize (
259 VIRTIO_DEVICE_PROTOCOL
*This
,
264 // This function is only applicable in Virtio-MMIO.
265 // (The QueueSize field is read-only in Virtio proper (PCI))
272 VirtioPciSetDeviceStatus (
273 VIRTIO_DEVICE_PROTOCOL
*This
,
277 VIRTIO_PCI_DEVICE
*Dev
;
279 Dev
= VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This
);
281 return VirtioPciIoWrite (Dev
, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS
,
282 sizeof (UINT8
), DeviceStatus
);