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