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