MemoryInitPeim.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /** @file
  2. Copyright (c) 2011, ARM Limited. All rights reserved.
  3. SPDX-License-Identifier: BSD-2-Clause-Patent
  4. **/
  5. #include <PiPei.h>
  6. //
  7. // The protocols, PPI and GUID definitions for this module
  8. //
  9. #include <Ppi/MasterBootMode.h>
  10. #include <Ppi/BootInRecoveryMode.h>
  11. #include <Guid/MemoryTypeInformation.h>
  12. //
  13. // The Library classes this module consumes
  14. //
  15. #include <Library/ArmPlatformLib.h>
  16. #include <Library/DebugLib.h>
  17. #include <Library/HobLib.h>
  18. #include <Library/PeimEntryPoint.h>
  19. #include <Library/PeiServicesLib.h>
  20. #include <Library/PcdLib.h>
  21. EFI_STATUS
  22. EFIAPI
  23. MemoryPeim (
  24. IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
  25. IN UINT64 UefiMemorySize
  26. );
  27. // May want to put this into a library so you only need the PCD settings if you are using the feature?
  28. VOID
  29. BuildMemoryTypeInformationHob (
  30. VOID
  31. )
  32. {
  33. EFI_MEMORY_TYPE_INFORMATION Info[10];
  34. Info[0].Type = EfiACPIReclaimMemory;
  35. Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory);
  36. Info[1].Type = EfiACPIMemoryNVS;
  37. Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS);
  38. Info[2].Type = EfiReservedMemoryType;
  39. Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType);
  40. Info[3].Type = EfiRuntimeServicesData;
  41. Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData);
  42. Info[4].Type = EfiRuntimeServicesCode;
  43. Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode);
  44. Info[5].Type = EfiBootServicesCode;
  45. Info[5].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesCode);
  46. Info[6].Type = EfiBootServicesData;
  47. Info[6].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesData);
  48. Info[7].Type = EfiLoaderCode;
  49. Info[7].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderCode);
  50. Info[8].Type = EfiLoaderData;
  51. Info[8].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderData);
  52. // Terminator for the list
  53. Info[9].Type = EfiMaxMemoryType;
  54. Info[9].NumberOfPages = 0;
  55. BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info));
  56. }
  57. /*++
  58. Routine Description:
  59. Arguments:
  60. FileHandle - Handle of the file being invoked.
  61. PeiServices - Describes the list of possible PEI Services.
  62. Returns:
  63. Status - EFI_SUCCESS if the boot mode could be set
  64. --*/
  65. EFI_STATUS
  66. EFIAPI
  67. InitializeMemory (
  68. IN EFI_PEI_FILE_HANDLE FileHandle,
  69. IN CONST EFI_PEI_SERVICES **PeiServices
  70. )
  71. {
  72. EFI_STATUS Status;
  73. UINTN SystemMemoryBase;
  74. UINT64 SystemMemoryTop;
  75. UINTN FdBase;
  76. UINTN FdTop;
  77. UINTN UefiMemoryBase;
  78. DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Memory Init PEIM Loaded\n"));
  79. // Ensure PcdSystemMemorySize has been set
  80. ASSERT (PcdGet64 (PcdSystemMemorySize) != 0);
  81. ASSERT (PcdGet64 (PcdSystemMemoryBase) < (UINT64)MAX_ALLOC_ADDRESS);
  82. SystemMemoryBase = (UINTN)PcdGet64 (PcdSystemMemoryBase);
  83. SystemMemoryTop = SystemMemoryBase + PcdGet64 (PcdSystemMemorySize);
  84. if (SystemMemoryTop - 1 > MAX_ALLOC_ADDRESS) {
  85. SystemMemoryTop = (UINT64)MAX_ALLOC_ADDRESS + 1;
  86. }
  87. FdBase = (UINTN)PcdGet64 (PcdFdBaseAddress);
  88. FdTop = FdBase + (UINTN)PcdGet32 (PcdFdSize);
  89. //
  90. // Declare the UEFI memory to PEI
  91. //
  92. // In case the firmware has been shadowed in the System Memory
  93. if ((FdBase >= SystemMemoryBase) && (FdTop <= SystemMemoryTop)) {
  94. // Check if there is enough space between the top of the system memory and the top of the
  95. // firmware to place the UEFI memory (for PEI & DXE phases)
  96. if (SystemMemoryTop - FdTop >= FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)) {
  97. UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
  98. } else {
  99. // Check there is enough space for the UEFI memory
  100. ASSERT (SystemMemoryBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize) <= FdBase);
  101. UefiMemoryBase = FdBase - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
  102. }
  103. } else {
  104. // Check the Firmware does not overlapped with the system memory
  105. ASSERT ((FdBase < SystemMemoryBase) || (FdBase >= SystemMemoryTop));
  106. ASSERT ((FdTop <= SystemMemoryBase) || (FdTop > SystemMemoryTop));
  107. UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
  108. }
  109. Status = PeiServicesInstallPeiMemory (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
  110. ASSERT_EFI_ERROR (Status);
  111. // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
  112. Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
  113. ASSERT_EFI_ERROR (Status);
  114. return Status;
  115. }