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