ArmVirtMemoryInitPeiLib.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /** @file
  2. *
  3. * Copyright (c) 2011-2014, ARM Limited. All rights reserved.
  4. * Copyright (c) 2014, Linaro Limited. All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-2-Clause-Patent
  7. *
  8. **/
  9. #include <PiPei.h>
  10. #include <Library/ArmMmuLib.h>
  11. #include <Library/ArmVirtMemInfoLib.h>
  12. #include <Library/DebugLib.h>
  13. #include <Library/HobLib.h>
  14. #include <Library/MemoryAllocationLib.h>
  15. #include <Library/PcdLib.h>
  16. #include <Library/CacheMaintenanceLib.h>
  17. VOID
  18. BuildMemoryTypeInformationHob (
  19. VOID
  20. );
  21. VOID
  22. InitMmu (
  23. VOID
  24. )
  25. {
  26. ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable;
  27. VOID *TranslationTableBase;
  28. UINTN TranslationTableSize;
  29. RETURN_STATUS Status;
  30. // Get Virtual Memory Map from the Platform Library
  31. ArmVirtGetMemoryMap (&MemoryTable);
  32. // Note: Because we called PeiServicesInstallPeiMemory() before to call InitMmu() the MMU Page Table resides in
  33. // DRAM (even at the top of DRAM as it is the first permanent memory allocation)
  34. Status = ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize);
  35. if (EFI_ERROR (Status)) {
  36. DEBUG ((DEBUG_ERROR, "Error: Failed to enable MMU\n"));
  37. }
  38. }
  39. EFI_STATUS
  40. EFIAPI
  41. MemoryPeim (
  42. IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
  43. IN UINT64 UefiMemorySize
  44. )
  45. {
  46. EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
  47. UINT64 SystemMemoryTop;
  48. // Ensure PcdSystemMemorySize has been set
  49. ASSERT (PcdGet64 (PcdSystemMemorySize) != 0);
  50. //
  51. // Now, the permanent memory has been installed, we can call AllocatePages()
  52. //
  53. ResourceAttributes = (
  54. EFI_RESOURCE_ATTRIBUTE_PRESENT |
  55. EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
  56. EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
  57. EFI_RESOURCE_ATTRIBUTE_TESTED
  58. );
  59. SystemMemoryTop = PcdGet64 (PcdSystemMemoryBase) +
  60. PcdGet64 (PcdSystemMemorySize);
  61. if (SystemMemoryTop - 1 > MAX_ALLOC_ADDRESS) {
  62. BuildResourceDescriptorHob (
  63. EFI_RESOURCE_SYSTEM_MEMORY,
  64. ResourceAttributes,
  65. PcdGet64 (PcdSystemMemoryBase),
  66. (UINT64)MAX_ALLOC_ADDRESS - PcdGet64 (PcdSystemMemoryBase) + 1
  67. );
  68. BuildResourceDescriptorHob (
  69. EFI_RESOURCE_SYSTEM_MEMORY,
  70. ResourceAttributes,
  71. (UINT64)MAX_ALLOC_ADDRESS + 1,
  72. SystemMemoryTop - MAX_ALLOC_ADDRESS - 1
  73. );
  74. } else {
  75. BuildResourceDescriptorHob (
  76. EFI_RESOURCE_SYSTEM_MEMORY,
  77. ResourceAttributes,
  78. PcdGet64 (PcdSystemMemoryBase),
  79. PcdGet64 (PcdSystemMemorySize)
  80. );
  81. }
  82. //
  83. // When running under virtualization, the PI/UEFI memory region may be
  84. // clean but not invalidated in system caches or in lower level caches
  85. // on other CPUs. So invalidate the region by virtual address, to ensure
  86. // that the contents we put there with the caches and MMU off will still
  87. // be visible after turning them on.
  88. //
  89. InvalidateDataCacheRange ((VOID *)(UINTN)UefiMemoryBase, UefiMemorySize);
  90. // Build Memory Allocation Hob
  91. InitMmu ();
  92. if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
  93. // Optional feature that helps prevent EFI memory map fragmentation.
  94. BuildMemoryTypeInformationHob ();
  95. }
  96. return EFI_SUCCESS;
  97. }