/** Dispatch function for SMM lock box set attributes. @param LockBoxParameterSetAttributes parameter of lock box set attributes **/ VOID SmmLockBoxSetAttributes ( IN EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *LockBoxParameterSetAttributes ) { EFI_STATUS Status; EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES TempLockBoxParameterSetAttributes; // // Sanity check // if (mLocked) { DEBUG ((EFI_D_ERROR, "SmmLockBox Locked!\n")); LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED; return ; } CopyMem (&TempLockBoxParameterSetAttributes, LockBoxParameterSetAttributes, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES)); // // Update data // Status = SetLockBoxAttributes ( &TempLockBoxParameterSetAttributes.Guid, TempLockBoxParameterSetAttributes.Attributes ); LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)Status; return ; }
/** Entry point function of the Boot Script Thunk Helper SMM driver. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI BootScriptThunkHelperMain ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { BOOT_SCRIPT_THUNK_DATA *BootScriptThunkData; EFI_STATUS Status; // // Get BootScriptThunk variable // BootScriptThunkData = (BOOT_SCRIPT_THUNK_DATA *)(UINTN)PcdGet64(BootScriptThunkDataPtr); ASSERT (BootScriptThunkData != NULL); if (BootScriptThunkData == NULL) { return EFI_NOT_FOUND; } // // Save BootScriptThunk image // Status = SaveLockBox ( &mBootScriptThunkGuid, (VOID *)(UINTN)BootScriptThunkData->BootScriptThunkBase, (UINTN)BootScriptThunkData->BootScriptThunkLength ); ASSERT_EFI_ERROR (Status); Status = SetLockBoxAttributes (&mBootScriptThunkGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE); ASSERT_EFI_ERROR (Status); return Status; }
/** Entrypoint of Boot script exector driver, this function will be executed in normal boot phase and invoked by DXE dispatch. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI BootScriptExecutorEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { UINTN BufferSize; UINTN Pages; BOOT_SCRIPT_EXECUTOR_VARIABLE *EfiBootScriptExecutorVariable; EFI_PHYSICAL_ADDRESS BootScriptExecutorBuffer; EFI_STATUS Status; VOID *DevicePath; EFI_EVENT ReadyToLockEvent; VOID *Registration; UINT32 RegEax; UINT32 RegEdx; if (!PcdGetBool (PcdAcpiS3Enable)) { return EFI_UNSUPPORTED; } // // Test if the gEfiCallerIdGuid of this image is already installed. if not, the entry // point is loaded by DXE code which is the first time loaded. or else, it is already // be reloaded be itself.This is a work-around // Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &DevicePath); if (EFI_ERROR (Status)) { // // Create ReadyToLock event to reload BootScriptExecutor image // to RESERVED mem and save it to LockBox. // ReadyToLockEvent = EfiCreateProtocolNotifyEvent ( &gEfiDxeSmmReadyToLockProtocolGuid, TPL_NOTIFY, ReadyToLockEventNotify, NULL, &Registration ); ASSERT (ReadyToLockEvent != NULL); } else { // // the entry point is invoked after reloading. following code only run in RESERVED mem // if (PcdGetBool(PcdUse1GPageTable)) { AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); if (RegEax >= 0x80000001) { AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); if ((RegEdx & BIT26) != 0) { mPage1GSupport = TRUE; } } } BufferSize = sizeof (BOOT_SCRIPT_EXECUTOR_VARIABLE); BootScriptExecutorBuffer = 0xFFFFFFFF; Pages = EFI_SIZE_TO_PAGES(BufferSize); Status = gBS->AllocatePages ( AllocateMaxAddress, EfiReservedMemoryType, Pages, &BootScriptExecutorBuffer ); ASSERT_EFI_ERROR (Status); EfiBootScriptExecutorVariable = (BOOT_SCRIPT_EXECUTOR_VARIABLE *)(UINTN)BootScriptExecutorBuffer; EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint = (UINTN) S3BootScriptExecutorEntryFunction ; Status = SaveLockBox ( &gEfiBootScriptExecutorVariableGuid, &BootScriptExecutorBuffer, sizeof(BootScriptExecutorBuffer) ); ASSERT_EFI_ERROR (Status); // // Additional step for BootScript integrity // Save BootScriptExecutor context // Status = SaveLockBox ( &gEfiBootScriptExecutorContextGuid, EfiBootScriptExecutorVariable, sizeof(*EfiBootScriptExecutorVariable) ); ASSERT_EFI_ERROR (Status); Status = SetLockBoxAttributes (&gEfiBootScriptExecutorContextGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE); ASSERT_EFI_ERROR (Status); } return EFI_SUCCESS; }
/** This is the Event notification function to reload BootScriptExecutor image to RESERVED mem and save it to LockBox. @param Event Pointer to this event @param Context Event handler private data **/ VOID EFIAPI ReadyToLockEventNotify ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; VOID *Interface; UINT8 *Buffer; UINTN BufferSize; EFI_HANDLE NewImageHandle; UINTN Pages; EFI_PHYSICAL_ADDRESS FfsBuffer; PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; Status = gBS->LocateProtocol (&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface); if (EFI_ERROR (Status)) { return; } // // A workaround: Here we install a dummy handle // NewImageHandle = NULL; Status = gBS->InstallProtocolInterface ( &NewImageHandle, &gEfiCallerIdGuid, EFI_NATIVE_INTERFACE, NULL ); ASSERT_EFI_ERROR (Status); // // Reload BootScriptExecutor image itself to RESERVED mem // Status = GetSectionFromAnyFv ( &gEfiCallerIdGuid, EFI_SECTION_PE32, 0, (VOID **) &Buffer, &BufferSize ); ASSERT_EFI_ERROR (Status); ImageContext.Handle = Buffer; ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; // // Get information about the image being loaded // Status = PeCoffLoaderGetImageInfo (&ImageContext); ASSERT_EFI_ERROR (Status); if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) { Pages = EFI_SIZE_TO_PAGES ((UINTN) (ImageContext.ImageSize + ImageContext.SectionAlignment)); } else { Pages = EFI_SIZE_TO_PAGES ((UINTN) ImageContext.ImageSize); } FfsBuffer = 0xFFFFFFFF; Status = gBS->AllocatePages ( AllocateMaxAddress, EfiReservedMemoryType, Pages, &FfsBuffer ); ASSERT_EFI_ERROR (Status); ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer; // // Align buffer on section boundry // ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)(ImageContext.SectionAlignment - 1)); // // Load the image to our new buffer // Status = PeCoffLoaderLoadImage (&ImageContext); ASSERT_EFI_ERROR (Status); // // Relocate the image in our new buffer // Status = PeCoffLoaderRelocateImage (&ImageContext); ASSERT_EFI_ERROR (Status); // // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer // gBS->FreePool (Buffer); // // Flush the instruction cache so the image data is written before we execute it // InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); RegisterMemoryProfileImage ( &gEfiCallerIdGuid, ImageContext.ImageAddress, ImageContext.ImageSize, EFI_FV_FILETYPE_DRIVER ); Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, gST); ASSERT_EFI_ERROR (Status); // // Additional step for BootScript integrity // Save BootScriptExecutor image // Status = SaveLockBox ( &mBootScriptExecutorImageGuid, (VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize ); ASSERT_EFI_ERROR (Status); Status = SetLockBoxAttributes (&mBootScriptExecutorImageGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE); ASSERT_EFI_ERROR (Status); gBS->CloseEvent (Event); }
/** Prepares all information that is needed in the S3 resume boot path. Allocate the resources or prepare informations and save in ACPI variable set for S3 resume boot path @param This A pointer to the EFI_ACPI_S3_SAVE_PROTOCOL instance. @param LegacyMemoryAddress The base address of legacy memory. @retval EFI_NOT_FOUND Some necessary information cannot be found. @retval EFI_SUCCESS All information was saved successfully. @retval EFI_OUT_OF_RESOURCES Resources were insufficient to save all the information. @retval EFI_INVALID_PARAMETER The memory range is not located below 1 MB. **/ EFI_STATUS EFIAPI S3Ready ( IN EFI_ACPI_S3_SAVE_PROTOCOL *This, IN VOID *LegacyMemoryAddress ) { EFI_STATUS Status; EFI_PHYSICAL_ADDRESS AcpiS3ContextBuffer; ACPI_S3_CONTEXT *AcpiS3Context; STATIC BOOLEAN AlreadyEntered; IA32_DESCRIPTOR *Idtr; IA32_IDT_GATE_DESCRIPTOR *IdtGate; DEBUG ((EFI_D_INFO, "S3Ready!\n")); // // Platform may invoke AcpiS3Save->S3Save() before ExitPmAuth, because we need save S3 information there, while BDS ReadyToBoot may invoke it again. // So if 2nd S3Save() is triggered later, we need ignore it. // if (AlreadyEntered) { return EFI_SUCCESS; } AlreadyEntered = TRUE; AcpiS3Context = AllocateMemoryBelow4G (EfiReservedMemoryType, sizeof(*AcpiS3Context)); ASSERT (AcpiS3Context != NULL); AcpiS3ContextBuffer = (EFI_PHYSICAL_ADDRESS)(UINTN)AcpiS3Context; // // Get ACPI Table because we will save its position to variable // AcpiS3Context->AcpiFacsTable = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiFacsTable (); ASSERT (AcpiS3Context->AcpiFacsTable != 0); IdtGate = AllocateMemoryBelow4G (EfiReservedMemoryType, sizeof(IA32_IDT_GATE_DESCRIPTOR) * 0x100 + sizeof(IA32_DESCRIPTOR)); Idtr = (IA32_DESCRIPTOR *)(IdtGate + 0x100); Idtr->Base = (UINTN)IdtGate; Idtr->Limit = (UINT16)(sizeof(IA32_IDT_GATE_DESCRIPTOR) * 0x100 - 1); AcpiS3Context->IdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)Idtr; Status = SaveLockBox ( &mAcpiS3IdtrProfileGuid, (VOID *)(UINTN)Idtr, (UINTN)sizeof(IA32_DESCRIPTOR) ); ASSERT_EFI_ERROR (Status); Status = SetLockBoxAttributes (&mAcpiS3IdtrProfileGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE); ASSERT_EFI_ERROR (Status); // // Allocate page table // AcpiS3Context->S3NvsPageTableAddress = S3CreateIdentityMappingPageTables (); // // Allocate stack // AcpiS3Context->BootScriptStackSize = PcdGet32 (PcdS3BootScriptStackSize); AcpiS3Context->BootScriptStackBase = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, PcdGet32 (PcdS3BootScriptStackSize)); ASSERT (AcpiS3Context->BootScriptStackBase != 0); // // Allocate a code buffer < 4G for S3 debug to load external code // AcpiS3Context->S3DebugBufferAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, EFI_PAGE_SIZE); DEBUG((EFI_D_INFO, "AcpiS3Context: AcpiFacsTable is 0x%8x\n", AcpiS3Context->AcpiFacsTable)); DEBUG((EFI_D_INFO, "AcpiS3Context: IdtrProfile is 0x%8x\n", AcpiS3Context->IdtrProfile)); DEBUG((EFI_D_INFO, "AcpiS3Context: S3NvsPageTableAddress is 0x%8x\n", AcpiS3Context->S3NvsPageTableAddress)); DEBUG((EFI_D_INFO, "AcpiS3Context: S3DebugBufferAddress is 0x%8x\n", AcpiS3Context->S3DebugBufferAddress)); Status = SaveLockBox ( &gEfiAcpiVariableGuid, &AcpiS3ContextBuffer, sizeof(AcpiS3ContextBuffer) ); ASSERT_EFI_ERROR (Status); Status = SaveLockBox ( &gEfiAcpiS3ContextGuid, (VOID *)(UINTN)AcpiS3Context, (UINTN)sizeof(*AcpiS3Context) ); ASSERT_EFI_ERROR (Status); Status = SetLockBoxAttributes (&gEfiAcpiS3ContextGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE); ASSERT_EFI_ERROR (Status); if (FeaturePcdGet(PcdFrameworkCompatibilitySupport)) { S3ReadyThunkPlatform (AcpiS3Context); } return EFI_SUCCESS; }
/** Prepares all information that is needed in the S3 resume boot path. Allocate the resources or prepare informations and save in ACPI variable set for S3 resume boot path @retval EFI_SUCCESS All information was saved successfully. **/ STATIC EFI_STATUS EFIAPI S3Ready ( VOID ) { EFI_STATUS Status; EFI_PHYSICAL_ADDRESS AcpiS3ContextBuffer; ACPI_S3_CONTEXT *AcpiS3Context; STATIC BOOLEAN AlreadyEntered; IA32_DESCRIPTOR *Idtr; IA32_IDT_GATE_DESCRIPTOR *IdtGate; DEBUG ((EFI_D_INFO, "S3Ready!\n")); ASSERT (!AlreadyEntered); if (AlreadyEntered) { return EFI_SUCCESS; } AlreadyEntered = TRUE; AcpiS3Context = AllocateMemoryBelow4G (EfiReservedMemoryType, sizeof(*AcpiS3Context)); ASSERT (AcpiS3Context != NULL); AcpiS3ContextBuffer = (EFI_PHYSICAL_ADDRESS)(UINTN)AcpiS3Context; // // Get ACPI Table because we will save its position to variable // AcpiS3Context->AcpiFacsTable = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiFacsTable (); ASSERT (AcpiS3Context->AcpiFacsTable != 0); IdtGate = AllocateMemoryBelow4G (EfiReservedMemoryType, sizeof(IA32_IDT_GATE_DESCRIPTOR) * 0x100 + sizeof(IA32_DESCRIPTOR)); Idtr = (IA32_DESCRIPTOR *)(IdtGate + 0x100); Idtr->Base = (UINTN)IdtGate; Idtr->Limit = (UINT16)(sizeof(IA32_IDT_GATE_DESCRIPTOR) * 0x100 - 1); AcpiS3Context->IdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)Idtr; Status = SaveLockBox ( &mAcpiS3IdtrProfileGuid, (VOID *)(UINTN)Idtr, (UINTN)sizeof(IA32_DESCRIPTOR) ); ASSERT_EFI_ERROR (Status); Status = SetLockBoxAttributes (&mAcpiS3IdtrProfileGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE); ASSERT_EFI_ERROR (Status); // // Allocate page table // AcpiS3Context->S3NvsPageTableAddress = S3CreateIdentityMappingPageTables (); // // Allocate stack // AcpiS3Context->BootScriptStackSize = PcdGet32 (PcdS3BootScriptStackSize); AcpiS3Context->BootScriptStackBase = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, PcdGet32 (PcdS3BootScriptStackSize)); ASSERT (AcpiS3Context->BootScriptStackBase != 0); // // Allocate a code buffer < 4G for S3 debug to load external code, set invalid code instructions in it. // AcpiS3Context->S3DebugBufferAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, EFI_PAGE_SIZE); SetMem ((VOID *)(UINTN)AcpiS3Context->S3DebugBufferAddress, EFI_PAGE_SIZE, 0xff); DEBUG ((EFI_D_INFO, "AcpiS3Context: AcpiFacsTable is 0x%8Lx\n", AcpiS3Context->AcpiFacsTable)); DEBUG ((EFI_D_INFO, "AcpiS3Context: IdtrProfile is 0x%8Lx\n", AcpiS3Context->IdtrProfile)); DEBUG ((EFI_D_INFO, "AcpiS3Context: S3NvsPageTableAddress is 0x%8Lx\n", AcpiS3Context->S3NvsPageTableAddress)); DEBUG ((EFI_D_INFO, "AcpiS3Context: S3DebugBufferAddress is 0x%8Lx\n", AcpiS3Context->S3DebugBufferAddress)); Status = SaveLockBox ( &gEfiAcpiVariableGuid, &AcpiS3ContextBuffer, sizeof(AcpiS3ContextBuffer) ); ASSERT_EFI_ERROR (Status); Status = SaveLockBox ( &gEfiAcpiS3ContextGuid, (VOID *)(UINTN)AcpiS3Context, (UINTN)sizeof(*AcpiS3Context) ); ASSERT_EFI_ERROR (Status); Status = SetLockBoxAttributes (&gEfiAcpiS3ContextGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }
/** Entrypoint of Boot script exector driver, this function will be executed in normal boot phase and invoked by DXE dispatch. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI BootScriptExecutorEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { UINT8 *Buffer; UINTN BufferSize; UINTN Pages; EFI_PHYSICAL_ADDRESS FfsBuffer; PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; BOOT_SCRIPT_EXECUTOR_VARIABLE *EfiBootScriptExecutorVariable; EFI_PHYSICAL_ADDRESS BootScriptExecutorBuffer; EFI_STATUS Status; VOID *DevicePath; EFI_HANDLE NewImageHandle; // // Test if the gEfiCallerIdGuid of this image is already installed. if not, the entry // point is loaded by DXE code which is the first time loaded. or else, it is already // be reloaded be itself.This is a work-around // Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &DevicePath); if (EFI_ERROR (Status)) { // // This is the first-time loaded by DXE core. reload itself to NVS mem // // // A workarouond: Here we install a dummy handle // NewImageHandle = NULL; Status = gBS->InstallProtocolInterface ( &NewImageHandle, &gEfiCallerIdGuid, EFI_NATIVE_INTERFACE, NULL ); Status = GetSectionFromAnyFv ( &gEfiCallerIdGuid, EFI_SECTION_PE32, 0, (VOID **) &Buffer, &BufferSize ); ImageContext.Handle = Buffer; ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; // // Get information about the image being loaded // Status = PeCoffLoaderGetImageInfo (&ImageContext); if (EFI_ERROR (Status)) { return Status; } Pages = EFI_SIZE_TO_PAGES(BufferSize + ImageContext.SectionAlignment); FfsBuffer = 0xFFFFFFFF; Status = gBS->AllocatePages ( AllocateMaxAddress, EfiACPIMemoryNVS, Pages, &FfsBuffer ); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer; // // Align buffer on section boundry // ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1); // // Load the image to our new buffer // Status = PeCoffLoaderLoadImage (&ImageContext); if (EFI_ERROR (Status)) { gBS->FreePages (FfsBuffer, Pages); return Status; } // // Relocate the image in our new buffer // Status = PeCoffLoaderRelocateImage (&ImageContext); if (EFI_ERROR (Status)) { PeCoffLoaderUnloadImage (&ImageContext); gBS->FreePages (FfsBuffer, Pages); return Status; } // // Flush the instruction cache so the image data is written before we execute it // InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, SystemTable); if (EFI_ERROR (Status)) { gBS->FreePages (FfsBuffer, Pages); return Status; } // // Additional step for BootScript integrity // Save BootScriptExecutor image // Status = SaveLockBox ( &mBootScriptExecutorImageGuid, (VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize ); ASSERT_EFI_ERROR (Status); Status = SetLockBoxAttributes (&mBootScriptExecutorImageGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE); ASSERT_EFI_ERROR (Status); } else { // // the entry point is invoked after reloading. following code only run in ACPI NVS // BufferSize = sizeof (BOOT_SCRIPT_EXECUTOR_VARIABLE); BootScriptExecutorBuffer = 0xFFFFFFFF; Pages = EFI_SIZE_TO_PAGES(BufferSize); Status = gBS->AllocatePages ( AllocateMaxAddress, EfiACPIMemoryNVS, Pages, &BootScriptExecutorBuffer ); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } EfiBootScriptExecutorVariable = (BOOT_SCRIPT_EXECUTOR_VARIABLE *)(UINTN)BootScriptExecutorBuffer; EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint = (UINTN) S3BootScriptExecutorEntryFunction ; Status = SaveLockBox ( &gEfiBootScriptExecutorVariableGuid, &BootScriptExecutorBuffer, sizeof(BootScriptExecutorBuffer) ); ASSERT_EFI_ERROR (Status); // // Additional step for BootScript integrity // Save BootScriptExecutor context // Status = SaveLockBox ( &gEfiBootScriptExecutorContextGuid, EfiBootScriptExecutorVariable, sizeof(*EfiBootScriptExecutorVariable) ); ASSERT_EFI_ERROR (Status); Status = SetLockBoxAttributes (&gEfiBootScriptExecutorContextGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE); ASSERT_EFI_ERROR (Status); } return EFI_SUCCESS; }