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