]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
OvmfPkg/VirtioLib: take VirtIo instance in VirtioRingInit/VirtioRingUninit
[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
LE
183 IN VIRTIO_DEVICE_PROTOCOL *This,\r
184 IN VRING *Ring\r
6fb4e772
OM
185 )\r
186{\r
187 VIRTIO_MMIO_DEVICE *Device;\r
188\r
189 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
190\r
07af4eee
LE
191 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN,\r
192 (UINT32)((UINTN)Ring->Base >> EFI_PAGE_SHIFT));\r
6fb4e772
OM
193\r
194 return EFI_SUCCESS;\r
195}\r
196\r
197EFI_STATUS\r
198EFIAPI\r
199VirtioMmioSetGuestFeatures (\r
22701a3d
BS
200 IN VIRTIO_DEVICE_PROTOCOL *This,\r
201 IN UINT64 Features\r
6fb4e772
OM
202 )\r
203{\r
204 VIRTIO_MMIO_DEVICE *Device;\r
205\r
206 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
207\r
bc8fde6f
LE
208 if (Features > MAX_UINT32) {\r
209 return EFI_UNSUPPORTED;\r
210 }\r
211 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_FEATURES,\r
212 (UINT32)Features);\r
6fb4e772
OM
213\r
214 return EFI_SUCCESS;\r
215}\r
216\r
217EFI_STATUS\r
218EFIAPI\r
219VirtioMmioDeviceWrite (\r
220 IN VIRTIO_DEVICE_PROTOCOL *This,\r
221 IN UINTN FieldOffset,\r
222 IN UINTN FieldSize,\r
223 IN UINT64 Value\r
224 )\r
225{\r
226 UINTN DstBaseAddress;\r
227 VIRTIO_MMIO_DEVICE *Device;\r
228\r
229 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
230\r
231 //\r
232 // Double-check fieldsize\r
233 //\r
234 if ((FieldSize != 1) && (FieldSize != 2) &&\r
235 (FieldSize != 4) && (FieldSize != 8)) {\r
236 return EFI_INVALID_PARAMETER;\r
237 }\r
238\r
239 //\r
240 // Compute base address\r
241 //\r
242 DstBaseAddress = Device->BaseAddress +\r
243 VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset;\r
244\r
245 //\r
246 // The device-specific memory area of Virtio-MMIO can only be written in\r
247 // byte accesses. This is not currently in the Virtio spec.\r
248 //\r
249 MmioWriteBuffer8 (DstBaseAddress, FieldSize, (UINT8*)&Value);\r
250\r
251 return EFI_SUCCESS;\r
252}\r
253\r
254EFI_STATUS\r
255EFIAPI\r
256VirtioMmioDeviceRead (\r
257 IN VIRTIO_DEVICE_PROTOCOL *This,\r
258 IN UINTN FieldOffset,\r
259 IN UINTN FieldSize,\r
260 IN UINTN BufferSize,\r
261 OUT VOID *Buffer\r
262 )\r
263{\r
264 UINTN SrcBaseAddress;\r
265 VIRTIO_MMIO_DEVICE *Device;\r
266\r
267 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
268\r
269 //\r
270 // Parameter validation\r
271 //\r
272 ASSERT (FieldSize == BufferSize);\r
273\r
274 //\r
275 // Double-check fieldsize\r
276 //\r
277 if ((FieldSize != 1) && (FieldSize != 2) &&\r
278 (FieldSize != 4) && (FieldSize != 8)) {\r
279 return EFI_INVALID_PARAMETER;\r
280 }\r
281\r
282 //\r
283 // Compute base address\r
284 //\r
285 SrcBaseAddress = Device->BaseAddress +\r
286 VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset;\r
287\r
288 //\r
289 // The device-specific memory area of Virtio-MMIO can only be read in\r
290 // byte reads. This is not currently in the Virtio spec.\r
291 //\r
292 MmioReadBuffer8 (SrcBaseAddress, BufferSize, Buffer);\r
293\r
294 return EFI_SUCCESS;\r
295}\r
084cfc1a
BS
296\r
297EFI_STATUS\r
298EFIAPI\r
299VirtioMmioAllocateSharedPages (\r
300 IN VIRTIO_DEVICE_PROTOCOL *This,\r
301 IN UINTN NumPages,\r
302 OUT VOID **HostAddress\r
303 )\r
304{\r
305 VOID *Buffer;\r
306\r
307 Buffer = AllocatePages (NumPages);\r
308 if (Buffer == NULL) {\r
309 return EFI_OUT_OF_RESOURCES;\r
310 }\r
311\r
312 *HostAddress = Buffer;\r
313 return EFI_SUCCESS;\r
314}\r
315\r
316VOID\r
317EFIAPI\r
318VirtioMmioFreeSharedPages (\r
319 IN VIRTIO_DEVICE_PROTOCOL *This,\r
320 IN UINTN NumPages,\r
321 IN VOID *HostAddress\r
322 )\r
323{\r
324 FreePages (HostAddress, NumPages);\r
325}\r
326\r
327EFI_STATUS\r
328EFIAPI\r
329VirtioMmioMapSharedBuffer (\r
330 IN VIRTIO_DEVICE_PROTOCOL *This,\r
331 IN VIRTIO_MAP_OPERATION Operation,\r
332 IN VOID *HostAddress,\r
333 IN OUT UINTN *NumberOfBytes,\r
334 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
335 OUT VOID **Mapping\r
336 )\r
337{\r
338 *DeviceAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;\r
339 *Mapping = NULL;\r
340\r
341 return EFI_SUCCESS;\r
342}\r
343\r
344EFI_STATUS\r
345EFIAPI\r
346VirtioMmioUnmapSharedBuffer (\r
347 IN VIRTIO_DEVICE_PROTOCOL *This,\r
348 IN VOID *Mapping\r
349 )\r
350{\r
351 return EFI_SUCCESS;\r
352}\r