]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/PeiHobLib/HobLib.c
MdePkg/UefiDevicePathLib: Rename StrToGuid to avoid link failure
[mirror_edk2.git] / MdePkg / Library / PeiHobLib / HobLib.c
index 113de832fc488577278732c51eff31a3da12791e..a1522dd9f5fffb2d11c1f6eef6a56d6204791f51 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Provide Hob Library functions for Pei phase.\r
 \r
-Copyright (c) 2007 - 2011, 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,6 +300,47 @@ BuildModuleHob (
   Hob->EntryPoint = EntryPoint;\r
 }\r
 \r
+/**\r
+  Builds a HOB that describes a chunk of system memory with Owner GUID.\r
+\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
+\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
+\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
   Builds a HOB that describes a chunk of system memory.\r
 \r
@@ -335,6 +376,7 @@ BuildResourceDescriptorHob (
   Hob->ResourceAttribute = ResourceAttribute;\r
   Hob->PhysicalStart     = PhysicalStart;\r
   Hob->ResourceLength    = NumberOfBytes;\r
+  ZeroMem (&(Hob->Owner), sizeof (EFI_GUID));\r
 }\r
 \r
 /**\r
@@ -349,7 +391,8 @@ BuildResourceDescriptorHob (
   \r
   If Guid is NULL, then ASSERT().\r
   If there is no additional space for HOB creation, then ASSERT().\r
-  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().\r
+  If DataLength > (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().\r
+  HobLength is UINT16 and multiples of 8 bytes, so the max HobLength is 0xFFF8.\r
 \r
   @param  Guid          The GUID to tag the customized HOB.\r
   @param  DataLength    The size of the data payload for the GUID HOB.\r
@@ -375,7 +418,7 @@ BuildGuidHob (
   //\r
   // Make sure that data length is not too long.\r
   //\r
-  ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));\r
+  ASSERT (DataLength <= (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE)));\r
 \r
   Hob = InternalPeiCreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));\r
   if (Hob == NULL) {\r
@@ -399,7 +442,8 @@ BuildGuidHob (
   If Guid is NULL, then ASSERT().\r
   If Data is NULL and DataLength > 0, then ASSERT().\r
   If there is no additional space for HOB creation, then ASSERT().\r
-  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().\r
+  If DataLength > (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().\r
+  HobLength is UINT16 and multiples of 8 bytes, so the max HobLength is 0xFFF8.\r
 \r
   @param  Guid          The GUID to tag the customized HOB.\r
   @param  Data          The data to be copied into the data field of the GUID HOB.\r
@@ -429,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
@@ -437,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
@@ -451,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
@@ -468,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
@@ -486,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