3 Copyright (c) 2006 - 2007, 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
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.
18 Definition of Pei Core Structures and Services
28 #include <FrameworkPei.h>
29 #include <Guid/StatusCodeDataTypeId.h>
30 #include <Ppi/DxeIpl.h>
31 #include <Ppi/MemoryDiscovered.h>
32 #include <Ppi/FindFv.h>
33 #include <Ppi/StatusCode.h>
34 #include <Ppi/Security.h>
35 #include <Ppi/Reset.h>
36 #include <Ppi/FvLoadFile.h>
37 #include <Library/DebugLib.h>
38 #include <Library/PeiCoreEntryPoint.h>
39 #include <Library/BaseLib.h>
40 #include <Library/HobLib.h>
41 #include <Library/PerformanceLib.h>
42 #include <Library/PeiServicesLib.h>
43 #include <Library/ReportStatusCodeLib.h>
44 #include <Library/PeCoffGetEntryPointLib.h>
45 #include <Library/BaseMemoryLib.h>
46 #include <Library/TimerLib.h>
47 #include <IndustryStandard/PeImage.h>
49 extern EFI_GUID gEfiPeiCorePrivateGuid
;
52 // Pei Core private data structures
55 EFI_PEI_PPI_DESCRIPTOR
*Ppi
;
56 EFI_PEI_NOTIFY_DESCRIPTOR
*Notify
;
58 } PEI_PPI_LIST_POINTERS
;
60 #define PEI_STACK_SIZE 0x20000
62 #define MAX_PPI_DESCRIPTORS 64
68 INTN LastDispatchedInstall
;
69 INTN LastDispatchedNotify
;
70 PEI_PPI_LIST_POINTERS PpiListPtrs
[MAX_PPI_DESCRIPTORS
];
76 UINT32 DispatchedPeimBitMap
;
77 UINT32 PreviousPeimBitMap
;
78 EFI_FFS_FILE_HEADER
*CurrentPeimAddress
;
79 EFI_FIRMWARE_VOLUME_HEADER
*CurrentFvAddress
;
80 EFI_FIRMWARE_VOLUME_HEADER
*BootFvAddress
;
81 EFI_PEI_FIND_FV_PPI
*FindFv
;
82 } PEI_CORE_DISPATCH_DATA
;
86 // Pei Core private data structure instance
89 #define PEI_CORE_HANDLE_SIGNATURE EFI_SIGNATURE_32('P','e','i','C')
93 EFI_PEI_SERVICES
*PS
; // Point to ServiceTableShadow
94 PEI_PPI_DATABASE PpiData
;
95 PEI_CORE_DISPATCH_DATA DispatchData
;
96 EFI_PEI_HOB_POINTERS HobList
;
97 BOOLEAN SwitchStackSignal
;
98 BOOLEAN PeiMemoryInstalled
;
99 EFI_PHYSICAL_ADDRESS StackBase
;
101 VOID
*BottomOfCarHeap
;
104 EFI_PEI_SECURITY_PPI
*PrivateSecurityPpi
;
105 EFI_PEI_SERVICES ServiceTableShadow
;
106 UINTN SizeOfCacheAsRam
;
107 VOID
*MaxTopOfCarHeap
;
111 // Pei Core Instance Data Macros
114 #define PEI_CORE_INSTANCE_FROM_PS_THIS(a) \
115 CR(a, PEI_CORE_INSTANCE, PS, PEI_CORE_HANDLE_SIGNATURE)
118 // BUGBUG: Where does this go really?
122 (EFIAPI
*PEI_CORE_ENTRY_POINT
)(
123 IN EFI_PEI_STARTUP_DESCRIPTOR
*PeiStartupDescriptor
,
124 IN PEI_CORE_INSTANCE
*OldCoreData
128 // Union of temporarily used function pointers (to save stack space)
131 PEI_CORE_ENTRY_POINT PeiCore
;
132 EFI_PEIM_ENTRY_POINT2 PeimEntry
;
133 EFI_PEIM_NOTIFY_ENTRY_POINT PeimNotifyEntry
;
134 EFI_DXE_IPL_PPI
*DxeIpl
;
135 EFI_PEI_PPI_DESCRIPTOR
*PpiDescriptor
;
136 EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
;
138 } PEI_CORE_TEMP_POINTERS
;
147 IN EFI_PEI_STARTUP_DESCRIPTOR
*PeiStartupDescriptor
,
154 The entry routine to Pei Core, invoked by PeiMain during transition
155 from SEC to PEI. After switching stack in the PEI core, it will restart
156 with the old core data.
160 PeiStartupDescriptor - Information and services provided by SEC phase.
161 OldCoreData - Pointer to old core data that is used to initialize the
166 This function never returns
167 EFI_NOT_FOUND - Never reach
173 // Dispatcher support functions
177 PeimDispatchReadiness (
178 IN EFI_PEI_SERVICES
**PeiServices
,
179 IN VOID
*DependencyExpression
,
180 IN OUT BOOLEAN
*Runnable
186 This is the POSTFIX version of the dependency evaluator. When a
187 PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on
188 the evaluation stack. When that entry is poped from the evaluation
189 stack, the PPI is checked if it is installed. This method allows
190 some time savings as not all PPIs must be checked for certain
191 operation types (AND, OR).
195 PeiServices - Calling context.
197 DependencyExpression - Pointer to a dependency expression. The Grammar adheres to
198 the BNF described above and is stored in postfix notation.
199 Runnable - is True if the driver can be scheduled and False if the driver
200 cannot be scheduled. This is the value that the schedulers
201 should use for deciding the state of the driver.
205 Status = EFI_SUCCESS if it is a well-formed Grammar
206 EFI_INVALID_PARAMETER if the dependency expression overflows
208 EFI_INVALID_PARAMETER if the dependency expression underflows
210 EFI_INVALID_PARAMETER if the dependency expression is not a
218 IN EFI_PEI_STARTUP_DESCRIPTOR
*PeiStartupDescriptor
,
219 IN PEI_CORE_INSTANCE
*PrivateData
,
220 IN PEI_CORE_DISPATCH_DATA
*DispatchData
227 Conduct PEIM dispatch.
231 PeiStartupDescriptor - Pointer to IN EFI_PEI_STARTUP_DESCRIPTOR
232 PrivateData - Pointer to the private data passed in from caller
233 DispatchData - Pointer to PEI_CORE_DISPATCH_DATA data.
237 EFI_SUCCESS - Successfully dispatched PEIM.
238 EFI_NOT_FOUND - The dispatch failed.
245 InitializeDispatcherData (
246 IN EFI_PEI_SERVICES
**PeiServices
,
247 IN PEI_CORE_INSTANCE
*OldCoreData
,
248 IN EFI_PEI_STARTUP_DESCRIPTOR
*PeiStartupDescriptor
254 Initialize the Dispatcher's data members
258 PeiServices - The PEI core services table.
259 OldCoreData - Pointer to old core data (before switching stack).
260 NULL if being run in non-permament memory mode.
261 PeiStartupDescriptor - Information and services provided by SEC phase.
274 IN EFI_PEI_SERVICES
**PeiServices
,
275 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
,
276 IN OUT EFI_FFS_FILE_HEADER
**PeimFileHeader
281 Given the input file pointer, search for the next matching file in the
282 FFS volume. The search starts from FileHeader inside
283 the Firmware Volume defined by FwVolHeader.
286 PeiServices - Pointer to the PEI Core Services Table.
288 FwVolHeader - Pointer to the FV header of the volume to search.
289 This parameter must point to a valid FFS volume.
291 PeimFileHeader - Pointer to the current file from which to begin searching.
292 This pointer will be updated upon return to reflect the file found.
295 EFI_NOT_FOUND - No files matching the search criteria were found
303 IN UINT8 CurrentPeim
,
304 IN UINT32 DispatchedPeimBitMap
310 This routine checks to see if a particular PEIM has been dispatched during
311 the PEI core dispatch.
314 CurrentPeim - The PEIM/FV in the bit array to check.
315 DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
318 TRUE if PEIM already dispatched
326 IN EFI_PEI_SERVICES
**PeiServices
,
327 IN UINT8 CurrentPeim
,
328 OUT UINT32
*DispatchedPeimBitMap
334 This routine sets a PEIM as having been dispatched once its entry
335 point has been invoked.
339 PeiServices - The PEI core services table.
340 CurrentPeim - The PEIM/FV in the bit array to check.
341 DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
351 IN EFI_PEI_SERVICES
**PeiServices
,
352 IN VOID
*CurrentPeimAddress
358 This routine parses the Dependency Expression, if available, and
359 decides if the module can be executed.
362 PeiServices - The PEI Service Table
363 CurrentPeimAddress - Address of the PEIM Firmware File under investigation
366 TRUE - Can be dispatched
367 FALSE - Cannot be dispatched
372 #if defined (MDE_CPU_IPF)
374 // In Ipf we should make special changes for the PHIT pointers to support
375 // recovery boot in cache mode.
377 #define SWITCH_TO_CACHE_MODE(CoreData) SwitchToCacheMode(CoreData)
378 #define CACHE_MODE_ADDRESS_MASK 0x7FFFFFFFFFFFFFFFULL
381 IN PEI_CORE_INSTANCE
*CoreData
387 Switch the PHIT pointers to cache mode after InstallPeiMemory in CAR.
391 CoreData - The PEI core Private Data
400 #define SWITCH_TO_CACHE_MODE(CoreData)
405 // PPI support functions
408 InitializePpiServices (
409 IN EFI_PEI_SERVICES
**PeiServices
,
410 IN PEI_CORE_INSTANCE
*OldCoreData
416 Initialize PPI services.
420 PeiServices - The PEI core services table.
421 OldCoreData - Pointer to the PEI Core data.
422 NULL if being run in non-permament memory mode.
432 IN EFI_PEI_SERVICES
**PeiServices
,
433 IN EFI_HOB_HANDOFF_INFO_TABLE
*OldHandOffHob
,
434 IN EFI_HOB_HANDOFF_INFO_TABLE
*NewHandOffHob
440 Migrate the Hob list from the CAR stack to PEI installed memory.
444 PeiServices - The PEI core services table.
445 OldHandOffHob - The old handoff HOB list.
446 NewHandOffHob - The new handoff HOB list.
456 IN EFI_PEI_SERVICES
**PeiServices
,
457 IN EFI_PEI_PPI_DESCRIPTOR
*PpiList
463 Install PPI services.
467 PeiServices - Pointer to the PEI Service Table
468 PpiList - Pointer to a list of PEI PPI Descriptors.
472 EFI_SUCCESS - if all PPIs in PpiList are successfully installed.
473 EFI_INVALID_PARAMETER - if PpiList is NULL pointer
474 EFI_INVALID_PARAMETER - if any PPI in PpiList is not valid
475 EFI_OUT_OF_RESOURCES - if there is no more memory resource to install PPI
483 IN EFI_PEI_SERVICES
**PeiServices
,
484 IN EFI_PEI_PPI_DESCRIPTOR
*OldPpi
,
485 IN EFI_PEI_PPI_DESCRIPTOR
*NewPpi
491 Re-Install PPI services.
495 PeiServices - Pointer to the PEI Service Table
496 OldPpi - Pointer to the old PEI PPI Descriptors.
497 NewPpi - Pointer to the new PEI PPI Descriptors.
501 EFI_SUCCESS - if the operation was successful
502 EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL
503 EFI_INVALID_PARAMETER - if NewPpi is not valid
504 EFI_NOT_FOUND - if the PPI was not in the database
512 IN EFI_PEI_SERVICES
**PeiServices
,
515 IN OUT EFI_PEI_PPI_DESCRIPTOR
**PpiDescriptor
,
522 Locate a given named PPI.
526 PeiServices - Pointer to the PEI Service Table
527 Guid - Pointer to GUID of the PPI.
528 Instance - Instance Number to discover.
529 PpiDescriptor - Pointer to reference the found descriptor. If not NULL,
530 returns a pointer to the descriptor (includes flags, etc)
531 Ppi - Pointer to reference the found PPI
535 Status - EFI_SUCCESS if the PPI is in the database
536 EFI_NOT_FOUND if the PPI is not in the database
543 IN EFI_PEI_SERVICES
**PeiServices
,
544 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyList
550 Install a notification for a given PPI.
554 PeiServices - Pointer to the PEI Service Table
555 NotifyList - Pointer to list of Descriptors to notify upon.
559 Status - EFI_SUCCESS if successful
560 EFI_OUT_OF_RESOURCES if no space in the database
561 EFI_INVALID_PARAMETER if not a good decriptor
568 IN EFI_PEI_SERVICES
**PeiServices
574 Process the Notify List at dispatch level.
578 PeiServices - Pointer to the PEI Service Table
587 IN EFI_PEI_SERVICES
**PeiServices
,
589 IN INTN InstallStartIndex
,
590 IN INTN InstallStopIndex
,
591 IN INTN NotifyStartIndex
,
592 IN INTN NotifyStopIndex
598 Dispatch notifications.
602 PeiServices - Pointer to the PEI Service Table
603 NotifyType - Type of notify to fire.
604 InstallStartIndex - Install Beginning index.
605 InstallStopIndex - Install Ending index.
606 NotifyStartIndex - Notify Beginning index.
607 NotifyStopIndex - Notify Ending index.
615 // Boot mode support functions
620 IN EFI_PEI_SERVICES
**PeiServices
,
621 IN OUT EFI_BOOT_MODE
*BootMode
627 This service enables PEIMs to ascertain the present value of the boot mode.
631 PeiServices - The PEI core services table.
632 BootMode - A pointer to contain the value of the boot mode.
636 EFI_SUCCESS - The boot mode was returned successfully.
637 EFI_INVALID_PARAMETER - BootMode is NULL.
645 IN EFI_PEI_SERVICES
**PeiServices
,
646 IN EFI_BOOT_MODE BootMode
652 This service enables PEIMs to update the boot mode variable.
656 PeiServices - The PEI core services table.
657 BootMode - The value of the boot mode to set.
661 EFI_SUCCESS - The value was successfully updated
667 // Security support functions
670 InitializeSecurityServices (
671 IN EFI_PEI_SERVICES
**PeiServices
,
672 IN PEI_CORE_INSTANCE
*OldCoreData
678 Initialize the security services.
682 PeiServices - The PEI core services table.
683 OldCoreData - Pointer to the old core data.
684 NULL if being run in non-permament memory mode.
694 IN EFI_FIRMWARE_VOLUME_HEADER
*CurrentFvAddress
700 Provide a callout to the OEM FV verification service.
704 CurrentFvAddress - Pointer to the FV under investigation.
716 IN EFI_PEI_SERVICES
**PeiServices
,
717 IN EFI_FFS_FILE_HEADER
*CurrentPeimAddress
723 Provide a callout to the security verification service.
727 PeiServices - The PEI core services table.
728 CurrentPeimAddress - Pointer to the Firmware File under investigation.
732 EFI_SUCCESS - Image is OK
733 EFI_SECURITY_VIOLATION - Image is illegal
742 IN EFI_PEI_SERVICES
**PeiServices
,
743 IN OUT VOID
**HobList
749 Gets the pointer to the HOB List.
753 PeiServices - The PEI core services table.
754 HobList - Pointer to the HOB List.
758 EFI_SUCCESS - Get the pointer of HOB List
759 EFI_NOT_AVAILABLE_YET - the HOB List is not yet published
760 EFI_INVALID_PARAMETER - HobList is NULL (in debug mode)
768 IN EFI_PEI_SERVICES
**PeiServices
,
777 Add a new HOB to the HOB List.
781 PeiServices - The PEI core services table.
782 Type - Type of the new HOB.
783 Length - Length of the new HOB to allocate.
784 Hob - Pointer to the new HOB.
789 - EFI_INVALID_PARAMETER if Hob is NULL
790 - EFI_NOT_AVAILABLE_YET if HobList is still not available.
791 - EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.
797 PeiCoreBuildHobHandoffInfoTable (
798 IN EFI_BOOT_MODE BootMode
,
799 IN EFI_PHYSICAL_ADDRESS MemoryBegin
,
800 IN UINT64 MemoryLength
806 Builds a Handoff Information Table HOB
810 BootMode - Current Bootmode
811 MemoryBegin - Start Memory Address.
812 MemoryLength - Length of Memory.
823 // FFS Fw Volume support functions
828 IN EFI_PEI_SERVICES
**PeiServices
,
830 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
,
831 IN OUT EFI_FFS_FILE_HEADER
**FileHeader
836 Given the input file pointer, search for the next matching file in the
837 FFS volume as defined by SearchType. The search starts from FileHeader inside
838 the Firmware Volume defined by FwVolHeader.
841 PeiServices - Pointer to the PEI Core Services Table.
843 SearchType - Filter to find only files of this type.
844 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
846 FwVolHeader - Pointer to the FV header of the volume to search.
847 This parameter must point to a valid FFS volume.
849 FileHeader - Pointer to the current file from which to begin searching.
850 This pointer will be updated upon return to reflect the file found.
853 EFI_NOT_FOUND - No files matching the search criteria were found
861 PeiFfsFindSectionData (
862 IN EFI_PEI_SERVICES
**PeiServices
,
863 IN EFI_SECTION_TYPE SectionType
,
864 IN EFI_FFS_FILE_HEADER
*FfsFileHeader
,
865 IN OUT VOID
**SectionData
870 Given the input file pointer, search for the next matching section in the
874 PeiServices - Pointer to the PEI Core Services Table.
875 SearchType - Filter to find only sections of this type.
876 FfsFileHeader - Pointer to the current file to search.
877 SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
878 - NULL if section not found
881 EFI_NOT_FOUND - No files matching the search criteria were found
889 PeiFvFindNextVolume (
890 IN EFI_PEI_SERVICES
**PeiServices
,
892 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**FwVolHeader
898 Return the BFV location
900 BugBug -- Move this to the location of this code to where the
901 other FV and FFS support code lives.
902 Also, update to use FindFV for instances #'s >= 1.
906 PeiServices - The PEI core services table.
907 Instance - Instance of FV to find
908 FwVolHeader - Pointer to contain the data to return
911 Pointer to the Firmware Volume instance requested
913 EFI_INVALID_PARAMETER - FwVolHeader is NULL
915 EFI_SUCCESS - Firmware volume instance successfully found.
921 // Memory support functions
924 InitializeMemoryServices (
925 IN EFI_PEI_SERVICES
**PeiServices
,
926 IN EFI_PEI_STARTUP_DESCRIPTOR
*PeiStartupDescriptor
,
927 IN PEI_CORE_INSTANCE
*OldCoreData
933 Initialize the memory services.
937 PeiServices - The PEI core services table.
938 PeiStartupDescriptor - Information and services provided by SEC phase.
939 OldCoreData - Pointer to the PEI Core data.
940 NULL if being run in non-permament memory mode.
951 PeiInstallPeiMemory (
952 IN EFI_PEI_SERVICES
**PeiServices
,
953 IN EFI_PHYSICAL_ADDRESS MemoryBegin
,
954 IN UINT64 MemoryLength
960 Install the permanent memory is now available.
961 Creates HOB (PHIT and Stack).
965 PeiServices - The PEI core services table.
966 MemoryBegin - Start of memory address.
967 MemoryLength - Length of memory.
979 IN EFI_PEI_SERVICES
**PeiServices
,
980 IN EFI_MEMORY_TYPE MemoryType
,
982 OUT EFI_PHYSICAL_ADDRESS
*Memory
988 Memory allocation service on permanent memory,
989 not usable prior to the memory installation.
993 PeiServices - The PEI core services table.
994 Type - Type of allocation.
995 MemoryType - Type of memory to allocate.
996 Pages - Number of pages to allocate.
997 Memory - Pointer of memory allocated.
1001 Status - EFI_SUCCESS The allocation was successful
1002 EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.
1003 EFI_NOT_AVAILABLE_YET Called with permanent memory not available
1004 EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement
1005 to allocate the number of pages.
1013 IN EFI_PEI_SERVICES
**PeiServices
,
1019 Routine Description:
1021 Memory allocation service on the CAR.
1025 PeiServices - The PEI core services table.
1027 Size - Amount of memory required
1029 Buffer - Address of pointer to the buffer
1033 Status - EFI_SUCCESS The allocation was successful
1034 EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
1035 to allocate the requested size.
1042 IN EFI_PEI_SERVICES
**PeiServices
,
1043 IN EFI_FFS_FILE_HEADER
*PeimFileHeader
,
1044 OUT VOID
**EntryPoint
1048 Routine Description:
1050 Get entry point of a Peim file.
1054 PeiServices - Calling context.
1056 PeimFileHeader - Peim file's header.
1058 EntryPoint - Entry point of that Peim file.
1070 PeiReportStatusCode (
1071 IN EFI_PEI_SERVICES
**PeiServices
,
1072 IN EFI_STATUS_CODE_TYPE CodeType
,
1073 IN EFI_STATUS_CODE_VALUE Value
,
1075 IN EFI_GUID
*CallerId
,
1076 IN EFI_STATUS_CODE_DATA
*Data OPTIONAL
1080 Routine Description:
1082 Core version of the Status Code reporter
1086 PeiServices - The PEI core services table.
1088 CodeType - Type of Status Code.
1090 Value - Value to output for Status Code.
1092 Instance - Instance Number of this status code.
1094 CallerId - ID of the caller of this status code.
1096 Data - Optional data associated with this status code.
1100 Status - EFI_SUCCESS if status code is successfully reported
1101 - EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed
1110 IN EFI_PEI_SERVICES
**PeiServices
1114 Routine Description:
1116 Core version of the Reset System
1120 PeiServices - The PEI core services table.
1124 Status - EFI_NOT_AVAILABLE_YET. PPI not available yet.
1125 - EFI_DEVICE_ERROR. Did not reset system.
1127 Otherwise, resets the system.
1133 Transfers control to a function starting with a new stack.
1135 Transfers control to the function specified by EntryPoint using the new stack
1136 specified by NewStack and passing in the parameters specified by Context1 and
1137 Context2. Context1 and Context2 are optional and may be NULL. The function
1138 EntryPoint must never return.
1140 If EntryPoint is NULL, then ASSERT().
1141 If NewStack is NULL, then ASSERT().
1143 @param EntryPoint A pointer to function to call with the new stack.
1144 @param Context1 A pointer to the context to pass into the EntryPoint
1146 @param Context2 A pointer to the context to pass into the EntryPoint
1148 @param NewStack A pointer to the new stack to use for the EntryPoint
1150 @param NewBsp A pointer to the new BSP for the EntryPoint on IPF. It's
1151 Reserved on other architectures.
1157 IN SWITCH_STACK_ENTRY_POINT EntryPoint
,
1158 IN VOID
*Context1
, OPTIONAL
1159 IN VOID
*Context2
, OPTIONAL