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