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 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include <Library/BaseLib.h>
13 #include <Library/BaseMemoryLib.h>
14 #include <Library/DebugLib.h>
15 #include <Library/IoLib.h>
16 #include <Library/QemuFwCfgLib.h>
17 #include <Library/MemoryAllocationLib.h>
18 #include <Library/UefiBootServicesTableLib.h>
20 #include "QemuFwCfgLibInternal.h"
24 Selects a firmware configuration item for reading.
26 Following this call, any data read from this item will start from
27 the beginning of the configuration item's data.
29 @param[in] QemuFwCfgItem - Firmware Configuration item to read
35 IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem
38 DEBUG ((EFI_D_INFO
, "Select Item: 0x%x\n", (UINT16
)(UINTN
) QemuFwCfgItem
));
39 IoWrite16 (FW_CFG_IO_SELECTOR
, (UINT16
)(UINTN
) QemuFwCfgItem
);
43 Reads firmware configuration bytes into a buffer
45 @param[in] Size - Size in bytes to read
46 @param[in] Buffer - Buffer to store data into (OPTIONAL if Size is 0)
51 InternalQemuFwCfgReadBytes (
53 IN VOID
*Buffer OPTIONAL
56 if (InternalQemuFwCfgDmaIsAvailable () && Size
<= MAX_UINT32
) {
57 InternalQemuFwCfgDmaBytes ((UINT32
)Size
, Buffer
, FW_CFG_DMA_CTL_READ
);
60 IoReadFifo8 (FW_CFG_IO_DATA
, Size
, Buffer
);
65 Reads firmware configuration bytes into a buffer
67 If called multiple times, then the data read will
68 continue at the offset of the firmware configuration
69 item where the previous read ended.
71 @param[in] Size - Size in bytes to read
72 @param[in] Buffer - Buffer to store data into
82 if (InternalQemuFwCfgIsAvailable ()) {
83 InternalQemuFwCfgReadBytes (Size
, Buffer
);
85 ZeroMem (Buffer
, Size
);
90 Write firmware configuration bytes from a buffer
92 If called multiple times, then the data written will
93 continue at the offset of the firmware configuration
94 item where the previous write ended.
96 @param[in] Size - Size in bytes to write
97 @param[in] Buffer - Buffer to read data from
102 QemuFwCfgWriteBytes (
107 if (InternalQemuFwCfgIsAvailable ()) {
108 if (InternalQemuFwCfgDmaIsAvailable () && Size
<= MAX_UINT32
) {
109 InternalQemuFwCfgDmaBytes ((UINT32
)Size
, Buffer
, FW_CFG_DMA_CTL_WRITE
);
112 IoWriteFifo8 (FW_CFG_IO_DATA
, Size
, Buffer
);
118 Skip bytes in the firmware configuration item.
120 Increase the offset of the firmware configuration item without transferring
121 bytes between the item and a caller-provided buffer. Subsequent read, write
122 or skip operations will commence at the increased offset.
124 @param[in] Size Number of bytes to skip.
133 UINT8 SkipBuffer
[256];
135 if (!InternalQemuFwCfgIsAvailable ()) {
139 if (InternalQemuFwCfgDmaIsAvailable () && Size
<= MAX_UINT32
) {
140 InternalQemuFwCfgDmaBytes ((UINT32
)Size
, NULL
, FW_CFG_DMA_CTL_SKIP
);
145 // Emulate the skip by reading data in chunks, and throwing it away. The
146 // implementation below is suitable even for phases where RAM or dynamic
147 // allocation is not available or appropriate. It also doesn't affect the
148 // static data footprint for client modules. Large skips are not expected,
149 // therefore this fallback is not performance critical. The size of
150 // SkipBuffer is thought not to exert a large pressure on the stack in any
154 ChunkSize
= MIN (Size
, sizeof SkipBuffer
);
155 IoReadFifo8 (FW_CFG_IO_DATA
, ChunkSize
, SkipBuffer
);
162 Reads a UINT8 firmware configuration value
164 @return Value of Firmware Configuration item read
175 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
182 Reads a UINT16 firmware configuration value
184 @return Value of Firmware Configuration item read
195 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
202 Reads a UINT32 firmware configuration value
204 @return Value of Firmware Configuration item read
215 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
222 Reads a UINT64 firmware configuration value
224 @return Value of Firmware Configuration item read
235 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
242 Find the configuration item corresponding to the firmware configuration file.
244 @param[in] Name - Name of file to look up.
245 @param[out] Item - Configuration item corresponding to the file, to be passed
246 to QemuFwCfgSelectItem ().
247 @param[out] Size - Number of bytes in the file.
249 @return RETURN_SUCCESS If file is found.
250 RETURN_NOT_FOUND If file is not found.
251 RETURN_UNSUPPORTED If firmware configuration is unavailable.
257 IN CONST CHAR8
*Name
,
258 OUT FIRMWARE_CONFIG_ITEM
*Item
,
265 if (!InternalQemuFwCfgIsAvailable ()) {
266 return RETURN_UNSUPPORTED
;
269 QemuFwCfgSelectItem (QemuFwCfgItemFileDir
);
270 Count
= SwapBytes32 (QemuFwCfgRead32 ());
272 for (Idx
= 0; Idx
< Count
; ++Idx
) {
276 CHAR8 FName
[QEMU_FW_CFG_FNAME_SIZE
];
278 FileSize
= QemuFwCfgRead32 ();
279 FileSelect
= QemuFwCfgRead16 ();
280 FileReserved
= QemuFwCfgRead16 ();
281 (VOID
) FileReserved
; /* Force a do-nothing reference. */
282 InternalQemuFwCfgReadBytes (sizeof (FName
), FName
);
284 if (AsciiStrCmp (Name
, FName
) == 0) {
285 *Item
= SwapBytes16 (FileSelect
);
286 *Size
= SwapBytes32 (FileSize
);
287 return RETURN_SUCCESS
;
291 return RETURN_NOT_FOUND
;