]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/PrePi/PrePi.c
b563b5ee3a8f6009cecbb3fd907366a7e7d6f3ed
[mirror_edk2.git] / ArmPlatformPkg / PrePi / PrePi.c
1 /** @file
2 *
3 * Copyright (c) 2011-2014, ARM Limited. All rights reserved.
4 *
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
9 *
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 *
13 **/
14
15 #include <PiPei.h>
16
17 #include <Library/DebugAgentLib.h>
18 #include <Library/PrePiLib.h>
19 #include <Library/PrintLib.h>
20 #include <Library/PeCoffGetEntryPointLib.h>
21 #include <Library/PrePiHobListPointerLib.h>
22 #include <Library/TimerLib.h>
23 #include <Library/PerformanceLib.h>
24
25 #include <Ppi/GuidedSectionExtraction.h>
26 #include <Ppi/ArmMpCoreInfo.h>
27 #include <Guid/LzmaDecompress.h>
28
29 #include "PrePi.h"
30 #include "LzmaDecompress.h"
31
32 #define IS_XIP() (((UINT32)FixedPcdGet32 (PcdFdBaseAddress) > mSystemMemoryEnd) || \
33 ((FixedPcdGet32 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) < FixedPcdGet64 (PcdSystemMemoryBase)))
34
35 EFI_STATUS
36 EFIAPI
37 ExtractGuidedSectionLibConstructor (
38 VOID
39 );
40
41 EFI_STATUS
42 EFIAPI
43 LzmaDecompressLibConstructor (
44 VOID
45 );
46
47 EFI_STATUS
48 GetPlatformPpi (
49 IN EFI_GUID *PpiGuid,
50 OUT VOID **Ppi
51 )
52 {
53 UINTN PpiListSize;
54 UINTN PpiListCount;
55 EFI_PEI_PPI_DESCRIPTOR *PpiList;
56 UINTN Index;
57
58 PpiListSize = 0;
59 ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList);
60 PpiListCount = PpiListSize / sizeof(EFI_PEI_PPI_DESCRIPTOR);
61 for (Index = 0; Index < PpiListCount; Index++, PpiList++) {
62 if (CompareGuid (PpiList->Guid, PpiGuid) == TRUE) {
63 *Ppi = PpiList->Ppi;
64 return EFI_SUCCESS;
65 }
66 }
67
68 return EFI_NOT_FOUND;
69 }
70
71 VOID
72 PrePiMain (
73 IN UINTN UefiMemoryBase,
74 IN UINTN StacksBase,
75 IN UINT64 StartTimeStamp
76 )
77 {
78 EFI_HOB_HANDOFF_INFO_TABLE* HobList;
79 ARM_MP_CORE_INFO_PPI* ArmMpCoreInfoPpi;
80 UINTN ArmCoreCount;
81 ARM_CORE_INFO* ArmCoreInfoTable;
82 EFI_STATUS Status;
83 CHAR8 Buffer[100];
84 UINTN CharCount;
85 UINTN StacksSize;
86
87 // If ensure the FD is either part of the System Memory or totally outside of the System Memory (XIP)
88 ASSERT (IS_XIP() ||
89 ((FixedPcdGet32 (PcdFdBaseAddress) >= FixedPcdGet64 (PcdSystemMemoryBase)) &&
90 ((UINT32)(FixedPcdGet32 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= (UINT32)mSystemMemoryEnd)));
91
92 // Initialize the architecture specific bits
93 ArchInitialize ();
94
95 // Initialize the Serial Port
96 SerialPortInitialize ();
97 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"UEFI firmware (version %s built at %a on %a)\n\r",
98 (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__, __DATE__);
99 SerialPortWrite ((UINT8 *) Buffer, CharCount);
100
101 // Initialize the Debug Agent for Source Level Debugging
102 InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
103 SaveAndSetDebugTimerInterrupt (TRUE);
104
105 // Declare the PI/UEFI memory region
106 HobList = HobConstructor (
107 (VOID*)UefiMemoryBase,
108 FixedPcdGet32 (PcdSystemMemoryUefiRegionSize),
109 (VOID*)UefiMemoryBase,
110 (VOID*)StacksBase // The top of the UEFI Memory is reserved for the stacks
111 );
112 PrePeiSetHobList (HobList);
113
114 // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
115 Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
116 ASSERT_EFI_ERROR (Status);
117
118 // Create the Stacks HOB (reserve the memory for all stacks)
119 if (ArmIsMpCore ()) {
120 StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize) +
121 ((FixedPcdGet32 (PcdCoreCount) - 1) * FixedPcdGet32 (PcdCPUCoreSecondaryStackSize));
122 } else {
123 StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
124 }
125 BuildStackHob (StacksBase, StacksSize);
126
127 //TODO: Call CpuPei as a library
128 BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));
129
130 if (ArmIsMpCore ()) {
131 // Only MP Core platform need to produce gArmMpCoreInfoPpiGuid
132 Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID**)&ArmMpCoreInfoPpi);
133
134 // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid)
135 ASSERT_EFI_ERROR (Status);
136
137 // Build the MP Core Info Table
138 ArmCoreCount = 0;
139 Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
140 if (!EFI_ERROR(Status) && (ArmCoreCount > 0)) {
141 // Build MPCore Info HOB
142 BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount);
143 }
144 }
145
146 // Set the Boot Mode
147 SetBootMode (ArmPlatformGetBootMode ());
148
149 // Initialize Platform HOBs (CpuHob and FvHob)
150 Status = PlatformPeim ();
151 ASSERT_EFI_ERROR (Status);
152
153 // Now, the HOB List has been initialized, we can register performance information
154 PERF_START (NULL, "PEI", NULL, StartTimeStamp);
155
156 // SEC phase needs to run library constructors by hand.
157 ExtractGuidedSectionLibConstructor ();
158 LzmaDecompressLibConstructor ();
159
160 // Build HOBs to pass up our version of stuff the DXE Core needs to save space
161 BuildPeCoffLoaderHob ();
162 BuildExtractSectionHob (
163 &gLzmaCustomDecompressGuid,
164 LzmaGuidedSectionGetInfo,
165 LzmaGuidedSectionExtraction
166 );
167
168 // Assume the FV that contains the SEC (our code) also contains a compressed FV.
169 Status = DecompressFirstFv ();
170 ASSERT_EFI_ERROR (Status);
171
172 // Load the DXE Core and transfer control to it
173 Status = LoadDxeCoreFromFv (NULL, 0);
174 ASSERT_EFI_ERROR (Status);
175 }
176
177 VOID
178 CEntryPoint (
179 IN UINTN MpId,
180 IN UINTN UefiMemoryBase,
181 IN UINTN StacksBase
182 )
183 {
184 UINT64 StartTimeStamp;
185
186 ASSERT(!ArmIsMpCore() || (PcdGet32 (PcdCoreCount) > 1));
187
188 // Initialize the platform specific controllers
189 ArmPlatformInitialize (MpId);
190
191 if (ArmPlatformIsPrimaryCore (MpId) && PerformanceMeasurementEnabled ()) {
192 // Initialize the Timer Library to setup the Timer HW controller
193 TimerConstructor ();
194 // We cannot call yet the PerformanceLib because the HOB List has not been initialized
195 StartTimeStamp = GetPerformanceCounter ();
196 } else {
197 StartTimeStamp = 0;
198 }
199
200 // Data Cache enabled on Primary core when MMU is enabled.
201 ArmDisableDataCache ();
202 // Invalidate Data cache
203 ArmInvalidateDataCache ();
204 // Invalidate instruction cache
205 ArmInvalidateInstructionCache ();
206 // Enable Instruction Caches on all cores.
207 ArmEnableInstructionCache ();
208
209 // Define the Global Variable region when we are not running in XIP
210 if (!IS_XIP()) {
211 if (ArmPlatformIsPrimaryCore (MpId)) {
212 if (ArmIsMpCore()) {
213 // Signal the Global Variable Region is defined (event: ARM_CPU_EVENT_DEFAULT)
214 ArmCallSEV ();
215 }
216 } else {
217 // Wait the Primay core has defined the address of the Global Variable region (event: ARM_CPU_EVENT_DEFAULT)
218 ArmCallWFE ();
219 }
220 }
221
222 // If not primary Jump to Secondary Main
223 if (ArmPlatformIsPrimaryCore (MpId)) {
224 // Goto primary Main.
225 PrimaryMain (UefiMemoryBase, StacksBase, StartTimeStamp);
226 } else {
227 SecondaryMain (MpId);
228 }
229
230 // DXE Core should always load and never return
231 ASSERT (FALSE);
232 }
233