OvmfPkg/VirtioMmioDeviceLib: list "VirtioMmioDevice.h" in the INF file
[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
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
bc8fde6f 25 OUT UINT64 *DeviceFeatures\r
6fb4e772
OM
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
6fb4e772
OM
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
22701a3d
BS
84 IN VIRTIO_DEVICE_PROTOCOL *This,\r
85 IN UINT16 QueueSize\r
6fb4e772
OM
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
22701a3d
BS
100 IN VIRTIO_DEVICE_PROTOCOL *This,\r
101 IN UINT8 DeviceStatus\r
6fb4e772
OM
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
22701a3d
BS
116 IN VIRTIO_DEVICE_PROTOCOL *This,\r
117 IN UINT16 QueueNotify\r
6fb4e772
OM
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
22701a3d
BS
132 IN VIRTIO_DEVICE_PROTOCOL *This,\r
133 IN UINT32 Alignment\r
6fb4e772
OM
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
22701a3d
BS
148 IN VIRTIO_DEVICE_PROTOCOL *This,\r
149 IN UINT32 PageSize\r
6fb4e772
OM
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
22701a3d
BS
168 IN VIRTIO_DEVICE_PROTOCOL *This,\r
169 IN UINT16 Sel\r
6fb4e772
OM
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
07af4eee 183 IN VIRTIO_DEVICE_PROTOCOL *This,\r
53a4c604
BS
184 IN VRING *Ring,\r
185 IN UINT64 RingBaseShift\r
6fb4e772
OM
186 )\r
187{\r
188 VIRTIO_MMIO_DEVICE *Device;\r
189\r
53a4c604
BS
190 ASSERT (RingBaseShift == 0);\r
191\r
6fb4e772
OM
192 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
193\r
07af4eee
LE
194 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN,\r
195 (UINT32)((UINTN)Ring->Base >> EFI_PAGE_SHIFT));\r
6fb4e772
OM
196\r
197 return EFI_SUCCESS;\r
198}\r
199\r
200EFI_STATUS\r
201EFIAPI\r
202VirtioMmioSetGuestFeatures (\r
22701a3d
BS
203 IN VIRTIO_DEVICE_PROTOCOL *This,\r
204 IN UINT64 Features\r
6fb4e772
OM
205 )\r
206{\r
207 VIRTIO_MMIO_DEVICE *Device;\r
208\r
209 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
210\r
bc8fde6f
LE
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
6fb4e772
OM
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
084cfc1a
BS
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