]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkPkg/Library/PeiHobLibFramework/HobLib.c
IntelFrameworkPkg PeiHobLibFramework: Implement BuildFv3Hob
[mirror_edk2.git] / IntelFrameworkPkg / Library / PeiHobLibFramework / HobLib.c
index 3ce955a88c44ad4175f7cbce862e56ce48865360..eb89b4a535524050910e2ae1a5b748cacc7baf70 100644 (file)
@@ -5,7 +5,7 @@
  This library instance uses EFI_HOB_TYPE_CV defined in Intel framework HOB specification v0.9\r
  to implement HobLib BuildCvHob() API. \r
 \r
-Copyright (c) 2007 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2017, 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
@@ -230,7 +230,8 @@ GetBootModeHob (
   @param  Type          Type of the new HOB.\r
   @param  Length        Length of the new HOB to allocate.\r
 \r
-  @return The address of new HOB.\r
+  @retval  NULL         The HOB could not be allocated.\r
+  @retval  others       The address of new HOB.\r
 \r
 **/\r
 VOID *\r
@@ -244,10 +245,13 @@ InternalPeiCreateHob (
   VOID              *Hob;\r
 \r
   Status = PeiServicesCreateHob (Type, Length, &Hob);\r
+  if (EFI_ERROR (Status)) {\r
+    Hob = NULL;\r
+  }\r
   //\r
   // Assume the process of HOB building is always successful.\r
   //\r
-  ASSERT_EFI_ERROR (Status);\r
+  ASSERT (Hob != NULL);\r
   return Hob;\r
 }\r
 \r
@@ -281,7 +285,10 @@ BuildModuleHob (
   ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&\r
           ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));\r
 \r
-  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));\r
+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, (UINT16) sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));\r
+  if (Hob == NULL) {\r
+    return;\r
+  }\r
 \r
   CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);\r
   Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;\r
@@ -297,6 +304,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
@@ -323,12 +371,16 @@ BuildResourceDescriptorHob (
 {\r
   EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;\r
 \r
-  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));\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
+  ZeroMem (&(Hob->Owner), sizeof (EFI_GUID));\r
 }\r
 \r
 /**\r
@@ -348,7 +400,8 @@ BuildResourceDescriptorHob (
   @param  Guid          The GUID to tag the customized HOB.\r
   @param  DataLength    The size of the data payload for the GUID HOB.\r
 \r
-  @return The start address of GUID HOB data.\r
+  @retval  NULL         The GUID HOB could not be allocated.\r
+  @retval  others       The start address of GUID HOB data.\r
 \r
 **/\r
 VOID *\r
@@ -360,12 +413,20 @@ BuildGuidHob (
 {\r
   EFI_HOB_GUID_TYPE *Hob;\r
 \r
+  //\r
+  // Make sure Guid is valid\r
+  //\r
+  ASSERT (Guid != NULL);\r
+  \r
   //\r
   // Make sure that data length is not too long.\r
   //\r
   ASSERT (DataLength <= (0xffff - 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
+    return Hob;\r
+  }\r
   CopyGuid (&Hob->Name, Guid);\r
   return Hob + 1;\r
 }\r
@@ -390,7 +451,8 @@ BuildGuidHob (
   @param  Data          The data to be copied into the data field of the GUID HOB.\r
   @param  DataLength    The size of the data payload for the GUID HOB.\r
 \r
-  @return The start address of GUID HOB data.\r
+  @retval  NULL         The GUID HOB could not be allocated.\r
+  @retval  others       The start address of GUID HOB data.\r
 \r
 **/\r
 VOID *\r
@@ -406,10 +468,69 @@ BuildGuidDataHob (
   ASSERT (Data != NULL || DataLength == 0);\r
 \r
   HobData = BuildGuidHob (Guid, DataLength);\r
+  if (HobData == NULL) {\r
+    return HobData;\r
+  }\r
 \r
   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
@@ -418,6 +539,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
@@ -432,7 +554,15 @@ BuildFvHob (
 {\r
   EFI_HOB_FIRMWARE_VOLUME  *Hob;\r
 \r
-  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));\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
+  }\r
 \r
   Hob->BaseAddress = BaseAddress;\r
   Hob->Length      = Length;\r
@@ -446,6 +576,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
@@ -464,7 +595,15 @@ BuildFv2Hob (
 {\r
   EFI_HOB_FIRMWARE_VOLUME2  *Hob;\r
 \r
-  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));\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
+  }\r
 \r
   Hob->BaseAddress = BaseAddress;\r
   Hob->Length      = Length;\r
@@ -472,6 +611,60 @@ BuildFv2Hob (
   CopyGuid (&Hob->FileName, FileName);\r
 }\r
 \r
+/**\r
+  Builds a EFI_HOB_TYPE_FV3 HOB.\r
+\r
+  This function builds a EFI_HOB_TYPE_FV3 HOB.\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
+  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
+  @param AuthenticationStatus   The authentication status.\r
+  @param ExtractedFv            TRUE if the FV was extracted as a file within\r
+                                another firmware volume. FALSE otherwise.\r
+  @param FvName                 The name of the Firmware Volume.\r
+                                Valid only if IsExtractedFv is TRUE.\r
+  @param FileName               The name of the file.\r
+                                Valid only if IsExtractedFv is TRUE.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BuildFv3Hob (\r
+  IN          EFI_PHYSICAL_ADDRESS        BaseAddress,\r
+  IN          UINT64                      Length,\r
+  IN          UINT32                      AuthenticationStatus,\r
+  IN          BOOLEAN                     ExtractedFv,\r
+  IN CONST    EFI_GUID                    *FvName, OPTIONAL\r
+  IN CONST    EFI_GUID                    *FileName OPTIONAL\r
+  )\r
+{\r
+  EFI_HOB_FIRMWARE_VOLUME3  *Hob;\r
+\r
+  if (!InternalCheckFvAlignment (BaseAddress, Length)) {\r
+    ASSERT (FALSE);\r
+    return;\r
+  }\r
+\r
+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_FV3, (UINT16) sizeof (EFI_HOB_FIRMWARE_VOLUME3));\r
+  if (Hob == NULL) {\r
+    return;\r
+  }\r
+\r
+  Hob->BaseAddress          = BaseAddress;\r
+  Hob->Length               = Length;\r
+  Hob->AuthenticationStatus = AuthenticationStatus;\r
+  Hob->ExtractedFv          = ExtractedFv;\r
+  if (ExtractedFv) {\r
+    CopyGuid (&Hob->FvName, FvName);\r
+    CopyGuid (&Hob->FileName, FileName);\r
+  }\r
+}\r
+\r
 /**\r
   Builds a Capsule Volume HOB.\r
 \r
@@ -495,7 +688,10 @@ BuildCvHob (
 {\r
   EFI_HOB_CAPSULE_VOLUME     *Hob;\r
 \r
-  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_CV, sizeof (EFI_HOB_CAPSULE_VOLUME));\r
+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_CV, (UINT16) sizeof (EFI_HOB_CAPSULE_VOLUME));\r
+  if (Hob == NULL) {\r
+    return;\r
+  }\r
 \r
   Hob->BaseAddress = BaseAddress;\r
   Hob->Length      = Length;\r
@@ -523,7 +719,10 @@ BuildCpuHob (
 {\r
   EFI_HOB_CPU  *Hob;\r
 \r
-  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));\r
+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_CPU, (UINT16) sizeof (EFI_HOB_CPU));\r
+  if (Hob == NULL) {\r
+    return;\r
+  }\r
 \r
   Hob->SizeOfMemorySpace = SizeOfMemorySpace;\r
   Hob->SizeOfIoSpace     = SizeOfIoSpace;\r
@@ -559,7 +758,10 @@ BuildStackHob (
   ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&\r
           ((Length & (EFI_PAGE_SIZE - 1)) == 0));\r
 \r
-  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));\r
+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, (UINT16) sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));\r
+  if (Hob == NULL) {\r
+    return;\r
+  }\r
 \r
   CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);\r
   Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
@@ -599,7 +801,10 @@ BuildBspStoreHob (
   ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&\r
           ((Length & (EFI_PAGE_SIZE - 1)) == 0));\r
 \r
-  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_BSP_STORE));\r
+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, (UINT16) sizeof (EFI_HOB_MEMORY_ALLOCATION_BSP_STORE));\r
+  if (Hob == NULL) {\r
+    return;\r
+  }\r
 \r
   CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocBspStoreGuid);\r
   Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
@@ -639,7 +844,10 @@ BuildMemoryAllocationHob (
   ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&\r
           ((Length & (EFI_PAGE_SIZE - 1)) == 0));\r
   \r
-  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));\r
+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, (UINT16) sizeof (EFI_HOB_MEMORY_ALLOCATION));\r
+  if (Hob == NULL) {\r
+    return;\r
+  }\r
   \r
   ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));\r
   Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r