TianoCore EDK2 master
Loading...
Searching...
No Matches
BootScript.c
Go to the documentation of this file.
1
11#include <Library/BaseLib.h> // CpuDeadLoop()
12#include <Library/DebugLib.h> // DEBUG()
13#include <Library/MemoryAllocationLib.h> // AllocatePool()
14#include <Library/QemuFwCfgS3Lib.h> // QemuFwCfgS3ScriptSkipBytes()
15
16//
17// Condensed structure for capturing the fw_cfg operations -- select, skip,
18// write -- inherent in executing a QEMU_LOADER_WRITE_POINTER command.
19//
20typedef struct {
21 UINT16 PointerItem; // resolved from QEMU_LOADER_WRITE_POINTER.PointerFile
22 UINT8 PointerSize; // copied as-is from QEMU_LOADER_WRITE_POINTER
23 UINT32 PointerOffset; // copied as-is from QEMU_LOADER_WRITE_POINTER
24 UINT64 PointerValue; // resolved from QEMU_LOADER_WRITE_POINTER.PointeeFile
25 // and QEMU_LOADER_WRITE_POINTER.PointeeOffset
27
28//
29// Context structure to accumulate CONDENSED_WRITE_POINTER objects from
30// QEMU_LOADER_WRITE_POINTER commands.
31//
32// Any pointers in this structure own the pointed-to objects; that is, when the
33// context structure is released, all pointed-to objects must be released too.
34//
35struct S3_CONTEXT {
36 CONDENSED_WRITE_POINTER *WritePointers; // one array element per processed
37 // QEMU_LOADER_WRITE_POINTER
38 // command
39 UINTN Allocated; // number of elements allocated for
40 // WritePointers
41 UINTN Used; // number of elements populated in
42 // WritePointers
43};
44
45//
46// Scratch buffer, allocated in EfiReservedMemoryType type memory, for the ACPI
47// S3 Boot Script opcodes to work on.
48//
49#pragma pack (1)
50typedef union {
51 UINT64 PointerValue; // filled in from CONDENSED_WRITE_POINTER.PointerValue
53#pragma pack ()
54
73 OUT S3_CONTEXT **S3Context,
74 IN UINTN WritePointerCount
75 )
76{
77 EFI_STATUS Status;
78 S3_CONTEXT *Context;
79
80 if (WritePointerCount == 0) {
81 return EFI_INVALID_PARAMETER;
82 }
83
84 Context = AllocateZeroPool (sizeof *Context);
85 if (Context == NULL) {
86 return EFI_OUT_OF_RESOURCES;
87 }
88
89 Context->WritePointers = AllocatePool (
90 WritePointerCount *
91 sizeof *Context->WritePointers
92 );
93 if (Context->WritePointers == NULL) {
94 Status = EFI_OUT_OF_RESOURCES;
95 goto FreeContext;
96 }
97
98 Context->Allocated = WritePointerCount;
99 *S3Context = Context;
100 return EFI_SUCCESS;
101
102FreeContext:
103 FreePool (Context);
104
105 return Status;
106}
107
113VOID
115 IN S3_CONTEXT *S3Context
116 )
117{
118 FreePool (S3Context->WritePointers);
119 FreePool (S3Context);
120}
121
156 IN OUT S3_CONTEXT *S3Context,
157 IN UINT16 PointerItem,
158 IN UINT8 PointerSize,
159 IN UINT32 PointerOffset,
160 IN UINT64 PointerValue
161 )
162{
163 CONDENSED_WRITE_POINTER *Condensed;
164
165 if (S3Context->Used == S3Context->Allocated) {
166 return EFI_OUT_OF_RESOURCES;
167 }
168
169 Condensed = S3Context->WritePointers + S3Context->Used;
170 Condensed->PointerItem = PointerItem;
171 Condensed->PointerSize = PointerSize;
172 Condensed->PointerOffset = PointerOffset;
173 Condensed->PointerValue = PointerValue;
174 DEBUG ((
175 DEBUG_VERBOSE,
176 "%a: 0x%04x/[0x%08x+%d] := 0x%Lx (%Lu)\n",
177 __func__,
178 PointerItem,
179 PointerOffset,
180 PointerSize,
181 PointerValue,
182 (UINT64)S3Context->Used
183 ));
184 ++S3Context->Used;
185 return EFI_SUCCESS;
186}
187
191STATIC
192VOID
193EFIAPI
195 IN OUT VOID *Context OPTIONAL,
196 IN OUT VOID *ExternalScratchBuffer
197 )
198{
199 S3_CONTEXT *S3Context;
200 SCRATCH_BUFFER *ScratchBuffer;
201 UINTN Index;
202
203 S3Context = Context;
204 ScratchBuffer = ExternalScratchBuffer;
205
206 for (Index = 0; Index < S3Context->Used; ++Index) {
208 RETURN_STATUS Status;
209
210 Condensed = &S3Context->WritePointers[Index];
211
213 Condensed->PointerItem,
214 Condensed->PointerOffset
215 );
216 if (RETURN_ERROR (Status)) {
217 goto FatalError;
218 }
219
220 ScratchBuffer->PointerValue = Condensed->PointerValue;
221 Status = QemuFwCfgS3ScriptWriteBytes (-1, Condensed->PointerSize);
222 if (RETURN_ERROR (Status)) {
223 goto FatalError;
224 }
225 }
226
227 DEBUG ((DEBUG_VERBOSE, "%a: boot script fragment saved\n", __func__));
228
229 ReleaseS3Context (S3Context);
230 return;
231
232FatalError:
233 ASSERT (FALSE);
234 CpuDeadLoop ();
235}
236
259 IN S3_CONTEXT *S3Context
260 )
261{
262 RETURN_STATUS Status;
263
264 if (S3Context->Used == 0) {
265 ReleaseS3Context (S3Context);
266 return EFI_SUCCESS;
267 }
268
271 S3Context,
272 sizeof (SCRATCH_BUFFER)
273 );
274 return (EFI_STATUS)Status;
275}
UINT64 UINTN
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
EFI_STATUS SaveCondensedWritePointerToS3Context(IN OUT S3_CONTEXT *S3Context, IN UINT16 PointerItem, IN UINT8 PointerSize, IN UINT32 PointerOffset, IN UINT64 PointerValue)
Definition: BootScript.c:155
EFI_STATUS AllocateS3Context(OUT S3_CONTEXT **S3Context, IN UINTN WritePointerCount)
Definition: BootScript.c:72
EFI_STATUS TransferS3ContextToBootScript(IN S3_CONTEXT *S3Context)
Definition: BootScript.c:258
STATIC VOID EFIAPI AppendFwCfgBootScript(IN OUT VOID *Context OPTIONAL, IN OUT VOID *ExternalScratchBuffer)
Definition: BootScript.c:194
VOID ReleaseS3Context(IN S3_CONTEXT *S3Context)
Definition: BootScript.c:114
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define RETURN_ERROR(StatusCode)
Definition: Base.h:1061
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFIAPI QemuFwCfgS3ScriptWriteBytes(IN INT32 FirmwareConfigItem, IN UINTN NumberOfBytes)
RETURN_STATUS EFIAPI QemuFwCfgS3CallWhenBootScriptReady(IN FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *Callback, IN OUT VOID *Context OPTIONAL, IN UINTN ScratchBufferSize)
RETURN_STATUS EFIAPI QemuFwCfgS3ScriptSkipBytes(IN INT32 FirmwareConfigItem, IN UINTN NumberOfBytes)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112