Add PeiCore module for enabling NT32Pkg, please attention this PeiCore does follows PI specification except some FV definitions.

Also the old definition of MdeModulePkg/Include/Ppi/LoadFile.h and EFI_PEI_STARTUP_DESCRIPTOR in MdePkg/Include/PiPei.h will be removed when enabling PI.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3029 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
klu2 2007-07-04 07:51:48 +00:00
parent 6afbfebff4
commit 192f6d4c29
30 changed files with 5619 additions and 12 deletions

View File

@ -22,12 +22,6 @@
#include <PiPei.h>
typedef struct {
UINTN BootFirmwareVolume;
UINTN SizeOfCacheAsRam;
EFI_PEI_PPI_DESCRIPTOR *DispatchTable;
} EFI_PEI_STARTUP_DESCRIPTOR;
#include <Common/FrameworkFirmwareFileSystem.h>
#include <Common/FrameworkHob.h>
#include <Common/FrameworkLegacy16.h>

View File

@ -0,0 +1,111 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
BootMode.c
Abstract:
EFI PEI Core Boot Mode services
Revision History
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <PeiMain.h>
EFI_STATUS
EFIAPI
PeiGetBootMode (
IN EFI_PEI_SERVICES **PeiServices,
OUT EFI_BOOT_MODE *BootMode
)
/*++
Routine Description:
This service enables PEIMs to ascertain the present value of the boot mode.
Arguments:
PeiServices - The PEI core services table.
BootMode - A pointer to contain the value of the boot mode.
Returns:
EFI_SUCCESS - The boot mode was returned successfully.
EFI_INVALID_PARAMETER - BootMode is NULL.
--*/
{
PEI_CORE_INSTANCE *PrivateData;
EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
if (BootMode == NULL) {
return EFI_INVALID_PARAMETER;
}
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
HandOffHob = (PrivateData->HobList.HandoffInformationTable);
*BootMode = HandOffHob->BootMode;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
PeiSetBootMode (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_BOOT_MODE BootMode
)
/*++
Routine Description:
This service enables PEIMs to update the boot mode variable.
Arguments:
PeiServices - The PEI core services table.
BootMode - The value of the boot mode to set.
Returns:
EFI_SUCCESS - The value was successfully updated
--*/
{
PEI_CORE_INSTANCE *PrivateData;
EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
HandOffHob = (PrivateData->HobList.HandoffInformationTable);
HandOffHob->BootMode = BootMode;
return EFI_SUCCESS;
}

View File

@ -0,0 +1,44 @@
/**@file
Common header file shared by all source files.
This file includes package header files, library classes and protocol, PPI & GUID definitions.
Copyright (c) 2006 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef __COMMON_HEADER_H_
#define __COMMON_HEADER_H_
#include <PiPei.h>
#include <FrameworkPei.h>
//
// The protocols, PPI and GUID defintions for this module
//
#include <Ppi/DxeIpl.h>
#include <Ppi/MemoryDiscovered.h>
#include <Ppi/FindFv.h>
#include <Ppi/StatusCode.h>
#include <Ppi/Security.h>
#include <Ppi/Reset.h>
#include <Ppi/LoadFile.h>
//
// The Library classes this module consumes
//
#include <Library/DebugLib.h>
#include <Library/PeiCoreEntryPoint.h>
#include <Library/BaseLib.h>
#include <Library/HobLib.h>
#include <Library/PerformanceLib.h>
#include <Library/PeiServicesLib.h>
#include <Library/ReportStatusCodeLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/TimerLib.h>
#endif

View File

@ -0,0 +1,267 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
dependency.c
Abstract:
PEI Dispatcher Dependency Evaluator
This routine evaluates a dependency expression (DEPENDENCY_EXPRESSION) to determine
if a driver can be scheduled for execution. The criteria for
schedulability is that the dependency expression is satisfied.
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <PeiMain.h>
#include "dependency.h"
STATIC
BOOLEAN
IsPpiInstalled (
IN EFI_PEI_SERVICES **PeiServices,
IN EVAL_STACK_ENTRY *Stack
)
/*++
Routine Description:
This routine determines if a PPI has been installed.
The truth value of a GUID is determined by if the PPI has
been published and can be queried from the PPI database.
Arguments:
PeiServices - The PEI core services table.
Stack - Reference to EVAL_STACK_ENTRY that contains PPI GUID to check
Returns:
True if the PPI is already installed.
False if the PPI has yet to be installed.
--*/
{
VOID *PeiInstance;
EFI_STATUS Status;
EFI_GUID PpiGuid;
//
// If there is no GUID to evaluate, just return current result on stack.
//
if (Stack->Operator == NULL) {
return Stack->Result;
}
//
// Copy the Guid into a locale variable so that there are no
// possibilities of alignment faults for cross-compilation
// environments such as Intel?Itanium(TM).
//
CopyMem(&PpiGuid, Stack->Operator, sizeof(EFI_GUID));
//
// Check if the PPI is installed.
//
Status = PeiServicesLocatePpi(
&PpiGuid, // GUID
0, // INSTANCE
NULL, // EFI_PEI_PPI_DESCRIPTOR
&PeiInstance // PPI
);
if (EFI_ERROR(Status)) {
return FALSE;
}
return TRUE;
}
EFI_STATUS
PeimDispatchReadiness (
IN EFI_PEI_SERVICES **PeiServices,
IN VOID *DependencyExpression,
OUT BOOLEAN *Runnable
)
/*++
Routine Description:
This is the POSTFIX version of the dependency evaluator. When a
PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on
the evaluation stack. When that entry is poped from the evaluation
stack, the PPI is checked if it is installed. This method allows
some time savings as not all PPIs must be checked for certain
operation types (AND, OR).
Arguments:
PeiServices - Calling context.
DependencyExpression - Pointer to a dependency expression. The Grammar adheres to
the BNF described above and is stored in postfix notation.
Runnable - is True if the driver can be scheduled and False if the driver
cannot be scheduled. This is the value that the schedulers
should use for deciding the state of the driver.
Returns:
Status = EFI_SUCCESS if it is a well-formed Grammar
EFI_INVALID_PARAMETER if the dependency expression overflows
the evaluation stack
EFI_INVALID_PARAMETER if the dependency expression underflows
the evaluation stack
EFI_INVALID_PARAMETER if the dependency expression is not a
well-formed Grammar.
--*/
{
DEPENDENCY_EXPRESSION_OPERAND *Iterator;
EVAL_STACK_ENTRY *StackPtr;
EVAL_STACK_ENTRY EvalStack[MAX_GRAMMAR_SIZE];
Iterator = DependencyExpression;
*Runnable = FALSE;
StackPtr = &EvalStack[0];
while (TRUE) {
switch (*(Iterator++)) {
//
// For performance reason we put the frequently used items in front of
// the rarely used items
//
case (EFI_DEP_PUSH):
//
// Check to make sure the dependency grammar doesn't overflow the
// EvalStack on the push
//
if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {
return EFI_INVALID_PARAMETER;
}
//
// Push the pointer to the PUSH opcode operator (pointer to PPI GUID)
// We will evaluate if the PPI is insalled on the POP operation.
//
StackPtr->Operator = (VOID *) Iterator;
Iterator = Iterator + sizeof (EFI_GUID);
StackPtr++;
break;
case (EFI_DEP_AND):
case (EFI_DEP_OR):
//
// Check to make sure the dependency grammar doesn't underflow the
// EvalStack on the two POPs for the AND operation. Don't need to
// check for the overflow on PUSHing the result since we already
// did two POPs.
//
if (StackPtr < &EvalStack[2]) {
return EFI_INVALID_PARAMETER;
}
//
// Evaluate the first POPed operator only. If the operand is
// EFI_DEP_AND and the POPed operator evaluates to FALSE, or the
// operand is EFI_DEP_OR and the POPed operator evaluates to TRUE,
// we don't need to check the second operator, and the result will be
// evaluation of the POPed operator. Otherwise, don't POP the second
// operator since it will now evaluate to the final result on the
// next operand that causes a POP.
//
StackPtr--;
//
// Iterator has increased by 1 after we retrieve the operand, so here we
// should get the value pointed by (Iterator - 1), in order to obtain the
// same operand.
//
if (*(Iterator - 1) == EFI_DEP_AND) {
if (!(IsPpiInstalled (PeiServices, StackPtr))) {
(StackPtr-1)->Result = FALSE;
(StackPtr-1)->Operator = NULL;
}
} else {
if (IsPpiInstalled (PeiServices, StackPtr)) {
(StackPtr-1)->Result = TRUE;
(StackPtr-1)->Operator = NULL;
}
}
break;
case (EFI_DEP_END):
StackPtr--;
//
// Check to make sure EvalStack is balanced. If not, then there is
// an error in the dependency grammar, so return EFI_INVALID_PARAMETER.
//
if (StackPtr != &EvalStack[0]) {
return EFI_INVALID_PARAMETER;
}
*Runnable = IsPpiInstalled (PeiServices, StackPtr);
return EFI_SUCCESS;
break;
case (EFI_DEP_NOT):
//
// Check to make sure the dependency grammar doesn't underflow the
// EvalStack on the POP for the NOT operation. Don't need to
// check for the overflow on PUSHing the result since we already
// did a POP.
//
if (StackPtr < &EvalStack[1]) {
return EFI_INVALID_PARAMETER;
}
(StackPtr-1)->Result = (BOOLEAN) !IsPpiInstalled (PeiServices, (StackPtr-1));
(StackPtr-1)->Operator = NULL;
break;
case (EFI_DEP_TRUE):
case (EFI_DEP_FALSE):
//
// Check to make sure the dependency grammar doesn't overflow the
// EvalStack on the push
//
if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {
return EFI_INVALID_PARAMETER;
}
//
// Iterator has increased by 1 after we retrieve the operand, so here we
// should get the value pointed by (Iterator - 1), in order to obtain the
// same operand.
//
if (*(Iterator - 1) == EFI_DEP_TRUE) {
StackPtr->Result = TRUE;
} else {
StackPtr->Result = FALSE;
}
StackPtr->Operator = NULL;
StackPtr++;
break;
default:
//
// The grammar should never arrive here
//
return EFI_INVALID_PARAMETER;
break;
}
}
}

View File

@ -0,0 +1,43 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
dependency.h
Abstract:
This module contains data specific to dependency expressions
and local function prototypes.
--*/
#ifndef _PEI_DEPENDENCY_H_
#define _PEI_DEPENDENCY_H_
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#define MAX_GRAMMAR_SIZE 256
//
// type definitions
//
typedef UINT8 DEPENDENCY_EXPRESSION_OPERAND;
typedef struct {
BOOLEAN Result;
VOID *Operator;
} EVAL_STACK_ENTRY;
#endif

View File

@ -0,0 +1,543 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Dispatcher.c
Abstract:
EFI PEI Core dispatch services
Revision History
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <PeiMain.h>
STATIC
VOID *
TransferOldDataToNewDataRange (
IN PEI_CORE_INSTANCE *PrivateData
);
EFI_STATUS
PeiDispatcher (
IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
IN PEI_CORE_INSTANCE *PrivateData,
IN PEI_CORE_DISPATCH_DATA *DispatchData
)
/*++
Routine Description:
Conduct PEIM dispatch.
Arguments:
PeiStartupDescriptor - Pointer to IN EFI_PEI_STARTUP_DESCRIPTOR
PrivateData - Pointer to the private data passed in from caller
DispatchData - Pointer to PEI_CORE_DISPATCH_DATA data.
Returns:
EFI_SUCCESS - Successfully dispatched PEIM.
EFI_NOT_FOUND - The dispatch failed.
--*/
{
EFI_STATUS Status;
PEI_CORE_TEMP_POINTERS TempPtr;
UINTN PrivateDataInMem;
BOOLEAN NextFvFound;
EFI_FIRMWARE_VOLUME_HEADER *NextFvAddress;
EFI_FIRMWARE_VOLUME_HEADER *DefaultFvAddress;
VOID *TopOfStack;
//
// Debug data for uninstalled Peim list
//
EFI_GUID DebugFoundPeimList[32];
EFI_DEVICE_HANDLE_EXTENDED_DATA ExtendedData;
//
// save the Current FV Address so that we will not process it again if FindFv returns it later
//
DefaultFvAddress = DispatchData->BootFvAddress;
//
// This is the main dispatch loop. It will search known FVs for PEIMs and
// attempt to dispatch them. If any PEIM gets dispatched through a single
// pass of the dispatcher, it will start over from the Bfv again to see
// if any new PEIMs dependencies got satisfied. With a well ordered
// FV where PEIMs are found in the order their dependencies are also
// satisfied, this dipatcher should run only once.
//
for (;;) {
//
// This is the PEIM search loop. It will scan through all PEIMs it can find
// looking for PEIMs to dispatch, and will dipatch them if they have not
// already been dispatched and all of their dependencies are met.
// If no more PEIMs can be found in this pass through all known FVs,
// then it will break out of this loop.
//
for (;;) {
Status = FindNextPeim (
&PrivateData->PS,
DispatchData->CurrentFvAddress,
&DispatchData->CurrentPeimAddress
);
//
// If we found a PEIM, check if it is dispatched. If so, go to the
// next PEIM. If not, dispatch it if its dependencies are satisfied.
// If its dependencies are not satisfied, go to the next PEIM.
//
if (Status == EFI_SUCCESS) {
DEBUG_CODE_BEGIN ();
//
// Fill list of found Peims for later list of those not installed
//
CopyMem (
&DebugFoundPeimList[DispatchData->CurrentPeim],
&DispatchData->CurrentPeimAddress->Name,
sizeof (EFI_GUID)
);
DEBUG_CODE_END ();
if (!Dispatched (
DispatchData->CurrentPeim,
DispatchData->DispatchedPeimBitMap
)) {
if (DepexSatisfied (&PrivateData->PS, DispatchData->CurrentPeimAddress)) {
Status = PeiLoadImage (
&PrivateData->PS,
DispatchData->CurrentPeimAddress,
&TempPtr.Raw
);
if (Status == EFI_SUCCESS) {
//
// The PEIM has its dependencies satisfied, and its entry point
// has been found, so invoke it.
//
PERF_START (
(VOID *) (UINTN) (DispatchData->CurrentPeimAddress),
"PEIM",
NULL,
0
);
//
// BUGBUG: Used to be EFI_PEI_REPORT_STATUS_CODE_CODE
//
ExtendedData.Handle = (EFI_HANDLE)DispatchData->CurrentPeimAddress;
REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
EFI_PROGRESS_CODE,
EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN,
(VOID *)(&ExtendedData),
sizeof (ExtendedData)
);
//
// Is this a authentic image
//
Status = VerifyPeim (
&PrivateData->PS,
DispatchData->CurrentPeimAddress
);
if (Status != EFI_SECURITY_VIOLATION) {
//
// BUGBUG: Before enable PI, we need cast EFI_FFS_FILE_HEADER* to EFI_PEI_FILE_HANDLE*
// Because we use new MdePkg's definition, but they are binary compatible in fact.
//
Status = TempPtr.PeimEntry (
(EFI_PEI_FILE_HANDLE*)DispatchData->CurrentPeimAddress,
&PrivateData->PS
);
}
REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
EFI_PROGRESS_CODE,
EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END,
(VOID *)(&ExtendedData),
sizeof (ExtendedData)
);
PERF_END ((VOID *) (UINTN) (DispatchData->CurrentPeimAddress), "PEIM", NULL, 0);
//
// Mark the PEIM as dispatched so we don't attempt to run it again
//
SetDispatched (
&PrivateData->PS,
DispatchData->CurrentPeim,
&DispatchData->DispatchedPeimBitMap
);
//
// Process the Notify list and dispatch any notifies for
// newly installed PPIs.
//
ProcessNotifyList (&PrivateData->PS);
//
// If real system memory was discovered and installed by this
// PEIM, switch the stacks to the new memory. Since we are
// at dispatch level, only the Core's private data is preserved,
// nobody else should have any data on the stack.
//
if (PrivateData->SwitchStackSignal) {
TempPtr.PeiCore = (PEI_CORE_ENTRY_POINT)PeiCore;
PrivateDataInMem = (UINTN) TransferOldDataToNewDataRange (PrivateData);
ASSERT (PrivateDataInMem != 0);
//
// Adjust the top of stack to be aligned at CPU_STACK_ALIGNMENT
//
TopOfStack = (VOID *)((UINTN)PrivateData->StackBase + (UINTN)PrivateData->StackSize - CPU_STACK_ALIGNMENT);
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
PeiSwitchStacks (
(SWITCH_STACK_ENTRY_POINT)(UINTN)TempPtr.Raw,
PeiStartupDescriptor,
(VOID*)PrivateDataInMem,
TopOfStack,
(VOID*)(UINTN)PrivateData->StackBase
);
}
}
}
}
DispatchData->CurrentPeim++;
continue;
} else {
//
// If we could not find another PEIM in the current FV, go try
// the FindFv PPI to look in other FVs for more PEIMs. If we can
// not locate the FindFv PPI, or if the FindFv PPI can not find
// anymore FVs, then exit the PEIM search loop.
//
if (DispatchData->FindFv == NULL) {
Status = PeiServicesLocatePpi (
&gEfiFindFvPpiGuid,
0,
NULL,
(VOID **)&DispatchData->FindFv
);
if (Status != EFI_SUCCESS) {
break;
}
}
NextFvFound = FALSE;
while (!NextFvFound) {
Status = DispatchData->FindFv->FindFv (
DispatchData->FindFv,
&PrivateData->PS,
&DispatchData->CurrentFv,
&NextFvAddress
);
//
// if there is no next fv, get out of this loop of finding FVs
//
if (Status != EFI_SUCCESS) {
break;
}
//
// don't process the default Fv again. (we don't know the order in which the hobs were created)
//
if ((NextFvAddress != DefaultFvAddress) &&
(NextFvAddress != DispatchData->CurrentFvAddress)) {
//
// VerifyFv() is currently returns SUCCESS all the time, add code to it to
// actually verify the given FV
//
Status = VerifyFv (NextFvAddress);
if (Status == EFI_SUCCESS) {
NextFvFound = TRUE;
DispatchData->CurrentFvAddress = NextFvAddress;
DispatchData->CurrentPeimAddress = NULL;
//
// current PRIM number (CurrentPeim) must continue as is, don't reset it here
//
}
}
}
//
// if there is no next fv, get out of this loop of dispatching PEIMs
//
if (!NextFvFound) {
break;
}
//
// continue in the inner for(;;) loop with a new FV;
//
}
}
//
// If all the PEIMs that we have found have been dispatched, then
// there is nothing left to dispatch and we don't need to go search
// through all PEIMs again.
//
if ((~(DispatchData->DispatchedPeimBitMap) &
((1 << DispatchData->CurrentPeim)-1)) == 0) {
break;
}
//
// Check if no more PEIMs that depex was satisfied
//
if (DispatchData->DispatchedPeimBitMap == DispatchData->PreviousPeimBitMap) {
break;
}
//
// Case when Depex is not satisfied and has to traverse the list again
//
DispatchData->CurrentPeim = 0;
DispatchData->CurrentPeimAddress = 0;
DispatchData->PreviousPeimBitMap = DispatchData->DispatchedPeimBitMap;
//
// don't go back to the loop without making sure that the CurrentFvAddress is the
// same as the 1st (or default) FV we started with. otherwise we will interpret the bimap wrongly and
// mess it up, always start processing the PEIMs from the default FV just like in the first time around.
//
DispatchData->CurrentFv = 0;
DispatchData->CurrentFvAddress = DefaultFvAddress;
}
DEBUG_CODE_BEGIN ();
//
// Debug data for uninstalled Peim list
//
UINT32 DebugNotDispatchedBitmap;
UINT8 DebugFoundPeimPoint;
DebugFoundPeimPoint = 0;
//
// Get bitmap of Peims that were not dispatched,
//
DebugNotDispatchedBitmap = ((DispatchData->DispatchedPeimBitMap) ^ ((1 << DispatchData->CurrentPeim)-1));
//
// Scan bitmap of Peims not installed and print GUIDS
//
while (DebugNotDispatchedBitmap != 0) {
if ((DebugNotDispatchedBitmap & 1) != 0) {
DEBUG ((EFI_D_INFO, "WARNING -> InstallPpi: Not Installed: %g\n",
&DebugFoundPeimList[DebugFoundPeimPoint]
));
}
DebugFoundPeimPoint++;
DebugNotDispatchedBitmap >>= 1;
}
DEBUG_CODE_END ();
return EFI_NOT_FOUND;
}
VOID
InitializeDispatcherData (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_CORE_INSTANCE *OldCoreData,
IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor
)
/*++
Routine Description:
Initialize the Dispatcher's data members
Arguments:
PeiServices - The PEI core services table.
OldCoreData - Pointer to old core data (before switching stack).
NULL if being run in non-permament memory mode.
PeiStartupDescriptor - Information and services provided by SEC phase.
Returns:
None.
--*/
{
PEI_CORE_INSTANCE *PrivateData;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
if (OldCoreData == NULL) {
PrivateData->DispatchData.CurrentFvAddress = (EFI_FIRMWARE_VOLUME_HEADER *) PeiStartupDescriptor->BootFirmwareVolume;
PrivateData->DispatchData.BootFvAddress = (EFI_FIRMWARE_VOLUME_HEADER *) PeiStartupDescriptor->BootFirmwareVolume;
} else {
//
// Current peim has been dispatched, but not count
//
PrivateData->DispatchData.CurrentPeim = (UINT8)(OldCoreData->DispatchData.CurrentPeim + 1);
}
return;
}
BOOLEAN
Dispatched (
IN UINT8 CurrentPeim,
IN UINT32 DispatchedPeimBitMap
)
/*++
Routine Description:
This routine checks to see if a particular PEIM has been dispatched during
the PEI core dispatch.
Arguments:
CurrentPeim - The PEIM/FV in the bit array to check.
DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
Returns:
TRUE - PEIM already dispatched
FALSE - Otherwise
--*/
{
return (BOOLEAN)((DispatchedPeimBitMap & (1 << CurrentPeim)) != 0);
}
VOID
SetDispatched (
IN EFI_PEI_SERVICES **PeiServices,
IN UINT8 CurrentPeim,
OUT UINT32 *DispatchedPeimBitMap
)
/*++
Routine Description:
This routine sets a PEIM as having been dispatched once its entry
point has been invoked.
Arguments:
PeiServices - The PEI core services table.
CurrentPeim - The PEIM/FV in the bit array to check.
DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
Returns:
None
--*/
{
//
// Check if the total number of PEIMs exceed the bitmap.
// CurrentPeim is 0-based
//
ASSERT (CurrentPeim < (sizeof (*DispatchedPeimBitMap) * 8));
*DispatchedPeimBitMap |= (1 << CurrentPeim);
return;
}
BOOLEAN
DepexSatisfied (
IN EFI_PEI_SERVICES **PeiServices,
IN VOID *CurrentPeimAddress
)
/*++
Routine Description:
This routine parses the Dependency Expression, if available, and
decides if the module can be executed.
Arguments:
PeiServices - The PEI Service Table
CurrentPeimAddress - Address of the PEIM Firmware File under investigation
Returns:
TRUE - Can be dispatched
FALSE - Cannot be dispatched
--*/
{
EFI_STATUS Status;
INT8 *DepexData;
BOOLEAN Runnable;
Status = PeiServicesFfsFindSectionData (
EFI_SECTION_PEI_DEPEX,
CurrentPeimAddress,
(VOID **)&DepexData
);
//
// If there is no DEPEX, assume the module can be executed
//
if (EFI_ERROR (Status)) {
return TRUE;
}
//
// Evaluate a given DEPEX
//
Status = PeimDispatchReadiness (
PeiServices,
DepexData,
&Runnable
);
return Runnable;
}
STATIC
VOID *
TransferOldDataToNewDataRange (
IN PEI_CORE_INSTANCE *PrivateData
)
/*++
Routine Description:
This routine transfers the contents of the pre-permanent memory
PEI Core private data to a post-permanent memory data location.
Arguments:
PrivateData - Pointer to the current PEI Core private data pre-permanent memory
Returns:
Pointer to the PrivateData once the private data has been transferred to permanent memory
--*/
{
//
//Build private HOB to PEI core to transfer old NEM-range data to new NEM-range
//
return BuildGuidDataHob (&gEfiPeiCorePrivateGuid, PrivateData, sizeof (PEI_CORE_INSTANCE));
}

View File

@ -0,0 +1,55 @@
/** @file
PeiSwitchStacks() function for PEI dispatcher.
Copyright (c) 2006, Intel Corporation<BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name: String.c
**/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
/**
Transfers control to a function starting with a new stack.
Transfers control to the function specified by EntryPoint using the new stack
specified by NewStack and passing in the parameters specified by Context1 and
Context2. Context1 and Context2 are optional and may be NULL. The function
EntryPoint must never return.
If EntryPoint is NULL, then ASSERT().
If NewStack is NULL, then ASSERT().
@param EntryPoint A pointer to function to call with the new stack.
@param Context1 A pointer to the context to pass into the EntryPoint
function.
@param Context2 A pointer to the context to pass into the EntryPoint
function.
@param NewStack A pointer to the new stack to use for the EntryPoint
function.
@param NewBsp A pointer to the new BSP for the EntryPoint on IPF. It's
Reserved on other architectures.
**/
VOID
EFIAPI
PeiSwitchStacks (
IN SWITCH_STACK_ENTRY_POINT EntryPoint,
IN VOID *Context1, OPTIONAL
IN VOID *Context2, OPTIONAL
IN VOID *NewStack,
IN VOID *NewBsp
)
{
SwitchStack (EntryPoint, Context1, Context2, NewStack);
}

View File

@ -0,0 +1,479 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
FwVol.c
Abstract:
Pei Core Firmware File System service routines.
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <PeiMain.h>
#define GETOCCUPIEDSIZE(ActualSize, Alignment) \
(ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
STATIC
EFI_FFS_FILE_STATE
GetFileState(
IN UINT8 ErasePolarity,
IN EFI_FFS_FILE_HEADER *FfsHeader
)
/*++
Routine Description:
Returns the highest bit set of the State field
Arguments:
ErasePolarity - Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
in the Attributes field.
FfsHeader - Pointer to FFS File Header.
Returns:
Returns the highest bit in the State field
--*/
{
EFI_FFS_FILE_STATE FileState;
EFI_FFS_FILE_STATE HighestBit;
FileState = FfsHeader->State;
if (ErasePolarity != 0) {
FileState = (EFI_FFS_FILE_STATE)~FileState;
}
HighestBit = 0x80;
while (HighestBit != 0 && (HighestBit & FileState) == 0) {
HighestBit >>= 1;
}
return HighestBit;
}
STATIC
UINT8
CalculateHeaderChecksum (
IN EFI_FFS_FILE_HEADER *FileHeader
)
/*++
Routine Description:
Calculates the checksum of the header of a file.
Arguments:
FileHeader - Pointer to FFS File Header.
Returns:
Checksum of the header.
The header is zero byte checksum.
- Zero means the header is good.
- Non-zero means the header is bad.
Bugbug: For PEI performance reason, we comments this code at this time.
--*/
{
UINT8 *ptr;
UINTN Index;
UINT8 Sum;
Sum = 0;
ptr = (UINT8 *)FileHeader;
for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER) - 3; Index += 4) {
Sum = (UINT8)(Sum + ptr[Index]);
Sum = (UINT8)(Sum + ptr[Index+1]);
Sum = (UINT8)(Sum + ptr[Index+2]);
Sum = (UINT8)(Sum + ptr[Index+3]);
}
for (; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {
Sum = (UINT8)(Sum + ptr[Index]);
}
//
// State field (since this indicates the different state of file).
//
Sum = (UINT8)(Sum - FileHeader->State);
//
// Checksum field of the file is not part of the header checksum.
//
Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);
return Sum;
}
STATIC
EFI_STATUS
PeiFfsFindNextFileEx (
IN EFI_FV_FILETYPE SearchType,
IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
IN OUT EFI_FFS_FILE_HEADER **FileHeader,
IN BOOLEAN Flag
)
/*++
Routine Description:
Given the input file pointer, search for the next matching file in the
FFS volume as defined by SearchType. The search starts from FileHeader inside
the Firmware Volume defined by FwVolHeader.
Arguments:
PeiServices - Pointer to the PEI Core Services Table.
SearchType - Filter to find only files of this type.
Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
FwVolHeader - Pointer to the FV header of the volume to search.
This parameter must point to a valid FFS volume.
FileHeader - Pointer to the current file from which to begin searching.
This pointer will be updated upon return to reflect the file found.
Flag - Indicator for if this is for PEI Dispath search
Returns:
EFI_NOT_FOUND - No files matching the search criteria were found
EFI_SUCCESS
--*/
{
EFI_FFS_FILE_HEADER *FfsFileHeader;
UINT32 FileLength;
UINT32 FileOccupiedSize;
UINT32 FileOffset;
UINT64 FvLength;
UINT8 ErasePolarity;
UINT8 FileState;
FvLength = FwVolHeader->FvLength;
if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
ErasePolarity = 1;
} else {
ErasePolarity = 0;
}
//
// If FileHeader is not specified (NULL) start with the first file in the
// firmware volume. Otherwise, start from the FileHeader.
//
if (*FileHeader == NULL) {
FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);
} else {
//
// Length is 24 bits wide so mask upper 8 bits
// FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
//
FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF;
FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);
}
FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);
ASSERT (FileOffset <= 0xFFFFFFFF);
while (FileOffset < (FvLength - sizeof(EFI_FFS_FILE_HEADER))) {
//
// Get FileState which is the highest bit of the State
//
FileState = GetFileState (ErasePolarity, FfsFileHeader);
switch (FileState) {
case EFI_FILE_HEADER_INVALID:
FileOffset += sizeof(EFI_FFS_FILE_HEADER);
FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));
break;
case EFI_FILE_DATA_VALID:
case EFI_FILE_MARKED_FOR_UPDATE:
if (CalculateHeaderChecksum (FfsFileHeader) == 0) {
FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
if (Flag) {
if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) ||
(FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) {
*FileHeader = FfsFileHeader;
return EFI_SUCCESS;
}
} else {
if ((SearchType == FfsFileHeader->Type) ||
(SearchType == EFI_FV_FILETYPE_ALL)) {
*FileHeader = FfsFileHeader;
return EFI_SUCCESS;
}
}
FileOffset += FileOccupiedSize;
FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
} else {
ASSERT (FALSE);
return EFI_NOT_FOUND;
}
break;
case EFI_FILE_DELETED:
FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
FileOffset += FileOccupiedSize;
FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
break;
default:
return EFI_NOT_FOUND;
}
}
return EFI_NOT_FOUND;
}
EFI_STATUS
EFIAPI
PeiFfsFindSectionData (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_SECTION_TYPE SectionType,
IN EFI_FFS_FILE_HEADER *FfsFileHeader,
IN OUT VOID **SectionData
)
/*++
Routine Description:
Given the input file pointer, search for the next matching section in the
FFS volume.
Arguments:
PeiServices - Pointer to the PEI Core Services Table.
SearchType - Filter to find only sections of this type.
FfsFileHeader - Pointer to the current file to search.
SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
- NULL if section not found
Returns:
EFI_NOT_FOUND - No files matching the search criteria were found
EFI_SUCCESS
--*/
{
UINT32 FileSize;
EFI_COMMON_SECTION_HEADER *Section;
UINT32 SectionLength;
UINT32 ParsedLength;
//
// Size is 24 bits wide so mask upper 8 bits.
// Does not include FfsFileHeader header size
// FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
//
Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);
FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
FileSize -= sizeof(EFI_FFS_FILE_HEADER);
*SectionData = NULL;
ParsedLength = 0;
while (ParsedLength < FileSize) {
if (Section->Type == SectionType) {
*SectionData = (VOID *)(Section + 1);
return EFI_SUCCESS;
}
//
// Size is 24 bits wide so mask upper 8 bits.
// SectionLength is adjusted it is 4 byte aligned.
// Go to the next section
//
SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
SectionLength = GETOCCUPIEDSIZE (SectionLength, 4);
ASSERT (SectionLength != 0);
ParsedLength += SectionLength;
Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
}
return EFI_NOT_FOUND;
}
EFI_STATUS
FindNextPeim (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
IN OUT EFI_FFS_FILE_HEADER **PeimFileHeader
)
/*++
Routine Description:
Given the input file pointer, search for the next matching file in the
FFS volume. The search starts from FileHeader inside
the Firmware Volume defined by FwVolHeader.
Arguments:
PeiServices - Pointer to the PEI Core Services Table.
FwVolHeader - Pointer to the FV header of the volume to search.
This parameter must point to a valid FFS volume.
PeimFileHeader - Pointer to the current file from which to begin searching.
This pointer will be updated upon return to reflect the file found.
Returns:
EFI_NOT_FOUND - No files matching the search criteria were found
EFI_SUCCESS
--*/
{
return PeiFfsFindNextFileEx (
0,
FwVolHeader,
PeimFileHeader,
TRUE
);
}
EFI_STATUS
EFIAPI
PeiFfsFindNextFile (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_FV_FILETYPE SearchType,
IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
IN OUT EFI_FFS_FILE_HEADER **FileHeader
)
/*++
Routine Description:
Given the input file pointer, search for the next matching file in the
FFS volume as defined by SearchType. The search starts from FileHeader inside
the Firmware Volume defined by FwVolHeader.
Arguments:
PeiServices - Pointer to the PEI Core Services Table.
SearchType - Filter to find only files of this type.
Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
FwVolHeader - Pointer to the FV header of the volume to search.
This parameter must point to a valid FFS volume.
FileHeader - Pointer to the current file from which to begin searching.
This pointer will be updated upon return to reflect the file found.
Returns:
EFI_NOT_FOUND - No files matching the search criteria were found
EFI_SUCCESS
--*/
{
return PeiFfsFindNextFileEx (
SearchType,
FwVolHeader,
FileHeader,
FALSE
);
}
EFI_STATUS
EFIAPI
PeiFvFindNextVolume (
IN EFI_PEI_SERVICES **PeiServices,
IN UINTN Instance,
IN OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader
)
/*++
Routine Description:
Return the BFV location
BugBug -- Move this to the location of this code to where the
other FV and FFS support code lives.
Also, update to use FindFV for instances #'s >= 1.
Arguments:
PeiServices - The PEI core services table.
Instance - Instance of FV to find
FwVolHeader - Pointer to contain the data to return
Returns:
Pointer to the Firmware Volume instance requested
EFI_INVALID_PARAMETER - FwVolHeader is NULL
EFI_SUCCESS - Firmware volume instance successfully found.
--*/
{
PEI_CORE_INSTANCE *PrivateData;
EFI_STATUS Status;
EFI_PEI_FIND_FV_PPI *FindFvPpi;
UINT8 LocalInstance;
LocalInstance = (UINT8) Instance;
Status = EFI_SUCCESS;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
if (FwVolHeader == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Instance == 0) {
*FwVolHeader = PrivateData->DispatchData.BootFvAddress;
return Status;
} else {
//
// Locate all instances of FindFV
// Alternately, could use FV HOBs, but the PPI is cleaner
//
Status = PeiServicesLocatePpi (
&gEfiFindFvPpiGuid,
0,
NULL,
(VOID **)&FindFvPpi
);
if (Status != EFI_SUCCESS) {
Status = EFI_NOT_FOUND;
} else {
Status = FindFvPpi->FindFv (
FindFvPpi,
PeiServices,
&LocalInstance,
FwVolHeader
);
}
}
return Status;
}

View File

@ -0,0 +1,197 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Hob.c
Abstract:
EFI PEI Core HOB services
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <PeiMain.h>
EFI_STATUS
EFIAPI
PeiGetHobList (
IN EFI_PEI_SERVICES **PeiServices,
IN OUT VOID **HobList
)
/*++
Routine Description:
Gets the pointer to the HOB List.
Arguments:
PeiServices - The PEI core services table.
HobList - Pointer to the HOB List.
Returns:
EFI_SUCCESS - Get the pointer of HOB List
EFI_NOT_AVAILABLE_YET - the HOB List is not yet published
EFI_INVALID_PARAMETER - HobList is NULL (in debug mode)
--*/
{
PEI_CORE_INSTANCE *PrivateData;
//
// Only check this parameter in debug mode
//
DEBUG_CODE_BEGIN ();
if (HobList == NULL) {
return EFI_INVALID_PARAMETER;
}
DEBUG_CODE_END ();
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
*HobList = PrivateData->HobList.Raw;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
PeiCreateHob (
IN EFI_PEI_SERVICES **PeiServices,
IN UINT16 Type,
IN UINT16 Length,
IN OUT VOID **Hob
)
/*++
Routine Description:
Add a new HOB to the HOB List.
Arguments:
PeiServices - The PEI core services table.
Type - Type of the new HOB.
Length - Length of the new HOB to allocate.
Hob - Pointer to the new HOB.
Returns:
Status - EFI_SUCCESS
- EFI_INVALID_PARAMETER if Hob is NULL
- EFI_NOT_AVAILABLE_YET if HobList is still not available.
- EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.
--*/
{
EFI_STATUS Status;
EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
EFI_HOB_GENERIC_HEADER *HobEnd;
EFI_PHYSICAL_ADDRESS FreeMemory;
Status = PeiGetHobList (PeiServices, Hob);
if (EFI_ERROR(Status)) {
return Status;
}
HandOffHob = *Hob;
Length = (UINT16)((Length + 0x7) & (~0x7));
FreeMemory = HandOffHob->EfiFreeMemoryTop -
HandOffHob->EfiFreeMemoryBottom;
if (FreeMemory < Length) {
DEBUG ((EFI_D_ERROR, "PeiCreateHob fail: Length - 0x%08x\n", (UINTN)Length));
DEBUG ((EFI_D_ERROR, " FreeMemoryTop - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryTop));
DEBUG ((EFI_D_ERROR, " FreeMemoryBottom - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryBottom));
return EFI_OUT_OF_RESOURCES;
}
*Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
((EFI_HOB_GENERIC_HEADER*) *Hob)->HobType = Type;
((EFI_HOB_GENERIC_HEADER*) *Hob)->HobLength = Length;
((EFI_HOB_GENERIC_HEADER*) *Hob)->Reserved = 0;
HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN) *Hob + Length);
HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
HobEnd->Reserved = 0;
HobEnd++;
HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
return EFI_SUCCESS;
}
EFI_STATUS
PeiCoreBuildHobHandoffInfoTable (
IN EFI_BOOT_MODE BootMode,
IN EFI_PHYSICAL_ADDRESS MemoryBegin,
IN UINT64 MemoryLength
)
/*++
Routine Description:
Builds a Handoff Information Table HOB
Arguments:
BootMode - Current Bootmode
MemoryBegin - Start Memory Address.
MemoryLength - Length of Memory.
Returns:
EFI_SUCCESS
--*/
{
EFI_HOB_HANDOFF_INFO_TABLE *Hob;
EFI_HOB_GENERIC_HEADER *HobEnd;
Hob = (VOID *)(UINTN)MemoryBegin;
HobEnd = (EFI_HOB_GENERIC_HEADER*) (Hob+1);
Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;
Hob->Header.HobLength = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
Hob->Header.Reserved = 0;
HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
HobEnd->Reserved = 0;
Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;
Hob->BootMode = BootMode;
Hob->EfiMemoryTop = MemoryBegin + MemoryLength;
Hob->EfiMemoryBottom = MemoryBegin;
Hob->EfiFreeMemoryTop = MemoryBegin + MemoryLength;
Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) (HobEnd+1);
Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
return EFI_SUCCESS;
}

View File

@ -0,0 +1,272 @@
/*++
Copyright (c) 2006 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Image.c
Abstract:
Pei Core Load Image Support
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <PeiMain.h>
EFI_STATUS
PeiLoadImage (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_FFS_FILE_HEADER *PeimFileHeader,
OUT VOID **EntryPoint
)
/*++
Routine Description:
Routine for loading file image.
Arguments:
PeiServices - The PEI core services table.
PeimFileHeader - Pointer to the FFS file header of the image.
EntryPoint - Pointer to entry point of specified image file for output.
Returns:
Status - EFI_SUCCESS - Image is successfully loaded.
EFI_NOT_FOUND - Fail to locate necessary PPI
Others - Fail to load file.
--*/
{
EFI_STATUS Status;
VOID *Pe32Data;
EFI_PEI_FV_FILE_LOADER_PPI *FvLoadFilePpi;
EFI_PHYSICAL_ADDRESS ImageAddress;
UINT64 ImageSize;
EFI_PHYSICAL_ADDRESS ImageEntryPoint;
EFI_TE_IMAGE_HEADER *TEImageHeader;
UINT16 Machine;
*EntryPoint = NULL;
TEImageHeader = NULL;
//
// Try to find a PE32 section.
//
Status = PeiServicesFfsFindSectionData (
EFI_SECTION_PE32,
PeimFileHeader,
&Pe32Data
);
//
// If we didn't find a PE32 section, try to find a TE section.
//
if (EFI_ERROR (Status)) {
Status = PeiServicesFfsFindSectionData (
EFI_SECTION_TE,
PeimFileHeader,
(VOID **) &TEImageHeader
);
if (EFI_ERROR (Status) || TEImageHeader == NULL) {
//
// There was not a PE32 or a TE section, so assume that it's a Compressed section
// and use the LoadFile
//
Status = PeiServicesLocatePpi (
&gEfiPeiFvFileLoaderPpiGuid,
0,
NULL,
(VOID **)&FvLoadFilePpi
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
Status = FvLoadFilePpi->FvLoadFile (
FvLoadFilePpi,
PeimFileHeader,
&ImageAddress,
&ImageSize,
&ImageEntryPoint
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
//
// Got the entry point from ImageEntryPoint and ImageStartAddress
//
Pe32Data = (VOID *) ((UINTN) ImageAddress);
*EntryPoint = (VOID *) ((UINTN) ImageEntryPoint);
} else {
//
// Retrieve the entry point from the TE image header
//
ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) TEImageHeader;
*EntryPoint = (VOID *)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +
TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);
}
} else {
//
// Retrieve the entry point from the PE/COFF image header
//
ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Pe32Data;
Status = PeCoffLoaderGetEntryPoint (Pe32Data, EntryPoint);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
}
if (((EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress)->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
TEImageHeader = (EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress;
Machine = TEImageHeader->Machine;
} else {
Machine = PeCoffLoaderGetMachineType (Pe32Data);
}
if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Machine)) {
return EFI_UNSUPPORTED;
}
//
// Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi
//
DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%08x EntryPoint=0x%08x ", (UINTN) ImageAddress, *EntryPoint));
DEBUG_CODE_BEGIN ();
EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
UINTN DirCount;
UINTN Index;
UINTN Index1;
BOOLEAN FileNameFound;
CHAR8 *AsciiString;
CHAR8 AsciiBuffer[512];
VOID *CodeViewEntryPointer;
INTN TEImageAdjust;
EFI_IMAGE_DOS_HEADER *DosHeader;
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
UINT32 NumberOfRvaAndSizes;
Hdr.Pe32 = NULL;
if (TEImageHeader == NULL) {
DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
//
// DOS image header is present, so read the PE header after the DOS image header
//
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHeader->e_lfanew) & 0x0ffff));
} else {
//
// DOS image header is not present, so PE header is at the image base
//
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
}
}
//
// Find the codeview info in the image and display the file name
// being loaded.
//
// Per the PE/COFF spec, you can't assume that a given data directory
// is present in the image. You have to check the NumberOfRvaAndSizes in
// the optional header to verify a desired directory entry is there.
//
DebugEntry = NULL;
DirectoryEntry = NULL;
NumberOfRvaAndSizes = 0;
TEImageAdjust = 0;
if (TEImageHeader == NULL) {
if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
// Use PE32 offset get Debug Directory Entry
//
NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;
DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);
} else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
//
// Use PE32+ offset get Debug Directory Entry
//
NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);
}
if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
DirectoryEntry = NULL;
DebugEntry = NULL;
}
} else {
if (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {
DirectoryEntry = &TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];
TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize;
DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) TEImageHeader +
TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +
TEImageAdjust);
}
}
if (DebugEntry != NULL && DirectoryEntry != NULL) {
for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) {
if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
if (DebugEntry->SizeOfData > 0) {
CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust);
switch (* (UINT32 *) CodeViewEntryPointer) {
case CODEVIEW_SIGNATURE_NB10:
AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
break;
case CODEVIEW_SIGNATURE_RSDS:
AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
break;
default:
AsciiString = NULL;
break;
}
if (AsciiString != NULL) {
FileNameFound = FALSE;
for (Index = 0, Index1 = 0; AsciiString[Index] != '\0'; Index++) {
if (AsciiString[Index] == '\\') {
Index1 = Index;
FileNameFound = TRUE;
}
}
if (FileNameFound) {
for (Index = Index1 + 1; AsciiString[Index] != '.'; Index++) {
AsciiBuffer[Index - (Index1 + 1)] = AsciiString[Index];
}
AsciiBuffer[Index - (Index1 + 1)] = 0;
DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer));
break;
}
}
}
}
}
}
DEBUG_CODE_END ();
DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));
return EFI_SUCCESS;
}

View File

@ -0,0 +1,98 @@
//++
// Copyright (c) 2006, Intel Corporation
// All rights reserved. This program and the accompanying materials
// are licensed and made available under the terms and conditions of the BSD License
// which accompanies this distribution. The full text of the license may be found at
// http://opensource.org/licenses/bsd-license.php
//
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
// Module Name:
//
// IpfCpuCore.i
//
// Abstract:
// IPF CPU definitions
//
//--
#ifndef _IPF_CPU_CORE_
#define _IPF_CPU_CORE_
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#define PEI_BSP_STORE_SIZE 0x4000
#define ResetFn 0x00
#define MachineCheckFn 0x01
#define InitFn 0x02
#define RecoveryFn 0x03
#define GuardBand 0x10
//
// Define hardware RSE Configuration Register
//
//
// RS Configuration (RSC) bit field positions
//
#define RSC_MODE 0
#define RSC_PL 2
#define RSC_BE 4
//
// RSC bits 5-15 reserved
//
#define RSC_MBZ0 5
#define RSC_MBZ0_V 0x3ff
#define RSC_LOADRS 16
#define RSC_LOADRS_LEN 14
//
// RSC bits 30-63 reserved
//
#define RSC_MBZ1 30
#define RSC_MBZ1_V 0x3ffffffffULL
//
// RSC modes
//
//
// Lazy
//
#define RSC_MODE_LY (0x0)
//
// Store intensive
//
#define RSC_MODE_SI (0x1)
//
// Load intensive
//
#define RSC_MODE_LI (0x2)
//
// Eager
//
#define RSC_MODE_EA (0x3)
//
// RSC Endian bit values
//
#define RSC_BE_LITTLE 0
#define RSC_BE_BIG 1
//
// RSC while in kernel: enabled, little endian, pl = 0, eager mode
//
#define RSC_KERNEL ((RSC_MODE_EA<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
//
// Lazy RSC in kernel: enabled, little endian, pl = 0, lazy mode
//
#define RSC_KERNEL_LAZ ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
//
// RSE disabled: disabled, pl = 0, little endian, eager mode
//
#define RSC_KERNEL_DISABLED ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
#endif

View File

@ -0,0 +1,197 @@
//
// Include common header file for this module.
//
#include "CommonHeader.h"
//++
// Copyright (c) 2006, Intel Corporation
// All rights reserved. This program and the accompanying materials
// are licensed and made available under the terms and conditions of the BSD License
// which accompanies this distribution. The full text of the license may be found at
// http://opensource.org/licenses/bsd-license.php
//
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
// Module Name:
//
// IpfCpuCore.s
//
// Abstract:
// IPF Specific assembly routines
//
//--
.file "IpfCpuCore.s"
#include "IpfMacro.i"
#include "Ipf/IpfCpuCore.i"
//----------------------------------------------------------------------------------
// This module supports terminating CAR (Cache As RAM) stage. It copies all the
// CAR data into real RAM and then makes a stack switch.
// EFI_STATUS
// SwitchCoreStacks (
// IN VOID *EntryPoint,
// IN UINTN CopySize,
// IN VOID *OldBase,
// IN VOID *NewBase
// IN UINTN NewSP, OPTIONAL
// IN UINTN NewBSP OPTIONAL
// )
// EFI_STATUS
// SwitchCoreStacks (
// IN VOID *EntryPointForContinuationFunction,
// IN UINTN StartupDescriptor,
// IN VOID PEICorePointer,
// IN UINTN NewSP
// )
//----------------------------------------------------------------------------------
PROCEDURE_ENTRY (SwitchCoreStacks)
NESTED_SETUP (4,2,0,0)
// first save all stack registers in GPRs.
mov r13 = in0;; // this is a pointer to the PLABEL of the continuation function.
ld8 r16 = [r13],8;; // r16 = address of continuation function from the PLABEL
ld8 gp = [r13];; // gp = gp of continuation function from the PLABEL
mov b1 = r16;;
// save the parameters in r5, r6. these 2 seemed to be preserved across PAL calls
mov r5 = in1;; // this is the parameter1 to pass to the continuation function
mov r6 = in2;; // this is the parameter2 to pass to the continuation function
dep r6=0,r6,63,1;; // zero the bit 63.
mov r8 = in3;; // new stack pointer.
// r8 has the sp, this is 128K stack size, from this we will reserve 16K for the bspstore
movl r15 = PEI_BSP_STORE_SIZE;;
sub r8 = r8, r15;;
add r15 = (GuardBand),r8;; // some little buffer, now r15 will be our bspstore
// save the bspstore value to r4, save sp value to r7
mov r4 = r15
mov r7 = r8
mov r16 = r8;; // will be the new sp in uncache mode
alloc r11=0,0,0,0;; // Set 0-size frame
flushrs;;
mov r21 = RSC_KERNEL_DISABLED;; // for rse disable
mov ar.rsc = r21;; // turn off RSE
add sp = r0, r16 // transfer to the EFI stack
mov ar.bspstore = r15 // switch to EFI BSP
invala // change of ar.bspstore needs invala.
mov r19 = RSC_KERNEL_LAZ;; // RSC enabled, Lazy mode
mov ar.rsc = r19;; // turn rse on, in kernel mode
//-----------------------------------------------------------------------------------
// Save here the meaningful stuff for next few lines and then make the PAL call.
// Make PAL call to terminate the CAR status.
// AVL: do this only for recovery check call...
mov r28=ar.k3;;
dep r2 = r28,r0,0,8;; // Extract Function bits from GR20.
cmp.eq p6,p7 = RecoveryFn,r2;; // Is it Recovery check
(p7) br.sptk.few DoneCARTermination; // if not, don't terminate car..
TerminateCAR::
mov r28 = ip;;
add r28 = (DoneCARTerminationPALCall - TerminateCAR),r28;;
mov b0 = r28
mov r8 = ar.k5;;
mov b6 = r8
mov r28 = 0x208
mov r29 = r0
mov r30 = r0
mov r31 = r0
mov r8 = r0;;
br.sptk.few b6;; // Call PAL-A call.
DoneCARTerminationPALCall::
// don't check error in soft sdv, it is always returning -1 for this call for some reason
#if SOFT_SDV
#else
ReturnToPEIMain::
cmp.eq p6,p7 = r8,r0;;
//
// dead loop if the PAL call failed, we have the CAR on but the stack is now pointing to memory
//
(p7) br.sptk.few ReturnToPEIMain;;
//
// PAL call successed,now the stack are in memory so come into cache mode
// instead of uncache mode
//
alloc r11=0,0,0,0;; // Set 0-size frame
flushrs;;
mov r21 = RSC_KERNEL_DISABLED;; // for rse disable
mov ar.rsc = r21;; // turn off RSE
dep r6 = 0,r6,63,1 // zero the bit 63
dep r7 = 0,r7,63,1 // zero the bit 63
dep r4 = 0,r4,63,1;; // zero the bit 63
add sp = r0, r7 // transfer to the EFI stack in cache mode
mov ar.bspstore = r4 // switch to EFI BSP
invala // change of ar.bspstore needs invala.
mov r19 = RSC_KERNEL_LAZ;; // RSC enabled, Lazy mode
mov ar.rsc = r19;; // turn rse on, in kernel mode
#endif
DoneCARTermination::
// allocate a stack frame:
alloc r11=0,2,2,0 ;; // alloc outs going to ensuing DXE IPL service
// on the new stack
mov out0 = r5;;
mov out1 = r6;;
mov r16 = b1;;
mov b6 = r16;;
br.call.sptk.few b0=b6;; // Call the continuation function
NESTED_RETURN
PROCEDURE_EXIT(SwitchCoreStacks)
//-----------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
//++
// GetHandOffStatus
//
// This routine is called by all processors simultaneously, to get some hand-off
// status that has been captured by IPF dispatcher and recorded in kernel registers.
//
// Arguments :
//
// On Entry : None.
//
// Return Value: Lid, R20Status.
//
//--
//----------------------------------------------------------------------------------
PROCEDURE_ENTRY (GetHandOffStatus)
NESTED_SETUP (0,2+0,0,0)
mov r8 = ar.k6 // Health Status (Self test params)
mov r9 = ar.k4 // LID bits
mov r10 = ar.k3;; // SAL_E entry state
mov r11 = ar.k7 // Return address to PAL
NESTED_RETURN
PROCEDURE_EXIT (GetHandOffStatus)
//----------------------------------------------------------------------------------

View File

@ -0,0 +1,57 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
IpfPeiMain.h
Abstract:
Definition of IPF specific function
Revision History
--*/
#ifndef _IPF_PEI_MAIN_H_
#define _IPF_PEI_MAIN_H_
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <PeiMain.h>
SAL_RETURN_REGS
GetHandOffStatus (
VOID
)
/*++
Routine Description:
This routine is called by all processors simultaneously, to get some hand-off
status that has been captured by IPF dispatcher and recorded in kernel registers.
Arguments :
On Entry : None.
Returns:
Lid, R20Status.
--*/
;
#endif

View File

@ -0,0 +1,63 @@
/** @file
PeiSwitchStacks() function for PEI dispatcher.
Copyright (c) 2006 - 2007, Intel Corporation<BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name: String.c
**/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <PeiMain.h>
/**
Transfers control to a function starting with a new stack.
Transfers control to the function specified by EntryPoint using the new stack
specified by NewStack and passing in the parameters specified by Context1 and
Context2. Context1 and Context2 are optional and may be NULL. The function
EntryPoint must never return.
If EntryPoint is NULL, then ASSERT().
If NewStack is NULL, then ASSERT().
@param EntryPoint A pointer to function to call with the new stack.
@param Context1 A pointer to the context to pass into the EntryPoint
function.
@param Context2 A pointer to the context to pass into the EntryPoint
function.
@param NewStack A pointer to the new stack to use for the EntryPoint
function.
@param NewBsp A pointer to the new BSP for the EntryPoint on IPF. It's
Reserved on other architectures.
**/
VOID
EFIAPI
PeiSwitchStacks (
IN SWITCH_STACK_ENTRY_POINT EntryPoint,
IN VOID *Context1, OPTIONAL
IN VOID *Context2, OPTIONAL
IN VOID *NewStack,
IN VOID *NewBsp
)
{
SwitchStack (
EntryPoint,
Context1,
Context2,
NewStack,
NewBsp
);
}

View File

@ -0,0 +1,76 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
SwitchToCacheMode.c
Abstract:
Ipf CAR specific function used to switch to cache mode for the later memory access
Revision History
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include "IpfPeiMain.h"
#include "IpfCpuCore.i"
VOID
SwitchToCacheMode (
IN PEI_CORE_INSTANCE *CoreData
)
/*++
Routine Description:
Switch the PHIT pointers to cache mode after InstallPeiMemory in CAR.
Arguments:
CoreData - The PEI core Private Data
Returns:
--*/
{
EFI_HOB_HANDOFF_INFO_TABLE *Phit;
if (CoreData == NULL) {
//
// the first call with CoreData as NULL.
//
return;
}
if ((GetHandOffStatus().r10 & 0xFF) == RecoveryFn) {
CoreData->StackBase = CoreData->StackBase & CACHE_MODE_ADDRESS_MASK;
CoreData->HobList.Raw = (UINT8 *)((UINTN)CoreData->HobList.Raw & CACHE_MODE_ADDRESS_MASK);
//
// Change the PHIT pointer value to cache mode
//
Phit = CoreData->HobList.HandoffInformationTable;
Phit->EfiMemoryTop = Phit->EfiMemoryTop & CACHE_MODE_ADDRESS_MASK;
Phit->EfiFreeMemoryTop = Phit->EfiFreeMemoryTop & CACHE_MODE_ADDRESS_MASK;
Phit->EfiMemoryBottom = Phit->EfiMemoryBottom & CACHE_MODE_ADDRESS_MASK;
Phit->EfiFreeMemoryBottom = Phit->EfiFreeMemoryBottom & CACHE_MODE_ADDRESS_MASK;
Phit->EfiEndOfHobList = Phit->EfiEndOfHobList & CACHE_MODE_ADDRESS_MASK;
}
return;
}

View File

@ -0,0 +1,326 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
MemoryServices.c
Abstract:
EFI PEI Core memory services
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <PeiMain.h>
VOID
InitializeMemoryServices (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
IN PEI_CORE_INSTANCE *OldCoreData
)
/*++
Routine Description:
Initialize the memory services.
Arguments:
PeiServices - The PEI core services table.
PeiStartupDescriptor - Information and services provided by SEC phase.
OldCoreData - Pointer to the PEI Core data.
NULL if being run in non-permament memory mode.
Returns:
None
--*/
{
PEI_CORE_INSTANCE *PrivateData;
UINT64 SizeOfCarHeap;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
PrivateData->SwitchStackSignal = FALSE;
if (OldCoreData == NULL) {
PrivateData->PeiMemoryInstalled = FALSE;
PrivateData->BottomOfCarHeap = (VOID *) (((UINTN)(VOID *)(&PrivateData))
& (~((PeiStartupDescriptor->SizeOfCacheAsRam) - 1)));
PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + PeiStartupDescriptor->SizeOfCacheAsRam);
//
// SizeOfCarHeap is 1/2 (arbitrary) of CacheAsRam Size.
//
SizeOfCarHeap = (UINT64) PeiStartupDescriptor->SizeOfCacheAsRam;
SizeOfCarHeap = RShiftU64 (SizeOfCarHeap, 1);
DEBUG_CODE_BEGIN ();
PrivateData->SizeOfCacheAsRam = PeiStartupDescriptor->SizeOfCacheAsRam;
PrivateData->MaxTopOfCarHeap = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) SizeOfCarHeap);
DEBUG_CODE_END ();
PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;
PeiCoreBuildHobHandoffInfoTable (
BOOT_WITH_FULL_CONFIGURATION,
(EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->BottomOfCarHeap,
(UINTN) SizeOfCarHeap
);
//
// Copy PeiServices from ROM to Cache in PrivateData
//
CopyMem (&(PrivateData->ServiceTableShadow), *PeiServices, sizeof (EFI_PEI_SERVICES));
//
// Set PS to point to ServiceTableShadow in Cache
//
PrivateData->PS = &(PrivateData->ServiceTableShadow);
} else {
//
// Set PS to point to ServiceTableShadow in Cache one time after the
// stack switched to main memory
//
PrivateData->PS = &(PrivateData->ServiceTableShadow);
}
return;
}
EFI_STATUS
EFIAPI
PeiInstallPeiMemory (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PHYSICAL_ADDRESS MemoryBegin,
IN UINT64 MemoryLength
)
/*++
Routine Description:
Install the permanent memory is now available.
Creates HOB (PHIT and Stack).
Arguments:
PeiServices - The PEI core services table.
MemoryBegin - Start of memory address.
MemoryLength - Length of memory.
Returns:
Status - EFI_SUCCESS
--*/
{
PEI_CORE_INSTANCE *PrivateData;
EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob;
EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob;
UINT64 PeiStackSize;
UINT64 EfiFreeMemorySize;
EFI_PHYSICAL_ADDRESS PhysicalAddressOfOldHob;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
PrivateData->SwitchStackSignal = TRUE;
PrivateData->PeiMemoryInstalled = TRUE;
PrivateData->StackBase = MemoryBegin;
PeiStackSize = RShiftU64 (MemoryLength, 1);
if (PEI_STACK_SIZE > PeiStackSize) {
PrivateData->StackSize = PeiStackSize;
} else {
PrivateData->StackSize = PEI_STACK_SIZE;
}
OldHandOffHob = PrivateData->HobList.HandoffInformationTable;
PrivateData->HobList.Raw = (VOID *)((UINTN)(MemoryBegin + PrivateData->StackSize));
NewHandOffHob = PrivateData->HobList.HandoffInformationTable;
PhysicalAddressOfOldHob = (EFI_PHYSICAL_ADDRESS) (UINTN) OldHandOffHob;
EfiFreeMemorySize = OldHandOffHob->EfiFreeMemoryBottom - PhysicalAddressOfOldHob;
DEBUG ((EFI_D_INFO, "HOBLIST address before memory init = 0x%08x\n", OldHandOffHob));
DEBUG ((EFI_D_INFO, "HOBLIST address after memory init = 0x%08x\n", NewHandOffHob));
CopyMem (
NewHandOffHob,
OldHandOffHob,
(UINTN)EfiFreeMemorySize
);
NewHandOffHob->EfiMemoryTop = MemoryBegin + MemoryLength;
NewHandOffHob->EfiFreeMemoryTop = NewHandOffHob->EfiMemoryTop;
NewHandOffHob->EfiMemoryBottom = MemoryBegin;
NewHandOffHob->EfiFreeMemoryBottom = (UINTN)NewHandOffHob + EfiFreeMemorySize;
NewHandOffHob->EfiEndOfHobList = (UINTN)NewHandOffHob +
(OldHandOffHob->EfiEndOfHobList -
PhysicalAddressOfOldHob);
ConvertPpiPointers (PeiServices, OldHandOffHob, NewHandOffHob);
BuildStackHob (PrivateData->StackBase, PrivateData->StackSize);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
PeiAllocatePages (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN Pages,
OUT EFI_PHYSICAL_ADDRESS *Memory
)
/*++
Routine Description:
Memory allocation service on permanent memory,
not usable prior to the memory installation.
Arguments:
PeiServices - The PEI core services table.
MemoryType - Type of memory to allocate.
Pages - Number of pages to allocate.
Memory - Pointer of memory allocated.
Returns:
Status - EFI_SUCCESS The allocation was successful
EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.
EFI_NOT_AVAILABLE_YET Called with permanent memory not available
EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement
to allocate the number of pages.
--*/
{
PEI_CORE_INSTANCE *PrivateData;
EFI_PEI_HOB_POINTERS Hob;
EFI_PHYSICAL_ADDRESS Offset;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
//
// Check if Hob already available
//
if (!PrivateData->PeiMemoryInstalled) {
return EFI_NOT_AVAILABLE_YET;
}
Hob.Raw = PrivateData->HobList.Raw;
//
// Check to see if on 4k boundary
//
Offset = Hob.HandoffInformationTable->EfiFreeMemoryTop & 0xFFF;
//
// If not aligned, make the allocation aligned.
//
if (Offset != 0) {
Hob.HandoffInformationTable->EfiFreeMemoryTop -= Offset;
}
//
// Verify that there is sufficient memory to satisfy the allocation
//
if (Hob.HandoffInformationTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) <
Hob.HandoffInformationTable->EfiFreeMemoryBottom) {
DEBUG ((EFI_D_ERROR, "AllocatePages failed: No 0x%x Pages is available.\n", Pages));
DEBUG ((EFI_D_ERROR, "There is only left 0x%x pages memory resource to be allocated.\n", \
EFI_SIZE_TO_PAGES ((UINTN) (Hob.HandoffInformationTable->EfiFreeMemoryTop - Hob.HandoffInformationTable->EfiFreeMemoryBottom))));
return EFI_OUT_OF_RESOURCES;
} else {
//
// Update the PHIT to reflect the memory usage
//
Hob.HandoffInformationTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE;
//
// Update the value for the caller
//
*Memory = Hob.HandoffInformationTable->EfiFreeMemoryTop;
//
// Create a memory allocation HOB.
//
BuildMemoryAllocationHob (
Hob.HandoffInformationTable->EfiFreeMemoryTop,
Pages * EFI_PAGE_SIZE + Offset,
MemoryType
);
return EFI_SUCCESS;
}
}
EFI_STATUS
EFIAPI
PeiAllocatePool (
IN EFI_PEI_SERVICES **PeiServices,
IN UINTN Size,
OUT VOID **Buffer
)
/*++
Routine Description:
Memory allocation service on the CAR.
Arguments:
PeiServices - The PEI core services table.
Size - Amount of memory required
Buffer - Address of pointer to the buffer
Returns:
Status - EFI_SUCCESS The allocation was successful
EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
to allocate the requested size.
--*/
{
EFI_STATUS Status;
EFI_HOB_MEMORY_POOL *Hob;
//
// If some "post-memory" PEIM wishes to allocate larger pool,
// it should use AllocatePages service instead.
//
ASSERT (Size < 0x10000 - sizeof (EFI_HOB_MEMORY_POOL));
Status = PeiServicesCreateHob (
EFI_HOB_TYPE_MEMORY_POOL,
(UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size),
(VOID **)&Hob
);
*Buffer = Hob+1;
return Status;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,146 @@
#/** @file
# Component description file for PeiMain module
#
# This module provide an DXE CIS compliant implementation.
# Copyright (c) 2006 - 2007, Intel Corporation
#
# All rights reserved. This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#
#**/
################################################################################
#
# Defines Section - statements that will be processed to create a Makefile.
#
################################################################################
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = PeiMain
FILE_GUID = 52C05B14-0B98-496c-BC3B-04B50211D680
MODULE_TYPE = PEI_CORE
VERSION_STRING = 1.0
EDK_RELEASE_VERSION = 0x00020000
EFI_SPECIFICATION_VERSION = 0x00020000
ENTRY_POINT = PeiCore
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
################################################################################
#
# Sources Section - list of files that are required for the build to succeed.
#
################################################################################
[Sources.common]
StatusCode/StatusCode.c
Security/Security.c
Reset/Reset.c
Ppi/Ppi.c
PeiMain/PeiMain.c
Memory/MemoryServices.c
Image/Image.c
Hob/Hob.c
FwVol/FwVol.c
Dispatcher/Dispatcher.c
Dependency/dependency.c
Dependency/dependency.h
BootMode/BootMode.c
PeiMain.h
CommonHeader.h
[Sources.Ia32]
Dispatcher/Stack.c
[Sources.X64]
Dispatcher/Stack.c
[Sources.IPF]
Ipf/Stack.c
Ipf/IpfPeiMain.h
Ipf/IpfCpuCore.s
Ipf/IpfCpuCore.i
Ipf/SwitchToCacheMode.c
[Sources.EBC]
Dispatcher/Stack.c
################################################################################
#
# Includes Section - list of Include locations that are required for
# this module.
#
################################################################################
[Includes]
$(WORKSPACE)/MdePkg\Include/Library
################################################################################
#
# Package Dependency Section - list of Package files that are required for
# this module.
#
################################################################################
[Packages]
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
IntelFrameworkPkg/IntelFrameworkPkg.dec
################################################################################
#
# Library Class Section - list of Library Classes that are required for
# this module.
#
################################################################################
[LibraryClasses]
TimerLib
BaseMemoryLib
PeCoffGetEntryPointLib
ReportStatusCodeLib
PeiServicesLib
PerformanceLib
HobLib
BaseLib
PeiCoreEntryPoint
DebugLib
################################################################################
#
# Guid C Name Section - list of Guids that this module uses or produces.
#
################################################################################
[Guids]
gEfiPeiCorePrivateGuid # PRIVATE
################################################################################
#
# PPI C Name Section - list of PPI and PPI Notify C Names that this module
# uses or produces.
#
################################################################################
[Ppis]
gEfiPeiSecurityPpiGuid # PPI_NOTIFY SOMETIMES_CONSUMED
gEfiPeiStatusCodePpiGuid # PPI SOMETIMES_CONSUMED
gEfiPeiResetPpiGuid # PPI SOMETIMES_CONSUMED
gEfiDxeIplPpiGuid # PPI ALWAYS_CONSUMED
gEfiPeiFvFileLoaderPpiGuid # PPI ALWAYS_CONSUMED
gEfiFindFvPpiGuid # PPI ALWAYS_CONSUMED
gEfiPeiMemoryDiscoveredPpiGuid # PPI ALWAYS_PRODUCED

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8"?>
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<MsaHeader>
<ModuleName>PeiMain</ModuleName>
<ModuleType>PEI_CORE</ModuleType>
<GuidValue>52C05B14-0B98-496c-BC3B-04B50211D680</GuidValue>
<Version>1.0</Version>
<Abstract>Component description file for PeiMain module</Abstract>
<Description>This module provide an DXE CIS compliant implementation.</Description>
<Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>
<License>All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
</MsaHeader>
<ModuleDefinitions>
<SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
<BinaryModule>false</BinaryModule>
<OutputFileBasename>PeiMain</OutputFileBasename>
</ModuleDefinitions>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>DebugLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>PeiCoreEntryPoint</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>HobLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>PerformanceLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>PeiServicesLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>ReportStatusCodeLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>PeCoffGetEntryPointLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseMemoryLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>TimerLib</Keyword>
</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>PeiMain.h</Filename>
<Filename>BootMode/BootMode.c</Filename>
<Filename>Dependency/dependency.h</Filename>
<Filename>Dependency/dependency.c</Filename>
<Filename>Dispatcher/Dispatcher.c</Filename>
<Filename>FwVol/FwVol.c</Filename>
<Filename>Hob/Hob.c</Filename>
<Filename>Image/Image.c</Filename>
<Filename>Memory/MemoryServices.c</Filename>
<Filename>PeiMain/PeiMain.c</Filename>
<Filename>Ppi/Ppi.c</Filename>
<Filename>Reset/Reset.c</Filename>
<Filename>Security/Security.c</Filename>
<Filename>StatusCode/StatusCode.c</Filename>
<Filename SupArchList="IPF">Ipf/SwitchToCacheMode.c</Filename>
<Filename SupArchList="IPF">Ipf/IpfCpuCore.i</Filename>
<Filename SupArchList="IPF">Ipf/IpfCpuCore.s</Filename>
<Filename SupArchList="IPF">Ipf/IpfPeiMain.h</Filename>
<Filename SupArchList="IPF">Ipf/Stack.c</Filename>
<Filename SupArchList="IA32 X64 EBC">Dispatcher/Stack.c</Filename>
</SourceFiles>
<PackageDependencies>
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
</PackageDependencies>
<PPIs>
<Ppi Usage="ALWAYS_PRODUCED">
<PpiCName>gEfiPeiMemoryDiscoveredPpiGuid</PpiCName>
</Ppi>
<Ppi Usage="ALWAYS_CONSUMED">
<PpiCName>gEfiFindFvPpiGuid</PpiCName>
</Ppi>
<Ppi Usage="ALWAYS_CONSUMED">
<PpiCName>gEfiPeiFvFileLoaderPpiGuid</PpiCName>
</Ppi>
<Ppi Usage="ALWAYS_CONSUMED">
<PpiCName>gEfiDxeIplPpiGuid</PpiCName>
</Ppi>
<Ppi Usage="SOMETIMES_CONSUMED">
<PpiCName>gEfiPeiResetPpiGuid</PpiCName>
</Ppi>
<Ppi Usage="SOMETIMES_CONSUMED">
<PpiCName>gEfiPeiStatusCodePpiGuid</PpiCName>
</Ppi>
<PpiNotify Usage="SOMETIMES_CONSUMED">
<PpiNotifyCName>gEfiPeiSecurityPpiGuid</PpiNotifyCName>
</PpiNotify>
</PPIs>
<Guids>
<GuidCNames Usage="PRIVATE">
<GuidCName>gEfiPeiCorePrivateGuid</GuidCName>
</GuidCNames>
</Guids>
<Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
<Extern>
<ModuleEntryPoint>PeiCore</ModuleEntryPoint>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@ -0,0 +1,251 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
PeiMain.c
Abstract:
Pei Core Main Entry Point
Revision History
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <PeiMain.h>
//
//CAR is filled with this initial value during SEC phase
//
#define INIT_CAR_VALUE 0x5AA55AA5
static EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEfiPeiMemoryDiscoveredPpiGuid,
NULL
};
//
// Pei Core Module Variables
//
//
static EFI_PEI_SERVICES mPS = {
{
PEI_SERVICES_SIGNATURE,
PEI_SERVICES_REVISION,
sizeof (EFI_PEI_SERVICES),
0,
0
},
PeiInstallPpi,
PeiReInstallPpi,
PeiLocatePpi,
PeiNotifyPpi,
PeiGetBootMode,
PeiSetBootMode,
PeiGetHobList,
PeiCreateHob,
PeiFvFindNextVolume,
PeiFfsFindNextFile,
PeiFfsFindSectionData,
PeiInstallPeiMemory,
PeiAllocatePages,
PeiAllocatePool,
(EFI_PEI_COPY_MEM)CopyMem,
(EFI_PEI_SET_MEM)SetMem,
PeiReportStatusCode,
PeiResetSystem
};
EFI_STATUS
EFIAPI
PeiCore (
IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
IN VOID *Data
)
/*++
Routine Description:
The entry routine to Pei Core, invoked by PeiMain during transition
from SEC to PEI. After switching stack in the PEI core, it will restart
with the old core data.
Arguments:
PeiStartupDescriptor - Information and services provided by SEC phase.
OldCoreData - Pointer to old core data that is used to initialize the
core's data areas.
Returns:
This function never returns
EFI_NOT_FOUND - Never reach
--*/
{
PEI_CORE_INSTANCE PrivateData;
EFI_STATUS Status;
PEI_CORE_TEMP_POINTERS TempPtr;
PEI_CORE_DISPATCH_DATA *DispatchData;
UINT64 mTick;
PEI_CORE_INSTANCE *OldCoreData;
mTick = 0;
OldCoreData = (PEI_CORE_INSTANCE *) Data;
if (PerformanceMeasurementEnabled()) {
if (OldCoreData == NULL) {
mTick = GetPerformanceCounter ();
}
}
//
// For IPF in CAR mode the real memory access is uncached,in InstallPeiMemory()
// the 63-bit of address is set to 1.
//
SWITCH_TO_CACHE_MODE (OldCoreData);
if (OldCoreData != NULL) {
CopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));
} else {
ZeroMem (&PrivateData, sizeof (PEI_CORE_INSTANCE));
}
PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;
PrivateData.PS = &mPS;
//
// Initialize libraries that the PeiCore is linked against
// BUGBUG: The FfsHeader is passed in as NULL. Do we look it up or remove it from the lib init?
//
ProcessLibraryConstructorList (NULL, &PrivateData.PS);
InitializeMemoryServices (&PrivateData.PS, PeiStartupDescriptor, OldCoreData);
InitializePpiServices (&PrivateData.PS, OldCoreData);
InitializeSecurityServices (&PrivateData.PS, OldCoreData);
InitializeDispatcherData (&PrivateData.PS, OldCoreData, PeiStartupDescriptor);
if (OldCoreData != NULL) {
PERF_END (NULL,"PreMem", NULL, 0);
PERF_START (NULL,"PostMem", NULL, 0);
//
// The following code dumps out interesting cache as RAM usage information
// so we can keep tabs on how the cache as RAM is being utilized. The
// DEBUG_CODE_BEGIN macro is used to prevent this code from being compiled
// on a debug build.
//
DEBUG_CODE_BEGIN ();
UINTN *StackPointer;
UINTN StackValue;
StackValue = INIT_CAR_VALUE;
for (StackPointer = (UINTN *) OldCoreData->MaxTopOfCarHeap;
((UINTN) StackPointer < ((UINTN) OldCoreData->BottomOfCarHeap + OldCoreData->SizeOfCacheAsRam))
&& StackValue == INIT_CAR_VALUE;
StackPointer++) {
StackValue = *StackPointer;
}
DEBUG ((EFI_D_INFO, "Total Cache as RAM: %d bytes.\n", OldCoreData->SizeOfCacheAsRam));
DEBUG ((EFI_D_INFO, " CAR stack ever used: %d bytes.\n",
((UINTN) OldCoreData->TopOfCarHeap - (UINTN) StackPointer)
));
DEBUG ((EFI_D_INFO, " CAR heap used: %d bytes.\n",
((UINTN) OldCoreData->HobList.HandoffInformationTable->EfiFreeMemoryBottom -
(UINTN) OldCoreData->HobList.Raw)
));
DEBUG_CODE_END ();
//
// Alert any listeners that there is permanent memory available
//
PERF_START (NULL,"DisMem", NULL, 0);
Status = PeiServicesInstallPpi (&mMemoryDiscoveredPpi);
PERF_END (NULL,"DisMem", NULL, 0);
} else {
//
// Report Status Code EFI_SW_PC_INIT
//
REPORT_STATUS_CODE (
EFI_PROGRESS_CODE,
EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT
);
PERF_START (NULL,"PEI", NULL, mTick);
//
// If first pass, start performance measurement.
//
PERF_START (NULL,"PreMem", NULL, mTick);
//
// If SEC provided any PPI services to PEI, install them.
//
if (PeiStartupDescriptor->DispatchTable != NULL) {
Status = PeiServicesInstallPpi (PeiStartupDescriptor->DispatchTable);
ASSERT_EFI_ERROR (Status);
}
}
DispatchData = &PrivateData.DispatchData;
//
// Call PEIM dispatcher
//
PeiDispatcher (PeiStartupDescriptor, &PrivateData, DispatchData);
//
// Check if InstallPeiMemory service was called.
//
ASSERT(PrivateData.PeiMemoryInstalled == TRUE);
PERF_END (NULL, "PostMem", NULL, 0);
Status = PeiServicesLocatePpi (
&gEfiDxeIplPpiGuid,
0,
NULL,
(VOID **)&TempPtr.DxeIpl
);
ASSERT_EFI_ERROR (Status);
DEBUG ((EFI_D_INFO, "DXE IPL Entry\n"));
Status = TempPtr.DxeIpl->Entry (
TempPtr.DxeIpl,
&PrivateData.PS,
PrivateData.HobList
);
ASSERT_EFI_ERROR (Status);
return EFI_NOT_FOUND;
}

View File

@ -0,0 +1,663 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Ppi.c
Abstract:
EFI PEI Core PPI services
Revision History
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <PeiMain.h>
VOID
InitializePpiServices (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_CORE_INSTANCE *OldCoreData
)
/*++
Routine Description:
Initialize PPI services.
Arguments:
PeiServices - The PEI core services table.
OldCoreData - Pointer to the PEI Core data.
NULL if being run in non-permament memory mode.
Returns:
Nothing
--*/
{
PEI_CORE_INSTANCE *PrivateData;
if (OldCoreData == NULL) {
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
PrivateData->PpiData.NotifyListEnd = MAX_PPI_DESCRIPTORS-1;
PrivateData->PpiData.DispatchListEnd = MAX_PPI_DESCRIPTORS-1;
PrivateData->PpiData.LastDispatchedNotify = MAX_PPI_DESCRIPTORS-1;
}
return;
}
VOID
ConvertPpiPointers (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob,
IN EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob
)
/*++
Routine Description:
Migrate the Hob list from the CAR stack to PEI installed memory.
Arguments:
PeiServices - The PEI core services table.
OldHandOffHob - The old handoff HOB list.
NewHandOffHob - The new handoff HOB list.
Returns:
--*/
{
PEI_CORE_INSTANCE *PrivateData;
UINT8 Index;
PEI_PPI_LIST_POINTERS *PpiPointer;
UINTN Fixup;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
Fixup = (UINTN)NewHandOffHob - (UINTN)OldHandOffHob;
for (Index = 0; Index < MAX_PPI_DESCRIPTORS; Index++) {
if (Index < PrivateData->PpiData.PpiListEnd ||
Index > PrivateData->PpiData.NotifyListEnd) {
PpiPointer = &PrivateData->PpiData.PpiListPtrs[Index];
if (((UINTN)PpiPointer->Raw < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) &&
((UINTN)PpiPointer->Raw >= (UINTN)OldHandOffHob)) {
//
// Convert the pointer to the PEIM descriptor from the old HOB heap
// to the relocated HOB heap.
//
PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Fixup);
//
// Only when the PEIM descriptor is in the old HOB should it be necessary
// to try to convert the pointers in the PEIM descriptor
//
if (((UINTN)PpiPointer->Ppi->Guid < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) &&
((UINTN)PpiPointer->Ppi->Guid >= (UINTN)OldHandOffHob)) {
//
// Convert the pointer to the GUID in the PPI or NOTIFY descriptor
// from the old HOB heap to the relocated HOB heap.
//
PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Fixup);
}
//
// Assume that no code is located in the temporary memory, so the pointer to
// the notification function in the NOTIFY descriptor needs not be converted.
//
if (Index < PrivateData->PpiData.PpiListEnd &&
(UINTN)PpiPointer->Ppi->Ppi < (UINTN)OldHandOffHob->EfiFreeMemoryBottom &&
(UINTN)PpiPointer->Ppi->Ppi >= (UINTN)OldHandOffHob) {
//
// Convert the pointer to the PPI interface structure in the PPI descriptor
// from the old HOB heap to the relocated HOB heap.
//
PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi+ Fixup);
}
}
}
}
}
EFI_STATUS
EFIAPI
PeiInstallPpi (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_PPI_DESCRIPTOR *PpiList
)
/*++
Routine Description:
Install PPI services.
Arguments:
PeiServices - Pointer to the PEI Service Table
PpiList - Pointer to a list of PEI PPI Descriptors.
Returns:
EFI_SUCCESS - if all PPIs in PpiList are successfully installed.
EFI_INVALID_PARAMETER - if PpiList is NULL pointer
EFI_INVALID_PARAMETER - if any PPI in PpiList is not valid
EFI_OUT_OF_RESOURCES - if there is no more memory resource to install PPI
--*/
{
PEI_CORE_INSTANCE *PrivateData;
INTN Index;
INTN LastCallbackInstall;
if (PpiList == NULL) {
return EFI_INVALID_PARAMETER;
}
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
Index = PrivateData->PpiData.PpiListEnd;
LastCallbackInstall = Index;
//
// This is loop installs all PPI descriptors in the PpiList. It is terminated
// by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
// EFI_PEI_PPI_DESCRIPTOR in the list.
//
for (;;) {
//
// Since PpiData is used for NotifyList and InstallList, max resource
// is reached if the Install reaches the NotifyList
//
if (Index == PrivateData->PpiData.NotifyListEnd + 1) {
return EFI_OUT_OF_RESOURCES;
}
//
// Check if it is a valid PPI.
// If not, rollback list to exclude all in this list.
// Try to indicate which item failed.
//
if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
PrivateData->PpiData.PpiListEnd = LastCallbackInstall;
DEBUG((EFI_D_ERROR, "ERROR -> InstallPpi: %g %x\n", PpiList->Guid, PpiList->Ppi));
return EFI_INVALID_PARAMETER;
}
DEBUG((EFI_D_INFO, "Install PPI: %g\n", PpiList->Guid));
PrivateData->PpiData.PpiListPtrs[Index].Ppi = PpiList;
PrivateData->PpiData.PpiListEnd++;
//
// Continue until the end of the PPI List.
//
if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
break;
}
PpiList++;
Index++;
}
//
// Dispatch any callback level notifies for newly installed PPIs.
//
DispatchNotify (
PeiServices,
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
LastCallbackInstall,
PrivateData->PpiData.PpiListEnd,
PrivateData->PpiData.DispatchListEnd,
PrivateData->PpiData.NotifyListEnd
);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
PeiReInstallPpi (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_PPI_DESCRIPTOR *OldPpi,
IN EFI_PEI_PPI_DESCRIPTOR *NewPpi
)
/*++
Routine Description:
Re-Install PPI services.
Arguments:
PeiServices - Pointer to the PEI Service Table
OldPpi - Pointer to the old PEI PPI Descriptors.
NewPpi - Pointer to the new PEI PPI Descriptors.
Returns:
EFI_SUCCESS - if the operation was successful
EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL
EFI_INVALID_PARAMETER - if NewPpi is not valid
EFI_NOT_FOUND - if the PPI was not in the database
--*/
{
PEI_CORE_INSTANCE *PrivateData;
INTN Index;
if ((OldPpi == NULL) || (NewPpi == NULL)) {
return EFI_INVALID_PARAMETER;
}
if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
return EFI_INVALID_PARAMETER;
}
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
//
// Find the old PPI instance in the database. If we can not find it,
// return the EFI_NOT_FOUND error.
//
for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {
if (OldPpi == PrivateData->PpiData.PpiListPtrs[Index].Ppi) {
break;
}
}
if (Index == PrivateData->PpiData.PpiListEnd) {
return EFI_NOT_FOUND;
}
//
// Remove the old PPI from the database, add the new one.
//
DEBUG((EFI_D_INFO, "Reinstall PPI: %g\n", NewPpi->Guid));
PrivateData->PpiData.PpiListPtrs[Index].Ppi = NewPpi;
//
// Dispatch any callback level notifies for the newly installed PPI.
//
DispatchNotify (
PeiServices,
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
Index,
Index+1,
PrivateData->PpiData.DispatchListEnd,
PrivateData->PpiData.NotifyListEnd
);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
PeiLocatePpi (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_GUID *Guid,
IN UINTN Instance,
IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,
IN OUT VOID **Ppi
)
/*++
Routine Description:
Locate a given named PPI.
Arguments:
PeiServices - Pointer to the PEI Service Table
Guid - Pointer to GUID of the PPI.
Instance - Instance Number to discover.
PpiDescriptor - Pointer to reference the found descriptor. If not NULL,
returns a pointer to the descriptor (includes flags, etc)
Ppi - Pointer to reference the found PPI
Returns:
Status - EFI_SUCCESS if the PPI is in the database
EFI_NOT_FOUND if the PPI is not in the database
--*/
{
PEI_CORE_INSTANCE *PrivateData;
INTN Index;
EFI_GUID *CheckGuid;
EFI_PEI_PPI_DESCRIPTOR *TempPtr;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
//
// Search the data base for the matching instance of the GUIDed PPI.
//
for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {
TempPtr = PrivateData->PpiData.PpiListPtrs[Index].Ppi;
CheckGuid = TempPtr->Guid;
//
// Don't use CompareGuid function here for performance reasons.
// Instead we compare the GUID as INT32 at a time and branch
// on the first failed comparison.
//
if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) &&
(((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) &&
(((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) &&
(((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3])) {
if (Instance == 0) {
if (PpiDescriptor != NULL) {
*PpiDescriptor = TempPtr;
}
if (Ppi != NULL) {
*Ppi = TempPtr->Ppi;
}
return EFI_SUCCESS;
}
Instance--;
}
}
return EFI_NOT_FOUND;
}
EFI_STATUS
EFIAPI
PeiNotifyPpi (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList
)
/*++
Routine Description:
Install a notification for a given PPI.
Arguments:
PeiServices - Pointer to the PEI Service Table
NotifyList - Pointer to list of Descriptors to notify upon.
Returns:
Status - EFI_SUCCESS if successful
EFI_OUT_OF_RESOURCES if no space in the database
EFI_INVALID_PARAMETER if not a good decriptor
--*/
{
PEI_CORE_INSTANCE *PrivateData;
INTN Index;
INTN NotifyIndex;
INTN LastCallbackNotify;
EFI_PEI_NOTIFY_DESCRIPTOR *NotifyPtr;
UINTN NotifyDispatchCount;
NotifyDispatchCount = 0;
if (NotifyList == NULL) {
return EFI_INVALID_PARAMETER;
}
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
Index = PrivateData->PpiData.NotifyListEnd;
LastCallbackNotify = Index;
//
// This is loop installs all Notify descriptors in the NotifyList. It is
// terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
// EFI_PEI_NOTIFY_DESCRIPTOR in the list.
//
for (;;) {
//
// Since PpiData is used for NotifyList and InstallList, max resource
// is reached if the Install reaches the PpiList
//
if (Index == PrivateData->PpiData.PpiListEnd - 1) {
return EFI_OUT_OF_RESOURCES;
}
//
// If some of the PPI data is invalid restore original Notify PPI database value
//
if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) {
PrivateData->PpiData.NotifyListEnd = LastCallbackNotify;
DEBUG((EFI_D_ERROR, "ERROR -> InstallNotify: %g %x\n", NotifyList->Guid, NotifyList->Notify));
return EFI_INVALID_PARAMETER;
}
if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {
NotifyDispatchCount ++;
}
PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyList;
PrivateData->PpiData.NotifyListEnd--;
DEBUG((EFI_D_INFO, "Register PPI Notify: %g\n", NotifyList->Guid));
if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
break;
}
//
// Go the next descriptor. Remember the NotifyList moves down.
//
NotifyList++;
Index--;
}
//
// If there is Dispatch Notify PPI installed put them on the bottom
//
if (NotifyDispatchCount > 0) {
for (NotifyIndex = LastCallbackNotify; NotifyIndex > PrivateData->PpiData.NotifyListEnd; NotifyIndex--) {
if ((PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {
NotifyPtr = PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify;
for (Index = NotifyIndex; Index < PrivateData->PpiData.DispatchListEnd; Index++){
PrivateData->PpiData.PpiListPtrs[Index].Notify = PrivateData->PpiData.PpiListPtrs[Index + 1].Notify;
}
PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyPtr;
PrivateData->PpiData.DispatchListEnd--;
}
}
LastCallbackNotify -= NotifyDispatchCount;
}
//
// Dispatch any callback level notifies for all previously installed PPIs.
//
DispatchNotify (
PeiServices,
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
0,
PrivateData->PpiData.PpiListEnd,
LastCallbackNotify,
PrivateData->PpiData.NotifyListEnd
);
return EFI_SUCCESS;
}
VOID
ProcessNotifyList (
IN EFI_PEI_SERVICES **PeiServices
)
/*++
Routine Description:
Process the Notify List at dispatch level.
Arguments:
PeiServices - Pointer to the PEI Service Table
Returns:
--*/
{
PEI_CORE_INSTANCE *PrivateData;
INTN TempValue;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
while (TRUE) {
//
// Check if the PEIM that was just dispatched resulted in any
// Notifies getting installed. If so, go process any dispatch
// level Notifies that match the previouly installed PPIs.
// Use "while" instead of "if" since DispatchNotify can modify
// DispatchListEnd (with NotifyPpi) so we have to iterate until the same.
//
while (PrivateData->PpiData.LastDispatchedNotify != PrivateData->PpiData.DispatchListEnd) {
TempValue = PrivateData->PpiData.DispatchListEnd;
DispatchNotify (
PeiServices,
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
0,
PrivateData->PpiData.LastDispatchedInstall,
PrivateData->PpiData.LastDispatchedNotify,
PrivateData->PpiData.DispatchListEnd
);
PrivateData->PpiData.LastDispatchedNotify = TempValue;
}
//
// Check if the PEIM that was just dispatched resulted in any
// PPIs getting installed. If so, go process any dispatch
// level Notifies that match the installed PPIs.
// Use "while" instead of "if" since DispatchNotify can modify
// PpiListEnd (with InstallPpi) so we have to iterate until the same.
//
while (PrivateData->PpiData.LastDispatchedInstall != PrivateData->PpiData.PpiListEnd) {
TempValue = PrivateData->PpiData.PpiListEnd;
DispatchNotify (
PeiServices,
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
PrivateData->PpiData.LastDispatchedInstall,
PrivateData->PpiData.PpiListEnd,
MAX_PPI_DESCRIPTORS-1,
PrivateData->PpiData.DispatchListEnd
);
PrivateData->PpiData.LastDispatchedInstall = TempValue;
}
if (PrivateData->PpiData.LastDispatchedNotify == PrivateData->PpiData.DispatchListEnd) {
break;
}
}
return;
}
VOID
DispatchNotify (
IN EFI_PEI_SERVICES **PeiServices,
IN UINTN NotifyType,
IN INTN InstallStartIndex,
IN INTN InstallStopIndex,
IN INTN NotifyStartIndex,
IN INTN NotifyStopIndex
)
/*++
Routine Description:
Dispatch notifications.
Arguments:
PeiServices - Pointer to the PEI Service Table
NotifyType - Type of notify to fire.
InstallStartIndex - Install Beginning index.
InstallStopIndex - Install Ending index.
NotifyStartIndex - Notify Beginning index.
NotifyStopIndex - Notify Ending index.
Returns: None
--*/
{
PEI_CORE_INSTANCE *PrivateData;
INTN Index1;
INTN Index2;
EFI_GUID *SearchGuid;
EFI_GUID *CheckGuid;
EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
//
// Remember that Installs moves up and Notifies moves down.
//
for (Index1 = NotifyStartIndex; Index1 > NotifyStopIndex; Index1--) {
NotifyDescriptor = PrivateData->PpiData.PpiListPtrs[Index1].Notify;
CheckGuid = NotifyDescriptor->Guid;
for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) {
SearchGuid = PrivateData->PpiData.PpiListPtrs[Index2].Ppi->Guid;
//
// Don't use CompareGuid function here for performance reasons.
// Instead we compare the GUID as INT32 at a time and branch
// on the first failed comparison.
//
if ((((INT32 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) &&
(((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) &&
(((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) &&
(((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3])) {
DEBUG ((EFI_D_INFO, "Notify: PPI Guid: %g, Peim notify entry point: %x\n",
SearchGuid,
NotifyDescriptor->Notify
));
NotifyDescriptor->Notify (
PeiServices,
NotifyDescriptor,
(PrivateData->PpiData.PpiListPtrs[Index2].Ppi)->Ppi
);
}
}
}
return;
}

View File

@ -0,0 +1,73 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Reset.c
Abstract:
Pei Core Reset System Support
Revision History
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <PeiMain.h>
EFI_STATUS
EFIAPI
PeiResetSystem (
IN EFI_PEI_SERVICES **PeiServices
)
/*++
Routine Description:
Core version of the Reset System
Arguments:
PeiServices - The PEI core services table.
Returns:
Status - EFI_NOT_AVAILABLE_YET. PPI not available yet.
- EFI_DEVICE_ERROR. Did not reset system.
Otherwise, resets the system.
--*/
{
EFI_STATUS Status;
EFI_PEI_RESET_PPI *ResetPpi;
Status = PeiServicesLocatePpi (
&gEfiPeiResetPpiGuid,
0,
NULL,
(VOID **)&ResetPpi
);
//
// LocatePpi returns EFI_NOT_FOUND on error
//
if (!EFI_ERROR (Status)) {
return ResetPpi->ResetSystem (PeiServices);
}
return EFI_NOT_AVAILABLE_YET;
}

View File

@ -0,0 +1,199 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Security.c
Abstract:
EFI PEI Core Security services
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <PeiMain.h>
STATIC
EFI_STATUS
EFIAPI
SecurityPpiNotifyCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
);
static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
&gEfiPeiSecurityPpiGuid,
SecurityPpiNotifyCallback
};
VOID
InitializeSecurityServices (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_CORE_INSTANCE *OldCoreData
)
/*++
Routine Description:
Initialize the security services.
Arguments:
PeiServices - The PEI core services table.
OldCoreData - Pointer to the old core data.
NULL if being run in non-permament memory mode.
Returns:
None
--*/
{
if (OldCoreData == NULL) {
PeiServicesNotifyPpi (&mNotifyList);
}
return;
}
STATIC
EFI_STATUS
EFIAPI
SecurityPpiNotifyCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
)
/*++
Routine Description:
Provide a callback for when the security PPI is installed.
Arguments:
PeiServices - The PEI core services table.
NotifyDescriptor - The descriptor for the notification event.
Ppi - Pointer to the PPI in question.
Returns:
EFI_SUCCESS - The function is successfully processed.
--*/
{
PEI_CORE_INSTANCE *PrivateData;
//
// Get PEI Core private data
//
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
//
// If there isn't a security PPI installed, use the one from notification
//
if (PrivateData->PrivateSecurityPpi == NULL) {
PrivateData->PrivateSecurityPpi = (EFI_PEI_SECURITY_PPI *)Ppi;
}
return EFI_SUCCESS;
}
EFI_STATUS
VerifyPeim (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_FFS_FILE_HEADER *CurrentPeimAddress
)
/*++
Routine Description:
Provide a callout to the security verification service.
Arguments:
PeiServices - The PEI core services table.
CurrentPeimAddress - Pointer to the Firmware File under investigation.
Returns:
EFI_SUCCESS - Image is OK
EFI_SECURITY_VIOLATION - Image is illegal
--*/
{
PEI_CORE_INSTANCE *PrivateData;
EFI_STATUS Status;
UINT32 AuthenticationStatus;
BOOLEAN StartCrisisRecovery;
//
// Set a default authentication state
//
AuthenticationStatus = 0;
//
// get security PPI instance from PEI private data
//
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
if (PrivateData->PrivateSecurityPpi == NULL) {
Status = EFI_NOT_FOUND;
} else {
//
// Check to see if the image is OK
//
Status = PrivateData->PrivateSecurityPpi->AuthenticationState (
PeiServices,
PrivateData->PrivateSecurityPpi,
AuthenticationStatus,
CurrentPeimAddress,
&StartCrisisRecovery
);
if (StartCrisisRecovery) {
Status = EFI_SECURITY_VIOLATION;
}
}
return Status;
}
EFI_STATUS
VerifyFv (
IN EFI_FIRMWARE_VOLUME_HEADER *CurrentFvAddress
)
/*++
Routine Description:
Verify a Firmware volume
Arguments:
CurrentFvAddress - Pointer to the current Firmware Volume under consideration
Returns:
EFI_SUCCESS - Firmware Volume is legal
EFI_SECURITY_VIOLATION - Firmware Volume fails integrity test
--*/
{
//
// Right now just pass the test. Future can authenticate and/or check the
// FV-header or other metric for goodness of binary.
//
return EFI_SUCCESS;
}

View File

@ -0,0 +1,100 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
StatusCode.c
Abstract:
Pei Core Status Code Support
Revision History
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <PeiMain.h>
EFI_STATUS
EFIAPI
PeiReportStatusCode (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_STATUS_CODE_TYPE CodeType,
IN EFI_STATUS_CODE_VALUE Value,
IN UINT32 Instance,
IN EFI_GUID *CallerId,
IN EFI_STATUS_CODE_DATA *Data OPTIONAL
)
/*++
Routine Description:
Core version of the Status Code reporter
Arguments:
PeiServices - The PEI core services table.
CodeType - Type of Status Code.
Value - Value to output for Status Code.
Instance - Instance Number of this status code.
CallerId - ID of the caller of this status code.
Data - Optional data associated with this status code.
Returns:
Status - EFI_SUCCESS if status code is successfully reported
- EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed
--*/
{
EFI_STATUS Status;
EFI_PEI_PROGRESS_CODE_PPI *StatusCodePpi;
//
//Locate StatusCode Ppi.
//
Status = PeiServicesLocatePpi (
&gEfiPeiStatusCodePpiGuid,
0,
NULL,
(VOID **)&StatusCodePpi
);
if (!EFI_ERROR (Status)) {
Status = StatusCodePpi->ReportStatusCode (
PeiServices,
CodeType,
Value,
Instance,
CallerId,
Data
);
return Status;
}
return EFI_NOT_AVAILABLE_YET;
}

View File

@ -0,0 +1,72 @@
/** @file
Load image file from fv to memory.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name: LoadFile.h
@par Revision Reference:
This PPI is defined in PEI CIS spec Version 0.91.
**/
#ifndef __FV_FILE_LOADER_PPI_H__
#define __FV_FILE_LOADER_PPI_H__
#define EFI_PEI_FV_FILE_LOADER_GUID \
{ \
0x7e1f0d85, 0x4ff, 0x4bb2, {0x86, 0x6a, 0x31, 0xa2, 0x99, 0x6a, 0x48, 0xa8 } \
}
typedef struct _EFI_PEI_FV_FILE_LOADER_PPI EFI_PEI_FV_FILE_LOADER_PPI;
/**
Loads a PEIM into memory for subsequent execution.
@param This Interface pointer that implements the Load File PPI instance.
@param FfsHeader Pointer to the FFS header of the file to load.
@param ImageAddress Pointer to the address of the loaded Image
@param ImageSize Pointer to the size of the loaded image.
@param EntryPoint Pointer to the entry point of the image.
@retval EFI_SUCCESS The image was loaded successfully.
@retval EFI_OUT_OF_RESOURCES There was not enough memory.
@retval EFI_INVALID_PARAMETER The contents of the FFS file did not
contain a valid PE/COFF image that could be loaded.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_PEI_FV_LOAD_FILE) (
IN EFI_PEI_FV_FILE_LOADER_PPI *This,
IN EFI_FFS_FILE_HEADER *FfsHeader,
OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
OUT UINT64 *ImageSize,
OUT EFI_PHYSICAL_ADDRESS *EntryPoint
);
/**
@par Ppi Description:
This PPI is a pointer to the Load File service. This service will be
published by a PEIM.The PEI Foundation will use this service to
launch the known non-XIP PE/COFF PEIM images. This service may
depend upon the presence of the EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI.
@param FvLoadFile
Loads a PEIM into memory for subsequent execution
**/
struct _EFI_PEI_FV_FILE_LOADER_PPI {
EFI_PEI_FV_LOAD_FILE FvLoadFile;
};
extern EFI_GUID gEfiPeiFvFileLoaderPpiGuid;
#endif

View File

@ -66,7 +66,8 @@
gEfiMdePkgTokenSpaceGuid = { 0xA1AFF049, 0xFDEB, 0x442a, { 0xB3, 0x20, 0x13, 0xAB, 0x4C, 0xB7, 0x2B, 0xBC }}
##gEfiPeiPeCoffLoaderGuid will be removed in future
gEfiPeiPeCoffLoaderGuid = { 0xd8117cff, 0x94a6, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
gEfiPeiCorePrivateGuid = { 0xd641a0f5, 0xcb7c, 0x4846, { 0xa3, 0x80, 0x1d, 0x01, 0xb4, 0xd9, 0xe3, 0xb9 }}
################################################################################
#
# Global Protocols Definition section - list of Global Protocols C Name Data
@ -102,8 +103,7 @@
################################################################################
[Ppis.common]
gPeiBaseMemoryTestPpiGuid = { 0xB6EC423C, 0x21D2, 0x490D, { 0x85, 0xC6, 0xDD, 0x58, 0x64, 0xEA, 0xA6, 0x74 }}
gEfiPeiFvFileLoaderPpiGuid = { 0x7e1f0d85, 0x04ff, 0x4bb2, { 0x86, 0x6a, 0x31, 0xa2, 0x99, 0x6a, 0x48, 0xa8 }}
################################################################################

View File

@ -77,7 +77,10 @@
PcdLib|${WORKSPACE}/MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
PeiServiceLib|${WORKSPACE}/MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
PeiServicesTablePointerLib|${WORKSPACE}/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
ReportStatusCodeLib|${WORKSPACE}/IntelFrameworkPkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
PeiServicesLib|$(WORKSPACE)/MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
PeCoffGetEntryPointLib|$(WORKSPACE)/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
[LibraryClasses.common.PEIM]
HobLib|${WORKSPACE}/MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|${WORKSPACE}/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
@ -373,6 +376,7 @@
${WORKSPACE}/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.inf
$(WORKSPACE)/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
$(WORKSPACE)/MdeModulePkg/Universal/PCD/Pei/Pcd.inf
$(WORKSPACE)/MdeModulePkg/Core/Pei/PeiMain.inf
[Components.X64]
${WORKSPACE}/MdeModulePkg/Application/HelloWorld/HelloWorld.inf

View File

@ -25,6 +25,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Pi/PiPeiCis.h>
#include <Uefi/UefiMultiPhase.h>
//
// BUGBUG: The EFI_PEI_STARTUP_DESCRIPTOR definition does not follows PI specification.
// After enabling PI for Nt32Pkg and tools generate correct autogen for PEI_CORE,
// the following structure should be removed at once.
//
typedef struct {
UINTN BootFirmwareVolume;
UINTN SizeOfCacheAsRam;
EFI_PEI_PPI_DESCRIPTOR *DispatchTable;
} EFI_PEI_STARTUP_DESCRIPTOR;
#endif

View File

@ -19,7 +19,8 @@
//
// The package level header files this module uses
//
#include <Peim.h>
#include <PiPei.h>
#include <IndustryStandard/PeImage.h>
#include <WinNtPeim.h>
//
// The protocols, PPI and GUID defintions for this module

View File

@ -367,4 +367,6 @@
$(WORKSPACE)/IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.inf
$(WORKSPACE)/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.inf ##This driver follows UEFI specification definition
$(WORKSPACE)/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.inf ##This driver follows UEFI specification definition
$(WORKSPACE)/Nt32Pkg/Sec/SecMain.inf
$(WORKSPACE)/Nt32Pkg/Sec/SecMain.inf
$(WORKSPACE)/MdeModulePkg/Core/Pei/PeiMain.inf