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:
@ -22,12 +22,6 @@
|
|||||||
|
|
||||||
#include <PiPei.h>
|
#include <PiPei.h>
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
UINTN BootFirmwareVolume;
|
|
||||||
UINTN SizeOfCacheAsRam;
|
|
||||||
EFI_PEI_PPI_DESCRIPTOR *DispatchTable;
|
|
||||||
} EFI_PEI_STARTUP_DESCRIPTOR;
|
|
||||||
|
|
||||||
#include <Common/FrameworkFirmwareFileSystem.h>
|
#include <Common/FrameworkFirmwareFileSystem.h>
|
||||||
#include <Common/FrameworkHob.h>
|
#include <Common/FrameworkHob.h>
|
||||||
#include <Common/FrameworkLegacy16.h>
|
#include <Common/FrameworkLegacy16.h>
|
||||||
|
111
MdeModulePkg/Core/Pei/BootMode/BootMode.c
Normal file
111
MdeModulePkg/Core/Pei/BootMode/BootMode.c
Normal 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;
|
||||||
|
}
|
44
MdeModulePkg/Core/Pei/CommonHeader.h
Normal file
44
MdeModulePkg/Core/Pei/CommonHeader.h
Normal 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
|
267
MdeModulePkg/Core/Pei/Dependency/dependency.c
Normal file
267
MdeModulePkg/Core/Pei/Dependency/dependency.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
MdeModulePkg/Core/Pei/Dependency/dependency.h
Normal file
43
MdeModulePkg/Core/Pei/Dependency/dependency.h
Normal 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
|
543
MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
Normal file
543
MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
Normal 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));
|
||||||
|
}
|
||||||
|
|
55
MdeModulePkg/Core/Pei/Dispatcher/Stack.c
Normal file
55
MdeModulePkg/Core/Pei/Dispatcher/Stack.c
Normal 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);
|
||||||
|
}
|
479
MdeModulePkg/Core/Pei/FwVol/FwVol.c
Normal file
479
MdeModulePkg/Core/Pei/FwVol/FwVol.c
Normal 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;
|
||||||
|
}
|
197
MdeModulePkg/Core/Pei/Hob/Hob.c
Normal file
197
MdeModulePkg/Core/Pei/Hob/Hob.c
Normal 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;
|
||||||
|
}
|
272
MdeModulePkg/Core/Pei/Image/Image.c
Normal file
272
MdeModulePkg/Core/Pei/Image/Image.c
Normal 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;
|
||||||
|
}
|
98
MdeModulePkg/Core/Pei/Ipf/IpfCpuCore.i
Normal file
98
MdeModulePkg/Core/Pei/Ipf/IpfCpuCore.i
Normal 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
|
197
MdeModulePkg/Core/Pei/Ipf/IpfCpuCore.s
Normal file
197
MdeModulePkg/Core/Pei/Ipf/IpfCpuCore.s
Normal 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)
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
57
MdeModulePkg/Core/Pei/Ipf/IpfPeiMain.h
Normal file
57
MdeModulePkg/Core/Pei/Ipf/IpfPeiMain.h
Normal 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
|
63
MdeModulePkg/Core/Pei/Ipf/Stack.c
Normal file
63
MdeModulePkg/Core/Pei/Ipf/Stack.c
Normal 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
|
||||||
|
);
|
||||||
|
}
|
76
MdeModulePkg/Core/Pei/Ipf/SwitchToCacheMode.c
Normal file
76
MdeModulePkg/Core/Pei/Ipf/SwitchToCacheMode.c
Normal 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;
|
||||||
|
}
|
326
MdeModulePkg/Core/Pei/Memory/MemoryServices.c
Normal file
326
MdeModulePkg/Core/Pei/Memory/MemoryServices.c
Normal 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;
|
||||||
|
}
|
1147
MdeModulePkg/Core/Pei/PeiMain.h
Normal file
1147
MdeModulePkg/Core/Pei/PeiMain.h
Normal file
File diff suppressed because it is too large
Load Diff
146
MdeModulePkg/Core/Pei/PeiMain.inf
Normal file
146
MdeModulePkg/Core/Pei/PeiMain.inf
Normal 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
|
||||||
|
|
117
MdeModulePkg/Core/Pei/PeiMain.msa
Normal file
117
MdeModulePkg/Core/Pei/PeiMain.msa
Normal 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>
|
251
MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
Normal file
251
MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
663
MdeModulePkg/Core/Pei/Ppi/Ppi.c
Normal file
663
MdeModulePkg/Core/Pei/Ppi/Ppi.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
73
MdeModulePkg/Core/Pei/Reset/Reset.c
Normal file
73
MdeModulePkg/Core/Pei/Reset/Reset.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
199
MdeModulePkg/Core/Pei/Security/Security.c
Normal file
199
MdeModulePkg/Core/Pei/Security/Security.c
Normal 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;
|
||||||
|
}
|
100
MdeModulePkg/Core/Pei/StatusCode/StatusCode.c
Normal file
100
MdeModulePkg/Core/Pei/StatusCode/StatusCode.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
72
MdeModulePkg/Include/Ppi/LoadFile.h
Normal file
72
MdeModulePkg/Include/Ppi/LoadFile.h
Normal 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
|
@ -66,6 +66,7 @@
|
|||||||
gEfiMdePkgTokenSpaceGuid = { 0xA1AFF049, 0xFDEB, 0x442a, { 0xB3, 0x20, 0x13, 0xAB, 0x4C, 0xB7, 0x2B, 0xBC }}
|
gEfiMdePkgTokenSpaceGuid = { 0xA1AFF049, 0xFDEB, 0x442a, { 0xB3, 0x20, 0x13, 0xAB, 0x4C, 0xB7, 0x2B, 0xBC }}
|
||||||
##gEfiPeiPeCoffLoaderGuid will be removed in future
|
##gEfiPeiPeCoffLoaderGuid will be removed in future
|
||||||
gEfiPeiPeCoffLoaderGuid = { 0xd8117cff, 0x94a6, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
|
gEfiPeiPeCoffLoaderGuid = { 0xd8117cff, 0x94a6, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
|
||||||
|
gEfiPeiCorePrivateGuid = { 0xd641a0f5, 0xcb7c, 0x4846, { 0xa3, 0x80, 0x1d, 0x01, 0xb4, 0xd9, 0xe3, 0xb9 }}
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
@ -102,8 +103,7 @@
|
|||||||
################################################################################
|
################################################################################
|
||||||
[Ppis.common]
|
[Ppis.common]
|
||||||
gPeiBaseMemoryTestPpiGuid = { 0xB6EC423C, 0x21D2, 0x490D, { 0x85, 0xC6, 0xDD, 0x58, 0x64, 0xEA, 0xA6, 0x74 }}
|
gPeiBaseMemoryTestPpiGuid = { 0xB6EC423C, 0x21D2, 0x490D, { 0x85, 0xC6, 0xDD, 0x58, 0x64, 0xEA, 0xA6, 0x74 }}
|
||||||
|
gEfiPeiFvFileLoaderPpiGuid = { 0x7e1f0d85, 0x04ff, 0x4bb2, { 0x86, 0x6a, 0x31, 0xa2, 0x99, 0x6a, 0x48, 0xa8 }}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
@ -77,6 +77,9 @@
|
|||||||
PcdLib|${WORKSPACE}/MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
|
PcdLib|${WORKSPACE}/MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
|
||||||
PeiServiceLib|${WORKSPACE}/MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
|
PeiServiceLib|${WORKSPACE}/MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
|
||||||
PeiServicesTablePointerLib|${WORKSPACE}/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.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]
|
[LibraryClasses.common.PEIM]
|
||||||
HobLib|${WORKSPACE}/MdePkg/Library/PeiHobLib/PeiHobLib.inf
|
HobLib|${WORKSPACE}/MdePkg/Library/PeiHobLib/PeiHobLib.inf
|
||||||
@ -373,6 +376,7 @@
|
|||||||
${WORKSPACE}/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.inf
|
${WORKSPACE}/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.inf
|
||||||
$(WORKSPACE)/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
|
$(WORKSPACE)/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
|
||||||
$(WORKSPACE)/MdeModulePkg/Universal/PCD/Pei/Pcd.inf
|
$(WORKSPACE)/MdeModulePkg/Universal/PCD/Pei/Pcd.inf
|
||||||
|
$(WORKSPACE)/MdeModulePkg/Core/Pei/PeiMain.inf
|
||||||
|
|
||||||
[Components.X64]
|
[Components.X64]
|
||||||
${WORKSPACE}/MdeModulePkg/Application/HelloWorld/HelloWorld.inf
|
${WORKSPACE}/MdeModulePkg/Application/HelloWorld/HelloWorld.inf
|
||||||
|
@ -25,6 +25,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include <Pi/PiPeiCis.h>
|
#include <Pi/PiPeiCis.h>
|
||||||
#include <Uefi/UefiMultiPhase.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
|
#endif
|
||||||
|
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
//
|
//
|
||||||
// The package level header files this module uses
|
// The package level header files this module uses
|
||||||
//
|
//
|
||||||
#include <Peim.h>
|
#include <PiPei.h>
|
||||||
|
#include <IndustryStandard/PeImage.h>
|
||||||
#include <WinNtPeim.h>
|
#include <WinNtPeim.h>
|
||||||
//
|
//
|
||||||
// The protocols, PPI and GUID defintions for this module
|
// The protocols, PPI and GUID defintions for this module
|
||||||
|
@ -368,3 +368,5 @@
|
|||||||
$(WORKSPACE)/MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.inf ##This driver follows UEFI specification definition
|
$(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)/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
|
||||||
|
|
Reference in New Issue
Block a user