VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c@ 85718

Last change on this file since 85718 was 80721, checked in by vboxsync, 6 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.1 KB
Line 
1/** @file
2
3 This driver produces Virtio Device Protocol instances for Virtio MMIO 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
9 SPDX-License-Identifier: BSD-2-Clause-Patent
10
11**/
12
13#include "VirtioMmioDevice.h"
14
15EFI_STATUS
16EFIAPI
17VirtioMmioGetDeviceFeatures (
18 IN VIRTIO_DEVICE_PROTOCOL *This,
19 OUT UINT64 *DeviceFeatures
20 )
21{
22 VIRTIO_MMIO_DEVICE *Device;
23
24 if (DeviceFeatures == NULL) {
25 return EFI_INVALID_PARAMETER;
26 }
27
28 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
29
30 *DeviceFeatures = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_HOST_FEATURES);
31
32 return EFI_SUCCESS;
33}
34
35EFI_STATUS
36EFIAPI
37VirtioMmioGetQueueSize (
38 IN VIRTIO_DEVICE_PROTOCOL *This,
39 OUT UINT16 *QueueNumMax
40 )
41{
42 VIRTIO_MMIO_DEVICE *Device;
43
44 if (QueueNumMax == NULL) {
45 return EFI_INVALID_PARAMETER;
46 }
47
48 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
49
50 *QueueNumMax = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM_MAX) & 0xFFFF;
51
52 return EFI_SUCCESS;
53}
54
55EFI_STATUS
56EFIAPI
57VirtioMmioGetDeviceStatus (
58 IN VIRTIO_DEVICE_PROTOCOL *This,
59 OUT UINT8 *DeviceStatus
60 )
61{
62 VIRTIO_MMIO_DEVICE *Device;
63
64 if (DeviceStatus == NULL) {
65 return EFI_INVALID_PARAMETER;
66 }
67
68 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
69
70 *DeviceStatus = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_STATUS) & 0xFF;
71
72 return EFI_SUCCESS;
73}
74
75EFI_STATUS
76EFIAPI
77VirtioMmioSetQueueSize (
78 IN VIRTIO_DEVICE_PROTOCOL *This,
79 IN UINT16 QueueSize
80 )
81{
82 VIRTIO_MMIO_DEVICE *Device;
83
84 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
85
86 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM, QueueSize);
87
88 return EFI_SUCCESS;
89}
90
91EFI_STATUS
92EFIAPI
93VirtioMmioSetDeviceStatus (
94 IN VIRTIO_DEVICE_PROTOCOL *This,
95 IN UINT8 DeviceStatus
96 )
97{
98 VIRTIO_MMIO_DEVICE *Device;
99
100 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
101
102 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_STATUS, DeviceStatus);
103
104 return EFI_SUCCESS;
105}
106
107EFI_STATUS
108EFIAPI
109VirtioMmioSetQueueNotify (
110 IN VIRTIO_DEVICE_PROTOCOL *This,
111 IN UINT16 QueueNotify
112 )
113{
114 VIRTIO_MMIO_DEVICE *Device;
115
116 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
117
118 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NOTIFY, QueueNotify);
119
120 return EFI_SUCCESS;
121}
122
123EFI_STATUS
124EFIAPI
125VirtioMmioSetQueueAlignment (
126 IN VIRTIO_DEVICE_PROTOCOL *This,
127 IN UINT32 Alignment
128 )
129{
130 VIRTIO_MMIO_DEVICE *Device;
131
132 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
133
134 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_ALIGN, Alignment);
135
136 return EFI_SUCCESS;
137}
138
139EFI_STATUS
140EFIAPI
141VirtioMmioSetPageSize (
142 IN VIRTIO_DEVICE_PROTOCOL *This,
143 IN UINT32 PageSize
144 )
145{
146 VIRTIO_MMIO_DEVICE *Device;
147
148 if (PageSize != EFI_PAGE_SIZE) {
149 return EFI_UNSUPPORTED;
150 }
151
152 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
153
154 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_PAGE_SIZE, PageSize);
155
156 return EFI_SUCCESS;
157}
158
159EFI_STATUS
160EFIAPI
161VirtioMmioSetQueueSel (
162 IN VIRTIO_DEVICE_PROTOCOL *This,
163 IN UINT16 Sel
164 )
165{
166 VIRTIO_MMIO_DEVICE *Device;
167
168 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
169
170 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_SEL, Sel);
171
172 return EFI_SUCCESS;
173}
174
175EFI_STATUS
176VirtioMmioSetQueueAddress (
177 IN VIRTIO_DEVICE_PROTOCOL *This,
178 IN VRING *Ring,
179 IN UINT64 RingBaseShift
180 )
181{
182 VIRTIO_MMIO_DEVICE *Device;
183
184 ASSERT (RingBaseShift == 0);
185
186 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
187
188 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN,
189 (UINT32)((UINTN)Ring->Base >> EFI_PAGE_SHIFT));
190
191 return EFI_SUCCESS;
192}
193
194EFI_STATUS
195EFIAPI
196VirtioMmioSetGuestFeatures (
197 IN VIRTIO_DEVICE_PROTOCOL *This,
198 IN UINT64 Features
199 )
200{
201 VIRTIO_MMIO_DEVICE *Device;
202
203 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
204
205 if (Features > MAX_UINT32) {
206 return EFI_UNSUPPORTED;
207 }
208 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_FEATURES,
209 (UINT32)Features);
210
211 return EFI_SUCCESS;
212}
213
214EFI_STATUS
215EFIAPI
216VirtioMmioDeviceWrite (
217 IN VIRTIO_DEVICE_PROTOCOL *This,
218 IN UINTN FieldOffset,
219 IN UINTN FieldSize,
220 IN UINT64 Value
221 )
222{
223 UINTN DstBaseAddress;
224 VIRTIO_MMIO_DEVICE *Device;
225
226 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
227
228 //
229 // Double-check fieldsize
230 //
231 if ((FieldSize != 1) && (FieldSize != 2) &&
232 (FieldSize != 4) && (FieldSize != 8)) {
233 return EFI_INVALID_PARAMETER;
234 }
235
236 //
237 // Compute base address
238 //
239 DstBaseAddress = Device->BaseAddress +
240 VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset;
241
242 //
243 // The device-specific memory area of Virtio-MMIO can only be written in
244 // byte accesses. This is not currently in the Virtio spec.
245 //
246 MmioWriteBuffer8 (DstBaseAddress, FieldSize, (UINT8*)&Value);
247
248 return EFI_SUCCESS;
249}
250
251EFI_STATUS
252EFIAPI
253VirtioMmioDeviceRead (
254 IN VIRTIO_DEVICE_PROTOCOL *This,
255 IN UINTN FieldOffset,
256 IN UINTN FieldSize,
257 IN UINTN BufferSize,
258 OUT VOID *Buffer
259 )
260{
261 UINTN SrcBaseAddress;
262 VIRTIO_MMIO_DEVICE *Device;
263
264 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
265
266 //
267 // Parameter validation
268 //
269 ASSERT (FieldSize == BufferSize);
270
271 //
272 // Double-check fieldsize
273 //
274 if ((FieldSize != 1) && (FieldSize != 2) &&
275 (FieldSize != 4) && (FieldSize != 8)) {
276 return EFI_INVALID_PARAMETER;
277 }
278
279 //
280 // Compute base address
281 //
282 SrcBaseAddress = Device->BaseAddress +
283 VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset;
284
285 //
286 // The device-specific memory area of Virtio-MMIO can only be read in
287 // byte reads. This is not currently in the Virtio spec.
288 //
289 MmioReadBuffer8 (SrcBaseAddress, BufferSize, Buffer);
290
291 return EFI_SUCCESS;
292}
293
294EFI_STATUS
295EFIAPI
296VirtioMmioAllocateSharedPages (
297 IN VIRTIO_DEVICE_PROTOCOL *This,
298 IN UINTN NumPages,
299 OUT VOID **HostAddress
300 )
301{
302 VOID *Buffer;
303
304 Buffer = AllocatePages (NumPages);
305 if (Buffer == NULL) {
306 return EFI_OUT_OF_RESOURCES;
307 }
308
309 *HostAddress = Buffer;
310 return EFI_SUCCESS;
311}
312
313VOID
314EFIAPI
315VirtioMmioFreeSharedPages (
316 IN VIRTIO_DEVICE_PROTOCOL *This,
317 IN UINTN NumPages,
318 IN VOID *HostAddress
319 )
320{
321 FreePages (HostAddress, NumPages);
322}
323
324EFI_STATUS
325EFIAPI
326VirtioMmioMapSharedBuffer (
327 IN VIRTIO_DEVICE_PROTOCOL *This,
328 IN VIRTIO_MAP_OPERATION Operation,
329 IN VOID *HostAddress,
330 IN OUT UINTN *NumberOfBytes,
331 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
332 OUT VOID **Mapping
333 )
334{
335 *DeviceAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
336 *Mapping = NULL;
337
338 return EFI_SUCCESS;
339}
340
341EFI_STATUS
342EFIAPI
343VirtioMmioUnmapSharedBuffer (
344 IN VIRTIO_DEVICE_PROTOCOL *This,
345 IN VOID *Mapping
346 )
347{
348 return EFI_SUCCESS;
349}
Note: See TracBrowser for help on using the repository browser.

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