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"
23 Selects a firmware configuration item for reading.
25 Following this call, any data read from this item will start from
26 the beginning of the configuration item's data.
28 @param[in] QemuFwCfgItem - Firmware Configuration item to read
34 IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem
37 DEBUG ((DEBUG_INFO
, "Select Item: 0x%x\n", (UINT16
)(UINTN
)QemuFwCfgItem
));
38 IoWrite16 (FW_CFG_IO_SELECTOR
, (UINT16
)(UINTN
)QemuFwCfgItem
);
42 Reads firmware configuration bytes into a buffer
44 @param[in] Size - Size in bytes to read
45 @param[in] Buffer - Buffer to store data into (OPTIONAL if Size is 0)
50 InternalQemuFwCfgReadBytes (
52 IN VOID
*Buffer OPTIONAL
55 if (InternalQemuFwCfgDmaIsAvailable () && (Size
<= MAX_UINT32
)) {
56 InternalQemuFwCfgDmaBytes ((UINT32
)Size
, Buffer
, FW_CFG_DMA_CTL_READ
);
60 IoReadFifo8 (FW_CFG_IO_DATA
, Size
, Buffer
);
64 Reads firmware configuration bytes into a buffer
66 If called multiple times, then the data read will
67 continue at the offset of the firmware configuration
68 item where the previous read ended.
70 @param[in] Size - Size in bytes to read
71 @param[in] Buffer - Buffer to store data into
81 if (InternalQemuFwCfgIsAvailable ()) {
82 InternalQemuFwCfgReadBytes (Size
, Buffer
);
84 ZeroMem (Buffer
, Size
);
89 Write firmware configuration bytes from a buffer
91 If called multiple times, then the data written will
92 continue at the offset of the firmware configuration
93 item where the previous write ended.
95 @param[in] Size - Size in bytes to write
96 @param[in] Buffer - Buffer to read data from
101 QemuFwCfgWriteBytes (
106 if (InternalQemuFwCfgIsAvailable ()) {
107 if (InternalQemuFwCfgDmaIsAvailable () && (Size
<= MAX_UINT32
)) {
108 InternalQemuFwCfgDmaBytes ((UINT32
)Size
, Buffer
, FW_CFG_DMA_CTL_WRITE
);
112 IoWriteFifo8 (FW_CFG_IO_DATA
, Size
, Buffer
);
117 Skip bytes in the firmware configuration item.
119 Increase the offset of the firmware configuration item without transferring
120 bytes between the item and a caller-provided buffer. Subsequent read, write
121 or skip operations will commence at the increased offset.
123 @param[in] Size Number of bytes to skip.
132 UINT8 SkipBuffer
[256];
134 if (!InternalQemuFwCfgIsAvailable ()) {
138 if (InternalQemuFwCfgDmaIsAvailable () && (Size
<= MAX_UINT32
)) {
139 InternalQemuFwCfgDmaBytes ((UINT32
)Size
, NULL
, FW_CFG_DMA_CTL_SKIP
);
144 // Emulate the skip by reading data in chunks, and throwing it away. The
145 // implementation below is suitable even for phases where RAM or dynamic
146 // allocation is not available or appropriate. It also doesn't affect the
147 // static data footprint for client modules. Large skips are not expected,
148 // therefore this fallback is not performance critical. The size of
149 // SkipBuffer is thought not to exert a large pressure on the stack in any
153 ChunkSize
= MIN (Size
, sizeof SkipBuffer
);
154 IoReadFifo8 (FW_CFG_IO_DATA
, ChunkSize
, SkipBuffer
);
160 Reads a UINT8 firmware configuration value
162 @return Value of Firmware Configuration item read
173 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
179 Reads a UINT16 firmware configuration value
181 @return Value of Firmware Configuration item read
192 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
198 Reads a UINT32 firmware configuration value
200 @return Value of Firmware Configuration item read
211 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
217 Reads a UINT64 firmware configuration value
219 @return Value of Firmware Configuration item read
230 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
236 Find the configuration item corresponding to the firmware configuration file.
238 @param[in] Name - Name of file to look up.
239 @param[out] Item - Configuration item corresponding to the file, to be passed
240 to QemuFwCfgSelectItem ().
241 @param[out] Size - Number of bytes in the file.
243 @return RETURN_SUCCESS If file is found.
244 RETURN_NOT_FOUND If file is not found.
245 RETURN_UNSUPPORTED If firmware configuration is unavailable.
251 IN CONST CHAR8
*Name
,
252 OUT FIRMWARE_CONFIG_ITEM
*Item
,
259 if (!InternalQemuFwCfgIsAvailable ()) {
260 return RETURN_UNSUPPORTED
;
263 QemuFwCfgSelectItem (QemuFwCfgItemFileDir
);
264 Count
= SwapBytes32 (QemuFwCfgRead32 ());
266 for (Idx
= 0; Idx
< Count
; ++Idx
) {
270 CHAR8 FName
[QEMU_FW_CFG_FNAME_SIZE
];
272 FileSize
= QemuFwCfgRead32 ();
273 FileSelect
= QemuFwCfgRead16 ();
274 FileReserved
= QemuFwCfgRead16 ();
275 (VOID
)FileReserved
; /* Force a do-nothing reference. */
276 InternalQemuFwCfgReadBytes (sizeof (FName
), FName
);
278 if (AsciiStrCmp (Name
, FName
) == 0) {
279 *Item
= SwapBytes16 (FileSelect
);
280 *Size
= SwapBytes32 (FileSize
);
281 return RETURN_SUCCESS
;
285 return RETURN_NOT_FOUND
;