- // If a platform has system memory extensions, it can declare those in this function\r
- Status = ArmPlatformGetAdditionalSystemMemory (&EfiMemoryMap);\r
- if (!EFI_ERROR(Status)) {\r
- // Install the EFI Memory Map\r
- for (Index = 0; EfiMemoryMap[Index].ResourceAttribute != 0; Index++) {\r
- BuildResourceDescriptorHob (\r
- EFI_RESOURCE_SYSTEM_MEMORY,\r
- EfiMemoryMap[Index].ResourceAttribute,\r
- EfiMemoryMap[Index].PhysicalStart,\r
- EfiMemoryMap[Index].NumberOfBytes\r
- );\r
+ SystemMemoryTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemoryBase) + (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemorySize);\r
+ FdTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdFdBaseAddress) + (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFdSize);\r
+\r
+ // EDK2 does not have the concept of boot firmware copied into DRAM. To avoid the DXE\r
+ // core to overwrite this area we must create a memory allocation HOB for the region,\r
+ // but this only works if we split off the underlying resource descriptor as well.\r
+ if ((PcdGet64 (PcdFdBaseAddress) >= PcdGet64 (PcdSystemMemoryBase)) && (FdTop <= SystemMemoryTop)) {\r
+ Found = FALSE;\r
+\r
+ // Search for System Memory Hob that contains the firmware\r
+ NextHob.Raw = GetHobList ();\r
+ while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) {\r
+ if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&\r
+ (PcdGet64 (PcdFdBaseAddress) >= NextHob.ResourceDescriptor->PhysicalStart) &&\r
+ (FdTop <= NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength))\r
+ {\r
+ ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute;\r
+ ResourceLength = NextHob.ResourceDescriptor->ResourceLength;\r
+ ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength;\r
+\r
+ if (PcdGet64 (PcdFdBaseAddress) == NextHob.ResourceDescriptor->PhysicalStart) {\r
+ if (SystemMemoryTop != FdTop) {\r
+ // Create the System Memory HOB for the firmware\r
+ BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,\r
+ ResourceAttributes,\r
+ PcdGet64 (PcdFdBaseAddress),\r
+ PcdGet32 (PcdFdSize));\r
+\r
+ // Top of the FD is system memory available for UEFI\r
+ NextHob.ResourceDescriptor->PhysicalStart += PcdGet32(PcdFdSize);\r
+ NextHob.ResourceDescriptor->ResourceLength -= PcdGet32(PcdFdSize);\r
+ }\r
+ } else {\r
+ // Create the System Memory HOB for the firmware\r
+ BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,\r
+ ResourceAttributes,\r
+ PcdGet64 (PcdFdBaseAddress),\r
+ PcdGet32 (PcdFdSize));\r
+\r
+ // Update the HOB\r
+ NextHob.ResourceDescriptor->ResourceLength = PcdGet64 (PcdFdBaseAddress) - NextHob.ResourceDescriptor->PhysicalStart;\r
+\r
+ // If there is some memory available on the top of the FD then create a HOB\r
+ if (FdTop < NextHob.ResourceDescriptor->PhysicalStart + ResourceLength) {\r
+ // Create the System Memory HOB for the remaining region (top of the FD)\r
+ BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,\r
+ ResourceAttributes,\r
+ FdTop,\r
+ ResourceTop - FdTop);\r
+ }\r
+ }\r
+\r
+ // Mark the memory covering the Firmware Device as boot services data\r
+ BuildMemoryAllocationHob (PcdGet64 (PcdFdBaseAddress),\r
+ PcdGet32 (PcdFdSize),\r
+ EfiBootServicesData);\r
+\r
+ Found = TRUE;\r
+ break;\r
+ }\r
+ NextHob.Raw = GET_NEXT_HOB (NextHob);\r