]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
OvmfPkg: Apply uncrustify changes
[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
2b631390 5 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
f1ec65ba 6\r
b26f0cf9 7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
f1ec65ba 8\r
9**/\r
10\r
11#include "Uefi.h"\r
12#include <Library/BaseLib.h>\r
13#include <Library/BaseMemoryLib.h>\r
14#include <Library/DebugLib.h>\r
15#include <Library/IoLib.h>\r
16#include <Library/QemuFwCfgLib.h>\r
17#include <Library/MemoryAllocationLib.h>\r
18#include <Library/UefiBootServicesTableLib.h>\r
19\r
5297c0bf
LE
20#include "QemuFwCfgLibInternal.h"\r
21\r
f1ec65ba 22/**\r
23 Selects a firmware configuration item for reading.\r
4040754d 24\r
f1ec65ba 25 Following this call, any data read from this item will start from\r
26 the beginning of the configuration item's data.\r
27\r
28 @param[in] QemuFwCfgItem - Firmware Configuration item to read\r
29\r
30**/\r
31VOID\r
32EFIAPI\r
33QemuFwCfgSelectItem (\r
ac0a286f 34 IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem\r
f1ec65ba 35 )\r
36{\r
ac0a286f
MK
37 DEBUG ((DEBUG_INFO, "Select Item: 0x%x\n", (UINT16)(UINTN)QemuFwCfgItem));\r
38 IoWrite16 (FW_CFG_IO_SELECTOR, (UINT16)(UINTN)QemuFwCfgItem);\r
f1ec65ba 39}\r
40\r
f1ec65ba 41/**\r
42 Reads firmware configuration bytes into a buffer\r
43\r
44 @param[in] Size - Size in bytes to read\r
45 @param[in] Buffer - Buffer to store data into (OPTIONAL if Size is 0)\r
46\r
47**/\r
48VOID\r
49EFIAPI\r
50InternalQemuFwCfgReadBytes (\r
ac0a286f
MK
51 IN UINTN Size,\r
52 IN VOID *Buffer OPTIONAL\r
f1ec65ba 53 )\r
54{\r
ac0a286f 55 if (InternalQemuFwCfgDmaIsAvailable () && (Size <= MAX_UINT32)) {\r
d055601e 56 InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_READ);\r
2c8dcbc6
LE
57 return;\r
58 }\r
ac0a286f 59\r
509e6b5a 60 IoReadFifo8 (FW_CFG_IO_DATA, Size, Buffer);\r
f1ec65ba 61}\r
62\r
f1ec65ba 63/**\r
64 Reads firmware configuration bytes into a buffer\r
65\r
66 If called multiple times, then the data read will\r
67 continue at the offset of the firmware configuration\r
68 item where the previous read ended.\r
69\r
70 @param[in] Size - Size in bytes to read\r
71 @param[in] Buffer - Buffer to store data into\r
72\r
73**/\r
74VOID\r
75EFIAPI\r
76QemuFwCfgReadBytes (\r
ac0a286f
MK
77 IN UINTN Size,\r
78 IN VOID *Buffer\r
f1ec65ba 79 )\r
80{\r
0dc231c9 81 if (InternalQemuFwCfgIsAvailable ()) {\r
f1ec65ba 82 InternalQemuFwCfgReadBytes (Size, Buffer);\r
83 } else {\r
84 ZeroMem (Buffer, Size);\r
85 }\r
86}\r
87\r
29874a8c 88/**\r
89 Write firmware configuration bytes from a buffer\r
90\r
91 If called multiple times, then the data written will\r
92 continue at the offset of the firmware configuration\r
93 item where the previous write ended.\r
94\r
95 @param[in] Size - Size in bytes to write\r
96 @param[in] Buffer - Buffer to read data from\r
97\r
98**/\r
99VOID\r
100EFIAPI\r
101QemuFwCfgWriteBytes (\r
ac0a286f
MK
102 IN UINTN Size,\r
103 IN VOID *Buffer\r
29874a8c 104 )\r
105{\r
0dc231c9 106 if (InternalQemuFwCfgIsAvailable ()) {\r
ac0a286f 107 if (InternalQemuFwCfgDmaIsAvailable () && (Size <= MAX_UINT32)) {\r
d055601e 108 InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_WRITE);\r
2c8dcbc6
LE
109 return;\r
110 }\r
ac0a286f 111\r
509e6b5a 112 IoWriteFifo8 (FW_CFG_IO_DATA, Size, Buffer);\r
29874a8c 113 }\r
114}\r
115\r
fcca9f67
LE
116/**\r
117 Skip bytes in the firmware configuration item.\r
118\r
119 Increase the offset of the firmware configuration item without transferring\r
120 bytes between the item and a caller-provided buffer. Subsequent read, write\r
121 or skip operations will commence at the increased offset.\r
122\r
123 @param[in] Size Number of bytes to skip.\r
124**/\r
125VOID\r
126EFIAPI\r
127QemuFwCfgSkipBytes (\r
ac0a286f 128 IN UINTN Size\r
fcca9f67
LE
129 )\r
130{\r
ac0a286f
MK
131 UINTN ChunkSize;\r
132 UINT8 SkipBuffer[256];\r
fcca9f67
LE
133\r
134 if (!InternalQemuFwCfgIsAvailable ()) {\r
135 return;\r
136 }\r
137\r
ac0a286f 138 if (InternalQemuFwCfgDmaIsAvailable () && (Size <= MAX_UINT32)) {\r
fcca9f67
LE
139 InternalQemuFwCfgDmaBytes ((UINT32)Size, NULL, FW_CFG_DMA_CTL_SKIP);\r
140 return;\r
141 }\r
142\r
143 //\r
144 // Emulate the skip by reading data in chunks, and throwing it away. The\r
145 // implementation below is suitable even for phases where RAM or dynamic\r
146 // allocation is not available or appropriate. It also doesn't affect the\r
147 // static data footprint for client modules. Large skips are not expected,\r
148 // therefore this fallback is not performance critical. The size of\r
149 // SkipBuffer is thought not to exert a large pressure on the stack in any\r
150 // phase.\r
151 //\r
152 while (Size > 0) {\r
153 ChunkSize = MIN (Size, sizeof SkipBuffer);\r
509e6b5a 154 IoReadFifo8 (FW_CFG_IO_DATA, ChunkSize, SkipBuffer);\r
fcca9f67
LE
155 Size -= ChunkSize;\r
156 }\r
157}\r
158\r
f1ec65ba 159/**\r
160 Reads a UINT8 firmware configuration value\r
161\r
162 @return Value of Firmware Configuration item read\r
163\r
164**/\r
165UINT8\r
166EFIAPI\r
167QemuFwCfgRead8 (\r
168 VOID\r
169 )\r
170{\r
ac0a286f 171 UINT8 Result;\r
f1ec65ba 172\r
173 QemuFwCfgReadBytes (sizeof (Result), &Result);\r
174\r
175 return Result;\r
176}\r
177\r
f1ec65ba 178/**\r
179 Reads a UINT16 firmware configuration value\r
180\r
181 @return Value of Firmware Configuration item read\r
182\r
183**/\r
184UINT16\r
185EFIAPI\r
186QemuFwCfgRead16 (\r
187 VOID\r
188 )\r
189{\r
ac0a286f 190 UINT16 Result;\r
f1ec65ba 191\r
192 QemuFwCfgReadBytes (sizeof (Result), &Result);\r
193\r
194 return Result;\r
195}\r
196\r
f1ec65ba 197/**\r
198 Reads a UINT32 firmware configuration value\r
199\r
200 @return Value of Firmware Configuration item read\r
201\r
202**/\r
203UINT32\r
204EFIAPI\r
205QemuFwCfgRead32 (\r
206 VOID\r
207 )\r
208{\r
ac0a286f 209 UINT32 Result;\r
f1ec65ba 210\r
211 QemuFwCfgReadBytes (sizeof (Result), &Result);\r
212\r
213 return Result;\r
214}\r
215\r
f1ec65ba 216/**\r
217 Reads a UINT64 firmware configuration value\r
218\r
219 @return Value of Firmware Configuration item read\r
220\r
221**/\r
222UINT64\r
223EFIAPI\r
224QemuFwCfgRead64 (\r
225 VOID\r
226 )\r
227{\r
ac0a286f 228 UINT64 Result;\r
f1ec65ba 229\r
230 QemuFwCfgReadBytes (sizeof (Result), &Result);\r
231\r
232 return Result;\r
233}\r
234\r
0ac9bc9b 235/**\r
236 Find the configuration item corresponding to the firmware configuration file.\r
237\r
238 @param[in] Name - Name of file to look up.\r
239 @param[out] Item - Configuration item corresponding to the file, to be passed\r
240 to QemuFwCfgSelectItem ().\r
241 @param[out] Size - Number of bytes in the file.\r
242\r
243 @return RETURN_SUCCESS If file is found.\r
244 RETURN_NOT_FOUND If file is not found.\r
245 RETURN_UNSUPPORTED If firmware configuration is unavailable.\r
246\r
247**/\r
248RETURN_STATUS\r
249EFIAPI\r
250QemuFwCfgFindFile (\r
251 IN CONST CHAR8 *Name,\r
252 OUT FIRMWARE_CONFIG_ITEM *Item,\r
253 OUT UINTN *Size\r
254 )\r
255{\r
ac0a286f
MK
256 UINT32 Count;\r
257 UINT32 Idx;\r
0ac9bc9b 258\r
0dc231c9 259 if (!InternalQemuFwCfgIsAvailable ()) {\r
0ac9bc9b 260 return RETURN_UNSUPPORTED;\r
261 }\r
262\r
263 QemuFwCfgSelectItem (QemuFwCfgItemFileDir);\r
264 Count = SwapBytes32 (QemuFwCfgRead32 ());\r
265\r
266 for (Idx = 0; Idx < Count; ++Idx) {\r
ac0a286f
MK
267 UINT32 FileSize;\r
268 UINT16 FileSelect;\r
269 UINT16 FileReserved;\r
270 CHAR8 FName[QEMU_FW_CFG_FNAME_SIZE];\r
0ac9bc9b 271\r
272 FileSize = QemuFwCfgRead32 ();\r
273 FileSelect = QemuFwCfgRead16 ();\r
274 FileReserved = QemuFwCfgRead16 ();\r
ac0a286f 275 (VOID)FileReserved; /* Force a do-nothing reference. */\r
0ac9bc9b 276 InternalQemuFwCfgReadBytes (sizeof (FName), FName);\r
277\r
278 if (AsciiStrCmp (Name, FName) == 0) {\r
279 *Item = SwapBytes16 (FileSelect);\r
280 *Size = SwapBytes32 (FileSize);\r
281 return RETURN_SUCCESS;\r
282 }\r
283 }\r
284\r
285 return RETURN_NOT_FOUND;\r
286}\r