+ ResourceHob = Hob.ResourceDescriptor;\r
+ //\r
+ // See if this resource descrior HOB describes tested system memory below MAX_ADDRESS\r
+ // \r
+ if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&\r
+ ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS) {\r
+ //\r
+ // See if Top address specified by user is valid.\r
+ //\r
+ if (ResourceHob->PhysicalStart + TotalReservedMemorySize < TopLoadingAddress && \r
+ (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - MINIMUM_INITIAL_MEMORY_SIZE) >= TopLoadingAddress) {\r
+ CurrentResourceHob = ResourceHob; \r
+ CurrentHob = Hob;\r
+ break;\r
+ }\r
+ }\r
+ } \r
+ } \r
+ if (CurrentResourceHob != NULL) {\r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO:Top Address %lx is valid \n", TopLoadingAddress));\r
+ TopLoadingAddress += MINIMUM_INITIAL_MEMORY_SIZE; \r
+ } else {\r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR:Top Address %lx is invalid \n", TopLoadingAddress)); \r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR:The recommended Top Address for the platform is: \n")); \r
+ //\r
+ // Print the recomended Top address range.\r
+ // \r
+ for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {\r
+ //\r
+ // See if this is a resource descriptor HOB\r
+ //\r
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+ \r
+ ResourceHob = Hob.ResourceDescriptor;\r
+ //\r
+ // See if this resource descrior HOB describes tested system memory below MAX_ADDRESS\r
+ // \r
+ if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&\r
+ ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS) {\r
+ //\r
+ // See if Top address specified by user is valid.\r
+ //\r
+ if (ResourceHob->ResourceLength > TotalReservedMemorySize) {\r
+ DEBUG ((EFI_D_INFO, "(%lx, %lx)\n", \r
+ (ResourceHob->PhysicalStart + TotalReservedMemorySize -MINIMUM_INITIAL_MEMORY_SIZE), \r
+ (ResourceHob->PhysicalStart + ResourceHob->ResourceLength -MINIMUM_INITIAL_MEMORY_SIZE) \r
+ )); \r
+ }\r
+ }\r
+ }\r
+ } \r
+ //\r
+ // Assert here \r
+ //\r
+ ASSERT (FALSE); \r
+ } \r
+ } else {\r
+ //\r
+ // The LMFA feature is enabled as load module at fixed offset relative to TOLM\r
+ // Parse the Hob list to find the topest available memory. Generally it is (TOLM - TSEG)\r
+ //\r
+ //\r
+ // Search for a tested memory region that is below MAX_ADDRESS\r
+ //\r
+ for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {\r
+ //\r
+ // See if this is a resource descriptor HOB \r
+ //\r
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+ \r
+ ResourceHob = Hob.ResourceDescriptor; \r
+ //\r
+ // See if this resource descrior HOB describes tested system memory below MAX_ADDRESS\r
+ //\r
+ if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY && \r
+ ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS &&\r
+ ResourceHob->ResourceLength > TotalReservedMemorySize) {\r
+ //\r
+ // See if this is the highest largest system memory region below MaxAddress\r
+ //\r
+ if (ResourceHob->PhysicalStart > HighAddress) {\r
+ CurrentResourceHob = ResourceHob;\r
+ CurrentHob = Hob;\r
+ HighAddress = CurrentResourceHob->PhysicalStart;\r
+ }\r
+ }\r
+ } \r
+ }\r
+ if (CurrentResourceHob == NULL) {\r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR:The System Memory is too small\n")); \r
+ //\r
+ // Assert here \r
+ //\r
+ ASSERT (FALSE); \r
+ } else {\r
+ TopLoadingAddress = CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength ; \r
+ } \r
+ }\r
+ \r
+ if (CurrentResourceHob != NULL) {\r
+ //\r
+ // rebuild hob for PEI memmory and reserved memory\r
+ //\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_SYSTEM_MEMORY, // MemoryType,\r
+ (\r
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+ EFI_RESOURCE_ATTRIBUTE_TESTED |\r
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
+ ),\r
+ (TopLoadingAddress - TotalReservedMemorySize), // MemoryBegin\r
+ TotalReservedMemorySize // MemoryLength\r
+ );\r
+ //\r
+ // rebuild hob for the remain memory if necessary\r
+ //\r
+ if (CurrentResourceHob->PhysicalStart < TopLoadingAddress - TotalReservedMemorySize) {\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_SYSTEM_MEMORY, // MemoryType,\r
+ (\r
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
+ ),\r
+ CurrentResourceHob->PhysicalStart, // MemoryBegin\r
+ (TopLoadingAddress - TotalReservedMemorySize - CurrentResourceHob->PhysicalStart) // MemoryLength\r
+ );\r
+ }\r
+ if (CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength > TopLoadingAddress ) {\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_SYSTEM_MEMORY, \r
+ (\r
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
+ ),\r
+ TopLoadingAddress, \r
+ (CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength - TopLoadingAddress) \r
+ );\r
+ }\r
+ //\r
+ // Delete CurrentHob by marking it as unused since the the memory range described by is rebuilt.\r
+ //\r
+ GET_HOB_TYPE (CurrentHob) = EFI_HOB_TYPE_UNUSED; \r
+ }\r