]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
OvmfPkg/VirtioPciDeviceDxe: add missing IN and OUT decoration
[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
84 VIRTIO_DEVICE_PROTOCOL *This,\r
85 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 VIRTIO_DEVICE_PROTOCOL *This,\r
101 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 VIRTIO_DEVICE_PROTOCOL *This,\r
117 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 VIRTIO_DEVICE_PROTOCOL *This,\r
133 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 VIRTIO_DEVICE_PROTOCOL *This,\r
149 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 VIRTIO_DEVICE_PROTOCOL *This,\r
169 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
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
200 VIRTIO_DEVICE_PROTOCOL *This,\r
bc8fde6f 201 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