]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
OvmfPkg: introduce QemuFwCfgFindFile ()
[mirror_edk2.git] / OvmfPkg / Library / QemuFwCfgLib / QemuFwCfgLib.c
1 /** @file
2
3 Copyright (c) 2011 - 2012, 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 /**
55 Returns a boolean indicating if the firmware configuration interface
56 is available or not.
57
58 @retval TRUE The interface is available
59 @retval FALSE The interface is not available
60
61 **/
62 BOOLEAN
63 EFIAPI
64 QemuFwCfgIsAvailable (
65 VOID
66 )
67 {
68 return mQemuFwCfgSupported;
69 }
70
71
72 /**
73 Selects a firmware configuration item for reading.
74
75 Following this call, any data read from this item will start from
76 the beginning of the configuration item's data.
77
78 @param[in] QemuFwCfgItem - Firmware Configuration item to read
79
80 **/
81 VOID
82 EFIAPI
83 QemuFwCfgSelectItem (
84 IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem
85 )
86 {
87 DEBUG ((EFI_D_INFO, "Select Item: 0x%x\n", (UINT16)(UINTN) QemuFwCfgItem));
88 IoWrite16 (0x510, (UINT16)(UINTN) QemuFwCfgItem);
89 }
90
91
92 /**
93 Reads firmware configuration bytes into a buffer
94
95 @param[in] Size - Size in bytes to read
96 @param[in] Buffer - Buffer to store data into (OPTIONAL if Size is 0)
97
98 **/
99 VOID
100 EFIAPI
101 InternalQemuFwCfgReadBytes (
102 IN UINTN Size,
103 IN VOID *Buffer OPTIONAL
104 )
105 {
106 IoReadFifo8 (0x511, Size, Buffer);
107 }
108
109
110 /**
111 Reads firmware configuration bytes into a buffer
112
113 If called multiple times, then the data read will
114 continue at the offset of the firmware configuration
115 item where the previous read ended.
116
117 @param[in] Size - Size in bytes to read
118 @param[in] Buffer - Buffer to store data into
119
120 **/
121 VOID
122 EFIAPI
123 QemuFwCfgReadBytes (
124 IN UINTN Size,
125 IN VOID *Buffer
126 )
127 {
128 if (mQemuFwCfgSupported) {
129 InternalQemuFwCfgReadBytes (Size, Buffer);
130 } else {
131 ZeroMem (Buffer, Size);
132 }
133 }
134
135
136 /**
137 Reads a UINT8 firmware configuration value
138
139 @return Value of Firmware Configuration item read
140
141 **/
142 UINT8
143 EFIAPI
144 QemuFwCfgRead8 (
145 VOID
146 )
147 {
148 UINT8 Result;
149
150 QemuFwCfgReadBytes (sizeof (Result), &Result);
151
152 return Result;
153 }
154
155
156 /**
157 Reads a UINT16 firmware configuration value
158
159 @return Value of Firmware Configuration item read
160
161 **/
162 UINT16
163 EFIAPI
164 QemuFwCfgRead16 (
165 VOID
166 )
167 {
168 UINT16 Result;
169
170 QemuFwCfgReadBytes (sizeof (Result), &Result);
171
172 return Result;
173 }
174
175
176 /**
177 Reads a UINT32 firmware configuration value
178
179 @return Value of Firmware Configuration item read
180
181 **/
182 UINT32
183 EFIAPI
184 QemuFwCfgRead32 (
185 VOID
186 )
187 {
188 UINT32 Result;
189
190 QemuFwCfgReadBytes (sizeof (Result), &Result);
191
192 return Result;
193 }
194
195
196 /**
197 Reads a UINT64 firmware configuration value
198
199 @return Value of Firmware Configuration item read
200
201 **/
202 UINT64
203 EFIAPI
204 QemuFwCfgRead64 (
205 VOID
206 )
207 {
208 UINT64 Result;
209
210 QemuFwCfgReadBytes (sizeof (Result), &Result);
211
212 return Result;
213 }
214
215
216 RETURN_STATUS
217 EFIAPI
218 QemuFwCfgInitialize (
219 VOID
220 )
221 {
222 UINT32 Signature;
223 UINT32 Revision;
224
225 //
226 // Enable the access routines while probing to see if it is supported.
227 //
228 mQemuFwCfgSupported = TRUE;
229
230 QemuFwCfgSelectItem (QemuFwCfgItemSignature);
231 Signature = QemuFwCfgRead32 ();
232 DEBUG ((EFI_D_INFO, "FW CFG Signature: 0x%x\n", Signature));
233 QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);
234 Revision = QemuFwCfgRead32 ();
235 DEBUG ((EFI_D_INFO, "FW CFG Revision: 0x%x\n", Revision));
236 if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) ||
237 (Revision < 1)
238 ) {
239 DEBUG ((EFI_D_INFO, "QemuFwCfg interface not supported.\n"));
240 mQemuFwCfgSupported = FALSE;
241 return RETURN_SUCCESS;
242 }
243
244 DEBUG ((EFI_D_INFO, "QemuFwCfg interface is supported.\n"));
245 return RETURN_SUCCESS;
246 }
247
248
249 /**
250 Find the configuration item corresponding to the firmware configuration file.
251
252 @param[in] Name - Name of file to look up.
253 @param[out] Item - Configuration item corresponding to the file, to be passed
254 to QemuFwCfgSelectItem ().
255 @param[out] Size - Number of bytes in the file.
256
257 @return RETURN_SUCCESS If file is found.
258 RETURN_NOT_FOUND If file is not found.
259 RETURN_UNSUPPORTED If firmware configuration is unavailable.
260
261 **/
262 RETURN_STATUS
263 EFIAPI
264 QemuFwCfgFindFile (
265 IN CONST CHAR8 *Name,
266 OUT FIRMWARE_CONFIG_ITEM *Item,
267 OUT UINTN *Size
268 )
269 {
270 UINT32 Count;
271 UINT32 Idx;
272
273 if (!mQemuFwCfgSupported) {
274 return RETURN_UNSUPPORTED;
275 }
276
277 QemuFwCfgSelectItem (QemuFwCfgItemFileDir);
278 Count = SwapBytes32 (QemuFwCfgRead32 ());
279
280 for (Idx = 0; Idx < Count; ++Idx) {
281 UINT32 FileSize;
282 UINT16 FileSelect;
283 UINT16 FileReserved;
284 CHAR8 FName[56];
285
286 FileSize = QemuFwCfgRead32 ();
287 FileSelect = QemuFwCfgRead16 ();
288 FileReserved = QemuFwCfgRead16 ();
289 InternalQemuFwCfgReadBytes (sizeof (FName), FName);
290
291 if (AsciiStrCmp (Name, FName) == 0) {
292 *Item = SwapBytes16 (FileSelect);
293 *Size = SwapBytes32 (FileSize);
294 return RETURN_SUCCESS;
295 }
296 }
297
298 return RETURN_NOT_FOUND;
299 }