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