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