]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
OvmfPkg: VIRTIO_DEVICE_PROTOCOL: remove GetQueueAddress() member
[mirror_edk2.git] / OvmfPkg / Library / VirtioMmioDeviceLib / VirtioMmioDeviceFunctions.c
1 /** @file
2
3 This driver produces Virtio Device Protocol instances for Virtio MMIO devices.
4
5 Copyright (C) 2012, Red Hat, Inc.
6 Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
7 Copyright (C) 2013, ARM Ltd.
8
9 This program and the accompanying materials are licensed and made available
10 under the terms and conditions of the BSD License which accompanies this
11 distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
13
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
15 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16
17 **/
18
19 #include "VirtioMmioDevice.h"
20
21 EFI_STATUS
22 EFIAPI
23 VirtioMmioGetDeviceFeatures (
24 IN VIRTIO_DEVICE_PROTOCOL *This,
25 OUT UINT64 *DeviceFeatures
26 )
27 {
28 VIRTIO_MMIO_DEVICE *Device;
29
30 if (DeviceFeatures == NULL) {
31 return EFI_INVALID_PARAMETER;
32 }
33
34 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
35
36 *DeviceFeatures = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_HOST_FEATURES);
37
38 return EFI_SUCCESS;
39 }
40
41 EFI_STATUS
42 EFIAPI
43 VirtioMmioGetQueueSize (
44 IN VIRTIO_DEVICE_PROTOCOL *This,
45 OUT UINT16 *QueueNumMax
46 )
47 {
48 VIRTIO_MMIO_DEVICE *Device;
49
50 if (QueueNumMax == NULL) {
51 return EFI_INVALID_PARAMETER;
52 }
53
54 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
55
56 *QueueNumMax = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM_MAX) & 0xFFFF;
57
58 return EFI_SUCCESS;
59 }
60
61 EFI_STATUS
62 EFIAPI
63 VirtioMmioGetDeviceStatus (
64 IN VIRTIO_DEVICE_PROTOCOL *This,
65 OUT UINT8 *DeviceStatus
66 )
67 {
68 VIRTIO_MMIO_DEVICE *Device;
69
70 if (DeviceStatus == NULL) {
71 return EFI_INVALID_PARAMETER;
72 }
73
74 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
75
76 *DeviceStatus = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_STATUS) & 0xFF;
77
78 return EFI_SUCCESS;
79 }
80
81 EFI_STATUS
82 EFIAPI
83 VirtioMmioSetQueueSize (
84 VIRTIO_DEVICE_PROTOCOL *This,
85 UINT16 QueueSize
86 )
87 {
88 VIRTIO_MMIO_DEVICE *Device;
89
90 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
91
92 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM, QueueSize);
93
94 return EFI_SUCCESS;
95 }
96
97 EFI_STATUS
98 EFIAPI
99 VirtioMmioSetDeviceStatus (
100 VIRTIO_DEVICE_PROTOCOL *This,
101 UINT8 DeviceStatus
102 )
103 {
104 VIRTIO_MMIO_DEVICE *Device;
105
106 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
107
108 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_STATUS, DeviceStatus);
109
110 return EFI_SUCCESS;
111 }
112
113 EFI_STATUS
114 EFIAPI
115 VirtioMmioSetQueueNotify (
116 VIRTIO_DEVICE_PROTOCOL *This,
117 UINT16 QueueNotify
118 )
119 {
120 VIRTIO_MMIO_DEVICE *Device;
121
122 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
123
124 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NOTIFY, QueueNotify);
125
126 return EFI_SUCCESS;
127 }
128
129 EFI_STATUS
130 EFIAPI
131 VirtioMmioSetQueueAlignment (
132 VIRTIO_DEVICE_PROTOCOL *This,
133 UINT32 Alignment
134 )
135 {
136 VIRTIO_MMIO_DEVICE *Device;
137
138 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
139
140 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_ALIGN, Alignment);
141
142 return EFI_SUCCESS;
143 }
144
145 EFI_STATUS
146 EFIAPI
147 VirtioMmioSetPageSize (
148 VIRTIO_DEVICE_PROTOCOL *This,
149 UINT32 PageSize
150 )
151 {
152 VIRTIO_MMIO_DEVICE *Device;
153
154 if (PageSize != EFI_PAGE_SIZE) {
155 return EFI_UNSUPPORTED;
156 }
157
158 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
159
160 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_PAGE_SIZE, PageSize);
161
162 return EFI_SUCCESS;
163 }
164
165 EFI_STATUS
166 EFIAPI
167 VirtioMmioSetQueueSel (
168 VIRTIO_DEVICE_PROTOCOL *This,
169 UINT16 Sel
170 )
171 {
172 VIRTIO_MMIO_DEVICE *Device;
173
174 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
175
176 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_SEL, Sel);
177
178 return EFI_SUCCESS;
179 }
180
181 EFI_STATUS
182 VirtioMmioSetQueueAddress (
183 VIRTIO_DEVICE_PROTOCOL *This,
184 UINT32 Address
185 )
186 {
187 VIRTIO_MMIO_DEVICE *Device;
188
189 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
190
191 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN, Address);
192
193 return EFI_SUCCESS;
194 }
195
196 EFI_STATUS
197 EFIAPI
198 VirtioMmioSetGuestFeatures (
199 VIRTIO_DEVICE_PROTOCOL *This,
200 UINT64 Features
201 )
202 {
203 VIRTIO_MMIO_DEVICE *Device;
204
205 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
206
207 if (Features > MAX_UINT32) {
208 return EFI_UNSUPPORTED;
209 }
210 VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_FEATURES,
211 (UINT32)Features);
212
213 return EFI_SUCCESS;
214 }
215
216 EFI_STATUS
217 EFIAPI
218 VirtioMmioDeviceWrite (
219 IN VIRTIO_DEVICE_PROTOCOL *This,
220 IN UINTN FieldOffset,
221 IN UINTN FieldSize,
222 IN UINT64 Value
223 )
224 {
225 UINTN DstBaseAddress;
226 VIRTIO_MMIO_DEVICE *Device;
227
228 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
229
230 //
231 // Double-check fieldsize
232 //
233 if ((FieldSize != 1) && (FieldSize != 2) &&
234 (FieldSize != 4) && (FieldSize != 8)) {
235 return EFI_INVALID_PARAMETER;
236 }
237
238 //
239 // Compute base address
240 //
241 DstBaseAddress = Device->BaseAddress +
242 VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset;
243
244 //
245 // The device-specific memory area of Virtio-MMIO can only be written in
246 // byte accesses. This is not currently in the Virtio spec.
247 //
248 MmioWriteBuffer8 (DstBaseAddress, FieldSize, (UINT8*)&Value);
249
250 return EFI_SUCCESS;
251 }
252
253 EFI_STATUS
254 EFIAPI
255 VirtioMmioDeviceRead (
256 IN VIRTIO_DEVICE_PROTOCOL *This,
257 IN UINTN FieldOffset,
258 IN UINTN FieldSize,
259 IN UINTN BufferSize,
260 OUT VOID *Buffer
261 )
262 {
263 UINTN SrcBaseAddress;
264 VIRTIO_MMIO_DEVICE *Device;
265
266 Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
267
268 //
269 // Parameter validation
270 //
271 ASSERT (FieldSize == BufferSize);
272
273 //
274 // Double-check fieldsize
275 //
276 if ((FieldSize != 1) && (FieldSize != 2) &&
277 (FieldSize != 4) && (FieldSize != 8)) {
278 return EFI_INVALID_PARAMETER;
279 }
280
281 //
282 // Compute base address
283 //
284 SrcBaseAddress = Device->BaseAddress +
285 VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset;
286
287 //
288 // The device-specific memory area of Virtio-MMIO can only be read in
289 // byte reads. This is not currently in the Virtio spec.
290 //
291 MmioReadBuffer8 (SrcBaseAddress, BufferSize, Buffer);
292
293 return EFI_SUCCESS;
294 }