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