]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
OvmfPkg: VIRTIO_DEVICE_PROTOCOL: widen the Features bitmap to 64 bits
[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
125EFI_STATUS\r
126EFIAPI\r
127VirtioPciGetQueueAddress (\r
128 IN VIRTIO_DEVICE_PROTOCOL *This,\r
129 OUT UINT32 *QueueAddress\r
130 )\r
131{\r
132 VIRTIO_PCI_DEVICE *Dev;\r
133\r
134 if (QueueAddress == 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_ADDRESS, sizeof (UINT32),\r
141 sizeof (UINT32), QueueAddress);\r
142}\r
143\r
144EFI_STATUS\r
145EFIAPI\r
146VirtioPciGetQueueSize (\r
147 IN VIRTIO_DEVICE_PROTOCOL *This,\r
148 OUT UINT16 *QueueNumMax\r
149 )\r
150{\r
151 VIRTIO_PCI_DEVICE *Dev;\r
152\r
153 if (QueueNumMax == 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_SIZE, sizeof (UINT16),\r
160 sizeof (UINT16), QueueNumMax);\r
161}\r
162\r
163EFI_STATUS\r
164EFIAPI\r
165VirtioPciGetDeviceStatus (\r
166 IN VIRTIO_DEVICE_PROTOCOL *This,\r
167 OUT UINT8 *DeviceStatus\r
168 )\r
169{\r
170 VIRTIO_PCI_DEVICE *Dev;\r
171\r
172 if (DeviceStatus == NULL) {\r
173 return EFI_INVALID_PARAMETER;\r
174 }\r
175\r
176 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
177\r
178 return VirtioPciIoRead (Dev, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS,\r
179 sizeof (UINT8), sizeof (UINT8), DeviceStatus);\r
180}\r
181\r
182EFI_STATUS\r
183EFIAPI\r
184VirtioPciSetGuestFeatures (\r
185 IN VIRTIO_DEVICE_PROTOCOL *This,\r
bc8fde6f 186 IN UINT64 Features\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
bc8fde6f
LE
193 if (Features > MAX_UINT32) {\r
194 return EFI_UNSUPPORTED;\r
195 }\r
3bb56c06
OM
196 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_GUEST_FEATURES,\r
197 sizeof (UINT32), Features);\r
198}\r
199\r
200EFI_STATUS\r
201EFIAPI\r
202VirtioPciSetQueueAddress (\r
203 VIRTIO_DEVICE_PROTOCOL *This,\r
204 UINT32 Address\r
205 )\r
206{\r
207 VIRTIO_PCI_DEVICE *Dev;\r
208\r
209 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
210\r
211 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_ADDRESS, sizeof (UINT32),\r
212 Address);\r
213}\r
214\r
215EFI_STATUS\r
216EFIAPI\r
217VirtioPciSetQueueSel (\r
218 VIRTIO_DEVICE_PROTOCOL *This,\r
219 UINT16 Sel\r
220 )\r
221{\r
222 VIRTIO_PCI_DEVICE *Dev;\r
223\r
224 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
225\r
226 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_SELECT, sizeof (UINT16),\r
227 Sel);\r
228}\r
229\r
230EFI_STATUS\r
231EFIAPI\r
232VirtioPciSetQueueAlignment (\r
233 VIRTIO_DEVICE_PROTOCOL *This,\r
234 UINT32 Alignment\r
235 )\r
236{\r
237 return EFI_SUCCESS;\r
238}\r
239\r
240EFI_STATUS\r
241EFIAPI\r
242VirtioPciSetPageSize (\r
243 VIRTIO_DEVICE_PROTOCOL *This,\r
244 UINT32 PageSize\r
245 )\r
246{\r
247 return (PageSize == EFI_PAGE_SIZE) ? EFI_SUCCESS : EFI_UNSUPPORTED;\r
248}\r
249\r
250EFI_STATUS\r
251EFIAPI\r
252VirtioPciSetQueueNotify (\r
253 VIRTIO_DEVICE_PROTOCOL *This,\r
254 UINT16 Index\r
255 )\r
256{\r
257 VIRTIO_PCI_DEVICE *Dev;\r
258\r
259 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
260\r
261 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_NOTIFY, sizeof (UINT16),\r
262 Index);\r
263}\r
264\r
265EFI_STATUS\r
266EFIAPI\r
267VirtioPciSetQueueSize (\r
268 VIRTIO_DEVICE_PROTOCOL *This,\r
269 UINT16 Size\r
270 )\r
271{\r
272 //\r
273 // This function is only applicable in Virtio-MMIO.\r
274 // (The QueueSize field is read-only in Virtio proper (PCI))\r
275 //\r
276 return EFI_SUCCESS;\r
277}\r
278\r
279EFI_STATUS\r
280EFIAPI\r
281VirtioPciSetDeviceStatus (\r
282 VIRTIO_DEVICE_PROTOCOL *This,\r
283 UINT8 DeviceStatus\r
284 )\r
285{\r
286 VIRTIO_PCI_DEVICE *Dev;\r
287\r
288 Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);\r
289\r
290 return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS,\r
291 sizeof (UINT8), DeviceStatus);\r
292}\r