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