MemoryInitPeim.c 4.8 KB

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