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