Reviewed-by: [email protected]

> -----Original Message-----
> From: Zeng, Star
> Sent: Monday, June 20, 2016 9:20 AM
> To: [email protected]
> Cc: Yao, Jiewen <[email protected]>
> Subject: [PATCH 2/2] MdeModulePkg CapsulePei: Validate capsule integrity
> by memory resource hob
> 
> Cc: Jiewen Yao <[email protected]>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Star Zeng <[email protected]>
> ---
>  MdeModulePkg/Universal/CapsulePei/Capsule.h        |   1 +
>  MdeModulePkg/Universal/CapsulePei/CapsulePei.inf   |   3 +-
>  .../Universal/CapsulePei/Common/CapsuleCoalesce.c  | 125
> ++++++++++++------
>  .../Universal/CapsulePei/Common/CommonHeader.h     |  18 ++-
>  MdeModulePkg/Universal/CapsulePei/UefiCapsule.c    | 139
> ++++++++++++++++++++-
>  MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c   |   3 +-
>  6 files changed, 241 insertions(+), 48 deletions(-)
> 
> diff --git a/MdeModulePkg/Universal/CapsulePei/Capsule.h
> b/MdeModulePkg/Universal/CapsulePei/Capsule.h
> index 411dffa682a1..3614c21f8780 100644
> --- a/MdeModulePkg/Universal/CapsulePei/Capsule.h
> +++ b/MdeModulePkg/Universal/CapsulePei/Capsule.h
> @@ -24,6 +24,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF
> ANY KIND, EITHER EXPRESS OR IMPLIED.
>  #include <Ppi/ReadOnlyVariable2.h>
>  #include <Guid/CapsuleVendor.h>
> 
> +#include <Library/BaseLib.h>
>  #include <Library/DebugLib.h>
>  #include <Library/PeimEntryPoint.h>
>  #include <Library/PeiServicesLib.h>
> diff --git a/MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
> b/MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
> index d7aa37186f66..d2ca0d06912c 100644
> --- a/MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
> +++ b/MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
> @@ -6,7 +6,7 @@
>  #  This external input must be validated carefully to avoid security issue
> like
>  #  buffer overflow, integer overflow.
>  #
> -# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
>  #
>  # This program and the accompanying materials
>  # are licensed and made available under the terms and conditions
> @@ -46,6 +46,7 @@ [Packages]
> 
> 
>  [LibraryClasses]
> +  BaseLib
>    HobLib
>    BaseMemoryLib
>    PeiServicesLib
> diff --git
> a/MdeModulePkg/Universal/CapsulePei/Common/CapsuleCoalesce.c
> b/MdeModulePkg/Universal/CapsulePei/Common/CapsuleCoalesce.c
> index 006d9006369c..9e8315eb97c6 100644
> --- a/MdeModulePkg/Universal/CapsulePei/Common/CapsuleCoalesce.c
> +++ b/MdeModulePkg/Universal/CapsulePei/Common/CapsuleCoalesce.c
> @@ -60,20 +60,6 @@ FindFreeMem (
>    );
> 
>  /**
> -  Check the integrity of the capsule descriptors.
> -
> -  @param BlockList    Pointer to the capsule descriptors
> -
> -  @retval NULL           BlockList is not valid.
> -  @retval LastBlockDesc  Last one Block in BlockList
> -
> -**/
> -EFI_CAPSULE_BLOCK_DESCRIPTOR *
> -ValidateCapsuleIntegrity (
> -  IN EFI_CAPSULE_BLOCK_DESCRIPTOR    *BlockList
> -  );
> -
> -/**
>    The capsule block descriptors may be fragmented and spread all over
> memory.
>    To simplify the coalescing of capsule blocks, first coalesce all the
>    capsule block descriptors low in memory.
> @@ -248,9 +234,68 @@ FindFreeMem (
>  }
> 
>  /**
> +  Validate capsule by MemoryResource.
> +
> +  @param MemoryResource  Pointer to the buffer of memory resource
> descriptor.
> +  @param Address         Address to be validated.
> +  @param Size            Size to be validated.
> +
> +  @retval TRUE  No memory resource descriptor reported in HOB list
> before capsule Coalesce,
> +                or it is valid in one MemoryResource.
> +          FALSE It is not in any MemoryResource.
> +
> +**/
> +BOOLEAN
> +ValidateCapsuleByMemoryResource (
> +  IN MEMORY_RESOURCE_DESCRIPTOR     *MemoryResource,
> +  IN EFI_PHYSICAL_ADDRESS           Address,
> +  IN UINT64                         Size
> +  )
> +{
> +  UINTN             Index;
> +
> +  //
> +  // Sanity Check
> +  //
> +  if (Size > MAX_ADDRESS) {
> +    DEBUG ((EFI_D_ERROR, "ERROR: Size(0x%lx) > MAX_ADDRESS\n",
> Size));
> +    return FALSE;
> +  }
> +
> +  //
> +  // Sanity Check
> +  //
> +  if (Address > (MAX_ADDRESS - Size)) {
> +    DEBUG ((EFI_D_ERROR, "ERROR: Address(0x%lx) > (MAX_ADDRESS -
> Size(0x%lx))\n", Address, Size));
> +    return FALSE;
> +  }
> +
> +  if (MemoryResource == NULL) {
> +    //
> +    // No memory resource descriptor reported in HOB list before capsule
> Coalesce.
> +    //
> +    return TRUE;
> +  }
> +
> +  for (Index = 0; MemoryResource[Index].ResourceLength != 0; Index++) {
> +    if ((Address >= MemoryResource[Index].PhysicalStart) &&
> +        ((Address + Size) <= (MemoryResource[Index].PhysicalStart +
> MemoryResource[Index].ResourceLength))) {
> +      DEBUG ((EFI_D_INFO, "Address(0x%lx) Size(0x%lx) in
> MemoryResource[0x%x] - Start(0x%lx) Length(0x%lx)\n",
> +                          Address, Size,
> +                          Index,
> MemoryResource[Index].PhysicalStart,
> MemoryResource[Index].ResourceLength));
> +      return TRUE;
> +    }
> +  }
> +
> +  DEBUG ((EFI_D_ERROR, "ERROR: Address(0x%lx) Size(0x%lx) not in any
> MemoryResource\n", Address, Size));
> +  return FALSE;
> +}
> +
> +/**
>    Check the integrity of the capsule descriptors.
> 
> -  @param BlockList    Pointer to the capsule descriptors
> +  @param BlockList       Pointer to the capsule descriptors
> +  @param MemoryResource  Pointer to the buffer of memory resource
> descriptor.
> 
>    @retval NULL           BlockList is not valid.
>    @retval LastBlockDesc  Last one Block in BlockList
> @@ -258,7 +303,8 @@ FindFreeMem (
>  **/
>  EFI_CAPSULE_BLOCK_DESCRIPTOR *
>  ValidateCapsuleIntegrity (
> -  IN EFI_CAPSULE_BLOCK_DESCRIPTOR    *BlockList
> +  IN EFI_CAPSULE_BLOCK_DESCRIPTOR    *BlockList,
> +  IN MEMORY_RESOURCE_DESCRIPTOR      *MemoryResource
>    )
>  {
>    EFI_CAPSULE_HEADER             *CapsuleHeader;
> @@ -274,14 +320,19 @@ ValidateCapsuleIntegrity (
>    //   * The first capsule header guid
>    //   * The first capsule header flag
>    //   * The first capsule header HeaderSize
> -  //   * Length > MAX_ADDRESS
> -  //   * ContinuationPointer > MAX_ADDRESS
> -  //   * DataBlock + Length > MAX_ADDRESS
> +  //   * Below check will be done in ValidateCapsuleByMemoryResource()
> +  //     Length > MAX_ADDRESS
> +  //     Ptr + sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR) >
> MAX_ADDRESS
> +  //     DataBlock + Length > MAX_ADDRESS
>    //
>    CapsuleSize  = 0;
>    CapsuleCount = 0;
>    Ptr = BlockList;
> 
> +  if (!ValidateCapsuleByMemoryResource (MemoryResource,
> (EFI_PHYSICAL_ADDRESS) (UINTN) Ptr, sizeof
> (EFI_CAPSULE_BLOCK_DESCRIPTOR))) {
> +    return NULL;
> +  }
> +
>    DEBUG ((EFI_D_INFO, "Ptr - 0x%x\n", Ptr));
>    DEBUG ((EFI_D_INFO, "Ptr->Length - 0x%x\n", Ptr->Length));
>    DEBUG ((EFI_D_INFO, "Ptr->Union - 0x%x\n",
> Ptr->Union.ContinuationPointer));
> @@ -293,36 +344,21 @@ ValidateCapsuleIntegrity (
>        DEBUG ((EFI_D_ERROR, "ERROR: BlockList address failed alignment
> check\n"));
>        return NULL;
>      }
> -    //
> -    // Sanity Check
> -    //
> -    if (Ptr->Length > MAX_ADDRESS) {
> -      DEBUG ((EFI_D_ERROR, "ERROR: Ptr->Length(0x%lx) >
> MAX_ADDRESS\n", Ptr->Length));
> -      return NULL;
> -    }
> 
>      if (Ptr->Length == 0) {
>        //
> -      // Sanity Check
> -      //
> -      if (Ptr->Union.ContinuationPointer > MAX_ADDRESS) {
> -        DEBUG ((EFI_D_ERROR, "ERROR:
> Ptr->Union.ContinuationPointer(0x%lx) > MAX_ADDRESS\n",
> Ptr->Union.ContinuationPointer));
> -        return NULL;
> -      }
> -      //
>        // Descriptor points to another list of block descriptors somewhere
>        // else.
>        //
>        Ptr = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN)
> Ptr->Union.ContinuationPointer;
> +      if (!ValidateCapsuleByMemoryResource (MemoryResource,
> (EFI_PHYSICAL_ADDRESS) (UINTN) Ptr, sizeof
> (EFI_CAPSULE_BLOCK_DESCRIPTOR))) {
> +        return NULL;
> +      }
>        DEBUG ((EFI_D_INFO, "Ptr(C) - 0x%x\n", Ptr));
>        DEBUG ((EFI_D_INFO, "Ptr->Length - 0x%x\n", Ptr->Length));
>        DEBUG ((EFI_D_INFO, "Ptr->Union - 0x%x\n",
> Ptr->Union.ContinuationPointer));
>      } else {
> -      //
> -      // Sanity Check
> -      //
> -      if (Ptr->Union.DataBlock > (MAX_ADDRESS - (UINTN)Ptr->Length)) {
> -        DEBUG ((EFI_D_ERROR, "ERROR: Ptr->Union.DataBlock(0x%lx) >
> (MAX_ADDRESS - (UINTN)Ptr->Length(0x%lx))\n", Ptr->Union.DataBlock,
> Ptr->Length));
> +      if (!ValidateCapsuleByMemoryResource (MemoryResource,
> Ptr->Union.DataBlock, Ptr->Length)) {
>          return NULL;
>        }
> 
> @@ -370,6 +406,9 @@ ValidateCapsuleIntegrity (
>        // Move to next BLOCK descriptor
>        //
>        Ptr++;
> +      if (!ValidateCapsuleByMemoryResource (MemoryResource,
> (EFI_PHYSICAL_ADDRESS) (UINTN) Ptr, sizeof
> (EFI_CAPSULE_BLOCK_DESCRIPTOR))) {
> +        return NULL;
> +      }
>        DEBUG ((EFI_D_INFO, "Ptr(B) - 0x%x\n", Ptr));
>        DEBUG ((EFI_D_INFO, "Ptr->Length - 0x%x\n", Ptr->Length));
>        DEBUG ((EFI_D_INFO, "Ptr->Union - 0x%x\n",
> Ptr->Union.ContinuationPointer));
> @@ -816,6 +855,7 @@ CapsuleTestPatternPreCoalesce (
>    Get capsule descriptors from variable CapsuleUpdateData,
> CapsuleUpdateData1, CapsuleUpdateData2...
> 
>    @param BlockListBuffer            Pointer to the buffer of capsule
> descriptors variables
> +  @param MemoryResource             Pointer to the buffer of
> memory resource descriptor.
>    @param BlockDescriptorList        Pointer to the capsule descriptors
> list
> 
>    @retval EFI_SUCCESS               a valid capsule is present
> @@ -824,6 +864,7 @@ CapsuleTestPatternPreCoalesce (
>  EFI_STATUS
>  BuildCapsuleDescriptors (
>    IN  EFI_PHYSICAL_ADDRESS            *BlockListBuffer,
> +  IN  MEMORY_RESOURCE_DESCRIPTOR      *MemoryResource,
>    OUT EFI_CAPSULE_BLOCK_DESCRIPTOR    **BlockDescriptorList
>    )
>  {
> @@ -844,7 +885,7 @@ BuildCapsuleDescriptors (
>      // Test integrity of descriptors.
>      //
>      if (BlockListBuffer[Index] < MAX_ADDRESS) {
> -      TempBlock = ValidateCapsuleIntegrity
> ((EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)BlockListBuffer[Index]);
> +      TempBlock = ValidateCapsuleIntegrity
> ((EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)BlockListBuffer[Index],
> MemoryResource);
>        if (TempBlock != NULL) {
>          if (LastBlock == NULL) {
>            LastBlock = TempBlock;
> @@ -928,7 +969,8 @@ CapsuleImageBase-->+---------------------------+
>    coalesce capsule data into memory.
> 
>    @param PeiServices        General purpose services available to
> every PEIM.
> -  @param BlockListBuffer    Point to the buffer of Capsule Descriptor
> Variables.
> +  @param BlockListBuffer    Pointer to the buffer of Capsule Descriptor
> Variables.
> +  @param MemoryResource     Pointer to the buffer of memory
> resource descriptor.
>    @param MemoryBase         Pointer to the base of a block of
> memory that we can walk
>                              all over while trying to coalesce our
> buffers.
>                              On output, this variable will hold the
> base address of
> @@ -950,6 +992,7 @@ EFIAPI
>  CapsuleDataCoalesce (
>    IN EFI_PEI_SERVICES                **PeiServices,
>    IN EFI_PHYSICAL_ADDRESS            *BlockListBuffer,
> +  IN MEMORY_RESOURCE_DESCRIPTOR      *MemoryResource,
>    IN OUT VOID                        **MemoryBase,
>    IN OUT UINTN                       *MemorySize
>    )
> @@ -994,7 +1037,7 @@ CapsuleDataCoalesce (
>    //
>    // Build capsule descriptors list
>    //
> -  Status = BuildCapsuleDescriptors (BlockListBuffer, &BlockList);
> +  Status = BuildCapsuleDescriptors (BlockListBuffer, MemoryResource,
> &BlockList);
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
> diff --git
> a/MdeModulePkg/Universal/CapsulePei/Common/CommonHeader.h
> b/MdeModulePkg/Universal/CapsulePei/Common/CommonHeader.h
> index 6210d2133ebc..7298874f9e62 100644
> --- a/MdeModulePkg/Universal/CapsulePei/Common/CommonHeader.h
> +++ b/MdeModulePkg/Universal/CapsulePei/Common/CommonHeader.h
> @@ -1,7 +1,7 @@
>  /** @file
>    Common header file.
> 
> -Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
>  This program and the accompanying materials
>  are licensed and made available under the terms and conditions of the BSD
> License
>  which accompanies this distribution.  The full text of the license may be
> found at
> @@ -35,6 +35,17 @@ typedef struct {
>  } EFI_CAPSULE_PEIM_PRIVATE_DATA;
>  #pragma pack()
> 
> +typedef struct {
> +  ///
> +  /// The physical start address of the resource region.
> +  ///
> +  EFI_PHYSICAL_ADDRESS        PhysicalStart;
> +  ///
> +  /// The number of bytes of the resource region.
> +  ///
> +  UINT64                      ResourceLength;
> +} MEMORY_RESOURCE_DESCRIPTOR;
> +
>  #define CAPSULE_TEST_SIGNATURE SIGNATURE_32('T', 'E', 'S', 'T')
> 
>  #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> @@ -45,6 +56,7 @@ typedef struct {
>    UINT64                StackBufferLength;
>    EFI_PHYSICAL_ADDRESS  JumpBuffer;
>    EFI_PHYSICAL_ADDRESS  BlockListAddr;
> +  EFI_PHYSICAL_ADDRESS  MemoryResource;
>    EFI_PHYSICAL_ADDRESS  MemoryBase64Ptr;
>    EFI_PHYSICAL_ADDRESS  MemorySize64Ptr;
>    BOOLEAN               Page1GSupport;
> @@ -71,6 +83,7 @@ typedef struct {
> 
>    @param PeiServices        General purpose services available to
> every PEIM.
>    @param BlockListBuffer    Point to the buffer of Capsule Descriptor
> Variables.
> +  @param MemoryResource     Pointer to the buffer of memory
> resource descriptor.
>    @param MemoryBase         Pointer to the base of a block of
> memory that we can walk
>                              all over while trying to coalesce our
> buffers.
>                              On output, this variable will hold the
> base address of
> @@ -94,7 +107,8 @@ EFI_STATUS
>  EFIAPI
>  CapsuleDataCoalesce (
>    IN EFI_PEI_SERVICES                **PeiServices,
> -  IN IN EFI_PHYSICAL_ADDRESS         *BlockListBuffer,
> +  IN EFI_PHYSICAL_ADDRESS            *BlockListBuffer,
> +  IN MEMORY_RESOURCE_DESCRIPTOR      *MemoryResource,
>    IN OUT VOID                        **MemoryBase,
>    IN OUT UINTN                       *MemorySize
>    );
> diff --git a/MdeModulePkg/Universal/CapsulePei/UefiCapsule.c
> b/MdeModulePkg/Universal/CapsulePei/UefiCapsule.c
> index befd803af17b..e60105b31caa 100644
> --- a/MdeModulePkg/Universal/CapsulePei/UefiCapsule.c
> +++ b/MdeModulePkg/Universal/CapsulePei/UefiCapsule.c
> @@ -354,6 +354,7 @@ Thunk32To64 (
>    @param  LongModeBuffer            The context of long mode.
>    @param  CoalesceEntry             Entry of coalesce image.
>    @param  BlockListAddr             Address of block list.
> +  @param  MemoryResource            Pointer to the buffer of
> memory resource descriptor.
>    @param  MemoryBase                Base of memory range.
>    @param  MemorySize                Size of memory range.
> 
> @@ -366,6 +367,7 @@ ModeSwitch (
>    IN EFI_CAPSULE_LONG_MODE_BUFFER   *LongModeBuffer,
>    IN COALESCE_ENTRY                 CoalesceEntry,
>    IN EFI_PHYSICAL_ADDRESS           BlockListAddr,
> +  IN MEMORY_RESOURCE_DESCRIPTOR     *MemoryResource,
>    IN OUT VOID                       **MemoryBase,
>    IN OUT UINTN                      *MemorySize
>    )
> @@ -429,6 +431,7 @@ ModeSwitch (
>    Context.StackBufferLength     = LongModeBuffer->StackSize;
>    Context.EntryPoint            =
> (EFI_PHYSICAL_ADDRESS)(UINTN)CoalesceEntry;
>    Context.BlockListAddr         = BlockListAddr;
> +  Context.MemoryResource        =
> (EFI_PHYSICAL_ADDRESS)(UINTN)MemoryResource;
>    Context.MemoryBase64Ptr       =
> (EFI_PHYSICAL_ADDRESS)(UINTN)&MemoryBase64;
>    Context.MemorySize64Ptr       =
> (EFI_PHYSICAL_ADDRESS)(UINTN)&MemorySize64;
>    Context.Page1GSupport         = Page1GSupport;
> @@ -560,6 +563,133 @@ GetLongModeContext (
>  }
>  #endif
> 
> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> +/**
> +  Get physical address bits.
> +
> +  @return Physical address bits.
> +
> +**/
> +UINT8
> +GetPhysicalAddressBits (
> +  VOID
> +  )
> +{
> +  UINT32                        RegEax;
> +  UINT8                         PhysicalAddressBits;
> +  VOID                          *Hob;
> +
> +  //
> +  // Get physical address bits supported.
> +  //
> +  Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
> +  if (Hob != NULL) {
> +    PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
> +  } else {
> +    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
> +    if (RegEax >= 0x80000008) {
> +      AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
> +      PhysicalAddressBits = (UINT8) RegEax;
> +    } else {
> +      PhysicalAddressBits = 36;
> +    }
> +  }
> +
> +  //
> +  // IA-32e paging translates 48-bit linear addresses to 52-bit physical
> addresses.
> +  //
> +  ASSERT (PhysicalAddressBits <= 52);
> +  if (PhysicalAddressBits > 48) {
> +    PhysicalAddressBits = 48;
> +  }
> +
> +  return PhysicalAddressBits;
> +}
> +#endif
> +
> +/**
> +  Build memory resource descriptor from resource descriptor in HOB list.
> +
> +  @return Pointer to the buffer of memory resource descriptor.
> +          NULL if no memory resource descriptor reported in HOB list
> +          before capsule Coalesce.
> +
> +**/
> +MEMORY_RESOURCE_DESCRIPTOR *
> +BuildMemoryResourceDescriptor (
> +  VOID
> +  )
> +{
> +  EFI_PEI_HOB_POINTERS          Hob;
> +  UINTN                         Index;
> +  EFI_HOB_RESOURCE_DESCRIPTOR   *ResourceDescriptor;
> +  MEMORY_RESOURCE_DESCRIPTOR    *MemoryResource;
> +  EFI_STATUS                    Status;
> +
> +  //
> +  // Get the count of memory resource descriptor.
> +  //
> +  Index = 0;
> +  Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
> +  while (Hob.Raw != NULL) {
> +    ResourceDescriptor = (EFI_HOB_RESOURCE_DESCRIPTOR *) Hob.Raw;
> +    if (ResourceDescriptor->ResourceType ==
> EFI_RESOURCE_SYSTEM_MEMORY) {
> +      Index++;
> +    }
> +    Hob.Raw = GET_NEXT_HOB (Hob);
> +    Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
> Hob.Raw);
> +  }
> +
> +  if (Index == 0) {
> +    DEBUG ((EFI_D_INFO | EFI_D_WARN, "No memory resource
> descriptor reported in HOB list before capsule Coalesce\n"));
> +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> +    //
> +    // Allocate memory to hold memory resource descriptor,
> +    // include extra one NULL terminate memory resource descriptor.
> +    //
> +    Status = PeiServicesAllocatePool ((1 + 1) * sizeof
> (MEMORY_RESOURCE_DESCRIPTOR), (VOID **) &MemoryResource);
> +    ASSERT_EFI_ERROR (Status);
> +    ZeroMem (MemoryResource, (1 + 1) * sizeof
> (MEMORY_RESOURCE_DESCRIPTOR));
> +
> +    MemoryResource[0].PhysicalStart = 0;
> +    MemoryResource[0].ResourceLength = LShiftU64 (1,
> GetPhysicalAddressBits ());
> +    DEBUG ((EFI_D_INFO, "MemoryResource[0x0] - Start(0x%0lx)
> Length(0x%0lx)\n",
> +                        MemoryResource[0x0].PhysicalStart,
> MemoryResource[0x0].ResourceLength));
> +    return MemoryResource;
> +#else
> +    return NULL;
> +#endif
> +  }
> +
> +  //
> +  // Allocate memory to hold memory resource descriptor,
> +  // include extra one NULL terminate memory resource descriptor.
> +  //
> +  Status = PeiServicesAllocatePool ((Index + 1) * sizeof
> (MEMORY_RESOURCE_DESCRIPTOR), (VOID **) &MemoryResource);
> +  ASSERT_EFI_ERROR (Status);
> +  ZeroMem (MemoryResource, (Index + 1) * sizeof
> (MEMORY_RESOURCE_DESCRIPTOR));
> +
> +  //
> +  // Get the content of memory resource descriptor.
> +  //
> +  Index = 0;
> +  Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
> +  while (Hob.Raw != NULL) {
> +    ResourceDescriptor = (EFI_HOB_RESOURCE_DESCRIPTOR *) Hob.Raw;
> +    if (ResourceDescriptor->ResourceType ==
> EFI_RESOURCE_SYSTEM_MEMORY) {
> +      DEBUG ((EFI_D_INFO, "MemoryResource[0x%x] - Start(0x%0lx)
> Length(0x%0lx)\n",
> +                          Index, ResourceDescriptor->PhysicalStart,
> ResourceDescriptor->ResourceLength));
> +      MemoryResource[Index].PhysicalStart =
> ResourceDescriptor->PhysicalStart;
> +      MemoryResource[Index].ResourceLength =
> ResourceDescriptor->ResourceLength;
> +      Index++;
> +    }
> +    Hob.Raw = GET_NEXT_HOB (Hob);
> +    Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
> Hob.Raw);
> +  }
> +
> +  return MemoryResource;
> +}
> +
>  /**
>    Checks for the presence of capsule descriptors.
>    Get capsule descriptors from variable CapsuleUpdateData,
> CapsuleUpdateData1, CapsuleUpdateData2...
> @@ -711,6 +841,7 @@ CapsuleCoalesce (
>    EFI_BOOT_MODE                        BootMode;
>    EFI_PEI_READ_ONLY_VARIABLE2_PPI      *PPIVariableServices;
>    EFI_PHYSICAL_ADDRESS                 *VariableArrayAddress;
> +  MEMORY_RESOURCE_DESCRIPTOR           *MemoryResource;
>  #ifdef MDE_CPU_IA32
>    UINT16
> CoalesceImageMachineType;
>    EFI_PHYSICAL_ADDRESS                 CoalesceImageEntryPoint;
> @@ -800,6 +931,8 @@ CapsuleCoalesce (
>      goto Done;
>    }
> 
> +  MemoryResource = BuildMemoryResourceDescriptor ();
> +
>  #ifdef MDE_CPU_IA32
>    if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
>      //
> @@ -825,18 +958,18 @@ CapsuleCoalesce (
>      }
>      ASSERT (CoalesceImageEntryPoint != 0);
>      CoalesceEntry = (COALESCE_ENTRY) (UINTN)
> CoalesceImageEntryPoint;
> -    Status = ModeSwitch (&LongModeBuffer, CoalesceEntry,
> (EFI_PHYSICAL_ADDRESS)(UINTN)VariableArrayAddress, MemoryBase,
> MemorySize);
> +    Status = ModeSwitch (&LongModeBuffer, CoalesceEntry,
> (EFI_PHYSICAL_ADDRESS)(UINTN)VariableArrayAddress, MemoryResource,
> MemoryBase, MemorySize);
>    } else {
>      //
>      // Capsule is processed in IA32 mode.
>      //
> -    Status = CapsuleDataCoalesce (PeiServices, (EFI_PHYSICAL_ADDRESS
> *)(UINTN)VariableArrayAddress, MemoryBase, MemorySize);
> +    Status = CapsuleDataCoalesce (PeiServices, (EFI_PHYSICAL_ADDRESS
> *)(UINTN)VariableArrayAddress, MemoryResource, MemoryBase,
> MemorySize);
>    }
>  #else
>    //
>    // Process capsule directly.
>    //
> -  Status = CapsuleDataCoalesce (PeiServices, (EFI_PHYSICAL_ADDRESS
> *)(UINTN)VariableArrayAddress, MemoryBase, MemorySize);
> +  Status = CapsuleDataCoalesce (PeiServices, (EFI_PHYSICAL_ADDRESS
> *)(UINTN)VariableArrayAddress, MemoryResource, MemoryBase,
> MemorySize);
>  #endif
> 
>    DEBUG ((EFI_D_INFO, "Capsule Coalesce Status = %r!\n", Status));
> diff --git a/MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c
> b/MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c
> index 670e2c7d5ff8..d1042e30efb1 100644
> --- a/MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c
> +++ b/MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c
> @@ -1,7 +1,7 @@
>  /** @file
>    The X64 entrypoint is used to process capsule in long mode.
> 
> -Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
>  This program and the accompanying materials
>  are licensed and made available under the terms and conditions of the BSD
> License
>  which accompanies this distribution.  The full text of the license may be
> found at
> @@ -258,6 +258,7 @@ _ModuleEntryPoint (
>    Status = CapsuleDataCoalesce (
>               NULL,
>               (EFI_PHYSICAL_ADDRESS *) (UINTN)
> EntrypointContext->BlockListAddr,
> +             (MEMORY_RESOURCE_DESCRIPTOR *) (UINTN)
> EntrypointContext->MemoryResource,
>               (VOID **) (UINTN) EntrypointContext->MemoryBase64Ptr,
>               (UINTN *) (UINTN) EntrypointContext->MemorySize64Ptr
>               );
> --
> 2.7.0.windows.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to