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 (FW_CFG_IO_SELECTOR
, (UINT16
)(UINTN
) QemuFwCfgItem
);
49 Reads firmware configuration bytes into a buffer
51 @param[in] Size - Size in bytes to read
52 @param[in] Buffer - Buffer to store data into (OPTIONAL if Size is 0)
57 InternalQemuFwCfgReadBytes (
59 IN VOID
*Buffer OPTIONAL
62 if (InternalQemuFwCfgDmaIsAvailable () && Size
<= MAX_UINT32
) {
63 InternalQemuFwCfgDmaBytes ((UINT32
)Size
, Buffer
, FW_CFG_DMA_CTL_READ
);
66 IoReadFifo8 (FW_CFG_IO_DATA
, Size
, Buffer
);
71 Reads firmware configuration bytes into a buffer
73 If called multiple times, then the data read will
74 continue at the offset of the firmware configuration
75 item where the previous read ended.
77 @param[in] Size - Size in bytes to read
78 @param[in] Buffer - Buffer to store data into
88 if (InternalQemuFwCfgIsAvailable ()) {
89 InternalQemuFwCfgReadBytes (Size
, Buffer
);
91 ZeroMem (Buffer
, Size
);
96 Write firmware configuration bytes from a buffer
98 If called multiple times, then the data written will
99 continue at the offset of the firmware configuration
100 item where the previous write ended.
102 @param[in] Size - Size in bytes to write
103 @param[in] Buffer - Buffer to read data from
108 QemuFwCfgWriteBytes (
113 if (InternalQemuFwCfgIsAvailable ()) {
114 if (InternalQemuFwCfgDmaIsAvailable () && Size
<= MAX_UINT32
) {
115 InternalQemuFwCfgDmaBytes ((UINT32
)Size
, Buffer
, FW_CFG_DMA_CTL_WRITE
);
118 IoWriteFifo8 (FW_CFG_IO_DATA
, Size
, Buffer
);
124 Skip bytes in the firmware configuration item.
126 Increase the offset of the firmware configuration item without transferring
127 bytes between the item and a caller-provided buffer. Subsequent read, write
128 or skip operations will commence at the increased offset.
130 @param[in] Size Number of bytes to skip.
139 UINT8 SkipBuffer
[256];
141 if (!InternalQemuFwCfgIsAvailable ()) {
145 if (InternalQemuFwCfgDmaIsAvailable () && Size
<= MAX_UINT32
) {
146 InternalQemuFwCfgDmaBytes ((UINT32
)Size
, NULL
, FW_CFG_DMA_CTL_SKIP
);
151 // Emulate the skip by reading data in chunks, and throwing it away. The
152 // implementation below is suitable even for phases where RAM or dynamic
153 // allocation is not available or appropriate. It also doesn't affect the
154 // static data footprint for client modules. Large skips are not expected,
155 // therefore this fallback is not performance critical. The size of
156 // SkipBuffer is thought not to exert a large pressure on the stack in any
160 ChunkSize
= MIN (Size
, sizeof SkipBuffer
);
161 IoReadFifo8 (FW_CFG_IO_DATA
, ChunkSize
, SkipBuffer
);
168 Reads a UINT8 firmware configuration value
170 @return Value of Firmware Configuration item read
181 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
188 Reads a UINT16 firmware configuration value
190 @return Value of Firmware Configuration item read
201 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
208 Reads a UINT32 firmware configuration value
210 @return Value of Firmware Configuration item read
221 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
228 Reads a UINT64 firmware configuration value
230 @return Value of Firmware Configuration item read
241 QemuFwCfgReadBytes (sizeof (Result
), &Result
);
248 Find the configuration item corresponding to the firmware configuration file.
250 @param[in] Name - Name of file to look up.
251 @param[out] Item - Configuration item corresponding to the file, to be passed
252 to QemuFwCfgSelectItem ().
253 @param[out] Size - Number of bytes in the file.
255 @return RETURN_SUCCESS If file is found.
256 RETURN_NOT_FOUND If file is not found.
257 RETURN_UNSUPPORTED If firmware configuration is unavailable.
263 IN CONST CHAR8
*Name
,
264 OUT FIRMWARE_CONFIG_ITEM
*Item
,
271 if (!InternalQemuFwCfgIsAvailable ()) {
272 return RETURN_UNSUPPORTED
;
275 QemuFwCfgSelectItem (QemuFwCfgItemFileDir
);
276 Count
= SwapBytes32 (QemuFwCfgRead32 ());
278 for (Idx
= 0; Idx
< Count
; ++Idx
) {
282 CHAR8 FName
[QEMU_FW_CFG_FNAME_SIZE
];
284 FileSize
= QemuFwCfgRead32 ();
285 FileSelect
= QemuFwCfgRead16 ();
286 FileReserved
= QemuFwCfgRead16 ();
287 (VOID
) FileReserved
; /* Force a do-nothing reference. */
288 InternalQemuFwCfgReadBytes (sizeof (FName
), FName
);
290 if (AsciiStrCmp (Name
, FName
) == 0) {
291 *Item
= SwapBytes16 (FileSelect
);
292 *Size
= SwapBytes32 (FileSize
);
293 return RETURN_SUCCESS
;
297 return RETURN_NOT_FOUND
;