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