]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions
[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
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#include <Library/BaseMemoryLib.h>\r
19#include <Library/DebugLib.h>\r
20#include <Library/MemoryAllocationLib.h>\r
21#include <Library/UefiBootServicesTableLib.h>\r
22#include <Library/UefiLib.h>\r
23#include "VirtioPciDevice.h"\r
24\r
25/**\r
26\r
27 Read a word from Region 0 of the device specified by VirtIo Device protocol.\r
28\r
29 The function implements the ReadDevice protocol member of\r
30 VIRTIO_DEVICE_PROTOCOL.\r
31\r
32 @param[in] This VirtIo Device protocol.\r
33\r
34 @param[in] FieldOffset Source offset.\r
35\r
36 @param[in] FieldSize Source field size, must be in { 1, 2, 4, 8 }.\r
37\r
38 @param[in] BufferSize Number of bytes available in the target buffer. Must\r
39 equal FieldSize.\r
40\r
41 @param[out] Buffer Target buffer.\r
42\r
43\r
44 @return Status code returned by PciIo->Io.Read().\r
45\r
46**/\r
47EFI_STATUS\r
48EFIAPI\r
49VirtioPciDeviceRead (\r
50 IN VIRTIO_DEVICE_PROTOCOL *This,\r
51 IN UINTN FieldOffset,\r
52 IN UINTN FieldSize,\r
53 IN UINTN BufferSize,\r
54 OUT VOID *Buffer\r
55 )\r
56{\r
57 VIRTIO_PCI_DEVICE *Dev;\r
58\r
59 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
60\r
61 return VirtioPciIoRead (Dev,\r
62 Dev->DeviceSpecificConfigurationOffset + FieldOffset,\r
63 FieldSize, BufferSize, Buffer);\r
64}\r
65\r
66/**\r
67\r
68 Write a word into Region 0 of the device specified by VirtIo Device protocol.\r
69\r
70 @param[in] This VirtIo Device protocol.\r
71\r
72 @param[in] FieldOffset Destination offset.\r
73\r
74 @param[in] FieldSize Destination field size, must be in { 1, 2, 4, 8 }.\r
75\r
76 @param[in] Value Little endian value to write, converted to UINT64.\r
77 The least significant FieldSize bytes will be used.\r
78\r
79\r
80 @return Status code returned by PciIo->Io.Write().\r
81\r
82**/\r
83EFI_STATUS\r
84EFIAPI\r
85VirtioPciDeviceWrite (\r
86 IN VIRTIO_DEVICE_PROTOCOL *This,\r
87 IN UINTN FieldOffset,\r
88 IN UINTN FieldSize,\r
89 IN UINT64 Value\r
90 )\r
91{\r
92 VIRTIO_PCI_DEVICE *Dev;\r
93\r
94 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
95\r
96 return VirtioPciIoWrite (Dev,\r
97 Dev->DeviceSpecificConfigurationOffset + FieldOffset, FieldSize, Value);\r
98}\r
99\r
100EFI_STATUS\r
101EFIAPI\r
102VirtioPciGetDeviceFeatures (\r
103 IN VIRTIO_DEVICE_PROTOCOL *This,\r
bc8fde6f 104 OUT UINT64 *DeviceFeatures\r
3bb56c06
OM
105 )\r
106{\r
107 VIRTIO_PCI_DEVICE *Dev;\r
bc8fde6f
LE
108 EFI_STATUS Status;\r
109 UINT32 Features32;\r
3bb56c06
OM
110\r
111 if (DeviceFeatures == NULL) {\r
112 return EFI_INVALID_PARAMETER;\r
113 }\r
114\r
115 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
116\r
bc8fde6f
LE
117 Status = VirtioPciIoRead (Dev, VIRTIO_PCI_OFFSET_DEVICE_FEATURES,\r
118 sizeof (UINT32), sizeof (UINT32), &Features32);\r
119 if (!EFI_ERROR (Status)) {\r
120 *DeviceFeatures = Features32;\r
121 }\r
122 return Status;\r
3bb56c06
OM
123}\r
124\r
3bb56c06
OM
125EFI_STATUS\r
126EFIAPI\r
127VirtioPciGetQueueSize (\r
128 IN VIRTIO_DEVICE_PROTOCOL *This,\r
129 OUT UINT16 *QueueNumMax\r
130 )\r
131{\r
132 VIRTIO_PCI_DEVICE *Dev;\r
133\r
134 if (QueueNumMax == NULL) {\r
135 return EFI_INVALID_PARAMETER;\r
136 }\r
137\r
138 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
139\r
140 return VirtioPciIoRead (Dev, VIRTIO_PCI_OFFSET_QUEUE_SIZE, sizeof (UINT16),\r
141 sizeof (UINT16), QueueNumMax);\r
142}\r
143\r
144EFI_STATUS\r
145EFIAPI\r
146VirtioPciGetDeviceStatus (\r
147 IN VIRTIO_DEVICE_PROTOCOL *This,\r
148 OUT UINT8 *DeviceStatus\r
149 )\r
150{\r
151 VIRTIO_PCI_DEVICE *Dev;\r
152\r
153 if (DeviceStatus == NULL) {\r
154 return EFI_INVALID_PARAMETER;\r
155 }\r
156\r
157 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
158\r
159 return VirtioPciIoRead (Dev, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS,\r
160 sizeof (UINT8), sizeof (UINT8), DeviceStatus);\r
161}\r
162\r
163EFI_STATUS\r
164EFIAPI\r
165VirtioPciSetGuestFeatures (\r
166 IN VIRTIO_DEVICE_PROTOCOL *This,\r
bc8fde6f 167 IN UINT64 Features\r
3bb56c06
OM
168 )\r
169{\r
170 VIRTIO_PCI_DEVICE *Dev;\r
171\r
172 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
173\r
bc8fde6f
LE
174 if (Features > MAX_UINT32) {\r
175 return EFI_UNSUPPORTED;\r
176 }\r
3bb56c06
OM
177 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_GUEST_FEATURES,\r
178 sizeof (UINT32), Features);\r
179}\r
180\r
181EFI_STATUS\r
182EFIAPI\r
183VirtioPciSetQueueAddress (\r
07af4eee
LE
184 IN VIRTIO_DEVICE_PROTOCOL *This,\r
185 IN VRING *Ring\r
3bb56c06
OM
186 )\r
187{\r
188 VIRTIO_PCI_DEVICE *Dev;\r
189\r
190 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
191\r
192 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_ADDRESS, sizeof (UINT32),\r
07af4eee 193 (UINT32)((UINTN)Ring->Base >> EFI_PAGE_SHIFT));\r
3bb56c06
OM
194}\r
195\r
196EFI_STATUS\r
197EFIAPI\r
198VirtioPciSetQueueSel (\r
e5251fec
BS
199 IN VIRTIO_DEVICE_PROTOCOL *This,\r
200 IN UINT16 Sel\r
3bb56c06
OM
201 )\r
202{\r
203 VIRTIO_PCI_DEVICE *Dev;\r
204\r
205 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
206\r
207 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_SELECT, sizeof (UINT16),\r
208 Sel);\r
209}\r
210\r
211EFI_STATUS\r
212EFIAPI\r
213VirtioPciSetQueueAlignment (\r
e5251fec
BS
214 IN VIRTIO_DEVICE_PROTOCOL *This,\r
215 IN UINT32 Alignment\r
3bb56c06
OM
216 )\r
217{\r
218 return EFI_SUCCESS;\r
219}\r
220\r
221EFI_STATUS\r
222EFIAPI\r
223VirtioPciSetPageSize (\r
e5251fec
BS
224 IN VIRTIO_DEVICE_PROTOCOL *This,\r
225 IN UINT32 PageSize\r
3bb56c06
OM
226 )\r
227{\r
228 return (PageSize == EFI_PAGE_SIZE) ? EFI_SUCCESS : EFI_UNSUPPORTED;\r
229}\r
230\r
231EFI_STATUS\r
232EFIAPI\r
233VirtioPciSetQueueNotify (\r
e5251fec
BS
234 IN VIRTIO_DEVICE_PROTOCOL *This,\r
235 IN UINT16 Index\r
3bb56c06
OM
236 )\r
237{\r
238 VIRTIO_PCI_DEVICE *Dev;\r
239\r
240 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
241\r
242 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_NOTIFY, sizeof (UINT16),\r
243 Index);\r
244}\r
245\r
246EFI_STATUS\r
247EFIAPI\r
248VirtioPciSetQueueSize (\r
e5251fec
BS
249 IN VIRTIO_DEVICE_PROTOCOL *This,\r
250 IN UINT16 Size\r
3bb56c06
OM
251 )\r
252{\r
253 //\r
254 // This function is only applicable in Virtio-MMIO.\r
255 // (The QueueSize field is read-only in Virtio proper (PCI))\r
256 //\r
257 return EFI_SUCCESS;\r
258}\r
259\r
260EFI_STATUS\r
261EFIAPI\r
262VirtioPciSetDeviceStatus (\r
e5251fec
BS
263 IN VIRTIO_DEVICE_PROTOCOL *This,\r
264 IN UINT8 DeviceStatus\r
3bb56c06
OM
265 )\r
266{\r
267 VIRTIO_PCI_DEVICE *Dev;\r
268\r
269 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
270\r
271 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS,\r
272 sizeof (UINT8), DeviceStatus);\r
273}\r