MemoryInitPeiLib.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /** @file
  2. Copyright (c) 2011-2015, ARM Limited. All rights reserved.
  3. SPDX-License-Identifier: BSD-2-Clause-Patent
  4. **/
  5. #include <PiPei.h>
  6. #include <Library/ArmMmuLib.h>
  7. #include <Library/ArmPlatformLib.h>
  8. #include <Library/DebugLib.h>
  9. #include <Library/HobLib.h>
  10. #include <Library/MemoryAllocationLib.h>
  11. #include <Library/PcdLib.h>
  12. VOID
  13. BuildMemoryTypeInformationHob (
  14. VOID
  15. );
  16. STATIC
  17. VOID
  18. InitMmu (
  19. IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable
  20. )
  21. {
  22. VOID *TranslationTableBase;
  23. UINTN TranslationTableSize;
  24. RETURN_STATUS Status;
  25. // Note: Because we called PeiServicesInstallPeiMemory() before to call InitMmu() the MMU Page Table resides in
  26. // DRAM (even at the top of DRAM as it is the first permanent memory allocation)
  27. Status = ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize);
  28. if (EFI_ERROR (Status)) {
  29. DEBUG ((DEBUG_ERROR, "Error: Failed to enable MMU\n"));
  30. }
  31. }
  32. /*++
  33. Routine Description:
  34. Arguments:
  35. FileHandle - Handle of the file being invoked.
  36. PeiServices - Describes the list of possible PEI Services.
  37. Returns:
  38. Status - EFI_SUCCESS if the boot mode could be set
  39. --*/
  40. EFI_STATUS
  41. EFIAPI
  42. MemoryPeim (
  43. IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
  44. IN UINT64 UefiMemorySize
  45. )
  46. {
  47. ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable;
  48. EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
  49. UINT64 ResourceLength;
  50. EFI_PEI_HOB_POINTERS NextHob;
  51. EFI_PHYSICAL_ADDRESS FdTop;
  52. EFI_PHYSICAL_ADDRESS SystemMemoryTop;
  53. EFI_PHYSICAL_ADDRESS ResourceTop;
  54. BOOLEAN Found;
  55. // Get Virtual Memory Map from the Platform Library
  56. ArmPlatformGetVirtualMemoryMap (&MemoryTable);
  57. // Ensure PcdSystemMemorySize has been set
  58. ASSERT (PcdGet64 (PcdSystemMemorySize) != 0);
  59. //
  60. // Now, the permanent memory has been installed, we can call AllocatePages()
  61. //
  62. ResourceAttributes = (
  63. EFI_RESOURCE_ATTRIBUTE_PRESENT |
  64. EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
  65. EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
  66. EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
  67. EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
  68. EFI_RESOURCE_ATTRIBUTE_TESTED
  69. );
  70. //
  71. // Check if the resource for the main system memory has been declared
  72. //
  73. Found = FALSE;
  74. NextHob.Raw = GetHobList ();
  75. while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) {
  76. if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
  77. (PcdGet64 (PcdSystemMemoryBase) >= NextHob.ResourceDescriptor->PhysicalStart) &&
  78. (NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength <= PcdGet64 (PcdSystemMemoryBase) + PcdGet64 (PcdSystemMemorySize)))
  79. {
  80. Found = TRUE;
  81. break;
  82. }
  83. NextHob.Raw = GET_NEXT_HOB (NextHob);
  84. }
  85. if (!Found) {
  86. // Reserved the memory space occupied by the firmware volume
  87. BuildResourceDescriptorHob (
  88. EFI_RESOURCE_SYSTEM_MEMORY,
  89. ResourceAttributes,
  90. PcdGet64 (PcdSystemMemoryBase),
  91. PcdGet64 (PcdSystemMemorySize)
  92. );
  93. }
  94. //
  95. // Reserved the memory space occupied by the firmware volume
  96. //
  97. SystemMemoryTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemoryBase) + (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemorySize);
  98. FdTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdFdBaseAddress) + (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFdSize);
  99. // EDK2 does not have the concept of boot firmware copied into DRAM. To avoid the DXE
  100. // core to overwrite this area we must create a memory allocation HOB for the region,
  101. // but this only works if we split off the underlying resource descriptor as well.
  102. if ((PcdGet64 (PcdFdBaseAddress) >= PcdGet64 (PcdSystemMemoryBase)) && (FdTop <= SystemMemoryTop)) {
  103. Found = FALSE;
  104. // Search for System Memory Hob that contains the firmware
  105. NextHob.Raw = GetHobList ();
  106. while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) {
  107. if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
  108. (PcdGet64 (PcdFdBaseAddress) >= NextHob.ResourceDescriptor->PhysicalStart) &&
  109. (FdTop <= NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength))
  110. {
  111. ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute;
  112. ResourceLength = NextHob.ResourceDescriptor->ResourceLength;
  113. ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength;
  114. if (PcdGet64 (PcdFdBaseAddress) == NextHob.ResourceDescriptor->PhysicalStart) {
  115. if (SystemMemoryTop != FdTop) {
  116. // Create the System Memory HOB for the firmware
  117. BuildResourceDescriptorHob (
  118. EFI_RESOURCE_SYSTEM_MEMORY,
  119. ResourceAttributes,
  120. PcdGet64 (PcdFdBaseAddress),
  121. PcdGet32 (PcdFdSize)
  122. );
  123. // Top of the FD is system memory available for UEFI
  124. NextHob.ResourceDescriptor->PhysicalStart += PcdGet32 (PcdFdSize);
  125. NextHob.ResourceDescriptor->ResourceLength -= PcdGet32 (PcdFdSize);
  126. }
  127. } else {
  128. // Create the System Memory HOB for the firmware
  129. BuildResourceDescriptorHob (
  130. EFI_RESOURCE_SYSTEM_MEMORY,
  131. ResourceAttributes,
  132. PcdGet64 (PcdFdBaseAddress),
  133. PcdGet32 (PcdFdSize)
  134. );
  135. // Update the HOB
  136. NextHob.ResourceDescriptor->ResourceLength = PcdGet64 (PcdFdBaseAddress) - NextHob.ResourceDescriptor->PhysicalStart;
  137. // If there is some memory available on the top of the FD then create a HOB
  138. if (FdTop < NextHob.ResourceDescriptor->PhysicalStart + ResourceLength) {
  139. // Create the System Memory HOB for the remaining region (top of the FD)
  140. BuildResourceDescriptorHob (
  141. EFI_RESOURCE_SYSTEM_MEMORY,
  142. ResourceAttributes,
  143. FdTop,
  144. ResourceTop - FdTop
  145. );
  146. }
  147. }
  148. // Mark the memory covering the Firmware Device as boot services data
  149. BuildMemoryAllocationHob (
  150. PcdGet64 (PcdFdBaseAddress),
  151. PcdGet32 (PcdFdSize),
  152. EfiBootServicesData
  153. );
  154. Found = TRUE;
  155. break;
  156. }
  157. NextHob.Raw = GET_NEXT_HOB (NextHob);
  158. }
  159. ASSERT (Found);
  160. }
  161. // Build Memory Allocation Hob
  162. InitMmu (MemoryTable);
  163. if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
  164. // Optional feature that helps prevent EFI memory map fragmentation.
  165. BuildMemoryTypeInformationHob ();
  166. }
  167. return EFI_SUCCESS;
  168. }