TianoCore EDK2 master
Loading...
Searching...
No Matches
VirtioMmioDeviceFunctions.c
Go to the documentation of this file.
1
13#include "VirtioMmioDevice.h"
14
16EFIAPI
17VirtioMmioGetDeviceFeatures (
19 OUT UINT64 *DeviceFeatures
20 )
21{
22 VIRTIO_MMIO_DEVICE *Device;
23 UINT32 LowBits, HighBits;
24
25 if (DeviceFeatures == NULL) {
26 return EFI_INVALID_PARAMETER;
27 }
28
29 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
30
31 if (Device->Version == VIRTIO_MMIO_DEVICE_VERSION_0_95) {
32 *DeviceFeatures = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_HOST_FEATURES);
33 } else {
34 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_HOST_FEATURES_SEL, 0);
35 LowBits = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_HOST_FEATURES);
36 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_HOST_FEATURES_SEL, 1);
37 HighBits = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_HOST_FEATURES);
38 *DeviceFeatures = LShiftU64 (HighBits, 32) | LowBits;
39 }
40
41 return EFI_SUCCESS;
42}
43
45EFIAPI
46VirtioMmioGetQueueSize (
48 OUT UINT16 *QueueNumMax
49 )
50{
51 VIRTIO_MMIO_DEVICE *Device;
52
53 if (QueueNumMax == NULL) {
54 return EFI_INVALID_PARAMETER;
55 }
56
57 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
58
59 *QueueNumMax = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM_MAX) & 0xFFFF;
60
61 return EFI_SUCCESS;
62}
63
65EFIAPI
66VirtioMmioGetDeviceStatus (
68 OUT UINT8 *DeviceStatus
69 )
70{
71 VIRTIO_MMIO_DEVICE *Device;
72
73 if (DeviceStatus == NULL) {
74 return EFI_INVALID_PARAMETER;
75 }
76
77 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
78
79 *DeviceStatus = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_STATUS) & 0xFF;
80
81 return EFI_SUCCESS;
82}
83
85EFIAPI
86VirtioMmioSetQueueSize (
88 IN UINT16 QueueSize
89 )
90{
91 VIRTIO_MMIO_DEVICE *Device;
92
93 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
94
95 if (Device->Version == VIRTIO_MMIO_DEVICE_VERSION_0_95) {
96 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM, QueueSize);
97 } else {
98 Device->QueueNum = QueueSize;
99 }
100
101 return EFI_SUCCESS;
102}
103
105EFIAPI
106VirtioMmioSetDeviceStatus (
108 IN UINT8 DeviceStatus
109 )
110{
111 VIRTIO_MMIO_DEVICE *Device;
112
113 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
114
115 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_STATUS, DeviceStatus);
116
117 return EFI_SUCCESS;
118}
119
121EFIAPI
122VirtioMmioSetQueueNotify (
124 IN UINT16 QueueNotify
125 )
126{
127 VIRTIO_MMIO_DEVICE *Device;
128
129 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
130
131 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NOTIFY, QueueNotify);
132
133 return EFI_SUCCESS;
134}
135
137EFIAPI
138VirtioMmioSetQueueAlignment (
140 IN UINT32 Alignment
141 )
142{
143 VIRTIO_MMIO_DEVICE *Device;
144
145 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
146
147 if (Device->Version == VIRTIO_MMIO_DEVICE_VERSION_0_95) {
148 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_ALIGN, Alignment);
149 }
150
151 return EFI_SUCCESS;
152}
153
155EFIAPI
156VirtioMmioSetPageSize (
158 IN UINT32 PageSize
159 )
160{
161 VIRTIO_MMIO_DEVICE *Device;
162
163 if (PageSize != EFI_PAGE_SIZE) {
164 return EFI_UNSUPPORTED;
165 }
166
167 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
168
169 if (Device->Version == VIRTIO_MMIO_DEVICE_VERSION_0_95) {
170 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_PAGE_SIZE, PageSize);
171 }
172
173 return EFI_SUCCESS;
174}
175
177EFIAPI
178VirtioMmioSetQueueSel (
180 IN UINT16 Sel
181 )
182{
183 VIRTIO_MMIO_DEVICE *Device;
184
185 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
186
187 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_SEL, Sel);
188
189 if (Device->Version == VIRTIO_MMIO_DEVICE_VERSION_0_95) {
190 Device->QueueNum = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM_MAX) & 0xFFFF;
191 }
192
193 return EFI_SUCCESS;
194}
195
197EFIAPI
198VirtioMmioSetQueueAddress (
200 IN VRING *Ring,
201 IN UINT64 RingBaseShift
202 )
203{
204 VIRTIO_MMIO_DEVICE *Device;
205 UINT64 Address;
206
207 ASSERT (RingBaseShift == 0);
208
209 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
210
211 if (Device->Version == VIRTIO_MMIO_DEVICE_VERSION_0_95) {
212 VIRTIO_CFG_WRITE (
213 Device,
214 VIRTIO_MMIO_OFFSET_QUEUE_PFN,
215 (UINT32)((UINTN)Ring->Base >> EFI_PAGE_SHIFT)
216 );
217 } else {
218 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM, Device->QueueNum);
219
220 Address = (UINTN)Ring->Base;
221 VIRTIO_CFG_WRITE (
222 Device,
223 VIRTIO_MMIO_OFFSET_QUEUE_DESC_LO,
224 (UINT32)Address
225 );
226 VIRTIO_CFG_WRITE (
227 Device,
228 VIRTIO_MMIO_OFFSET_QUEUE_DESC_HI,
229 (UINT32)RShiftU64 (Address, 32)
230 );
231
232 Address = (UINTN)Ring->Avail.Flags;
233 VIRTIO_CFG_WRITE (
234 Device,
235 VIRTIO_MMIO_OFFSET_QUEUE_AVAIL_LO,
236 (UINT32)Address
237 );
238 VIRTIO_CFG_WRITE (
239 Device,
240 VIRTIO_MMIO_OFFSET_QUEUE_AVAIL_HI,
241 (UINT32)RShiftU64 (Address, 32)
242 );
243
244 Address = (UINTN)Ring->Used.Flags;
245 VIRTIO_CFG_WRITE (
246 Device,
247 VIRTIO_MMIO_OFFSET_QUEUE_USED_LO,
248 (UINT32)Address
249 );
250 VIRTIO_CFG_WRITE (
251 Device,
252 VIRTIO_MMIO_OFFSET_QUEUE_USED_HI,
253 (UINT32)RShiftU64 (Address, 32)
254 );
255
256 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_READY, 1);
257 }
258
259 return EFI_SUCCESS;
260}
261
263EFIAPI
264VirtioMmioSetGuestFeatures (
266 IN UINT64 Features
267 )
268{
269 VIRTIO_MMIO_DEVICE *Device;
270
271 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
272
273 if (Device->Version == VIRTIO_MMIO_DEVICE_VERSION_0_95) {
274 if (Features > MAX_UINT32) {
275 return EFI_UNSUPPORTED;
276 }
277
278 VIRTIO_CFG_WRITE (
279 Device,
280 VIRTIO_MMIO_OFFSET_GUEST_FEATURES,
281 (UINT32)Features
282 );
283 } else {
284 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_FEATURES_SEL, 0);
285 VIRTIO_CFG_WRITE (
286 Device,
287 VIRTIO_MMIO_OFFSET_GUEST_FEATURES,
288 (UINT32)Features
289 );
290 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_FEATURES_SEL, 1);
291 VIRTIO_CFG_WRITE (
292 Device,
293 VIRTIO_MMIO_OFFSET_GUEST_FEATURES,
294 (UINT32)RShiftU64 (Features, 32)
295 );
296 }
297
298 return EFI_SUCCESS;
299}
300
302EFIAPI
303VirtioMmioDeviceWrite (
305 IN UINTN FieldOffset,
306 IN UINTN FieldSize,
307 IN UINT64 Value
308 )
309{
310 UINTN DstBaseAddress;
311 VIRTIO_MMIO_DEVICE *Device;
312
313 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
314
315 //
316 // Double-check fieldsize
317 //
318 if ((FieldSize != 1) && (FieldSize != 2) &&
319 (FieldSize != 4) && (FieldSize != 8))
320 {
321 return EFI_INVALID_PARAMETER;
322 }
323
324 //
325 // Compute base address
326 //
327 DstBaseAddress = Device->BaseAddress +
328 VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset;
329
330 //
331 // The device-specific memory area of Virtio-MMIO can only be written in
332 // byte accesses. This is not currently in the Virtio spec.
333 //
334 MmioWriteBuffer8 (DstBaseAddress, FieldSize, (UINT8 *)&Value);
335
336 return EFI_SUCCESS;
337}
338
340EFIAPI
341VirtioMmioDeviceRead (
343 IN UINTN FieldOffset,
344 IN UINTN FieldSize,
345 IN UINTN BufferSize,
346 OUT VOID *Buffer
347 )
348{
349 UINTN SrcBaseAddress;
350 VIRTIO_MMIO_DEVICE *Device;
351
352 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
353
354 //
355 // Parameter validation
356 //
357 ASSERT (FieldSize == BufferSize);
358
359 //
360 // Double-check fieldsize
361 //
362 if ((FieldSize != 1) && (FieldSize != 2) &&
363 (FieldSize != 4) && (FieldSize != 8))
364 {
365 return EFI_INVALID_PARAMETER;
366 }
367
368 //
369 // Compute base address
370 //
371 SrcBaseAddress = Device->BaseAddress +
372 VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset;
373
374 //
375 // The device-specific memory area of Virtio-MMIO can only be read in
376 // byte reads. This is not currently in the Virtio spec.
377 //
378 MmioReadBuffer8 (SrcBaseAddress, BufferSize, Buffer);
379
380 return EFI_SUCCESS;
381}
382
384EFIAPI
385VirtioMmioAllocateSharedPages (
387 IN UINTN NumPages,
388 OUT VOID **HostAddress
389 )
390{
391 VOID *Buffer;
392
393 Buffer = AllocatePages (NumPages);
394 if (Buffer == NULL) {
395 return EFI_OUT_OF_RESOURCES;
396 }
397
398 *HostAddress = Buffer;
399 return EFI_SUCCESS;
400}
401
402VOID
403EFIAPI
404VirtioMmioFreeSharedPages (
406 IN UINTN NumPages,
407 IN VOID *HostAddress
408 )
409{
410 FreePages (HostAddress, NumPages);
411}
412
414EFIAPI
415VirtioMmioMapSharedBuffer (
417 IN VIRTIO_MAP_OPERATION Operation,
418 IN VOID *HostAddress,
419 IN OUT UINTN *NumberOfBytes,
420 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
421 OUT VOID **Mapping
422 )
423{
424 *DeviceAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress;
425 *Mapping = NULL;
426
427 return EFI_SUCCESS;
428}
429
431EFIAPI
432VirtioMmioUnmapSharedBuffer (
434 IN VOID *Mapping
435 )
436{
437 return EFI_SUCCESS;
438}
UINT64 UINTN
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
UINT8 *EFIAPI MmioReadBuffer8(IN UINTN StartAddress, IN UINTN Length, OUT UINT8 *Buffer)
UINT8 *EFIAPI MmioWriteBuffer8(IN UINTN StartAddress, IN UINTN Length, IN CONST UINT8 *Buffer)
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
VOID *EFIAPI AllocatePages(IN UINTN Pages)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112