/** @file | |
S3 support for QEMU fw_cfg | |
This library class enables driver modules (a) to query whether S3 support was | |
enabled on the QEMU command line, (b) to produce fw_cfg DMA operations that | |
are to be replayed at S3 resume time. | |
Copyright (C) 2017, Red Hat, Inc. | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#ifndef __FW_CFG_S3_LIB__ | |
#define __FW_CFG_S3_LIB__ | |
#include <Base.h> | |
/** | |
Determine if S3 support is explicitly enabled. | |
@retval TRUE If S3 support is explicitly enabled. Other functions in this | |
library may be called (subject to their individual | |
restrictions). | |
FALSE Otherwise. This includes unavailability of the firmware | |
configuration interface. No other function in this library | |
must be called. | |
**/ | |
BOOLEAN | |
EFIAPI | |
QemuFwCfgS3Enabled ( | |
VOID | |
); | |
/** | |
Prototype for the callback function that the client module provides. | |
In the callback function, the client module calls the | |
QemuFwCfgS3ScriptWriteBytes(), QemuFwCfgS3ScriptReadBytes(), | |
QemuFwCfgS3ScriptSkipBytes(), and QemuFwCfgS3ScriptCheckValue() functions. | |
Those functions produce ACPI S3 Boot Script opcodes that will perform fw_cfg | |
DMA operations, and will check any desired values that were read, during S3 | |
resume. | |
The callback function is invoked when the production of ACPI S3 Boot Script | |
opcodes becomes possible. This may occur directly on the call stack of | |
QemuFwCfgS3CallWhenBootScriptReady() (see below), or after | |
QemuFwCfgS3CallWhenBootScriptReady() has successfully returned. | |
The callback function must not return if it fails -- in the general case, | |
there is noone to propagate any errors to. Therefore, on error, an error | |
message should be logged, and CpuDeadLoop() must be called. | |
@param[in,out] Context Carries information from the client module | |
itself (i.e., from the invocation of | |
QemuFwCfgS3CallWhenBootScriptReady()) to the | |
callback function. | |
If Context points to dynamically allocated | |
storage, then the callback function must | |
release it. | |
@param[in,out] ScratchBuffer Points to reserved memory, allocated by | |
QemuFwCfgS3CallWhenBootScriptReady() | |
internally. | |
ScratchBuffer is typed and sized by the client | |
module when it calls | |
QemuFwCfgS3CallWhenBootScriptReady(). The | |
client module defines a union type of | |
structures for ScratchBuffer such that the | |
union can hold client data for any desired | |
fw_cfg DMA read and write operations, and value | |
checking. | |
The callback function casts ScratchBuffer to | |
the union type described above. It passes union | |
member sizes as NumberOfBytes to | |
QemuFwCfgS3ScriptReadBytes() and | |
QemuFwCfgS3ScriptWriteBytes(). It passes field | |
addresses and sizes in structures in the union | |
as ScratchData and ValueSize to | |
QemuFwCfgS3ScriptCheckValue(). | |
ScratchBuffer is aligned at 8 bytes. | |
**/ | |
typedef | |
VOID(EFIAPI FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION)( | |
IN OUT VOID *Context OPTIONAL, | |
IN OUT VOID *ScratchBuffer | |
); | |
/** | |
Install the client module's FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION callback for | |
when the production of ACPI S3 Boot Script opcodes becomes possible. | |
Take ownership of the client-provided Context, and pass it to the callback | |
function, when the latter is invoked. | |
Allocate scratch space for those ACPI S3 Boot Script opcodes to work upon | |
that the client will produce in the callback function. | |
@param[in] Callback FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION to invoke | |
when the production of ACPI S3 Boot Script | |
opcodes becomes possible. Callback() may be | |
called immediately from | |
QemuFwCfgS3CallWhenBootScriptReady(). | |
@param[in,out] Context Client-provided data structure for the | |
Callback() callback function to consume. | |
If Context points to dynamically allocated | |
memory, then Callback() must release it. | |
If Context points to dynamically allocated | |
memory, and | |
QemuFwCfgS3CallWhenBootScriptReady() returns | |
successfully, then the caller of | |
QemuFwCfgS3CallWhenBootScriptReady() must | |
neither dereference nor even evaluate Context | |
any longer, as ownership of the referenced area | |
has been transferred to Callback(). | |
@param[in] ScratchBufferSize The size of the scratch buffer that will hold, | |
in reserved memory, all client data read, | |
written, and checked by the ACPI S3 Boot Script | |
opcodes produced by Callback(). | |
@retval RETURN_UNSUPPORTED The library instance does not support this | |
function. | |
@retval RETURN_NOT_FOUND The fw_cfg DMA interface to QEMU is | |
unavailable. | |
@retval RETURN_BAD_BUFFER_SIZE ScratchBufferSize is too large. | |
@retval RETURN_OUT_OF_RESOURCES Memory allocation failed. | |
@retval RETURN_SUCCESS Callback() has been installed, and the | |
ownership of Context has been transferred. | |
Reserved memory has been allocated for the | |
scratch buffer. | |
A successful invocation of | |
QemuFwCfgS3CallWhenBootScriptReady() cannot | |
be rolled back. | |
@return Error codes from underlying functions. | |
**/ | |
RETURN_STATUS | |
EFIAPI | |
QemuFwCfgS3CallWhenBootScriptReady ( | |
IN FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *Callback, | |
IN OUT VOID *Context OPTIONAL, | |
IN UINTN ScratchBufferSize | |
); | |
/** | |
Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item, | |
and transfer data to it. | |
The opcodes produced by QemuFwCfgS3ScriptWriteBytes() will first restore | |
NumberOfBytes bytes in ScratchBuffer in-place, in reserved memory, then write | |
them to fw_cfg using DMA. | |
If the operation fails during S3 resume, the boot script will hang. | |
This function may only be called from the client module's | |
FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to | |
QemuFwCfgS3CallWhenBootScriptReady() as Callback. | |
@param[in] FirmwareConfigItem The UINT16 selector key of the firmware config | |
item to write, expressed as INT32. If | |
FirmwareConfigItem is -1, no selection is | |
made, the write will occur to the currently | |
selected item, at its currently selected | |
offset. Otherwise, the specified item will be | |
selected, and the write will occur at offset | |
0. | |
@param[in] NumberOfBytes Size of the data to restore in ScratchBuffer, | |
and to write from ScratchBuffer, during S3 | |
resume. NumberOfBytes must not exceed | |
ScratchBufferSize, which was passed to | |
QemuFwCfgS3CallWhenBootScriptReady(). | |
@retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 | |
Boot Script successfully. There is no way | |
to undo this action. | |
@retval RETURN_INVALID_PARAMETER FirmwareConfigItem is invalid. | |
@retval RETURN_BAD_BUFFER_SIZE NumberOfBytes is larger than | |
ScratchBufferSize. | |
@return Error codes from underlying functions. | |
**/ | |
RETURN_STATUS | |
EFIAPI | |
QemuFwCfgS3ScriptWriteBytes ( | |
IN INT32 FirmwareConfigItem, | |
IN UINTN NumberOfBytes | |
); | |
/** | |
Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item, | |
and transfer data from it. | |
The opcodes produced by QemuFwCfgS3ScriptReadBytes() will read NumberOfBytes | |
bytes from fw_cfg using DMA, storing the result in ScratchBuffer, in reserved | |
memory. | |
If the operation fails during S3 resume, the boot script will hang. | |
This function may only be called from the client module's | |
FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to | |
QemuFwCfgS3CallWhenBootScriptReady() as Callback. | |
@param[in] FirmwareConfigItem The UINT16 selector key of the firmware config | |
item to read, expressed as INT32. If | |
FirmwareConfigItem is -1, no selection is | |
made, the read will occur from the currently | |
selected item, from its currently selected | |
offset. Otherwise, the specified item will be | |
selected, and the read will occur from offset | |
0. | |
@param[in] NumberOfBytes Size of the data to read during S3 resume. | |
NumberOfBytes must not exceed | |
ScratchBufferSize, which was passed to | |
QemuFwCfgS3CallWhenBootScriptReady(). | |
@retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 | |
Boot Script successfully. There is no way | |
to undo this action. | |
@retval RETURN_INVALID_PARAMETER FirmwareConfigItem is invalid. | |
@retval RETURN_BAD_BUFFER_SIZE NumberOfBytes is larger than | |
ScratchBufferSize. | |
@return Error codes from underlying functions. | |
**/ | |
RETURN_STATUS | |
EFIAPI | |
QemuFwCfgS3ScriptReadBytes ( | |
IN INT32 FirmwareConfigItem, | |
IN UINTN NumberOfBytes | |
); | |
/** | |
Produce ACPI S3 Boot Script opcodes that (optionally) select an fw_cfg item, | |
and increase its offset. | |
If the operation fails during S3 resume, the boot script will hang. | |
This function may only be called from the client module's | |
FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to | |
QemuFwCfgS3CallWhenBootScriptReady() as Callback. | |
@param[in] FirmwareConfigItem The UINT16 selector key of the firmware config | |
item to advance the offset of, expressed as | |
INT32. If FirmwareConfigItem is -1, no | |
selection is made, and the offset for the | |
currently selected item is increased. | |
Otherwise, the specified item will be | |
selected, and the offset increment will occur | |
from offset 0. | |
@param[in] NumberOfBytes The number of bytes to skip in the subject | |
fw_cfg item. | |
@retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 | |
Boot Script successfully. There is no way | |
to undo this action. | |
@retval RETURN_INVALID_PARAMETER FirmwareConfigItem is invalid. | |
@retval RETURN_BAD_BUFFER_SIZE NumberOfBytes is too large. | |
@return Error codes from underlying functions. | |
**/ | |
RETURN_STATUS | |
EFIAPI | |
QemuFwCfgS3ScriptSkipBytes ( | |
IN INT32 FirmwareConfigItem, | |
IN UINTN NumberOfBytes | |
); | |
/** | |
Produce ACPI S3 Boot Script opcodes that check a value in ScratchBuffer. | |
If the check fails during S3 resume, the boot script will hang. | |
This function may only be called from the client module's | |
FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION, which was passed to | |
QemuFwCfgS3CallWhenBootScriptReady() as Callback. | |
@param[in] ScratchData Pointer to the UINT8, UINT16, UINT32 or UINT64 field | |
in ScratchBuffer that should be checked. The caller | |
is responsible for populating the field during S3 | |
resume, by calling QemuFwCfgS3ScriptReadBytes() ahead | |
of QemuFwCfgS3ScriptCheckValue(). | |
ScratchData must point into ScratchBuffer, which was | |
allocated, and passed to Callback(), by | |
QemuFwCfgS3CallWhenBootScriptReady(). | |
ScratchData must be aligned at ValueSize bytes. | |
@param[in] ValueSize One of 1, 2, 4 or 8, specifying the size of the field | |
to check. | |
@param[in] ValueMask The value read from ScratchData is binarily AND-ed | |
with ValueMask, and the result is compared against | |
Value. If the masked data equals Value, the check | |
passes, and the boot script can proceed. Otherwise, | |
the check fails, and the boot script hangs. | |
@param[in] Value Refer to ValueMask. | |
@retval RETURN_SUCCESS The opcodes were appended to the ACPI S3 | |
Boot Script successfully. There is no way | |
to undo this action. | |
@retval RETURN_INVALID_PARAMETER ValueSize is invalid. | |
@retval RETURN_INVALID_PARAMETER ValueMask or Value cannot be represented in | |
ValueSize bytes. | |
@retval RETURN_INVALID_PARAMETER ScratchData is not aligned at ValueSize | |
bytes. | |
@retval RETURN_BAD_BUFFER_SIZE The ValueSize bytes at ScratchData aren't | |
wholly contained in the ScratchBufferSize | |
bytes at ScratchBuffer. | |
@return Error codes from underlying functions. | |
**/ | |
RETURN_STATUS | |
EFIAPI | |
QemuFwCfgS3ScriptCheckValue ( | |
IN VOID *ScratchData, | |
IN UINT8 ValueSize, | |
IN UINT64 ValueMask, | |
IN UINT64 Value | |
); | |
#endif |