]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
OvmfPkg/VirtioLib: take VirtIo instance in VirtioRingInit/VirtioRingUninit
[mirror_edk2.git] / OvmfPkg / VirtioPciDeviceDxe / VirtioPciFunctions.c
CommitLineData
3bb56c06
OM
1/** @file\r
2\r
3 This driver produces Virtio Device Protocol instances for Virtio PCI 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
4157b841 8 Copyright (C) 2017, AMD Inc, All rights reserved.<BR>\r
3bb56c06
OM
9\r
10 This program and the accompanying materials are licensed and made available\r
11 under the terms and conditions of the BSD License which accompanies this\r
12 distribution. The full text of the license may be found at\r
13 http://opensource.org/licenses/bsd-license.php\r
14\r
15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
16 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
17\r
18**/\r
19#include <Library/BaseMemoryLib.h>\r
20#include <Library/DebugLib.h>\r
21#include <Library/MemoryAllocationLib.h>\r
22#include <Library/UefiBootServicesTableLib.h>\r
23#include <Library/UefiLib.h>\r
24#include "VirtioPciDevice.h"\r
25\r
26/**\r
27\r
28 Read a word from Region 0 of the device specified by VirtIo Device protocol.\r
29\r
30 The function implements the ReadDevice protocol member of\r
31 VIRTIO_DEVICE_PROTOCOL.\r
32\r
33 @param[in] This VirtIo Device protocol.\r
34\r
35 @param[in] FieldOffset Source offset.\r
36\r
37 @param[in] FieldSize Source field size, must be in { 1, 2, 4, 8 }.\r
38\r
39 @param[in] BufferSize Number of bytes available in the target buffer. Must\r
40 equal FieldSize.\r
41\r
42 @param[out] Buffer Target buffer.\r
43\r
44\r
45 @return Status code returned by PciIo->Io.Read().\r
46\r
47**/\r
48EFI_STATUS\r
49EFIAPI\r
50VirtioPciDeviceRead (\r
51 IN VIRTIO_DEVICE_PROTOCOL *This,\r
52 IN UINTN FieldOffset,\r
53 IN UINTN FieldSize,\r
54 IN UINTN BufferSize,\r
55 OUT VOID *Buffer\r
56 )\r
57{\r
58 VIRTIO_PCI_DEVICE *Dev;\r
59\r
60 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
61\r
62 return VirtioPciIoRead (Dev,\r
63 Dev->DeviceSpecificConfigurationOffset + FieldOffset,\r
64 FieldSize, BufferSize, Buffer);\r
65}\r
66\r
67/**\r
68\r
69 Write a word into Region 0 of the device specified by VirtIo Device protocol.\r
70\r
71 @param[in] This VirtIo Device protocol.\r
72\r
73 @param[in] FieldOffset Destination offset.\r
74\r
75 @param[in] FieldSize Destination field size, must be in { 1, 2, 4, 8 }.\r
76\r
77 @param[in] Value Little endian value to write, converted to UINT64.\r
78 The least significant FieldSize bytes will be used.\r
79\r
80\r
81 @return Status code returned by PciIo->Io.Write().\r
82\r
83**/\r
84EFI_STATUS\r
85EFIAPI\r
86VirtioPciDeviceWrite (\r
87 IN VIRTIO_DEVICE_PROTOCOL *This,\r
88 IN UINTN FieldOffset,\r
89 IN UINTN FieldSize,\r
90 IN UINT64 Value\r
91 )\r
92{\r
93 VIRTIO_PCI_DEVICE *Dev;\r
94\r
95 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
96\r
97 return VirtioPciIoWrite (Dev,\r
98 Dev->DeviceSpecificConfigurationOffset + FieldOffset, FieldSize, Value);\r
99}\r
100\r
101EFI_STATUS\r
102EFIAPI\r
103VirtioPciGetDeviceFeatures (\r
104 IN VIRTIO_DEVICE_PROTOCOL *This,\r
bc8fde6f 105 OUT UINT64 *DeviceFeatures\r
3bb56c06
OM
106 )\r
107{\r
108 VIRTIO_PCI_DEVICE *Dev;\r
bc8fde6f
LE
109 EFI_STATUS Status;\r
110 UINT32 Features32;\r
3bb56c06
OM
111\r
112 if (DeviceFeatures == NULL) {\r
113 return EFI_INVALID_PARAMETER;\r
114 }\r
115\r
116 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
117\r
bc8fde6f
LE
118 Status = VirtioPciIoRead (Dev, VIRTIO_PCI_OFFSET_DEVICE_FEATURES,\r
119 sizeof (UINT32), sizeof (UINT32), &Features32);\r
120 if (!EFI_ERROR (Status)) {\r
121 *DeviceFeatures = Features32;\r
122 }\r
123 return Status;\r
3bb56c06
OM
124}\r
125\r
3bb56c06
OM
126EFI_STATUS\r
127EFIAPI\r
128VirtioPciGetQueueSize (\r
129 IN VIRTIO_DEVICE_PROTOCOL *This,\r
130 OUT UINT16 *QueueNumMax\r
131 )\r
132{\r
133 VIRTIO_PCI_DEVICE *Dev;\r
134\r
135 if (QueueNumMax == NULL) {\r
136 return EFI_INVALID_PARAMETER;\r
137 }\r
138\r
139 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
140\r
141 return VirtioPciIoRead (Dev, VIRTIO_PCI_OFFSET_QUEUE_SIZE, sizeof (UINT16),\r
142 sizeof (UINT16), QueueNumMax);\r
143}\r
144\r
145EFI_STATUS\r
146EFIAPI\r
147VirtioPciGetDeviceStatus (\r
148 IN VIRTIO_DEVICE_PROTOCOL *This,\r
149 OUT UINT8 *DeviceStatus\r
150 )\r
151{\r
152 VIRTIO_PCI_DEVICE *Dev;\r
153\r
154 if (DeviceStatus == NULL) {\r
155 return EFI_INVALID_PARAMETER;\r
156 }\r
157\r
158 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
159\r
160 return VirtioPciIoRead (Dev, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS,\r
161 sizeof (UINT8), sizeof (UINT8), DeviceStatus);\r
162}\r
163\r
164EFI_STATUS\r
165EFIAPI\r
166VirtioPciSetGuestFeatures (\r
167 IN VIRTIO_DEVICE_PROTOCOL *This,\r
bc8fde6f 168 IN UINT64 Features\r
3bb56c06
OM
169 )\r
170{\r
171 VIRTIO_PCI_DEVICE *Dev;\r
172\r
173 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
174\r
bc8fde6f
LE
175 if (Features > MAX_UINT32) {\r
176 return EFI_UNSUPPORTED;\r
177 }\r
3bb56c06
OM
178 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_GUEST_FEATURES,\r
179 sizeof (UINT32), Features);\r
180}\r
181\r
182EFI_STATUS\r
183EFIAPI\r
184VirtioPciSetQueueAddress (\r
07af4eee
LE
185 IN VIRTIO_DEVICE_PROTOCOL *This,\r
186 IN VRING *Ring\r
3bb56c06
OM
187 )\r
188{\r
189 VIRTIO_PCI_DEVICE *Dev;\r
190\r
191 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
192\r
193 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_ADDRESS, sizeof (UINT32),\r
07af4eee 194 (UINT32)((UINTN)Ring->Base >> EFI_PAGE_SHIFT));\r
3bb56c06
OM
195}\r
196\r
197EFI_STATUS\r
198EFIAPI\r
199VirtioPciSetQueueSel (\r
e5251fec
BS
200 IN VIRTIO_DEVICE_PROTOCOL *This,\r
201 IN UINT16 Sel\r
3bb56c06
OM
202 )\r
203{\r
204 VIRTIO_PCI_DEVICE *Dev;\r
205\r
206 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
207\r
208 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_SELECT, sizeof (UINT16),\r
209 Sel);\r
210}\r
211\r
212EFI_STATUS\r
213EFIAPI\r
214VirtioPciSetQueueAlignment (\r
e5251fec
BS
215 IN VIRTIO_DEVICE_PROTOCOL *This,\r
216 IN UINT32 Alignment\r
3bb56c06
OM
217 )\r
218{\r
219 return EFI_SUCCESS;\r
220}\r
221\r
222EFI_STATUS\r
223EFIAPI\r
224VirtioPciSetPageSize (\r
e5251fec
BS
225 IN VIRTIO_DEVICE_PROTOCOL *This,\r
226 IN UINT32 PageSize\r
3bb56c06
OM
227 )\r
228{\r
229 return (PageSize == EFI_PAGE_SIZE) ? EFI_SUCCESS : EFI_UNSUPPORTED;\r
230}\r
231\r
232EFI_STATUS\r
233EFIAPI\r
234VirtioPciSetQueueNotify (\r
e5251fec
BS
235 IN VIRTIO_DEVICE_PROTOCOL *This,\r
236 IN UINT16 Index\r
3bb56c06
OM
237 )\r
238{\r
239 VIRTIO_PCI_DEVICE *Dev;\r
240\r
241 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
242\r
243 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_NOTIFY, sizeof (UINT16),\r
244 Index);\r
245}\r
246\r
247EFI_STATUS\r
248EFIAPI\r
249VirtioPciSetQueueSize (\r
e5251fec
BS
250 IN VIRTIO_DEVICE_PROTOCOL *This,\r
251 IN UINT16 Size\r
3bb56c06
OM
252 )\r
253{\r
254 //\r
255 // This function is only applicable in Virtio-MMIO.\r
256 // (The QueueSize field is read-only in Virtio proper (PCI))\r
257 //\r
258 return EFI_SUCCESS;\r
259}\r
260\r
261EFI_STATUS\r
262EFIAPI\r
263VirtioPciSetDeviceStatus (\r
e5251fec
BS
264 IN VIRTIO_DEVICE_PROTOCOL *This,\r
265 IN UINT8 DeviceStatus\r
3bb56c06
OM
266 )\r
267{\r
268 VIRTIO_PCI_DEVICE *Dev;\r
269\r
270 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
271\r
272 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS,\r
273 sizeof (UINT8), DeviceStatus);\r
274}\r
4157b841
BS
275\r
276EFI_STATUS\r
277EFIAPI\r
278VirtioPciAllocateSharedPages (\r
279 IN VIRTIO_DEVICE_PROTOCOL *This,\r
280 IN UINTN NumPages,\r
281 OUT VOID **HostAddress\r
282 )\r
283{\r
284 VOID *Buffer;\r
285\r
286 Buffer = AllocatePages (NumPages);\r
287 if (Buffer == NULL) {\r
288 return EFI_OUT_OF_RESOURCES;\r
289 }\r
290\r
291 *HostAddress = Buffer;\r
292 return EFI_SUCCESS;\r
293}\r
294\r
295VOID\r
296EFIAPI\r
297VirtioPciFreeSharedPages (\r
298 IN VIRTIO_DEVICE_PROTOCOL *This,\r
299 IN UINTN NumPages,\r
300 IN VOID *HostAddress\r
301 )\r
302{\r
303 FreePages (HostAddress, NumPages);\r
304}\r
305\r
306EFI_STATUS\r
307EFIAPI\r
308VirtioPciMapSharedBuffer (\r
309 IN VIRTIO_DEVICE_PROTOCOL *This,\r
310 IN VIRTIO_MAP_OPERATION Operation,\r
311 IN VOID *HostAddress,\r
312 IN OUT UINTN *NumberOfBytes,\r
313 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
314 OUT VOID **Mapping\r
315 )\r
316{\r
317 *DeviceAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;\r
318 *Mapping = NULL;\r
319\r
320 return EFI_SUCCESS;\r
321}\r
322\r
323EFI_STATUS\r
324EFIAPI\r
325VirtioPciUnmapSharedBuffer (\r
326 IN VIRTIO_DEVICE_PROTOCOL *This,\r
327 IN VOID *Mapping\r
328 )\r
329{\r
330 return EFI_SUCCESS;\r
331}\r