| /** @file | |
| Esrt management module. | |
| Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #include "EsrtImpl.h" | |
| // | |
| // Module globals. | |
| // | |
| ESRT_PRIVATE_DATA mPrivate; | |
| ESRT_MANAGEMENT_PROTOCOL mEsrtManagementProtocolTemplate = { | |
| EsrtDxeGetEsrtEntry, | |
| EsrtDxeUpdateEsrtEntry, | |
| EsrtDxeRegisterEsrtEntry, | |
| EsrtDxeUnRegisterEsrtEntry, | |
| EsrtDxeSyncFmp, | |
| EsrtDxeLockEsrtRepository | |
| }; | |
| /** | |
| Get ESRT entry from ESRT Cache by FwClass Guid | |
| @param[in] FwClass FwClass of Esrt entry to get | |
| @param[in, out] Entry Esrt entry returned | |
| @retval EFI_SUCCESS The variable saving this Esrt Entry exists. | |
| @retval EF_NOT_FOUND No correct variable found. | |
| @retval EFI_WRITE_PROTECTED ESRT Cache repository is locked | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| EsrtDxeGetEsrtEntry ( | |
| IN EFI_GUID *FwClass, | |
| IN OUT EFI_SYSTEM_RESOURCE_ENTRY *Entry | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| if ((FwClass == NULL) || (Entry == NULL)) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| // | |
| // Find in Non-FMP Cached Esrt Repository | |
| // | |
| Status = GetEsrtEntry ( | |
| FwClass, | |
| ESRT_FROM_NONFMP, | |
| Entry | |
| ); | |
| EfiReleaseLock (&mPrivate.NonFmpLock); | |
| if (EFI_ERROR (Status)) { | |
| Status = EfiAcquireLockOrFail (&mPrivate.FmpLock); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| // | |
| // Find in FMP Cached Esrt NV Variable | |
| // | |
| Status = GetEsrtEntry ( | |
| FwClass, | |
| ESRT_FROM_FMP, | |
| Entry | |
| ); | |
| EfiReleaseLock (&mPrivate.FmpLock); | |
| } | |
| return Status; | |
| } | |
| /** | |
| Update one ESRT entry in ESRT Cache. | |
| @param[in] Entry Esrt entry to be updated | |
| @retval EFI_SUCCESS Successfully update an ESRT entry in cache. | |
| @retval EFI_INVALID_PARAMETER Entry does't exist in ESRT Cache | |
| @retval EFI_WRITE_PROTECTED ESRT Cache repositoy is locked | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| EsrtDxeUpdateEsrtEntry ( | |
| IN EFI_SYSTEM_RESOURCE_ENTRY *Entry | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| if (Entry == NULL) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| Status = EfiAcquireLockOrFail (&mPrivate.FmpLock); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| Status = UpdateEsrtEntry (Entry, ESRT_FROM_FMP); | |
| if (!EFI_ERROR (Status)) { | |
| EfiReleaseLock (&mPrivate.FmpLock); | |
| return Status; | |
| } | |
| EfiReleaseLock (&mPrivate.FmpLock); | |
| Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| Status = UpdateEsrtEntry (Entry, ESRT_FROM_NONFMP); | |
| EfiReleaseLock (&mPrivate.NonFmpLock); | |
| return Status; | |
| } | |
| /** | |
| Non-FMP instance to unregister Esrt Entry from ESRT Cache. | |
| @param[in] FwClass FwClass of Esrt entry to Unregister | |
| @retval EFI_SUCCESS Insert all entries Successfully | |
| @retval EFI_NOT_FOUND Entry of FwClass does not exsit | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| EsrtDxeUnRegisterEsrtEntry ( | |
| IN EFI_GUID *FwClass | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| if (FwClass == NULL) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| Status = DeleteEsrtEntry (FwClass, ESRT_FROM_NONFMP); | |
| EfiReleaseLock (&mPrivate.NonFmpLock); | |
| return Status; | |
| } | |
| /** | |
| Non-FMP instance to register one ESRT entry into ESRT Cache. | |
| @param[in] Entry Esrt entry to be set | |
| @retval EFI_SUCCESS Successfully set a variable. | |
| @retval EFI_INVALID_PARAMETER ESRT Entry is already exist | |
| @retval EFI_OUT_OF_RESOURCES Non-FMP ESRT repository is full | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| EsrtDxeRegisterEsrtEntry ( | |
| IN EFI_SYSTEM_RESOURCE_ENTRY *Entry | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EFI_SYSTEM_RESOURCE_ENTRY EsrtEntryTmp; | |
| if (Entry == NULL) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| Status = GetEsrtEntry ( | |
| &Entry->FwClass, | |
| ESRT_FROM_NONFMP, | |
| &EsrtEntryTmp | |
| ); | |
| if (Status == EFI_NOT_FOUND) { | |
| Status = InsertEsrtEntry (Entry, ESRT_FROM_NONFMP); | |
| } | |
| EfiReleaseLock (&mPrivate.NonFmpLock); | |
| return Status; | |
| } | |
| /** | |
| This function syn up Cached ESRT with data from FMP instances | |
| Function should be called after Connect All in order to locate all FMP protocols | |
| installed. | |
| @retval EFI_SUCCESS Successfully sync cache repository from FMP instances | |
| @retval EFI_NOT_FOUND No FMP Instance are found | |
| @retval EFI_OUT_OF_RESOURCES Resource allocaton fail | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| EsrtDxeSyncFmp ( | |
| VOID | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINTN Index1; | |
| UINTN Index2; | |
| UINTN Index3; | |
| EFI_HANDLE *HandleBuffer; | |
| EFI_FIRMWARE_MANAGEMENT_PROTOCOL **FmpBuf; | |
| UINTN NumberOfHandles; | |
| UINTN *DescriptorSizeBuf; | |
| EFI_FIRMWARE_IMAGE_DESCRIPTOR **FmpImageInfoBuf; | |
| EFI_FIRMWARE_IMAGE_DESCRIPTOR *TempFmpImageInfo; | |
| UINT8 *FmpImageInfoCountBuf; | |
| UINT32 *FmpImageInfoDescriptorVerBuf; | |
| UINTN ImageInfoSize; | |
| UINT32 PackageVersion; | |
| CHAR16 *PackageVersionName; | |
| EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepositoryNew; | |
| UINTN EntryNumNew; | |
| NumberOfHandles = 0; | |
| EntryNumNew = 0; | |
| FmpBuf = NULL; | |
| HandleBuffer = NULL; | |
| FmpImageInfoBuf = NULL; | |
| FmpImageInfoCountBuf = NULL; | |
| PackageVersionName = NULL; | |
| DescriptorSizeBuf = NULL; | |
| FmpImageInfoDescriptorVerBuf = NULL; | |
| EsrtRepositoryNew = NULL; | |
| // | |
| // Get image information from all FMP protocol | |
| // | |
| Status = gBS->LocateHandleBuffer ( | |
| ByProtocol, | |
| &gEfiFirmwareManagementProtocolGuid, | |
| NULL, | |
| &NumberOfHandles, | |
| &HandleBuffer | |
| ); | |
| if (Status == EFI_NOT_FOUND) { | |
| EntryNumNew = 0; | |
| goto UPDATE_REPOSITORY; | |
| } else if (EFI_ERROR (Status)) { | |
| goto END; | |
| } | |
| // | |
| // Allocate buffer to hold new FMP ESRT Cache repository | |
| // | |
| EsrtRepositoryNew = AllocateZeroPool (PcdGet32 (PcdMaxFmpEsrtCacheNum) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)); | |
| if (EsrtRepositoryNew == NULL) { | |
| Status = EFI_OUT_OF_RESOURCES; | |
| goto END; | |
| } | |
| FmpBuf = AllocatePool (sizeof (EFI_FIRMWARE_MANAGEMENT_PROTOCOL *) * NumberOfHandles); | |
| if (FmpBuf == NULL) { | |
| Status = EFI_OUT_OF_RESOURCES; | |
| goto END; | |
| } | |
| FmpImageInfoBuf = AllocateZeroPool (sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR *) * NumberOfHandles); | |
| if (FmpImageInfoBuf == NULL) { | |
| Status = EFI_OUT_OF_RESOURCES; | |
| goto END; | |
| } | |
| FmpImageInfoCountBuf = AllocateZeroPool (sizeof (UINT8) * NumberOfHandles); | |
| if (FmpImageInfoCountBuf == NULL) { | |
| Status = EFI_OUT_OF_RESOURCES; | |
| goto END; | |
| } | |
| DescriptorSizeBuf = AllocateZeroPool (sizeof (UINTN) * NumberOfHandles); | |
| if (DescriptorSizeBuf == NULL) { | |
| Status = EFI_OUT_OF_RESOURCES; | |
| goto END; | |
| } | |
| FmpImageInfoDescriptorVerBuf = AllocateZeroPool (sizeof (UINT32) * NumberOfHandles); | |
| if (FmpImageInfoDescriptorVerBuf == NULL) { | |
| Status = EFI_OUT_OF_RESOURCES; | |
| goto END; | |
| } | |
| // | |
| // Get all FmpImageInfo Descriptor into FmpImageInfoBuf | |
| // | |
| for (Index1 = 0; Index1 < NumberOfHandles; Index1++) { | |
| Status = gBS->HandleProtocol ( | |
| HandleBuffer[Index1], | |
| &gEfiFirmwareManagementProtocolGuid, | |
| (VOID **)&FmpBuf[Index1] | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| continue; | |
| } | |
| ImageInfoSize = 0; | |
| Status = FmpBuf[Index1]->GetImageInfo ( | |
| FmpBuf[Index1], | |
| &ImageInfoSize, | |
| NULL, | |
| NULL, | |
| NULL, | |
| NULL, | |
| NULL, | |
| NULL | |
| ); | |
| if (Status == EFI_BUFFER_TOO_SMALL) { | |
| FmpImageInfoBuf[Index1] = AllocateZeroPool (ImageInfoSize); | |
| if (FmpImageInfoBuf[Index1] == NULL) { | |
| Status = EFI_OUT_OF_RESOURCES; | |
| goto END; | |
| } | |
| } else { | |
| continue; | |
| } | |
| PackageVersionName = NULL; | |
| Status = FmpBuf[Index1]->GetImageInfo ( | |
| FmpBuf[Index1], | |
| &ImageInfoSize, | |
| FmpImageInfoBuf[Index1], | |
| &FmpImageInfoDescriptorVerBuf[Index1], | |
| &FmpImageInfoCountBuf[Index1], | |
| &DescriptorSizeBuf[Index1], | |
| &PackageVersion, | |
| &PackageVersionName | |
| ); | |
| // | |
| // If FMP GetInformation interface failed, skip this resource | |
| // | |
| if (EFI_ERROR (Status)) { | |
| FmpImageInfoCountBuf[Index1] = 0; | |
| continue; | |
| } | |
| if (PackageVersionName != NULL) { | |
| FreePool (PackageVersionName); | |
| } | |
| } | |
| // | |
| // Create new FMP cache repository based on FmpImageInfoBuf | |
| // | |
| for (Index2 = 0; Index2 < NumberOfHandles; Index2++) { | |
| TempFmpImageInfo = FmpImageInfoBuf[Index2]; | |
| for (Index3 = 0; Index3 < FmpImageInfoCountBuf[Index2]; Index3++) { | |
| if ( ((TempFmpImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IN_USE) != 0) | |
| && ((TempFmpImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IN_USE) != 0)) | |
| { | |
| // | |
| // Always put the first smallest version of Image info into ESRT cache | |
| // | |
| for (Index1 = 0; Index1 < EntryNumNew; Index1++) { | |
| if (CompareGuid (&EsrtRepositoryNew[Index1].FwClass, &TempFmpImageInfo->ImageTypeId)) { | |
| if (EsrtRepositoryNew[Index1].FwVersion > TempFmpImageInfo->Version) { | |
| SetEsrtEntryFromFmpInfo (&EsrtRepositoryNew[Index1], TempFmpImageInfo, FmpImageInfoDescriptorVerBuf[Index2]); | |
| } | |
| break; | |
| } | |
| } | |
| // | |
| // New ImageTypeId can't be found in EsrtRepositoryNew. Create a new one | |
| // | |
| if (Index1 == EntryNumNew) { | |
| SetEsrtEntryFromFmpInfo (&EsrtRepositoryNew[EntryNumNew], TempFmpImageInfo, FmpImageInfoDescriptorVerBuf[Index2]); | |
| EntryNumNew++; | |
| if (EntryNumNew >= PcdGet32 (PcdMaxFmpEsrtCacheNum)) { | |
| break; | |
| } | |
| } | |
| } | |
| // | |
| // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version | |
| // | |
| TempFmpImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)TempFmpImageInfo + DescriptorSizeBuf[Index2]); | |
| } | |
| } | |
| UPDATE_REPOSITORY: | |
| Status = EfiAcquireLockOrFail (&mPrivate.FmpLock); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| Status = gRT->SetVariable ( | |
| EFI_ESRT_FMP_VARIABLE_NAME, | |
| &gEfiCallerIdGuid, | |
| EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, | |
| EntryNumNew * sizeof (EFI_SYSTEM_RESOURCE_ENTRY), | |
| EsrtRepositoryNew | |
| ); | |
| EfiReleaseLock (&mPrivate.FmpLock); | |
| END: | |
| if (EsrtRepositoryNew != NULL) { | |
| FreePool (EsrtRepositoryNew); | |
| } | |
| if (HandleBuffer != NULL) { | |
| FreePool (HandleBuffer); | |
| } | |
| if (FmpBuf != NULL) { | |
| FreePool (FmpBuf); | |
| } | |
| if (FmpImageInfoCountBuf != NULL) { | |
| FreePool (FmpImageInfoCountBuf); | |
| } | |
| if (DescriptorSizeBuf != NULL) { | |
| FreePool (DescriptorSizeBuf); | |
| } | |
| if (FmpImageInfoDescriptorVerBuf != NULL) { | |
| FreePool (FmpImageInfoDescriptorVerBuf); | |
| } | |
| if (FmpImageInfoBuf != NULL) { | |
| for (Index1 = 0; Index1 < NumberOfHandles; Index1++) { | |
| if (FmpImageInfoBuf[Index1] != NULL) { | |
| FreePool (FmpImageInfoBuf[Index1]); | |
| } | |
| } | |
| FreePool (FmpImageInfoBuf); | |
| } | |
| return Status; | |
| } | |
| /** | |
| This function locks up Esrt repository to be readonly. It should be called | |
| before gEfiEndOfDxeEventGroupGuid event signaled | |
| @retval EFI_SUCCESS Locks up FMP Non-FMP repository successfully | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| EsrtDxeLockEsrtRepository ( | |
| VOID | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock; | |
| // | |
| // Mark ACPI_GLOBAL_VARIABLE variable to read-only if the Variable Lock protocol exists | |
| // | |
| Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLock); | |
| if (!EFI_ERROR (Status)) { | |
| Status = VariableLock->RequestToLock (VariableLock, EFI_ESRT_FMP_VARIABLE_NAME, &gEfiCallerIdGuid); | |
| DEBUG ((DEBUG_INFO, "EsrtDxe Lock EsrtFmp Variable Status 0x%x", Status)); | |
| Status = VariableLock->RequestToLock (VariableLock, EFI_ESRT_NONFMP_VARIABLE_NAME, &gEfiCallerIdGuid); | |
| DEBUG ((DEBUG_INFO, "EsrtDxe Lock EsrtNonFmp Variable Status 0x%x", Status)); | |
| } | |
| return Status; | |
| } | |
| /** | |
| Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to | |
| install the Esrt Table into system configuration table | |
| @param[in] Event The Event that is being processed. | |
| @param[in] Context The Event Context. | |
| **/ | |
| VOID | |
| EFIAPI | |
| EsrtReadyToBootEventNotify ( | |
| IN EFI_EVENT Event, | |
| IN VOID *Context | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EFI_SYSTEM_RESOURCE_TABLE *EsrtTable; | |
| EFI_SYSTEM_RESOURCE_ENTRY *FmpEsrtRepository; | |
| EFI_SYSTEM_RESOURCE_ENTRY *NonFmpEsrtRepository; | |
| UINTN FmpRepositorySize; | |
| UINTN NonFmpRepositorySize; | |
| FmpEsrtRepository = NULL; | |
| NonFmpEsrtRepository = NULL; | |
| FmpRepositorySize = 0; | |
| NonFmpRepositorySize = 0; | |
| Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock); | |
| if (EFI_ERROR (Status)) { | |
| return; | |
| } | |
| Status = GetVariable2 ( | |
| EFI_ESRT_NONFMP_VARIABLE_NAME, | |
| &gEfiCallerIdGuid, | |
| (VOID **)&NonFmpEsrtRepository, | |
| &NonFmpRepositorySize | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| NonFmpRepositorySize = 0; | |
| } | |
| if (NonFmpRepositorySize % sizeof (EFI_SYSTEM_RESOURCE_ENTRY) != 0) { | |
| DEBUG ((DEBUG_ERROR, "NonFmp Repository Corrupt. Need to rebuild NonFmp Repository.\n")); | |
| NonFmpRepositorySize = 0; | |
| } | |
| EfiReleaseLock (&mPrivate.NonFmpLock); | |
| Status = EfiAcquireLockOrFail (&mPrivate.FmpLock); | |
| Status = GetVariable2 ( | |
| EFI_ESRT_FMP_VARIABLE_NAME, | |
| &gEfiCallerIdGuid, | |
| (VOID **)&FmpEsrtRepository, | |
| &FmpRepositorySize | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| FmpRepositorySize = 0; | |
| } | |
| if (FmpRepositorySize % sizeof (EFI_SYSTEM_RESOURCE_ENTRY) != 0) { | |
| DEBUG ((DEBUG_ERROR, "Fmp Repository Corrupt. Need to rebuild Fmp Repository.\n")); | |
| FmpRepositorySize = 0; | |
| } | |
| EfiReleaseLock (&mPrivate.FmpLock); | |
| // | |
| // Skip ESRT table publish if no ESRT entry exists | |
| // | |
| if (NonFmpRepositorySize + FmpRepositorySize == 0) { | |
| goto EXIT; | |
| } | |
| EsrtTable = AllocatePool (sizeof (EFI_SYSTEM_RESOURCE_TABLE) + NonFmpRepositorySize + FmpRepositorySize); | |
| if (EsrtTable == NULL) { | |
| DEBUG ((DEBUG_ERROR, "Esrt table memory allocation failure\n")); | |
| goto EXIT; | |
| } | |
| EsrtTable->FwResourceVersion = EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION; | |
| EsrtTable->FwResourceCount = (UINT32)((NonFmpRepositorySize + FmpRepositorySize) / sizeof (EFI_SYSTEM_RESOURCE_ENTRY)); | |
| EsrtTable->FwResourceCountMax = PcdGet32 (PcdMaxNonFmpEsrtCacheNum) + PcdGet32 (PcdMaxFmpEsrtCacheNum); | |
| if ((NonFmpRepositorySize != 0) && (NonFmpEsrtRepository != NULL)) { | |
| CopyMem (EsrtTable + 1, NonFmpEsrtRepository, NonFmpRepositorySize); | |
| } | |
| if ((FmpRepositorySize != 0) && (FmpEsrtRepository != NULL)) { | |
| CopyMem ((UINT8 *)(EsrtTable + 1) + NonFmpRepositorySize, FmpEsrtRepository, FmpRepositorySize); | |
| } | |
| // | |
| // Publish Esrt to system config table | |
| // | |
| Status = gBS->InstallConfigurationTable (&gEfiSystemResourceTableGuid, EsrtTable); | |
| // | |
| // Only one successful install | |
| // | |
| gBS->CloseEvent (Event); | |
| EXIT: | |
| if (FmpEsrtRepository != NULL) { | |
| FreePool (FmpEsrtRepository); | |
| } | |
| if (NonFmpEsrtRepository != NULL) { | |
| FreePool (NonFmpEsrtRepository); | |
| } | |
| } | |
| /** | |
| The module Entry Point of the Esrt DXE driver that manages cached ESRT repository | |
| & publishes ESRT table | |
| @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 | |
| EsrtDxeEntryPoint ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EfiInitializeLock (&mPrivate.FmpLock, TPL_CALLBACK); | |
| EfiInitializeLock (&mPrivate.NonFmpLock, TPL_CALLBACK); | |
| // | |
| // Install Esrt management Protocol | |
| // | |
| Status = gBS->InstallMultipleProtocolInterfaces ( | |
| &mPrivate.Handle, | |
| &gEsrtManagementProtocolGuid, | |
| &mEsrtManagementProtocolTemplate, | |
| NULL | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| // | |
| // Register notify function to install Esrt Table on ReadyToBoot Event. | |
| // | |
| Status = gBS->CreateEventEx ( | |
| EVT_NOTIFY_SIGNAL, | |
| TPL_CALLBACK, | |
| EsrtReadyToBootEventNotify, | |
| NULL, | |
| &gEfiEventReadyToBootGuid, | |
| &mPrivate.Event | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| return EFI_SUCCESS; | |
| } |