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