Cc'ing Ben

On 09/17/15 10:09, Star Zeng wrote:
> Take the range in the resource descriptor HOB for the memory region described
> by the PHIT as higher priority if it is big enough. It can make the memory bin
> allocated to be at the same memory region with PHIT that has more better 
> compatibility
> to avoid memory fragmentation for some code practices assume and allocate <4G 
> ACPI memory.
> 
> Also let the minimal memory size needed include the total memory bin size 
> needed to
> make sure memory bin could be allocated successfully.
> 
> V2 corrects a comment in original code and a missing 
> MINIMUM_INITIAL_MEMORY_SIZE updated
> to MinimalMemorySizeNeeded in V1.
> 
> Cc: Jiewen Yao <jiewen....@intel.com>
> Cc: Liming Gao <liming....@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Star Zeng <star.z...@intel.com>
> Reviewed-by: Jiewen Yao <jiewen....@intel.com>
> ---
>  MdeModulePkg/Core/Dxe/Gcd/Gcd.c | 163 
> +++++++++++++++++++++++-----------------
>  1 file changed, 95 insertions(+), 68 deletions(-)

I gave this patch a light review (albeit after the fact :)), and I think
it's good. I think it captures what Ben wanted.

For OVMF the "fallback" loop (ie. the loop that is a fallback *now*) has
always been inactive (because we add the high memory as untested), but I
agree that this priority is preferable.

Anyway I regression-tested this with OVMF, and it seems okay.

Thanks also for addressing my comment remark about EfiFreeMemoryTop <->
EfiMemoryTop in
<http://thread.gmane.org/gmane.comp.bios.edk2.devel/1023/focus=1124>.

Another good thing added in the patch: the logging of the initial region
that was found, on the EFI_D_INFO level. This log message at the
beginning of DXE plays *very nicely* together with the debug message
printed by PeiInstallPeiMemory(), in
"MdeModulePkg/Core/Pei/Memory/MemoryServices.c". One can now verify from
the debug log that DXE's initial region falls within the permanent PEI RAM.

For example, this OVMF guest that I just used for testing, printed:

PeiInstallPeiMemory MemoryBegin 0xBBFBE000, MemoryLength 0x4042000
[...]
CoreInitializeMemoryServices:
  BaseAddress - 0xBBFE0000 Length - 0x3F1E000 MinimalMemorySizeNeeded -
0x10F4000

So the permanent PEI RAM is [0xBBFBE000 .. 0xC0000000), and the initial
DXE region is a proper sub-interval of that, [0xBBFE0000 .. BFEFE000).

Thanks!
Laszlo

> diff --git a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c
> index 77586a9..c276962 100644
> --- a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c
> +++ b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c
> @@ -2003,6 +2003,30 @@ 
> CoreConvertResourceDescriptorHobAttributesToCapabilities (
>    return Capabilities;
>  }
>  
> +/**
> +  Calculate total memory bin size neeeded.
> +
> +  @return The total memory bin size neeeded.
> +
> +**/
> +UINT64
> +CalculateTotalMemoryBinSizeNeeded (
> +  VOID
> +  )
> +{
> +  UINTN     Index;
> +  UINT64    TotalSize;
> +
> +  //
> +  // Loop through each memory type in the order specified by the 
> gMemoryTypeInformation[] array
> +  //
> +  TotalSize = 0;
> +  for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; 
> Index++) {
> +    TotalSize += LShiftU64 (gMemoryTypeInformation[Index].NumberOfPages, 
> EFI_PAGE_SHIFT);
> +  }
> +
> +  return TotalSize;
> +}
>  
>  /**
>    External function. Initializes memory services based on the memory
> @@ -2044,7 +2068,8 @@ CoreInitializeMemoryServices (
>    UINT64                             TestedMemoryLength;
>    EFI_PHYSICAL_ADDRESS               HighAddress;
>    EFI_HOB_GUID_TYPE                  *GuidHob;
> -  UINT32                              ReservedCodePageNumber;
> +  UINT32                             ReservedCodePageNumber;
> +  UINT64                             MinimalMemorySizeNeeded;
>  
>    //
>    // Point at the first HOB.  This must be the PHIT HOB.
> @@ -2098,9 +2123,13 @@ CoreInitializeMemoryServices (
>    }
>  
>    //
> +  // Include the total memory bin size needed to make sure memory bin could 
> be allocated successfully.
> +  //
> +  MinimalMemorySizeNeeded = MINIMUM_INITIAL_MEMORY_SIZE + 
> CalculateTotalMemoryBinSizeNeeded ();
> +
> +  //
>    // Find the Resource Descriptor HOB that contains PHIT range 
> EfiFreeMemoryBottom..EfiFreeMemoryTop
>    //
> -  Length = 0;
>    Found  = FALSE;
>    for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = 
> GET_NEXT_HOB(Hob)) {
>      //
> @@ -2138,19 +2167,19 @@ CoreInitializeMemoryServices (
>      Found = TRUE;
>  
>      //
> -    // Compute range between PHIT EfiFreeMemoryTop and the end of the 
> Resource Descriptor HOB
> +    // Compute range between PHIT EfiMemoryTop and the end of the Resource 
> Descriptor HOB
>      //
>      Attributes  = PhitResourceHob->ResourceAttribute;
>      BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop);
>      Length      = PageAlignLength  (ResourceHob->PhysicalStart + 
> ResourceHob->ResourceLength - BaseAddress);
> -    if (Length < MINIMUM_INITIAL_MEMORY_SIZE) {
> +    if (Length < MinimalMemorySizeNeeded) {
>        //
>        // If that range is not large enough to intialize the DXE Core, then 
>        // Compute range between PHIT EfiFreeMemoryBottom and PHIT 
> EfiFreeMemoryTop
>        //
>        BaseAddress = PageAlignAddress (PhitHob->EfiFreeMemoryBottom);
>        Length      = PageAlignLength  (PhitHob->EfiFreeMemoryTop - 
> BaseAddress);
> -      if (Length < MINIMUM_INITIAL_MEMORY_SIZE) {
> +      if (Length < MinimalMemorySizeNeeded) {
>          //
>          // If that range is not large enough to intialize the DXE Core, then 
>          // Compute range between the start of the Resource Descriptor HOB 
> and the start of the HOB List
> @@ -2168,81 +2197,79 @@ CoreInitializeMemoryServices (
>    ASSERT (Found);
>  
>    //
> -  // Search all the resource descriptor HOBs from the highest possible 
> addresses down for a memory
> -  // region that is big enough to initialize the DXE core.  Always skip the 
> PHIT Resource HOB.
> -  // The max address must be within the physically addressible range for the 
> processor.
> +  // Take the range in the resource descriptor HOB for the memory region 
> described
> +  // by the PHIT as higher priority if it is big enough. It can make the 
> memory bin
> +  // allocated to be at the same memory region with PHIT that has more 
> better compatibility
> +  // to avoid memory fragmentation for some code practices assume and 
> allocate <4G ACPI memory.
>    //
> -  HighAddress = MAX_ADDRESS;
> -  for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = 
> GET_NEXT_HOB(Hob)) {
> -    //
> -    // Skip the Resource Descriptor HOB that contains the PHIT
> -    //
> -    if (Hob.ResourceDescriptor == PhitResourceHob) {
> -      continue;
> -    }
> +  if (Length < MinimalMemorySizeNeeded) {
>      //
> -    // Skip all HOBs except Resource Descriptor HOBs
> +    // Search all the resource descriptor HOBs from the highest possible 
> addresses down for a memory
> +    // region that is big enough to initialize the DXE core.  Always skip 
> the PHIT Resource HOB.
> +    // The max address must be within the physically addressible range for 
> the processor.
>      //
> -    if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
> -      continue;
> -    }
> +    HighAddress = MAX_ADDRESS;
> +    for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = 
> GET_NEXT_HOB(Hob)) {
> +      //
> +      // Skip the Resource Descriptor HOB that contains the PHIT
> +      //
> +      if (Hob.ResourceDescriptor == PhitResourceHob) {
> +        continue;
> +      }
> +      //
> +      // Skip all HOBs except Resource Descriptor HOBs
> +      //
> +      if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
> +        continue;
> +      }
>  
> -    //
> -    // Skip Resource Descriptor HOBs that do not describe tested system 
> memory below MAX_ADDRESS
> -    //
> -    ResourceHob = Hob.ResourceDescriptor;
> -    if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
> -      continue;
> -    }
> -    if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != 
> TESTED_MEMORY_ATTRIBUTES) {
> -      continue;
> -    }
> -    if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > 
> (EFI_PHYSICAL_ADDRESS)MAX_ADDRESS) {
> -      continue;
> -    }
> -    
> -    //
> -    // Skip Resource Descriptor HOBs that are below a previously found 
> Resource Descriptor HOB
> -    //
> -    if (HighAddress != (EFI_PHYSICAL_ADDRESS)MAX_ADDRESS && 
> ResourceHob->PhysicalStart <= HighAddress) {
> -      continue;
> -    }
> +      //
> +      // Skip Resource Descriptor HOBs that do not describe tested system 
> memory below MAX_ADDRESS
> +      //
> +      ResourceHob = Hob.ResourceDescriptor;
> +      if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
> +        continue;
> +      }
> +      if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != 
> TESTED_MEMORY_ATTRIBUTES) {
> +        continue;
> +      }
> +      if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > 
> (EFI_PHYSICAL_ADDRESS)MAX_ADDRESS) {
> +        continue;
> +      }
>  
> -    //
> -    // Skip Resource Descriptor HOBs that are not large enough to initilize 
> the DXE Core
> -    //
> -    TestedMemoryBaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);
> -    TestedMemoryLength      = PageAlignLength  (ResourceHob->PhysicalStart + 
> ResourceHob->ResourceLength - TestedMemoryBaseAddress);
> -    if (TestedMemoryLength < MINIMUM_INITIAL_MEMORY_SIZE) {
> -      continue;
> +      //
> +      // Skip Resource Descriptor HOBs that are below a previously found 
> Resource Descriptor HOB
> +      //
> +      if (HighAddress != (EFI_PHYSICAL_ADDRESS)MAX_ADDRESS && 
> ResourceHob->PhysicalStart <= HighAddress) {
> +        continue;
> +      }
> +
> +      //
> +      // Skip Resource Descriptor HOBs that are not large enough to 
> initilize the DXE Core
> +      //
> +      TestedMemoryBaseAddress = PageAlignAddress 
> (ResourceHob->PhysicalStart);
> +      TestedMemoryLength      = PageAlignLength  (ResourceHob->PhysicalStart 
> + ResourceHob->ResourceLength - TestedMemoryBaseAddress);
> +      if (TestedMemoryLength < MinimalMemorySizeNeeded) {
> +        continue;
> +      }
> +
> +      //
> +      // Save the range described by the Resource Descriptor that is large 
> enough to initilize the DXE Core
> +      //
> +      BaseAddress = TestedMemoryBaseAddress;
> +      Length      = TestedMemoryLength;
> +      Attributes  = ResourceHob->ResourceAttribute; 
> +      HighAddress = ResourceHob->PhysicalStart;
>      }
> -    
> -    //
> -    // Save the Resource Descriptor HOB context that is large enough to 
> initilize the DXE Core
> -    //
> -    MaxMemoryBaseAddress = TestedMemoryBaseAddress;
> -    MaxMemoryLength      = TestedMemoryLength;
> -    MaxMemoryAttributes  = ResourceHob->ResourceAttribute; 
> -    HighAddress          = ResourceHob->PhysicalStart;
>    }
>  
> -  //
> -  // If Length is not large enough to initialize the DXE Core or a Resource 
> -  // Descriptor HOB was found above the PHIT HOB that is large enough to 
> initialize 
> -  // the DXE Core, then use the range described by the Resource Descriptor 
> -  // HOB that was found above the PHIT HOB.
> -  //
> -  if ((Length < MINIMUM_INITIAL_MEMORY_SIZE) ||
> -      (MaxMemoryBaseAddress > BaseAddress && MaxMemoryLength >= 
> MINIMUM_INITIAL_MEMORY_SIZE)) {
> -    BaseAddress = MaxMemoryBaseAddress;
> -    Length      = MaxMemoryLength;
> -    Attributes  = MaxMemoryAttributes;
> -  }
> +  DEBUG ((EFI_D_INFO, "CoreInitializeMemoryServices:\n"));
> +  DEBUG ((EFI_D_INFO, "  BaseAddress - 0x%lx Length - 0x%lx 
> MinimalMemorySizeNeeded - 0x%lx\n", BaseAddress, Length, 
> MinimalMemorySizeNeeded));
>  
>    //
>    // If no memory regions are found that are big enough to initialize the 
> DXE core, then ASSERT().
>    //
> -  ASSERT (Length >= MINIMUM_INITIAL_MEMORY_SIZE);
> +  ASSERT (Length >= MinimalMemorySizeNeeded);
>  
>    //
>    // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask
> 

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to