]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
c5fe851abeac7302fcdd32cd50d2ecef1c90712b
[mirror_edk2.git] / MdeModulePkg / Core / Pei / PeiMain / PeiMain.c
1 /** @file
2 Pei Core Main Entry Point
3
4 Copyright (c) 2006 - 2010, Intel Corporation
5 All rights reserved. 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 "PeiMain.h"
16
17 EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = {
18 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
19 &gEfiPeiMemoryDiscoveredPpiGuid,
20 NULL
21 };
22
23 ///
24 /// Pei service instance
25 ///
26 EFI_PEI_SERVICES gPs = {
27 {
28 PEI_SERVICES_SIGNATURE,
29 PEI_SERVICES_REVISION,
30 sizeof (EFI_PEI_SERVICES),
31 0,
32 0
33 },
34 PeiInstallPpi,
35 PeiReInstallPpi,
36 PeiLocatePpi,
37 PeiNotifyPpi,
38
39 PeiGetBootMode,
40 PeiSetBootMode,
41
42 PeiGetHobList,
43 PeiCreateHob,
44
45 PeiFfsFindNextVolume,
46 PeiFfsFindNextFile,
47 PeiFfsFindSectionData,
48
49 PeiInstallPeiMemory,
50 PeiAllocatePages,
51 PeiAllocatePool,
52 (EFI_PEI_COPY_MEM)CopyMem,
53 (EFI_PEI_SET_MEM)SetMem,
54
55 PeiReportStatusCode,
56 PeiResetSystem,
57
58 &gPeiDefaultCpuIoPpi,
59 &gPeiDefaultPciCfg2Ppi,
60
61 PeiFfsFindFileByName,
62 PeiFfsGetFileInfo,
63 PeiFfsGetVolumeInfo,
64 PeiRegisterForShadow
65 };
66
67 /**
68 This routine is invoked by main entry of PeiMain module during transition
69 from SEC to PEI. After switching stack in the PEI core, it will restart
70 with the old core data.
71
72 @param SecCoreData Points to a data structure containing information about the PEI core's operating
73 environment, such as the size and location of temporary RAM, the stack location and
74 the BFV location.
75 @param PpiList Points to a list of one or more PPI descriptors to be installed initially by the PEI core.
76 An empty PPI list consists of a single descriptor with the end-tag
77 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST. As part of its initialization
78 phase, the PEI Foundation will add these SEC-hosted PPIs to its PPI database such
79 that both the PEI Foundation and any modules can leverage the associated service
80 calls and/or code in these early PPIs
81 @param Data Pointer to old core data that is used to initialize the
82 core's data areas.
83 If NULL, it is first PeiCore entering.
84
85 **/
86 VOID
87 EFIAPI
88 PeiCore (
89 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
90 IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList,
91 IN VOID *Data
92 )
93 {
94 PEI_CORE_INSTANCE PrivateData;
95 EFI_STATUS Status;
96 PEI_CORE_TEMP_POINTERS TempPtr;
97 UINT64 Tick;
98 PEI_CORE_INSTANCE *OldCoreData;
99 EFI_PEI_CPU_IO_PPI *CpuIo;
100 EFI_PEI_PCI_CFG2_PPI *PciCfg;
101 PEICORE_FUNCTION_POINTER ShadowedPeiCore;
102
103 Tick = 0;
104 OldCoreData = (PEI_CORE_INSTANCE *) Data;
105
106 //
107 // Record the system tick for first entering PeiCore.
108 // This tick is duration of executing platform seccore module.
109 //
110 if (PerformanceMeasurementEnabled()) {
111 if (OldCoreData == NULL) {
112 Tick = GetPerformanceCounter ();
113 }
114 }
115
116 if (OldCoreData != NULL) {
117 ShadowedPeiCore = (PEICORE_FUNCTION_POINTER) (UINTN) OldCoreData->ShadowedPeiCore;
118
119 //
120 // PeiCore has been shadowed to memory for first entering, so
121 // just jump to PeiCore in memory here.
122 //
123 if (ShadowedPeiCore != NULL) {
124 OldCoreData->ShadowedPeiCore = NULL;
125 ShadowedPeiCore (
126 SecCoreData,
127 PpiList,
128 OldCoreData
129 );
130 }
131
132 CopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));
133
134 CpuIo = (VOID*)PrivateData.ServiceTableShadow.CpuIo;
135 PciCfg = (VOID*)PrivateData.ServiceTableShadow.PciCfg;
136
137 CopyMem (&PrivateData.ServiceTableShadow, &gPs, sizeof (gPs));
138
139 PrivateData.ServiceTableShadow.CpuIo = CpuIo;
140 PrivateData.ServiceTableShadow.PciCfg = PciCfg;
141 } else {
142 //
143 // If OldCoreData is NULL, means current is first Peicore's entering.
144 //
145
146 ZeroMem (&PrivateData, sizeof (PEI_CORE_INSTANCE));
147 PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;
148 CopyMem (&PrivateData.ServiceTableShadow, &gPs, sizeof (gPs));
149 }
150
151 PrivateData.Ps = &PrivateData.ServiceTableShadow;
152
153 //
154 // Initialize libraries that the PeiCore is linked against
155 //
156 ProcessLibraryConstructorList (NULL, (CONST EFI_PEI_SERVICES **)&PrivateData.Ps);
157
158 InitializeMemoryServices (&PrivateData, SecCoreData, OldCoreData);
159
160 InitializePpiServices (&PrivateData, OldCoreData);
161
162 //
163 // Save PeiServicePointer so that it can be retrieved anywhere.
164 //
165 SetPeiServicesTablePointer((CONST EFI_PEI_SERVICES **) &PrivateData.Ps);
166
167 if (OldCoreData != NULL) {
168
169 PERF_END (NULL,"PreMem", NULL, 0);
170 PERF_START (NULL,"PostMem", NULL, 0);
171
172 //
173 // Alert any listeners that there is permanent memory available
174 //
175
176 PERF_START (NULL,"DisMem", NULL, 0);
177 Status = PeiServicesInstallPpi (&mMemoryDiscoveredPpi);
178 PERF_END (NULL,"DisMem", NULL, 0);
179
180 } else {
181
182 //
183 // Report Status Code EFI_SW_PC_INIT
184 //
185 REPORT_STATUS_CODE (
186 EFI_PROGRESS_CODE,
187 (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT)
188 );
189
190 PERF_START (NULL, "SEC", NULL, 1);
191 PERF_END (NULL, "SEC", NULL, Tick);
192
193 PERF_START (NULL,"PEI", NULL, Tick);
194 //
195 // If first pass, start performance measurement.
196 //
197 PERF_START (NULL,"PreMem", NULL, Tick);
198
199 //
200 // If SEC provided any PPI services to PEI, install them.
201 //
202 if (PpiList != NULL) {
203 Status = PeiServicesInstallPpi (PpiList);
204 ASSERT_EFI_ERROR (Status);
205 }
206 }
207
208 InitializeSecurityServices (&PrivateData.Ps, OldCoreData);
209
210 InitializeDispatcherData (&PrivateData, OldCoreData, SecCoreData);
211
212 //
213 // Install Pei Load File PPI.
214 //
215 InitializeImageServices (&PrivateData, OldCoreData);
216
217 //
218 // Call PEIM dispatcher
219 //
220 PeiDispatcher (SecCoreData, &PrivateData);
221
222 //
223 // Check if InstallPeiMemory service was called.
224 //
225 ASSERT(PrivateData.PeiMemoryInstalled == TRUE);
226
227 //
228 // Till now, PEI phase will be finished, get performace count
229 // for computing duration of PEI phase
230 //
231 PERF_END (NULL, "PostMem", NULL, 0);
232
233 Status = PeiServicesLocatePpi (
234 &gEfiDxeIplPpiGuid,
235 0,
236 NULL,
237 (VOID **)&TempPtr.DxeIpl
238 );
239 ASSERT_EFI_ERROR (Status);
240
241 //
242 // Enter DxeIpl to load Dxe core.
243 //
244 DEBUG ((EFI_D_INFO, "DXE IPL Entry\n"));
245 Status = TempPtr.DxeIpl->Entry (
246 TempPtr.DxeIpl,
247 &PrivateData.Ps,
248 PrivateData.HobList
249 );
250 //
251 // Should never reach here.
252 //
253 ASSERT_EFI_ERROR (Status);
254 CpuDeadLoop();
255 }
256
257