]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/PrePeiCore/PrePeiCore.c
ArmPlatformPkg: Renamed and Invoked earlier ArmPlatformNormalInitialize()
[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, ARM Limited. All rights reserved.
5 *
6 * This program and the accompanying materials
7 * are licensed and made available under the terms and conditions of the BSD License
8 * which accompanies this distribution. The full text of the license may be found at
9 * http://opensource.org/licenses/bsd-license.php
10 *
11 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 *
14 **/
15
16 #include <Library/BaseLib.h>
17 #include <Library/DebugAgentLib.h>
18 #include <Library/PrintLib.h>
19 #include <Library/ArmLib.h>
20 #include <Library/SerialPortLib.h>
21
22 #include <Ppi/ArmGlobalVariable.h>
23
24 #include "PrePeiCore.h"
25
26 EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = { PrePeiCoreTemporaryRamSupport };
27 ARM_GLOBAL_VARIABLE_PPI mGlobalVariablePpi = { PrePeiCoreGetGlobalVariableMemory };
28
29 EFI_PEI_PPI_DESCRIPTOR gCommonPpiTable[] = {
30 {
31 EFI_PEI_PPI_DESCRIPTOR_PPI,
32 &gEfiTemporaryRamSupportPpiGuid,
33 &mTemporaryRamSupportPpi
34 },
35 {
36 EFI_PEI_PPI_DESCRIPTOR_PPI,
37 &gArmGlobalVariablePpiGuid,
38 &mGlobalVariablePpi
39 }
40 };
41
42 VOID
43 CreatePpiList (
44 OUT UINTN *PpiListSize,
45 OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
46 )
47 {
48 EFI_PEI_PPI_DESCRIPTOR *PlatformPpiList;
49 UINTN PlatformPpiListSize;
50 UINTN ListBase;
51 EFI_PEI_PPI_DESCRIPTOR *LastPpi;
52
53 // Get the Platform PPIs
54 PlatformPpiListSize = 0;
55 ArmPlatformGetPlatformPpiList (&PlatformPpiListSize, &PlatformPpiList);
56
57 // Copy the Common and Platform PPis in Temporrary Memory
58 ListBase = PcdGet32 (PcdCPUCoresStackBase);
59 CopyMem ((VOID*)ListBase, gCommonPpiTable, sizeof(gCommonPpiTable));
60 CopyMem ((VOID*)(ListBase + sizeof(gCommonPpiTable)), PlatformPpiList, PlatformPpiListSize);
61
62 // Set the Terminate flag on the last PPI entry
63 LastPpi = (EFI_PEI_PPI_DESCRIPTOR*)ListBase + ((sizeof(gCommonPpiTable) + PlatformPpiListSize) / sizeof(EFI_PEI_PPI_DESCRIPTOR)) - 1;
64 LastPpi->Flags |= EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
65
66 *PpiList = (EFI_PEI_PPI_DESCRIPTOR*)ListBase;
67 *PpiListSize = sizeof(gCommonPpiTable) + PlatformPpiListSize;
68 }
69
70 VOID
71 CEntryPoint (
72 IN UINTN MpId,
73 IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
74 )
75 {
76 //Clean Data cache
77 ArmCleanInvalidateDataCache();
78
79 //Invalidate instruction cache
80 ArmInvalidateInstructionCache();
81
82 // Enable Instruction & Data caches
83 ArmEnableDataCache ();
84 ArmEnableInstructionCache ();
85
86 //
87 // Note: Doesn't have to Enable CPU interface in non-secure world,
88 // as Non-secure interface is already enabled in Secure world.
89 //
90
91 // Write VBAR - The Vector table must be 32-byte aligned
92 ASSERT(((UINT32)PeiVectorTable & ((1 << 5)-1)) == 0);
93 ArmWriteVBar((UINT32)PeiVectorTable);
94
95 //Note: The MMU will be enabled by MemoryPeim. Only the primary core will have the MMU on.
96
97 // If not primary Jump to Secondary Main
98 if (IS_PRIMARY_CORE(MpId)) {
99 // Initialize the Debug Agent for Source Level Debugging
100 InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
101 SaveAndSetDebugTimerInterrupt (TRUE);
102
103 // Initialize the platform specific controllers
104 ArmPlatformInitialize (MpId);
105
106 // Goto primary Main.
107 PrimaryMain (PeiCoreEntryPoint);
108 } else {
109 SecondaryMain (MpId);
110 }
111
112 // PEI Core should always load and never return
113 ASSERT (FALSE);
114 }
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
130 OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
131 NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
132
133 OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
134 NewStack = (VOID*)(UINTN)PermanentMemoryBase;
135
136 //
137 // Migrate the temporary memory stack to permanent memory stack.
138 //
139 CopyMem (NewStack, OldStack, CopySize >> 1);
140
141 //
142 // Migrate the temporary memory heap to permanent memory heap.
143 //
144 CopyMem (NewHeap, OldHeap, CopySize >> 1);
145
146 SecSwitchStack ((UINTN)NewStack - (UINTN)OldStack);
147
148 return EFI_SUCCESS;
149 }
150
151 EFI_STATUS
152 PrePeiCoreGetGlobalVariableMemory (
153 OUT EFI_PHYSICAL_ADDRESS *GlobalVariableBase
154 )
155 {
156 ASSERT (GlobalVariableBase != NULL);
157
158 *GlobalVariableBase = (UINTN)PcdGet32 (PcdCPUCoresStackBase) +
159 (UINTN)PcdGet32 (PcdCPUCorePrimaryStackSize) -
160 (UINTN)PcdGet32 (PcdPeiGlobalVariableSize);
161
162 return EFI_SUCCESS;
163 }
164
165 VOID
166 PeiCommonExceptionEntry (
167 IN UINT32 Entry,
168 IN UINT32 LR
169 )
170 {
171 CHAR8 Buffer[100];
172 UINTN CharCount;
173
174 switch (Entry) {
175 case 0:
176 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Reset Exception at 0x%X\n\r",LR);
177 break;
178 case 1:
179 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Undefined Exception at 0x%X\n\r",LR);
180 break;
181 case 2:
182 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"SWI Exception at 0x%X\n\r",LR);
183 break;
184 case 3:
185 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"PrefetchAbort Exception at 0x%X\n\r",LR);
186 break;
187 case 4:
188 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"DataAbort Exception at 0x%X\n\r",LR);
189 break;
190 case 5:
191 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Reserved Exception at 0x%X\n\r",LR);
192 break;
193 case 6:
194 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"IRQ Exception at 0x%X\n\r",LR);
195 break;
196 case 7:
197 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"FIQ Exception at 0x%X\n\r",LR);
198 break;
199 default:
200 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Unknown Exception at 0x%X\n\r",LR);
201 break;
202 }
203 SerialPortWrite ((UINT8 *) Buffer, CharCount);
204 while(1);
205 }