]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add fixing for supporting third-party FV in unknown format.
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 25 Dec 2009 02:28:47 +0000 (02:28 +0000)
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 25 Dec 2009 02:28:47 +0000 (02:28 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9601 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Core/Pei/FwVol/FwVol.c
MdeModulePkg/Core/Pei/FwVol/FwVol.h
MdeModulePkg/Core/Pei/PeiMain.h

index 453b72f75a097c4526ab74761f45a1809476dc2d..140f1b0b73e48483b3991fb5a22be7996332e580 100644 (file)
@@ -455,26 +455,7 @@ FirmwareVolmeInfoPpiNotifyCallback (
   } 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
@@ -1440,3 +1421,217 @@ PeiReinitializeFv (
   }\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
index 65c17e3d091880cadfc9752ea6cee23362749629..940991012c6b9af9a06dd323fc29d016554ac719 100644 (file)
@@ -235,4 +235,72 @@ FindFileEx (
   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
index c6b41b6aaa328e1167fa52796947b5f13f82c1a6..dc5ea221d6db2fddf3377af87ec7c279c4ee90da 100644 (file)
@@ -112,6 +112,13 @@ typedef struct {
   BOOLEAN                             ScanFv;\r
 } PEI_CORE_FV_HANDLE;\r
 \r
+typedef struct {\r
+  EFI_GUID                            FvFormat;\r
+  VOID                                *FvInfo;\r
+  UINT32                              FvInfoSize;\r
+  EFI_PEI_NOTIFY_DESCRIPTOR           NotifyDescriptor;\r
+} PEI_CORE_UNKNOW_FORMAT_FV_INFO;\r
+\r
 #define CACHE_SETION_MAX_NUMBER       0x10\r
 typedef struct {\r
   EFI_COMMON_SECTION_HEADER*          Section[CACHE_SETION_MAX_NUMBER];\r
@@ -145,7 +152,9 @@ typedef struct{
   /// The instance arrary for FVs which contains FFS and could be dispatched by PeiCore.\r
   ///\r
   PEI_CORE_FV_HANDLE                 Fv[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];\r
-\r
+  PEI_CORE_UNKNOW_FORMAT_FV_INFO     UnknownFvInfo[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];\r
+  UINTN                              UnknownFvInfoCount;\r
+  \r
   EFI_PEI_FILE_HANDLE                CurrentFvFileHandles[FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv)];\r
   UINTN                              AprioriCount;\r
   UINTN                              CurrentPeimFvCount;\r