+++ /dev/null
-/** @file\r
-\r
- Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
- \r\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
- \r\r
-\r
-Module Name:\r
-\r
-\r
- Recovery.c\r
-\r
-Abstract:\r
-\r
- Tiano PEIM to provide the platform recovery functionality.\r
-\r
---*/\r
-\r
-#include "PlatformEarlyInit.h"\r
-\r
-#define PEI_FVMAIN_COMPACT_GUID \\r
- {0x4A538818, 0x5AE0, 0x4eb2, 0xB2, 0xEB, 0x48, 0x8b, 0x23, 0x65, 0x70, 0x22};\r
-\r
-EFI_GUID FvMainCompactFileGuid = PEI_FVMAIN_COMPACT_GUID;\r
-\r
-//\r
-// Required Service\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-PlatformRecoveryModule (\r
- IN CONST EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_PEI_RECOVERY_MODULE_PPI *This\r
- );\r
-\r
-//\r
-// Module globals\r
-//\r
-\r
-typedef struct {\r
- EFI_GUID CapsuleGuid;\r
- UINT32 HeaderSize;\r
- UINT32 Flags;\r
- UINT32 CapsuleImageSize;\r
- UINT32 SequenceNumber;\r
- EFI_GUID InstanceId;\r
- UINT32 OffsetToSplitInformation;\r
- UINT32 OffsetToCapsuleBody;\r
- UINT32 OffsetToOemDefinedHeader;\r
- UINT32 OffsetToAuthorInformation;\r
- UINT32 OffsetToRevisionInformation;\r
- UINT32 OffsetToShortDescription;\r
- UINT32 OffsetToLongDescription;\r
- UINT32 OffsetToApplicableDevices;\r
-} OLD_EFI_CAPSULE_HEADER;\r
-\r
-\r
-static EFI_PEI_RECOVERY_MODULE_PPI mRecoveryPpi = {\r
- PlatformRecoveryModule\r
-};\r
-\r
-static EFI_PEI_PPI_DESCRIPTOR mRecoveryPpiList = {\r
- (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
- &gEfiPeiRecoveryModulePpiGuid,\r
- &mRecoveryPpi\r
-};\r
-\r
-/**\r
- Provide the functionality of the Recovery Module.\r
-\r
- @param PeiServices General purpose services available to every PEIM.\r
-\r
- @retval Status EFI_SUCCESS if the interface could be successfully\r
- installed\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PeimInitializeRecovery (\r
- IN CONST EFI_PEI_SERVICES **PeiServices\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- Status = (*PeiServices)->InstallPpi (\r
- PeiServices,\r
- &mRecoveryPpiList\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Provide the functionality of the Ea Recovery Module.\r
-\r
- @param PeiServices General purpose services available to every PEIM.\r
- @param This Pointer to PEI_RECOVERY_MODULE_INTERFACE.\r
-\r
- @retval EFI_SUCCESS If the interface could be successfully\r
- installed.\r
- @retval EFI_UNSUPPORTED Not supported.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PlatformRecoveryModule (\r
- IN CONST EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_PEI_RECOVERY_MODULE_PPI *This\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *DeviceRecoveryModule;\r
- UINTN NumberOfImageProviders;\r
- BOOLEAN ProviderAvailable;\r
- UINTN NumberRecoveryCapsules;\r
- UINTN RecoveryCapsuleSize;\r
- EFI_GUID DeviceId;\r
- BOOLEAN ImageFound;\r
- EFI_PHYSICAL_ADDRESS Address;\r
- VOID *Buffer;\r
- OLD_EFI_CAPSULE_HEADER *CapsuleHeader;\r
- EFI_PEI_HOB_POINTERS Hob;\r
- EFI_PEI_HOB_POINTERS HobOld;\r
- EFI_HOB_CAPSULE_VOLUME *CapsuleHob;\r
- BOOLEAN HobUpdate;\r
- EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
- UINTN Index;\r
- BOOLEAN FoundFvMain;\r
- BOOLEAN FoundCapsule;\r
- static EFI_GUID mEfiCapsuleHeaderGuid = EFI_CAPSULE_GUID;\r
- EFI_PEI_STALL_PPI *StallPpi;\r
-\r
- (*PeiServices)->ReportStatusCode (\r
- PeiServices,\r
- EFI_PROGRESS_CODE,\r
- EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_RECOVERY_BEGIN,\r
- 0,\r
- NULL,\r
- NULL\r
- );\r
-\r
- Status = (**PeiServices).LocatePpi (\r
- PeiServices,\r
- &gEfiPeiStallPpiGuid,\r
- 0,\r
- NULL,\r
- &StallPpi\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- StallPpi->Stall(\r
- PeiServices,\r
- StallPpi,\r
- 5000000\r
- );\r
-\r
-\r
- Index = 0;\r
-\r
- Status = EFI_SUCCESS;\r
- HobUpdate = FALSE;\r
-\r
- ProviderAvailable = TRUE;\r
- ImageFound = FALSE;\r
- NumberOfImageProviders = 0;\r
-\r
- DeviceRecoveryModule = NULL;\r
-\r
- FoundCapsule = FALSE;\r
- FoundFvMain = FALSE;\r
-\r
- DEBUG ((EFI_D_ERROR | EFI_D_LOAD, "Recovery Entry\n"));\r
-\r
- //\r
- // Search the platform for some recovery capsule if the DXE IPL\r
- // discovered a recovery condition and has requested a load.\r
- //\r
- while (ProviderAvailable == TRUE) {\r
-\r
- Status = (*PeiServices)->LocatePpi (\r
- PeiServices,\r
- &gEfiPeiDeviceRecoveryModulePpiGuid,\r
- Index,\r
- NULL,\r
- &DeviceRecoveryModule\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Device Recovery PPI located\n"));\r
- NumberOfImageProviders++;\r
-\r
- Status = DeviceRecoveryModule->GetNumberRecoveryCapsules (\r
- (EFI_PEI_SERVICES**)PeiServices,\r
- DeviceRecoveryModule,\r
- &NumberRecoveryCapsules\r
- );\r
-\r
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Number Of Recovery Capsules: %d\n", NumberRecoveryCapsules));\r
-\r
- if (NumberRecoveryCapsules == 0) {\r
- Index++;\r
- } else {\r
- break;\r
- }\r
- } else {\r
- ProviderAvailable = FALSE;\r
- }\r
- }\r
-\r
- //\r
- // If there is an image provider, get the capsule ID\r
- //\r
- if (ProviderAvailable) {\r
- RecoveryCapsuleSize = 0;\r
-\r
- Status = DeviceRecoveryModule->GetRecoveryCapsuleInfo (\r
- (EFI_PEI_SERVICES**)PeiServices,\r
- DeviceRecoveryModule,\r
- 0,\r
- &RecoveryCapsuleSize,\r
- &DeviceId\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Recovery Capsule Size: %d\n", RecoveryCapsuleSize));\r
-\r
- //\r
- // Only support the 2 capsule types known\r
- // Future enhancement is to rank-order the selection\r
- //\r
- if ((!CompareGuid (&DeviceId, &gRecoveryOnFatIdeDiskGuid)) &&\r
- (!CompareGuid (&DeviceId, &gRecoveryOnFatFloppyDiskGuid)) &&\r
- (!CompareGuid (&DeviceId, &gRecoveryOnDataCdGuid)) &&\r
- (!CompareGuid (&DeviceId, &gRecoveryOnFatUsbDiskGuid))\r
- ) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Buffer = NULL;\r
- Status = (*PeiServices)->AllocatePages (\r
- PeiServices,\r
- EfiBootServicesCode,\r
- (RecoveryCapsuleSize - 1) / 0x1000 + 1,\r
- &Address\r
- );\r
-\r
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "AllocatePage Returns: %r\n", Status));\r
-\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- Buffer = (UINT8 *) (UINTN) Address;\r
-\r
- (*PeiServices)->ReportStatusCode (\r
- PeiServices,\r
- EFI_PROGRESS_CODE,\r
- EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_CAPSULE_LOAD,\r
- 0,\r
- NULL,\r
- NULL\r
- );\r
-\r
- Status = DeviceRecoveryModule->LoadRecoveryCapsule (\r
- (EFI_PEI_SERVICES**)PeiServices,\r
- DeviceRecoveryModule,\r
- 0,\r
- Buffer\r
- );\r
-\r
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "LoadRecoveryCapsule Returns: %r\n", Status));\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Update FV Hob if found\r
- //\r
- Status = (*PeiServices)->GetHobList (PeiServices, &Hob.Raw);\r
- HobOld.Raw = Hob.Raw;\r
- while (!END_OF_HOB_LIST (Hob)) {\r
- if (Hob.Header->HobType == EFI_HOB_TYPE_FV) {\r
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Hob FV Length: %x\n", Hob.FirmwareVolume->Length));\r
- //\r
- // BUGBUG Why is it a FV hob if it is greater than 0x50000?\r
- //\r
- if (Hob.FirmwareVolume->Length > 0x50000) {\r
- HobUpdate = TRUE;\r
- //\r
- // This looks like the Hob we are interested in\r
- //\r
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Hob Updated\n"));\r
- Hob.FirmwareVolume->BaseAddress = (UINTN) Buffer;\r
- Hob.FirmwareVolume->Length = RecoveryCapsuleSize;\r
- }\r
- }\r
- Hob.Raw = GET_NEXT_HOB (Hob);\r
- }\r
-\r
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)Buffer;\r
- CapsuleHeader = (OLD_EFI_CAPSULE_HEADER *)Buffer;\r
-\r
- //\r
- // Check if top of file is a capsule\r
- //\r
- if (CompareGuid ((EFI_GUID *)CapsuleHeader, &mEfiCapsuleHeaderGuid)) {\r
- FoundCapsule = TRUE;\r
- } else if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
- //\r
- // Assume the Firmware volume is a "FVMAIN" image\r
- //\r
- FoundFvMain = TRUE;\r
- }\r
-\r
- if (FoundFvMain) {\r
- //\r
- // build FV Hob if it is not built before\r
- //\r
- if (!HobUpdate) {\r
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "FV Hob is not found, Build FV Hob then..\n"));\r
-\r
- BuildFvHob (\r
- (UINTN)FvHeader,\r
- FvHeader->FvLength\r
- );\r
- }\r
- }\r
-\r
- if (FoundCapsule) {\r
- //\r
- // Build capsule hob\r
- //\r
- Status = (*PeiServices)->CreateHob (\r
- PeiServices,\r
- EFI_HOB_TYPE_CV,\r
- sizeof (EFI_HOB_CAPSULE_VOLUME),\r
- &CapsuleHob\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- CapsuleHob->BaseAddress = (UINT64)((UINTN)CapsuleHeader + (UINTN)CapsuleHeader->OffsetToCapsuleBody);\r
- CapsuleHob->Length = (UINT64)((UINTN)CapsuleHeader->CapsuleImageSize -(UINTN)CapsuleHeader->OffsetToCapsuleBody);\r
- (*PeiServices)->ReportStatusCode (\r
- PeiServices,\r
- EFI_PROGRESS_CODE,\r
- EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEIM_PC_CAPSULE_START,\r
- 0,\r
- NULL,\r
- NULL\r
- );\r
- }\r
- }\r
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Recovery Module Returning: %r\n", Status));\r
- return Status;\r
-}\r