ArmPlatformPkg: Add ArmPlatformGetPlatformPpiList()
[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 #include <Chipset/ArmV7.h>
24
25 #include "PrePeiCore.h"
26
27 EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = { PrePeiCoreTemporaryRamSupport };
28 ARM_GLOBAL_VARIABLE_PPI mGlobalVariablePpi = { PrePeiCoreGetGlobalVariableMemory };
29
30 EFI_PEI_PPI_DESCRIPTOR gCommonPpiTable[] = {
31 {
32 EFI_PEI_PPI_DESCRIPTOR_PPI,
33 &gEfiTemporaryRamSupportPpiGuid,
34 &mTemporaryRamSupportPpi
35 },
36 {
37 EFI_PEI_PPI_DESCRIPTOR_PPI,
38 &gArmGlobalVariablePpiGuid,
39 &mGlobalVariablePpi
40 }
41 };
42
43 VOID
44 CreatePpiList (
45 OUT UINTN *PpiListSize,
46 OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
47 )
48 {
49 EFI_PEI_PPI_DESCRIPTOR *PlatformPpiList;
50 UINTN PlatformPpiListSize;
51 UINTN ListBase;
52 EFI_PEI_PPI_DESCRIPTOR *LastPpi;
53
54 // Get the Platform PPIs
55 PlatformPpiListSize = 0;
56 ArmPlatformGetPlatformPpiList (&PlatformPpiListSize, &PlatformPpiList);
57
58 // Copy the Common and Platform PPis in Temporrary Memory
59 ListBase = PcdGet32 (PcdCPUCoresStackBase);
60 CopyMem ((VOID*)ListBase, gCommonPpiTable, sizeof(gCommonPpiTable));
61 CopyMem ((VOID*)(ListBase + sizeof(gCommonPpiTable)), PlatformPpiList, PlatformPpiListSize);
62
63 // Set the Terminate flag on the last PPI entry
64 LastPpi = (EFI_PEI_PPI_DESCRIPTOR*)ListBase + ((sizeof(gCommonPpiTable) + PlatformPpiListSize) / sizeof(EFI_PEI_PPI_DESCRIPTOR)) - 1;
65 LastPpi->Flags |= EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
66
67 *PpiList = (EFI_PEI_PPI_DESCRIPTOR*)ListBase;
68 *PpiListSize = sizeof(gCommonPpiTable) + PlatformPpiListSize;
69 }
70
71 VOID
72 CEntryPoint (
73 IN UINTN MpId,
74 IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
75 )
76 {
77 //Clean Data cache
78 ArmCleanInvalidateDataCache();
79
80 //Invalidate instruction cache
81 ArmInvalidateInstructionCache();
82
83 // Enable Instruction & Data caches
84 ArmEnableDataCache ();
85 ArmEnableInstructionCache ();
86
87 //
88 // Note: Doesn't have to Enable CPU interface in non-secure world,
89 // as Non-secure interface is already enabled in Secure world.
90 //
91
92 // Write VBAR - The Vector table must be 32-byte aligned
93 ASSERT(((UINT32)PeiVectorTable & ((1 << 5)-1)) == 0);
94 ArmWriteVBar((UINT32)PeiVectorTable);
95
96 //Note: The MMU will be enabled by MemoryPeim. Only the primary core will have the MMU on.
97
98 // If not primary Jump to Secondary Main
99 if (IS_PRIMARY_CORE(MpId)) {
100 // Initialize the Debug Agent for Source Level Debugging
101 InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
102 SaveAndSetDebugTimerInterrupt (TRUE);
103
104 // Goto primary Main.
105 PrimaryMain (PeiCoreEntryPoint);
106 } else {
107 SecondaryMain (MpId);
108 }
109
110 // PEI Core should always load and never return
111 ASSERT (FALSE);
112 }
113
114 EFI_STATUS
115 EFIAPI
116 PrePeiCoreTemporaryRamSupport (
117 IN CONST EFI_PEI_SERVICES **PeiServices,
118 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
119 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
120 IN UINTN CopySize
121 )
122 {
123 VOID *OldHeap;
124 VOID *NewHeap;
125 VOID *OldStack;
126 VOID *NewStack;
127
128 OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
129 NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
130
131 OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
132 NewStack = (VOID*)(UINTN)PermanentMemoryBase;
133
134 //
135 // Migrate the temporary memory stack to permanent memory stack.
136 //
137 CopyMem (NewStack, OldStack, CopySize >> 1);
138
139 //
140 // Migrate the temporary memory heap to permanent memory heap.
141 //
142 CopyMem (NewHeap, OldHeap, CopySize >> 1);
143
144 SecSwitchStack ((UINTN)NewStack - (UINTN)OldStack);
145
146 return EFI_SUCCESS;
147 }
148
149 EFI_STATUS
150 PrePeiCoreGetGlobalVariableMemory (
151 OUT EFI_PHYSICAL_ADDRESS *GlobalVariableBase
152 )
153 {
154 ASSERT (GlobalVariableBase != NULL);
155
156 *GlobalVariableBase = (UINTN)PcdGet32 (PcdCPUCoresStackBase) +
157 (UINTN)PcdGet32 (PcdCPUCorePrimaryStackSize) -
158 (UINTN)PcdGet32 (PcdPeiGlobalVariableSize);
159
160 return EFI_SUCCESS;
161 }
162
163 VOID
164 PeiCommonExceptionEntry (
165 IN UINT32 Entry,
166 IN UINT32 LR
167 )
168 {
169 CHAR8 Buffer[100];
170 UINTN CharCount;
171
172 switch (Entry) {
173 case 0:
174 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Reset Exception at 0x%X\n\r",LR);
175 break;
176 case 1:
177 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Undefined Exception at 0x%X\n\r",LR);
178 break;
179 case 2:
180 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"SWI Exception at 0x%X\n\r",LR);
181 break;
182 case 3:
183 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"PrefetchAbort Exception at 0x%X\n\r",LR);
184 break;
185 case 4:
186 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"DataAbort Exception at 0x%X\n\r",LR);
187 break;
188 case 5:
189 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Reserved Exception at 0x%X\n\r",LR);
190 break;
191 case 6:
192 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"IRQ Exception at 0x%X\n\r",LR);
193 break;
194 case 7:
195 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"FIQ Exception at 0x%X\n\r",LR);
196 break;
197 default:
198 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Unknown Exception at 0x%X\n\r",LR);
199 break;
200 }
201 SerialPortWrite ((UINT8 *) Buffer, CharCount);
202 while(1);
203 }