]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Universal / Acpi / BootScriptExecutorDxe / ScriptExecute.c
CommitLineData
be46cd5f 1/** @file\r
2 This is the code for Boot Script Executer module.\r
3\r
59cc677c 4 This driver is dispatched by Dxe core and the driver will reload itself to ACPI reserved memory\r
be46cd5f 5 in the entry point. The functionality is to interpret and restore the S3 boot script\r
6\r
306a5836 7Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
ab1a5a58 8Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
be46cd5f 9\r
9d510e61 10SPDX-License-Identifier: BSD-2-Clause-Patent\r
be46cd5f 11\r
12**/\r
13\r
14#include "ScriptExecute.h"\r
15\r
1436aea4 16EFI_GUID mBootScriptExecutorImageGuid = {\r
ce68d3bc 17 0x9a8d3433, 0x9fe8, 0x42b6, { 0x87, 0xb, 0x1e, 0x31, 0xc8, 0x4e, 0xbe, 0x3b }\r
be46cd5f 18};\r
19\r
1436aea4
MK
20BOOLEAN mPage1GSupport = FALSE;\r
21UINT64 mAddressEncMask = 0;\r
59cc677c 22\r
be46cd5f 23/**\r
24 Entry function of Boot script exector. This function will be executed in\r
25 S3 boot path.\r
26 This function should not return, because it is invoked by switch stack.\r
27\r
28 @param AcpiS3Context a pointer to a structure of ACPI_S3_CONTEXT\r
29 @param PeiS3ResumeState a pointer to a structure of PEI_S3_RESUME_STATE\r
30\r
31 @retval EFI_INVALID_PARAMETER - OS waking vector not found\r
32 @retval EFI_UNSUPPORTED - something wrong when we resume to OS\r
33**/\r
34EFI_STATUS\r
35EFIAPI\r
36S3BootScriptExecutorEntryFunction (\r
1436aea4
MK
37 IN ACPI_S3_CONTEXT *AcpiS3Context,\r
38 IN PEI_S3_RESUME_STATE *PeiS3ResumeState\r
be46cd5f 39 )\r
40{\r
41 EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;\r
42 EFI_STATUS Status;\r
43 UINTN TempStackTop;\r
44 UINTN TempStack[0x10];\r
45 UINTN AsmTransferControl16Address;\r
933d80a1 46 IA32_DESCRIPTOR IdtDescriptor;\r
be46cd5f 47\r
be46cd5f 48 //\r
49 // Disable interrupt of Debug timer, since new IDT table cannot handle it.\r
50 //\r
51 SaveAndSetDebugTimerInterrupt (FALSE);\r
52\r
933d80a1 53 AsmReadIdtr (&IdtDescriptor);\r
be46cd5f 54 //\r
55 // Restore IDT for debug\r
56 //\r
57 SetIdtEntry (AcpiS3Context);\r
58\r
59 //\r
933d80a1 60 // Initialize Debug Agent to support source level debug in S3 path, it will disable interrupt and Debug Timer.\r
be46cd5f 61 //\r
933d80a1 62 InitializeDebugAgent (DEBUG_AGENT_INIT_S3, (VOID *)&IdtDescriptor, NULL);\r
be46cd5f 63\r
64 //\r
65 // Because not install BootScriptExecute PPI(used just in this module), So just pass NULL\r
66 // for that parameter.\r
67 //\r
be46cd5f 68 Status = S3BootScriptExecute ();\r
d1102dba 69\r
c48abbed
SQ
70 //\r
71 // If invalid script table or opcode in S3 boot script table.\r
72 //\r
73 ASSERT_EFI_ERROR (Status);\r
d1102dba 74\r
c48abbed
SQ
75 if (EFI_ERROR (Status)) {\r
76 CpuDeadLoop ();\r
77 return Status;\r
78 }\r
37623a5c 79\r
be46cd5f 80 AsmWbinvd ();\r
81\r
82 //\r
83 // Get ACPI Table Address\r
84 //\r
1436aea4 85 Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)((UINTN)(AcpiS3Context->AcpiFacsTable));\r
be46cd5f 86\r
be46cd5f 87 //\r
88 // We need turn back to S3Resume - install boot script done ppi and report status code on S3resume.\r
89 //\r
90 if (PeiS3ResumeState != 0) {\r
17dd0f2b 91 //\r
d1102dba 92 // Need report status back to S3ResumePeim.\r
17dd0f2b 93 // If boot script execution is failed, S3ResumePeim wil report the error status code.\r
94 //\r
95 PeiS3ResumeState->ReturnStatus = (UINT64)(UINTN)Status;\r
be46cd5f 96 if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
97 //\r
98 // X64 S3 Resume\r
99 //\r
558f58e3 100 DEBUG ((DEBUG_INFO, "Call AsmDisablePaging64() to return to S3 Resume in PEI Phase\n"));\r
be46cd5f 101 PeiS3ResumeState->AsmTransferControl = (EFI_PHYSICAL_ADDRESS)(UINTN)AsmTransferControl32;\r
102\r
37623a5c 103 if ((Facs != NULL) &&\r
104 (Facs->Signature == EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) &&\r
1436aea4
MK
105 (Facs->FirmwareWakingVector != 0))\r
106 {\r
37623a5c 107 //\r
108 // more step needed - because relative address is handled differently between X64 and IA32.\r
109 //\r
110 AsmTransferControl16Address = (UINTN)AsmTransferControl16;\r
1436aea4
MK
111 AsmFixAddress16 = (UINT32)AsmTransferControl16Address;\r
112 AsmJmpAddr32 = (UINT32)((Facs->FirmwareWakingVector & 0xF) | ((Facs->FirmwareWakingVector & 0xFFFF0) << 12));\r
37623a5c 113 }\r
be46cd5f 114\r
115 AsmDisablePaging64 (\r
116 PeiS3ResumeState->ReturnCs,\r
117 (UINT32)PeiS3ResumeState->ReturnEntryPoint,\r
118 (UINT32)(UINTN)AcpiS3Context,\r
119 (UINT32)(UINTN)PeiS3ResumeState,\r
120 (UINT32)PeiS3ResumeState->ReturnStackPointer\r
121 );\r
122 } else {\r
123 //\r
124 // IA32 S3 Resume\r
125 //\r
558f58e3 126 DEBUG ((DEBUG_INFO, "Call SwitchStack() to return to S3 Resume in PEI Phase\n"));\r
be46cd5f 127 PeiS3ResumeState->AsmTransferControl = (EFI_PHYSICAL_ADDRESS)(UINTN)AsmTransferControl;\r
128\r
129 SwitchStack (\r
130 (SWITCH_STACK_ENTRY_POINT)(UINTN)PeiS3ResumeState->ReturnEntryPoint,\r
131 (VOID *)(UINTN)AcpiS3Context,\r
132 (VOID *)(UINTN)PeiS3ResumeState,\r
133 (VOID *)(UINTN)PeiS3ResumeState->ReturnStackPointer\r
134 );\r
135 }\r
136\r
137 //\r
138 // Never run to here\r
139 //\r
1436aea4 140 CpuDeadLoop ();\r
be46cd5f 141 return EFI_UNSUPPORTED;\r
142 }\r
d1102dba 143\r
37623a5c 144 //\r
145 // S3ResumePeim does not provide a way to jump back to itself, so resume to OS here directly\r
146 //\r
be46cd5f 147 if (Facs->XFirmwareWakingVector != 0) {\r
148 //\r
149 // Switch to native waking vector\r
150 //\r
1436aea4 151 TempStackTop = (UINTN)&TempStack + sizeof (TempStack);\r
be46cd5f 152 if ((Facs->Version == EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) &&\r
153 ((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0) &&\r
1436aea4
MK
154 ((Facs->OspmFlags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0))\r
155 {\r
be46cd5f 156 //\r
157 // X64 long mode waking vector\r
158 //\r
558f58e3 159 DEBUG ((DEBUG_INFO, "Transfer to 64bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));\r
be46cd5f 160 if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
161 SwitchStack (\r
162 (SWITCH_STACK_ENTRY_POINT)(UINTN)Facs->XFirmwareWakingVector,\r
163 NULL,\r
164 NULL,\r
165 (VOID *)(UINTN)TempStackTop\r
166 );\r
167 } else {\r
168 // Unsupported for 32bit DXE, 64bit OS vector\r
1436aea4 169 DEBUG ((DEBUG_ERROR, "Unsupported for 32bit DXE transfer to 64bit OS waking vector!\r\n"));\r
be46cd5f 170 ASSERT (FALSE);\r
171 }\r
172 } else {\r
173 //\r
174 // IA32 protected mode waking vector (Page disabled)\r
175 //\r
558f58e3 176 DEBUG ((DEBUG_INFO, "Transfer to 32bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));\r
be46cd5f 177 if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
178 AsmDisablePaging64 (\r
179 0x10,\r
180 (UINT32)Facs->XFirmwareWakingVector,\r
181 0,\r
182 0,\r
183 (UINT32)TempStackTop\r
184 );\r
185 } else {\r
186 SwitchStack (\r
187 (SWITCH_STACK_ENTRY_POINT)(UINTN)Facs->XFirmwareWakingVector,\r
188 NULL,\r
189 NULL,\r
190 (VOID *)(UINTN)TempStackTop\r
191 );\r
192 }\r
193 }\r
194 } else {\r
195 //\r
196 // 16bit Realmode waking vector\r
197 //\r
558f58e3 198 DEBUG ((DEBUG_INFO, "Transfer to 16bit OS waking vector - %x\r\n", (UINTN)Facs->FirmwareWakingVector));\r
be46cd5f 199 AsmTransferControl (Facs->FirmwareWakingVector, 0x0);\r
200 }\r
201\r
202 //\r
203 // Never run to here\r
204 //\r
1436aea4 205 CpuDeadLoop ();\r
be46cd5f 206 return EFI_UNSUPPORTED;\r
207}\r
59cc677c 208\r
84edd20b
SZ
209/**\r
210 Register image to memory profile.\r
211\r
212 @param FileName File name of the image.\r
213 @param ImageBase Image base address.\r
214 @param ImageSize Image size.\r
215 @param FileType File type of the image.\r
216\r
217**/\r
218VOID\r
219RegisterMemoryProfileImage (\r
1436aea4
MK
220 IN EFI_GUID *FileName,\r
221 IN PHYSICAL_ADDRESS ImageBase,\r
222 IN UINT64 ImageSize,\r
223 IN EFI_FV_FILETYPE FileType\r
84edd20b
SZ
224 )\r
225{\r
1436aea4
MK
226 EFI_STATUS Status;\r
227 EDKII_MEMORY_PROFILE_PROTOCOL *ProfileProtocol;\r
228 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath;\r
229 UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)];\r
84edd20b
SZ
230\r
231 if ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT0) != 0) {\r
84edd20b 232 FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer;\r
1436aea4 233 Status = gBS->LocateProtocol (&gEdkiiMemoryProfileGuid, NULL, (VOID **)&ProfileProtocol);\r
84edd20b
SZ
234 if (!EFI_ERROR (Status)) {\r
235 EfiInitializeFwVolDevicepathNode (FilePath, FileName);\r
236 SetDevicePathEndNode (FilePath + 1);\r
237\r
238 Status = ProfileProtocol->RegisterImage (\r
239 ProfileProtocol,\r
1436aea4 240 (EFI_DEVICE_PATH_PROTOCOL *)FilePath,\r
84edd20b
SZ
241 ImageBase,\r
242 ImageSize,\r
243 FileType\r
244 );\r
245 }\r
246 }\r
247}\r
248\r
59cc677c
SZ
249/**\r
250 This is the Event notification function to reload BootScriptExecutor image\r
251 to RESERVED mem and save it to LockBox.\r
d1102dba 252\r
59cc677c 253 @param Event Pointer to this event\r
d1102dba 254 @param Context Event handler private data\r
59cc677c
SZ
255 **/\r
256VOID\r
257EFIAPI\r
258ReadyToLockEventNotify (\r
259 IN EFI_EVENT Event,\r
260 IN VOID *Context\r
261 )\r
262{\r
1436aea4
MK
263 EFI_STATUS Status;\r
264 VOID *Interface;\r
265 UINT8 *Buffer;\r
266 UINTN BufferSize;\r
267 EFI_HANDLE NewImageHandle;\r
268 UINTN Pages;\r
269 EFI_PHYSICAL_ADDRESS FfsBuffer;\r
270 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
271 EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc;\r
59cc677c
SZ
272\r
273 Status = gBS->LocateProtocol (&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface);\r
274 if (EFI_ERROR (Status)) {\r
275 return;\r
276 }\r
277\r
278 //\r
279 // A workaround: Here we install a dummy handle\r
280 //\r
281 NewImageHandle = NULL;\r
1436aea4
MK
282 Status = gBS->InstallProtocolInterface (\r
283 &NewImageHandle,\r
284 &gEfiCallerIdGuid,\r
285 EFI_NATIVE_INTERFACE,\r
286 NULL\r
287 );\r
59cc677c
SZ
288 ASSERT_EFI_ERROR (Status);\r
289\r
290 //\r
291 // Reload BootScriptExecutor image itself to RESERVED mem\r
292 //\r
1436aea4 293 Status = GetSectionFromAnyFv (\r
59cc677c
SZ
294 &gEfiCallerIdGuid,\r
295 EFI_SECTION_PE32,\r
296 0,\r
1436aea4 297 (VOID **)&Buffer,\r
59cc677c
SZ
298 &BufferSize\r
299 );\r
300 ASSERT_EFI_ERROR (Status);\r
301 ImageContext.Handle = Buffer;\r
302 ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
303 //\r
304 // Get information about the image being loaded\r
305 //\r
306 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
307 ASSERT_EFI_ERROR (Status);\r
32a81741 308 if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {\r
1436aea4 309 Pages = EFI_SIZE_TO_PAGES ((UINTN)(ImageContext.ImageSize + ImageContext.SectionAlignment));\r
32a81741 310 } else {\r
1436aea4 311 Pages = EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize);\r
32a81741 312 }\r
1436aea4 313\r
59cc677c 314 FfsBuffer = 0xFFFFFFFF;\r
1436aea4
MK
315 Status = gBS->AllocatePages (\r
316 AllocateMaxAddress,\r
317 EfiReservedMemoryType,\r
318 Pages,\r
319 &FfsBuffer\r
320 );\r
59cc677c 321 ASSERT_EFI_ERROR (Status);\r
6a3094c9
JW
322\r
323 //\r
324 // Make sure that the buffer can be used to store code.\r
325 //\r
326 Status = gDS->GetMemorySpaceDescriptor (FfsBuffer, &MemDesc);\r
1436aea4 327 if (!EFI_ERROR (Status) && ((MemDesc.Attributes & EFI_MEMORY_XP) != 0)) {\r
6a3094c9
JW
328 gDS->SetMemorySpaceAttributes (\r
329 FfsBuffer,\r
330 EFI_PAGES_TO_SIZE (Pages),\r
331 MemDesc.Attributes & (~EFI_MEMORY_XP)\r
332 );\r
333 }\r
334\r
59cc677c
SZ
335 ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;\r
336 //\r
0a18956d 337 // Align buffer on section boundary\r
59cc677c
SZ
338 //\r
339 ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;\r
16f69227 340 ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);\r
59cc677c
SZ
341 //\r
342 // Load the image to our new buffer\r
343 //\r
344 Status = PeCoffLoaderLoadImage (&ImageContext);\r
345 ASSERT_EFI_ERROR (Status);\r
346\r
347 //\r
348 // Relocate the image in our new buffer\r
349 //\r
350 Status = PeCoffLoaderRelocateImage (&ImageContext);\r
351 ASSERT_EFI_ERROR (Status);\r
352\r
353 //\r
354 // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer\r
355 //\r
356 gBS->FreePool (Buffer);\r
357\r
358 //\r
359 // Flush the instruction cache so the image data is written before we execute it\r
360 //\r
361 InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);\r
84edd20b
SZ
362\r
363 RegisterMemoryProfileImage (\r
364 &gEfiCallerIdGuid,\r
365 ImageContext.ImageAddress,\r
366 ImageContext.ImageSize,\r
367 EFI_FV_FILETYPE_DRIVER\r
368 );\r
369\r
1436aea4 370 Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint))(NewImageHandle, gST);\r
59cc677c
SZ
371 ASSERT_EFI_ERROR (Status);\r
372\r
373 //\r
374 // Additional step for BootScript integrity\r
375 // Save BootScriptExecutor image\r
376 //\r
377 Status = SaveLockBox (\r
378 &mBootScriptExecutorImageGuid,\r
379 (VOID *)(UINTN)ImageContext.ImageAddress,\r
380 (UINTN)ImageContext.ImageSize\r
381 );\r
382 ASSERT_EFI_ERROR (Status);\r
383\r
384 Status = SetLockBoxAttributes (&mBootScriptExecutorImageGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);\r
385 ASSERT_EFI_ERROR (Status);\r
386\r
387 gBS->CloseEvent (Event);\r
388}\r
389\r
be46cd5f 390/**\r
391 Entrypoint of Boot script exector driver, this function will be executed in\r
392 normal boot phase and invoked by DXE dispatch.\r
393\r
394 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
395 @param[in] SystemTable A pointer to the EFI System Table.\r
396\r
397 @retval EFI_SUCCESS The entry point is executed successfully.\r
398 @retval other Some error occurs when executing this entry point.\r
399**/\r
400EFI_STATUS\r
401EFIAPI\r
402BootScriptExecutorEntryPoint (\r
1436aea4
MK
403 IN EFI_HANDLE ImageHandle,\r
404 IN EFI_SYSTEM_TABLE *SystemTable\r
be46cd5f 405 )\r
406{\r
1436aea4
MK
407 UINTN BufferSize;\r
408 UINTN Pages;\r
409 BOOT_SCRIPT_EXECUTOR_VARIABLE *EfiBootScriptExecutorVariable;\r
410 EFI_PHYSICAL_ADDRESS BootScriptExecutorBuffer;\r
411 EFI_STATUS Status;\r
412 VOID *DevicePath;\r
413 EFI_EVENT ReadyToLockEvent;\r
414 VOID *Registration;\r
415 UINT32 RegEax;\r
416 UINT32 RegEdx;\r
be46cd5f 417\r
800c02fb
SZ
418 if (!PcdGetBool (PcdAcpiS3Enable)) {\r
419 return EFI_UNSUPPORTED;\r
420 }\r
421\r
ab1a5a58
LD
422 //\r
423 // Make sure AddressEncMask is contained to smallest supported address field.\r
424 //\r
425 mAddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;\r
426\r
be46cd5f 427 //\r
428 // Test if the gEfiCallerIdGuid of this image is already installed. if not, the entry\r
429 // point is loaded by DXE code which is the first time loaded. or else, it is already\r
430 // be reloaded be itself.This is a work-around\r
431 //\r
432 Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &DevicePath);\r
433 if (EFI_ERROR (Status)) {\r
1436aea4
MK
434 //\r
435 // Create ReadyToLock event to reload BootScriptExecutor image\r
436 // to RESERVED mem and save it to LockBox.\r
437 //\r
438 ReadyToLockEvent = EfiCreateProtocolNotifyEvent (\r
439 &gEfiDxeSmmReadyToLockProtocolGuid,\r
440 TPL_NOTIFY,\r
441 ReadyToLockEventNotify,\r
442 NULL,\r
443 &Registration\r
444 );\r
445 ASSERT (ReadyToLockEvent != NULL);\r
446 } else {\r
447 //\r
448 // the entry point is invoked after reloading. following code only run in RESERVED mem\r
449 //\r
450 if (PcdGetBool (PcdUse1GPageTable)) {\r
451 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
452 if (RegEax >= 0x80000001) {\r
453 AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);\r
454 if ((RegEdx & BIT26) != 0) {\r
455 mPage1GSupport = TRUE;\r
59cc677c
SZ
456 }\r
457 }\r
1436aea4 458 }\r
59cc677c 459\r
1436aea4 460 BufferSize = sizeof (BOOT_SCRIPT_EXECUTOR_VARIABLE);\r
be46cd5f 461\r
1436aea4
MK
462 BootScriptExecutorBuffer = 0xFFFFFFFF;\r
463 Pages = EFI_SIZE_TO_PAGES (BufferSize);\r
464 Status = gBS->AllocatePages (\r
465 AllocateMaxAddress,\r
466 EfiReservedMemoryType,\r
467 Pages,\r
468 &BootScriptExecutorBuffer\r
469 );\r
470 ASSERT_EFI_ERROR (Status);\r
be46cd5f 471\r
1436aea4
MK
472 EfiBootScriptExecutorVariable = (BOOT_SCRIPT_EXECUTOR_VARIABLE *)(UINTN)BootScriptExecutorBuffer;\r
473 EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint = (UINTN)S3BootScriptExecutorEntryFunction;\r
be46cd5f 474\r
1436aea4
MK
475 Status = SaveLockBox (\r
476 &gEfiBootScriptExecutorVariableGuid,\r
477 &BootScriptExecutorBuffer,\r
478 sizeof (BootScriptExecutorBuffer)\r
479 );\r
480 ASSERT_EFI_ERROR (Status);\r
be46cd5f 481\r
1436aea4
MK
482 //\r
483 // Additional step for BootScript integrity\r
484 // Save BootScriptExecutor context\r
485 //\r
486 Status = SaveLockBox (\r
487 &gEfiBootScriptExecutorContextGuid,\r
488 EfiBootScriptExecutorVariable,\r
489 sizeof (*EfiBootScriptExecutorVariable)\r
490 );\r
491 ASSERT_EFI_ERROR (Status);\r
492\r
493 Status = SetLockBoxAttributes (&gEfiBootScriptExecutorContextGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);\r
494 ASSERT_EFI_ERROR (Status);\r
495 }\r
be46cd5f 496\r
1436aea4 497 return EFI_SUCCESS;\r
be46cd5f 498}\r