]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
OvmfPkg: QemuFwCfgLib: introduce InternalQemuFwCfgIsAvailable()
[mirror_edk2.git] / OvmfPkg / Library / QemuFwCfgLib / QemuFwCfgLib.c
1 /** @file
2
3 Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
4 Copyright (C) 2013, Red Hat, Inc.
5
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "Uefi.h"
17 #include <Library/BaseLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/IoLib.h>
21 #include <Library/QemuFwCfgLib.h>
22 #include <Library/MemoryAllocationLib.h>
23 #include <Library/UefiBootServicesTableLib.h>
24
25 STATIC BOOLEAN mQemuFwCfgSupported = FALSE;
26
27
28 /**
29 Reads an 8-bit I/O port fifo into a block of memory.
30
31 Reads the 8-bit I/O fifo port specified by Port.
32
33 The port is read Count times, and the read data is
34 stored in the provided Buffer.
35
36 This function must guarantee that all I/O read and write operations are
37 serialized.
38
39 If 8-bit I/O port operations are not supported, then ASSERT().
40
41 @param Port The I/O port to read.
42 @param Count The number of times to read I/O port.
43 @param Buffer The buffer to store the read data into.
44
45 **/
46 VOID
47 EFIAPI
48 IoReadFifo8 (
49 IN UINTN Port,
50 IN UINTN Count,
51 OUT VOID *Buffer
52 );
53
54 /**
55 Writes an 8-bit I/O port fifo from a block of memory.
56
57 Writes the 8-bit I/O fifo port specified by Port.
58
59 The port is written Count times, and the data are obtained
60 from the provided Buffer.
61
62 This function must guarantee that all I/O read and write operations are
63 serialized.
64
65 If 8-bit I/O port operations are not supported, then ASSERT().
66
67 @param Port The I/O port to read.
68 @param Count The number of times to read I/O port.
69 @param Buffer The buffer to store the read data into.
70
71 **/
72 VOID
73 EFIAPI
74 IoWriteFifo8 (
75 IN UINTN Port,
76 IN UINTN Count,
77 OUT VOID *Buffer
78 );
79
80
81 /**
82 Returns a boolean indicating if the firmware configuration interface
83 is available or not.
84
85 This function may change fw_cfg state.
86
87 @retval TRUE The interface is available
88 @retval FALSE The interface is not available
89
90 **/
91 BOOLEAN
92 EFIAPI
93 QemuFwCfgIsAvailable (
94 VOID
95 )
96 {
97 return InternalQemuFwCfgIsAvailable ();
98 }
99
100
101 /**
102 Selects a firmware configuration item for reading.
103
104 Following this call, any data read from this item will start from
105 the beginning of the configuration item's data.
106
107 @param[in] QemuFwCfgItem - Firmware Configuration item to read
108
109 **/
110 VOID
111 EFIAPI
112 QemuFwCfgSelectItem (
113 IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem
114 )
115 {
116 DEBUG ((EFI_D_INFO, "Select Item: 0x%x\n", (UINT16)(UINTN) QemuFwCfgItem));
117 IoWrite16 (0x510, (UINT16)(UINTN) QemuFwCfgItem);
118 }
119
120
121 /**
122 Reads firmware configuration bytes into a buffer
123
124 @param[in] Size - Size in bytes to read
125 @param[in] Buffer - Buffer to store data into (OPTIONAL if Size is 0)
126
127 **/
128 VOID
129 EFIAPI
130 InternalQemuFwCfgReadBytes (
131 IN UINTN Size,
132 IN VOID *Buffer OPTIONAL
133 )
134 {
135 IoReadFifo8 (0x511, Size, Buffer);
136 }
137
138
139 /**
140 Reads firmware configuration bytes into a buffer
141
142 If called multiple times, then the data read will
143 continue at the offset of the firmware configuration
144 item where the previous read ended.
145
146 @param[in] Size - Size in bytes to read
147 @param[in] Buffer - Buffer to store data into
148
149 **/
150 VOID
151 EFIAPI
152 QemuFwCfgReadBytes (
153 IN UINTN Size,
154 IN VOID *Buffer
155 )
156 {
157 if (InternalQemuFwCfgIsAvailable ()) {
158 InternalQemuFwCfgReadBytes (Size, Buffer);
159 } else {
160 ZeroMem (Buffer, Size);
161 }
162 }
163
164 /**
165 Write firmware configuration bytes from a buffer
166
167 If called multiple times, then the data written will
168 continue at the offset of the firmware configuration
169 item where the previous write ended.
170
171 @param[in] Size - Size in bytes to write
172 @param[in] Buffer - Buffer to read data from
173
174 **/
175 VOID
176 EFIAPI
177 QemuFwCfgWriteBytes (
178 IN UINTN Size,
179 IN VOID *Buffer
180 )
181 {
182 if (InternalQemuFwCfgIsAvailable ()) {
183 IoWriteFifo8 (0x511, Size, Buffer);
184 }
185 }
186
187
188 /**
189 Reads a UINT8 firmware configuration value
190
191 @return Value of Firmware Configuration item read
192
193 **/
194 UINT8
195 EFIAPI
196 QemuFwCfgRead8 (
197 VOID
198 )
199 {
200 UINT8 Result;
201
202 QemuFwCfgReadBytes (sizeof (Result), &Result);
203
204 return Result;
205 }
206
207
208 /**
209 Reads a UINT16 firmware configuration value
210
211 @return Value of Firmware Configuration item read
212
213 **/
214 UINT16
215 EFIAPI
216 QemuFwCfgRead16 (
217 VOID
218 )
219 {
220 UINT16 Result;
221
222 QemuFwCfgReadBytes (sizeof (Result), &Result);
223
224 return Result;
225 }
226
227
228 /**
229 Reads a UINT32 firmware configuration value
230
231 @return Value of Firmware Configuration item read
232
233 **/
234 UINT32
235 EFIAPI
236 QemuFwCfgRead32 (
237 VOID
238 )
239 {
240 UINT32 Result;
241
242 QemuFwCfgReadBytes (sizeof (Result), &Result);
243
244 return Result;
245 }
246
247
248 /**
249 Reads a UINT64 firmware configuration value
250
251 @return Value of Firmware Configuration item read
252
253 **/
254 UINT64
255 EFIAPI
256 QemuFwCfgRead64 (
257 VOID
258 )
259 {
260 UINT64 Result;
261
262 QemuFwCfgReadBytes (sizeof (Result), &Result);
263
264 return Result;
265 }
266
267
268 RETURN_STATUS
269 EFIAPI
270 QemuFwCfgInitialize (
271 VOID
272 )
273 {
274 UINT32 Signature;
275 UINT32 Revision;
276
277 //
278 // Enable the access routines while probing to see if it is supported.
279 //
280 mQemuFwCfgSupported = TRUE;
281
282 QemuFwCfgSelectItem (QemuFwCfgItemSignature);
283 Signature = QemuFwCfgRead32 ();
284 DEBUG ((EFI_D_INFO, "FW CFG Signature: 0x%x\n", Signature));
285 QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);
286 Revision = QemuFwCfgRead32 ();
287 DEBUG ((EFI_D_INFO, "FW CFG Revision: 0x%x\n", Revision));
288 if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) ||
289 (Revision < 1)
290 ) {
291 DEBUG ((EFI_D_INFO, "QemuFwCfg interface not supported.\n"));
292 mQemuFwCfgSupported = FALSE;
293 return RETURN_SUCCESS;
294 }
295
296 DEBUG ((EFI_D_INFO, "QemuFwCfg interface is supported.\n"));
297 return RETURN_SUCCESS;
298 }
299
300
301 /**
302 Find the configuration item corresponding to the firmware configuration file.
303
304 @param[in] Name - Name of file to look up.
305 @param[out] Item - Configuration item corresponding to the file, to be passed
306 to QemuFwCfgSelectItem ().
307 @param[out] Size - Number of bytes in the file.
308
309 @return RETURN_SUCCESS If file is found.
310 RETURN_NOT_FOUND If file is not found.
311 RETURN_UNSUPPORTED If firmware configuration is unavailable.
312
313 **/
314 RETURN_STATUS
315 EFIAPI
316 QemuFwCfgFindFile (
317 IN CONST CHAR8 *Name,
318 OUT FIRMWARE_CONFIG_ITEM *Item,
319 OUT UINTN *Size
320 )
321 {
322 UINT32 Count;
323 UINT32 Idx;
324
325 if (!InternalQemuFwCfgIsAvailable ()) {
326 return RETURN_UNSUPPORTED;
327 }
328
329 QemuFwCfgSelectItem (QemuFwCfgItemFileDir);
330 Count = SwapBytes32 (QemuFwCfgRead32 ());
331
332 for (Idx = 0; Idx < Count; ++Idx) {
333 UINT32 FileSize;
334 UINT16 FileSelect;
335 UINT16 FileReserved;
336 CHAR8 FName[56];
337
338 FileSize = QemuFwCfgRead32 ();
339 FileSelect = QemuFwCfgRead16 ();
340 FileReserved = QemuFwCfgRead16 ();
341 InternalQemuFwCfgReadBytes (sizeof (FName), FName);
342
343 if (AsciiStrCmp (Name, FName) == 0) {
344 *Item = SwapBytes16 (FileSelect);
345 *Size = SwapBytes32 (FileSize);
346 return RETURN_SUCCESS;
347 }
348 }
349
350 return RETURN_NOT_FOUND;
351 }
352
353
354 /**
355 Returns a boolean indicating if the firmware configuration interface is
356 available for library-internal purposes.
357
358 This function never changes fw_cfg state.
359
360 @retval TRUE The interface is available internally.
361 @retval FALSE The interface is not available internally.
362 **/
363 BOOLEAN
364 EFIAPI
365 InternalQemuFwCfgIsAvailable (
366 VOID
367 )
368 {
369 return mQemuFwCfgSupported;
370 }