]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
OvmfPkg: VIRTIO_DEVICE_PROTOCOL: widen the Features bitmap to 64 bits
[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
41EFI_STATUS\r
42EFIAPI\r
43VirtioMmioGetQueueAddress (\r
44 IN VIRTIO_DEVICE_PROTOCOL *This,\r
45 OUT UINT32 *QueueAddress\r
46 )\r
47{\r
48 VIRTIO_MMIO_DEVICE *Device;\r
49\r
50 if (QueueAddress == 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 *QueueAddress = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN);\r
57\r
58 return EFI_SUCCESS;\r
59}\r
60\r
61EFI_STATUS\r
62EFIAPI\r
63VirtioMmioGetQueueSize (\r
64 IN VIRTIO_DEVICE_PROTOCOL *This,\r
65 OUT UINT16 *QueueNumMax\r
66 )\r
67{\r
68 VIRTIO_MMIO_DEVICE *Device;\r
69\r
70 if (QueueNumMax == 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 *QueueNumMax = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM_MAX) & 0xFFFF;\r
77\r
78 return EFI_SUCCESS;\r
79}\r
80\r
81EFI_STATUS\r
82EFIAPI\r
83VirtioMmioGetDeviceStatus (\r
84 IN VIRTIO_DEVICE_PROTOCOL *This,\r
85 OUT UINT8 *DeviceStatus\r
86 )\r
87{\r
88 VIRTIO_MMIO_DEVICE *Device;\r
89\r
90 if (DeviceStatus == NULL) {\r
91 return EFI_INVALID_PARAMETER;\r
92 }\r
93\r
94 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
95\r
96 *DeviceStatus = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_STATUS) & 0xFF;\r
97\r
98 return EFI_SUCCESS;\r
99}\r
100\r
101EFI_STATUS\r
102EFIAPI\r
103VirtioMmioSetQueueSize (\r
104 VIRTIO_DEVICE_PROTOCOL *This,\r
105 UINT16 QueueSize\r
106 )\r
107{\r
108 VIRTIO_MMIO_DEVICE *Device;\r
109\r
110 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
111\r
112 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM, QueueSize);\r
113\r
114 return EFI_SUCCESS;\r
115}\r
116\r
117EFI_STATUS\r
118EFIAPI\r
119VirtioMmioSetDeviceStatus (\r
120 VIRTIO_DEVICE_PROTOCOL *This,\r
121 UINT8 DeviceStatus\r
122 )\r
123{\r
124 VIRTIO_MMIO_DEVICE *Device;\r
125\r
126 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
127\r
128 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_STATUS, DeviceStatus);\r
129\r
130 return EFI_SUCCESS;\r
131}\r
132\r
133EFI_STATUS\r
134EFIAPI\r
135VirtioMmioSetQueueNotify (\r
136 VIRTIO_DEVICE_PROTOCOL *This,\r
137 UINT16 QueueNotify\r
138 )\r
139{\r
140 VIRTIO_MMIO_DEVICE *Device;\r
141\r
142 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
143\r
144 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NOTIFY, QueueNotify);\r
145\r
146 return EFI_SUCCESS;\r
147}\r
148\r
149EFI_STATUS\r
150EFIAPI\r
151VirtioMmioSetQueueAlignment (\r
152 VIRTIO_DEVICE_PROTOCOL *This,\r
153 UINT32 Alignment\r
154 )\r
155{\r
156 VIRTIO_MMIO_DEVICE *Device;\r
157\r
158 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
159\r
160 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_ALIGN, Alignment);\r
161\r
162 return EFI_SUCCESS;\r
163}\r
164\r
165EFI_STATUS\r
166EFIAPI\r
167VirtioMmioSetPageSize (\r
168 VIRTIO_DEVICE_PROTOCOL *This,\r
169 UINT32 PageSize\r
170 )\r
171{\r
172 VIRTIO_MMIO_DEVICE *Device;\r
173\r
174 if (PageSize != EFI_PAGE_SIZE) {\r
175 return EFI_UNSUPPORTED;\r
176 }\r
177\r
178 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
179\r
180 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_PAGE_SIZE, PageSize);\r
181\r
182 return EFI_SUCCESS;\r
183}\r
184\r
185EFI_STATUS\r
186EFIAPI\r
187VirtioMmioSetQueueSel (\r
188 VIRTIO_DEVICE_PROTOCOL *This,\r
189 UINT16 Sel\r
190 )\r
191{\r
192 VIRTIO_MMIO_DEVICE *Device;\r
193\r
194 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
195\r
196 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_SEL, Sel);\r
197\r
198 return EFI_SUCCESS;\r
199}\r
200\r
201EFI_STATUS\r
202VirtioMmioSetQueueAddress (\r
203 VIRTIO_DEVICE_PROTOCOL *This,\r
204 UINT32 Address\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 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN, Address);\r
212\r
213 return EFI_SUCCESS;\r
214}\r
215\r
216EFI_STATUS\r
217EFIAPI\r
218VirtioMmioSetGuestFeatures (\r
219 VIRTIO_DEVICE_PROTOCOL *This,\r
bc8fde6f 220 UINT64 Features\r
6fb4e772
OM
221 )\r
222{\r
223 VIRTIO_MMIO_DEVICE *Device;\r
224\r
225 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
226\r
bc8fde6f
LE
227 if (Features > MAX_UINT32) {\r
228 return EFI_UNSUPPORTED;\r
229 }\r
230 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_FEATURES,\r
231 (UINT32)Features);\r
6fb4e772
OM
232\r
233 return EFI_SUCCESS;\r
234}\r
235\r
236EFI_STATUS\r
237EFIAPI\r
238VirtioMmioDeviceWrite (\r
239 IN VIRTIO_DEVICE_PROTOCOL *This,\r
240 IN UINTN FieldOffset,\r
241 IN UINTN FieldSize,\r
242 IN UINT64 Value\r
243 )\r
244{\r
245 UINTN DstBaseAddress;\r
246 VIRTIO_MMIO_DEVICE *Device;\r
247\r
248 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
249\r
250 //\r
251 // Double-check fieldsize\r
252 //\r
253 if ((FieldSize != 1) && (FieldSize != 2) &&\r
254 (FieldSize != 4) && (FieldSize != 8)) {\r
255 return EFI_INVALID_PARAMETER;\r
256 }\r
257\r
258 //\r
259 // Compute base address\r
260 //\r
261 DstBaseAddress = Device->BaseAddress +\r
262 VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset;\r
263\r
264 //\r
265 // The device-specific memory area of Virtio-MMIO can only be written in\r
266 // byte accesses. This is not currently in the Virtio spec.\r
267 //\r
268 MmioWriteBuffer8 (DstBaseAddress, FieldSize, (UINT8*)&Value);\r
269\r
270 return EFI_SUCCESS;\r
271}\r
272\r
273EFI_STATUS\r
274EFIAPI\r
275VirtioMmioDeviceRead (\r
276 IN VIRTIO_DEVICE_PROTOCOL *This,\r
277 IN UINTN FieldOffset,\r
278 IN UINTN FieldSize,\r
279 IN UINTN BufferSize,\r
280 OUT VOID *Buffer\r
281 )\r
282{\r
283 UINTN SrcBaseAddress;\r
284 VIRTIO_MMIO_DEVICE *Device;\r
285\r
286 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);\r
287\r
288 //\r
289 // Parameter validation\r
290 //\r
291 ASSERT (FieldSize == BufferSize);\r
292\r
293 //\r
294 // Double-check fieldsize\r
295 //\r
296 if ((FieldSize != 1) && (FieldSize != 2) &&\r
297 (FieldSize != 4) && (FieldSize != 8)) {\r
298 return EFI_INVALID_PARAMETER;\r
299 }\r
300\r
301 //\r
302 // Compute base address\r
303 //\r
304 SrcBaseAddress = Device->BaseAddress +\r
305 VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset;\r
306\r
307 //\r
308 // The device-specific memory area of Virtio-MMIO can only be read in\r
309 // byte reads. This is not currently in the Virtio spec.\r
310 //\r
311 MmioReadBuffer8 (SrcBaseAddress, BufferSize, Buffer);\r
312\r
313 return EFI_SUCCESS;\r
314}\r