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