} else {\r
DEBUG ((EFI_D_ERROR, "Fail to process FV %p because no corresponding EFI_FIRMWARE_VOLUME_PPI is found!\n", FvInfoPpi->FvInfo));\r
\r
- //\r
- // If can not find EFI_FIRMWARE_VOLUME_PPI to process firmware to get FvHandle, \r
- // use the address of FV buffer as its handle.\r
- //\r
- FvHandle = FvInfoPpi->FvInfo;\r
- \r
- //\r
- // Check whether the FV has already been processed.\r
- //\r
- for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex ++) {\r
- if (PrivateData->Fv[FvIndex].FvHandle == FvHandle) {\r
- DEBUG ((EFI_D_INFO, "The Fv %p has already been processed!\n", FvHandle));\r
- return EFI_SUCCESS;\r
- }\r
- } \r
- \r
- PrivateData->Fv[PrivateData->FvCount].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) FvInfoPpi->FvInfo;\r
- PrivateData->Fv[PrivateData->FvCount].FvPpi = NULL;\r
- PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;\r
- PrivateData->FvCount ++;\r
+ AddUnknownFormatFvInfo (PrivateData, &FvInfoPpi->FvFormat, FvInfoPpi->FvInfo, FvInfoPpi->FvInfoSize);\r
}\r
\r
return EFI_SUCCESS;\r
}\r
} \r
\r
+/**\r
+ Report the information for a new discoveried FV in unknown third-party format.\r
+ \r
+ If the EFI_PEI_FIRMWARE_VOLUME_PPI has not been installed for third-party FV format, but\r
+ the FV in this format has been discoveried, then this FV's information will be cached into \r
+ PEI_CORE_INSTANCE's UnknownFvInfo array.\r
+ Also a notification would be installed for unknown third-party FV format guid, if EFI_PEI_FIRMWARE_VOLUME_PPI\r
+ is installed later by platform's PEIM, the original unknown third-party FV will be processed by\r
+ using new installed EFI_PEI_FIRMWARE_VOLUME_PPI.\r
+ \r
+ @param PrivateData Point to instance of PEI_CORE_INSTANCE\r
+ @param Format Point to the unknown third-party format guid.\r
+ @param FvInfo Point to FvInfo buffer.\r
+ @param FvInfoSize The size of FvInfo buffer.\r
+ \r
+ @retval EFI_OUT_OF_RESOURCES The FV info array in PEI_CORE_INSTANCE has no more spaces.\r
+ @retval EFI_SUCCESS Success to add the information for unknown FV.\r
+**/\r
+EFI_STATUS\r
+AddUnknownFormatFvInfo (\r
+ IN PEI_CORE_INSTANCE *PrivateData,\r
+ IN EFI_GUID *Format,\r
+ IN VOID *FvInfo,\r
+ IN UINT32 FvInfoSize\r
+ )\r
+{\r
+ PEI_CORE_UNKNOW_FORMAT_FV_INFO *NewUnknownFv;\r
+ \r
+ if (PrivateData->UnknownFvInfoCount + 1 >= FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ \r
+ NewUnknownFv = &PrivateData->UnknownFvInfo[PrivateData->UnknownFvInfoCount];\r
+ PrivateData->UnknownFvInfoCount ++;\r
+ \r
+ CopyGuid (&NewUnknownFv->FvFormat, Format);\r
+ NewUnknownFv->FvInfo = FvInfo;\r
+ NewUnknownFv->FvInfoSize = FvInfoSize;\r
+ NewUnknownFv->NotifyDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r
+ NewUnknownFv->NotifyDescriptor.Guid = &NewUnknownFv->FvFormat;\r
+ NewUnknownFv->NotifyDescriptor.Notify = ThirdPartyFvPpiNotifyCallback;\r
+ \r
+ PeiServicesNotifyPpi (&NewUnknownFv->NotifyDescriptor);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Find the FV information according to third-party FV format guid.\r
+ \r
+ This routine also will remove the FV information found by given FV format guid from\r
+ PrivateData->UnknownFvInfo[].\r
+ \r
+ @param PrivateData Point to instance of PEI_CORE_INSTANCE\r
+ @param Format Point to given FV format guid\r
+ @param FvInfo On return, the pointer of FV information buffer\r
+ @param FvInfoSize On return, the size of FV information buffer.\r
+ \r
+ @retval EFI_NOT_FOUND The FV is not found for new installed EFI_PEI_FIRMWARE_VOLUME_PPI\r
+ @retval EFI_SUCCESS Success to find a FV which could be processed by new installed EFI_PEI_FIRMWARE_VOLUME_PPI.\r
+**/\r
+EFI_STATUS\r
+FindUnknownFormatFvInfo (\r
+ IN PEI_CORE_INSTANCE *PrivateData,\r
+ IN EFI_GUID *Format,\r
+ OUT VOID **FvInfo,\r
+ OUT UINT32 *FvInfoSize\r
+ )\r
+{\r
+ UINTN Index;\r
+ UINTN Index2;\r
+\r
+ Index = 0;\r
+ for (; Index < PrivateData->UnknownFvInfoCount; Index ++) {\r
+ if (CompareGuid (Format, &PrivateData->UnknownFvInfo[Index].FvFormat)) {\r
+ break;\r
+ }\r
+ }\r
+ \r
+ if (Index == PrivateData->UnknownFvInfoCount) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ \r
+ *FvInfo = PrivateData->UnknownFvInfo[Index].FvInfo;\r
+ *FvInfoSize = PrivateData->UnknownFvInfo[Index].FvInfoSize;\r
+ \r
+ //\r
+ // Remove an entry from UnknownFvInfo array.\r
+ //\r
+ Index2 = Index + 1;\r
+ for (;Index2 < PrivateData->UnknownFvInfoCount; Index2 ++, Index ++) {\r
+ CopyMem (&PrivateData->UnknownFvInfo[Index], &PrivateData->UnknownFvInfo[Index2], sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO));\r
+ }\r
+ PrivateData->UnknownFvInfoCount --;\r
+ return EFI_SUCCESS;\r
+} \r
+\r
+/**\r
+ Notification callback function for EFI_PEI_FIRMWARE_VOLUME_PPI.\r
+ \r
+ When a EFI_PEI_FIRMWARE_VOLUME_PPI is installed to support new FV format, this \r
+ routine is called to process all discoveried FVs in this format.\r
+ \r
+ @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
+ @param NotifyDescriptor Address of the notification descriptor data structure.\r
+ @param Ppi Address of the PPI that was installed.\r
+ \r
+ @retval EFI_SUCCESS The notification callback is processed correctly.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ThirdPartyFvPpiNotifyCallback (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
+ IN VOID *Ppi\r
+ )\r
+{\r
+ PEI_CORE_INSTANCE *PrivateData;\r
+ EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;\r
+ VOID *FvInfo;\r
+ UINT32 FvInfoSize;\r
+ EFI_STATUS Status;\r
+ EFI_PEI_FV_HANDLE FvHandle;\r
+ BOOLEAN IsProcessed;\r
+ UINTN FvIndex;\r
+ EFI_PEI_FILE_HANDLE FileHandle;\r
+ VOID *DepexData; \r
+ \r
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
+ FvPpi = (EFI_PEI_FIRMWARE_VOLUME_PPI*) Ppi;\r
+ \r
+ do {\r
+ Status = FindUnknownFormatFvInfo (PrivateData, NotifyDescriptor->Guid, &FvInfo, &FvInfoSize);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ \r
+ //\r
+ // Process new found FV and get FV handle.\r
+ //\r
+ Status = FvPpi->ProcessVolume (FvPpi, FvInfo, FvInfoSize, &FvHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Fail to process the FV 0x%p, FV may be corrupted!\n", FvInfo));\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Check whether the FV has already been processed.\r
+ //\r
+ IsProcessed = FALSE;\r
+ for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex ++) {\r
+ if (PrivateData->Fv[FvIndex].FvHandle == FvHandle) {\r
+ DEBUG ((EFI_D_INFO, "The Fv %p has already been processed!\n", FvInfo));\r
+ IsProcessed = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ \r
+ if (IsProcessed) {\r
+ continue;\r
+ }\r
+ \r
+ //\r
+ // Update internal PEI_CORE_FV array.\r
+ //\r
+ PrivateData->Fv[PrivateData->FvCount].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) FvInfo;\r
+ PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi;\r
+ PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;\r
+ DEBUG ((\r
+ EFI_D_INFO, \r
+ "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n", \r
+ (UINT32) PrivateData->FvCount, \r
+ (VOID *) FvInfo, \r
+ FvInfoSize,\r
+ FvHandle\r
+ )); \r
+ PrivateData->FvCount ++;\r
+\r
+ //\r
+ // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE \r
+ //\r
+ FileHandle = NULL;\r
+ do {\r
+ Status = FvPpi->FindFileByType (\r
+ FvPpi,\r
+ EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,\r
+ FvHandle,\r
+ &FileHandle\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = FvPpi->FindSectionByType (\r
+ FvPpi,\r
+ EFI_SECTION_PEI_DEPEX,\r
+ FileHandle,\r
+ (VOID**)&DepexData\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ if (!PeimDispatchReadiness (PeiServices, DepexData)) {\r
+ //\r
+ // Dependency is not satisfied.\r
+ //\r
+ continue;\r
+ }\r
+ }\r
+ \r
+ DEBUG ((EFI_D_INFO, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle, PrivateData->FvCount - 1, FvHandle));\r
+ ProcessFvFile (&PrivateData->Fv[PrivateData->FvCount - 1], FileHandle);\r
+ }\r
+ } while (FileHandle != NULL);\r
+ } while (TRUE);\r
+ \r
+ return EFI_SUCCESS;\r
+}\r
+\r
+
\ No newline at end of file
IN OUT EFI_PEI_FV_HANDLE *AprioriFile OPTIONAL\r
);\r
\r
+/**\r
+ Report the information for a new discoveried FV in unknown format.\r
+ \r
+ If the EFI_PEI_FIRMWARE_VOLUME_PPI has not been install for specifical FV format, but\r
+ the FV in this FV format has been discoveried, then the information of this FV\r
+ will be cached into PEI_CORE_INSTANCE's UnknownFvInfo array.\r
+ Also a notification would be installed for unknown FV format guid, if EFI_PEI_FIRMWARE_VOLUME_PPI\r
+ is installed later by platform's PEIM, the original unknown FV will be processed by\r
+ using new installed EFI_PEI_FIRMWARE_VOLUME_PPI.\r
+ \r
+ @param PrivateData Point to instance of PEI_CORE_INSTANCE\r
+ @param Format Point to the unknown FV format guid.\r
+ @param FvInfo Point to FvInfo buffer.\r
+ @param FvInfoSize The size of FvInfo buffer.\r
+ \r
+ @retval EFI_OUT_OF_RESOURCES The FV info array in PEI_CORE_INSTANCE has no more spaces.\r
+ @retval EFI_SUCCESS Success to add the information for unknown FV.\r
+**/\r
+EFI_STATUS\r
+AddUnknownFormatFvInfo (\r
+ IN PEI_CORE_INSTANCE *PrivateData,\r
+ IN EFI_GUID *Format,\r
+ IN VOID *FvInfo,\r
+ IN UINT32 FvInfoSize\r
+ );\r
+ \r
+/**\r
+ Find the FV information according to FV format guid.\r
+ \r
+ This routine also will remove the FV information found by given FV format guid from\r
+ PrivateData->UnknownFvInfo[].\r
+ \r
+ @param PrivateData Point to instance of PEI_CORE_INSTANCE\r
+ @param Format Point to given FV format guid\r
+ @param FvInfo On return, the pointer of FV information buffer in given FV format guid\r
+ @param FvInfoSize On return, the size of FV information buffer.\r
+ \r
+ @retval EFI_NOT_FOUND The FV is not found for new installed EFI_PEI_FIRMWARE_VOLUME_PPI\r
+ @retval EFI_SUCCESS Success to find a FV which could be processed by new installed EFI_PEI_FIRMWARE_VOLUME_PPI.\r
+**/\r
+EFI_STATUS\r
+FindUnknownFormatFvInfo (\r
+ IN PEI_CORE_INSTANCE *PrivateData,\r
+ IN EFI_GUID *Format,\r
+ OUT VOID **FvInfo,\r
+ OUT UINT32 *FvInfoSize\r
+ );\r
+ \r
+/**\r
+ Notification callback function for EFI_PEI_FIRMWARE_VOLUME_PPI.\r
+ \r
+ When a EFI_PEI_FIRMWARE_VOLUME_PPI is installed to support new FV format, this \r
+ routine is called to process all discoveried FVs in this format.\r
+ \r
+ @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
+ @param NotifyDescriptor Address of the notification descriptor data structure.\r
+ @param Ppi Address of the PPI that was installed.\r
+ \r
+ @retval EFI_SUCCESS The notification callback is processed correctly.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ThirdPartyFvPpiNotifyCallback (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
+ IN VOID *Ppi\r
+ ); \r
+ \r
#endif \r