1 | /** @file
|
---|
2 | S3 support for QEMU fw_cfg
|
---|
3 |
|
---|
4 | This library class enables driver modules (a) to query whether S3 support was
|
---|
5 | enabled on the QEMU command line, (b) to produce fw_cfg DMA operations that
|
---|
6 | are to be replayed at S3 resume time.
|
---|
7 |
|
---|
8 | Copyright (C) 2017, Red Hat, Inc.
|
---|
9 |
|
---|
10 | SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
11 | **/
|
---|
12 |
|
---|
13 | #ifndef __FW_CFG_S3_LIB__
|
---|
14 | #define __FW_CFG_S3_LIB__
|
---|
15 |
|
---|
16 | #include <Base.h>
|
---|
17 |
|
---|
18 | /**
|
---|
19 | Determine if S3 support is explicitly enabled.
|
---|
20 |
|
---|
21 | @retval TRUE If S3 support is explicitly enabled. Other functions in this
|
---|
22 | library may be called (subject to their individual
|
---|
23 | restrictions).
|
---|
24 |
|
---|
25 | FALSE Otherwise. This includes unavailability of the firmware
|
---|
26 | configuration interface. No other function in this library
|
---|
27 | must be called.
|
---|
28 | **/
|
---|
29 | BOOLEAN
|
---|
30 | EFIAPI
|
---|
31 | QemuFwCfgS3Enabled (
|
---|
32 | VOID
|
---|
33 | );
|
---|
34 |
|
---|
35 |
|
---|
36 | /**
|
---|
37 | Prototype for the callback function that the client module provides.
|
---|
38 |
|
---|
39 | In the callback function, the client module calls the
|
---|
40 | QemuFwCfgS3ScriptWriteBytes(), QemuFwCfgS3ScriptReadBytes(),
|
---|
41 | QemuFwCfgS3ScriptSkipBytes(), and QemuFwCfgS3ScriptCheckValue() functions.
|
---|
42 | Those functions produce ACPI S3 Boot Script opcodes that will perform fw_cfg
|
---|
43 | DMA operations, and will check any desired values that were read, during S3
|
---|
44 | resume.
|
---|
45 |
|
---|
46 | The callback function is invoked when the production of ACPI S3 Boot Script
|
---|
47 | opcodes becomes possible. This may occur directly on the call stack of
|
---|
48 | QemuFwCfgS3CallWhenBootScriptReady() (see below), or after
|
---|
49 | QemuFwCfgS3CallWhenBootScriptReady() has successfully returned.
|
---|
50 |
|
---|
51 | The callback function must not return if it fails -- in the general case,
|
---|
52 | there is noone to propagate any errors to. Therefore, on error, an error
|
---|
53 | message should be logged, and CpuDeadLoop() must be called.
|
---|
54 |
|
---|
55 | @param[in,out] Context Carries information from the client module
|
---|
56 | itself (i.e., from the invocation of
|
---|
57 | QemuFwCfgS3CallWhenBootScriptReady()) to the
|
---|
58 | callback function.
|
---|
59 |
|
---|
60 | If Context points to dynamically allocated
|
---|
61 | storage, then the callback function must
|
---|
62 | release it.
|
---|
63 |
|
---|
64 | @param[in,out] ScratchBuffer Points to reserved memory, allocated by
|
---|
65 | QemuFwCfgS3CallWhenBootScriptReady()
|
---|
66 | internally.
|
---|
67 |
|
---|
68 | ScratchBuffer is typed and sized by the client
|
---|
69 | module when it calls
|
---|
70 | QemuFwCfgS3CallWhenBootScriptReady(). The
|
---|
71 | client module defines a union type of
|
---|
72 | structures for ScratchBuffer such that the
|
---|
73 | union can hold client data for any desired
|
---|
74 | fw_cfg DMA read and write operations, and value
|
---|
75 | checking.
|
---|
76 |
|
---|
77 | The callback function casts ScratchBuffer to
|
---|
78 | the union type described above. It passes union
|
---|
79 | member sizes as NumberOfBytes to
|
---|
80 | QemuFwCfgS3ScriptReadBytes() and
|
---|
81 | QemuFwCfgS3ScriptWriteBytes(). It passes field
|
---|
82 | addresses and sizes in structures in the union
|
---|
83 | as ScratchData and ValueSize to
|
---|
84 | QemuFwCfgS3ScriptCheckValue().
|
---|
85 |
|
---|
86 | ScratchBuffer is aligned at 8 bytes.
|
---|
87 | **/
|
---|
88 | typedef
|
---|
89 | VOID (EFIAPI FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION) (
|
---|
90 | IN OUT VOID *Context, OPTIONAL
|
---|
91 | IN OUT VOID *ScratchBuffer
|
---|
92 | );
|
---|
93 |
|
---|
94 |
|
---|
95 | /**
|
---|
96 | Install the client module's FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION callback for
|
---|
97 | when the production of ACPI S3 Boot Script opcodes becomes possible.
|
---|
98 |
|
---|
99 | Take ownership of the client-provided Context, and pass it to the callback
|
---|
100 | function, when the latter is invoked.
|
---|
101 |
|
---|
102 | Allocate scratch space for those ACPI S3 Boot Script opcodes to work upon
|
---|
103 | that the client will produce in the callback function.
|
---|
104 |
|
---|
105 | @param[in] Callback FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION to invoke
|
---|
106 | when the production of ACPI S3 Boot Script
|
---|
107 | opcodes becomes possible. Callback() may be
|
---|
108 | called immediately from
|
---|
109 | QemuFwCfgS3CallWhenBootScriptReady().
|
---|
110 |
|
---|
111 | @param[in,out] Context Client-provided data structure for the
|
---|
112 | Callback() callback function to consume.
|
---|
113 |
|
---|
114 | If Context points to dynamically allocated
|
---|
115 | memory, then Callback() must release it.
|
---|
116 |
|
---|
117 | If Context points to dynamically allocated
|
---|
118 | memory, and
|
---|
119 | QemuFwCfgS3CallWhenBootScriptReady() returns
|
---|
120 | successfully, then the caller of
|
---|
121 | QemuFwCfgS3CallWhenBootScriptReady() must
|
---|
122 | neither dereference nor even evaluate Context
|
---|
123 | any longer, as ownership of the referenced area
|
---|
124 | has been transferred to Callback().
|
---|
125 |
|
---|
126 | @param[in] ScratchBufferSize The size of the scratch buffer that will hold,
|
---|
127 | in reserved memory, all client data read,
|
---|
128 | written, and checked by the ACPI S3 Boot Script
|
---|
129 | opcodes produced by Callback().
|
---|
130 |
|
---|
131 | @retval RETURN_UNSUPPORTED The library instance does not support this
|
---|
132 | function.
|
---|
133 |
|
---|
134 | @retval RETURN_NOT_FOUND The fw_cfg DMA interface to QEMU is
|
---|
135 | unavailable.
|
---|
136 |
|
---|
137 | @retval RETURN_BAD_BUFFER_SIZE ScratchBufferSize is too large.
|
---|
138 |
|
---|
139 | @retval RETURN_OUT_OF_RESOURCES Memory allocation failed.
|
---|
140 |
|
---|
141 | @retval RETURN_SUCCESS Callback() has been installed, and the
|
---|
142 | ownership of Context has been transferred.
|
---|
143 | Reserved memory has been allocated for the
|
---|
144 | scratch buffer.
|
---|
145 |
|
---|
146 | A successful invocation of
|
---|
147 | QemuFwCfgS3CallWhenBootScriptReady() cannot
|
---|
148 | be rolled back.
|
---|
149 |
|
---|
150 | @return Error codes from underlying functions.
|
---|
151 | **/
|
---|
152 | RETURN_STATUS
|
---|
153 | EFIAPI
|
---|
154 | QemuFwCfgS3CallWhenBootScriptReady (
|
---|
155 | IN FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *Callback,
|
---|
156 | IN OUT VOID *Context, OPTIONAL
|
---|
157 | IN UINTN ScratchBufferSize
|
---|
158 | );
|
---|
159 |
|
---|
160 |
|
---|
161 | /**
|
---|
162 | Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item,
|
---|
163 | and transfer data to it.
|
---|
164 |
|
---|
165 | The opcodes produced by QemuFwCfgS3ScriptWriteBytes() will first restore
|
---|
166 | NumberOfBytes bytes in ScratchBuffer in-place, in reserved memory, then write
|
---|
167 | them to fw_cfg using DMA.
|
---|
168 |
|
---|
169 | If the operation fails during S3 resume, the boot script will hang.
|
---|
170 |
|
---|
171 | This function may only be called from the client module's
|
---|
172 | FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
|
---|
173 | QemuFwCfgS3CallWhenBootScriptReady() as Callback.
|
---|
174 |
|
---|
175 | @param[in] FirmwareConfigItem The UINT16 selector key of the firmware config
|
---|
176 | item to write, expressed as INT32. If
|
---|
177 | FirmwareConfigItem is -1, no selection is
|
---|
178 | made, the write will occur to the currently
|
---|
179 | selected item, at its currently selected
|
---|
180 | offset. Otherwise, the specified item will be
|
---|
181 | selected, and the write will occur at offset
|
---|
182 | 0.
|
---|
183 |
|
---|
184 | @param[in] NumberOfBytes Size of the data to restore in ScratchBuffer,
|
---|
185 | and to write from ScratchBuffer, during S3
|
---|
186 | resume. NumberOfBytes must not exceed
|
---|
187 | ScratchBufferSize, which was passed to
|
---|
188 | QemuFwCfgS3CallWhenBootScriptReady().
|
---|
189 |
|
---|
190 | @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3
|
---|
191 | Boot Script successfully. There is no way
|
---|
192 | to undo this action.
|
---|
193 |
|
---|
194 | @retval RETURN_INVALID_PARAMETER FirmwareConfigItem is invalid.
|
---|
195 |
|
---|
196 | @retval RETURN_BAD_BUFFER_SIZE NumberOfBytes is larger than
|
---|
197 | ScratchBufferSize.
|
---|
198 |
|
---|
199 | @return Error codes from underlying functions.
|
---|
200 | **/
|
---|
201 | RETURN_STATUS
|
---|
202 | EFIAPI
|
---|
203 | QemuFwCfgS3ScriptWriteBytes (
|
---|
204 | IN INT32 FirmwareConfigItem,
|
---|
205 | IN UINTN NumberOfBytes
|
---|
206 | );
|
---|
207 |
|
---|
208 |
|
---|
209 | /**
|
---|
210 | Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item,
|
---|
211 | and transfer data from it.
|
---|
212 |
|
---|
213 | The opcodes produced by QemuFwCfgS3ScriptReadBytes() will read NumberOfBytes
|
---|
214 | bytes from fw_cfg using DMA, storing the result in ScratchBuffer, in reserved
|
---|
215 | memory.
|
---|
216 |
|
---|
217 | If the operation fails during S3 resume, the boot script will hang.
|
---|
218 |
|
---|
219 | This function may only be called from the client module's
|
---|
220 | FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
|
---|
221 | QemuFwCfgS3CallWhenBootScriptReady() as Callback.
|
---|
222 |
|
---|
223 | @param[in] FirmwareConfigItem The UINT16 selector key of the firmware config
|
---|
224 | item to read, expressed as INT32. If
|
---|
225 | FirmwareConfigItem is -1, no selection is
|
---|
226 | made, the read will occur from the currently
|
---|
227 | selected item, from its currently selected
|
---|
228 | offset. Otherwise, the specified item will be
|
---|
229 | selected, and the read will occur from offset
|
---|
230 | 0.
|
---|
231 |
|
---|
232 | @param[in] NumberOfBytes Size of the data to read during S3 resume.
|
---|
233 | NumberOfBytes must not exceed
|
---|
234 | ScratchBufferSize, which was passed to
|
---|
235 | QemuFwCfgS3CallWhenBootScriptReady().
|
---|
236 |
|
---|
237 | @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3
|
---|
238 | Boot Script successfully. There is no way
|
---|
239 | to undo this action.
|
---|
240 |
|
---|
241 | @retval RETURN_INVALID_PARAMETER FirmwareConfigItem is invalid.
|
---|
242 |
|
---|
243 | @retval RETURN_BAD_BUFFER_SIZE NumberOfBytes is larger than
|
---|
244 | ScratchBufferSize.
|
---|
245 |
|
---|
246 | @return Error codes from underlying functions.
|
---|
247 | **/
|
---|
248 | RETURN_STATUS
|
---|
249 | EFIAPI
|
---|
250 | QemuFwCfgS3ScriptReadBytes (
|
---|
251 | IN INT32 FirmwareConfigItem,
|
---|
252 | IN UINTN NumberOfBytes
|
---|
253 | );
|
---|
254 |
|
---|
255 |
|
---|
256 | /**
|
---|
257 | Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item,
|
---|
258 | and increase its offset.
|
---|
259 |
|
---|
260 | If the operation fails during S3 resume, the boot script will hang.
|
---|
261 |
|
---|
262 | This function may only be called from the client module's
|
---|
263 | FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
|
---|
264 | QemuFwCfgS3CallWhenBootScriptReady() as Callback.
|
---|
265 |
|
---|
266 | @param[in] FirmwareConfigItem The UINT16 selector key of the firmware config
|
---|
267 | item to advance the offset of, expressed as
|
---|
268 | INT32. If FirmwareConfigItem is -1, no
|
---|
269 | selection is made, and the offset for the
|
---|
270 | currently selected item is increased.
|
---|
271 | Otherwise, the specified item will be
|
---|
272 | selected, and the offset increment will occur
|
---|
273 | from offset 0.
|
---|
274 |
|
---|
275 | @param[in] NumberOfBytes The number of bytes to skip in the subject
|
---|
276 | fw_cfg item.
|
---|
277 |
|
---|
278 | @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3
|
---|
279 | Boot Script successfully. There is no way
|
---|
280 | to undo this action.
|
---|
281 |
|
---|
282 | @retval RETURN_INVALID_PARAMETER FirmwareConfigItem is invalid.
|
---|
283 |
|
---|
284 | @retval RETURN_BAD_BUFFER_SIZE NumberOfBytes is too large.
|
---|
285 |
|
---|
286 | @return Error codes from underlying functions.
|
---|
287 | **/
|
---|
288 | RETURN_STATUS
|
---|
289 | EFIAPI
|
---|
290 | QemuFwCfgS3ScriptSkipBytes (
|
---|
291 | IN INT32 FirmwareConfigItem,
|
---|
292 | IN UINTN NumberOfBytes
|
---|
293 | );
|
---|
294 |
|
---|
295 |
|
---|
296 | /**
|
---|
297 | Produce ACPI S3 Boot Script opcodes that check a value in ScratchBuffer.
|
---|
298 |
|
---|
299 | If the check fails during S3 resume, the boot script will hang.
|
---|
300 |
|
---|
301 | This function may only be called from the client module's
|
---|
302 | FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to
|
---|
303 | QemuFwCfgS3CallWhenBootScriptReady() as Callback.
|
---|
304 |
|
---|
305 | @param[in] ScratchData Pointer to the UINT8, UINT16, UINT32 or UINT64 field
|
---|
306 | in ScratchBuffer that should be checked. The caller
|
---|
307 | is responsible for populating the field during S3
|
---|
308 | resume, by calling QemuFwCfgS3ScriptReadBytes() ahead
|
---|
309 | of QemuFwCfgS3ScriptCheckValue().
|
---|
310 |
|
---|
311 | ScratchData must point into ScratchBuffer, which was
|
---|
312 | allocated, and passed to Callback(), by
|
---|
313 | QemuFwCfgS3CallWhenBootScriptReady().
|
---|
314 |
|
---|
315 | ScratchData must be aligned at ValueSize bytes.
|
---|
316 |
|
---|
317 | @param[in] ValueSize One of 1, 2, 4 or 8, specifying the size of the field
|
---|
318 | to check.
|
---|
319 |
|
---|
320 | @param[in] ValueMask The value read from ScratchData is binarily AND-ed
|
---|
321 | with ValueMask, and the result is compared against
|
---|
322 | Value. If the masked data equals Value, the check
|
---|
323 | passes, and the boot script can proceed. Otherwise,
|
---|
324 | the check fails, and the boot script hangs.
|
---|
325 |
|
---|
326 | @param[in] Value Refer to ValueMask.
|
---|
327 |
|
---|
328 | @retval RETURN_SUCCESS The opcodes were appended to the ACPI S3
|
---|
329 | Boot Script successfully. There is no way
|
---|
330 | to undo this action.
|
---|
331 |
|
---|
332 | @retval RETURN_INVALID_PARAMETER ValueSize is invalid.
|
---|
333 |
|
---|
334 | @retval RETURN_INVALID_PARAMETER ValueMask or Value cannot be represented in
|
---|
335 | ValueSize bytes.
|
---|
336 |
|
---|
337 | @retval RETURN_INVALID_PARAMETER ScratchData is not aligned at ValueSize
|
---|
338 | bytes.
|
---|
339 |
|
---|
340 | @retval RETURN_BAD_BUFFER_SIZE The ValueSize bytes at ScratchData aren't
|
---|
341 | wholly contained in the ScratchBufferSize
|
---|
342 | bytes at ScratchBuffer.
|
---|
343 |
|
---|
344 | @return Error codes from underlying functions.
|
---|
345 | **/
|
---|
346 | RETURN_STATUS
|
---|
347 | EFIAPI
|
---|
348 | QemuFwCfgS3ScriptCheckValue (
|
---|
349 | IN VOID *ScratchData,
|
---|
350 | IN UINT8 ValueSize,
|
---|
351 | IN UINT64 ValueMask,
|
---|
352 | IN UINT64 Value
|
---|
353 | );
|
---|
354 |
|
---|
355 | #endif
|
---|