PrePeiCore.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /** @file
  2. Main file supporting the transition to PEI Core in Normal World for Versatile Express
  3. Copyright (c) 2011 - 2022, ARM Limited. All rights reserved.
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <Library/BaseLib.h>
  7. #include <Library/CacheMaintenanceLib.h>
  8. #include <Library/DebugAgentLib.h>
  9. #include <Library/ArmLib.h>
  10. #include <Library/PrintLib.h>
  11. #include <Library/SerialPortLib.h>
  12. #include "PrePeiCore.h"
  13. CONST EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = { PrePeiCoreTemporaryRamSupport };
  14. CONST EFI_PEI_PPI_DESCRIPTOR gCommonPpiTable[] = {
  15. {
  16. EFI_PEI_PPI_DESCRIPTOR_PPI,
  17. &gEfiTemporaryRamSupportPpiGuid,
  18. (VOID *)&mTemporaryRamSupportPpi
  19. }
  20. };
  21. VOID
  22. CreatePpiList (
  23. OUT UINTN *PpiListSize,
  24. OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
  25. )
  26. {
  27. EFI_PEI_PPI_DESCRIPTOR *PlatformPpiList;
  28. UINTN PlatformPpiListSize;
  29. UINTN ListBase;
  30. EFI_PEI_PPI_DESCRIPTOR *LastPpi;
  31. // Get the Platform PPIs
  32. PlatformPpiListSize = 0;
  33. ArmPlatformGetPlatformPpiList (&PlatformPpiListSize, &PlatformPpiList);
  34. // Copy the Common and Platform PPis in Temporary Memory
  35. ListBase = PcdGet64 (PcdCPUCoresStackBase);
  36. CopyMem ((VOID *)ListBase, gCommonPpiTable, sizeof (gCommonPpiTable));
  37. CopyMem ((VOID *)(ListBase + sizeof (gCommonPpiTable)), PlatformPpiList, PlatformPpiListSize);
  38. // Set the Terminate flag on the last PPI entry
  39. LastPpi = (EFI_PEI_PPI_DESCRIPTOR *)ListBase + ((sizeof (gCommonPpiTable) + PlatformPpiListSize) / sizeof (EFI_PEI_PPI_DESCRIPTOR)) - 1;
  40. LastPpi->Flags |= EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
  41. *PpiList = (EFI_PEI_PPI_DESCRIPTOR *)ListBase;
  42. *PpiListSize = sizeof (gCommonPpiTable) + PlatformPpiListSize;
  43. }
  44. /**
  45. Prints firmware version and build time to serial console.
  46. **/
  47. STATIC
  48. VOID
  49. PrintFirmwareVersion (
  50. VOID
  51. )
  52. {
  53. CHAR8 Buffer[100];
  54. UINTN CharCount;
  55. CharCount = AsciiSPrint (
  56. Buffer,
  57. sizeof (Buffer),
  58. "UEFI firmware (version %s built at %a on %a)\n\r",
  59. (CHAR16 *)PcdGetPtr (PcdFirmwareVersionString),
  60. __TIME__,
  61. __DATE__
  62. );
  63. SerialPortWrite ((UINT8 *)Buffer, CharCount);
  64. }
  65. VOID
  66. CEntryPoint (
  67. IN UINTN MpId,
  68. IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
  69. )
  70. {
  71. if (!ArmMmuEnabled ()) {
  72. // Data Cache enabled on Primary core when MMU is enabled.
  73. ArmDisableDataCache ();
  74. // Invalidate instruction cache
  75. ArmInvalidateInstructionCache ();
  76. // Enable Instruction Caches on all cores.
  77. ArmEnableInstructionCache ();
  78. InvalidateDataCacheRange (
  79. (VOID *)(UINTN)PcdGet64 (PcdCPUCoresStackBase),
  80. PcdGet32 (PcdCPUCorePrimaryStackSize)
  81. );
  82. }
  83. //
  84. // Note: Doesn't have to Enable CPU interface in non-secure world,
  85. // as Non-secure interface is already enabled in Secure world.
  86. //
  87. // Write VBAR - The Exception Vector table must be aligned to its requirement
  88. // Note: The AArch64 Vector table must be 2k-byte aligned - if this assertion fails ensure
  89. // 'Align=4K' is defined into your FDF for this module.
  90. ASSERT (((UINTN)PeiVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0);
  91. ArmWriteVBar ((UINTN)PeiVectorTable);
  92. // Enable Floating Point
  93. if (FixedPcdGet32 (PcdVFPEnabled)) {
  94. ArmEnableVFP ();
  95. }
  96. // Note: The MMU will be enabled by MemoryPeim. Only the primary core will have the MMU on.
  97. // If not primary Jump to Secondary Main
  98. if (ArmPlatformIsPrimaryCore (MpId)) {
  99. // Invoke "ProcessLibraryConstructorList" to have all library constructors
  100. // called.
  101. ProcessLibraryConstructorList ();
  102. PrintFirmwareVersion ();
  103. // Initialize the Debug Agent for Source Level Debugging
  104. InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
  105. SaveAndSetDebugTimerInterrupt (TRUE);
  106. // Initialize the platform specific controllers
  107. ArmPlatformInitialize (MpId);
  108. // Goto primary Main.
  109. PrimaryMain (PeiCoreEntryPoint);
  110. } else {
  111. SecondaryMain (MpId);
  112. }
  113. // PEI Core should always load and never return
  114. ASSERT (FALSE);
  115. }
  116. EFI_STATUS
  117. EFIAPI
  118. PrePeiCoreTemporaryRamSupport (
  119. IN CONST EFI_PEI_SERVICES **PeiServices,
  120. IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
  121. IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
  122. IN UINTN CopySize
  123. )
  124. {
  125. VOID *OldHeap;
  126. VOID *NewHeap;
  127. VOID *OldStack;
  128. VOID *NewStack;
  129. UINTN HeapSize;
  130. HeapSize = ALIGN_VALUE (CopySize / 2, CPU_STACK_ALIGNMENT);
  131. OldHeap = (VOID *)(UINTN)TemporaryMemoryBase;
  132. NewHeap = (VOID *)((UINTN)PermanentMemoryBase + (CopySize - HeapSize));
  133. OldStack = (VOID *)((UINTN)TemporaryMemoryBase + HeapSize);
  134. NewStack = (VOID *)(UINTN)PermanentMemoryBase;
  135. //
  136. // Migrate the temporary memory stack to permanent memory stack.
  137. //
  138. CopyMem (NewStack, OldStack, CopySize - HeapSize);
  139. //
  140. // Migrate the temporary memory heap to permanent memory heap.
  141. //
  142. CopyMem (NewHeap, OldHeap, HeapSize);
  143. SecSwitchStack ((UINTN)NewStack - (UINTN)OldStack);
  144. return EFI_SUCCESS;
  145. }