On Fri, 2015-09-18 at 17:03 +0200, Laszlo Ersek wrote: > Cc'ing Ben Thanks, I saw it :) I just got caught up with a bunch of other things and haven't had a chance to look more closely.
I got legal approval to release code, so I'm hoping sometime in the next few weeks, to push out on github a slightly cleaned up version of my proof of concept ppc64 port. While doing that I will clean up my memory management and test this patch properly. I will also submit patches for dealing with non-1:1 mapping of MMIO in PCI land vs. GetBarAttributes(). Cheers, 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 <[email protected]> > > Cc: Liming Gao <[email protected]> > > Contributed-under: TianoCore Contribution Agreement 1.0 > > Signed-off-by: Star Zeng <[email protected]> > > Reviewed-by: Jiewen Yao <[email protected]> > > --- > > 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 [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

