PrePi.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /** @file
  2. *
  3. * Copyright (c) 2011-2014, ARM Limited. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause-Patent
  6. *
  7. **/
  8. #include <PiPei.h>
  9. #include <Pi/PiBootMode.h>
  10. #include <Library/PeCoffLib.h>
  11. #include <Library/PrePiLib.h>
  12. #include <Library/PrintLib.h>
  13. #include <Library/PrePiHobListPointerLib.h>
  14. #include <Library/TimerLib.h>
  15. #include <Library/PerformanceLib.h>
  16. #include <Library/CacheMaintenanceLib.h>
  17. #include <Ppi/GuidedSectionExtraction.h>
  18. #include <Ppi/ArmMpCoreInfo.h>
  19. #include "PrePi.h"
  20. VOID
  21. EFIAPI
  22. ProcessLibraryConstructorList (
  23. VOID
  24. );
  25. VOID
  26. PrePiMain (
  27. IN UINTN UefiMemoryBase,
  28. IN UINTN StacksBase,
  29. IN UINT64 StartTimeStamp
  30. )
  31. {
  32. EFI_HOB_HANDOFF_INFO_TABLE *HobList;
  33. EFI_STATUS Status;
  34. CHAR8 Buffer[100];
  35. UINTN CharCount;
  36. UINTN StacksSize;
  37. // Initialize the architecture specific bits
  38. ArchInitialize ();
  39. // Declare the PI/UEFI memory region
  40. HobList = HobConstructor (
  41. (VOID *)UefiMemoryBase,
  42. FixedPcdGet32 (PcdSystemMemoryUefiRegionSize),
  43. (VOID *)UefiMemoryBase,
  44. (VOID *)StacksBase // The top of the UEFI Memory is reserved for the stacks
  45. );
  46. PrePeiSetHobList (HobList);
  47. //
  48. // Ensure that the loaded image is invalidated in the caches, so that any
  49. // modifications we made with the caches and MMU off (such as the applied
  50. // relocations) don't become invisible once we turn them on.
  51. //
  52. InvalidateDataCacheRange ((VOID *)(UINTN)PcdGet64 (PcdFdBaseAddress), PcdGet32 (PcdFdSize));
  53. // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
  54. Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
  55. ASSERT_EFI_ERROR (Status);
  56. // Initialize the Serial Port
  57. SerialPortInitialize ();
  58. CharCount = AsciiSPrint (
  59. Buffer,
  60. sizeof (Buffer),
  61. "UEFI firmware (version %s built at %a on %a)\n\r",
  62. (CHAR16 *)PcdGetPtr (PcdFirmwareVersionString),
  63. __TIME__,
  64. __DATE__
  65. );
  66. SerialPortWrite ((UINT8 *)Buffer, CharCount);
  67. // Create the Stacks HOB (reserve the memory for all stacks)
  68. StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
  69. BuildStackHob (StacksBase, StacksSize);
  70. // TODO: Call CpuPei as a library
  71. BuildCpuHob (ArmGetPhysicalAddressBits (), PcdGet8 (PcdPrePiCpuIoSize));
  72. // Set the Boot Mode
  73. SetBootMode (BOOT_WITH_FULL_CONFIGURATION);
  74. // Initialize Platform HOBs (CpuHob and FvHob)
  75. Status = PlatformPeim ();
  76. ASSERT_EFI_ERROR (Status);
  77. // Now, the HOB List has been initialized, we can register performance information
  78. PERF_START (NULL, "PEI", NULL, StartTimeStamp);
  79. // SEC phase needs to run library constructors by hand.
  80. ProcessLibraryConstructorList ();
  81. // Assume the FV that contains the SEC (our code) also contains a compressed FV.
  82. Status = DecompressFirstFv ();
  83. ASSERT_EFI_ERROR (Status);
  84. // Load the DXE Core and transfer control to it
  85. Status = LoadDxeCoreFromFv (NULL, 0);
  86. ASSERT_EFI_ERROR (Status);
  87. }
  88. VOID
  89. CEntryPoint (
  90. IN UINTN MpId,
  91. IN UINTN UefiMemoryBase,
  92. IN UINTN StacksBase
  93. )
  94. {
  95. UINT64 StartTimeStamp;
  96. if (PerformanceMeasurementEnabled ()) {
  97. // Initialize the Timer Library to setup the Timer HW controller
  98. TimerConstructor ();
  99. // We cannot call yet the PerformanceLib because the HOB List has not been initialized
  100. StartTimeStamp = GetPerformanceCounter ();
  101. } else {
  102. StartTimeStamp = 0;
  103. }
  104. // Data Cache enabled on Primary core when MMU is enabled.
  105. ArmDisableDataCache ();
  106. // Invalidate instruction cache
  107. ArmInvalidateInstructionCache ();
  108. // Enable Instruction Caches on all cores.
  109. ArmEnableInstructionCache ();
  110. PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp);
  111. // DXE Core should always load and never return
  112. ASSERT (FALSE);
  113. }
  114. VOID
  115. RelocatePeCoffImage (
  116. IN EFI_PEI_FV_HANDLE FwVolHeader,
  117. IN PE_COFF_LOADER_READ_FILE ImageRead
  118. )
  119. {
  120. EFI_PEI_FILE_HANDLE FileHandle;
  121. VOID *SectionData;
  122. PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
  123. EFI_STATUS Status;
  124. FileHandle = NULL;
  125. Status = FfsFindNextFile (
  126. EFI_FV_FILETYPE_SECURITY_CORE,
  127. FwVolHeader,
  128. &FileHandle
  129. );
  130. ASSERT_EFI_ERROR (Status);
  131. Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SectionData);
  132. if (EFI_ERROR (Status)) {
  133. Status = FfsFindSectionData (EFI_SECTION_TE, FileHandle, &SectionData);
  134. }
  135. ASSERT_EFI_ERROR (Status);
  136. ZeroMem (&ImageContext, sizeof ImageContext);
  137. ImageContext.Handle = (EFI_HANDLE)SectionData;
  138. ImageContext.ImageRead = ImageRead;
  139. PeCoffLoaderGetImageInfo (&ImageContext);
  140. if (ImageContext.ImageAddress != (UINTN)SectionData) {
  141. ImageContext.ImageAddress = (UINTN)SectionData;
  142. PeCoffLoaderRelocateImage (&ImageContext);
  143. }
  144. }