]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/PeiHobLib/HobLib.c
MdePkg HobLib: Check FV alignment when building FV HOB
[mirror_edk2.git] / MdePkg / Library / PeiHobLib / HobLib.c
index f853452f563ab34a7666ea6c19c5f1ea21d5625b..a1522dd9f5fffb2d11c1f6eef6a56d6204791f51 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Provide Hob Library functions for Pei phase.\r
 \r
-Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
 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
@@ -300,45 +300,45 @@ BuildModuleHob (
   Hob->EntryPoint = EntryPoint;\r
 }\r
 \r
-/**
+/**\r
   Builds a HOB that describes a chunk of system memory with Owner GUID.\r
-
-  This function builds a HOB that describes a chunk of system memory.
-  It can only be invoked during PEI phase;
-  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
-  
-  If there is no additional space for HOB creation, then ASSERT().
-
-  @param  ResourceType        The type of resource described by this HOB.
-  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.
-  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.
-  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.
+\r
+  This function builds a HOB that describes a chunk of system memory.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  \r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  ResourceType        The type of resource described by this HOB.\r
+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.\r
+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.\r
+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.\r
   @param  OwnerGUID           GUID for the owner of this resource.\r
-
-**/
-VOID
-EFIAPI
-BuildResourceDescriptorWithOwnerHob (
-  IN EFI_RESOURCE_TYPE            ResourceType,
-  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,
-  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
-  IN UINT64                       NumberOfBytes,
-  IN EFI_GUID                     *OwnerGUID
-  )
-{
-  EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BuildResourceDescriptorWithOwnerHob (\r
+  IN EFI_RESOURCE_TYPE            ResourceType,\r
+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,\r
+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,\r
+  IN UINT64                       NumberOfBytes,\r
+  IN EFI_GUID                     *OwnerGUID\r
+  )\r
+{\r
+  EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;\r
 \r
   Hob = InternalPeiCreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, (UINT16) sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));\r
   if (Hob == NULL) {\r
     return;\r
   }\r
-
-  Hob->ResourceType      = ResourceType;
-  Hob->ResourceAttribute = ResourceAttribute;
-  Hob->PhysicalStart     = PhysicalStart;
-  Hob->ResourceLength    = NumberOfBytes;
-
-  CopyGuid (&Hob->Owner, OwnerGUID);
+\r
+  Hob->ResourceType      = ResourceType;\r
+  Hob->ResourceAttribute = ResourceAttribute;\r
+  Hob->PhysicalStart     = PhysicalStart;\r
+  Hob->ResourceLength    = NumberOfBytes;\r
+\r
+  CopyGuid (&Hob->Owner, OwnerGUID);\r
 }\r
 \r
 /**\r
@@ -473,6 +473,62 @@ BuildGuidDataHob (
   return CopyMem (HobData, Data, DataLength);\r
 }\r
 \r
+/**\r
+  Check FV alignment.\r
+\r
+  @param  BaseAddress   The base address of the Firmware Volume.\r
+  @param  Length        The size of the Firmware Volume in bytes.\r
+\r
+  @retval TRUE          FvImage buffer is at its required alignment.\r
+  @retval FALSE         FvImage buffer is not at its required alignment.\r
+\r
+**/\r
+BOOLEAN\r
+InternalCheckFvAlignment (\r
+  IN EFI_PHYSICAL_ADDRESS       BaseAddress,\r
+  IN UINT64                     Length\r
+  )\r
+{\r
+  EFI_FIRMWARE_VOLUME_HEADER    *FwVolHeader;\r
+  UINT32                        FvAlignment;\r
+\r
+  FvAlignment = 0;\r
+  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;\r
+\r
+  //\r
+  // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume\r
+  // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from\r
+  // its initial linked location and maintain its alignment.\r
+  //\r
+  if ((FwVolHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {\r
+    //\r
+    // Get FvHeader alignment\r
+    //\r
+    FvAlignment = 1 << ((FwVolHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
+    //\r
+    // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.\r
+    //\r
+    if (FvAlignment < 8) {\r
+      FvAlignment = 8;\r
+    }\r
+    if ((UINTN)BaseAddress % FvAlignment != 0) {\r
+      //\r
+      // FvImage buffer is not at its required alignment.\r
+      //\r
+      DEBUG ((\r
+        DEBUG_ERROR,\r
+        "Unaligned FvImage found at 0x%lx:0x%lx, the required alignment is 0x%x\n",\r
+        BaseAddress,\r
+        Length,\r
+        FvAlignment\r
+        ));\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
 /**\r
   Builds a Firmware Volume HOB.\r
 \r
@@ -481,6 +537,7 @@ BuildGuidDataHob (
   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
   \r
   If there is no additional space for HOB creation, then ASSERT().\r
+  If the FvImage buffer is not at its required alignment, then ASSERT().\r
 \r
   @param  BaseAddress   The base address of the Firmware Volume.\r
   @param  Length        The size of the Firmware Volume in bytes.\r
@@ -495,6 +552,11 @@ BuildFvHob (
 {\r
   EFI_HOB_FIRMWARE_VOLUME  *Hob;\r
 \r
+  if (!InternalCheckFvAlignment (BaseAddress, Length)) {\r
+    ASSERT (FALSE);\r
+    return;\r
+  }\r
+\r
   Hob = InternalPeiCreateHob (EFI_HOB_TYPE_FV, (UINT16) sizeof (EFI_HOB_FIRMWARE_VOLUME));\r
   if (Hob == NULL) {\r
     return;\r
@@ -512,6 +574,7 @@ BuildFvHob (
   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
   \r
   If there is no additional space for HOB creation, then ASSERT().\r
+  If the FvImage buffer is not at its required alignment, then ASSERT().\r
 \r
   @param  BaseAddress   The base address of the Firmware Volume.\r
   @param  Length        The size of the Firmware Volume in bytes.\r
@@ -530,6 +593,11 @@ BuildFv2Hob (
 {\r
   EFI_HOB_FIRMWARE_VOLUME2  *Hob;\r
 \r
+  if (!InternalCheckFvAlignment (BaseAddress, Length)) {\r
+    ASSERT (FALSE);\r
+    return;\r
+  }\r
+\r
   Hob = InternalPeiCreateHob (EFI_HOB_TYPE_FV2, (UINT16) sizeof (EFI_HOB_FIRMWARE_VOLUME2));\r
   if (Hob == NULL) {\r
     return;\r