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