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>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include <Library/BaseLib.h>
19 #include <Library/BaseMemoryLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/IoLib.h>
22 #include <Library/QemuFwCfgLib.h>
23 #include <Library/MemoryAllocationLib.h>
24 #include <Library/UefiBootServicesTableLib.h>
26 #include "QemuFwCfgLibInternal.h"
30 Selects a firmware configuration item for reading.
32 Following this call, any data read from this item will start from
33 the beginning of the configuration item's data.
35 @param[in] QemuFwCfgItem - Firmware Configuration item to read
41 IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem
44 DEBUG ((EFI_D_INFO
, "Select Item: 0x%x\n", (UINT16
)(UINTN
) QemuFwCfgItem
));
45 IoWrite16 (0x510, (UINT16
)(UINTN
) QemuFwCfgItem
);
50 Transfer an array of bytes, or skip a number of bytes, using the DMA
53 @param[in] Size Size in bytes to transfer or skip.
55 @param[in,out] Buffer Buffer to read data into or write data from. Ignored,
56 and may be NULL, if Size is zero, or Control is
59 @param[in] Control One of the following:
60 FW_CFG_DMA_CTL_WRITE - write to fw_cfg from Buffer.
61 FW_CFG_DMA_CTL_READ - read from fw_cfg into Buffer.
62 FW_CFG_DMA_CTL_SKIP - skip bytes in fw_cfg.
65 InternalQemuFwCfgDmaBytes (
67 IN OUT VOID
*Buffer OPTIONAL
,
71 volatile FW_CFG_DMA_ACCESS Access
;
72 UINT32 AccessHigh
, AccessLow
;
75 ASSERT (Control
== FW_CFG_DMA_CTL_WRITE
|| Control
== FW_CFG_DMA_CTL_READ
||
76 Control
== FW_CFG_DMA_CTL_SKIP
);
82 Access
.Control
= SwapBytes32 (Control
);
83 Access
.Length
= SwapBytes32 (Size
);
84 Access
.Address
= SwapBytes64 ((UINTN
)Buffer
);
87 // Delimit the transfer from (a) modifications to Access, (b) in case of a
88 // write, from writes to Buffer by the caller.
93 // Start the transfer.
95 AccessHigh
= (UINT32
)RShiftU64 ((UINTN
)&Access
, 32);
96 AccessLow
= (UINT32
)(UINTN
)&Access
;
97 IoWrite32 (0x514, SwapBytes32 (AccessHigh
));
98 IoWrite32 (0x518, SwapBytes32 (AccessLow
));
101 // Don't look at Access.Control before starting the transfer.
106 // Wait for the transfer to complete.
109 Status
= SwapBytes32 (Access
.Control
);
110 ASSERT ((Status
& FW_CFG_DMA_CTL_ERROR
) == 0);
111 } while (Status
!= 0);
114 // After a read, the caller will want to use Buffer.
121 Reads firmware configuration bytes into a buffer
123 @param[in] Size - Size in bytes to read
124 @param[in] Buffer - Buffer to store data into (OPTIONAL if Size is 0)
129 InternalQemuFwCfgReadBytes (
131 IN VOID
*Buffer OPTIONAL
134 if (InternalQemuFwCfgDmaIsAvailable () && Size
<= MAX_UINT32
) {
135 InternalQemuFwCfgDmaBytes ((UINT32
)Size
, Buffer
, FW_CFG_DMA_CTL_READ
);
138 IoReadFifo8 (0x511, Size
, Buffer
);
143 Reads firmware configuration bytes into a buffer
145 If called multiple times, then the data read will
146 continue at the offset of the firmware configuration
147 item where the previous read ended.
149 @param[in] Size - Size in bytes to read
150 @param[in] Buffer - Buffer to store data into
160 if (InternalQemuFwCfgIsAvailable ()) {
161 InternalQemuFwCfgReadBytes (Size
, Buffer
);
163 ZeroMem (Buffer
, Size
);
168 Write firmware configuration bytes from a buffer
170 If called multiple times, then the data written will
171 continue at the offset of the firmware configuration
172 item where the previous write ended.
174 @param[in] Size - Size in bytes to write
175 @param[in] Buffer - Buffer to read data from
180 QemuFwCfgWriteBytes (
185 if (InternalQemuFwCfgIsAvailable ()) {
186 if (InternalQemuFwCfgDmaIsAvailable () && Size
<= MAX_UINT32
) {
187 InternalQemuFwCfgDmaBytes ((UINT32
)Size
, Buffer
, FW_CFG_DMA_CTL_WRITE
);
190 IoWriteFifo8 (0x511, Size
, Buffer
);
196 Reads a UINT8 firmware configuration value
198 @return Value of Firmware Configuration item read
209 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
216 Reads a UINT16 firmware configuration value
218 @return Value of Firmware Configuration item read
229 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
236 Reads a UINT32 firmware configuration value
238 @return Value of Firmware Configuration item read
249 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
256 Reads a UINT64 firmware configuration value
258 @return Value of Firmware Configuration item read
269 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
276 Find the configuration item corresponding to the firmware configuration file.
278 @param[in] Name - Name of file to look up.
279 @param[out] Item - Configuration item corresponding to the file, to be passed
280 to QemuFwCfgSelectItem ().
281 @param[out] Size - Number of bytes in the file.
283 @return RETURN_SUCCESS If file is found.
284 RETURN_NOT_FOUND If file is not found.
285 RETURN_UNSUPPORTED If firmware configuration is unavailable.
291 IN CONST CHAR8
*Name
,
292 OUT FIRMWARE_CONFIG_ITEM
*Item
,
299 if (!InternalQemuFwCfgIsAvailable ()) {
300 return RETURN_UNSUPPORTED
;
303 QemuFwCfgSelectItem (QemuFwCfgItemFileDir
);
304 Count
= SwapBytes32 (QemuFwCfgRead32 ());
306 for (Idx
= 0; Idx
< Count
; ++Idx
) {
310 CHAR8 FName
[QEMU_FW_CFG_FNAME_SIZE
];
312 FileSize
= QemuFwCfgRead32 ();
313 FileSelect
= QemuFwCfgRead16 ();
314 FileReserved
= QemuFwCfgRead16 ();
315 (VOID
) FileReserved
; /* Force a do-nothing reference. */
316 InternalQemuFwCfgReadBytes (sizeof (FName
), FName
);
318 if (AsciiStrCmp (Name
, FName
) == 0) {
319 *Item
= SwapBytes16 (FileSelect
);
320 *Size
= SwapBytes32 (FileSize
);
321 return RETURN_SUCCESS
;
325 return RETURN_NOT_FOUND
;
330 Determine if S3 support is explicitly enabled.
332 @retval TRUE if S3 support is explicitly enabled.
333 FALSE otherwise. This includes unavailability of the firmware
334 configuration interface.
342 RETURN_STATUS Status
;
343 FIRMWARE_CONFIG_ITEM FwCfgItem
;
345 UINT8 SystemStates
[6];
347 Status
= QemuFwCfgFindFile ("etc/system-states", &FwCfgItem
, &FwCfgSize
);
348 if (Status
!= RETURN_SUCCESS
|| FwCfgSize
!= sizeof SystemStates
) {
351 QemuFwCfgSelectItem (FwCfgItem
);
352 QemuFwCfgReadBytes (sizeof SystemStates
, SystemStates
);
353 return (BOOLEAN
) (SystemStates
[3] & BIT7
);