]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
Move sure FvImage buffer at its alignment when install FVB protocol on it.
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Dispatcher / Dispatcher.c
index 9792a16485c2a05a2a51884bf2e1302002c415a0..d348c82a9e318c2fd46aa9195b0b98644dfa6c6f 100644 (file)
@@ -1,21 +1,5 @@
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
-\r
-Module Name:\r
-\r
-  Dispatcher.c\r
-\r
-Abstract:\r
-\r
-  Tiano DXE Dispatcher.\r
+/**@file\r
+  DXE Dispatcher.\r
 \r
   Step #1 - When a FV protocol is added to the system every driver in the FV\r
             is added to the mDiscoveredList. The SOR, Before, and After Depex are \r
@@ -42,7 +26,16 @@ Abstract:
   Depex - Dependency Expresion.\r
   SOR   - Schedule On Request - Don't schedule if this bit is set.\r
 \r
---*/\r
+Copyright (c) 2006 - 2007, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+**/\r
 \r
 #include <DxeMain.h>\r
 \r
@@ -118,7 +111,7 @@ CoreFwVolEventProtocolNotify (
 STATIC\r
 EFI_DEVICE_PATH_PROTOCOL *\r
 CoreFvToDevicePath (\r
-  IN  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv,\r
+  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,\r
   IN  EFI_HANDLE                      FvHandle,\r
   IN  EFI_GUID                        *DriverName\r
   );\r
@@ -126,7 +119,7 @@ CoreFvToDevicePath (
 STATIC \r
 EFI_STATUS\r
 CoreAddToDriverList (\r
-  IN  EFI_FIRMWARE_VOLUME_PROTOCOL  *Fv,\r
+  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,\r
   IN  EFI_HANDLE                    FvHandle,\r
   IN  EFI_GUID                      *DriverName\r
   );\r
@@ -134,7 +127,7 @@ CoreAddToDriverList (
 STATIC\r
 EFI_STATUS \r
 CoreProcessFvImageFile (\r
-  IN  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv,\r
+  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,\r
   IN  EFI_HANDLE                      FvHandle,\r
   IN  EFI_GUID                        *DriverName\r
   );\r
@@ -218,7 +211,7 @@ Returns:
   EFI_STATUS                    Status;\r
   EFI_SECTION_TYPE              SectionType;\r
   UINT32                        AuthenticationStatus;\r
-  EFI_FIRMWARE_VOLUME_PROTOCOL  *Fv;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
 \r
   \r
   Fv = DriverEntry->Fv;\r
@@ -244,7 +237,7 @@ Returns:
       DriverEntry->DepexProtocolError = TRUE;\r
     } else {\r
       //\r
-      // If no Depex assume EFI 1.1 driver model\r
+      // If no Depex assume UEFI 2.0 driver model\r
       //\r
       DriverEntry->Depex = NULL;\r
       DriverEntry->Dependent = TRUE;\r
@@ -490,10 +483,15 @@ Returns:
       \r
       CoreReleaseDispatcherLock ();\r
 \r
-\r
-      CoreReportProgressCodeSpecific (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN, DriverEntry->ImageHandle);\r
+      CoreReportProgressCodeSpecific (\r
+        FixedPcdGet32(PcdStatusCodeValueDxeDriverBegin), \r
+        DriverEntry->ImageHandle\r
+        );\r
       Status = CoreStartImage (DriverEntry->ImageHandle, NULL, NULL);\r
-      CoreReportProgressCodeSpecific (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END, DriverEntry->ImageHandle);\r
+      CoreReportProgressCodeSpecific (\r
+        FixedPcdGet32(PcdStatusCodeValueDxeDriverEnd), \r
+        DriverEntry->ImageHandle\r
+        );\r
 \r
       ReturnStatus = EFI_SUCCESS;\r
     }\r
@@ -670,7 +668,7 @@ Returns:
 STATIC\r
 EFI_DEVICE_PATH_PROTOCOL *\r
 CoreFvToDevicePath (\r
-  IN  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv,\r
+  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,\r
   IN  EFI_HANDLE                      FvHandle,\r
   IN  EFI_GUID                        *DriverName\r
   )\r
@@ -727,7 +725,7 @@ Returns:
 \r
 EFI_STATUS\r
 CoreAddToDriverList (\r
-  IN  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv,\r
+  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,\r
   IN  EFI_HANDLE                      FvHandle,\r
   IN  EFI_GUID                        *DriverName\r
   )\r
@@ -786,11 +784,51 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+STATIC\r
+BOOLEAN\r
+FvFoundInHobFv2 (\r
+  IN  EFI_HANDLE                      FvHandle,\r
+  IN  CONST EFI_GUID                  *DriverName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check if a FV Image type file (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) is\r
+  described by a EFI_HOB_FIRMWARE_VOLUME2 Hob.\r
+\r
+Arguments:\r
+\r
+  FvHandle    - The handle which FVB protocol installed on.\r
+  DriverName  - The driver guid specified.\r
+\r
+Returns:\r
+\r
+  TRUE    - This file is found in a EFI_HOB_FIRMWARE_VOLUME2 Hob.\r
+\r
+  FALSE   - Not found.\r
+  \r
+\r
+--*/\r
+{\r
+  EFI_PEI_HOB_POINTERS                HobFv2;\r
+  \r
+  HobFv2.Raw = GetHobList ();\r
+  \r
+  while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {\r
+    if (CompareGuid (DriverName, &HobFv2.FirmwareVolume2->FileName)) {\r
+      return TRUE;\r
+    }\r
+    HobFv2.Raw = GET_NEXT_HOB (HobFv2);\r
+  }\r
+\r
+  return FALSE;\r
+}\r
 \r
 \r
 EFI_STATUS \r
 CoreProcessFvImageFile (\r
-  IN  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv,\r
+  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,\r
   IN  EFI_HANDLE                      FvHandle,\r
   IN  EFI_GUID                        *DriverName\r
   )\r
@@ -821,14 +859,20 @@ Returns:
   EFI_SECTION_TYPE                    SectionType;\r
   UINT32                              AuthenticationStatus;\r
   VOID                                *Buffer;\r
+  VOID                                *AlignedBuffer;\r
   UINTN                               BufferSize;\r
+  EFI_FIRMWARE_VOLUME_HEADER          *FvHeader;\r
+  UINT32                              FvAlignment;  \r
 \r
   //\r
   // Read the first (and only the first) firmware volume section\r
   //\r
   SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;\r
+  FvHeader    = NULL;\r
+  FvAlignment = 0;\r
   Buffer      = NULL;\r
   BufferSize  = 0;\r
+  AlignedBuffer = NULL;\r
   Status = Fv->ReadSection (\r
                 Fv, \r
                 DriverName, \r
@@ -840,22 +884,50 @@ Returns:
                 );\r
   if (!EFI_ERROR (Status)) {\r
     //\r
-    // Produce a FVB protocol for the file\r
+    // FvImage should be at its required alignment.\r
+    //\r
+    FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;\r
+    FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
     //\r
-    Status = ProduceFVBProtocolOnBuffer (\r
-              (EFI_PHYSICAL_ADDRESS) (UINTN) Buffer,\r
-              (UINT64)BufferSize,\r
-              FvHandle,\r
-              NULL\r
-              );\r
+    // FvAlignment must be more than 8 bytes required by FvHeader structure.\r
+    // \r
+    if (FvAlignment < 8) {\r
+      FvAlignment = 8;\r
+    }\r
+    \r
+    AlignedBuffer = AllocateAlignedPool ((UINTN) BufferSize, (UINTN) FvAlignment);\r
+    if (AlignedBuffer == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+    } else {\r
+      //\r
+      // Move FvImage into the aligned buffer and release the original buffer.\r
+      //\r
+      CopyMem (AlignedBuffer, Buffer, BufferSize);\r
+      CoreFreePool (Buffer);\r
+      Buffer = NULL;\r
+      //\r
+      // Produce a FVB protocol for the file\r
+      //\r
+      Status = ProduceFVBProtocolOnBuffer (\r
+                (EFI_PHYSICAL_ADDRESS) (UINTN) AlignedBuffer,\r
+                (UINT64)BufferSize,\r
+                FvHandle,\r
+                NULL\r
+                );\r
+    }\r
   }\r
 \r
-  if (EFI_ERROR (Status) && (Buffer != NULL)) {    \r
-  //\r
-  // ReadSection or Produce FVB failed, Free data buffer\r
-  //\r
-  CoreFreePool (Buffer); \r
-\r
+  if (EFI_ERROR (Status)) {    \r
+    //\r
+    // ReadSection or Produce FVB failed, Free data buffer\r
+    //\r
+    if (Buffer != NULL) {\r
+      CoreFreePool (Buffer); \r
+    }\r
+    \r
+    if (AlignedBuffer != NULL) {\r
+      FreeAlignedPool (AlignedBuffer);\r
+    }\r
   }\r
 \r
   return Status;\r
@@ -902,7 +974,7 @@ Returns:
   EFI_STATUS                    Status;\r
   EFI_STATUS                    GetNextFileStatus;\r
   EFI_STATUS                    SecurityStatus;\r
-  EFI_FIRMWARE_VOLUME_PROTOCOL  *Fv;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
   EFI_DEVICE_PATH_PROTOCOL      *FvDevicePath;\r
   EFI_HANDLE                    FvHandle;\r
   UINTN                         BufferSize;\r
@@ -958,7 +1030,7 @@ Returns:
     FvIsBeingProcesssed (FvHandle);\r
 \r
 \r
-    Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeProtocolGuid, (VOID **)&Fv);\r
+    Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);\r
     if (EFI_ERROR (Status)) {\r
       //\r
       // The Handle has a FirmwareVolumeDispatch protocol and should also contiain\r
@@ -1038,6 +1110,13 @@ Returns:
               }\r
             }\r
           } else if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {\r
+            //\r
+            // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already \r
+            // been extracted.\r
+            //\r
+            if (FvFoundInHobFv2 (FvHandle, &NameGuid)) {\r
+              continue;\r
+            }\r
             //\r
             // Found a firmware volume image. Produce a firmware volume block\r
             // protocol for it so it gets dispatched from. This is usually a \r
@@ -1125,7 +1204,7 @@ Returns:
 --*/\r
 {\r
   mFwVolEvent = CoreCreateProtocolNotifyEvent (\r
-                  &gEfiFirmwareVolumeProtocolGuid, \r
+                  &gEfiFirmwareVolume2ProtocolGuid, \r
                   TPL_CALLBACK,\r
                   CoreFwVolEventProtocolNotify,\r
                   NULL,\r