VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c@ 81913

Last change on this file since 81913 was 80721, checked in by vboxsync, 5 years ago

Devices/EFI/FirmwareNew: Start upgrade process to edk2-stable201908 (compiles on Windows and works to some extent), bugref:4643

  • Property svn:eol-style set to native
File size: 7.2 KB
Line 
1/** @file
2
3 This driver produces Virtio Device Protocol instances for Virtio PCI devices.
4
5 Copyright (C) 2012, Red Hat, Inc.
6 Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
7 Copyright (C) 2013, ARM Ltd.
8 Copyright (C) 2017, AMD Inc, All rights reserved.<BR>
9
10 SPDX-License-Identifier: BSD-2-Clause-Patent
11
12**/
13#include <Library/BaseMemoryLib.h>
14#include <Library/DebugLib.h>
15#include <Library/MemoryAllocationLib.h>
16#include <Library/UefiBootServicesTableLib.h>
17#include <Library/UefiLib.h>
18#include "VirtioPciDevice.h"
19
20/**
21
22 Read a word from Region 0 of the device specified by VirtIo Device protocol.
23
24 The function implements the ReadDevice protocol member of
25 VIRTIO_DEVICE_PROTOCOL.
26
27 @param[in] This VirtIo Device protocol.
28
29 @param[in] FieldOffset Source offset.
30
31 @param[in] FieldSize Source field size, must be in { 1, 2, 4, 8 }.
32
33 @param[in] BufferSize Number of bytes available in the target buffer. Must
34 equal FieldSize.
35
36 @param[out] Buffer Target buffer.
37
38
39 @return Status code returned by PciIo->Io.Read().
40
41**/
42EFI_STATUS
43EFIAPI
44VirtioPciDeviceRead (
45 IN VIRTIO_DEVICE_PROTOCOL *This,
46 IN UINTN FieldOffset,
47 IN UINTN FieldSize,
48 IN UINTN BufferSize,
49 OUT VOID *Buffer
50 )
51{
52 VIRTIO_PCI_DEVICE *Dev;
53
54 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
55
56 return VirtioPciIoRead (Dev,
57 Dev->DeviceSpecificConfigurationOffset + FieldOffset,
58 FieldSize, BufferSize, Buffer);
59}
60
61/**
62
63 Write a word into Region 0 of the device specified by VirtIo Device protocol.
64
65 @param[in] This VirtIo Device protocol.
66
67 @param[in] FieldOffset Destination offset.
68
69 @param[in] FieldSize Destination field size, must be in { 1, 2, 4, 8 }.
70
71 @param[in] Value Little endian value to write, converted to UINT64.
72 The least significant FieldSize bytes will be used.
73
74
75 @return Status code returned by PciIo->Io.Write().
76
77**/
78EFI_STATUS
79EFIAPI
80VirtioPciDeviceWrite (
81 IN VIRTIO_DEVICE_PROTOCOL *This,
82 IN UINTN FieldOffset,
83 IN UINTN FieldSize,
84 IN UINT64 Value
85 )
86{
87 VIRTIO_PCI_DEVICE *Dev;
88
89 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
90
91 return VirtioPciIoWrite (Dev,
92 Dev->DeviceSpecificConfigurationOffset + FieldOffset, FieldSize, Value);
93}
94
95EFI_STATUS
96EFIAPI
97VirtioPciGetDeviceFeatures (
98 IN VIRTIO_DEVICE_PROTOCOL *This,
99 OUT UINT64 *DeviceFeatures
100 )
101{
102 VIRTIO_PCI_DEVICE *Dev;
103 EFI_STATUS Status;
104 UINT32 Features32;
105
106 if (DeviceFeatures == NULL) {
107 return EFI_INVALID_PARAMETER;
108 }
109
110 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
111
112 Status = VirtioPciIoRead (Dev, VIRTIO_PCI_OFFSET_DEVICE_FEATURES,
113 sizeof (UINT32), sizeof (UINT32), &Features32);
114 if (!EFI_ERROR (Status)) {
115 *DeviceFeatures = Features32;
116 }
117 return Status;
118}
119
120EFI_STATUS
121EFIAPI
122VirtioPciGetQueueSize (
123 IN VIRTIO_DEVICE_PROTOCOL *This,
124 OUT UINT16 *QueueNumMax
125 )
126{
127 VIRTIO_PCI_DEVICE *Dev;
128
129 if (QueueNumMax == NULL) {
130 return EFI_INVALID_PARAMETER;
131 }
132
133 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
134
135 return VirtioPciIoRead (Dev, VIRTIO_PCI_OFFSET_QUEUE_SIZE, sizeof (UINT16),
136 sizeof (UINT16), QueueNumMax);
137}
138
139EFI_STATUS
140EFIAPI
141VirtioPciGetDeviceStatus (
142 IN VIRTIO_DEVICE_PROTOCOL *This,
143 OUT UINT8 *DeviceStatus
144 )
145{
146 VIRTIO_PCI_DEVICE *Dev;
147
148 if (DeviceStatus == NULL) {
149 return EFI_INVALID_PARAMETER;
150 }
151
152 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
153
154 return VirtioPciIoRead (Dev, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS,
155 sizeof (UINT8), sizeof (UINT8), DeviceStatus);
156}
157
158EFI_STATUS
159EFIAPI
160VirtioPciSetGuestFeatures (
161 IN VIRTIO_DEVICE_PROTOCOL *This,
162 IN UINT64 Features
163 )
164{
165 VIRTIO_PCI_DEVICE *Dev;
166
167 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
168
169 if (Features > MAX_UINT32) {
170 return EFI_UNSUPPORTED;
171 }
172 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_GUEST_FEATURES,
173 sizeof (UINT32), Features);
174}
175
176EFI_STATUS
177EFIAPI
178VirtioPciSetQueueAddress (
179 IN VIRTIO_DEVICE_PROTOCOL *This,
180 IN VRING *Ring,
181 IN UINT64 RingBaseShift
182 )
183{
184 VIRTIO_PCI_DEVICE *Dev;
185
186 ASSERT (RingBaseShift == 0);
187
188 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
189
190 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_ADDRESS, sizeof (UINT32),
191 (UINT32)((UINTN)Ring->Base >> EFI_PAGE_SHIFT));
192}
193
194EFI_STATUS
195EFIAPI
196VirtioPciSetQueueSel (
197 IN VIRTIO_DEVICE_PROTOCOL *This,
198 IN UINT16 Sel
199 )
200{
201 VIRTIO_PCI_DEVICE *Dev;
202
203 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
204
205 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_SELECT, sizeof (UINT16),
206 Sel);
207}
208
209EFI_STATUS
210EFIAPI
211VirtioPciSetQueueAlignment (
212 IN VIRTIO_DEVICE_PROTOCOL *This,
213 IN UINT32 Alignment
214 )
215{
216 return EFI_SUCCESS;
217}
218
219EFI_STATUS
220EFIAPI
221VirtioPciSetPageSize (
222 IN VIRTIO_DEVICE_PROTOCOL *This,
223 IN UINT32 PageSize
224 )
225{
226 return (PageSize == EFI_PAGE_SIZE) ? EFI_SUCCESS : EFI_UNSUPPORTED;
227}
228
229EFI_STATUS
230EFIAPI
231VirtioPciSetQueueNotify (
232 IN VIRTIO_DEVICE_PROTOCOL *This,
233 IN UINT16 Index
234 )
235{
236 VIRTIO_PCI_DEVICE *Dev;
237
238 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
239
240 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_NOTIFY, sizeof (UINT16),
241 Index);
242}
243
244EFI_STATUS
245EFIAPI
246VirtioPciSetQueueSize (
247 IN VIRTIO_DEVICE_PROTOCOL *This,
248 IN UINT16 Size
249 )
250{
251 //
252 // This function is only applicable in Virtio-MMIO.
253 // (The QueueSize field is read-only in Virtio proper (PCI))
254 //
255 return EFI_SUCCESS;
256}
257
258EFI_STATUS
259EFIAPI
260VirtioPciSetDeviceStatus (
261 IN VIRTIO_DEVICE_PROTOCOL *This,
262 IN UINT8 DeviceStatus
263 )
264{
265 VIRTIO_PCI_DEVICE *Dev;
266
267 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
268
269 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS,
270 sizeof (UINT8), DeviceStatus);
271}
272
273EFI_STATUS
274EFIAPI
275VirtioPciAllocateSharedPages (
276 IN VIRTIO_DEVICE_PROTOCOL *This,
277 IN UINTN NumPages,
278 OUT VOID **HostAddress
279 )
280{
281 VOID *Buffer;
282
283 Buffer = AllocatePages (NumPages);
284 if (Buffer == NULL) {
285 return EFI_OUT_OF_RESOURCES;
286 }
287
288 *HostAddress = Buffer;
289 return EFI_SUCCESS;
290}
291
292VOID
293EFIAPI
294VirtioPciFreeSharedPages (
295 IN VIRTIO_DEVICE_PROTOCOL *This,
296 IN UINTN NumPages,
297 IN VOID *HostAddress
298 )
299{
300 FreePages (HostAddress, NumPages);
301}
302
303EFI_STATUS
304EFIAPI
305VirtioPciMapSharedBuffer (
306 IN VIRTIO_DEVICE_PROTOCOL *This,
307 IN VIRTIO_MAP_OPERATION Operation,
308 IN VOID *HostAddress,
309 IN OUT UINTN *NumberOfBytes,
310 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
311 OUT VOID **Mapping
312 )
313{
314 *DeviceAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
315 *Mapping = NULL;
316
317 return EFI_SUCCESS;
318}
319
320EFI_STATUS
321EFIAPI
322VirtioPciUnmapSharedBuffer (
323 IN VIRTIO_DEVICE_PROTOCOL *This,
324 IN VOID *Mapping
325 )
326{
327 return EFI_SUCCESS;
328}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette