]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
db4a69f568eab4e4accf57423787290ad0ae5921
[mirror_edk2.git] / MdeModulePkg / Core / Pei / PeiMain / PeiMain.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 PeiMain.c
15
16 Abstract:
17
18 Pei Core Main Entry Point
19
20 Revision History
21
22 --*/
23
24 //
25 // Include common header file for this module.
26 //
27 #include "CommonHeader.h"
28
29 #include <PeiMain.h>
30
31 //
32 //CAR is filled with this initial value during SEC phase
33 //
34 #define INIT_CAR_VALUE 0x5AA55AA5
35
36 static EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = {
37 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
38 &gEfiPeiMemoryDiscoveredPpiGuid,
39 NULL
40 };
41
42 //
43 // Pei Core Module Variables
44 //
45 //
46 static EFI_PEI_SERVICES mPS = {
47 {
48 PEI_SERVICES_SIGNATURE,
49 PEI_SERVICES_REVISION,
50 sizeof (EFI_PEI_SERVICES),
51 0,
52 0
53 },
54 PeiInstallPpi,
55 PeiReInstallPpi,
56 PeiLocatePpi,
57 PeiNotifyPpi,
58
59 PeiGetBootMode,
60 PeiSetBootMode,
61
62 PeiGetHobList,
63 PeiCreateHob,
64
65 PeiFvFindNextVolume,
66 PeiFfsFindNextFile,
67 PeiFfsFindSectionData,
68
69 PeiInstallPeiMemory,
70 PeiAllocatePages,
71 PeiAllocatePool,
72 (EFI_PEI_COPY_MEM)CopyMem,
73 (EFI_PEI_SET_MEM)SetMem,
74
75 PeiReportStatusCode,
76
77 PeiResetSystem
78 };
79
80 EFI_STATUS
81 EFIAPI
82 PeiCore (
83 IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
84 IN VOID *Data
85 )
86 /*++
87
88 Routine Description:
89
90 The entry routine to Pei Core, invoked by PeiMain during transition
91 from SEC to PEI. After switching stack in the PEI core, it will restart
92 with the old core data.
93
94 Arguments:
95
96 PeiStartupDescriptor - Information and services provided by SEC phase.
97 OldCoreData - Pointer to old core data that is used to initialize the
98 core's data areas.
99
100 Returns:
101
102 This function never returns
103 EFI_NOT_FOUND - Never reach
104
105 --*/
106 {
107 PEI_CORE_INSTANCE PrivateData;
108 EFI_STATUS Status;
109 PEI_CORE_TEMP_POINTERS TempPtr;
110 PEI_CORE_DISPATCH_DATA *DispatchData;
111 UINT64 mTick;
112 PEI_CORE_INSTANCE *OldCoreData;
113
114 mTick = 0;
115 OldCoreData = (PEI_CORE_INSTANCE *) Data;
116
117 if (PerformanceMeasurementEnabled()) {
118 if (OldCoreData == NULL) {
119 mTick = GetPerformanceCounter ();
120 }
121 }
122
123 //
124 // For IPF in CAR mode the real memory access is uncached,in InstallPeiMemory()
125 // the 63-bit of address is set to 1.
126 //
127 SWITCH_TO_CACHE_MODE (OldCoreData);
128
129 if (OldCoreData != NULL) {
130 CopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));
131 } else {
132 ZeroMem (&PrivateData, sizeof (PEI_CORE_INSTANCE));
133 }
134
135 PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;
136 PrivateData.PS = &mPS;
137
138 //
139 // Initialize libraries that the PeiCore is linked against
140 // BUGBUG: The FfsHeader is passed in as NULL. Do we look it up or remove it from the lib init?
141 //
142 ProcessLibraryConstructorList (NULL, &PrivateData.PS);
143
144 InitializeMemoryServices (&PrivateData.PS, PeiStartupDescriptor, OldCoreData);
145
146 InitializePpiServices (&PrivateData.PS, OldCoreData);
147
148 InitializeSecurityServices (&PrivateData.PS, OldCoreData);
149
150 InitializeDispatcherData (&PrivateData.PS, OldCoreData, PeiStartupDescriptor);
151
152 if (OldCoreData != NULL) {
153
154 PERF_END (NULL,"PreMem", NULL, 0);
155 PERF_START (NULL,"PostMem", NULL, 0);
156
157 //
158 // The following code dumps out interesting cache as RAM usage information
159 // so we can keep tabs on how the cache as RAM is being utilized. The
160 // DEBUG_CODE_BEGIN macro is used to prevent this code from being compiled
161 // on a debug build.
162 //
163 DEBUG_CODE_BEGIN ();
164 UINTN *StackPointer;
165 UINTN StackValue;
166
167 StackValue = INIT_CAR_VALUE;
168 for (StackPointer = (UINTN *) OldCoreData->MaxTopOfCarHeap;
169 ((UINTN) StackPointer < ((UINTN) OldCoreData->BottomOfCarHeap + OldCoreData->SizeOfCacheAsRam))
170 && StackValue == INIT_CAR_VALUE;
171 StackPointer++) {
172 StackValue = *StackPointer;
173 }
174
175 DEBUG ((EFI_D_INFO, "Total Cache as RAM: %d bytes.\n", OldCoreData->SizeOfCacheAsRam));
176 DEBUG ((EFI_D_INFO, " CAR stack ever used: %d bytes.\n",
177 ((UINTN) OldCoreData->TopOfCarHeap - (UINTN) StackPointer)
178 ));
179 DEBUG ((EFI_D_INFO, " CAR heap used: %d bytes.\n",
180 ((UINTN) OldCoreData->HobList.HandoffInformationTable->EfiFreeMemoryBottom -
181 (UINTN) OldCoreData->HobList.Raw)
182 ));
183 DEBUG_CODE_END ();
184
185 //
186 // Alert any listeners that there is permanent memory available
187 //
188
189 PERF_START (NULL,"DisMem", NULL, 0);
190 Status = PeiServicesInstallPpi (&mMemoryDiscoveredPpi);
191 PERF_END (NULL,"DisMem", NULL, 0);
192
193 } else {
194
195 //
196 // Report Status Code EFI_SW_PC_INIT
197 //
198 REPORT_STATUS_CODE (
199 EFI_PROGRESS_CODE,
200 EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT
201 );
202
203 PERF_START (NULL,"PEI", NULL, mTick);
204 //
205 // If first pass, start performance measurement.
206 //
207 PERF_START (NULL,"PreMem", NULL, mTick);
208
209 //
210 // If SEC provided any PPI services to PEI, install them.
211 //
212 if (PeiStartupDescriptor->DispatchTable != NULL) {
213 Status = PeiServicesInstallPpi (PeiStartupDescriptor->DispatchTable);
214 ASSERT_EFI_ERROR (Status);
215 }
216 }
217
218 DispatchData = &PrivateData.DispatchData;
219
220 //
221 // Call PEIM dispatcher
222 //
223 PeiDispatcher (PeiStartupDescriptor, &PrivateData, DispatchData);
224
225 //
226 // Check if InstallPeiMemory service was called.
227 //
228 ASSERT(PrivateData.PeiMemoryInstalled == TRUE);
229
230 PERF_END (NULL, "PostMem", NULL, 0);
231
232 Status = PeiServicesLocatePpi (
233 &gEfiDxeIplPpiGuid,
234 0,
235 NULL,
236 (VOID **)&TempPtr.DxeIpl
237 );
238 ASSERT_EFI_ERROR (Status);
239
240 DEBUG ((EFI_D_INFO, "DXE IPL Entry\n"));
241 Status = TempPtr.DxeIpl->Entry (
242 TempPtr.DxeIpl,
243 &PrivateData.PS,
244 PrivateData.HobList
245 );
246
247 ASSERT_EFI_ERROR (Status);
248
249 return EFI_NOT_FOUND;
250 }
251