]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Pei/Ppi/Ppi.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Core / Pei / Ppi / Ppi.c
CommitLineData
615c6dd0 1/** @file\r
b1f6a7c6 2 EFI PEI Core PPI services\r
d1102dba 3\r
d39d1260 4Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
192f6d4c 6\r
b1f6a7c6 7**/\r
192f6d4c 8\r
0d516397 9#include "PeiMain.h"\r
192f6d4c 10\r
b1f6a7c6 11/**\r
12\r
e9f4a2a9 13 Migrate Pointer from the temporary memory to PEI installed memory.\r
0f9ebb32 14\r
e9f4a2a9 15 @param Pointer Pointer to the Pointer needs to be converted.\r
0f9ebb32
LG
16 @param TempBottom Base of old temporary memory\r
17 @param TempTop Top of old temporary memory\r
18 @param Offset Offset of new memory to old temporary memory.\r
d1102dba 19 @param OffsetPositive Positive flag of Offset value.\r
0f9ebb32
LG
20\r
21**/\r
22VOID\r
e9f4a2a9 23ConvertPointer (\r
1436aea4
MK
24 IN OUT VOID **Pointer,\r
25 IN UINTN TempBottom,\r
26 IN UINTN TempTop,\r
27 IN UINTN Offset,\r
28 IN BOOLEAN OffsetPositive\r
0f9ebb32
LG
29 )\r
30{\r
1436aea4
MK
31 if (((UINTN)*Pointer < TempTop) &&\r
32 ((UINTN)*Pointer >= TempBottom))\r
33 {\r
0f9ebb32 34 if (OffsetPositive) {\r
1436aea4 35 *Pointer = (VOID *)((UINTN)*Pointer + Offset);\r
0f9ebb32 36 } else {\r
1436aea4 37 *Pointer = (VOID *)((UINTN)*Pointer - Offset);\r
0f9ebb32 38 }\r
e9f4a2a9
SZ
39 }\r
40}\r
0f9ebb32 41\r
e9f4a2a9 42/**\r
0f9ebb32 43\r
e9f4a2a9
SZ
44 Migrate Pointer in ranges of the temporary memory to PEI installed memory.\r
45\r
46 @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size\r
47 and location of temporary RAM, the stack location and the BFV location.\r
48 @param PrivateData Pointer to PeiCore's private data structure.\r
49 @param Pointer Pointer to the Pointer needs to be converted.\r
50\r
51**/\r
52VOID\r
53ConvertPointerInRanges (\r
54 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,\r
55 IN PEI_CORE_INSTANCE *PrivateData,\r
56 IN OUT VOID **Pointer\r
57 )\r
58{\r
1436aea4 59 UINT8 IndexHole;\r
0f9ebb32 60\r
e9f4a2a9 61 if (PrivateData->MemoryPages.Size != 0) {\r
0f9ebb32 62 //\r
e9f4a2a9
SZ
63 // Convert PPI pointer in old memory pages\r
64 // It needs to be done before Convert PPI pointer in old Heap\r
0f9ebb32 65 //\r
e9f4a2a9
SZ
66 ConvertPointer (\r
67 Pointer,\r
68 (UINTN)PrivateData->MemoryPages.Base,\r
69 (UINTN)PrivateData->MemoryPages.Base + PrivateData->MemoryPages.Size,\r
70 PrivateData->MemoryPages.Offset,\r
71 PrivateData->MemoryPages.OffsetPositive\r
72 );\r
73 }\r
74\r
75 //\r
76 // Convert PPI pointer in old Heap\r
77 //\r
78 ConvertPointer (\r
79 Pointer,\r
80 (UINTN)SecCoreData->PeiTemporaryRamBase,\r
81 (UINTN)SecCoreData->PeiTemporaryRamBase + SecCoreData->PeiTemporaryRamSize,\r
82 PrivateData->HeapOffset,\r
83 PrivateData->HeapOffsetPositive\r
84 );\r
85\r
86 //\r
87 // Convert PPI pointer in old Stack\r
88 //\r
89 ConvertPointer (\r
90 Pointer,\r
91 (UINTN)SecCoreData->StackBase,\r
92 (UINTN)SecCoreData->StackBase + SecCoreData->StackSize,\r
93 PrivateData->StackOffset,\r
94 PrivateData->StackOffsetPositive\r
95 );\r
96\r
97 //\r
98 // Convert PPI pointer in old TempRam Hole\r
99 //\r
1436aea4 100 for (IndexHole = 0; IndexHole < HOLE_MAX_NUMBER; IndexHole++) {\r
e9f4a2a9
SZ
101 if (PrivateData->HoleData[IndexHole].Size == 0) {\r
102 continue;\r
0f9ebb32 103 }\r
e9f4a2a9
SZ
104\r
105 ConvertPointer (\r
106 Pointer,\r
107 (UINTN)PrivateData->HoleData[IndexHole].Base,\r
108 (UINTN)PrivateData->HoleData[IndexHole].Base + PrivateData->HoleData[IndexHole].Size,\r
109 PrivateData->HoleData[IndexHole].Offset,\r
110 PrivateData->HoleData[IndexHole].OffsetPositive\r
111 );\r
0f9ebb32
LG
112 }\r
113}\r
114\r
e9f4a2a9
SZ
115/**\r
116\r
117 Migrate Single PPI Pointer from the temporary memory to PEI installed memory.\r
118\r
4a76d9b9 119 @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size\r
e9f4a2a9
SZ
120 and location of temporary RAM, the stack location and the BFV location.\r
121 @param PrivateData Pointer to PeiCore's private data structure.\r
122 @param PpiPointer Pointer to Ppi\r
123\r
124**/\r
125VOID\r
126ConvertSinglePpiPointer (\r
127 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,\r
128 IN PEI_CORE_INSTANCE *PrivateData,\r
129 IN PEI_PPI_LIST_POINTERS *PpiPointer\r
130 )\r
131{\r
132 //\r
133 // 1. Convert the pointer to the PPI descriptor from the old TempRam\r
134 // to the relocated physical memory.\r
135 // It (for the pointer to the PPI descriptor) needs to be done before 2 (for\r
136 // the pointer to the GUID) and 3 (for the pointer to the PPI interface structure).\r
137 //\r
138 ConvertPointerInRanges (SecCoreData, PrivateData, &PpiPointer->Raw);\r
139 //\r
140 // 2. Convert the pointer to the GUID in the PPI or NOTIFY descriptor\r
141 // from the old TempRam to the relocated physical memory.\r
142 //\r
1436aea4 143 ConvertPointerInRanges (SecCoreData, PrivateData, (VOID **)&PpiPointer->Ppi->Guid);\r
e9f4a2a9
SZ
144 //\r
145 // 3. Convert the pointer to the PPI interface structure in the PPI descriptor\r
146 // from the old TempRam to the relocated physical memory.\r
147 //\r
1436aea4 148 ConvertPointerInRanges (SecCoreData, PrivateData, (VOID **)&PpiPointer->Ppi->Ppi);\r
e9f4a2a9
SZ
149}\r
150\r
0f9ebb32
LG
151/**\r
152\r
b2374cec 153 Migrate PPI Pointers from the temporary memory to PEI installed memory.\r
b1f6a7c6 154\r
4a76d9b9 155 @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size\r
424b7c9f 156 and location of temporary RAM, the stack location and the BFV location.\r
157 @param PrivateData Pointer to PeiCore's private data structure.\r
b1f6a7c6 158\r
159**/\r
192f6d4c 160VOID\r
161ConvertPpiPointers (\r
424b7c9f 162 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,\r
163 IN PEI_CORE_INSTANCE *PrivateData\r
192f6d4c 164 )\r
192f6d4c 165{\r
1436aea4 166 UINT8 Index;\r
192f6d4c 167\r
f2bc359c
SZ
168 //\r
169 // Convert normal PPIs.\r
170 //\r
171 for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {\r
172 ConvertSinglePpiPointer (\r
173 SecCoreData,\r
174 PrivateData,\r
175 &PrivateData->PpiData.PpiList.PpiPtrs[Index]\r
176 );\r
177 }\r
178\r
179 //\r
180 // Convert Callback Notification PPIs.\r
181 //\r
182 for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount; Index++) {\r
183 ConvertSinglePpiPointer (\r
184 SecCoreData,\r
185 PrivateData,\r
186 &PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index]\r
187 );\r
188 }\r
189\r
190 //\r
191 // Convert Dispatch Notification PPIs.\r
192 //\r
193 for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount; Index++) {\r
194 ConvertSinglePpiPointer (\r
195 SecCoreData,\r
196 PrivateData,\r
197 &PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index]\r
198 );\r
192f6d4c 199 }\r
200}\r
201\r
9bedaec0
MK
202/**\r
203\r
204 Migrate Notify Pointers inside an FV from temporary memory to permanent memory.\r
205\r
206 @param PrivateData Pointer to PeiCore's private data structure.\r
207 @param OrgFvHandle Address of FV Handle in temporary memory.\r
208 @param FvHandle Address of FV Handle in permanent memory.\r
209 @param FvSize Size of the FV.\r
210\r
211**/\r
212VOID\r
213ConvertPpiPointersFv (\r
1436aea4
MK
214 IN PEI_CORE_INSTANCE *PrivateData,\r
215 IN UINTN OrgFvHandle,\r
216 IN UINTN FvHandle,\r
217 IN UINTN FvSize\r
9bedaec0
MK
218 )\r
219{\r
220 UINT8 Index;\r
221 UINTN Offset;\r
222 BOOLEAN OffsetPositive;\r
223 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *FvInfoPpi;\r
224 UINT8 GuidIndex;\r
225 EFI_GUID *Guid;\r
226 EFI_GUID *GuidCheckList[2];\r
227\r
228 GuidCheckList[0] = &gEfiPeiFirmwareVolumeInfoPpiGuid;\r
229 GuidCheckList[1] = &gEfiPeiFirmwareVolumeInfo2PpiGuid;\r
230\r
231 if (FvHandle > OrgFvHandle) {\r
232 OffsetPositive = TRUE;\r
1436aea4 233 Offset = FvHandle - OrgFvHandle;\r
9bedaec0
MK
234 } else {\r
235 OffsetPositive = FALSE;\r
1436aea4 236 Offset = OrgFvHandle - FvHandle;\r
9bedaec0
MK
237 }\r
238\r
239 DEBUG ((DEBUG_VERBOSE, "Converting PPI pointers in FV.\n"));\r
240 DEBUG ((\r
241 DEBUG_VERBOSE,\r
242 " OrgFvHandle at 0x%08x. FvHandle at 0x%08x. FvSize = 0x%x\n",\r
1436aea4
MK
243 (UINTN)OrgFvHandle,\r
244 (UINTN)FvHandle,\r
9bedaec0
MK
245 FvSize\r
246 ));\r
247 DEBUG ((\r
248 DEBUG_VERBOSE,\r
249 " OrgFvHandle range: 0x%08x - 0x%08x\n",\r
250 OrgFvHandle,\r
251 OrgFvHandle + FvSize\r
252 ));\r
253\r
254 for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount; Index++) {\r
1436aea4
MK
255 ConvertPointer (\r
256 (VOID **)&PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw,\r
257 OrgFvHandle,\r
258 OrgFvHandle + FvSize,\r
259 Offset,\r
260 OffsetPositive\r
261 );\r
262 ConvertPointer (\r
263 (VOID **)&PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Guid,\r
264 OrgFvHandle,\r
265 OrgFvHandle + FvSize,\r
266 Offset,\r
267 OffsetPositive\r
268 );\r
269 ConvertPointer (\r
270 (VOID **)&PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Notify,\r
271 OrgFvHandle,\r
272 OrgFvHandle + FvSize,\r
273 Offset,\r
274 OffsetPositive\r
275 );\r
9bedaec0
MK
276 }\r
277\r
278 for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount; Index++) {\r
279 ConvertPointer (\r
1436aea4 280 (VOID **)&PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw,\r
9bedaec0
MK
281 OrgFvHandle,\r
282 OrgFvHandle + FvSize,\r
283 Offset,\r
284 OffsetPositive\r
285 );\r
286 ConvertPointer (\r
1436aea4 287 (VOID **)&PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Guid,\r
9bedaec0
MK
288 OrgFvHandle,\r
289 OrgFvHandle + FvSize,\r
290 Offset,\r
291 OffsetPositive\r
292 );\r
293 ConvertPointer (\r
1436aea4 294 (VOID **)&PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Notify,\r
9bedaec0
MK
295 OrgFvHandle,\r
296 OrgFvHandle + FvSize,\r
297 Offset,\r
298 OffsetPositive\r
299 );\r
300 }\r
301\r
302 for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {\r
303 ConvertPointer (\r
1436aea4 304 (VOID **)&PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw,\r
9bedaec0
MK
305 OrgFvHandle,\r
306 OrgFvHandle + FvSize,\r
307 Offset,\r
308 OffsetPositive\r
309 );\r
310 ConvertPointer (\r
1436aea4 311 (VOID **)&PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid,\r
9bedaec0
MK
312 OrgFvHandle,\r
313 OrgFvHandle + FvSize,\r
314 Offset,\r
315 OffsetPositive\r
316 );\r
317 ConvertPointer (\r
1436aea4 318 (VOID **)&PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Ppi,\r
9bedaec0
MK
319 OrgFvHandle,\r
320 OrgFvHandle + FvSize,\r
321 Offset,\r
322 OffsetPositive\r
323 );\r
324\r
325 Guid = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid;\r
326 for (GuidIndex = 0; GuidIndex < ARRAY_SIZE (GuidCheckList); ++GuidIndex) {\r
327 //\r
328 // Don't use CompareGuid function here for performance reasons.\r
329 // Instead we compare the GUID as INT32 at a time and branch\r
330 // on the first failed comparison.\r
331 //\r
332 if ((((INT32 *)Guid)[0] == ((INT32 *)GuidCheckList[GuidIndex])[0]) &&\r
333 (((INT32 *)Guid)[1] == ((INT32 *)GuidCheckList[GuidIndex])[1]) &&\r
334 (((INT32 *)Guid)[2] == ((INT32 *)GuidCheckList[GuidIndex])[2]) &&\r
1436aea4
MK
335 (((INT32 *)Guid)[3] == ((INT32 *)GuidCheckList[GuidIndex])[3]))\r
336 {\r
9bedaec0
MK
337 FvInfoPpi = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Ppi;\r
338 DEBUG ((DEBUG_VERBOSE, " FvInfo: %p -> ", FvInfoPpi->FvInfo));\r
339 if ((UINTN)FvInfoPpi->FvInfo == OrgFvHandle) {\r
340 ConvertPointer (\r
341 (VOID **)&FvInfoPpi->FvInfo,\r
342 OrgFvHandle,\r
343 OrgFvHandle + FvSize,\r
344 Offset,\r
345 OffsetPositive\r
346 );\r
347 DEBUG ((DEBUG_VERBOSE, "%p", FvInfoPpi->FvInfo));\r
348 }\r
1436aea4 349\r
9bedaec0
MK
350 DEBUG ((DEBUG_VERBOSE, "\n"));\r
351 break;\r
352 }\r
353 }\r
354 }\r
355}\r
356\r
357/**\r
358\r
359 Dumps the PPI lists to debug output.\r
360\r
361 @param PrivateData Points to PeiCore's private instance data.\r
362\r
363**/\r
364VOID\r
365DumpPpiList (\r
1436aea4 366 IN PEI_CORE_INSTANCE *PrivateData\r
9bedaec0
MK
367 )\r
368{\r
369 DEBUG_CODE_BEGIN ();\r
1436aea4 370 UINTN Index;\r
9bedaec0
MK
371\r
372 if (PrivateData == NULL) {\r
373 return;\r
374 }\r
375\r
376 for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount; Index++) {\r
377 DEBUG ((\r
378 DEBUG_VERBOSE,\r
379 "CallbackNotify[%2d] {%g} at 0x%x (%a)\n",\r
380 Index,\r
381 PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Guid,\r
1436aea4 382 (UINTN)PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw,\r
9bedaec0 383 (\r
1436aea4
MK
384 !(\r
385 ((EFI_PHYSICAL_ADDRESS)(UINTN)PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw >= PrivateData->PhysicalMemoryBegin) &&\r
386 (((EFI_PHYSICAL_ADDRESS)((UINTN)PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw) + sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)\r
387 )\r
9bedaec0 388 ? "CAR" : "Post-Memory"\r
1436aea4 389 )\r
9bedaec0
MK
390 ));\r
391 }\r
1436aea4 392\r
9bedaec0 393 for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount; Index++) {\r
1436aea4
MK
394 DEBUG ((\r
395 DEBUG_VERBOSE,\r
396 "DispatchNotify[%2d] {%g} at 0x%x (%a)\n",\r
397 Index,\r
398 PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Guid,\r
399 (UINTN)PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw,\r
400 (\r
401 !(\r
402 ((EFI_PHYSICAL_ADDRESS)(UINTN)PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw >= PrivateData->PhysicalMemoryBegin) &&\r
403 (((EFI_PHYSICAL_ADDRESS)((UINTN)PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw) + sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)\r
404 )\r
9bedaec0
MK
405 ? "CAR" : "Post-Memory"\r
406 )\r
1436aea4 407 ));\r
9bedaec0 408 }\r
1436aea4 409\r
9bedaec0 410 for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {\r
1436aea4
MK
411 DEBUG ((\r
412 DEBUG_VERBOSE,\r
413 "PPI[%2d] {%g} at 0x%x (%a)\n",\r
414 Index,\r
415 PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid,\r
416 (UINTN)PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw,\r
417 (\r
418 !(\r
419 ((EFI_PHYSICAL_ADDRESS)(UINTN)PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw >= PrivateData->PhysicalMemoryBegin) &&\r
420 (((EFI_PHYSICAL_ADDRESS)((UINTN)PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw) + sizeof (EFI_PEI_PPI_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)\r
421 )\r
9bedaec0
MK
422 ? "CAR" : "Post-Memory"\r
423 )\r
1436aea4 424 ));\r
9bedaec0 425 }\r
1436aea4 426\r
9bedaec0
MK
427 DEBUG_CODE_END ();\r
428}\r
429\r
b1f6a7c6 430/**\r
192f6d4c 431\r
d1102dba 432 This function installs an interface in the PEI PPI database by GUID.\r
0f65cdaa 433 The purpose of the service is to publish an interface that other parties\r
434 can use to call additional PEIMs.\r
192f6d4c 435\r
0f65cdaa 436 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
437 @param PpiList Pointer to a list of PEI PPI Descriptors.\r
884200f9
SZ
438 @param Single TRUE if only single entry in the PpiList.\r
439 FALSE if the PpiList is ended with an entry which has the\r
440 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST flag set in its Flags field.\r
b1f6a7c6 441\r
0f65cdaa 442 @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed.\r
443 @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer\r
731bd38e 444 if any PPI in PpiList is not valid\r
0f65cdaa 445 @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI\r
b1f6a7c6 446\r
447**/\r
192f6d4c 448EFI_STATUS\r
884200f9 449InternalPeiInstallPpi (\r
0c2b5da8 450 IN CONST EFI_PEI_SERVICES **PeiServices,\r
884200f9
SZ
451 IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList,\r
452 IN BOOLEAN Single\r
192f6d4c 453 )\r
192f6d4c 454{\r
1436aea4
MK
455 PEI_CORE_INSTANCE *PrivateData;\r
456 PEI_PPI_LIST *PpiListPointer;\r
457 UINTN Index;\r
458 UINTN LastCount;\r
459 VOID *TempPtr;\r
192f6d4c 460\r
461 if (PpiList == NULL) {\r
462 return EFI_INVALID_PARAMETER;\r
463 }\r
464\r
1436aea4 465 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
192f6d4c 466\r
f2bc359c 467 PpiListPointer = &PrivateData->PpiData.PpiList;\r
1436aea4
MK
468 Index = PpiListPointer->CurrentCount;\r
469 LastCount = Index;\r
192f6d4c 470\r
471 //\r
472 // This is loop installs all PPI descriptors in the PpiList. It is terminated\r
473 // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last\r
474 // EFI_PEI_PPI_DESCRIPTOR in the list.\r
475 //\r
58dcdada 476\r
1436aea4 477 for ( ; ;) {\r
192f6d4c 478 //\r
58dcdada 479 // Check if it is a valid PPI.\r
192f6d4c 480 // If not, rollback list to exclude all in this list.\r
481 // Try to indicate which item failed.\r
482 //\r
483 if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {\r
f2bc359c 484 PpiListPointer->CurrentCount = LastCount;\r
1436aea4
MK
485 DEBUG ((DEBUG_ERROR, "ERROR -> InstallPpi: %g %p\n", PpiList->Guid, PpiList->Ppi));\r
486 return EFI_INVALID_PARAMETER;\r
192f6d4c 487 }\r
488\r
f2bc359c
SZ
489 if (Index >= PpiListPointer->MaxCount) {\r
490 //\r
491 // Run out of room, grow the buffer.\r
492 //\r
493 TempPtr = AllocateZeroPool (\r
494 sizeof (PEI_PPI_LIST_POINTERS) * (PpiListPointer->MaxCount + PPI_GROWTH_STEP)\r
495 );\r
496 ASSERT (TempPtr != NULL);\r
497 CopyMem (\r
498 TempPtr,\r
499 PpiListPointer->PpiPtrs,\r
500 sizeof (PEI_PPI_LIST_POINTERS) * PpiListPointer->MaxCount\r
501 );\r
1436aea4 502 PpiListPointer->PpiPtrs = TempPtr;\r
f2bc359c
SZ
503 PpiListPointer->MaxCount = PpiListPointer->MaxCount + PPI_GROWTH_STEP;\r
504 }\r
505\r
1436aea4
MK
506 DEBUG ((DEBUG_INFO, "Install PPI: %g\n", PpiList->Guid));\r
507 PpiListPointer->PpiPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *)PpiList;\r
f2bc359c
SZ
508 Index++;\r
509 PpiListPointer->CurrentCount++;\r
58dcdada 510\r
884200f9
SZ
511 if (Single) {\r
512 //\r
513 // Only single entry in the PpiList.\r
514 //\r
515 break;\r
516 } else if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==\r
1436aea4
MK
517 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)\r
518 {\r
884200f9
SZ
519 //\r
520 // Continue until the end of the PPI List.\r
521 //\r
192f6d4c 522 break;\r
523 }\r
1436aea4 524\r
f2bc359c
SZ
525 //\r
526 // Go to the next descriptor.\r
527 //\r
192f6d4c 528 PpiList++;\r
192f6d4c 529 }\r
530\r
531 //\r
f2bc359c 532 // Process any callback level notifies for newly installed PPIs.\r
192f6d4c 533 //\r
f2bc359c 534 ProcessNotify (\r
b0d803fe 535 PrivateData,\r
192f6d4c 536 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
f2bc359c
SZ
537 LastCount,\r
538 PpiListPointer->CurrentCount,\r
539 0,\r
540 PrivateData->PpiData.CallbackNotifyList.CurrentCount\r
192f6d4c 541 );\r
542\r
192f6d4c 543 return EFI_SUCCESS;\r
544}\r
545\r
884200f9
SZ
546/**\r
547\r
d1102dba 548 This function installs an interface in the PEI PPI database by GUID.\r
884200f9
SZ
549 The purpose of the service is to publish an interface that other parties\r
550 can use to call additional PEIMs.\r
551\r
552 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
553 @param PpiList Pointer to a list of PEI PPI Descriptors.\r
554\r
555 @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed.\r
556 @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer\r
557 if any PPI in PpiList is not valid\r
558 @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI\r
559\r
560**/\r
561EFI_STATUS\r
562EFIAPI\r
563PeiInstallPpi (\r
564 IN CONST EFI_PEI_SERVICES **PeiServices,\r
565 IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList\r
566 )\r
567{\r
568 return InternalPeiInstallPpi (PeiServices, PpiList, FALSE);\r
569}\r
570\r
b1f6a7c6 571/**\r
572\r
d1102dba
LG
573 This function reinstalls an interface in the PEI PPI database by GUID.\r
574 The purpose of the service is to publish an interface that other parties can\r
575 use to replace an interface of the same name in the protocol database with a\r
0f65cdaa 576 different interface.\r
b1f6a7c6 577\r
0f65cdaa 578 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
579 @param OldPpi Pointer to the old PEI PPI Descriptors.\r
580 @param NewPpi Pointer to the new PEI PPI Descriptors.\r
192f6d4c 581\r
0f65cdaa 582 @retval EFI_SUCCESS if the operation was successful\r
583 @retval EFI_INVALID_PARAMETER if OldPpi or NewPpi is NULL\r
584 @retval EFI_INVALID_PARAMETER if NewPpi is not valid\r
585 @retval EFI_NOT_FOUND if the PPI was not in the database\r
b1f6a7c6 586\r
587**/\r
192f6d4c 588EFI_STATUS\r
589EFIAPI\r
590PeiReInstallPpi (\r
0c2b5da8 591 IN CONST EFI_PEI_SERVICES **PeiServices,\r
592 IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi,\r
593 IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi\r
192f6d4c 594 )\r
192f6d4c 595{\r
1436aea4
MK
596 PEI_CORE_INSTANCE *PrivateData;\r
597 UINTN Index;\r
192f6d4c 598\r
599 if ((OldPpi == NULL) || (NewPpi == NULL)) {\r
600 return EFI_INVALID_PARAMETER;\r
601 }\r
602\r
603 if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {\r
1436aea4 604 return EFI_INVALID_PARAMETER;\r
192f6d4c 605 }\r
606\r
1436aea4 607 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
192f6d4c 608\r
609 //\r
610 // Find the old PPI instance in the database. If we can not find it,\r
611 // return the EFI_NOT_FOUND error.\r
612 //\r
f2bc359c
SZ
613 for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {\r
614 if (OldPpi == PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi) {\r
192f6d4c 615 break;\r
616 }\r
617 }\r
1436aea4 618\r
f2bc359c 619 if (Index == PrivateData->PpiData.PpiList.CurrentCount) {\r
192f6d4c 620 return EFI_NOT_FOUND;\r
621 }\r
622\r
623 //\r
f2bc359c 624 // Replace the old PPI with the new one.\r
58dcdada 625 //\r
1436aea4
MK
626 DEBUG ((DEBUG_INFO, "Reinstall PPI: %g\n", NewPpi->Guid));\r
627 PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *)NewPpi;\r
192f6d4c 628\r
629 //\r
f2bc359c 630 // Process any callback level notifies for the newly installed PPI.\r
192f6d4c 631 //\r
f2bc359c 632 ProcessNotify (\r
b0d803fe 633 PrivateData,\r
192f6d4c 634 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
635 Index,\r
636 Index+1,\r
f2bc359c
SZ
637 0,\r
638 PrivateData->PpiData.CallbackNotifyList.CurrentCount\r
192f6d4c 639 );\r
640\r
192f6d4c 641 return EFI_SUCCESS;\r
642}\r
643\r
b1f6a7c6 644/**\r
645\r
646 Locate a given named PPI.\r
647\r
192f6d4c 648\r
0f65cdaa 649 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
650 @param Guid Pointer to GUID of the PPI.\r
651 @param Instance Instance Number to discover.\r
652 @param PpiDescriptor Pointer to reference the found descriptor. If not NULL,\r
653 returns a pointer to the descriptor (includes flags, etc)\r
654 @param Ppi Pointer to reference the found PPI\r
b1f6a7c6 655\r
656 @retval EFI_SUCCESS if the PPI is in the database\r
657 @retval EFI_NOT_FOUND if the PPI is not in the database\r
658\r
659**/\r
192f6d4c 660EFI_STATUS\r
661EFIAPI\r
662PeiLocatePpi (\r
1436aea4
MK
663 IN CONST EFI_PEI_SERVICES **PeiServices,\r
664 IN CONST EFI_GUID *Guid,\r
665 IN UINTN Instance,\r
666 IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,\r
667 IN OUT VOID **Ppi\r
192f6d4c 668 )\r
192f6d4c 669{\r
1436aea4
MK
670 PEI_CORE_INSTANCE *PrivateData;\r
671 UINTN Index;\r
672 EFI_GUID *CheckGuid;\r
673 EFI_PEI_PPI_DESCRIPTOR *TempPtr;\r
58dcdada 674\r
1436aea4 675 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
192f6d4c 676\r
677 //\r
678 // Search the data base for the matching instance of the GUIDed PPI.\r
679 //\r
f2bc359c 680 for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {\r
1436aea4 681 TempPtr = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi;\r
192f6d4c 682 CheckGuid = TempPtr->Guid;\r
683\r
684 //\r
685 // Don't use CompareGuid function here for performance reasons.\r
686 // Instead we compare the GUID as INT32 at a time and branch\r
687 // on the first failed comparison.\r
688 //\r
689 if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) &&\r
690 (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) &&\r
691 (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) &&\r
1436aea4
MK
692 (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3]))\r
693 {\r
192f6d4c 694 if (Instance == 0) {\r
192f6d4c 695 if (PpiDescriptor != NULL) {\r
696 *PpiDescriptor = TempPtr;\r
697 }\r
698\r
699 if (Ppi != NULL) {\r
700 *Ppi = TempPtr->Ppi;\r
701 }\r
702\r
192f6d4c 703 return EFI_SUCCESS;\r
704 }\r
1436aea4 705\r
192f6d4c 706 Instance--;\r
707 }\r
708 }\r
709\r
710 return EFI_NOT_FOUND;\r
711}\r
712\r
b1f6a7c6 713/**\r
192f6d4c 714\r
d1102dba
LG
715 This function installs a notification service to be called back when a given\r
716 interface is installed or reinstalled. The purpose of the service is to publish\r
0f65cdaa 717 an interface that other parties can use to call additional PPIs that may materialize later.\r
b1f6a7c6 718\r
0f65cdaa 719 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
720 @param NotifyList Pointer to list of Descriptors to notify upon.\r
884200f9
SZ
721 @param Single TRUE if only single entry in the NotifyList.\r
722 FALSE if the NotifyList is ended with an entry which has the\r
723 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST flag set in its Flags field.\r
b1f6a7c6 724\r
725 @retval EFI_SUCCESS if successful\r
726 @retval EFI_OUT_OF_RESOURCES if no space in the database\r
884200f9 727 @retval EFI_INVALID_PARAMETER if not a good descriptor\r
b1f6a7c6 728\r
729**/\r
192f6d4c 730EFI_STATUS\r
884200f9 731InternalPeiNotifyPpi (\r
0c2b5da8 732 IN CONST EFI_PEI_SERVICES **PeiServices,\r
884200f9
SZ
733 IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList,\r
734 IN BOOLEAN Single\r
192f6d4c 735 )\r
192f6d4c 736{\r
f2bc359c
SZ
737 PEI_CORE_INSTANCE *PrivateData;\r
738 PEI_CALLBACK_NOTIFY_LIST *CallbackNotifyListPointer;\r
739 UINTN CallbackNotifyIndex;\r
740 UINTN LastCallbackNotifyCount;\r
741 PEI_DISPATCH_NOTIFY_LIST *DispatchNotifyListPointer;\r
742 UINTN DispatchNotifyIndex;\r
743 UINTN LastDispatchNotifyCount;\r
744 VOID *TempPtr;\r
192f6d4c 745\r
746 if (NotifyList == NULL) {\r
747 return EFI_INVALID_PARAMETER;\r
748 }\r
749\r
1436aea4 750 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
192f6d4c 751\r
f2bc359c 752 CallbackNotifyListPointer = &PrivateData->PpiData.CallbackNotifyList;\r
1436aea4
MK
753 CallbackNotifyIndex = CallbackNotifyListPointer->CurrentCount;\r
754 LastCallbackNotifyCount = CallbackNotifyIndex;\r
f2bc359c
SZ
755\r
756 DispatchNotifyListPointer = &PrivateData->PpiData.DispatchNotifyList;\r
1436aea4
MK
757 DispatchNotifyIndex = DispatchNotifyListPointer->CurrentCount;\r
758 LastDispatchNotifyCount = DispatchNotifyIndex;\r
192f6d4c 759\r
760 //\r
761 // This is loop installs all Notify descriptors in the NotifyList. It is\r
762 // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last\r
763 // EFI_PEI_NOTIFY_DESCRIPTOR in the list.\r
764 //\r
765\r
1436aea4 766 for ( ; ;) {\r
192f6d4c 767 //\r
768 // If some of the PPI data is invalid restore original Notify PPI database value\r
769 //\r
770 if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) {\r
1436aea4
MK
771 CallbackNotifyListPointer->CurrentCount = LastCallbackNotifyCount;\r
772 DispatchNotifyListPointer->CurrentCount = LastDispatchNotifyCount;\r
773 DEBUG ((DEBUG_ERROR, "ERROR -> NotifyPpi: %g %p\n", NotifyList->Guid, NotifyList->Notify));\r
774 return EFI_INVALID_PARAMETER;\r
192f6d4c 775 }\r
58dcdada 776\r
f2bc359c
SZ
777 if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) != 0) {\r
778 if (CallbackNotifyIndex >= CallbackNotifyListPointer->MaxCount) {\r
779 //\r
780 // Run out of room, grow the buffer.\r
781 //\r
782 TempPtr = AllocateZeroPool (\r
783 sizeof (PEI_PPI_LIST_POINTERS) * (CallbackNotifyListPointer->MaxCount + CALLBACK_NOTIFY_GROWTH_STEP)\r
784 );\r
785 ASSERT (TempPtr != NULL);\r
786 CopyMem (\r
787 TempPtr,\r
788 CallbackNotifyListPointer->NotifyPtrs,\r
789 sizeof (PEI_PPI_LIST_POINTERS) * CallbackNotifyListPointer->MaxCount\r
790 );\r
791 CallbackNotifyListPointer->NotifyPtrs = TempPtr;\r
1436aea4 792 CallbackNotifyListPointer->MaxCount = CallbackNotifyListPointer->MaxCount + CALLBACK_NOTIFY_GROWTH_STEP;\r
f2bc359c 793 }\r
1436aea4
MK
794\r
795 CallbackNotifyListPointer->NotifyPtrs[CallbackNotifyIndex].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *)NotifyList;\r
f2bc359c
SZ
796 CallbackNotifyIndex++;\r
797 CallbackNotifyListPointer->CurrentCount++;\r
798 } else {\r
799 if (DispatchNotifyIndex >= DispatchNotifyListPointer->MaxCount) {\r
800 //\r
801 // Run out of room, grow the buffer.\r
802 //\r
803 TempPtr = AllocateZeroPool (\r
804 sizeof (PEI_PPI_LIST_POINTERS) * (DispatchNotifyListPointer->MaxCount + DISPATCH_NOTIFY_GROWTH_STEP)\r
805 );\r
806 ASSERT (TempPtr != NULL);\r
807 CopyMem (\r
808 TempPtr,\r
809 DispatchNotifyListPointer->NotifyPtrs,\r
810 sizeof (PEI_PPI_LIST_POINTERS) * DispatchNotifyListPointer->MaxCount\r
811 );\r
812 DispatchNotifyListPointer->NotifyPtrs = TempPtr;\r
1436aea4 813 DispatchNotifyListPointer->MaxCount = DispatchNotifyListPointer->MaxCount + DISPATCH_NOTIFY_GROWTH_STEP;\r
f2bc359c 814 }\r
1436aea4
MK
815\r
816 DispatchNotifyListPointer->NotifyPtrs[DispatchNotifyIndex].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *)NotifyList;\r
f2bc359c
SZ
817 DispatchNotifyIndex++;\r
818 DispatchNotifyListPointer->CurrentCount++;\r
58dcdada 819 }\r
820\r
1436aea4 821 DEBUG ((DEBUG_INFO, "Register PPI Notify: %g\n", NotifyList->Guid));\r
f2bc359c 822\r
884200f9
SZ
823 if (Single) {\r
824 //\r
825 // Only single entry in the NotifyList.\r
826 //\r
827 break;\r
828 } else if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==\r
1436aea4
MK
829 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)\r
830 {\r
884200f9
SZ
831 //\r
832 // Continue until the end of the Notify List.\r
833 //\r
192f6d4c 834 break;\r
835 }\r
1436aea4 836\r
192f6d4c 837 //\r
f2bc359c 838 // Go to the next descriptor.\r
192f6d4c 839 //\r
840 NotifyList++;\r
192f6d4c 841 }\r
58dcdada 842\r
192f6d4c 843 //\r
f2bc359c 844 // Process any callback level notifies for all previously installed PPIs.\r
192f6d4c 845 //\r
f2bc359c 846 ProcessNotify (\r
b0d803fe 847 PrivateData,\r
192f6d4c 848 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
849 0,\r
f2bc359c
SZ
850 PrivateData->PpiData.PpiList.CurrentCount,\r
851 LastCallbackNotifyCount,\r
852 CallbackNotifyListPointer->CurrentCount\r
192f6d4c 853 );\r
58dcdada 854\r
1436aea4 855 return EFI_SUCCESS;\r
192f6d4c 856}\r
857\r
884200f9
SZ
858/**\r
859\r
d1102dba
LG
860 This function installs a notification service to be called back when a given\r
861 interface is installed or reinstalled. The purpose of the service is to publish\r
884200f9
SZ
862 an interface that other parties can use to call additional PPIs that may materialize later.\r
863\r
864 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
865 @param NotifyList Pointer to list of Descriptors to notify upon.\r
866\r
867 @retval EFI_SUCCESS if successful\r
868 @retval EFI_OUT_OF_RESOURCES if no space in the database\r
869 @retval EFI_INVALID_PARAMETER if not a good descriptor\r
870\r
871**/\r
872EFI_STATUS\r
873EFIAPI\r
874PeiNotifyPpi (\r
875 IN CONST EFI_PEI_SERVICES **PeiServices,\r
876 IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList\r
877 )\r
878{\r
879 return InternalPeiNotifyPpi (PeiServices, NotifyList, FALSE);\r
880}\r
881\r
b1f6a7c6 882/**\r
192f6d4c 883\r
884 Process the Notify List at dispatch level.\r
885\r
b1f6a7c6 886 @param PrivateData PeiCore's private data structure.\r
192f6d4c 887\r
b1f6a7c6 888**/\r
889VOID\r
f2bc359c 890ProcessDispatchNotifyList (\r
b1f6a7c6 891 IN PEI_CORE_INSTANCE *PrivateData\r
892 )\r
192f6d4c 893{\r
1436aea4 894 UINTN TempValue;\r
58dcdada 895\r
192f6d4c 896 while (TRUE) {\r
897 //\r
898 // Check if the PEIM that was just dispatched resulted in any\r
899 // Notifies getting installed. If so, go process any dispatch\r
d39d1260 900 // level Notifies that match the previously installed PPIs.\r
f2bc359c
SZ
901 // Use "while" instead of "if" since ProcessNotify can modify\r
902 // DispatchNotifyList.CurrentCount (with NotifyPpi) so we have\r
903 // to iterate until the same.\r
192f6d4c 904 //\r
f2bc359c
SZ
905 while (PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount != PrivateData->PpiData.DispatchNotifyList.CurrentCount) {\r
906 TempValue = PrivateData->PpiData.DispatchNotifyList.CurrentCount;\r
907 ProcessNotify (\r
b0d803fe 908 PrivateData,\r
192f6d4c 909 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,\r
910 0,\r
f2bc359c
SZ
911 PrivateData->PpiData.PpiList.LastDispatchedCount,\r
912 PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount,\r
913 PrivateData->PpiData.DispatchNotifyList.CurrentCount\r
192f6d4c 914 );\r
f2bc359c 915 PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount = TempValue;\r
192f6d4c 916 }\r
58dcdada 917\r
192f6d4c 918 //\r
919 // Check if the PEIM that was just dispatched resulted in any\r
920 // PPIs getting installed. If so, go process any dispatch\r
921 // level Notifies that match the installed PPIs.\r
f2bc359c
SZ
922 // Use "while" instead of "if" since ProcessNotify can modify\r
923 // PpiList.CurrentCount (with InstallPpi) so we have to iterate\r
924 // until the same.\r
192f6d4c 925 //\r
f2bc359c
SZ
926 while (PrivateData->PpiData.PpiList.LastDispatchedCount != PrivateData->PpiData.PpiList.CurrentCount) {\r
927 TempValue = PrivateData->PpiData.PpiList.CurrentCount;\r
928 ProcessNotify (\r
b0d803fe 929 PrivateData,\r
192f6d4c 930 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,\r
f2bc359c
SZ
931 PrivateData->PpiData.PpiList.LastDispatchedCount,\r
932 PrivateData->PpiData.PpiList.CurrentCount,\r
933 0,\r
934 PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount\r
192f6d4c 935 );\r
f2bc359c 936 PrivateData->PpiData.PpiList.LastDispatchedCount = TempValue;\r
192f6d4c 937 }\r
58dcdada 938\r
f2bc359c 939 if (PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount == PrivateData->PpiData.DispatchNotifyList.CurrentCount) {\r
192f6d4c 940 break;\r
941 }\r
58dcdada 942 }\r
1436aea4 943\r
192f6d4c 944 return;\r
945}\r
946\r
b1f6a7c6 947/**\r
948\r
f2bc359c 949 Process notifications.\r
b1f6a7c6 950\r
951 @param PrivateData PeiCore's private data structure\r
952 @param NotifyType Type of notify to fire.\r
953 @param InstallStartIndex Install Beginning index.\r
954 @param InstallStopIndex Install Ending index.\r
955 @param NotifyStartIndex Notify Beginning index.\r
956 @param NotifyStopIndex Notify Ending index.\r
957\r
958**/\r
192f6d4c 959VOID\r
f2bc359c 960ProcessNotify (\r
b0d803fe 961 IN PEI_CORE_INSTANCE *PrivateData,\r
1436aea4
MK
962 IN UINTN NotifyType,\r
963 IN INTN InstallStartIndex,\r
964 IN INTN InstallStopIndex,\r
965 IN INTN NotifyStartIndex,\r
966 IN INTN NotifyStopIndex\r
192f6d4c 967 )\r
192f6d4c 968{\r
1436aea4
MK
969 INTN Index1;\r
970 INTN Index2;\r
971 EFI_GUID *SearchGuid;\r
972 EFI_GUID *CheckGuid;\r
973 EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor;\r
f2bc359c
SZ
974\r
975 for (Index1 = NotifyStartIndex; Index1 < NotifyStopIndex; Index1++) {\r
976 if (NotifyType == EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) {\r
977 NotifyDescriptor = PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index1].Notify;\r
978 } else {\r
979 NotifyDescriptor = PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index1].Notify;\r
980 }\r
192f6d4c 981\r
982 CheckGuid = NotifyDescriptor->Guid;\r
983\r
984 for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) {\r
f2bc359c 985 SearchGuid = PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi->Guid;\r
192f6d4c 986 //\r
987 // Don't use CompareGuid function here for performance reasons.\r
988 // Instead we compare the GUID as INT32 at a time and branch\r
989 // on the first failed comparison.\r
990 //\r
991 if ((((INT32 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) &&\r
992 (((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) &&\r
993 (((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) &&\r
1436aea4
MK
994 (((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3]))\r
995 {\r
996 DEBUG ((\r
997 DEBUG_INFO,\r
998 "Notify: PPI Guid: %g, Peim notify entry point: %p\n",\r
58dcdada 999 SearchGuid,\r
192f6d4c 1000 NotifyDescriptor->Notify\r
1001 ));\r
1002 NotifyDescriptor->Notify (\r
1436aea4 1003 (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (),\r
192f6d4c 1004 NotifyDescriptor,\r
f2bc359c 1005 (PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi)->Ppi\r
192f6d4c 1006 );\r
1007 }\r
1008 }\r
1009 }\r
192f6d4c 1010}\r
1011\r
884200f9
SZ
1012/**\r
1013 Process PpiList from SEC phase.\r
1014\r
1015 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
1016 @param PpiList Points to a list of one or more PPI descriptors to be installed initially by the PEI core.\r
1017 These PPI's will be installed and/or immediately signaled if they are notification type.\r
1018\r
1019**/\r
1020VOID\r
1021ProcessPpiListFromSec (\r
1436aea4
MK
1022 IN CONST EFI_PEI_SERVICES **PeiServices,\r
1023 IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList\r
884200f9
SZ
1024 )\r
1025{\r
1436aea4
MK
1026 EFI_STATUS Status;\r
1027 EFI_SEC_HOB_DATA_PPI *SecHobDataPpi;\r
1028 EFI_HOB_GENERIC_HEADER *SecHobList;\r
884200f9 1029\r
1436aea4 1030 for ( ; ;) {\r
884200f9
SZ
1031 if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) != 0) {\r
1032 //\r
1033 // It is a notification PPI.\r
1034 //\r
1436aea4 1035 Status = InternalPeiNotifyPpi (PeiServices, (CONST EFI_PEI_NOTIFY_DESCRIPTOR *)PpiList, TRUE);\r
884200f9
SZ
1036 ASSERT_EFI_ERROR (Status);\r
1037 } else {\r
1038 //\r
1039 // It is a normal PPI.\r
1040 //\r
1041 Status = InternalPeiInstallPpi (PeiServices, PpiList, TRUE);\r
1042 ASSERT_EFI_ERROR (Status);\r
1043 }\r
1044\r
1045 if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {\r
1046 //\r
1047 // Continue until the end of the PPI List.\r
1048 //\r
1049 break;\r
1050 }\r
1051\r
1052 PpiList++;\r
1053 }\r
483e2cdd
SZ
1054\r
1055 //\r
1056 // If the EFI_SEC_HOB_DATA_PPI is in the list of PPIs passed to the PEI entry point,\r
1057 // the PEI Foundation will call the GetHobs() member function and install all HOBs\r
1058 // returned into the HOB list. It does this after installing all PPIs passed from SEC\r
1059 // into the PPI database and before dispatching any PEIMs.\r
1060 //\r
1436aea4 1061 Status = PeiLocatePpi (PeiServices, &gEfiSecHobDataPpiGuid, 0, NULL, (VOID **)&SecHobDataPpi);\r
483e2cdd
SZ
1062 if (!EFI_ERROR (Status)) {\r
1063 Status = SecHobDataPpi->GetHobs (SecHobDataPpi, &SecHobList);\r
1064 if (!EFI_ERROR (Status)) {\r
1065 Status = PeiInstallSecHobData (PeiServices, SecHobList);\r
1066 ASSERT_EFI_ERROR (Status);\r
1067 }\r
1068 }\r
884200f9
SZ
1069}\r
1070\r
9bedaec0
MK
1071/**\r
1072\r
1073 Migrate PPI Pointers of PEI_CORE from temporary memory to permanent memory.\r
1074\r
1075 @param PrivateData Pointer to PeiCore's private data structure.\r
1076 @param CoreFvHandle Address of PEI_CORE FV Handle in temporary memory.\r
1077\r
1078**/\r
1079VOID\r
1080ConvertPeiCorePpiPointers (\r
1436aea4
MK
1081 IN PEI_CORE_INSTANCE *PrivateData,\r
1082 IN PEI_CORE_FV_HANDLE *CoreFvHandle\r
9bedaec0
MK
1083 )\r
1084{\r
1085 EFI_FV_FILE_INFO FileInfo;\r
1086 EFI_PHYSICAL_ADDRESS OrgImageBase;\r
1087 EFI_PHYSICAL_ADDRESS MigratedImageBase;\r
1088 UINTN PeiCoreModuleSize;\r
1089 EFI_PEI_FILE_HANDLE PeiCoreFileHandle;\r
1090 VOID *PeiCoreImageBase;\r
1091 VOID *PeiCoreEntryPoint;\r
1092 EFI_STATUS Status;\r
1093\r
1094 PeiCoreFileHandle = NULL;\r
1095\r
1096 //\r
1097 // Find the PEI Core in the BFV in temporary memory.\r
1098 //\r
31e8a47b 1099 Status = CoreFvHandle->FvPpi->FindFileByType (\r
1436aea4
MK
1100 CoreFvHandle->FvPpi,\r
1101 EFI_FV_FILETYPE_PEI_CORE,\r
1102 CoreFvHandle->FvHandle,\r
1103 &PeiCoreFileHandle\r
1104 );\r
9bedaec0
MK
1105 ASSERT_EFI_ERROR (Status);\r
1106\r
1107 if (!EFI_ERROR (Status)) {\r
31e8a47b 1108 Status = CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, PeiCoreFileHandle, &FileInfo);\r
9bedaec0
MK
1109 ASSERT_EFI_ERROR (Status);\r
1110\r
1111 Status = PeiGetPe32Data (PeiCoreFileHandle, &PeiCoreImageBase);\r
1112 ASSERT_EFI_ERROR (Status);\r
1113\r
1114 //\r
1115 // Find PEI Core EntryPoint in the BFV in temporary memory.\r
1116 //\r
1436aea4 1117 Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, &PeiCoreEntryPoint);\r
9bedaec0
MK
1118 ASSERT_EFI_ERROR (Status);\r
1119\r
1436aea4
MK
1120 OrgImageBase = (UINTN)PeiCoreImageBase;\r
1121 MigratedImageBase = (UINTN)_ModuleEntryPoint - ((UINTN)PeiCoreEntryPoint - (UINTN)PeiCoreImageBase);\r
9bedaec0
MK
1122\r
1123 //\r
1124 // Size of loaded PEI_CORE in permanent memory.\r
1125 //\r
1436aea4 1126 PeiCoreModuleSize = (UINTN)FileInfo.BufferSize - ((UINTN)OrgImageBase - (UINTN)FileInfo.Buffer);\r
9bedaec0
MK
1127\r
1128 //\r
1129 // Migrate PEI_CORE PPI pointers from temporary memory to newly\r
1130 // installed PEI_CORE in permanent memory.\r
1131 //\r
1436aea4 1132 ConvertPpiPointersFv (PrivateData, (UINTN)OrgImageBase, (UINTN)MigratedImageBase, PeiCoreModuleSize);\r
9bedaec0
MK
1133 }\r
1134}\r