]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
OvmfPkg QemuFwCfgLib: Fix broken IA32 Microsoft assembler code
[mirror_edk2.git] / OvmfPkg / Library / QemuFwCfgLib / QemuFwCfgLib.c
CommitLineData
f1ec65ba 1/** @file\r
2\r
3 Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>\r
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
53\r
54/**\r
55 Returns a boolean indicating if the firmware configuration interface\r
56 is available or not.\r
57\r
58 @retval TRUE The interface is available\r
59 @retval FALSE The interface is not available\r
60\r
61**/\r
62BOOLEAN\r
63EFIAPI\r
64QemuFwCfgIsAvailable (\r
65 VOID\r
66 )\r
67{\r
68 return mQemuFwCfgSupported;\r
69}\r
70\r
71\r
72/**\r
73 Selects a firmware configuration item for reading.\r
74 \r
75 Following this call, any data read from this item will start from\r
76 the beginning of the configuration item's data.\r
77\r
78 @param[in] QemuFwCfgItem - Firmware Configuration item to read\r
79\r
80**/\r
81VOID\r
82EFIAPI\r
83QemuFwCfgSelectItem (\r
84 IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem\r
85 )\r
86{\r
87 DEBUG ((EFI_D_INFO, "Select Item: 0x%x\n", (UINT16)(UINTN) QemuFwCfgItem));\r
88 IoWrite16 (0x510, (UINT16)(UINTN) QemuFwCfgItem);\r
89}\r
90\r
91\r
92/**\r
93 Reads firmware configuration bytes into a buffer\r
94\r
95 @param[in] Size - Size in bytes to read\r
96 @param[in] Buffer - Buffer to store data into (OPTIONAL if Size is 0)\r
97\r
98**/\r
99VOID\r
100EFIAPI\r
101InternalQemuFwCfgReadBytes (\r
102 IN UINTN Size,\r
103 IN VOID *Buffer OPTIONAL\r
104 )\r
105{\r
106 IoReadFifo8 (0x511, Size, Buffer);\r
107}\r
108\r
109\r
110/**\r
111 Reads firmware configuration bytes into a buffer\r
112\r
113 If called multiple times, then the data read will\r
114 continue at the offset of the firmware configuration\r
115 item where the previous read ended.\r
116\r
117 @param[in] Size - Size in bytes to read\r
118 @param[in] Buffer - Buffer to store data into\r
119\r
120**/\r
121VOID\r
122EFIAPI\r
123QemuFwCfgReadBytes (\r
124 IN UINTN Size,\r
125 IN VOID *Buffer\r
126 )\r
127{\r
128 if (mQemuFwCfgSupported) {\r
129 InternalQemuFwCfgReadBytes (Size, Buffer);\r
130 } else {\r
131 ZeroMem (Buffer, Size);\r
132 }\r
133}\r
134\r
135\r
136/**\r
137 Reads a UINT8 firmware configuration value\r
138\r
139 @return Value of Firmware Configuration item read\r
140\r
141**/\r
142UINT8\r
143EFIAPI\r
144QemuFwCfgRead8 (\r
145 VOID\r
146 )\r
147{\r
148 UINT8 Result;\r
149\r
150 QemuFwCfgReadBytes (sizeof (Result), &Result);\r
151\r
152 return Result;\r
153}\r
154\r
155\r
156/**\r
157 Reads a UINT16 firmware configuration value\r
158\r
159 @return Value of Firmware Configuration item read\r
160\r
161**/\r
162UINT16\r
163EFIAPI\r
164QemuFwCfgRead16 (\r
165 VOID\r
166 )\r
167{\r
168 UINT16 Result;\r
169\r
170 QemuFwCfgReadBytes (sizeof (Result), &Result);\r
171\r
172 return Result;\r
173}\r
174\r
175\r
176/**\r
177 Reads a UINT32 firmware configuration value\r
178\r
179 @return Value of Firmware Configuration item read\r
180\r
181**/\r
182UINT32\r
183EFIAPI\r
184QemuFwCfgRead32 (\r
185 VOID\r
186 )\r
187{\r
188 UINT32 Result;\r
189\r
190 QemuFwCfgReadBytes (sizeof (Result), &Result);\r
191\r
192 return Result;\r
193}\r
194\r
195\r
196/**\r
197 Reads a UINT64 firmware configuration value\r
198\r
199 @return Value of Firmware Configuration item read\r
200\r
201**/\r
202UINT64\r
203EFIAPI\r
204QemuFwCfgRead64 (\r
205 VOID\r
206 )\r
207{\r
208 UINT64 Result;\r
209\r
210 QemuFwCfgReadBytes (sizeof (Result), &Result);\r
211\r
212 return Result;\r
213}\r
214\r
215\r
216RETURN_STATUS\r
217EFIAPI\r
218QemuFwCfgInitialize (\r
219 VOID\r
220 )\r
221{\r
222 UINT32 Signature;\r
223 UINT32 Revision;\r
224\r
225 //\r
226 // Enable the access routines while probing to see if it is supported.\r
227 //\r
228 mQemuFwCfgSupported = TRUE;\r
229\r
230 QemuFwCfgSelectItem (QemuFwCfgItemSignature);\r
231 Signature = QemuFwCfgRead32 ();\r
232 DEBUG ((EFI_D_INFO, "FW CFG Signature: 0x%x\n", Signature));\r
233 QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);\r
234 Revision = QemuFwCfgRead32 ();\r
235 DEBUG ((EFI_D_INFO, "FW CFG Revision: 0x%x\n", Revision));\r
236 if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) ||\r
237 (Revision < 1)\r
238 ) {\r
239 DEBUG ((EFI_D_INFO, "QemuFwCfg interface not supported.\n"));\r
240 mQemuFwCfgSupported = FALSE;\r
241 return RETURN_SUCCESS;\r
242 }\r
243\r
244 DEBUG ((EFI_D_INFO, "QemuFwCfg interface is supported.\n"));\r
245 return RETURN_SUCCESS;\r
246}\r
0ac9bc9b 247\r
248\r
249/**\r
250 Find the configuration item corresponding to the firmware configuration file.\r
251\r
252 @param[in] Name - Name of file to look up.\r
253 @param[out] Item - Configuration item corresponding to the file, to be passed\r
254 to QemuFwCfgSelectItem ().\r
255 @param[out] Size - Number of bytes in the file.\r
256\r
257 @return RETURN_SUCCESS If file is found.\r
258 RETURN_NOT_FOUND If file is not found.\r
259 RETURN_UNSUPPORTED If firmware configuration is unavailable.\r
260\r
261**/\r
262RETURN_STATUS\r
263EFIAPI\r
264QemuFwCfgFindFile (\r
265 IN CONST CHAR8 *Name,\r
266 OUT FIRMWARE_CONFIG_ITEM *Item,\r
267 OUT UINTN *Size\r
268 )\r
269{\r
270 UINT32 Count;\r
271 UINT32 Idx;\r
272\r
273 if (!mQemuFwCfgSupported) {\r
274 return RETURN_UNSUPPORTED;\r
275 }\r
276\r
277 QemuFwCfgSelectItem (QemuFwCfgItemFileDir);\r
278 Count = SwapBytes32 (QemuFwCfgRead32 ());\r
279\r
280 for (Idx = 0; Idx < Count; ++Idx) {\r
281 UINT32 FileSize;\r
282 UINT16 FileSelect;\r
283 UINT16 FileReserved;\r
284 CHAR8 FName[56];\r
285\r
286 FileSize = QemuFwCfgRead32 ();\r
287 FileSelect = QemuFwCfgRead16 ();\r
288 FileReserved = QemuFwCfgRead16 ();\r
289 InternalQemuFwCfgReadBytes (sizeof (FName), FName);\r
290\r
291 if (AsciiStrCmp (Name, FName) == 0) {\r
292 *Item = SwapBytes16 (FileSelect);\r
293 *Size = SwapBytes32 (FileSize);\r
294 return RETURN_SUCCESS;\r
295 }\r
296 }\r
297\r
298 return RETURN_NOT_FOUND;\r
299}\r