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