]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/PrePeiCore/PrePeiCore.c
93d7e1c4c0b18708d1b4d8f231fc02c599615ac2
[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-2014, 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/ArmLib.h>
19
20 #include <Ppi/ArmGlobalVariable.h>
21
22 #include "PrePeiCore.h"
23
24 EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = { PrePeiCoreTemporaryRamSupport };
25 ARM_GLOBAL_VARIABLE_PPI mGlobalVariablePpi = { PrePeiCoreGetGlobalVariableMemory };
26
27 EFI_PEI_PPI_DESCRIPTOR gCommonPpiTable[] = {
28 {
29 EFI_PEI_PPI_DESCRIPTOR_PPI,
30 &gEfiTemporaryRamSupportPpiGuid,
31 &mTemporaryRamSupportPpi
32 },
33 {
34 EFI_PEI_PPI_DESCRIPTOR_PPI,
35 &gArmGlobalVariablePpiGuid,
36 &mGlobalVariablePpi
37 }
38 };
39
40 VOID
41 CreatePpiList (
42 OUT UINTN *PpiListSize,
43 OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
44 )
45 {
46 EFI_PEI_PPI_DESCRIPTOR *PlatformPpiList;
47 UINTN PlatformPpiListSize;
48 UINTN ListBase;
49 EFI_PEI_PPI_DESCRIPTOR *LastPpi;
50
51 // Get the Platform PPIs
52 PlatformPpiListSize = 0;
53 ArmPlatformGetPlatformPpiList (&PlatformPpiListSize, &PlatformPpiList);
54
55 // Copy the Common and Platform PPis in Temporrary Memory
56 ListBase = PcdGet32 (PcdCPUCoresStackBase);
57 CopyMem ((VOID*)ListBase, gCommonPpiTable, sizeof(gCommonPpiTable));
58 CopyMem ((VOID*)(ListBase + sizeof(gCommonPpiTable)), PlatformPpiList, PlatformPpiListSize);
59
60 // Set the Terminate flag on the last PPI entry
61 LastPpi = (EFI_PEI_PPI_DESCRIPTOR*)ListBase + ((sizeof(gCommonPpiTable) + PlatformPpiListSize) / sizeof(EFI_PEI_PPI_DESCRIPTOR)) - 1;
62 LastPpi->Flags |= EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
63
64 *PpiList = (EFI_PEI_PPI_DESCRIPTOR*)ListBase;
65 *PpiListSize = sizeof(gCommonPpiTable) + PlatformPpiListSize;
66 }
67
68 VOID
69 CEntryPoint (
70 IN UINTN MpId,
71 IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
72 )
73 {
74 // Data Cache enabled on Primary core when MMU is enabled.
75 ArmDisableDataCache ();
76 // Invalidate Data cache
77 ArmInvalidateDataCache ();
78 // Invalidate instruction cache
79 ArmInvalidateInstructionCache ();
80 // Enable Instruction Caches on all cores.
81 ArmEnableInstructionCache ();
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
88 // Write VBAR - The Exception Vector table must be aligned to its requirement
89 // Note: The AArch64 Vector table must be 2k-byte aligned - if this assertion fails ensure
90 // 'Align=4K' is defined into your FDF for this module.
91 ASSERT (((UINTN)PeiVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0);
92 ArmWriteVBar ((UINTN)PeiVectorTable);
93
94 //Note: The MMU will be enabled by MemoryPeim. Only the primary core will have the MMU on.
95
96 // If not primary Jump to Secondary Main
97 if (ArmPlatformIsPrimaryCore (MpId)) {
98 // Initialize the Debug Agent for Source Level Debugging
99 InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
100 SaveAndSetDebugTimerInterrupt (TRUE);
101
102 // Initialize the platform specific controllers
103 ArmPlatformInitialize (MpId);
104
105 // Goto primary Main.
106 PrimaryMain (PeiCoreEntryPoint);
107 } else {
108 SecondaryMain (MpId);
109 }
110
111 // PEI Core should always load and never return
112 ASSERT (FALSE);
113 }
114
115 EFI_STATUS
116 EFIAPI
117 PrePeiCoreTemporaryRamSupport (
118 IN CONST EFI_PEI_SERVICES **PeiServices,
119 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
120 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
121 IN UINTN CopySize
122 )
123 {
124 VOID *OldHeap;
125 VOID *NewHeap;
126 VOID *OldStack;
127 VOID *NewStack;
128
129 OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
130 NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
131
132 OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
133 NewStack = (VOID*)(UINTN)PermanentMemoryBase;
134
135 //
136 // Migrate the temporary memory stack to permanent memory stack.
137 //
138 CopyMem (NewStack, OldStack, CopySize >> 1);
139
140 //
141 // Migrate the temporary memory heap to permanent memory heap.
142 //
143 CopyMem (NewHeap, OldHeap, CopySize >> 1);
144
145 SecSwitchStack ((UINTN)NewStack - (UINTN)OldStack);
146
147 return EFI_SUCCESS;
148 }
149
150 EFI_STATUS
151 PrePeiCoreGetGlobalVariableMemory (
152 OUT EFI_PHYSICAL_ADDRESS *GlobalVariableBase
153 )
154 {
155 ASSERT (GlobalVariableBase != NULL);
156
157 *GlobalVariableBase = (UINTN)PcdGet32 (PcdCPUCoresStackBase) +
158 (UINTN)PcdGet32 (PcdCPUCorePrimaryStackSize) -
159 (UINTN)PcdGet32 (PcdPeiGlobalVariableSize);
160
161 return EFI_SUCCESS;
162 }
163