VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c@ 85788

Last change on this file since 85788 was 85718, checked in by vboxsync, 5 years ago

Devices/EFI: Merge edk-stable202005 and make it build, bugref:4643

  • Property svn:eol-style set to native
File size: 6.3 KB
Line 
1/** @file
2
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>
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9**/
10
11#include "Uefi.h"
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>
19
20#include "QemuFwCfgLibInternal.h"
21
22
23/**
24 Selects a firmware configuration item for reading.
25
26 Following this call, any data read from this item will start from
27 the beginning of the configuration item's data.
28
29 @param[in] QemuFwCfgItem - Firmware Configuration item to read
30
31**/
32VOID
33EFIAPI
34QemuFwCfgSelectItem (
35 IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem
36 )
37{
38 DEBUG ((DEBUG_INFO, "Select Item: 0x%x\n", (UINT16)(UINTN) QemuFwCfgItem));
39 IoWrite16 (FW_CFG_IO_SELECTOR, (UINT16)(UINTN) QemuFwCfgItem);
40}
41
42/**
43 Reads firmware configuration bytes into a buffer
44
45 @param[in] Size - Size in bytes to read
46 @param[in] Buffer - Buffer to store data into (OPTIONAL if Size is 0)
47
48**/
49VOID
50EFIAPI
51InternalQemuFwCfgReadBytes (
52 IN UINTN Size,
53 IN VOID *Buffer OPTIONAL
54 )
55{
56 if (InternalQemuFwCfgDmaIsAvailable () && Size <= MAX_UINT32) {
57 InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_READ);
58 return;
59 }
60 IoReadFifo8 (FW_CFG_IO_DATA, Size, Buffer);
61}
62
63
64/**
65 Reads firmware configuration bytes into a buffer
66
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.
70
71 @param[in] Size - Size in bytes to read
72 @param[in] Buffer - Buffer to store data into
73
74**/
75VOID
76EFIAPI
77QemuFwCfgReadBytes (
78 IN UINTN Size,
79 IN VOID *Buffer
80 )
81{
82 if (InternalQemuFwCfgIsAvailable ()) {
83 InternalQemuFwCfgReadBytes (Size, Buffer);
84 } else {
85 ZeroMem (Buffer, Size);
86 }
87}
88
89/**
90 Write firmware configuration bytes from a buffer
91
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.
95
96 @param[in] Size - Size in bytes to write
97 @param[in] Buffer - Buffer to read data from
98
99**/
100VOID
101EFIAPI
102QemuFwCfgWriteBytes (
103 IN UINTN Size,
104 IN VOID *Buffer
105 )
106{
107 if (InternalQemuFwCfgIsAvailable ()) {
108 if (InternalQemuFwCfgDmaIsAvailable () && Size <= MAX_UINT32) {
109 InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_WRITE);
110 return;
111 }
112 IoWriteFifo8 (FW_CFG_IO_DATA, Size, Buffer);
113 }
114}
115
116
117/**
118 Skip bytes in the firmware configuration item.
119
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.
123
124 @param[in] Size Number of bytes to skip.
125**/
126VOID
127EFIAPI
128QemuFwCfgSkipBytes (
129 IN UINTN Size
130 )
131{
132 UINTN ChunkSize;
133 UINT8 SkipBuffer[256];
134
135 if (!InternalQemuFwCfgIsAvailable ()) {
136 return;
137 }
138
139 if (InternalQemuFwCfgDmaIsAvailable () && Size <= MAX_UINT32) {
140 InternalQemuFwCfgDmaBytes ((UINT32)Size, NULL, FW_CFG_DMA_CTL_SKIP);
141 return;
142 }
143
144 //
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
151 // phase.
152 //
153 while (Size > 0) {
154 ChunkSize = MIN (Size, sizeof SkipBuffer);
155 IoReadFifo8 (FW_CFG_IO_DATA, ChunkSize, SkipBuffer);
156 Size -= ChunkSize;
157 }
158}
159
160
161/**
162 Reads a UINT8 firmware configuration value
163
164 @return Value of Firmware Configuration item read
165
166**/
167UINT8
168EFIAPI
169QemuFwCfgRead8 (
170 VOID
171 )
172{
173 UINT8 Result;
174
175 QemuFwCfgReadBytes (sizeof (Result), &Result);
176
177 return Result;
178}
179
180
181/**
182 Reads a UINT16 firmware configuration value
183
184 @return Value of Firmware Configuration item read
185
186**/
187UINT16
188EFIAPI
189QemuFwCfgRead16 (
190 VOID
191 )
192{
193 UINT16 Result;
194
195 QemuFwCfgReadBytes (sizeof (Result), &Result);
196
197 return Result;
198}
199
200
201/**
202 Reads a UINT32 firmware configuration value
203
204 @return Value of Firmware Configuration item read
205
206**/
207UINT32
208EFIAPI
209QemuFwCfgRead32 (
210 VOID
211 )
212{
213 UINT32 Result;
214
215 QemuFwCfgReadBytes (sizeof (Result), &Result);
216
217 return Result;
218}
219
220
221/**
222 Reads a UINT64 firmware configuration value
223
224 @return Value of Firmware Configuration item read
225
226**/
227UINT64
228EFIAPI
229QemuFwCfgRead64 (
230 VOID
231 )
232{
233 UINT64 Result;
234
235 QemuFwCfgReadBytes (sizeof (Result), &Result);
236
237 return Result;
238}
239
240
241/**
242 Find the configuration item corresponding to the firmware configuration file.
243
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.
248
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.
252
253**/
254RETURN_STATUS
255EFIAPI
256QemuFwCfgFindFile (
257 IN CONST CHAR8 *Name,
258 OUT FIRMWARE_CONFIG_ITEM *Item,
259 OUT UINTN *Size
260 )
261{
262 UINT32 Count;
263 UINT32 Idx;
264
265 if (!InternalQemuFwCfgIsAvailable ()) {
266 return RETURN_UNSUPPORTED;
267 }
268
269 QemuFwCfgSelectItem (QemuFwCfgItemFileDir);
270 Count = SwapBytes32 (QemuFwCfgRead32 ());
271
272 for (Idx = 0; Idx < Count; ++Idx) {
273 UINT32 FileSize;
274 UINT16 FileSelect;
275 UINT16 FileReserved;
276 CHAR8 FName[QEMU_FW_CFG_FNAME_SIZE];
277
278 FileSize = QemuFwCfgRead32 ();
279 FileSelect = QemuFwCfgRead16 ();
280 FileReserved = QemuFwCfgRead16 ();
281 (VOID) FileReserved; /* Force a do-nothing reference. */
282 InternalQemuFwCfgReadBytes (sizeof (FName), FName);
283
284 if (AsciiStrCmp (Name, FName) == 0) {
285 *Item = SwapBytes16 (FileSelect);
286 *Size = SwapBytes32 (FileSize);
287 return RETURN_SUCCESS;
288 }
289 }
290
291 return RETURN_NOT_FOUND;
292}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette