]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
OvmfPkg/VirtioMmioDeviceLib: virtio 1.0: Fix SetPageSize.
[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
212a2b9b
GH
154 if (Device->Version == VIRTIO_MMIO_DEVICE_VERSION_0_95) {\r
155 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_PAGE_SIZE, PageSize);\r
156 }\r
6fb4e772
OM
157\r
158 return EFI_SUCCESS;\r
159}\r
160\r
161EFI_STATUS\r
162EFIAPI\r
163VirtioMmioSetQueueSel (\r
22701a3d
BS
164 IN VIRTIO_DEVICE_PROTOCOL *This,\r
165 IN UINT16 Sel\r
6fb4e772
OM
166 )\r
167{\r
168 VIRTIO_MMIO_DEVICE *Device;\r
169\r
170 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
171\r
172 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_SEL, Sel);\r
173\r
174 return EFI_SUCCESS;\r
175}\r
176\r
177EFI_STATUS\r
75e9154f 178EFIAPI\r
6fb4e772 179VirtioMmioSetQueueAddress (\r
07af4eee 180 IN VIRTIO_DEVICE_PROTOCOL *This,\r
53a4c604
BS
181 IN VRING *Ring,\r
182 IN UINT64 RingBaseShift\r
6fb4e772
OM
183 )\r
184{\r
185 VIRTIO_MMIO_DEVICE *Device;\r
186\r
53a4c604
BS
187 ASSERT (RingBaseShift == 0);\r
188\r
6fb4e772
OM
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