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 <Ppi/DxeIpl.h>
30 #include <Ppi/MemoryDiscovered.h>
31 #include <Ppi/FindFv.h>
32 #include <Ppi/StatusCode.h>
33 #include <Ppi/Security.h>
34 #include <Ppi/Reset.h>
35 #include <Ppi/FvLoadFile.h>
36 #include <Library/DebugLib.h>
37 #include <Library/PeiCoreEntryPoint.h>
38 #include <Library/BaseLib.h>
39 #include <Library/HobLib.h>
40 #include <Library/PerformanceLib.h>
41 #include <Library/PeiServicesLib.h>
42 #include <Library/ReportStatusCodeLib.h>
43 #include <Library/PeCoffGetEntryPointLib.h>
44 #include <Library/BaseMemoryLib.h>
45 #include <Library/TimerLib.h>
48 extern EFI_GUID gEfiPeiCorePrivateGuid
;
51 // Pei Core private data structures
54 EFI_PEI_PPI_DESCRIPTOR
*Ppi
;
55 EFI_PEI_NOTIFY_DESCRIPTOR
*Notify
;
57 } PEI_PPI_LIST_POINTERS
;
59 #define PEI_STACK_SIZE 0x20000
61 #define MAX_PPI_DESCRIPTORS 64
67 INTN LastDispatchedInstall
;
68 INTN LastDispatchedNotify
;
69 PEI_PPI_LIST_POINTERS PpiListPtrs
[MAX_PPI_DESCRIPTORS
];
75 UINT32 DispatchedPeimBitMap
;
76 UINT32 PreviousPeimBitMap
;
77 EFI_FFS_FILE_HEADER
*CurrentPeimAddress
;
78 EFI_FIRMWARE_VOLUME_HEADER
*CurrentFvAddress
;
79 EFI_FIRMWARE_VOLUME_HEADER
*BootFvAddress
;
80 EFI_PEI_FIND_FV_PPI
*FindFv
;
81 } PEI_CORE_DISPATCH_DATA
;
85 // Pei Core private data structure instance
88 #define PEI_CORE_HANDLE_SIGNATURE EFI_SIGNATURE_32('P','e','i','C')
92 EFI_PEI_SERVICES
*PS
; // Point to ServiceTableShadow
93 PEI_PPI_DATABASE PpiData
;
94 PEI_CORE_DISPATCH_DATA DispatchData
;
95 EFI_PEI_HOB_POINTERS HobList
;
96 BOOLEAN SwitchStackSignal
;
97 BOOLEAN PeiMemoryInstalled
;
98 EFI_PHYSICAL_ADDRESS StackBase
;
100 VOID
*BottomOfCarHeap
;
103 EFI_PEI_SECURITY_PPI
*PrivateSecurityPpi
;
104 EFI_PEI_SERVICES ServiceTableShadow
;
105 UINTN SizeOfCacheAsRam
;
106 VOID
*MaxTopOfCarHeap
;
110 // Pei Core Instance Data Macros
113 #define PEI_CORE_INSTANCE_FROM_PS_THIS(a) \
114 CR(a, PEI_CORE_INSTANCE, PS, PEI_CORE_HANDLE_SIGNATURE)
117 // BUGBUG: Where does this go really?
121 (EFIAPI
*PEI_CORE_ENTRY_POINT
)(
122 IN EFI_PEI_STARTUP_DESCRIPTOR
*PeiStartupDescriptor
,
123 IN PEI_CORE_INSTANCE
*OldCoreData
127 // Union of temporarily used function pointers (to save stack space)
130 PEI_CORE_ENTRY_POINT PeiCore
;
131 EFI_PEIM_ENTRY_POINT PeimEntry
;
132 EFI_PEIM_NOTIFY_ENTRY_POINT PeimNotifyEntry
;
133 EFI_DXE_IPL_PPI
*DxeIpl
;
134 EFI_PEI_PPI_DESCRIPTOR
*PpiDescriptor
;
135 EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
;
137 } PEI_CORE_TEMP_POINTERS
;
146 IN EFI_PEI_STARTUP_DESCRIPTOR
*PeiStartupDescriptor
,
153 The entry routine to Pei Core, invoked by PeiMain during transition
154 from SEC to PEI. After switching stack in the PEI core, it will restart
155 with the old core data.
159 PeiStartupDescriptor - Information and services provided by SEC phase.
160 OldCoreData - Pointer to old core data that is used to initialize the
165 This function never returns
166 EFI_NOT_FOUND - Never reach
172 // Dispatcher support functions
176 PeimDispatchReadiness (
177 IN EFI_PEI_SERVICES
**PeiServices
,
178 IN VOID
*DependencyExpression
,
179 IN OUT BOOLEAN
*Runnable
185 This is the POSTFIX version of the dependency evaluator. When a
186 PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on
187 the evaluation stack. When that entry is poped from the evaluation
188 stack, the PPI is checked if it is installed. This method allows
189 some time savings as not all PPIs must be checked for certain
190 operation types (AND, OR).
194 PeiServices - Calling context.
196 DependencyExpression - Pointer to a dependency expression. The Grammar adheres to
197 the BNF described above and is stored in postfix notation.
198 Runnable - is True if the driver can be scheduled and False if the driver
199 cannot be scheduled. This is the value that the schedulers
200 should use for deciding the state of the driver.
204 Status = EFI_SUCCESS if it is a well-formed Grammar
205 EFI_INVALID_PARAMETER if the dependency expression overflows
207 EFI_INVALID_PARAMETER if the dependency expression underflows
209 EFI_INVALID_PARAMETER if the dependency expression is not a
217 IN EFI_PEI_STARTUP_DESCRIPTOR
*PeiStartupDescriptor
,
218 IN PEI_CORE_INSTANCE
*PrivateData
,
219 IN PEI_CORE_DISPATCH_DATA
*DispatchData
226 Conduct PEIM dispatch.
230 PeiStartupDescriptor - Pointer to IN EFI_PEI_STARTUP_DESCRIPTOR
231 PrivateData - Pointer to the private data passed in from caller
232 DispatchData - Pointer to PEI_CORE_DISPATCH_DATA data.
236 EFI_SUCCESS - Successfully dispatched PEIM.
237 EFI_NOT_FOUND - The dispatch failed.
244 InitializeDispatcherData (
245 IN EFI_PEI_SERVICES
**PeiServices
,
246 IN PEI_CORE_INSTANCE
*OldCoreData
,
247 IN EFI_PEI_STARTUP_DESCRIPTOR
*PeiStartupDescriptor
253 Initialize the Dispatcher's data members
257 PeiServices - The PEI core services table.
258 OldCoreData - Pointer to old core data (before switching stack).
259 NULL if being run in non-permament memory mode.
260 PeiStartupDescriptor - Information and services provided by SEC phase.
273 IN EFI_PEI_SERVICES
**PeiServices
,
274 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
,
275 IN OUT EFI_FFS_FILE_HEADER
**PeimFileHeader
280 Given the input file pointer, search for the next matching file in the
281 FFS volume. The search starts from FileHeader inside
282 the Firmware Volume defined by FwVolHeader.
285 PeiServices - Pointer to the PEI Core Services Table.
287 FwVolHeader - Pointer to the FV header of the volume to search.
288 This parameter must point to a valid FFS volume.
290 PeimFileHeader - Pointer to the current file from which to begin searching.
291 This pointer will be updated upon return to reflect the file found.
294 EFI_NOT_FOUND - No files matching the search criteria were found
302 IN UINT8 CurrentPeim
,
303 IN UINT32 DispatchedPeimBitMap
309 This routine checks to see if a particular PEIM has been dispatched during
310 the PEI core dispatch.
313 CurrentPeim - The PEIM/FV in the bit array to check.
314 DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
317 TRUE if PEIM already dispatched
325 IN EFI_PEI_SERVICES
**PeiServices
,
326 IN UINT8 CurrentPeim
,
327 OUT UINT32
*DispatchedPeimBitMap
333 This routine sets a PEIM as having been dispatched once its entry
334 point has been invoked.
338 PeiServices - The PEI core services table.
339 CurrentPeim - The PEIM/FV in the bit array to check.
340 DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
350 IN EFI_PEI_SERVICES
**PeiServices
,
351 IN VOID
*CurrentPeimAddress
357 This routine parses the Dependency Expression, if available, and
358 decides if the module can be executed.
361 PeiServices - The PEI Service Table
362 CurrentPeimAddress - Address of the PEIM Firmware File under investigation
365 TRUE - Can be dispatched
366 FALSE - Cannot be dispatched
371 #if defined (MDE_CPU_IPF)
373 // In Ipf we should make special changes for the PHIT pointers to support
374 // recovery boot in cache mode.
376 #define SWITCH_TO_CACHE_MODE(CoreData) SwitchToCacheMode(CoreData)
377 #define CACHE_MODE_ADDRESS_MASK 0x7FFFFFFFFFFFFFFFULL
380 IN PEI_CORE_INSTANCE
*CoreData
386 Switch the PHIT pointers to cache mode after InstallPeiMemory in CAR.
390 CoreData - The PEI core Private Data
399 #define SWITCH_TO_CACHE_MODE(CoreData)
404 // PPI support functions
407 InitializePpiServices (
408 IN EFI_PEI_SERVICES
**PeiServices
,
409 IN PEI_CORE_INSTANCE
*OldCoreData
415 Initialize PPI services.
419 PeiServices - The PEI core services table.
420 OldCoreData - Pointer to the PEI Core data.
421 NULL if being run in non-permament memory mode.
431 IN EFI_PEI_SERVICES
**PeiServices
,
432 IN EFI_HOB_HANDOFF_INFO_TABLE
*OldHandOffHob
,
433 IN EFI_HOB_HANDOFF_INFO_TABLE
*NewHandOffHob
439 Migrate the Hob list from the CAR stack to PEI installed memory.
443 PeiServices - The PEI core services table.
444 OldHandOffHob - The old handoff HOB list.
445 NewHandOffHob - The new handoff HOB list.
455 IN EFI_PEI_SERVICES
**PeiServices
,
456 IN EFI_PEI_PPI_DESCRIPTOR
*PpiList
462 Install PPI services.
466 PeiServices - Pointer to the PEI Service Table
467 PpiList - Pointer to a list of PEI PPI Descriptors.
471 EFI_SUCCESS - if all PPIs in PpiList are successfully installed.
472 EFI_INVALID_PARAMETER - if PpiList is NULL pointer
473 EFI_INVALID_PARAMETER - if any PPI in PpiList is not valid
474 EFI_OUT_OF_RESOURCES - if there is no more memory resource to install PPI
482 IN EFI_PEI_SERVICES
**PeiServices
,
483 IN EFI_PEI_PPI_DESCRIPTOR
*OldPpi
,
484 IN EFI_PEI_PPI_DESCRIPTOR
*NewPpi
490 Re-Install PPI services.
494 PeiServices - Pointer to the PEI Service Table
495 OldPpi - Pointer to the old PEI PPI Descriptors.
496 NewPpi - Pointer to the new PEI PPI Descriptors.
500 EFI_SUCCESS - if the operation was successful
501 EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL
502 EFI_INVALID_PARAMETER - if NewPpi is not valid
503 EFI_NOT_FOUND - if the PPI was not in the database
511 IN EFI_PEI_SERVICES
**PeiServices
,
514 IN OUT EFI_PEI_PPI_DESCRIPTOR
**PpiDescriptor
,
521 Locate a given named PPI.
525 PeiServices - Pointer to the PEI Service Table
526 Guid - Pointer to GUID of the PPI.
527 Instance - Instance Number to discover.
528 PpiDescriptor - Pointer to reference the found descriptor. If not NULL,
529 returns a pointer to the descriptor (includes flags, etc)
530 Ppi - Pointer to reference the found PPI
534 Status - EFI_SUCCESS if the PPI is in the database
535 EFI_NOT_FOUND if the PPI is not in the database
542 IN EFI_PEI_SERVICES
**PeiServices
,
543 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyList
549 Install a notification for a given PPI.
553 PeiServices - Pointer to the PEI Service Table
554 NotifyList - Pointer to list of Descriptors to notify upon.
558 Status - EFI_SUCCESS if successful
559 EFI_OUT_OF_RESOURCES if no space in the database
560 EFI_INVALID_PARAMETER if not a good decriptor
567 IN EFI_PEI_SERVICES
**PeiServices
573 Process the Notify List at dispatch level.
577 PeiServices - Pointer to the PEI Service Table
586 IN EFI_PEI_SERVICES
**PeiServices
,
588 IN INTN InstallStartIndex
,
589 IN INTN InstallStopIndex
,
590 IN INTN NotifyStartIndex
,
591 IN INTN NotifyStopIndex
597 Dispatch notifications.
601 PeiServices - Pointer to the PEI Service Table
602 NotifyType - Type of notify to fire.
603 InstallStartIndex - Install Beginning index.
604 InstallStopIndex - Install Ending index.
605 NotifyStartIndex - Notify Beginning index.
606 NotifyStopIndex - Notify Ending index.
614 // Boot mode support functions
619 IN EFI_PEI_SERVICES
**PeiServices
,
620 IN OUT EFI_BOOT_MODE
*BootMode
626 This service enables PEIMs to ascertain the present value of the boot mode.
630 PeiServices - The PEI core services table.
631 BootMode - A pointer to contain the value of the boot mode.
635 EFI_SUCCESS - The boot mode was returned successfully.
636 EFI_INVALID_PARAMETER - BootMode is NULL.
644 IN EFI_PEI_SERVICES
**PeiServices
,
645 IN EFI_BOOT_MODE BootMode
651 This service enables PEIMs to update the boot mode variable.
655 PeiServices - The PEI core services table.
656 BootMode - The value of the boot mode to set.
660 EFI_SUCCESS - The value was successfully updated
666 // Security support functions
669 InitializeSecurityServices (
670 IN EFI_PEI_SERVICES
**PeiServices
,
671 IN PEI_CORE_INSTANCE
*OldCoreData
677 Initialize the security services.
681 PeiServices - The PEI core services table.
682 OldCoreData - Pointer to the old core data.
683 NULL if being run in non-permament memory mode.
693 IN EFI_FIRMWARE_VOLUME_HEADER
*CurrentFvAddress
699 Provide a callout to the OEM FV verification service.
703 CurrentFvAddress - Pointer to the FV under investigation.
715 IN EFI_PEI_SERVICES
**PeiServices
,
716 IN EFI_FFS_FILE_HEADER
*CurrentPeimAddress
722 Provide a callout to the security verification service.
726 PeiServices - The PEI core services table.
727 CurrentPeimAddress - Pointer to the Firmware File under investigation.
731 EFI_SUCCESS - Image is OK
732 EFI_SECURITY_VIOLATION - Image is illegal
741 IN EFI_PEI_SERVICES
**PeiServices
,
742 IN OUT VOID
**HobList
748 Gets the pointer to the HOB List.
752 PeiServices - The PEI core services table.
753 HobList - Pointer to the HOB List.
757 EFI_SUCCESS - Get the pointer of HOB List
758 EFI_NOT_AVAILABLE_YET - the HOB List is not yet published
759 EFI_INVALID_PARAMETER - HobList is NULL (in debug mode)
767 IN EFI_PEI_SERVICES
**PeiServices
,
776 Add a new HOB to the HOB List.
780 PeiServices - The PEI core services table.
781 Type - Type of the new HOB.
782 Length - Length of the new HOB to allocate.
783 Hob - Pointer to the new HOB.
788 - EFI_INVALID_PARAMETER if Hob is NULL
789 - EFI_NOT_AVAILABLE_YET if HobList is still not available.
790 - EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.
796 PeiCoreBuildHobHandoffInfoTable (
797 IN EFI_BOOT_MODE BootMode
,
798 IN EFI_PHYSICAL_ADDRESS MemoryBegin
,
799 IN UINT64 MemoryLength
805 Builds a Handoff Information Table HOB
809 BootMode - Current Bootmode
810 MemoryBegin - Start Memory Address.
811 MemoryLength - Length of Memory.
822 // FFS Fw Volume support functions
827 IN EFI_PEI_SERVICES
**PeiServices
,
829 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
,
830 IN OUT EFI_FFS_FILE_HEADER
**FileHeader
835 Given the input file pointer, search for the next matching file in the
836 FFS volume as defined by SearchType. The search starts from FileHeader inside
837 the Firmware Volume defined by FwVolHeader.
840 PeiServices - Pointer to the PEI Core Services Table.
842 SearchType - Filter to find only files of this type.
843 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
845 FwVolHeader - Pointer to the FV header of the volume to search.
846 This parameter must point to a valid FFS volume.
848 FileHeader - Pointer to the current file from which to begin searching.
849 This pointer will be updated upon return to reflect the file found.
852 EFI_NOT_FOUND - No files matching the search criteria were found
860 PeiFfsFindSectionData (
861 IN EFI_PEI_SERVICES
**PeiServices
,
862 IN EFI_SECTION_TYPE SectionType
,
863 IN EFI_FFS_FILE_HEADER
*FfsFileHeader
,
864 IN OUT VOID
**SectionData
869 Given the input file pointer, search for the next matching section in the
873 PeiServices - Pointer to the PEI Core Services Table.
874 SearchType - Filter to find only sections of this type.
875 FfsFileHeader - Pointer to the current file to search.
876 SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
877 - NULL if section not found
880 EFI_NOT_FOUND - No files matching the search criteria were found
888 PeiFvFindNextVolume (
889 IN EFI_PEI_SERVICES
**PeiServices
,
891 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**FwVolHeader
897 Return the BFV location
899 BugBug -- Move this to the location of this code to where the
900 other FV and FFS support code lives.
901 Also, update to use FindFV for instances #'s >= 1.
905 PeiServices - The PEI core services table.
906 Instance - Instance of FV to find
907 FwVolHeader - Pointer to contain the data to return
910 Pointer to the Firmware Volume instance requested
912 EFI_INVALID_PARAMETER - FwVolHeader is NULL
914 EFI_SUCCESS - Firmware volume instance successfully found.
920 // Memory support functions
923 InitializeMemoryServices (
924 IN EFI_PEI_SERVICES
**PeiServices
,
925 IN EFI_PEI_STARTUP_DESCRIPTOR
*PeiStartupDescriptor
,
926 IN PEI_CORE_INSTANCE
*OldCoreData
932 Initialize the memory services.
936 PeiServices - The PEI core services table.
937 PeiStartupDescriptor - Information and services provided by SEC phase.
938 OldCoreData - Pointer to the PEI Core data.
939 NULL if being run in non-permament memory mode.
950 PeiInstallPeiMemory (
951 IN EFI_PEI_SERVICES
**PeiServices
,
952 IN EFI_PHYSICAL_ADDRESS MemoryBegin
,
953 IN UINT64 MemoryLength
959 Install the permanent memory is now available.
960 Creates HOB (PHIT and Stack).
964 PeiServices - The PEI core services table.
965 MemoryBegin - Start of memory address.
966 MemoryLength - Length of memory.
978 IN EFI_PEI_SERVICES
**PeiServices
,
979 IN EFI_MEMORY_TYPE MemoryType
,
981 OUT EFI_PHYSICAL_ADDRESS
*Memory
987 Memory allocation service on permanent memory,
988 not usable prior to the memory installation.
992 PeiServices - The PEI core services table.
993 Type - Type of allocation.
994 MemoryType - Type of memory to allocate.
995 Pages - Number of pages to allocate.
996 Memory - Pointer of memory allocated.
1000 Status - EFI_SUCCESS The allocation was successful
1001 EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.
1002 EFI_NOT_AVAILABLE_YET Called with permanent memory not available
1003 EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement
1004 to allocate the number of pages.
1012 IN EFI_PEI_SERVICES
**PeiServices
,
1018 Routine Description:
1020 Memory allocation service on the CAR.
1024 PeiServices - The PEI core services table.
1026 Size - Amount of memory required
1028 Buffer - Address of pointer to the buffer
1032 Status - EFI_SUCCESS The allocation was successful
1033 EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
1034 to allocate the requested size.
1041 IN EFI_PEI_SERVICES
**PeiServices
,
1042 IN EFI_FFS_FILE_HEADER
*PeimFileHeader
,
1043 OUT VOID
**EntryPoint
1047 Routine Description:
1049 Get entry point of a Peim file.
1053 PeiServices - Calling context.
1055 PeimFileHeader - Peim file's header.
1057 EntryPoint - Entry point of that Peim file.
1069 PeiReportStatusCode (
1070 IN EFI_PEI_SERVICES
**PeiServices
,
1071 IN EFI_STATUS_CODE_TYPE CodeType
,
1072 IN EFI_STATUS_CODE_VALUE Value
,
1074 IN EFI_GUID
*CallerId
,
1075 IN EFI_STATUS_CODE_DATA
*Data OPTIONAL
1079 Routine Description:
1081 Core version of the Status Code reporter
1085 PeiServices - The PEI core services table.
1087 CodeType - Type of Status Code.
1089 Value - Value to output for Status Code.
1091 Instance - Instance Number of this status code.
1093 CallerId - ID of the caller of this status code.
1095 Data - Optional data associated with this status code.
1099 Status - EFI_SUCCESS if status code is successfully reported
1100 - EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed
1109 IN EFI_PEI_SERVICES
**PeiServices
1113 Routine Description:
1115 Core version of the Reset System
1119 PeiServices - The PEI core services table.
1123 Status - EFI_NOT_AVAILABLE_YET. PPI not available yet.
1124 - EFI_DEVICE_ERROR. Did not reset system.
1126 Otherwise, resets the system.
1132 Transfers control to a function starting with a new stack.
1134 Transfers control to the function specified by EntryPoint using the new stack
1135 specified by NewStack and passing in the parameters specified by Context1 and
1136 Context2. Context1 and Context2 are optional and may be NULL. The function
1137 EntryPoint must never return.
1139 If EntryPoint is NULL, then ASSERT().
1140 If NewStack is NULL, then ASSERT().
1142 @param EntryPoint A pointer to function to call with the new stack.
1143 @param Context1 A pointer to the context to pass into the EntryPoint
1145 @param Context2 A pointer to the context to pass into the EntryPoint
1147 @param NewStack A pointer to the new stack to use for the EntryPoint
1149 @param NewBsp A pointer to the new BSP for the EntryPoint on IPF. It's
1150 Reserved on other architectures.
1156 IN SWITCH_STACK_ENTRY_POINT EntryPoint
,
1157 IN VOID
*Context1
, OPTIONAL
1158 IN VOID
*Context2
, OPTIONAL