]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / OvmfPkg / VirtioPciDeviceDxe / VirtioPciFunctions.c
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 **/
42 EFI_STATUS
43 EFIAPI
44 VirtioPciDeviceRead (
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 (
57 Dev,
58 Dev->DeviceSpecificConfigurationOffset + FieldOffset,
59 FieldSize,
60 BufferSize,
61 Buffer
62 );
63 }
64
65 /**
66
67 Write a word into Region 0 of the device specified by VirtIo Device protocol.
68
69 @param[in] This VirtIo Device protocol.
70
71 @param[in] FieldOffset Destination offset.
72
73 @param[in] FieldSize Destination field size, must be in { 1, 2, 4, 8 }.
74
75 @param[in] Value Little endian value to write, converted to UINT64.
76 The least significant FieldSize bytes will be used.
77
78
79 @return Status code returned by PciIo->Io.Write().
80
81 **/
82 EFI_STATUS
83 EFIAPI
84 VirtioPciDeviceWrite (
85 IN VIRTIO_DEVICE_PROTOCOL *This,
86 IN UINTN FieldOffset,
87 IN UINTN FieldSize,
88 IN UINT64 Value
89 )
90 {
91 VIRTIO_PCI_DEVICE *Dev;
92
93 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
94
95 return VirtioPciIoWrite (
96 Dev,
97 Dev->DeviceSpecificConfigurationOffset + FieldOffset,
98 FieldSize,
99 Value
100 );
101 }
102
103 EFI_STATUS
104 EFIAPI
105 VirtioPciGetDeviceFeatures (
106 IN VIRTIO_DEVICE_PROTOCOL *This,
107 OUT UINT64 *DeviceFeatures
108 )
109 {
110 VIRTIO_PCI_DEVICE *Dev;
111 EFI_STATUS Status;
112 UINT32 Features32;
113
114 if (DeviceFeatures == NULL) {
115 return EFI_INVALID_PARAMETER;
116 }
117
118 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
119
120 Status = VirtioPciIoRead (
121 Dev,
122 VIRTIO_PCI_OFFSET_DEVICE_FEATURES,
123 sizeof (UINT32),
124 sizeof (UINT32),
125 &Features32
126 );
127 if (!EFI_ERROR (Status)) {
128 *DeviceFeatures = Features32;
129 }
130
131 return Status;
132 }
133
134 EFI_STATUS
135 EFIAPI
136 VirtioPciGetQueueSize (
137 IN VIRTIO_DEVICE_PROTOCOL *This,
138 OUT UINT16 *QueueNumMax
139 )
140 {
141 VIRTIO_PCI_DEVICE *Dev;
142
143 if (QueueNumMax == NULL) {
144 return EFI_INVALID_PARAMETER;
145 }
146
147 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
148
149 return VirtioPciIoRead (
150 Dev,
151 VIRTIO_PCI_OFFSET_QUEUE_SIZE,
152 sizeof (UINT16),
153 sizeof (UINT16),
154 QueueNumMax
155 );
156 }
157
158 EFI_STATUS
159 EFIAPI
160 VirtioPciGetDeviceStatus (
161 IN VIRTIO_DEVICE_PROTOCOL *This,
162 OUT UINT8 *DeviceStatus
163 )
164 {
165 VIRTIO_PCI_DEVICE *Dev;
166
167 if (DeviceStatus == NULL) {
168 return EFI_INVALID_PARAMETER;
169 }
170
171 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
172
173 return VirtioPciIoRead (
174 Dev,
175 VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS,
176 sizeof (UINT8),
177 sizeof (UINT8),
178 DeviceStatus
179 );
180 }
181
182 EFI_STATUS
183 EFIAPI
184 VirtioPciSetGuestFeatures (
185 IN VIRTIO_DEVICE_PROTOCOL *This,
186 IN UINT64 Features
187 )
188 {
189 VIRTIO_PCI_DEVICE *Dev;
190
191 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
192
193 if (Features > MAX_UINT32) {
194 return EFI_UNSUPPORTED;
195 }
196
197 return VirtioPciIoWrite (
198 Dev,
199 VIRTIO_PCI_OFFSET_GUEST_FEATURES,
200 sizeof (UINT32),
201 Features
202 );
203 }
204
205 EFI_STATUS
206 EFIAPI
207 VirtioPciSetQueueAddress (
208 IN VIRTIO_DEVICE_PROTOCOL *This,
209 IN VRING *Ring,
210 IN UINT64 RingBaseShift
211 )
212 {
213 VIRTIO_PCI_DEVICE *Dev;
214
215 ASSERT (RingBaseShift == 0);
216
217 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
218
219 return VirtioPciIoWrite (
220 Dev,
221 VIRTIO_PCI_OFFSET_QUEUE_ADDRESS,
222 sizeof (UINT32),
223 (UINT32)((UINTN)Ring->Base >> EFI_PAGE_SHIFT)
224 );
225 }
226
227 EFI_STATUS
228 EFIAPI
229 VirtioPciSetQueueSel (
230 IN VIRTIO_DEVICE_PROTOCOL *This,
231 IN UINT16 Sel
232 )
233 {
234 VIRTIO_PCI_DEVICE *Dev;
235
236 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
237
238 return VirtioPciIoWrite (
239 Dev,
240 VIRTIO_PCI_OFFSET_QUEUE_SELECT,
241 sizeof (UINT16),
242 Sel
243 );
244 }
245
246 EFI_STATUS
247 EFIAPI
248 VirtioPciSetQueueAlignment (
249 IN VIRTIO_DEVICE_PROTOCOL *This,
250 IN UINT32 Alignment
251 )
252 {
253 return EFI_SUCCESS;
254 }
255
256 EFI_STATUS
257 EFIAPI
258 VirtioPciSetPageSize (
259 IN VIRTIO_DEVICE_PROTOCOL *This,
260 IN UINT32 PageSize
261 )
262 {
263 return (PageSize == EFI_PAGE_SIZE) ? EFI_SUCCESS : EFI_UNSUPPORTED;
264 }
265
266 EFI_STATUS
267 EFIAPI
268 VirtioPciSetQueueNotify (
269 IN VIRTIO_DEVICE_PROTOCOL *This,
270 IN UINT16 Index
271 )
272 {
273 VIRTIO_PCI_DEVICE *Dev;
274
275 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
276
277 return VirtioPciIoWrite (
278 Dev,
279 VIRTIO_PCI_OFFSET_QUEUE_NOTIFY,
280 sizeof (UINT16),
281 Index
282 );
283 }
284
285 EFI_STATUS
286 EFIAPI
287 VirtioPciSetQueueSize (
288 IN VIRTIO_DEVICE_PROTOCOL *This,
289 IN UINT16 Size
290 )
291 {
292 //
293 // This function is only applicable in Virtio-MMIO.
294 // (The QueueSize field is read-only in Virtio proper (PCI))
295 //
296 return EFI_SUCCESS;
297 }
298
299 EFI_STATUS
300 EFIAPI
301 VirtioPciSetDeviceStatus (
302 IN VIRTIO_DEVICE_PROTOCOL *This,
303 IN UINT8 DeviceStatus
304 )
305 {
306 VIRTIO_PCI_DEVICE *Dev;
307
308 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
309
310 return VirtioPciIoWrite (
311 Dev,
312 VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS,
313 sizeof (UINT8),
314 DeviceStatus
315 );
316 }
317
318 EFI_STATUS
319 EFIAPI
320 VirtioPciAllocateSharedPages (
321 IN VIRTIO_DEVICE_PROTOCOL *This,
322 IN UINTN NumPages,
323 OUT VOID **HostAddress
324 )
325 {
326 VOID *Buffer;
327
328 Buffer = AllocatePages (NumPages);
329 if (Buffer == NULL) {
330 return EFI_OUT_OF_RESOURCES;
331 }
332
333 *HostAddress = Buffer;
334 return EFI_SUCCESS;
335 }
336
337 VOID
338 EFIAPI
339 VirtioPciFreeSharedPages (
340 IN VIRTIO_DEVICE_PROTOCOL *This,
341 IN UINTN NumPages,
342 IN VOID *HostAddress
343 )
344 {
345 FreePages (HostAddress, NumPages);
346 }
347
348 EFI_STATUS
349 EFIAPI
350 VirtioPciMapSharedBuffer (
351 IN VIRTIO_DEVICE_PROTOCOL *This,
352 IN VIRTIO_MAP_OPERATION Operation,
353 IN VOID *HostAddress,
354 IN OUT UINTN *NumberOfBytes,
355 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
356 OUT VOID **Mapping
357 )
358 {
359 *DeviceAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress;
360 *Mapping = NULL;
361
362 return EFI_SUCCESS;
363 }
364
365 EFI_STATUS
366 EFIAPI
367 VirtioPciUnmapSharedBuffer (
368 IN VIRTIO_DEVICE_PROTOCOL *This,
369 IN VOID *Mapping
370 )
371 {
372 return EFI_SUCCESS;
373 }