mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-08 17:05:09 +02:00
Check in DxeCore for Nt32 platform. Currently, it does not follow PI/UEFI2.1.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3045 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
db6c5cc103
commit
28a0029718
126
MdeModulePkg/Core/Dxe/DebugImageInfo.h
Normal file
126
MdeModulePkg/Core/Dxe/DebugImageInfo.h
Normal file
@ -0,0 +1,126 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
DebugImageInfo.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Support functions for managing debug image info table when loading and unloading
|
||||
images.
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef __DEBUG_IMAGE_INFO_H__
|
||||
#define __DEBUG_IMAGE_INFO_H__
|
||||
|
||||
#define FOUR_MEG_PAGES 0x400
|
||||
#define FOUR_MEG_MASK ((FOUR_MEG_PAGES * EFI_PAGE_SIZE) - 1)
|
||||
|
||||
#define EFI_DEBUG_TABLE_ENTRY_SIZE (sizeof (VOID *))
|
||||
|
||||
VOID
|
||||
CoreInitializeDebugImageInfoTable (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Creates and initializes the DebugImageInfo Table. Also creates the configuration
|
||||
table and registers it into the system table.
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Returns:
|
||||
NA
|
||||
|
||||
Notes:
|
||||
This function allocates memory, frees it, and then allocates memory at an
|
||||
address within the initial allocation. Since this function is called early
|
||||
in DXE core initialization (before drivers are dispatched), this should not
|
||||
be a problem.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
CoreUpdateDebugTableCrc32 (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Update the CRC32 in the Debug Table.
|
||||
Since the CRC32 service is made available by the Runtime driver, we have to
|
||||
wait for the Runtime Driver to be installed before the CRC32 can be computed.
|
||||
This function is called elsewhere by the core when the runtime architectural
|
||||
protocol is produced.
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Returns:
|
||||
NA
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
CoreNewDebugImageInfoEntry (
|
||||
UINT32 ImageInfoType,
|
||||
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
|
||||
EFI_HANDLE ImageHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates
|
||||
the table if it's not large enough to accomidate another entry.
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageInfoType - type of debug image information
|
||||
LoadedImage - pointer to the loaded image protocol for the image being loaded
|
||||
ImageHandle - image handle for the image being loaded
|
||||
|
||||
Returns:
|
||||
NA
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
CoreRemoveDebugImageInfoEntry (
|
||||
EFI_HANDLE ImageHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Removes and frees an entry from the DebugImageInfo Table.
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle - image handle for the image being unloaded
|
||||
|
||||
Returns:
|
||||
|
||||
NA
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
#endif
|
1170
MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
Normal file
1170
MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
Normal file
File diff suppressed because it is too large
Load Diff
452
MdeModulePkg/Core/Dxe/Dispatcher/dependency.c
Normal file
452
MdeModulePkg/Core/Dxe/Dispatcher/dependency.c
Normal file
@ -0,0 +1,452 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
DXE 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 <DxeMain.h>
|
||||
|
||||
//
|
||||
// Global stack used to evaluate dependency expressions
|
||||
//
|
||||
BOOLEAN *mDepexEvaluationStack = NULL;
|
||||
BOOLEAN *mDepexEvaluationStackEnd = NULL;
|
||||
BOOLEAN *mDepexEvaluationStackPointer = NULL;
|
||||
|
||||
//
|
||||
// Worker functions
|
||||
//
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
GrowDepexStack (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Grow size of the Depex stack
|
||||
|
||||
Arguments:
|
||||
|
||||
Stack - Old stack on the way in and new stack on the way out
|
||||
|
||||
StackSize - New size of the stack
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Stack successfully growed.
|
||||
|
||||
EFI_OUT_OF_RESOURCES - There is not enough system memory to grow the stack.
|
||||
|
||||
|
||||
|
||||
--*/
|
||||
{
|
||||
BOOLEAN *NewStack;
|
||||
UINTN Size;
|
||||
|
||||
Size = DEPEX_STACK_SIZE_INCREMENT;
|
||||
if (mDepexEvaluationStack != NULL) {
|
||||
Size = Size + (mDepexEvaluationStackEnd - mDepexEvaluationStack);
|
||||
}
|
||||
|
||||
NewStack = CoreAllocateBootServicesPool (Size * sizeof (BOOLEAN));
|
||||
if (NewStack == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
if (mDepexEvaluationStack != NULL) {
|
||||
//
|
||||
// Copy to Old Stack to the New Stack
|
||||
//
|
||||
CopyMem (
|
||||
NewStack,
|
||||
mDepexEvaluationStack,
|
||||
(mDepexEvaluationStackEnd - mDepexEvaluationStack) * sizeof (BOOLEAN)
|
||||
);
|
||||
|
||||
//
|
||||
// Free The Old Stack
|
||||
//
|
||||
CoreFreePool (mDepexEvaluationStack);
|
||||
}
|
||||
|
||||
//
|
||||
// Make the Stack pointer point to the old data in the new stack
|
||||
//
|
||||
mDepexEvaluationStackPointer = NewStack + (mDepexEvaluationStackPointer - mDepexEvaluationStack);
|
||||
mDepexEvaluationStack = NewStack;
|
||||
mDepexEvaluationStackEnd = NewStack + Size;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PushBool (
|
||||
IN BOOLEAN Value
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Push an element onto the Boolean Stack
|
||||
|
||||
Arguments:
|
||||
|
||||
Value - BOOLEAN to push.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The value was pushed onto the stack.
|
||||
|
||||
EFI_OUT_OF_RESOURCES - There is not enough system memory to grow the stack.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Check for a stack overflow condition
|
||||
//
|
||||
if (mDepexEvaluationStackPointer == mDepexEvaluationStackEnd) {
|
||||
//
|
||||
// Grow the stack
|
||||
//
|
||||
Status = GrowDepexStack ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Push the item onto the stack
|
||||
//
|
||||
*mDepexEvaluationStackPointer = Value;
|
||||
mDepexEvaluationStackPointer++;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
PopBool (
|
||||
OUT BOOLEAN *Value
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Pop an element from the Boolean stack.
|
||||
|
||||
Arguments:
|
||||
|
||||
Value - BOOLEAN to pop.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The value was popped onto the stack.
|
||||
|
||||
EFI_ACCESS_DENIED - The pop operation underflowed the stack
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// Check for a stack underflow condition
|
||||
//
|
||||
if (mDepexEvaluationStackPointer == mDepexEvaluationStack) {
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
//
|
||||
// Pop the item off the stack
|
||||
//
|
||||
mDepexEvaluationStackPointer--;
|
||||
*Value = *mDepexEvaluationStackPointer;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
CorePreProcessDepex (
|
||||
IN EFI_CORE_DRIVER_ENTRY *DriverEntry
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Preprocess dependency expression and update DriverEntry to reflect the
|
||||
state of Before, After, and SOR dependencies. If DriverEntry->Before
|
||||
or DriverEntry->After is set it will never be cleared. If SOR is set
|
||||
it will be cleared by CoreSchedule(), and then the driver can be
|
||||
dispatched.
|
||||
|
||||
Arguments:
|
||||
|
||||
DriverEntry - DriverEntry element to update
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - It always works.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT8 *Iterator;
|
||||
|
||||
Iterator = DriverEntry->Depex;
|
||||
if (*Iterator == EFI_DEP_SOR) {
|
||||
DriverEntry->Unrequested = TRUE;
|
||||
} else {
|
||||
DriverEntry->Dependent = TRUE;
|
||||
}
|
||||
|
||||
if (*Iterator == EFI_DEP_BEFORE) {
|
||||
DriverEntry->Before = TRUE;
|
||||
} else if (*Iterator == EFI_DEP_AFTER) {
|
||||
DriverEntry->After = TRUE;
|
||||
}
|
||||
|
||||
if (DriverEntry->Before || DriverEntry->After) {
|
||||
CopyMem (&DriverEntry->BeforeAfterGuid, Iterator + 1, sizeof (EFI_GUID));
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
CoreIsSchedulable (
|
||||
IN EFI_CORE_DRIVER_ENTRY *DriverEntry
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This is the POSTFIX version of the dependency evaluator. This code does
|
||||
not need to handle Before or After, as it is not valid to call this
|
||||
routine in this case. The SOR is just ignored and is a nop in the grammer.
|
||||
|
||||
POSTFIX means all the math is done on top of the stack.
|
||||
|
||||
Arguments:
|
||||
|
||||
DriverEntry - DriverEntry element to update
|
||||
|
||||
Returns:
|
||||
|
||||
TRUE - If driver is ready to run.
|
||||
|
||||
FALSE - If driver is not ready to run or some fatal error was found.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT8 *Iterator;
|
||||
BOOLEAN Operator;
|
||||
BOOLEAN Operator2;
|
||||
EFI_GUID DriverGuid;
|
||||
VOID *Interface;
|
||||
|
||||
if (DriverEntry->After || DriverEntry->Before) {
|
||||
//
|
||||
// If Before or After Depex skip as CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter ()
|
||||
// processes them.
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (DriverEntry->Depex == NULL) {
|
||||
//
|
||||
// A NULL Depex means treat the driver like an EFI 1.0 thing.
|
||||
//
|
||||
Status = CoreAllEfiServicesAvailable ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Clean out memory leaks in Depex Boolean stack. Leaks are only caused by
|
||||
// incorrectly formed DEPEX expressions
|
||||
//
|
||||
mDepexEvaluationStackPointer = mDepexEvaluationStack;
|
||||
|
||||
|
||||
Iterator = DriverEntry->Depex;
|
||||
|
||||
while (TRUE) {
|
||||
//
|
||||
// Check to see if we are attempting to fetch dependency expression instructions
|
||||
// past the end of the dependency expression.
|
||||
//
|
||||
if (((UINTN)Iterator - (UINTN)DriverEntry->Depex) >= DriverEntry->DepexSize) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Look at the opcode of the dependency expression instruction.
|
||||
//
|
||||
switch (*Iterator) {
|
||||
case EFI_DEP_BEFORE:
|
||||
case EFI_DEP_AFTER:
|
||||
//
|
||||
// For a well-formed Dependency Expression, the code should never get here.
|
||||
// The BEFORE and AFTER are processed prior to this routine's invocation.
|
||||
// If the code flow arrives at this point, there was a BEFORE or AFTER
|
||||
// that were not the first opcodes.
|
||||
//
|
||||
ASSERT (FALSE);
|
||||
case EFI_DEP_SOR:
|
||||
//
|
||||
// These opcodes can only appear once as the first opcode. If it is found
|
||||
// at any other location, then the dependency expression evaluates to FALSE
|
||||
//
|
||||
if (Iterator != DriverEntry->Depex) {
|
||||
return FALSE;
|
||||
}
|
||||
//
|
||||
// Otherwise, it is the first opcode and should be treated as a NOP.
|
||||
//
|
||||
break;
|
||||
|
||||
case EFI_DEP_PUSH:
|
||||
//
|
||||
// Push operator is followed by a GUID. Test to see if the GUID protocol
|
||||
// is installed and push the boolean result on the stack.
|
||||
//
|
||||
CopyMem (&DriverGuid, Iterator + 1, sizeof (EFI_GUID));
|
||||
|
||||
Status = CoreLocateProtocol (&DriverGuid, NULL, &Interface);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = PushBool (FALSE);
|
||||
} else {
|
||||
*Iterator = EFI_DEP_REPLACE_TRUE;
|
||||
Status = PushBool (TRUE);
|
||||
}
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Iterator += sizeof (EFI_GUID);
|
||||
break;
|
||||
|
||||
case EFI_DEP_AND:
|
||||
Status = PopBool (&Operator);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = PopBool (&Operator2);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = PushBool ((BOOLEAN)(Operator && Operator2));
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case EFI_DEP_OR:
|
||||
Status = PopBool (&Operator);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = PopBool (&Operator2);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = PushBool ((BOOLEAN)(Operator || Operator2));
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case EFI_DEP_NOT:
|
||||
Status = PopBool (&Operator);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = PushBool ((BOOLEAN)(!Operator));
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case EFI_DEP_TRUE:
|
||||
Status = PushBool (TRUE);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case EFI_DEP_FALSE:
|
||||
Status = PushBool (FALSE);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case EFI_DEP_END:
|
||||
Status = PopBool (&Operator);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
return Operator;
|
||||
|
||||
case EFI_DEP_REPLACE_TRUE:
|
||||
Status = PushBool (TRUE);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Iterator += sizeof (EFI_GUID);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Skip over the Dependency Op Code we just processed in the switch.
|
||||
// The math is done out of order, but it should not matter. That is
|
||||
// we may add in the sizeof (EFI_GUID) before we account for the OP Code.
|
||||
// This is not an issue, since we just need the correct end result. You
|
||||
// need to be careful using Iterator in the loop as it's intermediate value
|
||||
// may be strange.
|
||||
//
|
||||
Iterator++;
|
||||
}
|
||||
|
||||
Done:
|
||||
return FALSE;
|
||||
}
|
||||
|
2847
MdeModulePkg/Core/Dxe/DxeMain.h
Normal file
2847
MdeModulePkg/Core/Dxe/DxeMain.h
Normal file
File diff suppressed because it is too large
Load Diff
175
MdeModulePkg/Core/Dxe/DxeMain.inf
Normal file
175
MdeModulePkg/Core/Dxe/DxeMain.inf
Normal file
@ -0,0 +1,175 @@
|
||||
#/** @file
|
||||
# Component description file for DxeMain module.
|
||||
#
|
||||
# This module provide an DXE CIS compliant implementation of DXE Core.
|
||||
# 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 = DxeMain
|
||||
FILE_GUID = D6A2CB7F-6A18-4e2f-B43B-9920A733700A
|
||||
MODULE_TYPE = DXE_CORE
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
ENTRY_POINT = DxeMain
|
||||
|
||||
#
|
||||
# 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]
|
||||
Library.h
|
||||
imem.h
|
||||
Image.h
|
||||
hand.h
|
||||
gcd.h
|
||||
FwVolDriver.h
|
||||
FwVolBlock.h
|
||||
Exec.h
|
||||
DxeMain.h
|
||||
DebugImageInfo.h
|
||||
SectionExtraction/CoreSectionExtraction.c
|
||||
Image/ImageFile.c
|
||||
Image/Image.c
|
||||
Misc/DebugImageInfo.c
|
||||
Misc/Stall.c
|
||||
Misc/SetWatchdogTimer.c
|
||||
Misc/InstallConfigurationTable.c
|
||||
Library/Library.c
|
||||
Hand/DriverSupport.c
|
||||
Hand/Notify.c
|
||||
Hand/locate.c
|
||||
Hand/handle.c
|
||||
Gcd/gcd.c
|
||||
Mem/pool.c
|
||||
Mem/Page.c
|
||||
Mem/memdata.c
|
||||
FwVolBlock/FwVolBlock.c
|
||||
FwVol/FwVolWrite.c
|
||||
FwVol/FwVolRead.c
|
||||
FwVol/FwVolAttrib.c
|
||||
FwVol/Ffs.c
|
||||
FwVol/FwVol.c
|
||||
Event/tpl.c
|
||||
Event/timer.c
|
||||
Event/event.c
|
||||
Event/execdata.c
|
||||
Dispatcher/dependency.c
|
||||
Dispatcher/Dispatcher.c
|
||||
DxeMain/DxeProtocolNotify.c
|
||||
DxeMain/DxeMain.c
|
||||
CommonHeader.h
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Package Dependency Section - list of Package files that are required for
|
||||
# this module.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Library Class Section - list of Library Classes that are required for
|
||||
# this module.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
[LibraryClasses]
|
||||
BaseMemoryLib
|
||||
CacheMaintenanceLib
|
||||
PeCoffLoaderLib
|
||||
UefiDecompressLib
|
||||
PerformanceLib
|
||||
HobLib
|
||||
BaseLib
|
||||
UefiLib
|
||||
DebugLib
|
||||
DxeCoreEntryPoint
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Guid C Name Section - list of Guids that this module uses or produces.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
[Guids]
|
||||
gEfiEventLegacyBootGuid # ALWAYS_CONSUMED
|
||||
gEfiEventReadyToBootGuid # ALWAYS_CONSUMED
|
||||
gEfiEventMemoryMapChangeGuid # ALWAYS_CONSUMED
|
||||
gEfiEventVirtualAddressChangeGuid # ALWAYS_CONSUMED
|
||||
gEfiEventExitBootServicesGuid # ALWAYS_CONSUMED
|
||||
gEfiHobMemoryAllocModuleGuid # ALWAYS_CONSUMED
|
||||
gEfiFileInfoGuid # ALWAYS_CONSUMED
|
||||
gEfiFirmwareFileSystemGuid # ALWAYS_CONSUMED
|
||||
gAprioriGuid # ALWAYS_CONSUMED
|
||||
gEfiDebugImageInfoTableGuid # ALWAYS_CONSUMED
|
||||
gEfiHobListGuid # ALWAYS_CONSUMED
|
||||
gEfiDxeServicesTableGuid # ALWAYS_CONSUMED
|
||||
gEfiMemoryTypeInformationGuid # ALWAYS_CONSUMED
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Protocol C Name Section - list of Protocol and Protocol Notify C Names
|
||||
# that this module uses or produces.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
[Protocols]
|
||||
gEfiStatusCodeRuntimeProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
|
||||
gEfiCapsuleArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiTianoDecompressProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiCustomizedDecompressProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDecompressProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiLoadPeImageProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
||||
gEfiSimpleFileSystemProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiLoadFileProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiResetArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiRealTimeClockArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiRuntimeArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiWatchdogTimerArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiSecurityArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiVariableArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiBdsArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiVariableWriteArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiMonotonicCounterArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiMetronomeArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiTimerArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiBusSpecificDriverOverrideProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiPlatformDriverOverrideProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDriverBindingProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
|
||||
gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
||||
gEfiFirmwareVolumeDispatchProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
||||
gEfiFirmwareVolumeProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
||||
gEfiCpuArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiLoadedImageProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
||||
gEfiEbcProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
|
||||
gEfiSectionExtractionProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
243
MdeModulePkg/Core/Dxe/DxeMain.msa
Normal file
243
MdeModulePkg/Core/Dxe/DxeMain.msa
Normal file
@ -0,0 +1,243 @@
|
||||
<?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>DxeMain</ModuleName>
|
||||
<ModuleType>DXE_CORE</ModuleType>
|
||||
<GuidValue>D6A2CB7F-6A18-4e2f-B43B-9920A733700A</GuidValue>
|
||||
<Version>1.0</Version>
|
||||
<Abstract>Component description file for DxeMain module.</Abstract>
|
||||
<Description>This module provide an DXE CIS compliant implementation of DXE Core.</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>DxeMain</OutputFileBasename>
|
||||
</ModuleDefinitions>
|
||||
<LibraryClassDefinitions>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>DxeCoreEntryPoint</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>DebugLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiLib</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>UefiDecompressLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>TianoDecompressLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>CustomDecompressLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>EdkPeCoffLoaderLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>CacheMaintenanceLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>BaseMemoryLib</Keyword>
|
||||
</LibraryClass>
|
||||
</LibraryClassDefinitions>
|
||||
<SourceFiles>
|
||||
<Filename>DxeMain/DxeMain.c</Filename>
|
||||
<Filename>DxeMain/DxeProtocolNotify.c</Filename>
|
||||
<Filename>Dispatcher/Dispatcher.c</Filename>
|
||||
<Filename>Dispatcher/dependency.c</Filename>
|
||||
<Filename>Event/execdata.c</Filename>
|
||||
<Filename>Event/event.c</Filename>
|
||||
<Filename>Event/timer.c</Filename>
|
||||
<Filename>Event/tpl.c</Filename>
|
||||
<Filename>FwVol/FwVol.c</Filename>
|
||||
<Filename>FwVol/Ffs.c</Filename>
|
||||
<Filename>FwVol/FwVolAttrib.c</Filename>
|
||||
<Filename>FwVol/FwVolRead.c</Filename>
|
||||
<Filename>FwVol/FwVolWrite.c</Filename>
|
||||
<Filename>FwVolBlock/FwVolBlock.c</Filename>
|
||||
<Filename>Mem/memdata.c</Filename>
|
||||
<Filename>Mem/Page.c</Filename>
|
||||
<Filename>Mem/pool.c</Filename>
|
||||
<Filename>Gcd/gcd.c</Filename>
|
||||
<Filename>Hand/handle.c</Filename>
|
||||
<Filename>Hand/locate.c</Filename>
|
||||
<Filename>Hand/Notify.c</Filename>
|
||||
<Filename>Hand/DriverSupport.c</Filename>
|
||||
<Filename>Library/Library.c</Filename>
|
||||
<Filename>Misc/InstallConfigurationTable.c</Filename>
|
||||
<Filename>Misc/SetWatchdogTimer.c</Filename>
|
||||
<Filename>Misc/Stall.c</Filename>
|
||||
<Filename>Misc/DebugImageInfo.c</Filename>
|
||||
<Filename>Image/Image.c</Filename>
|
||||
<Filename>Image/ImageFile.c</Filename>
|
||||
<Filename>SectionExtraction/CoreSectionExtraction.c</Filename>
|
||||
<Filename>DebugImageInfo.h</Filename>
|
||||
<Filename>DxeMain.h</Filename>
|
||||
<Filename>Exec.h</Filename>
|
||||
<Filename>FwVolBlock.h</Filename>
|
||||
<Filename>FwVolDriver.h</Filename>
|
||||
<Filename>gcd.h</Filename>
|
||||
<Filename>hand.h</Filename>
|
||||
<Filename>Image.h</Filename>
|
||||
<Filename>imem.h</Filename>
|
||||
<Filename>Library.h</Filename>
|
||||
</SourceFiles>
|
||||
<PackageDependencies>
|
||||
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
|
||||
<Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
|
||||
</PackageDependencies>
|
||||
<Protocols>
|
||||
<Protocol Usage="SOMETIMES_CONSUMED">
|
||||
<ProtocolCName>gEfiEbcProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_PRODUCED">
|
||||
<ProtocolCName>gEfiLoadedImageProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiCpuArchProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_PRODUCED">
|
||||
<ProtocolCName>gEfiFirmwareVolumeProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_PRODUCED">
|
||||
<ProtocolCName>gEfiFirmwareVolumeDispatchProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_PRODUCED">
|
||||
<ProtocolCName>gEfiFirmwareVolumeBlockProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_PRODUCED">
|
||||
<ProtocolCName>gEfiSectionExtractionProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="SOMETIMES_CONSUMED">
|
||||
<ProtocolCName>gEfiDriverBindingProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiPlatformDriverOverrideProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiBusSpecificDriverOverrideProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiTimerArchProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiMetronomeArchProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiMonotonicCounterArchProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiVariableWriteArchProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiBdsArchProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiVariableArchProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiSecurityArchProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiWatchdogTimerArchProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiRuntimeArchProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiRealTimeClockArchProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiResetArchProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiLoadFileProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiSimpleFileSystemProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_PRODUCED">
|
||||
<ProtocolCName>gEfiLoadPeImageProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiDecompressProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiCustomizedDecompressProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiTianoDecompressProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiCapsuleArchProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="SOMETIMES_CONSUMED">
|
||||
<ProtocolCName>gEfiStatusCodeRuntimeProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
</Protocols>
|
||||
<Guids>
|
||||
<GuidCNames Usage="ALWAYS_CONSUMED">
|
||||
<GuidCName>gEfiMemoryTypeInformationGuid</GuidCName>
|
||||
</GuidCNames>
|
||||
<GuidCNames Usage="ALWAYS_CONSUMED">
|
||||
<GuidCName>gEfiDxeServicesTableGuid</GuidCName>
|
||||
</GuidCNames>
|
||||
<GuidCNames Usage="ALWAYS_CONSUMED">
|
||||
<GuidCName>gEfiHobListGuid</GuidCName>
|
||||
</GuidCNames>
|
||||
<GuidCNames Usage="ALWAYS_CONSUMED">
|
||||
<GuidCName>gEfiDebugImageInfoTableGuid</GuidCName>
|
||||
</GuidCNames>
|
||||
<GuidCNames Usage="ALWAYS_CONSUMED">
|
||||
<GuidCName>gAprioriGuid</GuidCName>
|
||||
</GuidCNames>
|
||||
<GuidCNames Usage="ALWAYS_CONSUMED">
|
||||
<GuidCName>gEfiFirmwareFileSystemGuid</GuidCName>
|
||||
</GuidCNames>
|
||||
<GuidCNames Usage="ALWAYS_CONSUMED">
|
||||
<GuidCName>gEfiFileInfoGuid</GuidCName>
|
||||
</GuidCNames>
|
||||
<GuidCNames Usage="ALWAYS_CONSUMED">
|
||||
<GuidCName>gEfiHobMemoryAllocModuleGuid</GuidCName>
|
||||
</GuidCNames>
|
||||
<GuidCNames Usage="ALWAYS_CONSUMED">
|
||||
<GuidCName>gEfiEventExitBootServicesGuid</GuidCName>
|
||||
</GuidCNames>
|
||||
<GuidCNames Usage="ALWAYS_CONSUMED">
|
||||
<GuidCName>gEfiEventVirtualAddressChangeGuid</GuidCName>
|
||||
</GuidCNames>
|
||||
<GuidCNames Usage="ALWAYS_CONSUMED">
|
||||
<GuidCName>gEfiEventMemoryMapChangeGuid</GuidCName>
|
||||
</GuidCNames>
|
||||
<GuidCNames Usage="ALWAYS_CONSUMED">
|
||||
<GuidCName>gEfiEventReadyToBootGuid</GuidCName>
|
||||
</GuidCNames>
|
||||
<GuidCNames Usage="ALWAYS_CONSUMED">
|
||||
<GuidCName>gEfiEventLegacyBootGuid</GuidCName>
|
||||
</GuidCNames>
|
||||
</Guids>
|
||||
<Externs>
|
||||
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
|
||||
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
|
||||
<Extern>
|
||||
<ModuleEntryPoint>DxeMain</ModuleEntryPoint>
|
||||
</Extern>
|
||||
</Externs>
|
||||
</ModuleSurfaceArea>
|
874
MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
Normal file
874
MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
Normal file
@ -0,0 +1,874 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
DxeMain.c
|
||||
|
||||
Abstract:
|
||||
|
||||
DXE Core Main Entry Point
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
//
|
||||
// DXE Core Global Variables for Protocols from PEI
|
||||
//
|
||||
EFI_HANDLE mDecompressHandle = NULL;
|
||||
EFI_PEI_PE_COFF_LOADER_PROTOCOL *gEfiPeiPeCoffLoader = NULL;
|
||||
|
||||
//
|
||||
// DXE Core globals for Architecture Protocols
|
||||
//
|
||||
EFI_SECURITY_ARCH_PROTOCOL *gSecurity = NULL;
|
||||
EFI_CPU_ARCH_PROTOCOL *gCpu = NULL;
|
||||
EFI_METRONOME_ARCH_PROTOCOL *gMetronome = NULL;
|
||||
EFI_TIMER_ARCH_PROTOCOL *gTimer = NULL;
|
||||
EFI_BDS_ARCH_PROTOCOL *gBds = NULL;
|
||||
EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *gWatchdogTimer = NULL;
|
||||
|
||||
|
||||
//
|
||||
// BugBug: I'n not runtime, but is the PPI?
|
||||
//
|
||||
EFI_STATUS_CODE_PROTOCOL gStatusCodeInstance = {
|
||||
NULL
|
||||
};
|
||||
|
||||
EFI_STATUS_CODE_PROTOCOL *gStatusCode = &gStatusCodeInstance;
|
||||
|
||||
|
||||
//
|
||||
// DXE Core Global used to update core loaded image protocol handle
|
||||
//
|
||||
EFI_GUID *gDxeCoreFileName;
|
||||
EFI_LOADED_IMAGE_PROTOCOL *gDxeCoreLoadedImage;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// DXE Core Module Variables
|
||||
//
|
||||
|
||||
EFI_BOOT_SERVICES mBootServices = {
|
||||
{
|
||||
EFI_BOOT_SERVICES_SIGNATURE, // Signature
|
||||
EFI_BOOT_SERVICES_REVISION, // Revision
|
||||
sizeof (EFI_BOOT_SERVICES), // HeaderSize
|
||||
0, // CRC32
|
||||
0 // Reserved
|
||||
},
|
||||
(EFI_RAISE_TPL) CoreRaiseTpl, // RaiseTPL
|
||||
(EFI_RESTORE_TPL) CoreRestoreTpl, // RestoreTPL
|
||||
(EFI_ALLOCATE_PAGES) CoreAllocatePages, // AllocatePages
|
||||
(EFI_FREE_PAGES) CoreFreePages, // FreePages
|
||||
(EFI_GET_MEMORY_MAP) CoreGetMemoryMap, // GetMemoryMap
|
||||
(EFI_ALLOCATE_POOL) CoreAllocatePool, // AllocatePool
|
||||
(EFI_FREE_POOL) CoreFreePool, // FreePool
|
||||
(EFI_CREATE_EVENT) CoreCreateEvent, // CreateEvent
|
||||
(EFI_SET_TIMER) CoreSetTimer, // SetTimer
|
||||
(EFI_WAIT_FOR_EVENT) CoreWaitForEvent, // WaitForEvent
|
||||
(EFI_SIGNAL_EVENT) CoreSignalEvent, // SignalEvent
|
||||
(EFI_CLOSE_EVENT) CoreCloseEvent, // CloseEvent
|
||||
(EFI_CHECK_EVENT) CoreCheckEvent, // CheckEvent
|
||||
(EFI_INSTALL_PROTOCOL_INTERFACE) CoreInstallProtocolInterface, // InstallProtocolInterface
|
||||
(EFI_REINSTALL_PROTOCOL_INTERFACE) CoreReinstallProtocolInterface, // ReinstallProtocolInterface
|
||||
(EFI_UNINSTALL_PROTOCOL_INTERFACE) CoreUninstallProtocolInterface, // UninstallProtocolInterface
|
||||
(EFI_HANDLE_PROTOCOL) CoreHandleProtocol, // HandleProtocol
|
||||
(VOID *) NULL, // Reserved
|
||||
(EFI_REGISTER_PROTOCOL_NOTIFY) CoreRegisterProtocolNotify, // RegisterProtocolNotify
|
||||
(EFI_LOCATE_HANDLE) CoreLocateHandle, // LocateHandle
|
||||
(EFI_LOCATE_DEVICE_PATH) CoreLocateDevicePath, // LocateDevicePath
|
||||
(EFI_INSTALL_CONFIGURATION_TABLE) CoreInstallConfigurationTable, // InstallConfigurationTable
|
||||
(EFI_IMAGE_LOAD) CoreLoadImage, // LoadImage
|
||||
(EFI_IMAGE_START) CoreStartImage, // StartImage
|
||||
(EFI_EXIT) CoreExit, // Exit
|
||||
(EFI_IMAGE_UNLOAD) CoreUnloadImage, // UnloadImage
|
||||
(EFI_EXIT_BOOT_SERVICES) CoreExitBootServices, // ExitBootServices
|
||||
(EFI_GET_NEXT_MONOTONIC_COUNT) CoreEfiNotAvailableYetArg1, // GetNextMonotonicCount
|
||||
(EFI_STALL) CoreStall, // Stall
|
||||
(EFI_SET_WATCHDOG_TIMER) CoreSetWatchdogTimer, // SetWatchdogTimer
|
||||
(EFI_CONNECT_CONTROLLER) CoreConnectController, // ConnectController
|
||||
(EFI_DISCONNECT_CONTROLLER) CoreDisconnectController, // DisconnectController
|
||||
(EFI_OPEN_PROTOCOL) CoreOpenProtocol, // OpenProtocol
|
||||
(EFI_CLOSE_PROTOCOL) CoreCloseProtocol, // CloseProtocol
|
||||
(EFI_OPEN_PROTOCOL_INFORMATION) CoreOpenProtocolInformation, // OpenProtocolInformation
|
||||
(EFI_PROTOCOLS_PER_HANDLE) CoreProtocolsPerHandle, // ProtocolsPerHandle
|
||||
(EFI_LOCATE_HANDLE_BUFFER) CoreLocateHandleBuffer, // LocateHandleBuffer
|
||||
(EFI_LOCATE_PROTOCOL) CoreLocateProtocol, // LocateProtocol
|
||||
(EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES) CoreInstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces
|
||||
(EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES) CoreUninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces
|
||||
(EFI_CALCULATE_CRC32) CoreEfiNotAvailableYetArg3, // CalculateCrc32
|
||||
(EFI_COPY_MEM) CopyMem, // CopyMem
|
||||
(EFI_SET_MEM) SetMem, // SetMem
|
||||
(EFI_CREATE_EVENT_EX) CoreCreateEventEx // CreateEventEx
|
||||
};
|
||||
|
||||
EFI_DXE_SERVICES mDxeServices = {
|
||||
{
|
||||
DXE_SERVICES_SIGNATURE, // Signature
|
||||
DXE_SERVICES_REVISION, // Revision
|
||||
sizeof (DXE_SERVICES), // HeaderSize
|
||||
0, // CRC32
|
||||
0 // Reserved
|
||||
},
|
||||
(EFI_ADD_MEMORY_SPACE) CoreAddMemorySpace, // AddMemorySpace
|
||||
(EFI_ALLOCATE_MEMORY_SPACE) CoreAllocateMemorySpace, // AllocateMemorySpace
|
||||
(EFI_FREE_MEMORY_SPACE) CoreFreeMemorySpace, // FreeMemorySpace
|
||||
(EFI_REMOVE_MEMORY_SPACE) CoreRemoveMemorySpace, // RemoveMemorySpace
|
||||
(EFI_GET_MEMORY_SPACE_DESCRIPTOR) CoreGetMemorySpaceDescriptor, // GetMemorySpaceDescriptor
|
||||
(EFI_SET_MEMORY_SPACE_ATTRIBUTES) CoreSetMemorySpaceAttributes, // SetMemorySpaceAttributes
|
||||
(EFI_GET_MEMORY_SPACE_MAP) CoreGetMemorySpaceMap, // GetMemorySpaceMap
|
||||
(EFI_ADD_IO_SPACE) CoreAddIoSpace, // AddIoSpace
|
||||
(EFI_ALLOCATE_IO_SPACE) CoreAllocateIoSpace, // AllocateIoSpace
|
||||
(EFI_FREE_IO_SPACE) CoreFreeIoSpace, // FreeIoSpace
|
||||
(EFI_REMOVE_IO_SPACE) CoreRemoveIoSpace, // RemoveIoSpace
|
||||
(EFI_GET_IO_SPACE_DESCRIPTOR) CoreGetIoSpaceDescriptor, // GetIoSpaceDescriptor
|
||||
(EFI_GET_IO_SPACE_MAP) CoreGetIoSpaceMap, // GetIoSpaceMap
|
||||
(EFI_DISPATCH) CoreDispatcher, // Dispatch
|
||||
(EFI_SCHEDULE) CoreSchedule, // Schedule
|
||||
(EFI_TRUST) CoreTrust, // Trust
|
||||
(EFI_PROCESS_FIRMWARE_VOLUME) CoreProcessFirmwareVolume, // ProcessFirmwareVolume
|
||||
};
|
||||
|
||||
EFI_SYSTEM_TABLE mEfiSystemTableTemplate = {
|
||||
{
|
||||
EFI_SYSTEM_TABLE_SIGNATURE, // Signature
|
||||
EFI_SYSTEM_TABLE_REVISION, // Revision
|
||||
sizeof (EFI_SYSTEM_TABLE), // HeaderSize
|
||||
0, // CRC32
|
||||
0 // Reserved
|
||||
},
|
||||
NULL, // FirmwareVendor
|
||||
0, // FirmwareRevision
|
||||
NULL, // ConsoleInHandle
|
||||
NULL, // ConIn
|
||||
NULL, // ConsoleOutHandle
|
||||
NULL, // ConOut
|
||||
NULL, // StandardErrorHandle
|
||||
NULL, // StdErr
|
||||
NULL, // RuntimeServices
|
||||
&mBootServices, // BootServices
|
||||
0, // NumberOfConfigurationTableEntries
|
||||
NULL // ConfigurationTable
|
||||
};
|
||||
|
||||
EFI_RUNTIME_SERVICES mEfiRuntimeServicesTableTemplate = {
|
||||
{
|
||||
EFI_RUNTIME_SERVICES_SIGNATURE, // Signature
|
||||
EFI_RUNTIME_SERVICES_REVISION, // Revision
|
||||
sizeof (EFI_RUNTIME_SERVICES), // HeaderSize
|
||||
0, // CRC32
|
||||
0 // Reserved
|
||||
},
|
||||
(EFI_GET_TIME) CoreEfiNotAvailableYetArg2, // GetTime
|
||||
(EFI_SET_TIME) CoreEfiNotAvailableYetArg1, // SetTime
|
||||
(EFI_GET_WAKEUP_TIME) CoreEfiNotAvailableYetArg3, // GetWakeupTime
|
||||
(EFI_SET_WAKEUP_TIME) CoreEfiNotAvailableYetArg2, // SetWakeupTime
|
||||
(EFI_SET_VIRTUAL_ADDRESS_MAP) CoreEfiNotAvailableYetArg4, // SetVirtualAddressMap
|
||||
(EFI_CONVERT_POINTER) CoreEfiNotAvailableYetArg2, // ConvertPointer
|
||||
(EFI_GET_VARIABLE) CoreEfiNotAvailableYetArg5, // GetVariable
|
||||
(EFI_GET_NEXT_VARIABLE_NAME) CoreEfiNotAvailableYetArg3, // GetNextVariableName
|
||||
(EFI_SET_VARIABLE) CoreEfiNotAvailableYetArg5, // SetVariable
|
||||
(EFI_GET_NEXT_HIGH_MONO_COUNT) CoreEfiNotAvailableYetArg1, // GetNextHighMonotonicCount
|
||||
(EFI_RESET_SYSTEM) CoreEfiNotAvailableYetArg4, // ResetSystem
|
||||
(EFI_UPDATE_CAPSULE) CoreEfiNotAvailableYetArg3, // UpdateCapsule
|
||||
(EFI_QUERY_CAPSULE_CAPABILITIES) CoreEfiNotAvailableYetArg4, // QueryCapsuleCapabilities
|
||||
(EFI_QUERY_VARIABLE_INFO) CoreEfiNotAvailableYetArg4 // QueryVariableInfo
|
||||
};
|
||||
|
||||
EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate = {
|
||||
INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.ImageHead),
|
||||
INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.EventHead),
|
||||
|
||||
//
|
||||
// Make sure Size != sizeof (EFI_MEMORY_DESCRIPTOR). This will
|
||||
// prevent people from having pointer math bugs in their code.
|
||||
// now you have to use *DescriptorSize to make things work.
|
||||
//
|
||||
sizeof (EFI_MEMORY_DESCRIPTOR) + sizeof (UINT64) - (sizeof (EFI_MEMORY_DESCRIPTOR) % sizeof (UINT64)),
|
||||
EFI_MEMORY_DESCRIPTOR_VERSION,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
FALSE
|
||||
};
|
||||
|
||||
EFI_RUNTIME_ARCH_PROTOCOL *gRuntime = &gRuntimeTemplate;
|
||||
|
||||
//
|
||||
// DXE Core Global Variables for the EFI System Table, Boot Services Table,
|
||||
// DXE Services Table, and Runtime Services Table
|
||||
//
|
||||
EFI_BOOT_SERVICES *gDxeCoreBS = &mBootServices;
|
||||
EFI_DXE_SERVICES *gDxeCoreDS = &mDxeServices;
|
||||
EFI_SYSTEM_TABLE *gDxeCoreST = NULL;
|
||||
|
||||
//
|
||||
// For debug initialize gDxeCoreRT to template. gDxeCoreRT must be allocated from RT memory
|
||||
// but gDxeCoreRT is used for ASSERT () and DEBUG () type macros so lets give it
|
||||
// a value that will not cause debug infrastructure to crash early on.
|
||||
//
|
||||
EFI_RUNTIME_SERVICES *gDxeCoreRT = &mEfiRuntimeServicesTableTemplate;
|
||||
EFI_HANDLE gDxeCoreImageHandle = NULL;
|
||||
|
||||
VOID *mHobStart;
|
||||
|
||||
//
|
||||
// EFI Decompress Protocol
|
||||
//
|
||||
EFI_DECOMPRESS_PROTOCOL gEfiDecompress = {
|
||||
DxeMainUefiDecompressGetInfo,
|
||||
DxeMainUefiDecompress
|
||||
};
|
||||
|
||||
//
|
||||
// Main entry point to the DXE Core
|
||||
//
|
||||
VOID
|
||||
EFIAPI
|
||||
DxeMain (
|
||||
IN VOID *HobStart
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Main entry point to DXE Core.
|
||||
|
||||
Arguments:
|
||||
|
||||
HobStart - Pointer to the beginning of the HOB List from PEI
|
||||
|
||||
Returns:
|
||||
|
||||
This function should never return
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
|
||||
UINT64 MemoryLength;
|
||||
|
||||
mHobStart = HobStart;
|
||||
|
||||
//
|
||||
// Initialize Memory Services
|
||||
//
|
||||
CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength);
|
||||
|
||||
//
|
||||
// Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData
|
||||
// Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table
|
||||
//
|
||||
gDxeCoreST = CoreAllocateRuntimeCopyPool (sizeof (EFI_SYSTEM_TABLE), &mEfiSystemTableTemplate);
|
||||
ASSERT (gDxeCoreST != NULL);
|
||||
|
||||
gDxeCoreRT = CoreAllocateRuntimeCopyPool (sizeof (EFI_RUNTIME_SERVICES), &mEfiRuntimeServicesTableTemplate);
|
||||
ASSERT (gDxeCoreRT != NULL);
|
||||
|
||||
gDxeCoreST->RuntimeServices = gDxeCoreRT;
|
||||
|
||||
//
|
||||
// Start the Image Services.
|
||||
//
|
||||
Status = CoreInitializeImageServices (HobStart);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Call constructor for all libraries
|
||||
//
|
||||
ProcessLibraryConstructorList (gDxeCoreImageHandle, gDxeCoreST);
|
||||
PERF_END (0,PEI_TOK, NULL, 0) ;
|
||||
PERF_START (0,DXE_TOK, NULL, 0) ;
|
||||
|
||||
//
|
||||
// Initialize the Global Coherency Domain Services
|
||||
//
|
||||
Status = CoreInitializeGcdServices (&HobStart, MemoryBaseAddress, MemoryLength);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Install the DXE Services Table into the EFI System Tables's Configuration Table
|
||||
//
|
||||
Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDxeCoreDS);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Install the HOB List into the EFI System Tables's Configuration Table
|
||||
//
|
||||
Status = CoreInstallConfigurationTable (&gEfiHobListGuid, HobStart);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Install Memory Type Information Table into the EFI System Tables's Configuration Table
|
||||
//
|
||||
Status = CoreInstallConfigurationTable (&gEfiMemoryTypeInformationGuid, &gMemoryTypeInformation);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Initialize the ReportStatusCode with PEI version, if available
|
||||
//
|
||||
CoreGetPeiProtocol (&gEfiStatusCodeRuntimeProtocolGuid, (VOID **)&gStatusCode->ReportStatusCode);
|
||||
|
||||
//
|
||||
// Report Status Code here for DXE_ENTRY_POINT once it is available
|
||||
//
|
||||
CoreReportProgressCode ((EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT));
|
||||
|
||||
//
|
||||
// Create the aligned system table pointer structure that is used by external
|
||||
// debuggers to locate the system table... Also, install debug image info
|
||||
// configuration table.
|
||||
//
|
||||
CoreInitializeDebugImageInfoTable ();
|
||||
CoreNewDebugImageInfoEntry (
|
||||
EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL,
|
||||
gDxeCoreLoadedImage,
|
||||
gDxeCoreImageHandle
|
||||
);
|
||||
|
||||
DEBUG ((EFI_D_INFO | EFI_D_LOAD, "HOBLIST address in DXE = 0x%08x\n", HobStart));
|
||||
|
||||
//
|
||||
// Initialize the Event Services
|
||||
//
|
||||
Status = CoreInitializeEventServices ();
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
|
||||
//
|
||||
// Get the Protocols that were passed in from PEI to DXE through GUIDed HOBs
|
||||
//
|
||||
// These Protocols are not architectural. This implementation is sharing code between
|
||||
// PEI and DXE in order to save FLASH space. These Protocols could also be implemented
|
||||
// as part of the DXE Core. However, that would also require the DXE Core to be ported
|
||||
// each time a different CPU is used, a different Decompression algorithm is used, or a
|
||||
// different Image type is used. By placing these Protocols in PEI, the DXE Core remains
|
||||
// generic, and only PEI and the Arch Protocols need to be ported from Platform to Platform,
|
||||
// and from CPU to CPU.
|
||||
//
|
||||
|
||||
//
|
||||
// Publish the EFI, Tiano, and Custom Decompress protocols for use by other DXE components
|
||||
//
|
||||
Status = CoreInstallMultipleProtocolInterfaces (
|
||||
&mDecompressHandle,
|
||||
&gEfiDecompressProtocolGuid, &gEfiDecompress,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
gEfiPeiPeCoffLoader = GetPeCoffLoaderProtocol ();
|
||||
ASSERT (gEfiPeiPeCoffLoader != NULL);
|
||||
|
||||
//
|
||||
// Register for the GUIDs of the Architectural Protocols, so the rest of the
|
||||
// EFI Boot Services and EFI Runtime Services tables can be filled in.
|
||||
//
|
||||
CoreNotifyOnArchProtocolInstallation ();
|
||||
|
||||
//
|
||||
// Produce Firmware Volume Protocols, one for each FV in the HOB list.
|
||||
//
|
||||
Status = FwVolBlockDriverInit (gDxeCoreImageHandle, gDxeCoreST);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = FwVolDriverInit (gDxeCoreImageHandle, gDxeCoreST);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Produce the Section Extraction Protocol
|
||||
//
|
||||
Status = InitializeSectionExtraction (gDxeCoreImageHandle, gDxeCoreST);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Initialize the DXE Dispatcher
|
||||
//
|
||||
PERF_START (0,"CoreInitializeDispatcher", "DxeMain", 0) ;
|
||||
CoreInitializeDispatcher ();
|
||||
PERF_END (0,"CoreInitializeDispatcher", "DxeMain", 0) ;
|
||||
|
||||
//
|
||||
// Invoke the DXE Dispatcher
|
||||
//
|
||||
PERF_START (0, "CoreDispatcher", "DxeMain", 0);
|
||||
CoreDispatcher ();
|
||||
PERF_END (0, "CoreDispatcher", "DxeMain", 0);
|
||||
|
||||
//
|
||||
// Display Architectural protocols that were not loaded if this is DEBUG build
|
||||
//
|
||||
DEBUG_CODE_BEGIN ();
|
||||
CoreDisplayMissingArchProtocols ();
|
||||
DEBUG_CODE_END ();
|
||||
|
||||
//
|
||||
// Assert if the Architectural Protocols are not present.
|
||||
//
|
||||
ASSERT_EFI_ERROR (CoreAllEfiServicesAvailable ());
|
||||
|
||||
//
|
||||
// Report Status code before transfer control to BDS
|
||||
//
|
||||
CoreReportProgressCode ((EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT));
|
||||
//
|
||||
// Display any drivers that were not dispatched because dependency expression
|
||||
// evaluated to false if this is a debug build
|
||||
//
|
||||
DEBUG_CODE_BEGIN ();
|
||||
CoreDisplayDiscoveredNotDispatched ();
|
||||
DEBUG_CODE_END ();
|
||||
|
||||
//
|
||||
// Transfer control to the BDS Architectural Protocol
|
||||
//
|
||||
gBds->Entry (gBds);
|
||||
|
||||
//
|
||||
// BDS should never return
|
||||
//
|
||||
ASSERT (FALSE);
|
||||
CpuDeadLoop ();
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreEfiNotAvailableYetArg0 (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Place holder function until all the Boot Services and Runtime Services are available
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_NOT_AVAILABLE_YET
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// This function should never be executed. If it does, then the architectural protocols
|
||||
// have not been designed correctly. The CpuBreakpoint () is commented out for now until the
|
||||
// DXE Core and all the Architectural Protocols are complete.
|
||||
//
|
||||
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreEfiNotAvailableYetArg1 (
|
||||
UINTN Arg1
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Place holder function until all the Boot Services and Runtime Services are available
|
||||
|
||||
Arguments:
|
||||
|
||||
Arg1 - Undefined
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_NOT_AVAILABLE_YET
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// This function should never be executed. If it does, then the architectural protocols
|
||||
// have not been designed correctly. The CpuBreakpoint () is commented out for now until the
|
||||
// DXE Core and all the Architectural Protocols are complete.
|
||||
//
|
||||
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreEfiNotAvailableYetArg2 (
|
||||
UINTN Arg1,
|
||||
UINTN Arg2
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Place holder function until all the Boot Services and Runtime Services are available
|
||||
|
||||
Arguments:
|
||||
|
||||
Arg1 - Undefined
|
||||
|
||||
Arg2 - Undefined
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_NOT_AVAILABLE_YET
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// This function should never be executed. If it does, then the architectural protocols
|
||||
// have not been designed correctly. The CpuBreakpoint () is commented out for now until the
|
||||
// DXE Core and all the Architectural Protocols are complete.
|
||||
//
|
||||
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreEfiNotAvailableYetArg3 (
|
||||
UINTN Arg1,
|
||||
UINTN Arg2,
|
||||
UINTN Arg3
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Place holder function until all the Boot Services and Runtime Services are available
|
||||
|
||||
Arguments:
|
||||
|
||||
Arg1 - Undefined
|
||||
|
||||
Arg2 - Undefined
|
||||
|
||||
Arg3 - Undefined
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_NOT_AVAILABLE_YET
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// This function should never be executed. If it does, then the architectural protocols
|
||||
// have not been designed correctly. The CpuBreakpoint () is commented out for now until the
|
||||
// DXE Core and all the Architectural Protocols are complete.
|
||||
//
|
||||
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreEfiNotAvailableYetArg4 (
|
||||
UINTN Arg1,
|
||||
UINTN Arg2,
|
||||
UINTN Arg3,
|
||||
UINTN Arg4
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Place holder function until all the Boot Services and Runtime Services are available
|
||||
|
||||
Arguments:
|
||||
|
||||
Arg1 - Undefined
|
||||
|
||||
Arg2 - Undefined
|
||||
|
||||
Arg3 - Undefined
|
||||
|
||||
Arg4 - Undefined
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_NOT_AVAILABLE_YET
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// This function should never be executed. If it does, then the architectural protocols
|
||||
// have not been designed correctly. The CpuBreakpoint () is commented out for now until the
|
||||
// DXE Core and all the Architectural Protocols are complete.
|
||||
//
|
||||
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreEfiNotAvailableYetArg5 (
|
||||
UINTN Arg1,
|
||||
UINTN Arg2,
|
||||
UINTN Arg3,
|
||||
UINTN Arg4,
|
||||
UINTN Arg5
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Place holder function until all the Boot Services and Runtime Services are available
|
||||
|
||||
Arguments:
|
||||
|
||||
Arg1 - Undefined
|
||||
|
||||
Arg2 - Undefined
|
||||
|
||||
Arg3 - Undefined
|
||||
|
||||
Arg4 - Undefined
|
||||
|
||||
Arg5 - Undefined
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_NOT_AVAILABLE_YET
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// This function should never be executed. If it does, then the architectural protocols
|
||||
// have not been designed correctly. The CpuBreakpoint () is commented out for now until the
|
||||
// DXE Core and all the Architectural Protocols are complete.
|
||||
//
|
||||
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
CoreGetPeiProtocol (
|
||||
IN EFI_GUID *ProtocolGuid,
|
||||
IN VOID **Interface
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Searches for a Protocol Interface passed from PEI through a HOB
|
||||
|
||||
Arguments:
|
||||
|
||||
ProtocolGuid - The Protocol GUID to search for in the HOB List
|
||||
|
||||
Interface - A pointer to the interface for the Protocol GUID
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The Protocol GUID was found and its interface is returned in Interface
|
||||
|
||||
EFI_NOT_FOUND - The Protocol GUID was not found in the HOB List
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_HOB_GUID_TYPE *GuidHob;
|
||||
VOID *Buffer;
|
||||
|
||||
GuidHob = GetNextGuidHob (ProtocolGuid, mHobStart);
|
||||
if (GuidHob == NULL) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
Buffer = GET_GUID_HOB_DATA (GuidHob);
|
||||
ASSERT (Buffer != NULL);
|
||||
|
||||
*Interface = (VOID *)(*(UINTN *)(Buffer));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CalculateEfiHdrCrc (
|
||||
IN OUT EFI_TABLE_HEADER *Hdr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Calcualte the 32-bit CRC in a EFI table using the service provided by the
|
||||
gRuntime service.
|
||||
|
||||
Arguments:
|
||||
|
||||
Hdr - Pointer to an EFI standard header
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT32 Crc;
|
||||
|
||||
Hdr->CRC32 = 0;
|
||||
|
||||
//
|
||||
// If gDxeCoreBS->CalculateCrce32 () == CoreEfiNotAvailableYet () then
|
||||
// Crc will come back as zero if we set it to zero here
|
||||
//
|
||||
Crc = 0;
|
||||
gDxeCoreBS->CalculateCrc32 ((UINT8 *)Hdr, Hdr->HeaderSize, &Crc);
|
||||
Hdr->CRC32 = Crc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreExitBootServices (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN UINTN MapKey
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Terminates all boot services.
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle - Handle that identifies the exiting image.
|
||||
|
||||
MapKey -Key to the latest memory map.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Boot Services terminated
|
||||
EFI_INVALID_PARAMETER - MapKey is incorrect.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Terminate memory services if the MapKey matches
|
||||
//
|
||||
Status = CoreTerminateMemoryMap (MapKey);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Notify other drivers that we are exiting boot services.
|
||||
//
|
||||
CoreNotifySignalList (&gEfiEventExitBootServicesGuid);
|
||||
|
||||
//
|
||||
// Disable Timer
|
||||
//
|
||||
gTimer->SetTimerPeriod (gTimer, 0);
|
||||
|
||||
//
|
||||
// Disable CPU Interrupts
|
||||
//
|
||||
gCpu->DisableInterrupt (gCpu);
|
||||
|
||||
//
|
||||
// Report that ExitBootServices() has been called
|
||||
//
|
||||
// We are using gEfiDxeServicesTableGuid as the caller ID for Dxe Core
|
||||
//
|
||||
CoreReportProgressCode ((EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES));
|
||||
|
||||
//
|
||||
// Clear the non-runtime values of the EFI System Table
|
||||
//
|
||||
gDxeCoreST->BootServices = NULL;
|
||||
gDxeCoreST->ConIn = NULL;
|
||||
gDxeCoreST->ConsoleInHandle = NULL;
|
||||
gDxeCoreST->ConOut = NULL;
|
||||
gDxeCoreST->ConsoleOutHandle = NULL;
|
||||
gDxeCoreST->StdErr = NULL;
|
||||
gDxeCoreST->StandardErrorHandle = NULL;
|
||||
|
||||
//
|
||||
// Recompute the 32-bit CRC of the EFI System Table
|
||||
//
|
||||
CalculateEfiHdrCrc (&gDxeCoreST->Hdr);
|
||||
|
||||
//
|
||||
// Zero out the Boot Service Table
|
||||
//
|
||||
SetMem (gDxeCoreBS, sizeof (EFI_BOOT_SERVICES), 0);
|
||||
gDxeCoreBS = NULL;
|
||||
|
||||
//
|
||||
// Update the AtRuntime field in Runtiem AP.
|
||||
//
|
||||
gRuntime->AtRuntime = TRUE;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
DxeMainUefiDecompressGetInfo (
|
||||
IN EFI_DECOMPRESS_PROTOCOL *This,
|
||||
IN VOID *Source,
|
||||
IN UINT32 SourceSize,
|
||||
OUT UINT32 *DestinationSize,
|
||||
OUT UINT32 *ScratchSize
|
||||
)
|
||||
{
|
||||
if (Source == NULL
|
||||
|| DestinationSize == NULL
|
||||
|| ScratchSize == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
return UefiDecompressGetInfo (Source, SourceSize, DestinationSize, ScratchSize);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DxeMainUefiDecompress (
|
||||
IN EFI_DECOMPRESS_PROTOCOL *This,
|
||||
IN VOID *Source,
|
||||
IN UINT32 SourceSize,
|
||||
IN OUT VOID *Destination,
|
||||
IN UINT32 DestinationSize,
|
||||
IN OUT VOID *Scratch,
|
||||
IN UINT32 ScratchSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 TestDestinationSize;
|
||||
UINT32 TestScratchSize;
|
||||
|
||||
if (Source == NULL
|
||||
|| Destination== NULL
|
||||
|| Scratch == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = UefiDecompressGetInfo (Source, SourceSize, &TestDestinationSize, &TestScratchSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (ScratchSize < TestScratchSize || DestinationSize < TestDestinationSize) {
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return UefiDecompress (Source, Destination, Scratch);
|
||||
}
|
||||
|
297
MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c
Normal file
297
MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c
Normal file
@ -0,0 +1,297 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
DxeProtocolNotify.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This file deals with Architecture Protocol (AP) registration in
|
||||
the Dxe Core. The mArchProtocols[] array represents a list of
|
||||
events that represent the Architectural Protocols.
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
|
||||
//
|
||||
// DXE Core Global Variables for all of the Architectural Protocols.
|
||||
// If a protocol is installed mArchProtocols[].Present will be TRUE.
|
||||
//
|
||||
// CoreNotifyOnArchProtocolInstallation () fills in mArchProtocols[].Event
|
||||
// and mArchProtocols[].Registration as it creates events for every array
|
||||
// entry.
|
||||
//
|
||||
|
||||
ARCHITECTURAL_PROTOCOL_ENTRY mArchProtocols[] = {
|
||||
{ &gEfiSecurityArchProtocolGuid, (VOID **)&gSecurity, NULL, NULL, FALSE },
|
||||
{ &gEfiCpuArchProtocolGuid, (VOID **)&gCpu, NULL, NULL, FALSE },
|
||||
{ &gEfiMetronomeArchProtocolGuid, (VOID **)&gMetronome, NULL, NULL, FALSE },
|
||||
{ &gEfiTimerArchProtocolGuid, (VOID **)&gTimer, NULL, NULL, FALSE },
|
||||
{ &gEfiBdsArchProtocolGuid, (VOID **)&gBds, NULL, NULL, FALSE },
|
||||
{ &gEfiWatchdogTimerArchProtocolGuid, (VOID **)&gWatchdogTimer, NULL, NULL, FALSE },
|
||||
{ &gEfiRuntimeArchProtocolGuid, (VOID **)&gRuntime, NULL, NULL, FALSE },
|
||||
{ &gEfiVariableArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
|
||||
{ &gEfiVariableWriteArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
|
||||
{ &gEfiCapsuleArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE},
|
||||
{ &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
|
||||
{ &gEfiResetArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
|
||||
{ &gEfiRealTimeClockArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
|
||||
{ NULL, (VOID **)NULL, NULL, NULL, FALSE }
|
||||
};
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
CoreAllEfiServicesAvailable (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Return TRUE if all AP services are availible.
|
||||
|
||||
Arguments:
|
||||
NONE
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - All AP services are available
|
||||
EFI_NOT_FOUND - At least one AP service is not available
|
||||
|
||||
--*/
|
||||
{
|
||||
ARCHITECTURAL_PROTOCOL_ENTRY *Entry;
|
||||
|
||||
for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {
|
||||
if (!Entry->Present) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
EFIAPI
|
||||
GenericArchProtocolNotify (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Notification event handler registered by CoreNotifyOnArchProtocolInstallation ().
|
||||
This notify function is registered for every architectural protocol. This handler
|
||||
updates mArchProtocol[] array entry with protocol instance data and sets it's
|
||||
present flag to TRUE. If any constructor is required it is executed. The EFI
|
||||
System Table headers are updated.
|
||||
|
||||
Arguments:
|
||||
|
||||
Event - The Event that is being processed, not used.
|
||||
|
||||
Context - Event Context, not used.
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARCHITECTURAL_PROTOCOL_ENTRY *Entry;
|
||||
VOID *Protocol;
|
||||
BOOLEAN Found;
|
||||
LIST_ENTRY *Link;
|
||||
LIST_ENTRY TempLinkNode;
|
||||
|
||||
Found = FALSE;
|
||||
for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {
|
||||
|
||||
Status = CoreLocateProtocol (Entry->ProtocolGuid, Entry->Registration, &Protocol);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Found = TRUE;
|
||||
Entry->Present = TRUE;
|
||||
|
||||
//
|
||||
// Update protocol global variable if one exists. Entry->Protocol points to a global variable
|
||||
// if one exists in the DXE core for this Architectural Protocol
|
||||
//
|
||||
if (Entry->Protocol != NULL) {
|
||||
*(Entry->Protocol) = Protocol;
|
||||
}
|
||||
|
||||
if (CompareGuid (Entry->ProtocolGuid, &gEfiTimerArchProtocolGuid)) {
|
||||
//
|
||||
// Register the Core timer tick handler with the Timer AP
|
||||
//
|
||||
gTimer->RegisterHandler (gTimer, CoreTimerTick);
|
||||
}
|
||||
|
||||
if (CompareGuid (Entry->ProtocolGuid, &gEfiRuntimeArchProtocolGuid)) {
|
||||
//
|
||||
// When runtime architectural protocol is available, updates CRC32 in the Debug Table
|
||||
//
|
||||
CoreUpdateDebugTableCrc32 ();
|
||||
|
||||
//
|
||||
// Update the Runtime Architectural protocol with the template that the core was
|
||||
// using so there would not need to be a dependency on the Runtime AP
|
||||
//
|
||||
|
||||
//
|
||||
// Copy all the registered Image to new gRuntime protocol
|
||||
//
|
||||
for (Link = gRuntimeTemplate.ImageHead.ForwardLink; Link != &gRuntimeTemplate.ImageHead; Link = TempLinkNode.ForwardLink) {
|
||||
CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY));
|
||||
InsertTailList (&gRuntime->ImageHead, Link);
|
||||
}
|
||||
//
|
||||
// Copy all the registered Event to new gRuntime protocol
|
||||
//
|
||||
for (Link = gRuntimeTemplate.EventHead.ForwardLink; Link != &gRuntimeTemplate.EventHead; Link = TempLinkNode.ForwardLink) {
|
||||
CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY));
|
||||
InsertTailList (&gRuntime->EventHead, Link);
|
||||
}
|
||||
|
||||
//
|
||||
// Clean up gRuntimeTemplate
|
||||
//
|
||||
gRuntimeTemplate.ImageHead.ForwardLink = &gRuntimeTemplate.ImageHead;
|
||||
gRuntimeTemplate.ImageHead.BackLink = &gRuntimeTemplate.ImageHead;
|
||||
gRuntimeTemplate.EventHead.ForwardLink = &gRuntimeTemplate.EventHead;
|
||||
gRuntimeTemplate.EventHead.BackLink = &gRuntimeTemplate.EventHead;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// It's over kill to do them all every time, but it saves a lot of code.
|
||||
//
|
||||
if (Found) {
|
||||
CalculateEfiHdrCrc (&gDxeCoreRT->Hdr);
|
||||
CalculateEfiHdrCrc (&gDxeCoreBS->Hdr);
|
||||
CalculateEfiHdrCrc (&gDxeCoreST->Hdr);
|
||||
CalculateEfiHdrCrc (&gDxeCoreDS->Hdr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
CoreNotifyOnArchProtocolInstallation (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Creates an event that is fired everytime a Protocol of a specific type is installed
|
||||
|
||||
Arguments:
|
||||
NONE
|
||||
|
||||
Returns:
|
||||
NONE
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARCHITECTURAL_PROTOCOL_ENTRY *Entry;
|
||||
|
||||
for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {
|
||||
|
||||
//
|
||||
// Create the event
|
||||
//
|
||||
Status = CoreCreateEvent (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_CALLBACK,
|
||||
GenericArchProtocolNotify,
|
||||
NULL,
|
||||
&Entry->Event
|
||||
);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
//
|
||||
// Register for protocol notifactions on this event
|
||||
//
|
||||
Status = CoreRegisterProtocolNotify (
|
||||
Entry->ProtocolGuid,
|
||||
Entry->Event,
|
||||
&Entry->Registration
|
||||
);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Following is needed to display missing architectural protocols in debug builds
|
||||
//
|
||||
typedef struct {
|
||||
EFI_GUID *ProtocolGuid;
|
||||
CHAR16 *GuidString;
|
||||
} GUID_TO_STRING_PROTOCOL_ENTRY;
|
||||
|
||||
static const GUID_TO_STRING_PROTOCOL_ENTRY MissingProtocols[] = {
|
||||
{ &gEfiSecurityArchProtocolGuid, (CHAR16 *)L"Security" },
|
||||
{ &gEfiCpuArchProtocolGuid, (CHAR16 *)L"CPU" },
|
||||
{ &gEfiMetronomeArchProtocolGuid, (CHAR16 *)L"Metronome" },
|
||||
{ &gEfiTimerArchProtocolGuid, (CHAR16 *)L"Timer" },
|
||||
{ &gEfiBdsArchProtocolGuid, (CHAR16 *)L"Bds" },
|
||||
{ &gEfiWatchdogTimerArchProtocolGuid, (CHAR16 *)L"Watchdog Timer" },
|
||||
{ &gEfiRuntimeArchProtocolGuid, (CHAR16 *)L"Runtime" },
|
||||
{ &gEfiVariableArchProtocolGuid, (CHAR16 *)L"Variable" },
|
||||
{ &gEfiVariableWriteArchProtocolGuid, (CHAR16 *)L"Variable Write" },
|
||||
{ &gEfiCapsuleArchProtocolGuid, (CHAR16 *)L"Capsule" },
|
||||
{ &gEfiMonotonicCounterArchProtocolGuid, (CHAR16 *)L"Monotonic Counter" },
|
||||
{ &gEfiResetArchProtocolGuid, (CHAR16 *)L"Reset" },
|
||||
// { &gEfiStatusCodeRuntimeProtocolGuid, (CHAR16 *)L"Status Code" },
|
||||
{ &gEfiRealTimeClockArchProtocolGuid, (CHAR16 *)L"Real Time Clock" }
|
||||
};
|
||||
|
||||
VOID
|
||||
CoreDisplayMissingArchProtocols (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Displays Architectural protocols that were not loaded and are required for DXE core to function
|
||||
Only used in Debug Builds
|
||||
|
||||
Arguments:
|
||||
NONE
|
||||
|
||||
Returns:
|
||||
NONE
|
||||
|
||||
--*/
|
||||
{
|
||||
const GUID_TO_STRING_PROTOCOL_ENTRY *MissingEntry;
|
||||
ARCHITECTURAL_PROTOCOL_ENTRY *Entry;
|
||||
|
||||
for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {
|
||||
if (!Entry->Present) {
|
||||
MissingEntry = MissingProtocols;
|
||||
for (MissingEntry = MissingProtocols; TRUE ; MissingEntry++) {
|
||||
if (CompareGuid (Entry->ProtocolGuid, MissingEntry->ProtocolGuid)) {
|
||||
DEBUG ((EFI_D_ERROR, "\n%s Arch Protocol not present!!\n", MissingEntry->GuidString));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
757
MdeModulePkg/Core/Dxe/Event/event.c
Normal file
757
MdeModulePkg/Core/Dxe/Event/event.c
Normal file
@ -0,0 +1,757 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
event.c
|
||||
|
||||
Abstract:
|
||||
|
||||
EFI Event support
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
//
|
||||
// Enumerate the valid types
|
||||
//
|
||||
UINT32 mEventTable[] = {
|
||||
//
|
||||
// 0x80000200 Timer event with a notification function that is
|
||||
// queue when the event is signaled with SignalEvent()
|
||||
//
|
||||
EVT_TIMER | EVT_NOTIFY_SIGNAL,
|
||||
//
|
||||
// 0x80000000 Timer event without a notification function. It can be
|
||||
// signaled with SignalEvent() and checked with CheckEvent() or WaitForEvent().
|
||||
//
|
||||
EVT_TIMER,
|
||||
//
|
||||
// 0x00000100 Generic event with a notification function that
|
||||
// can be waited on with CheckEvent() or WaitForEvent()
|
||||
//
|
||||
EVT_NOTIFY_WAIT,
|
||||
//
|
||||
// 0x00000200 Generic event with a notification function that
|
||||
// is queue when the event is signaled with SignalEvent()
|
||||
//
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
//
|
||||
// 0x00000201 ExitBootServicesEvent.
|
||||
//
|
||||
EVT_SIGNAL_EXIT_BOOT_SERVICES,
|
||||
//
|
||||
// 0x60000202 SetVirtualAddressMapEvent.
|
||||
//
|
||||
EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
|
||||
|
||||
//
|
||||
// 0x00000000 Generic event without a notification function.
|
||||
// It can be signaled with SignalEvent() and checked with CheckEvent()
|
||||
// or WaitForEvent().
|
||||
//
|
||||
0x00000000,
|
||||
//
|
||||
// 0x80000100 Timer event with a notification function that can be
|
||||
// waited on with CheckEvent() or WaitForEvent()
|
||||
//
|
||||
EVT_TIMER | EVT_NOTIFY_WAIT,
|
||||
};
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
CoreAcquireEventLock (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Enter critical section by acquiring the lock on gEventQueueLock.
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
CoreAcquireLock (&gEventQueueLock);
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
CoreReleaseEventLock (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Exit critical section by releasing the lock on gEventQueueLock.
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
CoreReleaseLock (&gEventQueueLock);
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
CoreInitializeEventServices (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Initializes "event" support and populates parts of the System and Runtime Table.
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Always return success
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
for (Index=0; Index <= TPL_HIGH_LEVEL; Index++) {
|
||||
InitializeListHead (&gEventQueue[Index]);
|
||||
}
|
||||
|
||||
CoreInitializeTimer ();
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CoreDispatchEventNotifies (
|
||||
IN EFI_TPL Priority
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Dispatches all pending events.
|
||||
|
||||
Arguments:
|
||||
|
||||
Priority - The task priority level of event notifications to dispatch
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
IEVENT *Event;
|
||||
LIST_ENTRY *Head;
|
||||
|
||||
CoreAcquireEventLock ();
|
||||
ASSERT (gEventQueueLock.OwnerTpl == Priority);
|
||||
Head = &gEventQueue[Priority];
|
||||
|
||||
//
|
||||
// Dispatch all the pending notifications
|
||||
//
|
||||
while (!IsListEmpty (Head)) {
|
||||
|
||||
Event = CR (Head->ForwardLink, IEVENT, NotifyLink, EVENT_SIGNATURE);
|
||||
RemoveEntryList (&Event->NotifyLink);
|
||||
|
||||
Event->NotifyLink.ForwardLink = NULL;
|
||||
|
||||
//
|
||||
// Only clear the SIGNAL status if it is a SIGNAL type event.
|
||||
// WAIT type events are only cleared in CheckEvent()
|
||||
//
|
||||
if (Event->Type & EVT_NOTIFY_SIGNAL) {
|
||||
Event->SignalCount = 0;
|
||||
}
|
||||
|
||||
CoreReleaseEventLock ();
|
||||
|
||||
//
|
||||
// Notify this event
|
||||
//
|
||||
ASSERT (Event->NotifyFunction != NULL);
|
||||
Event->NotifyFunction (Event, Event->NotifyContext);
|
||||
|
||||
//
|
||||
// Check for next pending event
|
||||
//
|
||||
CoreAcquireEventLock ();
|
||||
}
|
||||
|
||||
gEventPending &= ~(1 << Priority);
|
||||
CoreReleaseEventLock ();
|
||||
}
|
||||
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
CoreNotifyEvent (
|
||||
IN IEVENT *Event
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Queues the event's notification function to fire
|
||||
|
||||
Arguments:
|
||||
|
||||
Event - The Event to notify
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
|
||||
//
|
||||
// Event database must be locked
|
||||
//
|
||||
ASSERT_LOCKED (&gEventQueueLock);
|
||||
|
||||
//
|
||||
// If the event is queued somewhere, remove it
|
||||
//
|
||||
|
||||
if (Event->NotifyLink.ForwardLink != NULL) {
|
||||
RemoveEntryList (&Event->NotifyLink);
|
||||
Event->NotifyLink.ForwardLink = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Queue the event to the pending notification list
|
||||
//
|
||||
|
||||
InsertTailList (&gEventQueue[Event->NotifyTpl], &Event->NotifyLink);
|
||||
gEventPending |= (UINTN)(1 << Event->NotifyTpl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
CoreNotifySignalList (
|
||||
IN EFI_GUID *EventGroup
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Signals all events in the EventGroup
|
||||
|
||||
Arguments:
|
||||
EventGroup - The list to signal
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
LIST_ENTRY *Link;
|
||||
LIST_ENTRY *Head;
|
||||
IEVENT *Event;
|
||||
|
||||
CoreAcquireEventLock ();
|
||||
|
||||
Head = &gEventSignalQueue;
|
||||
for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
|
||||
Event = CR (Link, IEVENT, SignalLink, EVENT_SIGNATURE);
|
||||
if (CompareGuid (&Event->EventGroup, EventGroup)) {
|
||||
CoreNotifyEvent (Event);
|
||||
}
|
||||
}
|
||||
|
||||
CoreReleaseEventLock ();
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreCreateEvent (
|
||||
IN UINT32 Type,
|
||||
IN EFI_TPL NotifyTpl,
|
||||
IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL
|
||||
IN VOID *NotifyContext, OPTIONAL
|
||||
OUT EFI_EVENT *Event
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Creates a general-purpose event structure
|
||||
|
||||
Arguments:
|
||||
Type - The type of event to create and its mode and attributes
|
||||
NotifyTpl - The task priority level of event notifications
|
||||
NotifyFunction - Pointer to the events notification function
|
||||
NotifyContext - Pointer to the notification functions context; corresponds to
|
||||
parameter "Context" in the notification function
|
||||
Event - Pointer to the newly created event if the call succeeds; undefined otherwise
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The event structure was created
|
||||
EFI_INVALID_PARAMETER - One of the parameters has an invalid value
|
||||
EFI_OUT_OF_RESOURCES - The event could not be allocated
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_GUID *GuidPtr;
|
||||
EFI_EVENT_NOTIFY Function;
|
||||
|
||||
GuidPtr = NULL;
|
||||
Function = NotifyFunction;
|
||||
|
||||
//
|
||||
// Convert EFI 1.10 Events to thier UEFI 2.0 CreateEventEx mapping
|
||||
//
|
||||
if (Type == EVT_SIGNAL_EXIT_BOOT_SERVICES) {
|
||||
GuidPtr = &gEfiEventExitBootServicesGuid;
|
||||
} else if (Type == EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) {
|
||||
GuidPtr = &gEfiEventVirtualAddressChangeGuid;
|
||||
}
|
||||
|
||||
return CoreCreateEventEx (Type, NotifyTpl, Function, NotifyContext, GuidPtr, Event);
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreCreateEventEx (
|
||||
IN UINT32 Type,
|
||||
IN EFI_TPL NotifyTpl,
|
||||
IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL
|
||||
IN CONST VOID *NotifyContext, OPTIONAL
|
||||
IN CONST EFI_GUID *EventGroup, OPTIONAL
|
||||
OUT EFI_EVENT *Event
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Creates a general-purpose event structure
|
||||
|
||||
Arguments:
|
||||
Type - The type of event to create and its mode and attributes
|
||||
NotifyTpl - The task priority level of event notifications
|
||||
NotifyFunction - Pointer to the events notification function
|
||||
NotifyContext - Pointer to the notification functions context; corresponds to
|
||||
parameter "Context" in the notification function
|
||||
EventGrout - GUID for EventGroup if NULL act the same as gBS->CreateEvent().
|
||||
Event - Pointer to the newly created event if the call succeeds; undefined otherwise
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The event structure was created
|
||||
EFI_INVALID_PARAMETER - One of the parameters has an invalid value
|
||||
EFI_OUT_OF_RESOURCES - The event could not be allocated
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
IEVENT *IEvent;
|
||||
INTN Index;
|
||||
|
||||
|
||||
if ((Event == NULL) || (NotifyTpl == TPL_APPLICATION)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Check to make sure no reserved flags are set
|
||||
//
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
for (Index = 0; Index < (sizeof (mEventTable) / sizeof (UINT32)); Index++) {
|
||||
if (Type == mEventTable[Index]) {
|
||||
Status = EFI_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(EFI_ERROR (Status)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// If it's a notify type of event, check its parameters
|
||||
//
|
||||
if ((Type & (EVT_NOTIFY_WAIT | EVT_NOTIFY_SIGNAL))) {
|
||||
//
|
||||
// Check for an invalid NotifyFunction or NotifyTpl
|
||||
//
|
||||
if ((NotifyFunction == NULL) ||
|
||||
(NotifyTpl < TPL_APPLICATION) ||
|
||||
(NotifyTpl >= TPL_HIGH_LEVEL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
} else {
|
||||
//
|
||||
// No notification needed, zero ignored values
|
||||
//
|
||||
NotifyTpl = 0;
|
||||
NotifyFunction = NULL;
|
||||
NotifyContext = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Allcoate and initialize a new event structure.
|
||||
//
|
||||
Status = CoreAllocatePool (
|
||||
(Type & EVT_RUNTIME) ? EfiRuntimeServicesData: EfiBootServicesData,
|
||||
sizeof (IEVENT),
|
||||
(VOID **)&IEvent
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
SetMem (IEvent, sizeof (IEVENT), 0);
|
||||
|
||||
IEvent->Signature = EVENT_SIGNATURE;
|
||||
IEvent->Type = Type;
|
||||
|
||||
IEvent->NotifyTpl = NotifyTpl;
|
||||
IEvent->NotifyFunction = NotifyFunction;
|
||||
IEvent->NotifyContext = (VOID *)NotifyContext;
|
||||
if (EventGroup != NULL) {
|
||||
CopyGuid (&IEvent->EventGroup, EventGroup);
|
||||
IEvent->ExFlag = TRUE;
|
||||
}
|
||||
|
||||
*Event = IEvent;
|
||||
|
||||
if (Type & EVT_RUNTIME) {
|
||||
//
|
||||
// Keep a list of all RT events so we can tell the RT AP.
|
||||
//
|
||||
IEvent->RuntimeData.Type = Type;
|
||||
IEvent->RuntimeData.NotifyTpl = NotifyTpl;
|
||||
IEvent->RuntimeData.NotifyFunction = NotifyFunction;
|
||||
IEvent->RuntimeData.NotifyContext = (VOID *) NotifyContext;
|
||||
IEvent->RuntimeData.Event = (EFI_EVENT *) IEvent;
|
||||
InsertTailList (&gRuntime->EventHead, &IEvent->RuntimeData.Link);
|
||||
}
|
||||
|
||||
CoreAcquireEventLock ();
|
||||
|
||||
if ((Type & EVT_NOTIFY_SIGNAL) != 0x00000000) {
|
||||
//
|
||||
// The Event's NotifyFunction must be queued whenever the event is signaled
|
||||
//
|
||||
InsertHeadList (&gEventSignalQueue, &IEvent->SignalLink);
|
||||
}
|
||||
|
||||
CoreReleaseEventLock ();
|
||||
|
||||
//
|
||||
// Done
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreSignalEvent (
|
||||
IN EFI_EVENT UserEvent
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Signals the event. Queues the event to be notified if needed
|
||||
|
||||
Arguments:
|
||||
|
||||
UserEvent - The event to signal
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_INVALID_PARAMETER - Parameters are not valid.
|
||||
|
||||
EFI_SUCCESS - The event was signaled.
|
||||
|
||||
--*/
|
||||
{
|
||||
IEVENT *Event;
|
||||
|
||||
Event = UserEvent;
|
||||
|
||||
if (Event == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Event->Signature != EVENT_SIGNATURE) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
CoreAcquireEventLock ();
|
||||
|
||||
//
|
||||
// If the event is not already signalled, do so
|
||||
//
|
||||
|
||||
if (Event->SignalCount == 0x00000000) {
|
||||
Event->SignalCount++;
|
||||
|
||||
//
|
||||
// If signalling type is a notify function, queue it
|
||||
//
|
||||
if (Event->Type & EVT_NOTIFY_SIGNAL) {
|
||||
if (Event->ExFlag) {
|
||||
//
|
||||
// The CreateEventEx() style requires all members of the Event Group
|
||||
// to be signaled.
|
||||
//
|
||||
CoreReleaseEventLock ();
|
||||
CoreNotifySignalList (&Event->EventGroup);
|
||||
CoreAcquireEventLock ();
|
||||
} else {
|
||||
CoreNotifyEvent (Event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CoreReleaseEventLock ();
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreCheckEvent (
|
||||
IN EFI_EVENT UserEvent
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Check the status of an event
|
||||
|
||||
Arguments:
|
||||
|
||||
UserEvent - The event to check
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The event is in the signaled state
|
||||
EFI_NOT_READY - The event is not in the signaled state
|
||||
EFI_INVALID_PARAMETER - Event is of type EVT_NOTIFY_SIGNAL
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
IEVENT *Event;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Event = UserEvent;
|
||||
|
||||
if (Event == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Event->Signature != EVENT_SIGNATURE) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Event->Type & EVT_NOTIFY_SIGNAL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = EFI_NOT_READY;
|
||||
|
||||
if (!Event->SignalCount && (Event->Type & EVT_NOTIFY_WAIT)) {
|
||||
|
||||
//
|
||||
// Queue the wait notify function
|
||||
//
|
||||
|
||||
CoreAcquireEventLock ();
|
||||
if (!Event->SignalCount) {
|
||||
CoreNotifyEvent (Event);
|
||||
}
|
||||
CoreReleaseEventLock ();
|
||||
}
|
||||
|
||||
//
|
||||
// If the even looks signalled, get the lock and clear it
|
||||
//
|
||||
|
||||
if (Event->SignalCount) {
|
||||
CoreAcquireEventLock ();
|
||||
|
||||
if (Event->SignalCount) {
|
||||
Event->SignalCount = 0;
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
|
||||
CoreReleaseEventLock ();
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreWaitForEvent (
|
||||
IN UINTN NumberOfEvents,
|
||||
IN EFI_EVENT *UserEvents,
|
||||
OUT UINTN *UserIndex
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Stops execution until an event is signaled.
|
||||
|
||||
Arguments:
|
||||
|
||||
NumberOfEvents - The number of events in the UserEvents array
|
||||
UserEvents - An array of EFI_EVENT
|
||||
UserIndex - Pointer to the index of the event which satisfied the wait condition
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The event indicated by Index was signaled.
|
||||
EFI_INVALID_PARAMETER - The event indicated by Index has a notification function or
|
||||
Event was not a valid type
|
||||
EFI_UNSUPPORTED - The current TPL is not TPL_APPLICATION
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
|
||||
//
|
||||
// Can only WaitForEvent at TPL_APPLICATION
|
||||
//
|
||||
if (gEfiCurrentTpl != TPL_APPLICATION) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
|
||||
for(Index = 0; Index < NumberOfEvents; Index++) {
|
||||
|
||||
Status = CoreCheckEvent (UserEvents[Index]);
|
||||
|
||||
//
|
||||
// provide index of event that caused problem
|
||||
//
|
||||
if (Status != EFI_NOT_READY) {
|
||||
*UserIndex = Index;
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// This was the location of the Idle loop callback in EFI 1.x reference
|
||||
// code. We don't have that concept in this base at this point.
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreCloseEvent (
|
||||
IN EFI_EVENT UserEvent
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Closes an event and frees the event structure.
|
||||
|
||||
Arguments:
|
||||
|
||||
UserEvent - Event to close
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_INVALID_PARAMETER - Parameters are not valid.
|
||||
|
||||
EFI_SUCCESS - The event has been closed
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
IEVENT *Event;
|
||||
|
||||
Event = UserEvent;
|
||||
|
||||
if (Event == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Event->Signature != EVENT_SIGNATURE) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// If it's a timer event, make sure it's not pending
|
||||
//
|
||||
if (Event->Type & EVT_TIMER) {
|
||||
CoreSetTimer (Event, TimerCancel, 0);
|
||||
}
|
||||
|
||||
CoreAcquireEventLock ();
|
||||
|
||||
//
|
||||
// If the event is queued somewhere, remove it
|
||||
//
|
||||
|
||||
if (Event->RuntimeData.Link.ForwardLink != NULL) {
|
||||
RemoveEntryList (&Event->RuntimeData.Link);
|
||||
}
|
||||
|
||||
if (Event->NotifyLink.ForwardLink != NULL) {
|
||||
RemoveEntryList (&Event->NotifyLink);
|
||||
}
|
||||
|
||||
if (Event->SignalLink.ForwardLink != NULL) {
|
||||
RemoveEntryList (&Event->SignalLink);
|
||||
}
|
||||
|
||||
CoreReleaseEventLock ();
|
||||
|
||||
//
|
||||
// If the event is registered on a protocol notify, then remove it from the protocol database
|
||||
//
|
||||
CoreUnregisterProtocolNotify (Event);
|
||||
|
||||
Status = CoreFreePool (Event);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
51
MdeModulePkg/Core/Dxe/Event/execdata.c
Normal file
51
MdeModulePkg/Core/Dxe/Event/execdata.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
execdata.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
|
||||
//
|
||||
// gTpl - Task priority level
|
||||
//
|
||||
EFI_TPL gEfiCurrentTpl = TPL_APPLICATION;
|
||||
|
||||
|
||||
//
|
||||
// gEventQueueLock - Protects the event queus
|
||||
//
|
||||
EFI_LOCK gEventQueueLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL);
|
||||
|
||||
//
|
||||
// gEventQueue - A list of event's to notify for each priority level
|
||||
// gEventPending - A bitmask of the EventQueues that are pending
|
||||
//
|
||||
LIST_ENTRY gEventQueue[TPL_HIGH_LEVEL + 1];
|
||||
UINTN gEventPending = 0;
|
||||
|
||||
|
||||
//
|
||||
// gEventSignalQueue - A list of events to signal based on EventGroup type
|
||||
//
|
||||
LIST_ENTRY gEventSignalQueue = INITIALIZE_LIST_HEAD_VARIABLE (gEventSignalQueue);
|
||||
|
388
MdeModulePkg/Core/Dxe/Event/timer.c
Normal file
388
MdeModulePkg/Core/Dxe/Event/timer.c
Normal file
@ -0,0 +1,388 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
timer.c
|
||||
|
||||
Abstract:
|
||||
|
||||
EFI Event support
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
//
|
||||
// Internal prototypes
|
||||
//
|
||||
STATIC
|
||||
UINT64
|
||||
CoreCurrentSystemTime (
|
||||
VOID
|
||||
);
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
EFIAPI
|
||||
CoreCheckTimers (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
CoreInsertEventTimer (
|
||||
IN IEVENT *Event
|
||||
);
|
||||
|
||||
//
|
||||
// Internal data
|
||||
//
|
||||
|
||||
static LIST_ENTRY mEfiTimerList = INITIALIZE_LIST_HEAD_VARIABLE (mEfiTimerList);
|
||||
static EFI_LOCK mEfiTimerLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL - 1);
|
||||
static EFI_EVENT mEfiCheckTimerEvent;
|
||||
|
||||
static EFI_LOCK mEfiSystemTimeLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL);
|
||||
static UINT64 mEfiSystemTime = 0;
|
||||
|
||||
//
|
||||
// Timer functions
|
||||
//
|
||||
|
||||
VOID
|
||||
CoreInitializeTimer (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Initializes timer support
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = CoreCreateEvent (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_HIGH_LEVEL - 1,
|
||||
CoreCheckTimers,
|
||||
NULL,
|
||||
&mEfiCheckTimerEvent
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
STATIC
|
||||
UINT64
|
||||
CoreCurrentSystemTime (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Returns the current system time
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Returns:
|
||||
|
||||
Returns the current system time
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT64 SystemTime;
|
||||
|
||||
CoreAcquireLock (&mEfiSystemTimeLock);
|
||||
SystemTime = mEfiSystemTime;
|
||||
CoreReleaseLock (&mEfiSystemTimeLock);
|
||||
return SystemTime;
|
||||
}
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
CoreTimerTick (
|
||||
IN UINT64 Duration
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Called by the platform code to process a tick.
|
||||
|
||||
Arguments:
|
||||
|
||||
Duration - The number of 100ns elasped since the last call to TimerTick
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
IEVENT *Event;
|
||||
|
||||
//
|
||||
// Check runtiem flag in case there are ticks while exiting boot services
|
||||
//
|
||||
|
||||
CoreAcquireLock (&mEfiSystemTimeLock);
|
||||
|
||||
//
|
||||
// Update the system time
|
||||
//
|
||||
|
||||
mEfiSystemTime += Duration;
|
||||
|
||||
//
|
||||
// If the head of the list is expired, fire the timer event
|
||||
// to process it
|
||||
//
|
||||
|
||||
if (!IsListEmpty (&mEfiTimerList)) {
|
||||
Event = CR (mEfiTimerList.ForwardLink, IEVENT, u.Timer.Link, EVENT_SIGNATURE);
|
||||
|
||||
if (Event->u.Timer.TriggerTime <= mEfiSystemTime) {
|
||||
CoreSignalEvent (mEfiCheckTimerEvent);
|
||||
}
|
||||
}
|
||||
|
||||
CoreReleaseLock (&mEfiSystemTimeLock);
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
EFIAPI
|
||||
CoreCheckTimers (
|
||||
IN EFI_EVENT CheckEvent,
|
||||
IN VOID *Context
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Checks the sorted timer list against the current system time.
|
||||
Signals any expired event timer.
|
||||
|
||||
Arguments:
|
||||
|
||||
CheckEvent - Not used
|
||||
|
||||
Context - Not used
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT64 SystemTime;
|
||||
IEVENT *Event;
|
||||
|
||||
//
|
||||
// Check the timer database for expired timers
|
||||
//
|
||||
|
||||
CoreAcquireLock (&mEfiTimerLock);
|
||||
SystemTime = CoreCurrentSystemTime ();
|
||||
|
||||
while (!IsListEmpty (&mEfiTimerList)) {
|
||||
Event = CR (mEfiTimerList.ForwardLink, IEVENT, u.Timer.Link, EVENT_SIGNATURE);
|
||||
|
||||
//
|
||||
// If this timer is not expired, then we're done
|
||||
//
|
||||
|
||||
if (Event->u.Timer.TriggerTime > SystemTime) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Remove this timer from the timer queue
|
||||
//
|
||||
|
||||
RemoveEntryList (&Event->u.Timer.Link);
|
||||
Event->u.Timer.Link.ForwardLink = NULL;
|
||||
|
||||
//
|
||||
// Signal it
|
||||
//
|
||||
CoreSignalEvent (Event);
|
||||
|
||||
//
|
||||
// If this is a periodic timer, set it
|
||||
//
|
||||
if (Event->u.Timer.Period) {
|
||||
|
||||
//
|
||||
// Compute the timers new trigger time
|
||||
//
|
||||
|
||||
Event->u.Timer.TriggerTime = Event->u.Timer.TriggerTime + Event->u.Timer.Period;
|
||||
|
||||
//
|
||||
// If that's before now, then reset the timer to start from now
|
||||
//
|
||||
if (Event->u.Timer.TriggerTime <= SystemTime) {
|
||||
Event->u.Timer.TriggerTime = SystemTime;
|
||||
CoreSignalEvent (mEfiCheckTimerEvent);
|
||||
}
|
||||
|
||||
//
|
||||
// Add the timer
|
||||
//
|
||||
|
||||
CoreInsertEventTimer (Event);
|
||||
}
|
||||
}
|
||||
|
||||
CoreReleaseLock (&mEfiTimerLock);
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
CoreInsertEventTimer (
|
||||
IN IEVENT *Event
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Inserts the timer event
|
||||
|
||||
Arguments:
|
||||
|
||||
Event - Points to the internal structure of timer event to be installed
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT64 TriggerTime;
|
||||
LIST_ENTRY *Link;
|
||||
IEVENT *Event2;
|
||||
|
||||
ASSERT_LOCKED (&mEfiTimerLock);
|
||||
|
||||
//
|
||||
// Get the timer's trigger time
|
||||
//
|
||||
|
||||
TriggerTime = Event->u.Timer.TriggerTime;
|
||||
|
||||
//
|
||||
// Insert the timer into the timer database in assending sorted order
|
||||
//
|
||||
|
||||
for (Link = mEfiTimerList.ForwardLink; Link != &mEfiTimerList; Link = Link->ForwardLink) {
|
||||
Event2 = CR (Link, IEVENT, u.Timer.Link, EVENT_SIGNATURE);
|
||||
|
||||
if (Event2->u.Timer.TriggerTime > TriggerTime) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
InsertTailList (Link, &Event->u.Timer.Link);
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreSetTimer (
|
||||
IN EFI_EVENT UserEvent,
|
||||
IN EFI_TIMER_DELAY Type,
|
||||
IN UINT64 TriggerTime
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Sets the type of timer and the trigger time for a timer event.
|
||||
|
||||
Arguments:
|
||||
|
||||
UserEvent - The timer event that is to be signaled at the specified time
|
||||
Type - The type of time that is specified in TriggerTime
|
||||
TriggerTime - The number of 100ns units until the timer expires
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The event has been set to be signaled at the requested time
|
||||
EFI_INVALID_PARAMETER - Event or Type is not valid
|
||||
|
||||
--*/
|
||||
{
|
||||
IEVENT *Event;
|
||||
|
||||
Event = UserEvent;
|
||||
|
||||
if (Event == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Event->Signature != EVENT_SIGNATURE) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Type < 0 || Type > TimerRelative || !(Event->Type & EVT_TIMER)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
CoreAcquireLock (&mEfiTimerLock);
|
||||
|
||||
//
|
||||
// If the timer is queued to the timer database, remove it
|
||||
//
|
||||
|
||||
if (Event->u.Timer.Link.ForwardLink != NULL) {
|
||||
RemoveEntryList (&Event->u.Timer.Link);
|
||||
Event->u.Timer.Link.ForwardLink = NULL;
|
||||
}
|
||||
|
||||
Event->u.Timer.TriggerTime = 0;
|
||||
Event->u.Timer.Period = 0;
|
||||
|
||||
if (Type != TimerCancel) {
|
||||
|
||||
if (Type == TimerPeriodic) {
|
||||
Event->u.Timer.Period = TriggerTime;
|
||||
}
|
||||
|
||||
Event->u.Timer.TriggerTime = CoreCurrentSystemTime () + TriggerTime;
|
||||
CoreInsertEventTimer (Event);
|
||||
|
||||
if (TriggerTime == 0) {
|
||||
CoreSignalEvent (mEfiCheckTimerEvent);
|
||||
}
|
||||
}
|
||||
|
||||
CoreReleaseLock (&mEfiTimerLock);
|
||||
return EFI_SUCCESS;
|
||||
}
|
198
MdeModulePkg/Core/Dxe/Event/tpl.c
Normal file
198
MdeModulePkg/Core/Dxe/Event/tpl.c
Normal file
@ -0,0 +1,198 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
tpl.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Task priority function
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
CoreSetInterruptState (
|
||||
IN BOOLEAN Enable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Set Interrupt State
|
||||
|
||||
Arguments:
|
||||
|
||||
Enable - The state of enable or disable interrupt
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
if (gCpu != NULL) {
|
||||
if (Enable) {
|
||||
gCpu->EnableInterrupt(gCpu);
|
||||
} else {
|
||||
gCpu->DisableInterrupt(gCpu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Return the highest set bit
|
||||
//
|
||||
UINTN
|
||||
CoreHighestSetBit (
|
||||
IN UINTN Number
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Return the highest set bit
|
||||
|
||||
Arguments:
|
||||
|
||||
Number - The value to check
|
||||
|
||||
Returns:
|
||||
|
||||
Bit position of the highest set bit
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN msb;
|
||||
|
||||
msb = 31;
|
||||
while ((msb > 0) && ((Number & (UINTN)(1 << msb)) == 0)) {
|
||||
msb--;
|
||||
}
|
||||
|
||||
return msb;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_TPL
|
||||
EFIAPI
|
||||
CoreRaiseTpl (
|
||||
IN EFI_TPL NewTpl
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Raise the task priority level to the new level.
|
||||
High level is implemented by disabling processor interrupts.
|
||||
|
||||
Arguments:
|
||||
|
||||
NewTpl - New task priority level
|
||||
|
||||
Returns:
|
||||
|
||||
The previous task priority level
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
OldTpl = gEfiCurrentTpl;
|
||||
ASSERT (OldTpl <= NewTpl);
|
||||
ASSERT (VALID_TPL (NewTpl));
|
||||
|
||||
//
|
||||
// If raising to high level, disable interrupts
|
||||
//
|
||||
if (NewTpl >= TPL_HIGH_LEVEL && OldTpl < TPL_HIGH_LEVEL) {
|
||||
CoreSetInterruptState (FALSE);
|
||||
}
|
||||
|
||||
//
|
||||
// Set the new value
|
||||
//
|
||||
gEfiCurrentTpl = NewTpl;
|
||||
|
||||
return OldTpl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
CoreRestoreTpl (
|
||||
IN EFI_TPL NewTpl
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Lowers the task priority to the previous value. If the new
|
||||
priority unmasks events at a higher priority, they are dispatched.
|
||||
|
||||
Arguments:
|
||||
|
||||
NewTpl - New, lower, task priority
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
OldTpl = gEfiCurrentTpl;
|
||||
ASSERT (NewTpl <= OldTpl);
|
||||
ASSERT (VALID_TPL (NewTpl));
|
||||
|
||||
//
|
||||
// If lowering below HIGH_LEVEL, make sure
|
||||
// interrupts are enabled
|
||||
//
|
||||
|
||||
if (OldTpl >= TPL_HIGH_LEVEL && NewTpl < TPL_HIGH_LEVEL) {
|
||||
gEfiCurrentTpl = TPL_HIGH_LEVEL;
|
||||
}
|
||||
|
||||
//
|
||||
// Dispatch any pending events
|
||||
//
|
||||
|
||||
while ((-2 << NewTpl) & gEventPending) {
|
||||
gEfiCurrentTpl = CoreHighestSetBit (gEventPending);
|
||||
if (gEfiCurrentTpl < TPL_HIGH_LEVEL) {
|
||||
CoreSetInterruptState (TRUE);
|
||||
}
|
||||
CoreDispatchEventNotifies (gEfiCurrentTpl);
|
||||
}
|
||||
|
||||
//
|
||||
// Set the new value
|
||||
//
|
||||
|
||||
gEfiCurrentTpl = NewTpl;
|
||||
|
||||
//
|
||||
// If lowering below HIGH_LEVEL, make sure
|
||||
// interrupts are enabled
|
||||
//
|
||||
if (gEfiCurrentTpl < TPL_HIGH_LEVEL) {
|
||||
CoreSetInterruptState (TRUE);
|
||||
}
|
||||
|
||||
}
|
208
MdeModulePkg/Core/Dxe/Exec.h
Normal file
208
MdeModulePkg/Core/Dxe/Exec.h
Normal file
@ -0,0 +1,208 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
exec.h
|
||||
|
||||
Abstract:
|
||||
|
||||
EFI Event support
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _EXEC_H_
|
||||
#define _EXEC_H_
|
||||
|
||||
#define VALID_TPL(a) ((a) <= TPL_HIGH_LEVEL)
|
||||
|
||||
//
|
||||
// EFI_EVENT
|
||||
//
|
||||
|
||||
|
||||
|
||||
#define EVENT_SIGNATURE EFI_SIGNATURE_32('e','v','n','t')
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
UINT32 Type;
|
||||
UINT32 SignalCount;
|
||||
|
||||
//
|
||||
// Entry if the event is registered to be signalled
|
||||
//
|
||||
|
||||
LIST_ENTRY SignalLink;
|
||||
|
||||
//
|
||||
// Notification information for this event
|
||||
//
|
||||
|
||||
EFI_TPL NotifyTpl;
|
||||
EFI_EVENT_NOTIFY NotifyFunction;
|
||||
VOID *NotifyContext;
|
||||
EFI_GUID EventGroup;
|
||||
LIST_ENTRY NotifyLink;
|
||||
BOOLEAN ExFlag;
|
||||
|
||||
//
|
||||
// A list of all runtime events
|
||||
//
|
||||
EFI_RUNTIME_EVENT_ENTRY RuntimeData;
|
||||
|
||||
//
|
||||
// Information by event type
|
||||
//
|
||||
|
||||
union {
|
||||
//
|
||||
// For timer events
|
||||
//
|
||||
struct {
|
||||
LIST_ENTRY Link;
|
||||
UINT64 TriggerTime;
|
||||
UINT64 Period;
|
||||
} Timer;
|
||||
} u;
|
||||
|
||||
} IEVENT;
|
||||
|
||||
//
|
||||
// Internal prototypes
|
||||
//
|
||||
|
||||
VOID
|
||||
CoreDispatchEventNotifies (
|
||||
IN EFI_TPL Priority
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Dispatches all pending events.
|
||||
|
||||
Arguments:
|
||||
|
||||
Priority - The task priority level of event notifications to dispatch
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
UINTN
|
||||
CoreHighestSetBit (
|
||||
IN UINTN Number
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Return the highest set bit
|
||||
|
||||
Arguments:
|
||||
|
||||
Number - The value to check
|
||||
|
||||
Returns:
|
||||
|
||||
Bit position of the highest set bit
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
BOOLEAN
|
||||
GetInterruptState (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Disables CPU interrupts.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - Protocol instance structure
|
||||
|
||||
State - Pointer to the CPU's current interrupt state
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - If interrupts were disabled in the CPU.
|
||||
|
||||
EFI_INVALID_PARAMETER - State is NULL.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
//
|
||||
// Exported functions
|
||||
//
|
||||
|
||||
VOID
|
||||
CoreEventVirtualAddressFixup (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
A function out of date, should be removed.
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
VOID
|
||||
CoreInitializeTimer (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Initializes timer support
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
//
|
||||
// extern data declarations
|
||||
//
|
||||
|
||||
extern EFI_LOCK gEventQueueLock;
|
||||
extern UINTN gEventPending;
|
||||
extern LIST_ENTRY gEventQueue[];
|
||||
extern LIST_ENTRY gEventSignalQueue;
|
||||
extern UINT8 gHSB[];
|
||||
|
||||
#endif
|
266
MdeModulePkg/Core/Dxe/FwVol/Ffs.c
Normal file
266
MdeModulePkg/Core/Dxe/FwVol/Ffs.c
Normal file
@ -0,0 +1,266 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
Ffs.c
|
||||
|
||||
Abstract:
|
||||
|
||||
FFS file access utilities.
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
#define PHYSICAL_ADDRESS_TO_POINTER(Address) ((VOID *)((UINTN)(Address)))
|
||||
|
||||
|
||||
EFI_FFS_FILE_STATE
|
||||
GetFileState (
|
||||
IN UINT8 ErasePolarity,
|
||||
IN EFI_FFS_FILE_HEADER *FfsHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Get the FFS file state by checking the highest bit set in the header's state field
|
||||
|
||||
Arguments:
|
||||
ErasePolarity - Erase polarity attribute of the firmware volume
|
||||
FfsHeader - Points to the FFS file header
|
||||
|
||||
Returns:
|
||||
FFS File state
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_FFS_FILE_STATE FileState;
|
||||
UINT8 HighestBit;
|
||||
|
||||
FileState = FfsHeader->State;
|
||||
|
||||
if (ErasePolarity != 0) {
|
||||
FileState = (EFI_FFS_FILE_STATE)~FileState;
|
||||
}
|
||||
|
||||
HighestBit = 0x80;
|
||||
while (HighestBit != 0 && ((HighestBit & FileState) == 0)) {
|
||||
HighestBit >>= 1;
|
||||
}
|
||||
|
||||
return (EFI_FFS_FILE_STATE)HighestBit;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
IsBufferErased (
|
||||
IN UINT8 ErasePolarity,
|
||||
IN VOID *InBuffer,
|
||||
IN UINTN BufferSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Check if a block of buffer is erased
|
||||
|
||||
Arguments:
|
||||
ErasePolarity - Erase polarity attribute of the firmware volume
|
||||
InBuffer - The buffer to be checked
|
||||
BufferSize - Size of the buffer in bytes
|
||||
|
||||
Returns:
|
||||
TRUE - The block of buffer is erased
|
||||
FALSE - The block of buffer is not erased
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN Count;
|
||||
UINT8 EraseByte;
|
||||
UINT8 *Buffer;
|
||||
|
||||
if(ErasePolarity == 1) {
|
||||
EraseByte = 0xFF;
|
||||
} else {
|
||||
EraseByte = 0;
|
||||
}
|
||||
|
||||
Buffer = InBuffer;
|
||||
for (Count = 0; Count < BufferSize; Count++) {
|
||||
if (Buffer[Count] != EraseByte) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
VerifyFvHeaderChecksum (
|
||||
IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Verify checksum of the firmware volume header
|
||||
|
||||
Arguments:
|
||||
FvHeader - Points to the firmware volume header to be checked
|
||||
|
||||
Returns:
|
||||
TRUE - Checksum verification passed
|
||||
FALSE - Checksum verification failed
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT32 Index;
|
||||
UINT32 HeaderLength;
|
||||
UINT16 Checksum;
|
||||
UINT16 *ptr;
|
||||
|
||||
HeaderLength = FvHeader->HeaderLength;
|
||||
ptr = (UINT16 *)FvHeader;
|
||||
Checksum = 0;
|
||||
|
||||
for (Index = 0; Index < HeaderLength / sizeof (UINT16); Index++) {
|
||||
Checksum = (UINT16)(Checksum + ptr[Index]);
|
||||
}
|
||||
|
||||
if (Checksum == 0) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
BOOLEAN
|
||||
VerifyHeaderChecksum (
|
||||
IN EFI_FFS_FILE_HEADER *FfsHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Verify checksum of the FFS file header
|
||||
|
||||
Arguments:
|
||||
FfsHeader - Points to the FFS file header to be checked
|
||||
|
||||
Returns:
|
||||
TRUE - Checksum verification passed
|
||||
FALSE - Checksum verification failed
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT32 Index;
|
||||
UINT8 *ptr;
|
||||
UINT8 HeaderChecksum;
|
||||
|
||||
ptr = (UINT8 *)FfsHeader;
|
||||
HeaderChecksum = 0;
|
||||
for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {
|
||||
HeaderChecksum = (UINT8)(HeaderChecksum + ptr[Index]);
|
||||
}
|
||||
|
||||
HeaderChecksum = (UINT8) (HeaderChecksum - FfsHeader->State - FfsHeader->IntegrityCheck.Checksum.File);
|
||||
|
||||
if (HeaderChecksum == 0) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
IsValidFfsHeader (
|
||||
IN UINT8 ErasePolarity,
|
||||
IN EFI_FFS_FILE_HEADER *FfsHeader,
|
||||
OUT EFI_FFS_FILE_STATE *FileState
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Check if it's a valid FFS file header
|
||||
|
||||
Arguments:
|
||||
ErasePolarity - Erase polarity attribute of the firmware volume
|
||||
FfsHeader - Points to the FFS file header to be checked
|
||||
FileState - FFS file state to be returned
|
||||
|
||||
Returns:
|
||||
TRUE - Valid FFS file header
|
||||
FALSE - Invalid FFS file header
|
||||
|
||||
--*/
|
||||
{
|
||||
*FileState = GetFileState (ErasePolarity, FfsHeader);
|
||||
|
||||
switch (*FileState) {
|
||||
case EFI_FILE_HEADER_VALID:
|
||||
case EFI_FILE_DATA_VALID:
|
||||
case EFI_FILE_MARKED_FOR_UPDATE:
|
||||
case EFI_FILE_DELETED:
|
||||
//
|
||||
// Here we need to verify header checksum
|
||||
//
|
||||
return VerifyHeaderChecksum (FfsHeader);
|
||||
|
||||
case EFI_FILE_HEADER_CONSTRUCTION:
|
||||
case EFI_FILE_HEADER_INVALID:
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
IsValidFfsFile (
|
||||
IN UINT8 ErasePolarity,
|
||||
IN EFI_FFS_FILE_HEADER *FfsHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Check if it's a valid FFS file.
|
||||
Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first.
|
||||
|
||||
Arguments:
|
||||
ErasePolarity - Erase polarity attribute of the firmware volume
|
||||
FfsHeader - Points to the FFS file to be checked
|
||||
|
||||
Returns:
|
||||
TRUE - Valid FFS file
|
||||
FALSE - Invalid FFS file
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_FFS_FILE_STATE FileState;
|
||||
|
||||
FileState = GetFileState (ErasePolarity, FfsHeader);
|
||||
switch (FileState) {
|
||||
|
||||
case EFI_FILE_DELETED:
|
||||
case EFI_FILE_DATA_VALID:
|
||||
case EFI_FILE_MARKED_FOR_UPDATE:
|
||||
//
|
||||
// Some other vliadation like file content checksum might be done here.
|
||||
// For performance issue, Tiano only do FileState check.
|
||||
//
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
547
MdeModulePkg/Core/Dxe/FwVol/FwVol.c
Normal file
547
MdeModulePkg/Core/Dxe/FwVol/FwVol.c
Normal file
@ -0,0 +1,547 @@
|
||||
/**@file
|
||||
Firmware File System driver that produce Firmware Volume protocol.
|
||||
Layers on top of Firmware Block protocol to produce a file abstraction
|
||||
of FV based files.
|
||||
|
||||
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.
|
||||
|
||||
**/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
#define KEYSIZE sizeof (UINTN)
|
||||
|
||||
//
|
||||
// Protocol notify related globals
|
||||
//
|
||||
VOID *gEfiFwVolBlockNotifyReg;
|
||||
EFI_EVENT gEfiFwVolBlockEvent;
|
||||
|
||||
FV_DEVICE mFvDevice = {
|
||||
FV_DEVICE_SIGNATURE,
|
||||
NULL,
|
||||
NULL,
|
||||
{
|
||||
FvGetVolumeAttributes,
|
||||
FvSetVolumeAttributes,
|
||||
FvReadFile,
|
||||
FvReadFileSection,
|
||||
FvWriteFile,
|
||||
FvGetNextFile,
|
||||
KEYSIZE
|
||||
},
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
{ NULL, NULL },
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// FFS helper functions
|
||||
//
|
||||
|
||||
EFI_STATUS
|
||||
GetFwVolHeader (
|
||||
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb,
|
||||
OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
given the supplied FW_VOL_BLOCK_PROTOCOL, allocate a buffer for output and
|
||||
copy the volume header into it.
|
||||
|
||||
Arguments:
|
||||
Fvb - The FW_VOL_BLOCK_PROTOCOL instance from which to read the volume
|
||||
header
|
||||
FwVolHeader - Pointer to pointer to allocated buffer in which the volume
|
||||
header is returned.
|
||||
|
||||
Returns:
|
||||
EFI_OUT_OF_RESOURCES - No enough buffer could be allocated.
|
||||
EFI_SUCCESS - Successfully read volume header to the allocated buffer.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FIRMWARE_VOLUME_HEADER TempFvh;
|
||||
UINTN FvhLength;
|
||||
UINT8 *Buffer;
|
||||
|
||||
|
||||
//
|
||||
//Determine the real length of FV header
|
||||
//
|
||||
FvhLength = sizeof (EFI_FIRMWARE_VOLUME_HEADER);
|
||||
Status = Fvb->Read (Fvb, 0, 0, &FvhLength, (UINT8 *)&TempFvh);
|
||||
|
||||
//
|
||||
// Allocate a buffer for the caller
|
||||
//
|
||||
*FwVolHeader = CoreAllocateBootServicesPool (TempFvh.HeaderLength);
|
||||
if (*FwVolHeader == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Copy the standard header into the buffer
|
||||
//
|
||||
CopyMem (*FwVolHeader, &TempFvh, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
|
||||
|
||||
//
|
||||
// Read the rest of the header
|
||||
//
|
||||
FvhLength = TempFvh.HeaderLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER);
|
||||
Buffer = (UINT8 *)*FwVolHeader + sizeof (EFI_FIRMWARE_VOLUME_HEADER);
|
||||
Status = Fvb->Read (Fvb, 0, sizeof (EFI_FIRMWARE_VOLUME_HEADER), &FvhLength, Buffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Read failed so free buffer
|
||||
//
|
||||
CoreFreePool (*FwVolHeader);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
FreeFvDeviceResource (
|
||||
IN FV_DEVICE *FvDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Free FvDevice resource when error happens
|
||||
|
||||
Arguments:
|
||||
FvDevice - pointer to the FvDevice to be freed.
|
||||
|
||||
Returns:
|
||||
None.
|
||||
|
||||
--*/
|
||||
{
|
||||
FFS_FILE_LIST_ENTRY *FfsFileEntry;
|
||||
LIST_ENTRY *NextEntry;
|
||||
|
||||
//
|
||||
// Free File List Entry
|
||||
//
|
||||
FfsFileEntry = (FFS_FILE_LIST_ENTRY *)FvDevice->FfsFileListHeader.ForwardLink;
|
||||
while (&FfsFileEntry->Link != &FvDevice->FfsFileListHeader) {
|
||||
NextEntry = (&FfsFileEntry->Link)->ForwardLink;
|
||||
|
||||
if (FfsFileEntry->StreamHandle != 0) {
|
||||
//
|
||||
// Close stream and free resources from SEP
|
||||
//
|
||||
FfsFileEntry->Sep->CloseSectionStream (FfsFileEntry->Sep, FfsFileEntry->StreamHandle);
|
||||
}
|
||||
|
||||
CoreFreePool (FfsFileEntry);
|
||||
|
||||
FfsFileEntry = (FFS_FILE_LIST_ENTRY *)NextEntry;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Free the cache
|
||||
//
|
||||
CoreFreePool (FvDevice->CachedFv);
|
||||
|
||||
//
|
||||
// Free Volume Header
|
||||
//
|
||||
CoreFreePool (FvDevice->FwVolHeader);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
FvCheck (
|
||||
IN OUT FV_DEVICE *FvDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Check if a FV is consistent and allocate cache
|
||||
|
||||
Arguments:
|
||||
FvDevice - pointer to the FvDevice to be checked.
|
||||
|
||||
Returns:
|
||||
EFI_OUT_OF_RESOURCES - No enough buffer could be allocated.
|
||||
EFI_SUCCESS - FV is consistent and cache is allocated.
|
||||
EFI_VOLUME_CORRUPTED - File system is corrupted.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
EFI_FVB_ATTRIBUTES FvbAttributes;
|
||||
EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
|
||||
FFS_FILE_LIST_ENTRY *FfsFileEntry;
|
||||
EFI_FFS_FILE_HEADER *FfsHeader;
|
||||
UINT8 *CacheLocation;
|
||||
UINTN LbaOffset;
|
||||
UINTN Index;
|
||||
EFI_LBA LbaIndex;
|
||||
UINTN Size;
|
||||
UINTN FileLength;
|
||||
EFI_FFS_FILE_STATE FileState;
|
||||
UINT8 *TopFvAddress;
|
||||
UINTN TestLength;
|
||||
|
||||
|
||||
Fvb = FvDevice->Fvb;
|
||||
FwVolHeader = FvDevice->FwVolHeader;
|
||||
|
||||
Status = Fvb->GetAttributes (Fvb, &FvbAttributes);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Size is the size of the FV minus the head. We have already allocated
|
||||
// the header to check to make sure the volume is valid
|
||||
//
|
||||
Size = (UINTN)(FwVolHeader->FvLength - FwVolHeader->HeaderLength);
|
||||
FvDevice->CachedFv = CoreAllocateBootServicesPool (Size);
|
||||
|
||||
if (FvDevice->CachedFv == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Remember a pointer to the end fo the CachedFv
|
||||
//
|
||||
FvDevice->EndOfCachedFv = FvDevice->CachedFv + Size;
|
||||
|
||||
//
|
||||
// Copy FV minus header into memory using the block map we have all ready
|
||||
// read into memory.
|
||||
//
|
||||
BlockMap = FwVolHeader->BlockMap;
|
||||
CacheLocation = FvDevice->CachedFv;
|
||||
LbaIndex = 0;
|
||||
LbaOffset = FwVolHeader->HeaderLength;
|
||||
while ((BlockMap->NumBlocks != 0) || (BlockMap->Length != 0)) {
|
||||
|
||||
for (Index = 0; Index < BlockMap->NumBlocks; Index ++) {
|
||||
|
||||
Size = BlockMap->Length;
|
||||
if (Index == 0) {
|
||||
//
|
||||
// Cache does not include FV Header
|
||||
//
|
||||
Size -= LbaOffset;
|
||||
}
|
||||
Status = Fvb->Read (Fvb,
|
||||
LbaIndex,
|
||||
LbaOffset,
|
||||
&Size,
|
||||
CacheLocation
|
||||
);
|
||||
//
|
||||
// Not check EFI_BAD_BUFFER_SIZE, for Size = BlockMap->Length
|
||||
//
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// After we skip Fv Header always read from start of block
|
||||
//
|
||||
LbaOffset = 0;
|
||||
|
||||
LbaIndex++;
|
||||
CacheLocation += Size;
|
||||
}
|
||||
BlockMap++;
|
||||
}
|
||||
|
||||
//
|
||||
// Scan to check the free space & File list
|
||||
//
|
||||
if (FvbAttributes & EFI_FVB_ERASE_POLARITY) {
|
||||
FvDevice->ErasePolarity = 1;
|
||||
} else {
|
||||
FvDevice->ErasePolarity = 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// go through the whole FV cache, check the consistence of the FV.
|
||||
// Make a linked list off all the Ffs file headers
|
||||
//
|
||||
Status = EFI_SUCCESS;
|
||||
InitializeListHead (&FvDevice->FfsFileListHeader);
|
||||
|
||||
//
|
||||
// Build FFS list
|
||||
//
|
||||
FfsHeader = (EFI_FFS_FILE_HEADER *)FvDevice->CachedFv;
|
||||
TopFvAddress = FvDevice->EndOfCachedFv;
|
||||
while ((UINT8 *)FfsHeader < TopFvAddress) {
|
||||
|
||||
TestLength = TopFvAddress - ((UINT8 *)FfsHeader);
|
||||
if (TestLength > sizeof (EFI_FFS_FILE_HEADER)) {
|
||||
TestLength = sizeof (EFI_FFS_FILE_HEADER);
|
||||
}
|
||||
|
||||
if (IsBufferErased (FvDevice->ErasePolarity, FfsHeader, TestLength)) {
|
||||
//
|
||||
// We have found the free space so we are done!
|
||||
//
|
||||
goto Done;
|
||||
}
|
||||
|
||||
if (!IsValidFfsHeader (FvDevice->ErasePolarity, FfsHeader, &FileState)) {
|
||||
if ((FileState == EFI_FILE_HEADER_INVALID) ||
|
||||
(FileState == EFI_FILE_HEADER_CONSTRUCTION)) {
|
||||
FfsHeader++;
|
||||
|
||||
continue;
|
||||
|
||||
} else {
|
||||
//
|
||||
// File system is corrputed
|
||||
//
|
||||
Status = EFI_VOLUME_CORRUPTED;
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsValidFfsFile (FvDevice->ErasePolarity, FfsHeader)) {
|
||||
//
|
||||
// File system is corrupted
|
||||
//
|
||||
Status = EFI_VOLUME_CORRUPTED;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Size[3] is a three byte array, read 4 bytes and throw one away
|
||||
//
|
||||
FileLength = *(UINT32 *)&FfsHeader->Size[0] & 0x00FFFFFF;
|
||||
|
||||
FileState = GetFileState (FvDevice->ErasePolarity, FfsHeader);
|
||||
|
||||
//
|
||||
// check for non-deleted file
|
||||
//
|
||||
if (FileState != EFI_FILE_DELETED) {
|
||||
//
|
||||
// Create a FFS list entry for each non-deleted file
|
||||
//
|
||||
FfsFileEntry = CoreAllocateZeroBootServicesPool (sizeof (FFS_FILE_LIST_ENTRY));
|
||||
if (FfsFileEntry == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
FfsFileEntry->FfsHeader = FfsHeader;
|
||||
InsertTailList (&FvDevice->FfsFileListHeader, &FfsFileEntry->Link);
|
||||
}
|
||||
|
||||
FfsHeader = (EFI_FFS_FILE_HEADER *)(((UINT8 *)FfsHeader) + FileLength);
|
||||
|
||||
//
|
||||
// Adjust pointer to the next 8-byte aligned boundry.
|
||||
//
|
||||
FfsHeader = (EFI_FFS_FILE_HEADER *)(((UINTN)FfsHeader + 7) & ~0x07);
|
||||
|
||||
}
|
||||
|
||||
Done:
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreeFvDeviceResource (FvDevice);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
EFIAPI
|
||||
NotifyFwVolBlock (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This notification function is invoked when an instance of the
|
||||
EFI_FW_VOLUME_BLOCK_PROTOCOL is produced. It layers an instance of the
|
||||
EFI_FIRMWARE_VOLUME_PROTOCOL on the same handle. This is the function where
|
||||
the actual initialization of the EFI_FIRMWARE_VOLUME_PROTOCOL is done.
|
||||
|
||||
Arguments:
|
||||
Event - The event that occured
|
||||
Context - For EFI compatiblity. Not used.
|
||||
|
||||
Returns:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_HANDLE Handle;
|
||||
EFI_STATUS Status;
|
||||
UINTN BufferSize;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
|
||||
EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
|
||||
FV_DEVICE *FvDevice;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
//
|
||||
// Examine all new handles
|
||||
//
|
||||
for (;;) {
|
||||
//
|
||||
// Get the next handle
|
||||
//
|
||||
BufferSize = sizeof (Handle);
|
||||
Status = CoreLocateHandle (
|
||||
ByRegisterNotify,
|
||||
NULL,
|
||||
gEfiFwVolBlockNotifyReg,
|
||||
&BufferSize,
|
||||
&Handle
|
||||
);
|
||||
|
||||
//
|
||||
// If not found, we're done
|
||||
//
|
||||
if (EFI_NOT_FOUND == Status) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the FirmwareVolumeBlock protocol on that handle
|
||||
//
|
||||
Status = CoreHandleProtocol (Handle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
|
||||
//
|
||||
// Make sure the Fv Header is O.K.
|
||||
//
|
||||
Status = GetFwVolHeader (Fvb, &FwVolHeader);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VerifyFvHeaderChecksum (FwVolHeader)) {
|
||||
CoreFreePool (FwVolHeader);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Check to see that the file system is indeed formatted in a way we can
|
||||
// understand it...
|
||||
//
|
||||
if (!CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystemGuid)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if there is an FV protocol already installed in that handle
|
||||
//
|
||||
Status = CoreHandleProtocol (Handle, &gEfiFirmwareVolumeProtocolGuid, (VOID **)&Fv);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Update Fv to use a new Fvb
|
||||
//
|
||||
FvDevice = _CR (Fv, FV_DEVICE, Fv);
|
||||
if (FvDevice->Signature == FV_DEVICE_SIGNATURE) {
|
||||
//
|
||||
// Only write into our device structure if it's our device structure
|
||||
//
|
||||
FvDevice->Fvb = Fvb;
|
||||
}
|
||||
|
||||
} else {
|
||||
//
|
||||
// No FwVol protocol on the handle so create a new one
|
||||
//
|
||||
FvDevice = CoreAllocateCopyPool (sizeof (FV_DEVICE), &mFvDevice);
|
||||
if (FvDevice == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
FvDevice->Fvb = Fvb;
|
||||
FvDevice->Handle = Handle;
|
||||
FvDevice->FwVolHeader = FwVolHeader;
|
||||
FvDevice->Fv.ParentHandle = Fvb->ParentHandle;
|
||||
|
||||
//
|
||||
// Install an New FV protocol on the existing handle
|
||||
//
|
||||
Status = CoreInstallProtocolInterface (
|
||||
&Handle,
|
||||
&gEfiFirmwareVolumeProtocolGuid,
|
||||
EFI_NATIVE_INTERFACE,
|
||||
&FvDevice->Fv
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolDriverInit (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This routine is the driver initialization entry point. It initializes the
|
||||
libraries, and registers two notification functions. These notification
|
||||
functions are responsible for building the FV stack dynamically.
|
||||
|
||||
Arguments:
|
||||
ImageHandle - The image handle.
|
||||
SystemTable - The system table.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Function successfully returned.
|
||||
|
||||
--*/
|
||||
{
|
||||
gEfiFwVolBlockEvent = CoreCreateProtocolNotifyEvent (
|
||||
&gEfiFirmwareVolumeBlockProtocolGuid,
|
||||
TPL_CALLBACK,
|
||||
NotifyFwVolBlock,
|
||||
NULL,
|
||||
&gEfiFwVolBlockNotifyReg,
|
||||
TRUE
|
||||
);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
99
MdeModulePkg/Core/Dxe/FwVol/FwVolAttrib.c
Normal file
99
MdeModulePkg/Core/Dxe/FwVol/FwVolAttrib.c
Normal file
@ -0,0 +1,99 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
FwVolAttrib.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Implements get/set firmware volume attributes
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvGetVolumeAttributes (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
OUT EFI_FV_ATTRIBUTES *Attributes
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrieves attributes, insures positive polarity of attribute bits, returns
|
||||
resulting attributes in output parameter
|
||||
|
||||
Arguments:
|
||||
This - Calling context
|
||||
Attributes - output buffer which contains attributes
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully got volume attributes
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
FV_DEVICE *FvDevice;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
|
||||
EFI_FVB_ATTRIBUTES FvbAttributes;
|
||||
|
||||
FvDevice = FV_DEVICE_FROM_THIS (This);
|
||||
Fvb = FvDevice->Fvb;
|
||||
|
||||
if (FvDevice->CachedFv == NULL) {
|
||||
Status = FvCheck (FvDevice);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// First get the Firmware Volume Block Attributes
|
||||
//
|
||||
Status = Fvb->GetAttributes (Fvb, &FvbAttributes);
|
||||
|
||||
//
|
||||
// Mask out Fvb bits that are not defined in FV
|
||||
//
|
||||
FvbAttributes &= 0xfffff0ff;
|
||||
|
||||
*Attributes = (EFI_FV_ATTRIBUTES)FvbAttributes;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvSetVolumeAttributes (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
IN OUT EFI_FV_ATTRIBUTES *Attributes
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Sets current attributes for volume
|
||||
|
||||
Arguments:
|
||||
This - Calling context
|
||||
Attributes - At input, contains attributes to be set. At output contains
|
||||
new value of FV
|
||||
|
||||
Returns:
|
||||
EFI_UNSUPPORTED - Could not be set.
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
516
MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c
Normal file
516
MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c
Normal file
@ -0,0 +1,516 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
FwVolRead.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Implements read firmware file
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
/*++
|
||||
|
||||
Required Alignment Alignment Value in FFS Alignment Value in
|
||||
(bytes) Attributes Field Firmware Volume Interfaces
|
||||
1 0 0
|
||||
2 0 1
|
||||
4 0 2
|
||||
8 0 3
|
||||
16 1 4
|
||||
128 2 7
|
||||
512 3 9
|
||||
1 KB 4 10
|
||||
4 KB 5 12
|
||||
32 KB 6 15
|
||||
64 KB 7 16
|
||||
|
||||
--*/
|
||||
|
||||
UINT8 mFvAttributes[] = {0, 4, 7, 9, 10, 12, 15, 16};
|
||||
|
||||
|
||||
STATIC
|
||||
EFI_FV_FILE_ATTRIBUTES
|
||||
FfsAttributes2FvFileAttributes (
|
||||
IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Convert the FFS File Attributes to FV File Attributes
|
||||
|
||||
Arguments:
|
||||
FfsAttributes - The attributes of UINT8 type.
|
||||
|
||||
Returns:
|
||||
The attributes of EFI_FV_FILE_ATTRIBUTES
|
||||
|
||||
--*/
|
||||
{
|
||||
FfsAttributes = (EFI_FFS_FILE_ATTRIBUTES)((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3);
|
||||
ASSERT (FfsAttributes < 8);
|
||||
|
||||
return (EFI_FV_FILE_ATTRIBUTES) mFvAttributes[FfsAttributes];
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvGetNextFile (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
IN OUT VOID *Key,
|
||||
IN OUT EFI_FV_FILETYPE *FileType,
|
||||
OUT EFI_GUID *NameGuid,
|
||||
OUT EFI_FV_FILE_ATTRIBUTES *Attributes,
|
||||
OUT UINTN *Size
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Given the input key, search for the next matching file in the volume.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
FileType - FileType is a pointer to a caller allocated
|
||||
EFI_FV_FILETYPE. The GetNextFile() API can filter it's
|
||||
search for files based on the value of *FileType input.
|
||||
A *FileType input of 0 causes GetNextFile() to search for
|
||||
files of all types. If a file is found, the file's type
|
||||
is returned in *FileType. *FileType is not modified if
|
||||
no file is found.
|
||||
Key - Key is a pointer to a caller allocated buffer that
|
||||
contains implementation specific data that is used to
|
||||
track where to begin the search for the next file.
|
||||
The size of the buffer must be at least This->KeySize
|
||||
bytes long. To reinitialize the search and begin from
|
||||
the beginning of the firmware volume, the entire buffer
|
||||
must be cleared to zero. Other than clearing the buffer
|
||||
to initiate a new search, the caller must not modify the
|
||||
data in the buffer between calls to GetNextFile().
|
||||
NameGuid - NameGuid is a pointer to a caller allocated EFI_GUID.
|
||||
If a file is found, the file's name is returned in
|
||||
*NameGuid. *NameGuid is not modified if no file is
|
||||
found.
|
||||
Attributes - Attributes is a pointer to a caller allocated
|
||||
EFI_FV_FILE_ATTRIBUTES. If a file is found, the file's
|
||||
attributes are returned in *Attributes. *Attributes is
|
||||
not modified if no file is found.
|
||||
Size - Size is a pointer to a caller allocated UINTN.
|
||||
If a file is found, the file's size is returned in *Size.
|
||||
*Size is not modified if no file is found.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully find the file.
|
||||
EFI_DEVICE_ERROR - Device error.
|
||||
EFI_ACCESS_DENIED - Fv could not read.
|
||||
EFI_NOT_FOUND - No matching file found.
|
||||
EFI_INVALID_PARAMETER - Invalid parameter
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
FV_DEVICE *FvDevice;
|
||||
EFI_FV_ATTRIBUTES FvAttributes;
|
||||
EFI_FFS_FILE_HEADER *FfsFileHeader;
|
||||
UINTN *KeyValue;
|
||||
LIST_ENTRY *Link;
|
||||
FFS_FILE_LIST_ENTRY *FfsFileEntry;
|
||||
UINTN FileLength;
|
||||
|
||||
FvDevice = FV_DEVICE_FROM_THIS (This);
|
||||
|
||||
Status = FvGetVolumeAttributes (This, &FvAttributes);
|
||||
if (EFI_ERROR (Status)){
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if read operation is enabled
|
||||
//
|
||||
if ((FvAttributes & EFI_FV_READ_STATUS) == 0) {
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (*FileType > EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
|
||||
//
|
||||
// File type needs to be in 0 - 0x0B
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
KeyValue = (UINTN *)Key;
|
||||
for (;;) {
|
||||
if (*KeyValue == 0) {
|
||||
//
|
||||
// Search for 1st matching file
|
||||
//
|
||||
Link = &FvDevice->FfsFileListHeader;
|
||||
} else {
|
||||
//
|
||||
// Key is pointer to FFsFileEntry, so get next one
|
||||
//
|
||||
Link = (LIST_ENTRY *)(*KeyValue);
|
||||
}
|
||||
|
||||
if (Link->ForwardLink == &FvDevice->FfsFileListHeader) {
|
||||
//
|
||||
// Next is end of list so we did not find data
|
||||
//
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
FfsFileEntry = (FFS_FILE_LIST_ENTRY *)Link->ForwardLink;
|
||||
FfsFileHeader = (EFI_FFS_FILE_HEADER *)FfsFileEntry->FfsHeader;
|
||||
|
||||
//
|
||||
// remember the key
|
||||
//
|
||||
*KeyValue = (UINTN)FfsFileEntry;
|
||||
|
||||
if (FfsFileHeader->Type == EFI_FV_FILETYPE_FFS_PAD) {
|
||||
//
|
||||
// we ignore pad files
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*FileType == 0) {
|
||||
//
|
||||
// Process all file types so we have a match
|
||||
//
|
||||
break;
|
||||
}
|
||||
|
||||
if (*FileType == FfsFileHeader->Type) {
|
||||
//
|
||||
// Found a matching file type
|
||||
//
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Return FileType, NameGuid, and Attributes
|
||||
//
|
||||
*FileType = FfsFileHeader->Type;
|
||||
CopyMem (NameGuid, &FfsFileHeader->Name, sizeof (EFI_GUID));
|
||||
*Attributes = FfsAttributes2FvFileAttributes (FfsFileHeader->Attributes);
|
||||
|
||||
//
|
||||
// Read four bytes out of the 3 byte array and throw out extra data
|
||||
//
|
||||
FileLength = *(UINT32 *)&FfsFileHeader->Size[0] & 0x00FFFFFF;
|
||||
|
||||
//
|
||||
// we need to substract the header size
|
||||
//
|
||||
*Size = FileLength - sizeof(EFI_FFS_FILE_HEADER);
|
||||
|
||||
if (FfsFileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
|
||||
//
|
||||
// If tail is present substract it's size;
|
||||
//
|
||||
*Size -= sizeof(EFI_FFS_FILE_TAIL);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvReadFile (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
IN EFI_GUID *NameGuid,
|
||||
IN OUT VOID **Buffer,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT EFI_FV_FILETYPE *FoundType,
|
||||
OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,
|
||||
OUT UINT32 *AuthenticationStatus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Locates a file in the firmware volume and
|
||||
copies it to the supplied buffer.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
NameGuid - Pointer to an EFI_GUID, which is the filename.
|
||||
Buffer - Buffer is a pointer to pointer to a buffer in
|
||||
which the file or section contents or are returned.
|
||||
BufferSize - BufferSize is a pointer to caller allocated
|
||||
UINTN. On input *BufferSize indicates the size
|
||||
in bytes of the memory region pointed to by
|
||||
Buffer. On output, *BufferSize contains the number
|
||||
of bytes required to read the file.
|
||||
FoundType - FoundType is a pointer to a caller allocated
|
||||
EFI_FV_FILETYPE that on successful return from Read()
|
||||
contains the type of file read. This output reflects
|
||||
the file type irrespective of the value of the
|
||||
SectionType input.
|
||||
FileAttributes - FileAttributes is a pointer to a caller allocated
|
||||
EFI_FV_FILE_ATTRIBUTES. On successful return from
|
||||
Read(), *FileAttributes contains the attributes of
|
||||
the file read.
|
||||
AuthenticationStatus - AuthenticationStatus is a pointer to a caller
|
||||
allocated UINTN in which the authentication status
|
||||
is returned.
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully read to memory buffer.
|
||||
EFI_WARN_BUFFER_TOO_SMALL - Buffer too small.
|
||||
EFI_NOT_FOUND - Not found.
|
||||
EFI_DEVICE_ERROR - Device error.
|
||||
EFI_ACCESS_DENIED - Could not read.
|
||||
EFI_INVALID_PARAMETER - Invalid parameter.
|
||||
EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
FV_DEVICE *FvDevice;
|
||||
EFI_GUID SearchNameGuid;
|
||||
EFI_FV_FILETYPE LocalFoundType;
|
||||
EFI_FV_FILE_ATTRIBUTES LocalAttributes;
|
||||
UINTN FileSize;
|
||||
UINT8 *SrcPtr;
|
||||
EFI_FFS_FILE_HEADER *FfsHeader;
|
||||
UINTN InputBufferSize;
|
||||
|
||||
if (NULL == NameGuid) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
FvDevice = FV_DEVICE_FROM_THIS (This);
|
||||
|
||||
|
||||
//
|
||||
// Keep looking until we find the matching NameGuid.
|
||||
// The Key is really an FfsFileEntry
|
||||
//
|
||||
FvDevice->LastKey = 0;
|
||||
do {
|
||||
LocalFoundType = 0;
|
||||
Status = FvGetNextFile (
|
||||
This,
|
||||
&FvDevice->LastKey,
|
||||
&LocalFoundType,
|
||||
&SearchNameGuid,
|
||||
&LocalAttributes,
|
||||
&FileSize
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
} while (!CompareGuid (&SearchNameGuid, NameGuid));
|
||||
|
||||
//
|
||||
// Get a pointer to the header
|
||||
//
|
||||
FfsHeader = FvDevice->LastKey->FfsHeader;
|
||||
|
||||
//
|
||||
// Remember callers buffer size
|
||||
//
|
||||
InputBufferSize = *BufferSize;
|
||||
|
||||
//
|
||||
// Calculate return values
|
||||
//
|
||||
*FoundType = FfsHeader->Type;
|
||||
*FileAttributes = FfsAttributes2FvFileAttributes (FfsHeader->Attributes);
|
||||
*AuthenticationStatus = 0;
|
||||
*BufferSize = FileSize;
|
||||
|
||||
if (Buffer == NULL) {
|
||||
//
|
||||
// If Buffer is NULL, we only want to get the information colected so far
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Skip over file header
|
||||
//
|
||||
SrcPtr = ((UINT8 *)FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
if (*Buffer == NULL) {
|
||||
//
|
||||
// Caller passed in a pointer so allocate buffer for them
|
||||
//
|
||||
*Buffer = CoreAllocateBootServicesPool (FileSize);
|
||||
if (*Buffer == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
} else if (FileSize > InputBufferSize) {
|
||||
//
|
||||
// Callers buffer was not big enough
|
||||
//
|
||||
Status = EFI_WARN_BUFFER_TOO_SMALL;
|
||||
FileSize = InputBufferSize;
|
||||
}
|
||||
|
||||
//
|
||||
// Copy data into callers buffer
|
||||
//
|
||||
CopyMem (*Buffer, SrcPtr, FileSize);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvReadFileSection (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
IN EFI_GUID *NameGuid,
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN UINTN SectionInstance,
|
||||
IN OUT VOID **Buffer,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT UINT32 *AuthenticationStatus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Locates a section in a given FFS File and
|
||||
copies it to the supplied buffer (not including section header).
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
NameGuid - Pointer to an EFI_GUID, which is the filename.
|
||||
SectionType - Indicates the section type to return.
|
||||
SectionInstance - Indicates which instance of sections with a type of
|
||||
SectionType to return.
|
||||
Buffer - Buffer is a pointer to pointer to a buffer in which
|
||||
the file or section contents or are returned.
|
||||
BufferSize - BufferSize is a pointer to caller allocated UINTN.
|
||||
AuthenticationStatus -AuthenticationStatus is a pointer to a caller
|
||||
allocated UINT32 in which the authentication status
|
||||
is returned.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully read the file section into buffer.
|
||||
EFI_WARN_BUFFER_TOO_SMALL - Buffer too small.
|
||||
EFI_NOT_FOUND - Section not found.
|
||||
EFI_DEVICE_ERROR - Device error.
|
||||
EFI_ACCESS_DENIED - Could not read.
|
||||
EFI_INVALID_PARAMETER - Invalid parameter.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
FV_DEVICE *FvDevice;
|
||||
EFI_FV_FILETYPE FileType;
|
||||
EFI_FV_FILE_ATTRIBUTES FileAttributes;
|
||||
UINTN FileSize;
|
||||
UINT8 *FileBuffer;
|
||||
EFI_SECTION_EXTRACTION_PROTOCOL *Sep;
|
||||
FFS_FILE_LIST_ENTRY *FfsEntry;
|
||||
|
||||
if (NULL == NameGuid || Buffer == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
FvDevice = FV_DEVICE_FROM_THIS (This);
|
||||
|
||||
//
|
||||
// Read the whole file into buffer
|
||||
//
|
||||
FileBuffer = NULL;
|
||||
Status = FvReadFile (
|
||||
This,
|
||||
NameGuid,
|
||||
(VOID **)&FileBuffer,
|
||||
&FileSize,
|
||||
&FileType,
|
||||
&FileAttributes,
|
||||
AuthenticationStatus
|
||||
);
|
||||
//
|
||||
// Get the last key used by our call to FvReadFile as it is the FfsEntry for this file.
|
||||
//
|
||||
FfsEntry = (FFS_FILE_LIST_ENTRY *)FvDevice->LastKey;
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Check to see that the file actually HAS sections before we go any further.
|
||||
//
|
||||
if (FileType == EFI_FV_FILETYPE_RAW) {
|
||||
Status = EFI_NOT_FOUND;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Use FfsEntry to cache Section Extraction Protocol Inforomation
|
||||
//
|
||||
if (FfsEntry->StreamHandle == 0) {
|
||||
//
|
||||
// Located the protocol
|
||||
//
|
||||
Status = CoreLocateProtocol (&gEfiSectionExtractionProtocolGuid, NULL, (VOID **)&Sep);
|
||||
//
|
||||
// Section Extraction Protocol is part of Dxe Core so this should never fail
|
||||
//
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = Sep->OpenSectionStream (
|
||||
Sep,
|
||||
FileSize,
|
||||
FileBuffer,
|
||||
&FfsEntry->StreamHandle
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
FfsEntry->Sep = Sep;
|
||||
} else {
|
||||
//
|
||||
// Get cached copy of Sep
|
||||
//
|
||||
Sep = FfsEntry->Sep;
|
||||
}
|
||||
|
||||
//
|
||||
// If SectionType == 0 We need the whole section stream
|
||||
//
|
||||
Status = Sep->GetSection (
|
||||
Sep,
|
||||
FfsEntry->StreamHandle,
|
||||
(SectionType == 0) ? NULL : &SectionType,
|
||||
NULL,
|
||||
(SectionType == 0) ? 0 : SectionInstance,
|
||||
Buffer,
|
||||
BufferSize,
|
||||
AuthenticationStatus
|
||||
);
|
||||
|
||||
//
|
||||
// Close of stream defered to close of FfsHeader list to allow SEP to cache data
|
||||
//
|
||||
|
||||
Done:
|
||||
CoreFreePool (FileBuffer);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
60
MdeModulePkg/Core/Dxe/FwVol/FwVolWrite.c
Normal file
60
MdeModulePkg/Core/Dxe/FwVol/FwVolWrite.c
Normal file
@ -0,0 +1,60 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
FwVolWrite.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Implements write firmware file
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvWriteFile (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
IN UINT32 NumberOfFiles,
|
||||
IN EFI_FV_WRITE_POLICY WritePolicy,
|
||||
IN EFI_FV_WRITE_FILE_DATA *FileData
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Writes one or more files to the firmware volume.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
NumberOfFiles - Number of files.
|
||||
WritePolicy - WritePolicy indicates the level of reliability for
|
||||
the write in the event of a power failure or other
|
||||
system failure during the write operation.
|
||||
FileData - FileData is an pointer to an array of EFI_FV_WRITE_DATA.
|
||||
Each element of FileData[] represents a file to be written.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Files successfully written to firmware volume
|
||||
EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
|
||||
EFI_DEVICE_ERROR - Device error.
|
||||
EFI_WRITE_PROTECTED - Write protected.
|
||||
EFI_NOT_FOUND - Not found.
|
||||
EFI_INVALID_PARAMETER - Invalid parameter.
|
||||
EFI_UNSUPPORTED - This function not supported.
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
324
MdeModulePkg/Core/Dxe/FwVolBlock.h
Normal file
324
MdeModulePkg/Core/Dxe/FwVolBlock.h
Normal file
@ -0,0 +1,324 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
FwVolBlock.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Firmware Volume Block protocol.. Consumes FV hobs and creates
|
||||
appropriate block protocols.
|
||||
|
||||
Also consumes NT_NON_MM_FV envinronment variable and produces appropriate
|
||||
block protocols fro them also... (this is TBD)
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _FWVOL_BLOCK_H_
|
||||
#define _FWVOL_BLOCK_H_
|
||||
|
||||
|
||||
#define FVB_DEVICE_SIGNATURE EFI_SIGNATURE_32('_','F','V','B')
|
||||
|
||||
typedef struct {
|
||||
UINTN Base;
|
||||
UINTN Length;
|
||||
} LBA_CACHE;
|
||||
|
||||
typedef struct {
|
||||
MEMMAP_DEVICE_PATH MemMapDevPath;
|
||||
EFI_DEVICE_PATH_PROTOCOL EndDevPath;
|
||||
} FV_DEVICE_PATH;
|
||||
|
||||
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
EFI_HANDLE Handle;
|
||||
FV_DEVICE_PATH DevicePath;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance;
|
||||
UINTN NumBlocks;
|
||||
LBA_CACHE *LbaCache;
|
||||
UINT32 FvbAttributes;
|
||||
EFI_PHYSICAL_ADDRESS BaseAddress;
|
||||
} EFI_FW_VOL_BLOCK_DEVICE;
|
||||
|
||||
#define FVB_DEVICE_FROM_THIS(a) \
|
||||
CR(a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockDriverInit (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This routine is the driver initialization entry point. It initializes the
|
||||
libraries, consumes FV hobs and NT_NON_MM_FV environment variable and
|
||||
produces instances of FW_VOL_BLOCK_PROTOCOL as appropriate.
|
||||
Arguments:
|
||||
ImageHandle - The image handle.
|
||||
SystemTable - The system table.
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully initialized firmware volume block driver.
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockGetAttributes (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
OUT EFI_FVB_ATTRIBUTES *Attributes
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrieves Volume attributes. No polarity translations are done.
|
||||
|
||||
Arguments:
|
||||
This - Calling context
|
||||
Attributes - output buffer which contains attributes
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The firmware volume attributes were returned.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockSetAttributes (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
IN CONST EFI_FVB_ATTRIBUTES *Attributes
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Modifies the current settings of the firmware volume according to the input parameter.
|
||||
|
||||
Arguments:
|
||||
This - Calling context
|
||||
Attributes - input buffer which contains attributes
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The firmware volume attributes were returned.
|
||||
EFI_INVALID_PARAMETER - The attributes requested are in conflict with the capabilities as
|
||||
declared in the firmware volume header.
|
||||
EFI_UNSUPPORTED - Not supported.
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockEraseBlock (
|
||||
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
...
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
The EraseBlock() function erases one or more blocks as denoted by the
|
||||
variable argument list. The entire parameter list of blocks must be verified
|
||||
prior to erasing any blocks. If a block is requested that does not exist
|
||||
within the associated firmware volume (it has a larger index than the last
|
||||
block of the firmware volume), the EraseBlock() function must return
|
||||
EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.
|
||||
|
||||
Arguments:
|
||||
This - Calling context
|
||||
... - Starting LBA followed by Number of Lba to erase. a -1 to terminate
|
||||
the list.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The erase request was successfully completed.
|
||||
EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state.
|
||||
EFI_DEVICE_ERROR - The block device is not functioning correctly and could not be
|
||||
written. The firmware device may have been partially erased.
|
||||
EFI_INVALID_PARAMETER - One or more of the LBAs listed in the variable argument list do
|
||||
EFI_UNSUPPORTED - Not supported.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockReadBlock (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
IN CONST EFI_LBA Lba,
|
||||
IN CONST UINTN Offset,
|
||||
IN OUT UINTN *NumBytes,
|
||||
IN OUT UINT8 *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Read the specified number of bytes from the block to the input buffer.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
Lba - The starting logical block index to read.
|
||||
Offset - Offset into the block at which to begin reading.
|
||||
NumBytes - Pointer to a UINT32. At entry, *NumBytes contains the
|
||||
total size of the buffer. At exit, *NumBytes contains the
|
||||
total number of bytes actually read.
|
||||
Buffer - Pinter to a caller-allocated buffer that contains the destine
|
||||
for the read.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The firmware volume was read successfully.
|
||||
EFI_BAD_BUFFER_SIZE - The read was attempted across an LBA boundary.
|
||||
EFI_ACCESS_DENIED - Access denied.
|
||||
EFI_DEVICE_ERROR - The block device is malfunctioning and could not be read.
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockWriteBlock (
|
||||
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN Offset,
|
||||
IN OUT UINTN *NumBytes,
|
||||
IN UINT8 *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Writes the specified number of bytes from the input buffer to the block.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
Lba - The starting logical block index to write to.
|
||||
Offset - Offset into the block at which to begin writing.
|
||||
NumBytes - Pointer to a UINT32. At entry, *NumBytes contains the
|
||||
total size of the buffer. At exit, *NumBytes contains the
|
||||
total number of bytes actually written.
|
||||
Buffer - Pinter to a caller-allocated buffer that contains the source
|
||||
for the write.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The firmware volume was written successfully.
|
||||
EFI_BAD_BUFFER_SIZE - The write was attempted across an LBA boundary. On output,
|
||||
NumBytes contains the total number of bytes actually written.
|
||||
EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state.
|
||||
EFI_DEVICE_ERROR - The block device is malfunctioning and could not be written.
|
||||
EFI_UNSUPPORTED - Not supported.
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockGetPhysicalAddress (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
OUT EFI_PHYSICAL_ADDRESS *Address
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Get Fvb's base address.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
Address - Fvb device base address.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully got Fvb's base address.
|
||||
EFI_UNSUPPORTED - Not supported.
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockGetBlockSize (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
IN CONST EFI_LBA Lba,
|
||||
OUT UINTN *BlockSize,
|
||||
OUT UINTN *NumberOfBlocks
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrieves the size in bytes of a specific block within a firmware volume.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
Lba - Indicates the block for which to return the size.
|
||||
BlockSize - Pointer to a caller-allocated UINTN in which the size of the
|
||||
block is returned.
|
||||
NumberOfBlocks - Pointer to a caller-allocated UINTN in which the number of
|
||||
consecutive blocks starting with Lba is returned. All blocks
|
||||
in this range have a size of BlockSize.
|
||||
Returns:
|
||||
EFI_SUCCESS - The firmware volume base address is returned.
|
||||
EFI_INVALID_PARAMETER - The requested LBA is out of range.
|
||||
--*/
|
||||
;
|
||||
EFI_STATUS
|
||||
FwVolBlockDriverInit (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This routine is the driver initialization entry point. It initializes the
|
||||
libraries, consumes FV hobs and NT_NON_MM_FV environment variable and
|
||||
produces instances of FW_VOL_BLOCK_PROTOCOL as appropriate.
|
||||
Arguments:
|
||||
ImageHandle - The image handle.
|
||||
SystemTable - The system table.
|
||||
Returns:
|
||||
Status code
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
ProduceFVBProtocolOnBuffer (
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN EFI_HANDLE ParentHandle,
|
||||
OUT EFI_HANDLE *FvProtocolHandle OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This routine produces a firmware volume block protocol on a given
|
||||
buffer.
|
||||
|
||||
Arguments:
|
||||
BaseAddress - base address of the firmware volume image
|
||||
Length - length of the firmware volume image
|
||||
ParentHandle - handle of parent firmware volume, if this
|
||||
image came from an FV image file in another
|
||||
firmware volume (ala capsules)
|
||||
FvProtocolHandle - Firmware volume block protocol produced.
|
||||
|
||||
Returns:
|
||||
EFI_VOLUME_CORRUPTED - Volume corrupted.
|
||||
EFI_OUT_OF_RESOURCES - No enough buffer to be allocated.
|
||||
EFI_SUCCESS - Successfully produced a FVB protocol on given buffer.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
#endif
|
598
MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c
Normal file
598
MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c
Normal file
@ -0,0 +1,598 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
FwVolBlock.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Firmware Volume Block protocol.. Consumes FV hobs and creates
|
||||
appropriate block protocols.
|
||||
|
||||
Also consumes NT_NON_MM_FV envinronment variable and produces appropriate
|
||||
block protocols fro them also... (this is TBD)
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
|
||||
EFI_FW_VOL_BLOCK_DEVICE mFwVolBlock = {
|
||||
FVB_DEVICE_SIGNATURE,
|
||||
NULL,
|
||||
{
|
||||
{
|
||||
{
|
||||
HARDWARE_DEVICE_PATH,
|
||||
HW_MEMMAP_DP,
|
||||
{ (UINT8)(sizeof (MEMMAP_DEVICE_PATH)), (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8) }
|
||||
},
|
||||
EfiMemoryMappedIO,
|
||||
(EFI_PHYSICAL_ADDRESS)0,
|
||||
(EFI_PHYSICAL_ADDRESS)0,
|
||||
},
|
||||
{
|
||||
END_DEVICE_PATH_TYPE,
|
||||
END_ENTIRE_DEVICE_PATH_SUBTYPE,
|
||||
{ END_DEVICE_PATH_LENGTH, 0 }
|
||||
},
|
||||
},
|
||||
{
|
||||
FwVolBlockGetAttributes,
|
||||
(EFI_FVB_SET_ATTRIBUTES)FwVolBlockSetAttributes,
|
||||
FwVolBlockGetPhysicalAddress,
|
||||
FwVolBlockGetBlockSize,
|
||||
FwVolBlockReadBlock,
|
||||
(EFI_FVB_WRITE)FwVolBlockWriteBlock,
|
||||
(EFI_FVB_ERASE_BLOCKS)FwVolBlockEraseBlock,
|
||||
NULL
|
||||
},
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockGetAttributes (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
OUT EFI_FVB_ATTRIBUTES *Attributes
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrieves Volume attributes. No polarity translations are done.
|
||||
|
||||
Arguments:
|
||||
This - Calling context
|
||||
Attributes - output buffer which contains attributes
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The firmware volume attributes were returned.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
|
||||
|
||||
FvbDevice = FVB_DEVICE_FROM_THIS (This);
|
||||
|
||||
//
|
||||
// Since we are read only, it's safe to get attributes data from our in-memory copy.
|
||||
//
|
||||
*Attributes = FvbDevice->FvbAttributes;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockSetAttributes (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
IN CONST EFI_FVB_ATTRIBUTES *Attributes
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Modifies the current settings of the firmware volume according to the input parameter.
|
||||
|
||||
Arguments:
|
||||
This - Calling context
|
||||
Attributes - input buffer which contains attributes
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The firmware volume attributes were returned.
|
||||
EFI_INVALID_PARAMETER - The attributes requested are in conflict with the capabilities as
|
||||
declared in the firmware volume header.
|
||||
EFI_UNSUPPORTED - Not supported.
|
||||
--*/
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockEraseBlock (
|
||||
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
...
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
The EraseBlock() function erases one or more blocks as denoted by the
|
||||
variable argument list. The entire parameter list of blocks must be verified
|
||||
prior to erasing any blocks. If a block is requested that does not exist
|
||||
within the associated firmware volume (it has a larger index than the last
|
||||
block of the firmware volume), the EraseBlock() function must return
|
||||
EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.
|
||||
|
||||
Arguments:
|
||||
This - Calling context
|
||||
... - Starting LBA followed by Number of Lba to erase. a -1 to terminate
|
||||
the list.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The erase request was successfully completed.
|
||||
EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state.
|
||||
EFI_DEVICE_ERROR - The block device is not functioning correctly and could not be
|
||||
written. The firmware device may have been partially erased.
|
||||
EFI_INVALID_PARAMETER - One or more of the LBAs listed in the variable argument list do
|
||||
EFI_UNSUPPORTED - Not supported.
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockReadBlock (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
IN CONST EFI_LBA Lba,
|
||||
IN CONST UINTN Offset,
|
||||
IN OUT UINTN *NumBytes,
|
||||
IN OUT UINT8 *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Read the specified number of bytes from the block to the input buffer.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
Lba - The starting logical block index to read.
|
||||
Offset - Offset into the block at which to begin reading.
|
||||
NumBytes - Pointer to a UINT32. At entry, *NumBytes contains the
|
||||
total size of the buffer. At exit, *NumBytes contains the
|
||||
total number of bytes actually read.
|
||||
Buffer - Pinter to a caller-allocated buffer that contains the destine
|
||||
for the read.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The firmware volume was read successfully.
|
||||
EFI_BAD_BUFFER_SIZE - The read was attempted across an LBA boundary.
|
||||
EFI_ACCESS_DENIED - Access denied.
|
||||
EFI_DEVICE_ERROR - The block device is malfunctioning and could not be read.
|
||||
--*/
|
||||
{
|
||||
EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
UINT8 *LbaOffset;
|
||||
UINTN LbaStart;
|
||||
UINTN NumOfBytesRead;
|
||||
UINTN LbaIndex;
|
||||
|
||||
FvbDevice = FVB_DEVICE_FROM_THIS (This);
|
||||
|
||||
//
|
||||
// Check if This FW can be read
|
||||
//
|
||||
if ((FvbDevice->FvbAttributes & EFI_FVB_READ_STATUS) == 0) {
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
LbaIndex = (UINTN)Lba;
|
||||
if (LbaIndex >= FvbDevice->NumBlocks) {
|
||||
//
|
||||
// Invalid Lba, read nothing.
|
||||
//
|
||||
*NumBytes = 0;
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
if (Offset > FvbDevice->LbaCache[LbaIndex].Length) {
|
||||
//
|
||||
// all exceed boundry, read nothing.
|
||||
//
|
||||
*NumBytes = 0;
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
NumOfBytesRead = *NumBytes;
|
||||
if (Offset + NumOfBytesRead > FvbDevice->LbaCache[LbaIndex].Length) {
|
||||
//
|
||||
// partial exceed boundry, read data from current postion to end.
|
||||
//
|
||||
NumOfBytesRead = FvbDevice->LbaCache[LbaIndex].Length - Offset;
|
||||
}
|
||||
|
||||
LbaStart = FvbDevice->LbaCache[LbaIndex].Base;
|
||||
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvbDevice->BaseAddress);
|
||||
LbaOffset = (UINT8 *)FwVolHeader + LbaStart + Offset;
|
||||
|
||||
//
|
||||
// Perform read operation
|
||||
//
|
||||
CopyMem (Buffer, LbaOffset, NumOfBytesRead);
|
||||
|
||||
if (NumOfBytesRead == *NumBytes) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
*NumBytes = NumOfBytesRead;
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockWriteBlock (
|
||||
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN Offset,
|
||||
IN OUT UINTN *NumBytes,
|
||||
IN UINT8 *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Writes the specified number of bytes from the input buffer to the block.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
Lba - The starting logical block index to write to.
|
||||
Offset - Offset into the block at which to begin writing.
|
||||
NumBytes - Pointer to a UINT32. At entry, *NumBytes contains the
|
||||
total size of the buffer. At exit, *NumBytes contains the
|
||||
total number of bytes actually written.
|
||||
Buffer - Pinter to a caller-allocated buffer that contains the source
|
||||
for the write.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The firmware volume was written successfully.
|
||||
EFI_BAD_BUFFER_SIZE - The write was attempted across an LBA boundary. On output,
|
||||
NumBytes contains the total number of bytes actually written.
|
||||
EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state.
|
||||
EFI_DEVICE_ERROR - The block device is malfunctioning and could not be written.
|
||||
EFI_UNSUPPORTED - Not supported.
|
||||
--*/
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockGetPhysicalAddress (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
OUT EFI_PHYSICAL_ADDRESS *Address
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Get Fvb's base address.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
Address - Fvb device base address.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully got Fvb's base address.
|
||||
EFI_UNSUPPORTED - Not supported.
|
||||
--*/
|
||||
{
|
||||
EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
|
||||
|
||||
FvbDevice = FVB_DEVICE_FROM_THIS (This);
|
||||
|
||||
if (FvbDevice->FvbAttributes & EFI_FVB_MEMORY_MAPPED) {
|
||||
*Address = FvbDevice->BaseAddress;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockGetBlockSize (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
IN CONST EFI_LBA Lba,
|
||||
IN OUT UINTN *BlockSize,
|
||||
IN OUT UINTN *NumberOfBlocks
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrieves the size in bytes of a specific block within a firmware volume.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
Lba - Indicates the block for which to return the size.
|
||||
BlockSize - Pointer to a caller-allocated UINTN in which the size of the
|
||||
block is returned.
|
||||
NumberOfBlocks - Pointer to a caller-allocated UINTN in which the number of
|
||||
consecutive blocks starting with Lba is returned. All blocks
|
||||
in this range have a size of BlockSize.
|
||||
Returns:
|
||||
EFI_SUCCESS - The firmware volume base address is returned.
|
||||
EFI_INVALID_PARAMETER - The requested LBA is out of range.
|
||||
--*/
|
||||
{
|
||||
UINTN TotalBlocks;
|
||||
EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
|
||||
EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
|
||||
FvbDevice = FVB_DEVICE_FROM_THIS (This);
|
||||
|
||||
//
|
||||
// Do parameter checking
|
||||
//
|
||||
if (Lba >= FvbDevice->NumBlocks) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvbDevice->BaseAddress);
|
||||
|
||||
PtrBlockMapEntry = FwVolHeader->BlockMap;
|
||||
|
||||
//
|
||||
// Search the block map for the given block
|
||||
//
|
||||
TotalBlocks = 0;
|
||||
while ((PtrBlockMapEntry->NumBlocks != 0) || (PtrBlockMapEntry->Length !=0 )) {
|
||||
TotalBlocks += PtrBlockMapEntry->NumBlocks;
|
||||
if (Lba < TotalBlocks) {
|
||||
//
|
||||
// We find the range
|
||||
//
|
||||
break;
|
||||
}
|
||||
|
||||
PtrBlockMapEntry++;
|
||||
}
|
||||
|
||||
*BlockSize = PtrBlockMapEntry->Length;
|
||||
*NumberOfBlocks = TotalBlocks - (UINTN)Lba;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
ProduceFVBProtocolOnBuffer (
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN EFI_HANDLE ParentHandle,
|
||||
OUT EFI_HANDLE *FvProtocol OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This routine produces a firmware volume block protocol on a given
|
||||
buffer.
|
||||
|
||||
Arguments:
|
||||
BaseAddress - base address of the firmware volume image
|
||||
Length - length of the firmware volume image
|
||||
ParentHandle - handle of parent firmware volume, if this
|
||||
image came from an FV image file in another
|
||||
firmware volume (ala capsules)
|
||||
FvProtocol - Firmware volume block protocol produced.
|
||||
|
||||
Returns:
|
||||
EFI_VOLUME_CORRUPTED - Volume corrupted.
|
||||
EFI_OUT_OF_RESOURCES - No enough buffer to be allocated.
|
||||
EFI_SUCCESS - Successfully produced a FVB protocol on given buffer.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FW_VOL_BLOCK_DEVICE *FvbDev;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
UINTN BlockIndex;
|
||||
UINTN BlockIndex2;
|
||||
UINTN LinearOffset;
|
||||
EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;
|
||||
|
||||
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)BaseAddress;
|
||||
//
|
||||
// Validate FV Header, if not as expected, return
|
||||
//
|
||||
if (FwVolHeader->Signature != EFI_FVH_SIGNATURE) {
|
||||
return EFI_VOLUME_CORRUPTED;
|
||||
}
|
||||
//
|
||||
// Allocate EFI_FW_VOL_BLOCK_DEVICE
|
||||
//
|
||||
FvbDev = CoreAllocateCopyPool (sizeof (EFI_FW_VOL_BLOCK_DEVICE), &mFwVolBlock);
|
||||
if (FvbDev == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
FvbDev->BaseAddress = BaseAddress;
|
||||
FvbDev->FvbAttributes = FwVolHeader->Attributes;
|
||||
FvbDev->FwVolBlockInstance.ParentHandle = ParentHandle;
|
||||
|
||||
//
|
||||
// Init the block caching fields of the device
|
||||
// First, count the number of blocks
|
||||
//
|
||||
FvbDev->NumBlocks = 0;
|
||||
for (PtrBlockMapEntry = FwVolHeader->BlockMap;
|
||||
PtrBlockMapEntry->NumBlocks != 0;
|
||||
PtrBlockMapEntry++) {
|
||||
FvbDev->NumBlocks += PtrBlockMapEntry->NumBlocks;
|
||||
}
|
||||
//
|
||||
// Second, allocate the cache
|
||||
//
|
||||
FvbDev->LbaCache = CoreAllocateBootServicesPool (FvbDev->NumBlocks * sizeof (LBA_CACHE));
|
||||
if (FvbDev->LbaCache == NULL) {
|
||||
CoreFreePool (FvbDev);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
//
|
||||
// Last, fill in the cache with the linear address of the blocks
|
||||
//
|
||||
BlockIndex = 0;
|
||||
LinearOffset = 0;
|
||||
for (PtrBlockMapEntry = FwVolHeader->BlockMap;
|
||||
PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {
|
||||
for (BlockIndex2 = 0; BlockIndex2 < PtrBlockMapEntry->NumBlocks; BlockIndex2++) {
|
||||
FvbDev->LbaCache[BlockIndex].Base = LinearOffset;
|
||||
FvbDev->LbaCache[BlockIndex].Length = PtrBlockMapEntry->Length;
|
||||
LinearOffset += PtrBlockMapEntry->Length;
|
||||
BlockIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Set up the devicepath
|
||||
//
|
||||
FvbDev->DevicePath.MemMapDevPath.StartingAddress = BaseAddress;
|
||||
FvbDev->DevicePath.MemMapDevPath.EndingAddress = BaseAddress + FwVolHeader->FvLength - 1;
|
||||
|
||||
//
|
||||
//
|
||||
// Attach FvVolBlock Protocol to new handle
|
||||
//
|
||||
Status = CoreInstallMultipleProtocolInterfaces (
|
||||
&FvbDev->Handle,
|
||||
&gEfiFirmwareVolumeBlockProtocolGuid, &FvbDev->FwVolBlockInstance,
|
||||
&gEfiDevicePathProtocolGuid, &FvbDev->DevicePath,
|
||||
&gEfiFirmwareVolumeDispatchProtocolGuid, NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
//
|
||||
// If they want the handle back, set it.
|
||||
//
|
||||
if (FvProtocol != NULL) {
|
||||
*FvProtocol = FvbDev->Handle;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FwVolBlockDriverInit (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This routine is the driver initialization entry point. It initializes the
|
||||
libraries, consumes FV hobs and NT_NON_MM_FV environment variable and
|
||||
produces instances of FW_VOL_BLOCK_PROTOCOL as appropriate.
|
||||
Arguments:
|
||||
ImageHandle - The image handle.
|
||||
SystemTable - The system table.
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully initialized firmware volume block driver.
|
||||
--*/
|
||||
{
|
||||
EFI_PEI_HOB_POINTERS FvHob;
|
||||
//
|
||||
// Core Needs Firmware Volumes to function
|
||||
//
|
||||
FvHob.Raw = GetHobList ();
|
||||
while ((FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw)) != NULL) {
|
||||
//
|
||||
// Produce an FVB protocol for it
|
||||
//
|
||||
ProduceFVBProtocolOnBuffer (FvHob.FirmwareVolume->BaseAddress, FvHob.FirmwareVolume->Length, NULL, NULL);
|
||||
FvHob.Raw = GET_NEXT_HOB (FvHob);
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
CoreProcessFirmwareVolume (
|
||||
IN VOID *FvHeader,
|
||||
IN UINTN Size,
|
||||
OUT EFI_HANDLE *FVProtocolHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This DXE service routine is used to process a firmware volume. In
|
||||
particular, it can be called by BDS to process a single firmware
|
||||
volume found in a capsule.
|
||||
|
||||
Arguments:
|
||||
FvHeader - pointer to a firmware volume header
|
||||
Size - the size of the buffer pointed to by FvHeader
|
||||
FVProtocolHandle - the handle on which a firmware volume protocol
|
||||
was produced for the firmware volume passed in.
|
||||
|
||||
Returns:
|
||||
EFI_OUT_OF_RESOURCES - if an FVB could not be produced due to lack of
|
||||
system resources
|
||||
EFI_VOLUME_CORRUPTED - if the volume was corrupted
|
||||
EFI_SUCCESS - a firmware volume protocol was produced for the
|
||||
firmware volume
|
||||
|
||||
--*/
|
||||
{
|
||||
VOID *Ptr;
|
||||
EFI_STATUS Status;
|
||||
|
||||
*FVProtocolHandle = NULL;
|
||||
Status = ProduceFVBProtocolOnBuffer (
|
||||
(EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,
|
||||
(UINT64)Size,
|
||||
NULL,
|
||||
FVProtocolHandle
|
||||
);
|
||||
//
|
||||
// Since in our implementation we use register-protocol-notify to put a
|
||||
// FV protocol on the FVB protocol handle, we can't directly verify that
|
||||
// the FV protocol was produced. Therefore here we will check the handle
|
||||
// and make sure an FV protocol is on it. This indicates that all went
|
||||
// well. Otherwise we have to assume that the volume was corrupted
|
||||
// somehow.
|
||||
//
|
||||
if (!EFI_ERROR(Status)) {
|
||||
Ptr = NULL;
|
||||
Status = CoreHandleProtocol (*FVProtocolHandle, &gEfiFirmwareVolumeProtocolGuid, (VOID **)&Ptr);
|
||||
if (EFI_ERROR(Status) || (Ptr == NULL)) {
|
||||
return EFI_VOLUME_CORRUPTED;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
466
MdeModulePkg/Core/Dxe/FwVolDriver.h
Normal file
466
MdeModulePkg/Core/Dxe/FwVolDriver.h
Normal file
@ -0,0 +1,466 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
FwVolDriver.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Firmware File System protocol. Layers on top of Firmware
|
||||
Block protocol to produce a file abstraction of FV based files.
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef __FWVOL_H
|
||||
#define __FWVOL_H
|
||||
|
||||
|
||||
//
|
||||
// Used to track all non-deleted files
|
||||
//
|
||||
typedef struct {
|
||||
LIST_ENTRY Link;
|
||||
EFI_FFS_FILE_HEADER *FfsHeader;
|
||||
UINTN StreamHandle;
|
||||
EFI_SECTION_EXTRACTION_PROTOCOL *Sep;
|
||||
} FFS_FILE_LIST_ENTRY;
|
||||
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_FIRMWARE_VOLUME_PROTOCOL Fv;
|
||||
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
UINT8 *CachedFv;
|
||||
UINT8 *EndOfCachedFv;
|
||||
|
||||
FFS_FILE_LIST_ENTRY *LastKey;
|
||||
|
||||
LIST_ENTRY FfsFileListHeader;
|
||||
|
||||
UINT8 ErasePolarity;
|
||||
} FV_DEVICE;
|
||||
|
||||
#define FV_DEVICE_FROM_THIS(a) CR(a, FV_DEVICE, Fv, FV_DEVICE_SIGNATURE)
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvGetVolumeAttributes (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
OUT EFI_FV_ATTRIBUTES *Attributes
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrieves attributes, insures positive polarity of attribute bits, returns
|
||||
resulting attributes in output parameter
|
||||
|
||||
Arguments:
|
||||
This - Calling context
|
||||
Attributes - output buffer which contains attributes
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully got volume attributes
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvSetVolumeAttributes (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
IN OUT EFI_FV_ATTRIBUTES *Attributes
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Sets current attributes for volume
|
||||
|
||||
Arguments:
|
||||
This - Calling context
|
||||
Attributes - At input, contains attributes to be set. At output contains
|
||||
new value of FV
|
||||
|
||||
Returns:
|
||||
EFI_UNSUPPORTED - Could not be set.
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvGetNextFile (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
IN OUT VOID *Key,
|
||||
IN OUT EFI_FV_FILETYPE *FileType,
|
||||
OUT EFI_GUID *NameGuid,
|
||||
OUT EFI_FV_FILE_ATTRIBUTES *Attributes,
|
||||
OUT UINTN *Size
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Given the input key, search for the next matching file in the volume.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
FileType - FileType is a pointer to a caller allocated
|
||||
EFI_FV_FILETYPE. The GetNextFile() API can filter it's
|
||||
search for files based on the value of *FileType input.
|
||||
A *FileType input of 0 causes GetNextFile() to search for
|
||||
files of all types. If a file is found, the file's type
|
||||
is returned in *FileType. *FileType is not modified if
|
||||
no file is found.
|
||||
Key - Key is a pointer to a caller allocated buffer that
|
||||
contains implementation specific data that is used to
|
||||
track where to begin the search for the next file.
|
||||
The size of the buffer must be at least This->KeySize
|
||||
bytes long. To reinitialize the search and begin from
|
||||
the beginning of the firmware volume, the entire buffer
|
||||
must be cleared to zero. Other than clearing the buffer
|
||||
to initiate a new search, the caller must not modify the
|
||||
data in the buffer between calls to GetNextFile().
|
||||
NameGuid - NameGuid is a pointer to a caller allocated EFI_GUID.
|
||||
If a file is found, the file's name is returned in
|
||||
*NameGuid. *NameGuid is not modified if no file is
|
||||
found.
|
||||
Attributes - Attributes is a pointer to a caller allocated
|
||||
EFI_FV_FILE_ATTRIBUTES. If a file is found, the file's
|
||||
attributes are returned in *Attributes. *Attributes is
|
||||
not modified if no file is found.
|
||||
Size - Size is a pointer to a caller allocated UINTN.
|
||||
If a file is found, the file's size is returned in *Size.
|
||||
*Size is not modified if no file is found.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully find the file.
|
||||
EFI_DEVICE_ERROR - Device error.
|
||||
EFI_ACCESS_DENIED - Fv could not read.
|
||||
EFI_NOT_FOUND - No matching file found.
|
||||
EFI_INVALID_PARAMETER - Invalid parameter
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvReadFile (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
IN EFI_GUID *NameGuid,
|
||||
IN OUT VOID **Buffer,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT EFI_FV_FILETYPE *FoundType,
|
||||
OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,
|
||||
OUT UINT32 *AuthenticationStatus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Locates a file in the firmware volume and
|
||||
copies it to the supplied buffer.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
NameGuid - Pointer to an EFI_GUID, which is the filename.
|
||||
Buffer - Buffer is a pointer to pointer to a buffer in
|
||||
which the file or section contents or are returned.
|
||||
BufferSize - BufferSize is a pointer to caller allocated
|
||||
UINTN. On input *BufferSize indicates the size
|
||||
in bytes of the memory region pointed to by
|
||||
Buffer. On output, *BufferSize contains the number
|
||||
of bytes required to read the file.
|
||||
FoundType - FoundType is a pointer to a caller allocated
|
||||
EFI_FV_FILETYPE that on successful return from Read()
|
||||
contains the type of file read. This output reflects
|
||||
the file type irrespective of the value of the
|
||||
SectionType input.
|
||||
FileAttributes - FileAttributes is a pointer to a caller allocated
|
||||
EFI_FV_FILE_ATTRIBUTES. On successful return from
|
||||
Read(), *FileAttributes contains the attributes of
|
||||
the file read.
|
||||
AuthenticationStatus - AuthenticationStatus is a pointer to a caller
|
||||
allocated UINTN in which the authentication status
|
||||
is returned.
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully read to memory buffer.
|
||||
EFI_WARN_BUFFER_TOO_SMALL - Buffer too small.
|
||||
EFI_NOT_FOUND - Not found.
|
||||
EFI_DEVICE_ERROR - Device error.
|
||||
EFI_ACCESS_DENIED - Could not read.
|
||||
EFI_INVALID_PARAMETER - Invalid parameter.
|
||||
EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvReadFileSection (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
IN EFI_GUID *NameGuid,
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN UINTN SectionInstance,
|
||||
IN OUT VOID **Buffer,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT UINT32 *AuthenticationStatus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Locates a section in a given FFS File and
|
||||
copies it to the supplied buffer (not including section header).
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
NameGuid - Pointer to an EFI_GUID, which is the filename.
|
||||
SectionType - Indicates the section type to return.
|
||||
SectionInstance - Indicates which instance of sections with a type of
|
||||
SectionType to return.
|
||||
Buffer - Buffer is a pointer to pointer to a buffer in which
|
||||
the file or section contents or are returned.
|
||||
BufferSize - BufferSize is a pointer to caller allocated UINTN.
|
||||
AuthenticationStatus -AuthenticationStatus is a pointer to a caller
|
||||
allocated UINT32 in which the authentication status
|
||||
is returned.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Successfully read the file section into buffer.
|
||||
EFI_WARN_BUFFER_TOO_SMALL - Buffer too small.
|
||||
EFI_NOT_FOUND - Section not found.
|
||||
EFI_DEVICE_ERROR - Device error.
|
||||
EFI_ACCESS_DENIED - Could not read.
|
||||
EFI_INVALID_PARAMETER - Invalid parameter.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvWriteFile (
|
||||
IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
|
||||
IN UINT32 NumberOfFiles,
|
||||
IN EFI_FV_WRITE_POLICY WritePolicy,
|
||||
IN EFI_FV_WRITE_FILE_DATA *FileData
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Writes one or more files to the firmware volume.
|
||||
|
||||
Arguments:
|
||||
This - Indicates the calling context.
|
||||
WritePolicy - WritePolicy indicates the level of reliability for
|
||||
the write in the event of a power failure or other
|
||||
system failure during the write operation.
|
||||
FileData - FileData is an pointer to an array of EFI_FV_WRITE_DATA.
|
||||
Each element of FileData[] represents a file to be written.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - Files successfully written to firmware volume
|
||||
EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
|
||||
EFI_DEVICE_ERROR - Device error.
|
||||
EFI_WRITE_PROTECTED - Write protected.
|
||||
EFI_NOT_FOUND - Not found.
|
||||
EFI_INVALID_PARAMETER - Invalid parameter.
|
||||
EFI_UNSUPPORTED - This function not supported.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
|
||||
//
|
||||
//Internal functions
|
||||
//
|
||||
typedef enum {
|
||||
EfiCheckSumUint8 = 0,
|
||||
EfiCheckSumUint16 = 1,
|
||||
EfiCheckSumUint32 = 2,
|
||||
EfiCheckSumUint64 = 3,
|
||||
EfiCheckSumMaximum = 4
|
||||
} EFI_CHECKSUM_TYPE;
|
||||
|
||||
|
||||
BOOLEAN
|
||||
IsBufferErased (
|
||||
IN UINT8 ErasePolarity,
|
||||
IN VOID *Buffer,
|
||||
IN UINTN BufferSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Check if a block of buffer is erased
|
||||
|
||||
Arguments:
|
||||
ErasePolarity - Erase polarity attribute of the firmware volume
|
||||
Buffer - The buffer to be checked
|
||||
BufferSize - Size of the buffer in bytes
|
||||
|
||||
Returns:
|
||||
TRUE - The block of buffer is erased
|
||||
FALSE - The block of buffer is not erased
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_FFS_FILE_STATE
|
||||
GetFileState (
|
||||
IN UINT8 ErasePolarity,
|
||||
IN EFI_FFS_FILE_HEADER *FfsHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Get the FFS file state by checking the highest bit set in the header's state field
|
||||
|
||||
Arguments:
|
||||
ErasePolarity - Erase polarity attribute of the firmware volume
|
||||
FfsHeader - Points to the FFS file header
|
||||
|
||||
Returns:
|
||||
FFS File state
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
SetFileState (
|
||||
IN UINT8 State,
|
||||
IN EFI_FFS_FILE_HEADER *FfsHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Set the FFS file state.
|
||||
|
||||
Arguments:
|
||||
State - The state to be set.
|
||||
FfsHeader - Points to the FFS file header
|
||||
|
||||
Returns:
|
||||
None.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
BOOLEAN
|
||||
VerifyFvHeaderChecksum (
|
||||
IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Verify checksum of the firmware volume header
|
||||
|
||||
Arguments:
|
||||
FvHeader - Points to the firmware volume header to be checked
|
||||
|
||||
Returns:
|
||||
TRUE - Checksum verification passed
|
||||
FALSE - Checksum verification failed
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
BOOLEAN
|
||||
IsValidFfsHeader (
|
||||
IN UINT8 ErasePolarity,
|
||||
IN EFI_FFS_FILE_HEADER *FfsHeader,
|
||||
OUT EFI_FFS_FILE_STATE *FileState
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Check if it's a valid FFS file header
|
||||
|
||||
Arguments:
|
||||
ErasePolarity - Erase polarity attribute of the firmware volume
|
||||
FfsHeader - Points to the FFS file header to be checked
|
||||
FileState - FFS file state to be returned
|
||||
|
||||
Returns:
|
||||
TRUE - Valid FFS file header
|
||||
FALSE - Invalid FFS file header
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
BOOLEAN
|
||||
IsValidFfsFile (
|
||||
IN UINT8 ErasePolarity,
|
||||
IN EFI_FFS_FILE_HEADER *FfsHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Check if it's a valid FFS file.
|
||||
Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first.
|
||||
|
||||
Arguments:
|
||||
ErasePolarity - Erase polarity attribute of the firmware volume
|
||||
FfsHeader - Points to the FFS file to be checked
|
||||
|
||||
Returns:
|
||||
TRUE - Valid FFS file
|
||||
FALSE - Invalid FFS file
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
GetFwVolHeader (
|
||||
IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb,
|
||||
OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
given the supplied FW_VOL_BLOCK_PROTOCOL, allocate a buffer for output and
|
||||
copy the volume header into it.
|
||||
|
||||
Arguments:
|
||||
Fvb - The FW_VOL_BLOCK_PROTOCOL instance from which to read the volume
|
||||
header
|
||||
FwVolHeader - Pointer to pointer to allocated buffer in which the volume
|
||||
header is returned.
|
||||
|
||||
Returns:
|
||||
Status code.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
FvCheck (
|
||||
IN OUT FV_DEVICE *FvDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Check if a FV is consistent and allocate cache
|
||||
|
||||
Arguments:
|
||||
FvDevice - pointer to the FvDevice to be checked.
|
||||
|
||||
Returns:
|
||||
EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
|
||||
EFI_SUCCESS - FV is consistent and cache is allocated.
|
||||
EFI_VOLUME_CORRUPTED - File system is corrupted.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
#endif
|
2495
MdeModulePkg/Core/Dxe/Gcd/gcd.c
Normal file
2495
MdeModulePkg/Core/Dxe/Gcd/gcd.c
Normal file
File diff suppressed because it is too large
Load Diff
845
MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
Normal file
845
MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
Normal file
@ -0,0 +1,845 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
DriverSupport.c
|
||||
|
||||
Abstract:
|
||||
|
||||
EFI Driver Support Protocol
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
GetHandleFromDriverBinding (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *DriverBindingNeed,
|
||||
OUT EFI_HANDLE *Handle
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// Driver Support Function Prototypes
|
||||
//
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
CoreConnectSingleController (
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE *DriverImageHandle OPTIONAL,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// Driver Support Functions
|
||||
//
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreConnectController (
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE *DriverImageHandle OPTIONAL,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
|
||||
IN BOOLEAN Recursive
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Connects one or more drivers to a controller.
|
||||
|
||||
Arguments:
|
||||
|
||||
ControllerHandle - Handle of the controller to be connected.
|
||||
|
||||
DriverImageHandle - DriverImageHandle A pointer to an ordered list of driver image handles.
|
||||
|
||||
RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child of the
|
||||
controller specified by ControllerHandle.
|
||||
|
||||
Recursive - Whether the function would be called recursively or not.
|
||||
|
||||
Returns:
|
||||
|
||||
Status code.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS ReturnStatus;
|
||||
IHANDLE *Handle;
|
||||
PROTOCOL_INTERFACE *Prot;
|
||||
LIST_ENTRY *Link;
|
||||
LIST_ENTRY *ProtLink;
|
||||
OPEN_PROTOCOL_DATA *OpenData;
|
||||
EFI_DEVICE_PATH_PROTOCOL *AlignedRemainingDevicePath;
|
||||
|
||||
//
|
||||
// Make sure ControllerHandle is valid
|
||||
//
|
||||
Status = CoreValidateHandle (ControllerHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Handle = ControllerHandle;
|
||||
|
||||
//
|
||||
// Connect all drivers to ControllerHandle
|
||||
//
|
||||
AlignedRemainingDevicePath = NULL;
|
||||
if (RemainingDevicePath != NULL) {
|
||||
AlignedRemainingDevicePath = CoreDuplicateDevicePath (RemainingDevicePath);
|
||||
}
|
||||
ReturnStatus = CoreConnectSingleController (
|
||||
ControllerHandle,
|
||||
DriverImageHandle,
|
||||
AlignedRemainingDevicePath
|
||||
);
|
||||
if (AlignedRemainingDevicePath != NULL) {
|
||||
CoreFreePool (AlignedRemainingDevicePath);
|
||||
}
|
||||
|
||||
//
|
||||
// If not recursive, then just return after connecting drivers to ControllerHandle
|
||||
//
|
||||
if (!Recursive) {
|
||||
return ReturnStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// If recursive, then connect all drivers to all of ControllerHandle's children
|
||||
//
|
||||
CoreAcquireProtocolLock ();
|
||||
for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
|
||||
Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
|
||||
for (ProtLink = Prot->OpenList.ForwardLink;
|
||||
ProtLink != &Prot->OpenList;
|
||||
ProtLink = ProtLink->ForwardLink) {
|
||||
OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
|
||||
if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
|
||||
CoreReleaseProtocolLock ();
|
||||
Status = CoreConnectController (
|
||||
OpenData->ControllerHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE
|
||||
);
|
||||
CoreAcquireProtocolLock ();
|
||||
}
|
||||
}
|
||||
}
|
||||
CoreReleaseProtocolLock ();
|
||||
|
||||
return ReturnStatus;
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
AddSortedDriverBindingProtocol (
|
||||
IN EFI_HANDLE DriverBindingHandle,
|
||||
IN OUT UINTN *NumberOfSortedDriverBindingProtocols,
|
||||
IN OUT EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols,
|
||||
IN UINTN DriverBindingHandleCount,
|
||||
IN OUT EFI_HANDLE *DriverBindingHandleBuffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Add Driver Binding Protocols from Context Driver Image Handles to sorted
|
||||
Driver Binding Protocol list.
|
||||
|
||||
Arguments:
|
||||
|
||||
DriverBindingHandle - Handle of the driver binding protocol.
|
||||
|
||||
NumberOfSortedDriverBindingProtocols - Number Of sorted driver binding protocols
|
||||
|
||||
SortedDriverBindingProtocols - The sorted protocol list.
|
||||
|
||||
DriverBindingHandleCount - Driver Binding Handle Count.
|
||||
|
||||
DriverBindingHandleBuffer - The buffer of driver binding protocol to be modified.
|
||||
|
||||
Returns:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
|
||||
UINTN Index;
|
||||
|
||||
//
|
||||
// Make sure the DriverBindingHandle is valid
|
||||
//
|
||||
Status = CoreValidateHandle (DriverBindingHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve the Driver Binding Protocol from DriverBindingHandle
|
||||
//
|
||||
Status = CoreHandleProtocol(
|
||||
DriverBindingHandle,
|
||||
&gEfiDriverBindingProtocolGuid,
|
||||
(VOID **)&DriverBinding
|
||||
);
|
||||
//
|
||||
// If DriverBindingHandle does not support the Driver Binding Protocol then return
|
||||
//
|
||||
if (EFI_ERROR (Status) || DriverBinding == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// See if DriverBinding is already in the sorted list
|
||||
//
|
||||
for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols; Index++) {
|
||||
if (DriverBinding == SortedDriverBindingProtocols[Index]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Add DriverBinding to the end of the list
|
||||
//
|
||||
SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding;
|
||||
*NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1;
|
||||
|
||||
//
|
||||
// Mark the cooresponding handle in DriverBindingHandleBuffer as used
|
||||
//
|
||||
for (Index = 0; Index < DriverBindingHandleCount; Index++) {
|
||||
if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) {
|
||||
DriverBindingHandleBuffer[Index] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
CoreConnectSingleController (
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE *ContextDriverImageHandles OPTIONAL,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Connects a controller to a driver.
|
||||
|
||||
Arguments:
|
||||
|
||||
ControllerHandle - Handle of the controller to be connected.
|
||||
ContextDriverImageHandles - DriverImageHandle A pointer to an ordered list of driver image handles.
|
||||
RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child
|
||||
of the controller specified by ControllerHandle.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - One or more drivers were connected to ControllerHandle.
|
||||
EFI_OUT_OF_RESOURCES - No enough system resources to complete the request.
|
||||
EFI_NOT_FOUND - No drivers were connected to ControllerHandle.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
EFI_HANDLE DriverImageHandle;
|
||||
EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *PlatformDriverOverride;
|
||||
EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;
|
||||
UINTN DriverBindingHandleCount;
|
||||
EFI_HANDLE *DriverBindingHandleBuffer;
|
||||
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
|
||||
UINTN NumberOfSortedDriverBindingProtocols;
|
||||
EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols;
|
||||
UINT32 HighestVersion;
|
||||
UINTN HighestIndex;
|
||||
UINTN SortIndex;
|
||||
BOOLEAN OneStarted;
|
||||
BOOLEAN DriverFound;
|
||||
EFI_HANDLE DriverBindingHandle;
|
||||
|
||||
//
|
||||
// DriverBindingHandle is used for performance measurement, initialize it here just in case.
|
||||
//
|
||||
DriverBindingHandle = NULL;
|
||||
//
|
||||
// Initialize local variables
|
||||
//
|
||||
DriverBindingHandleCount = 0;
|
||||
DriverBindingHandleBuffer = NULL;
|
||||
NumberOfSortedDriverBindingProtocols = 0;
|
||||
SortedDriverBindingProtocols = NULL;
|
||||
|
||||
//
|
||||
// Get list of all Driver Binding Protocol Instances
|
||||
//
|
||||
Status = CoreLocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiDriverBindingProtocolGuid,
|
||||
NULL,
|
||||
&DriverBindingHandleCount,
|
||||
&DriverBindingHandleBuffer
|
||||
);
|
||||
if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate a duplicate array for the sorted Driver Binding Protocol Instances
|
||||
//
|
||||
SortedDriverBindingProtocols = CoreAllocateBootServicesPool (sizeof (VOID *) * DriverBindingHandleCount);
|
||||
if (SortedDriverBindingProtocols == NULL) {
|
||||
CoreFreePool (DriverBindingHandleBuffer);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Add Driver Binding Protocols from Context Driver Image Handles first
|
||||
//
|
||||
if (ContextDriverImageHandles != NULL) {
|
||||
for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) {
|
||||
AddSortedDriverBindingProtocol (
|
||||
ContextDriverImageHandles[Index],
|
||||
&NumberOfSortedDriverBindingProtocols,
|
||||
SortedDriverBindingProtocols,
|
||||
DriverBindingHandleCount,
|
||||
DriverBindingHandleBuffer
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Add the Platform Driver Override Protocol drivers for ControllerHandle next
|
||||
//
|
||||
Status = CoreLocateProtocol (
|
||||
&gEfiPlatformDriverOverrideProtocolGuid,
|
||||
NULL,
|
||||
(VOID **)&PlatformDriverOverride
|
||||
);
|
||||
if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) {
|
||||
DriverImageHandle = NULL;
|
||||
do {
|
||||
Status = PlatformDriverOverride->GetDriver (
|
||||
PlatformDriverOverride,
|
||||
ControllerHandle,
|
||||
&DriverImageHandle
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
AddSortedDriverBindingProtocol (
|
||||
DriverImageHandle,
|
||||
&NumberOfSortedDriverBindingProtocols,
|
||||
SortedDriverBindingProtocols,
|
||||
DriverBindingHandleCount,
|
||||
DriverBindingHandleBuffer
|
||||
);
|
||||
}
|
||||
} while (!EFI_ERROR (Status));
|
||||
}
|
||||
|
||||
//
|
||||
// Get the Bus Specific Driver Override Protocol instance on the Controller Handle
|
||||
//
|
||||
Status = CoreHandleProtocol(
|
||||
ControllerHandle,
|
||||
&gEfiBusSpecificDriverOverrideProtocolGuid,
|
||||
(VOID **)&BusSpecificDriverOverride
|
||||
);
|
||||
if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) {
|
||||
DriverImageHandle = NULL;
|
||||
do {
|
||||
Status = BusSpecificDriverOverride->GetDriver (
|
||||
BusSpecificDriverOverride,
|
||||
&DriverImageHandle
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
AddSortedDriverBindingProtocol (
|
||||
DriverImageHandle,
|
||||
&NumberOfSortedDriverBindingProtocols,
|
||||
SortedDriverBindingProtocols,
|
||||
DriverBindingHandleCount,
|
||||
DriverBindingHandleBuffer
|
||||
);
|
||||
}
|
||||
} while (!EFI_ERROR (Status));
|
||||
}
|
||||
|
||||
//
|
||||
// Then add all the remaining Driver Binding Protocols
|
||||
//
|
||||
SortIndex = NumberOfSortedDriverBindingProtocols;
|
||||
for (Index = 0; Index < DriverBindingHandleCount; Index++) {
|
||||
AddSortedDriverBindingProtocol (
|
||||
DriverBindingHandleBuffer[Index],
|
||||
&NumberOfSortedDriverBindingProtocols,
|
||||
SortedDriverBindingProtocols,
|
||||
DriverBindingHandleCount,
|
||||
DriverBindingHandleBuffer
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Free the Driver Binding Handle Buffer
|
||||
//
|
||||
CoreFreePool (DriverBindingHandleBuffer);
|
||||
|
||||
//
|
||||
// Sort the remaining DriverBinding Protocol based on their Version field from
|
||||
// highest to lowest.
|
||||
//
|
||||
for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) {
|
||||
HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version;
|
||||
HighestIndex = SortIndex;
|
||||
for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) {
|
||||
if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) {
|
||||
HighestVersion = SortedDriverBindingProtocols[Index]->Version;
|
||||
HighestIndex = Index;
|
||||
}
|
||||
}
|
||||
if (SortIndex != HighestIndex) {
|
||||
DriverBinding = SortedDriverBindingProtocols[SortIndex];
|
||||
SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex];
|
||||
SortedDriverBindingProtocols[HighestIndex] = DriverBinding;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Loop until no more drivers can be started on ControllerHandle
|
||||
//
|
||||
OneStarted = FALSE;
|
||||
do {
|
||||
|
||||
//
|
||||
// Loop through the sorted Driver Binding Protocol Instances in order, and see if
|
||||
// any of the Driver Binding Protocols support the controller specified by
|
||||
// ControllerHandle.
|
||||
//
|
||||
DriverBinding = NULL;
|
||||
DriverFound = FALSE;
|
||||
for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) {
|
||||
if (SortedDriverBindingProtocols[Index] != NULL) {
|
||||
DriverBinding = SortedDriverBindingProtocols[Index];
|
||||
Status = DriverBinding->Supported(
|
||||
DriverBinding,
|
||||
ControllerHandle,
|
||||
RemainingDevicePath
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
SortedDriverBindingProtocols[Index] = NULL;
|
||||
DriverFound = TRUE;
|
||||
|
||||
//
|
||||
// A driver was found that supports ControllerHandle, so attempt to start the driver
|
||||
// on ControllerHandle.
|
||||
//
|
||||
PERF_CODE_BEGIN ();
|
||||
GetHandleFromDriverBinding (DriverBinding, &DriverBindingHandle);
|
||||
PERF_CODE_END ();
|
||||
|
||||
PERF_START (DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0);
|
||||
Status = DriverBinding->Start (
|
||||
DriverBinding,
|
||||
ControllerHandle,
|
||||
RemainingDevicePath
|
||||
);
|
||||
PERF_END (DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// The driver was successfully started on ControllerHandle, so set a flag
|
||||
//
|
||||
OneStarted = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (DriverFound);
|
||||
|
||||
//
|
||||
// Free any buffers that were allocated with AllocatePool()
|
||||
//
|
||||
CoreFreePool (SortedDriverBindingProtocols);
|
||||
|
||||
//
|
||||
// If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
|
||||
//
|
||||
if (OneStarted) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
|
||||
//
|
||||
if (RemainingDevicePath != NULL) {
|
||||
if (IsDevicePathEnd (RemainingDevicePath)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
|
||||
//
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreDisconnectController (
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE DriverImageHandle OPTIONAL,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Disonnects a controller from a driver
|
||||
|
||||
Arguments:
|
||||
|
||||
ControllerHandle - ControllerHandle The handle of the controller from which driver(s)
|
||||
are to be disconnected.
|
||||
DriverImageHandle - DriverImageHandle The driver to disconnect from ControllerHandle.
|
||||
ChildHandle - ChildHandle The handle of the child to destroy.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - One or more drivers were disconnected from the controller.
|
||||
EFI_SUCCESS - On entry, no drivers are managing ControllerHandle.
|
||||
EFI_SUCCESS - DriverImageHandle is not NULL, and on entry DriverImageHandle is not managing ControllerHandle.
|
||||
EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
|
||||
EFI_INVALID_PARAMETER - DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE.
|
||||
EFI_INVALID_PARAMETER - ChildHandle is not NULL, and it is not a valid EFI_HANDLE.
|
||||
EFI_OUT_OF_RESOURCES - There are not enough resources available to disconnect any drivers from ControllerHandle.
|
||||
EFI_DEVICE_ERROR - The controller could not be disconnected because of a device error.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
IHANDLE *Handle;
|
||||
EFI_HANDLE *DriverImageHandleBuffer;
|
||||
EFI_HANDLE *ChildBuffer;
|
||||
UINTN Index;
|
||||
UINTN HandleIndex;
|
||||
UINTN DriverImageHandleCount;
|
||||
UINTN ChildrenToStop;
|
||||
UINTN ChildBufferCount;
|
||||
UINTN StopCount;
|
||||
BOOLEAN Duplicate;
|
||||
BOOLEAN ChildHandleValid;
|
||||
BOOLEAN DriverImageHandleValid;
|
||||
LIST_ENTRY *Link;
|
||||
LIST_ENTRY *ProtLink;
|
||||
OPEN_PROTOCOL_DATA *OpenData;
|
||||
PROTOCOL_INTERFACE *Prot;
|
||||
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
|
||||
|
||||
//
|
||||
// Make sure ControllerHandle is valid
|
||||
//
|
||||
Status = CoreValidateHandle (ControllerHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure ChildHandle is valid if it is not NULL
|
||||
//
|
||||
if (ChildHandle != NULL) {
|
||||
Status = CoreValidateHandle (ChildHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
Handle = ControllerHandle;
|
||||
|
||||
//
|
||||
// Get list of drivers that are currently managing ControllerHandle
|
||||
//
|
||||
DriverImageHandleBuffer = NULL;
|
||||
DriverImageHandleCount = 1;
|
||||
|
||||
if (DriverImageHandle == NULL) {
|
||||
//
|
||||
// Look at each protocol interface for a match
|
||||
//
|
||||
DriverImageHandleCount = 0;
|
||||
|
||||
CoreAcquireProtocolLock ();
|
||||
for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
|
||||
Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
|
||||
for (ProtLink = Prot->OpenList.ForwardLink;
|
||||
ProtLink != &Prot->OpenList;
|
||||
ProtLink = ProtLink->ForwardLink) {
|
||||
OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
|
||||
if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
|
||||
DriverImageHandleCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
CoreReleaseProtocolLock ();
|
||||
|
||||
//
|
||||
// If there are no drivers managing this controller, then return EFI_SUCCESS
|
||||
//
|
||||
if (DriverImageHandleCount == 0) {
|
||||
Status = EFI_SUCCESS;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
DriverImageHandleBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * DriverImageHandleCount);
|
||||
if (DriverImageHandleBuffer == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
DriverImageHandleCount = 0;
|
||||
|
||||
CoreAcquireProtocolLock ();
|
||||
for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
|
||||
Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
|
||||
for (ProtLink = Prot->OpenList.ForwardLink;
|
||||
ProtLink != &Prot->OpenList;
|
||||
ProtLink = ProtLink->ForwardLink) {
|
||||
OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
|
||||
if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
|
||||
Duplicate = FALSE;
|
||||
for (Index = 0; Index< DriverImageHandleCount; Index++) {
|
||||
if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) {
|
||||
Duplicate = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!Duplicate) {
|
||||
DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle;
|
||||
DriverImageHandleCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CoreReleaseProtocolLock ();
|
||||
}
|
||||
|
||||
StopCount = 0;
|
||||
for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) {
|
||||
|
||||
if (DriverImageHandleBuffer != NULL) {
|
||||
DriverImageHandle = DriverImageHandleBuffer[HandleIndex];
|
||||
}
|
||||
|
||||
//
|
||||
// Get the Driver Binding Protocol of the driver that is managing this controller
|
||||
//
|
||||
Status = CoreHandleProtocol (
|
||||
DriverImageHandle,
|
||||
&gEfiDriverBindingProtocolGuid,
|
||||
(VOID **)&DriverBinding
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Look at each protocol interface for a match
|
||||
//
|
||||
DriverImageHandleValid = FALSE;
|
||||
ChildBufferCount = 0;
|
||||
|
||||
CoreAcquireProtocolLock ();
|
||||
for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
|
||||
Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
|
||||
for (ProtLink = Prot->OpenList.ForwardLink;
|
||||
ProtLink != &Prot->OpenList;
|
||||
ProtLink = ProtLink->ForwardLink) {
|
||||
OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
|
||||
if (OpenData->AgentHandle == DriverImageHandle) {
|
||||
if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
|
||||
ChildBufferCount++;
|
||||
}
|
||||
if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
|
||||
DriverImageHandleValid = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CoreReleaseProtocolLock ();
|
||||
|
||||
if (DriverImageHandleValid) {
|
||||
ChildHandleValid = FALSE;
|
||||
ChildBuffer = NULL;
|
||||
if (ChildBufferCount != 0) {
|
||||
ChildBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * ChildBufferCount);
|
||||
if (ChildBuffer == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
ChildBufferCount = 0;
|
||||
|
||||
CoreAcquireProtocolLock ();
|
||||
for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
|
||||
Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
|
||||
for (ProtLink = Prot->OpenList.ForwardLink;
|
||||
ProtLink != &Prot->OpenList;
|
||||
ProtLink = ProtLink->ForwardLink) {
|
||||
OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
|
||||
if ((OpenData->AgentHandle == DriverImageHandle) &&
|
||||
((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) {
|
||||
Duplicate = FALSE;
|
||||
for (Index = 0; Index < ChildBufferCount; Index++) {
|
||||
if (ChildBuffer[Index] == OpenData->ControllerHandle) {
|
||||
Duplicate = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!Duplicate) {
|
||||
ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle;
|
||||
if (ChildHandle == ChildBuffer[ChildBufferCount]) {
|
||||
ChildHandleValid = TRUE;
|
||||
}
|
||||
ChildBufferCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CoreReleaseProtocolLock ();
|
||||
}
|
||||
|
||||
if (ChildHandle == NULL || ChildHandleValid) {
|
||||
ChildrenToStop = 0;
|
||||
Status = EFI_SUCCESS;
|
||||
if (ChildBufferCount > 0) {
|
||||
if (ChildHandle != NULL) {
|
||||
ChildrenToStop = 1;
|
||||
Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle);
|
||||
} else {
|
||||
ChildrenToStop = ChildBufferCount;
|
||||
Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer);
|
||||
}
|
||||
}
|
||||
if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) {
|
||||
Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL);
|
||||
}
|
||||
if (!EFI_ERROR (Status)) {
|
||||
StopCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ChildBuffer != NULL) {
|
||||
CoreFreePool (ChildBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (StopCount > 0) {
|
||||
Status = EFI_SUCCESS;
|
||||
} else {
|
||||
Status = EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
Done:
|
||||
|
||||
if (DriverImageHandleBuffer != NULL) {
|
||||
CoreFreePool (DriverImageHandleBuffer);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
GetHandleFromDriverBinding (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *DriverBindingNeed,
|
||||
OUT EFI_HANDLE *Handle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Locate the driver binding handle which a specified driver binding protocol installed on.
|
||||
|
||||
Arguments:
|
||||
|
||||
DriverBindingNeed - The specified driver binding protocol.
|
||||
|
||||
Handle - The driver binding handle which the protocol installed on.
|
||||
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_NOT_FOUND - Could not find the handle.
|
||||
|
||||
EFI_SUCCESS - Successfully find the associated driver binding handle.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status ;
|
||||
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
|
||||
UINTN DriverBindingHandleCount;
|
||||
EFI_HANDLE *DriverBindingHandleBuffer;
|
||||
UINTN Index;
|
||||
|
||||
DriverBindingHandleCount = 0;
|
||||
DriverBindingHandleBuffer = NULL;
|
||||
*Handle = NULL_HANDLE;
|
||||
Status = CoreLocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiDriverBindingProtocolGuid,
|
||||
NULL,
|
||||
&DriverBindingHandleCount,
|
||||
&DriverBindingHandleBuffer
|
||||
);
|
||||
if (EFI_ERROR (Status) || DriverBindingHandleCount == 0) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
for (Index = 0 ; Index < DriverBindingHandleCount; Index++ ) {
|
||||
Status = CoreOpenProtocol(
|
||||
DriverBindingHandleBuffer[Index],
|
||||
&gEfiDriverBindingProtocolGuid,
|
||||
(VOID **)&DriverBinding,
|
||||
gDxeCoreImageHandle,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status) && DriverBinding != NULL) {
|
||||
|
||||
if ( DriverBinding == DriverBindingNeed ) {
|
||||
*Handle = DriverBindingHandleBuffer[Index];
|
||||
CoreFreePool (DriverBindingHandleBuffer);
|
||||
return EFI_SUCCESS ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CoreFreePool (DriverBindingHandleBuffer);
|
||||
return EFI_NOT_FOUND ;
|
||||
}
|
||||
|
333
MdeModulePkg/Core/Dxe/Hand/Notify.c
Normal file
333
MdeModulePkg/Core/Dxe/Hand/Notify.c
Normal file
@ -0,0 +1,333 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
notify.c
|
||||
|
||||
Abstract:
|
||||
|
||||
EFI notify infrastructure
|
||||
|
||||
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
VOID
|
||||
CoreNotifyProtocolEntry (
|
||||
IN PROTOCOL_ENTRY *ProtEntry
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Signal event for every protocol in protocol entry.
|
||||
|
||||
Arguments:
|
||||
|
||||
ProtEntry - Protocol entry
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
PROTOCOL_NOTIFY *ProtNotify;
|
||||
LIST_ENTRY *Link;
|
||||
|
||||
ASSERT_LOCKED (&gProtocolDatabaseLock);
|
||||
|
||||
for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {
|
||||
ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
|
||||
CoreSignalEvent (ProtNotify->Event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PROTOCOL_INTERFACE *
|
||||
CoreRemoveInterfaceFromProtocol (
|
||||
IN IHANDLE *Handle,
|
||||
IN EFI_GUID *Protocol,
|
||||
IN VOID *Interface
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Removes Protocol from the protocol list (but not the handle list).
|
||||
|
||||
Arguments:
|
||||
|
||||
Handle - The handle to remove protocol on.
|
||||
|
||||
Protocol - GUID of the protocol to be moved
|
||||
|
||||
Interface - The interface of the protocol
|
||||
|
||||
Returns:
|
||||
|
||||
Protocol Entry
|
||||
|
||||
--*/
|
||||
{
|
||||
PROTOCOL_INTERFACE *Prot;
|
||||
PROTOCOL_NOTIFY *ProtNotify;
|
||||
PROTOCOL_ENTRY *ProtEntry;
|
||||
LIST_ENTRY *Link;
|
||||
|
||||
ASSERT_LOCKED (&gProtocolDatabaseLock);
|
||||
|
||||
Prot = CoreFindProtocolInterface (Handle, Protocol, Interface);
|
||||
if (Prot != NULL) {
|
||||
|
||||
ProtEntry = Prot->Protocol;
|
||||
|
||||
//
|
||||
// If there's a protocol notify location pointing to this entry, back it up one
|
||||
//
|
||||
|
||||
for(Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {
|
||||
ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
|
||||
|
||||
if (ProtNotify->Position == &Prot->ByProtocol) {
|
||||
ProtNotify->Position = Prot->ByProtocol.BackLink;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Remove the protocol interface entry
|
||||
//
|
||||
|
||||
RemoveEntryList (&Prot->ByProtocol);
|
||||
}
|
||||
|
||||
return Prot;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreRegisterProtocolNotify (
|
||||
IN EFI_GUID *Protocol,
|
||||
IN EFI_EVENT Event,
|
||||
OUT VOID **Registration
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Add a new protocol notification record for the request protocol.
|
||||
|
||||
Arguments:
|
||||
|
||||
Protocol - The requested protocol to add the notify registration
|
||||
|
||||
Event - The event to signal
|
||||
|
||||
Registration - Returns the registration record
|
||||
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_INVALID_PARAMETER - Invalid parameter
|
||||
|
||||
EFI_SUCCESS - Successfully returned the registration record that has been added
|
||||
|
||||
--*/
|
||||
{
|
||||
PROTOCOL_ENTRY *ProtEntry;
|
||||
PROTOCOL_NOTIFY *ProtNotify;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if ((Protocol == NULL) || (Event == NULL) || (Registration == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
ProtNotify = NULL;
|
||||
|
||||
//
|
||||
// Get the protocol entry to add the notification too
|
||||
//
|
||||
|
||||
ProtEntry = CoreFindProtocolEntry (Protocol, TRUE);
|
||||
if (ProtEntry != NULL) {
|
||||
|
||||
//
|
||||
// Allocate a new notification record
|
||||
//
|
||||
|
||||
ProtNotify = CoreAllocateBootServicesPool (sizeof(PROTOCOL_NOTIFY));
|
||||
|
||||
if (ProtNotify != NULL) {
|
||||
|
||||
ProtNotify->Signature = PROTOCOL_NOTIFY_SIGNATURE;
|
||||
ProtNotify->Protocol = ProtEntry;
|
||||
ProtNotify->Event = Event;
|
||||
//
|
||||
// start at the begining
|
||||
//
|
||||
ProtNotify->Position = &ProtEntry->Protocols;
|
||||
|
||||
InsertTailList (&ProtEntry->Notify, &ProtNotify->Link);
|
||||
}
|
||||
}
|
||||
|
||||
CoreReleaseProtocolLock ();
|
||||
|
||||
//
|
||||
// Done. If we have a protocol notify entry, then return it.
|
||||
// Otherwise, we must have run out of resources trying to add one
|
||||
//
|
||||
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
if (ProtNotify != NULL) {
|
||||
*Registration = ProtNotify;
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreReinstallProtocolInterface (
|
||||
IN EFI_HANDLE UserHandle,
|
||||
IN EFI_GUID *Protocol,
|
||||
IN VOID *OldInterface,
|
||||
IN VOID *NewInterface
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.
|
||||
|
||||
Arguments:
|
||||
|
||||
UserHandle - Handle on which the interface is to be reinstalled
|
||||
Protocol - The numeric ID of the interface
|
||||
OldInterface - A pointer to the old interface
|
||||
NewInterface - A pointer to the new interface
|
||||
|
||||
|
||||
Returns:
|
||||
|
||||
Status code.
|
||||
|
||||
On EFI_SUCCESS The protocol interface was installed
|
||||
On EFI_NOT_FOUND The OldInterface on the handle was not found
|
||||
On EFI_INVALID_PARAMETER One of the parameters has an invalid value
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
IHANDLE *Handle;
|
||||
PROTOCOL_INTERFACE *Prot;
|
||||
PROTOCOL_ENTRY *ProtEntry;
|
||||
|
||||
Status = CoreValidateHandle (UserHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (Protocol == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Handle = (IHANDLE *) UserHandle;
|
||||
|
||||
//
|
||||
// Lock the protocol database
|
||||
//
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
//
|
||||
// Check that Protocol exists on UserHandle, and Interface matches the interface in the database
|
||||
//
|
||||
Prot = CoreFindProtocolInterface (UserHandle, Protocol, OldInterface);
|
||||
if (Prot == NULL) {
|
||||
CoreReleaseProtocolLock ();
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled
|
||||
//
|
||||
Status = CoreDisconnectControllersUsingProtocolInterface (
|
||||
UserHandle,
|
||||
Prot
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// One or more drivers refused to release, so return the error
|
||||
//
|
||||
CoreReleaseProtocolLock ();
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Remove the protocol interface from the protocol
|
||||
//
|
||||
Prot = CoreRemoveInterfaceFromProtocol (Handle, Protocol, OldInterface);
|
||||
|
||||
if (Prot == NULL) {
|
||||
CoreReleaseProtocolLock ();
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
ProtEntry = Prot->Protocol;
|
||||
|
||||
//
|
||||
// Update the interface on the protocol
|
||||
//
|
||||
Prot->Interface = NewInterface;
|
||||
|
||||
//
|
||||
// Add this protocol interface to the tail of the
|
||||
// protocol entry
|
||||
//
|
||||
InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);
|
||||
|
||||
//
|
||||
// Update the Key to show that the handle has been created/modified
|
||||
//
|
||||
gHandleDatabaseKey++;
|
||||
Handle->Key = gHandleDatabaseKey;
|
||||
|
||||
//
|
||||
// Release the lock and connect all drivers to UserHandle
|
||||
//
|
||||
CoreReleaseProtocolLock ();
|
||||
Status = CoreConnectController (
|
||||
UserHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE
|
||||
);
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
//
|
||||
// Notify the notification list for this protocol
|
||||
//
|
||||
CoreNotifyProtocolEntry (ProtEntry);
|
||||
|
||||
CoreReleaseProtocolLock ();
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
1700
MdeModulePkg/Core/Dxe/Hand/handle.c
Normal file
1700
MdeModulePkg/Core/Dxe/Hand/handle.c
Normal file
File diff suppressed because it is too large
Load Diff
733
MdeModulePkg/Core/Dxe/Hand/locate.c
Normal file
733
MdeModulePkg/Core/Dxe/Hand/locate.c
Normal file
@ -0,0 +1,733 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
locate.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Locate handle functions
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
//
|
||||
// ProtocolRequest - Last LocateHandle request ID
|
||||
//
|
||||
UINTN mEfiLocateHandleRequest = 0;
|
||||
|
||||
//
|
||||
// Internal prototypes
|
||||
//
|
||||
|
||||
typedef struct {
|
||||
EFI_GUID *Protocol;
|
||||
VOID *SearchKey;
|
||||
LIST_ENTRY *Position;
|
||||
PROTOCOL_ENTRY *ProtEntry;
|
||||
} LOCATE_POSITION;
|
||||
|
||||
typedef
|
||||
IHANDLE *
|
||||
(* CORE_GET_NEXT) (
|
||||
IN OUT LOCATE_POSITION *Position,
|
||||
OUT VOID **Interface
|
||||
);
|
||||
|
||||
STATIC
|
||||
IHANDLE *
|
||||
CoreGetNextLocateAllHandles (
|
||||
IN OUT LOCATE_POSITION *Position,
|
||||
OUT VOID **Interface
|
||||
);
|
||||
|
||||
STATIC
|
||||
IHANDLE *
|
||||
CoreGetNextLocateByRegisterNotify (
|
||||
IN OUT LOCATE_POSITION *Position,
|
||||
OUT VOID **Interface
|
||||
);
|
||||
|
||||
STATIC
|
||||
IHANDLE *
|
||||
CoreGetNextLocateByProtocol (
|
||||
IN OUT LOCATE_POSITION *Position,
|
||||
OUT VOID **Interface
|
||||
);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreLocateHandle (
|
||||
IN EFI_LOCATE_SEARCH_TYPE SearchType,
|
||||
IN EFI_GUID *Protocol OPTIONAL,
|
||||
IN VOID *SearchKey OPTIONAL,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT EFI_HANDLE *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Locates the requested handle(s) and returns them in Buffer.
|
||||
|
||||
Arguments:
|
||||
|
||||
SearchType - The type of search to perform to locate the handles
|
||||
|
||||
Protocol - The protocol to search for
|
||||
|
||||
SearchKey - Dependant on SearchType
|
||||
|
||||
BufferSize - On input the size of Buffer. On output the
|
||||
size of data returned.
|
||||
|
||||
Buffer - The buffer to return the results in
|
||||
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_BUFFER_TOO_SMALL - Buffer too small, required buffer size is returned in BufferSize.
|
||||
|
||||
EFI_INVALID_PARAMETER - Invalid parameter
|
||||
|
||||
EFI_SUCCESS - Successfully found the requested handle(s) and returns them in Buffer.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
LOCATE_POSITION Position;
|
||||
PROTOCOL_NOTIFY *ProtNotify;
|
||||
CORE_GET_NEXT GetNext;
|
||||
UINTN ResultSize;
|
||||
IHANDLE *Handle;
|
||||
IHANDLE **ResultBuffer;
|
||||
VOID *Interface;
|
||||
|
||||
if (BufferSize == NULL) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((*BufferSize > 0) && (Buffer == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
GetNext = NULL;
|
||||
//
|
||||
// Set initial position
|
||||
//
|
||||
|
||||
Position.Protocol = Protocol;
|
||||
Position.SearchKey = SearchKey;
|
||||
Position.Position = &gHandleList;
|
||||
|
||||
ResultSize = 0;
|
||||
ResultBuffer = (IHANDLE **) Buffer;
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
//
|
||||
// Lock the protocol database
|
||||
//
|
||||
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
//
|
||||
// Get the search function based on type
|
||||
//
|
||||
switch (SearchType) {
|
||||
case AllHandles:
|
||||
GetNext = CoreGetNextLocateAllHandles;
|
||||
break;
|
||||
|
||||
case ByRegisterNotify:
|
||||
//
|
||||
// Must have SearchKey for locate ByRegisterNotify
|
||||
//
|
||||
if (SearchKey == NULL) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
GetNext = CoreGetNextLocateByRegisterNotify;
|
||||
break;
|
||||
|
||||
case ByProtocol:
|
||||
GetNext = CoreGetNextLocateByProtocol;
|
||||
if (Protocol == NULL) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
//
|
||||
// Look up the protocol entry and set the head pointer
|
||||
//
|
||||
Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE);
|
||||
if (Position.ProtEntry == NULL) {
|
||||
Status = EFI_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
Position.Position = &Position.ProtEntry->Protocols;
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
if (EFI_ERROR(Status)) {
|
||||
CoreReleaseProtocolLock ();
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Enumerate out the matching handles
|
||||
//
|
||||
mEfiLocateHandleRequest += 1;
|
||||
for (; ;) {
|
||||
//
|
||||
// Get the next handle. If no more handles, stop
|
||||
//
|
||||
Handle = GetNext (&Position, &Interface);
|
||||
if (NULL == Handle) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Increase the resulting buffer size, and if this handle
|
||||
// fits return it
|
||||
//
|
||||
ResultSize += sizeof(Handle);
|
||||
if (ResultSize <= *BufferSize) {
|
||||
*ResultBuffer = Handle;
|
||||
ResultBuffer += 1;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// If the result is a zero length buffer, then there were no
|
||||
// matching handles
|
||||
//
|
||||
if (ResultSize == 0) {
|
||||
Status = EFI_NOT_FOUND;
|
||||
} else {
|
||||
//
|
||||
// Return the resulting buffer size. If it's larger than what
|
||||
// was passed, then set the error code
|
||||
//
|
||||
if (ResultSize > *BufferSize) {
|
||||
Status = EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
*BufferSize = ResultSize;
|
||||
|
||||
if (SearchType == ByRegisterNotify && !EFI_ERROR(Status)) {
|
||||
//
|
||||
// If this is a search by register notify and a handle was
|
||||
// returned, update the register notification position
|
||||
//
|
||||
ProtNotify = SearchKey;
|
||||
ProtNotify->Position = ProtNotify->Position->ForwardLink;
|
||||
}
|
||||
}
|
||||
|
||||
CoreReleaseProtocolLock ();
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
STATIC
|
||||
IHANDLE *
|
||||
CoreGetNextLocateAllHandles (
|
||||
IN OUT LOCATE_POSITION *Position,
|
||||
OUT VOID **Interface
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Routine to get the next Handle, when you are searching for all handles.
|
||||
|
||||
Arguments:
|
||||
|
||||
Position - Information about which Handle to seach for.
|
||||
|
||||
Interface - Return the interface structure for the matching protocol.
|
||||
|
||||
Returns:
|
||||
IHANDLE - An IHANDLE is returned if the next Position is not the end of the
|
||||
list. A NULL_HANDLE is returned if it's the end of the list.
|
||||
|
||||
--*/
|
||||
{
|
||||
IHANDLE *Handle;
|
||||
|
||||
//
|
||||
// Next handle
|
||||
//
|
||||
Position->Position = Position->Position->ForwardLink;
|
||||
|
||||
//
|
||||
// If not at the end of the list, get the handle
|
||||
//
|
||||
Handle = NULL_HANDLE;
|
||||
*Interface = NULL;
|
||||
if (Position->Position != &gHandleList) {
|
||||
Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
|
||||
}
|
||||
|
||||
return Handle;
|
||||
}
|
||||
|
||||
|
||||
STATIC
|
||||
IHANDLE *
|
||||
CoreGetNextLocateByRegisterNotify (
|
||||
IN OUT LOCATE_POSITION *Position,
|
||||
OUT VOID **Interface
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Routine to get the next Handle, when you are searching for register protocol
|
||||
notifies.
|
||||
|
||||
Arguments:
|
||||
|
||||
Position - Information about which Handle to seach for.
|
||||
|
||||
Interface - Return the interface structure for the matching protocol.
|
||||
|
||||
Returns:
|
||||
IHANDLE - An IHANDLE is returned if the next Position is not the end of the
|
||||
list. A NULL_HANDLE is returned if it's the end of the list.
|
||||
|
||||
--*/
|
||||
{
|
||||
IHANDLE *Handle;
|
||||
PROTOCOL_NOTIFY *ProtNotify;
|
||||
PROTOCOL_INTERFACE *Prot;
|
||||
LIST_ENTRY *Link;
|
||||
|
||||
Handle = NULL_HANDLE;
|
||||
*Interface = NULL;
|
||||
ProtNotify = Position->SearchKey;
|
||||
|
||||
//
|
||||
// If this is the first request, get the next handle
|
||||
//
|
||||
if (ProtNotify != NULL) {
|
||||
ASSERT(ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE);
|
||||
Position->SearchKey = NULL;
|
||||
|
||||
//
|
||||
// If not at the end of the list, get the next handle
|
||||
//
|
||||
Link = ProtNotify->Position->ForwardLink;
|
||||
if (Link != &ProtNotify->Protocol->Protocols) {
|
||||
Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);
|
||||
Handle = (IHANDLE *) Prot->Handle;
|
||||
*Interface = Prot->Interface;
|
||||
}
|
||||
}
|
||||
|
||||
return Handle;
|
||||
}
|
||||
|
||||
|
||||
STATIC
|
||||
IHANDLE *
|
||||
CoreGetNextLocateByProtocol (
|
||||
IN OUT LOCATE_POSITION *Position,
|
||||
OUT VOID **Interface
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Routine to get the next Handle, when you are searching for a given protocol.
|
||||
|
||||
Arguments:
|
||||
|
||||
Position - Information about which Handle to seach for.
|
||||
|
||||
Interface - Return the interface structure for the matching protocol.
|
||||
|
||||
Returns:
|
||||
IHANDLE - An IHANDLE is returned if the next Position is not the end of the
|
||||
list. A NULL_HANDLE is returned if it's the end of the list.
|
||||
|
||||
--*/
|
||||
{
|
||||
IHANDLE *Handle;
|
||||
LIST_ENTRY *Link;
|
||||
PROTOCOL_INTERFACE *Prot;
|
||||
|
||||
Handle = NULL_HANDLE;
|
||||
*Interface = NULL;
|
||||
for (; ;) {
|
||||
//
|
||||
// Next entry
|
||||
//
|
||||
Link = Position->Position->ForwardLink;
|
||||
Position->Position = Link;
|
||||
|
||||
//
|
||||
// If not at the end, return the handle
|
||||
//
|
||||
if (Link == &Position->ProtEntry->Protocols) {
|
||||
Handle = NULL_HANDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the handle
|
||||
//
|
||||
Prot = CR(Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);
|
||||
Handle = (IHANDLE *) Prot->Handle;
|
||||
*Interface = Prot->Interface;
|
||||
|
||||
//
|
||||
// If this handle has not been returned this request, then
|
||||
// return it now
|
||||
//
|
||||
if (Handle->LocateRequest != mEfiLocateHandleRequest) {
|
||||
Handle->LocateRequest = mEfiLocateHandleRequest;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Handle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreLocateDevicePath (
|
||||
IN EFI_GUID *Protocol,
|
||||
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
|
||||
OUT EFI_HANDLE *Device
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Locates the handle to a device on the device path that best matches the specified protocol.
|
||||
|
||||
Arguments:
|
||||
|
||||
Protocol - The protocol to search for.
|
||||
DevicePath - On input, a pointer to a pointer to the device path. On output, the device
|
||||
path pointer is modified to point to the remaining part of the devicepath.
|
||||
Device - A pointer to the returned device handle.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The resulting handle was returned.
|
||||
EFI_NOT_FOUND - No handles matched the search.
|
||||
EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
|
||||
|
||||
--*/
|
||||
{
|
||||
INTN SourceSize;
|
||||
INTN Size;
|
||||
INTN BestMatch;
|
||||
UINTN HandleCount;
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE *Handles;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_DEVICE_PATH_PROTOCOL *SourcePath;
|
||||
EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
|
||||
|
||||
if (Protocol == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((DevicePath == NULL) || (*DevicePath == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Device == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*Device = NULL_HANDLE;
|
||||
SourcePath = *DevicePath;
|
||||
SourceSize = CoreDevicePathSize (SourcePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);
|
||||
|
||||
//
|
||||
// The source path can only have 1 instance
|
||||
//
|
||||
if (CoreIsDevicePathMultiInstance (SourcePath)) {
|
||||
DEBUG((EFI_D_ERROR, "LocateDevicePath: Device path has too many instances\n"));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Get a list of all handles that support the requested protocol
|
||||
//
|
||||
Status = CoreLocateHandleBuffer (ByProtocol, Protocol, NULL, &HandleCount, &Handles);
|
||||
if (EFI_ERROR (Status) || HandleCount == 0) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
BestMatch = -1;
|
||||
for(Index = 0; Index < HandleCount; Index += 1) {
|
||||
Handle = Handles[Index];
|
||||
Status = CoreHandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&TmpDevicePath);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// If this handle doesn't support device path, then skip it
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if DevicePath is first part of SourcePath
|
||||
//
|
||||
Size = CoreDevicePathSize (TmpDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);
|
||||
if ((Size <= SourceSize) && CompareMem (SourcePath, TmpDevicePath, Size) == 0) {
|
||||
//
|
||||
// If the size is equal to the best match, then we
|
||||
// have a duplice device path for 2 different device
|
||||
// handles
|
||||
//
|
||||
ASSERT (Size != BestMatch);
|
||||
|
||||
//
|
||||
// We've got a match, see if it's the best match so far
|
||||
//
|
||||
if (Size > BestMatch) {
|
||||
BestMatch = Size;
|
||||
*Device = Handle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CoreFreePool (Handles);
|
||||
|
||||
//
|
||||
// If there wasn't any match, then no parts of the device path was found.
|
||||
// Which is strange since there is likely a "root level" device path in the system.
|
||||
//
|
||||
if (BestMatch == -1) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the remaining part of the device path
|
||||
//
|
||||
*DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) SourcePath) + BestMatch);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreLocateProtocol (
|
||||
IN EFI_GUID *Protocol,
|
||||
IN VOID *Registration OPTIONAL,
|
||||
OUT VOID **Interface
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Return the first Protocol Interface that matches the Protocol GUID. If
|
||||
Registration is pasased in return a Protocol Instance that was just add
|
||||
to the system. If Retistration is NULL return the first Protocol Interface
|
||||
you find.
|
||||
|
||||
Arguments:
|
||||
|
||||
Protocol - The protocol to search for
|
||||
|
||||
Registration - Optional Registration Key returned from RegisterProtocolNotify()
|
||||
|
||||
Interface - Return the Protocol interface (instance).
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - If a valid Interface is returned
|
||||
|
||||
EFI_INVALID_PARAMETER - Invalid parameter
|
||||
|
||||
EFI_NOT_FOUND - Protocol interface not found
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
LOCATE_POSITION Position;
|
||||
PROTOCOL_NOTIFY *ProtNotify;
|
||||
IHANDLE *Handle;
|
||||
|
||||
if (Interface == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Protocol == NULL) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
*Interface = NULL;
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
//
|
||||
// Set initial position
|
||||
//
|
||||
Position.Protocol = Protocol;
|
||||
Position.SearchKey = Registration;
|
||||
Position.Position = &gHandleList;
|
||||
|
||||
//
|
||||
// Lock the protocol database
|
||||
//
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
mEfiLocateHandleRequest += 1;
|
||||
|
||||
if (NULL == Registration) {
|
||||
//
|
||||
// Look up the protocol entry and set the head pointer
|
||||
//
|
||||
Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE);
|
||||
if (Position.ProtEntry == NULL) {
|
||||
Status = EFI_NOT_FOUND;
|
||||
goto Done;
|
||||
}
|
||||
Position.Position = &Position.ProtEntry->Protocols;
|
||||
|
||||
Handle = CoreGetNextLocateByProtocol (&Position, Interface);
|
||||
} else {
|
||||
Handle = CoreGetNextLocateByRegisterNotify (&Position, Interface);
|
||||
}
|
||||
|
||||
if (NULL == Handle) {
|
||||
Status = EFI_NOT_FOUND;
|
||||
} else if (NULL != Registration) {
|
||||
//
|
||||
// If this is a search by register notify and a handle was
|
||||
// returned, update the register notification position
|
||||
//
|
||||
ProtNotify = Registration;
|
||||
ProtNotify->Position = ProtNotify->Position->ForwardLink;
|
||||
}
|
||||
|
||||
Done:
|
||||
CoreReleaseProtocolLock ();
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreLocateHandleBuffer (
|
||||
IN EFI_LOCATE_SEARCH_TYPE SearchType,
|
||||
IN EFI_GUID *Protocol OPTIONAL,
|
||||
IN VOID *SearchKey OPTIONAL,
|
||||
IN OUT UINTN *NumberHandles,
|
||||
OUT EFI_HANDLE **Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Function returns an array of handles that support the requested protocol
|
||||
in a buffer allocated from pool. This is a version of CoreLocateHandle()
|
||||
that allocates a buffer for the caller.
|
||||
|
||||
Arguments:
|
||||
|
||||
SearchType - Specifies which handle(s) are to be returned.
|
||||
Protocol - Provides the protocol to search by.
|
||||
This parameter is only valid for SearchType ByProtocol.
|
||||
SearchKey - Supplies the search key depending on the SearchType.
|
||||
NumberHandles - The number of handles returned in Buffer.
|
||||
Buffer - A pointer to the buffer to return the requested array of
|
||||
handles that support Protocol.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The result array of handles was returned.
|
||||
EFI_NOT_FOUND - No handles match the search.
|
||||
EFI_OUT_OF_RESOURCES - There is not enough pool memory to store the matching results.
|
||||
EFI_INVALID_PARAMETER - Invalid parameter
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN BufferSize;
|
||||
|
||||
if (NumberHandles == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Buffer == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
BufferSize = 0;
|
||||
*NumberHandles = 0;
|
||||
*Buffer = NULL;
|
||||
Status = CoreLocateHandle (
|
||||
SearchType,
|
||||
Protocol,
|
||||
SearchKey,
|
||||
&BufferSize,
|
||||
*Buffer
|
||||
);
|
||||
//
|
||||
// LocateHandleBuffer() returns incorrect status code if SearchType is
|
||||
// invalid.
|
||||
//
|
||||
// Add code to correctly handle expected errors from CoreLocateHandle().
|
||||
//
|
||||
if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) {
|
||||
if (Status != EFI_INVALID_PARAMETER) {
|
||||
Status = EFI_NOT_FOUND;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
*Buffer = CoreAllocateBootServicesPool (BufferSize);
|
||||
if (*Buffer == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Status = CoreLocateHandle (
|
||||
SearchType,
|
||||
Protocol,
|
||||
SearchKey,
|
||||
&BufferSize,
|
||||
*Buffer
|
||||
);
|
||||
|
||||
*NumberHandles = BufferSize/sizeof(EFI_HANDLE);
|
||||
if (EFI_ERROR(Status)) {
|
||||
*NumberHandles = 0;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
379
MdeModulePkg/Core/Dxe/Image.h
Normal file
379
MdeModulePkg/Core/Dxe/Image.h
Normal file
@ -0,0 +1,379 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
Image.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#ifndef _IMAGE_H_
|
||||
#define _IMAGE_H_
|
||||
|
||||
|
||||
|
||||
#define LOADED_IMAGE_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32('l','d','r','i')
|
||||
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
EFI_HANDLE Handle; // Image handle
|
||||
UINTN Type; // Image type
|
||||
|
||||
BOOLEAN Started; // If entrypoint has been called
|
||||
|
||||
EFI_IMAGE_ENTRY_POINT EntryPoint; // The image's entry point
|
||||
EFI_LOADED_IMAGE_PROTOCOL Info; // loaded image protocol
|
||||
|
||||
EFI_PHYSICAL_ADDRESS ImageBasePage; // Location in memory
|
||||
UINTN NumberOfPages; // Number of pages
|
||||
|
||||
CHAR8 *FixupData; // Original fixup data
|
||||
|
||||
EFI_TPL Tpl; // Tpl of started image
|
||||
EFI_STATUS Status; // Status returned by started image
|
||||
|
||||
UINTN ExitDataSize; // Size of ExitData from started image
|
||||
VOID *ExitData; // Pointer to exit data from started image
|
||||
VOID *JumpBuffer; // Pointer to pool allocation for context save/retore
|
||||
BASE_LIBRARY_JUMP_BUFFER *JumpContext; // Pointer to buffer for context save/retore
|
||||
UINT16 Machine; // Machine type from PE image
|
||||
|
||||
EFI_EBC_PROTOCOL *Ebc; // EBC Protocol pointer
|
||||
|
||||
EFI_RUNTIME_IMAGE_ENTRY *RuntimeData; // Runtime image list
|
||||
|
||||
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; // PeCoffLoader ImageContext
|
||||
|
||||
} LOADED_IMAGE_PRIVATE_DATA;
|
||||
|
||||
#define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \
|
||||
CR(a, LOADED_IMAGE_PRIVATE_DATA, Info, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE)
|
||||
|
||||
|
||||
|
||||
#define LOAD_PE32_IMAGE_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32('l','p','e','i')
|
||||
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
EFI_HANDLE Handle; // Image handle
|
||||
EFI_PE32_IMAGE_PROTOCOL Pe32Image;
|
||||
} LOAD_PE32_IMAGE_PRIVATE_DATA;
|
||||
|
||||
#define LOAD_PE32_IMAGE_PRIVATE_DATA_FROM_THIS(a) \
|
||||
CR(a, LOAD_PE32_IMAGE_PRIVATE_DATA, Pe32Image, LOAD_PE32_IMAGE_PRIVATE_DATA_SIGNATURE)
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Private Data Types
|
||||
//
|
||||
#define IMAGE_FILE_HANDLE_SIGNATURE EFI_SIGNATURE_32('i','m','g','f')
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
BOOLEAN FreeBuffer;
|
||||
VOID *Source;
|
||||
UINTN SourceSize;
|
||||
} IMAGE_FILE_HANDLE;
|
||||
|
||||
|
||||
//
|
||||
// Abstractions for reading image contents
|
||||
//
|
||||
|
||||
EFI_STATUS
|
||||
CoreOpenImageFile (
|
||||
IN BOOLEAN BootPolicy,
|
||||
IN VOID *SourceBuffer OPTIONAL,
|
||||
IN UINTN SourceSize,
|
||||
IN OUT EFI_DEVICE_PATH_PROTOCOL *FilePath,
|
||||
OUT EFI_HANDLE *DeviceHandle,
|
||||
IN IMAGE_FILE_HANDLE *ImageFileHandle,
|
||||
OUT UINT32 *AuthenticationStatus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Opens a file for (simple) reading. The simple read abstraction
|
||||
will access the file either from a memory copy, from a file
|
||||
system interface, or from the load file interface.
|
||||
|
||||
Arguments:
|
||||
|
||||
BootPolicy - Policy for Open Image File.
|
||||
SourceBuffer - Pointer to the memory location containing copy
|
||||
of the image to be loaded.
|
||||
SourceSize - The size in bytes of SourceBuffer.
|
||||
FilePath - The specific file path from which the image is loaded
|
||||
DeviceHandle - Pointer to the return device handle.
|
||||
ImageFileHandle - Pointer to the image file handle.
|
||||
AuthenticationStatus - Pointer to a caller-allocated UINT32 in which the authentication status is returned.
|
||||
|
||||
Returns:
|
||||
|
||||
A handle to access the file
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreReadImageFile (
|
||||
IN VOID *UserHandle,
|
||||
IN UINTN Offset,
|
||||
IN OUT UINTN *ReadSize,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Read image file (specified by UserHandle) into user specified buffer with specified offset
|
||||
and length.
|
||||
|
||||
Arguments:
|
||||
|
||||
UserHandle - Image file handle
|
||||
|
||||
Offset - Offset to the source file
|
||||
|
||||
ReadSize - For input, pointer of size to read;
|
||||
For output, pointer of size actually read.
|
||||
|
||||
Buffer - Buffer to write into
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Successfully read the specified part of file into buffer.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
CoreCloseImageFile (
|
||||
IN IMAGE_FILE_HANDLE *ImageFileHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
A function out of date, should be removed.
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageFileHandle - Handle of the file to close
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
//
|
||||
// Image processing worker functions
|
||||
//
|
||||
EFI_STATUS
|
||||
CoreDevicePathToInterface (
|
||||
IN EFI_GUID *Protocol,
|
||||
IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
|
||||
OUT VOID **Interface,
|
||||
OUT EFI_HANDLE *Handle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Search a handle to a device on a specified device path that supports a specified protocol,
|
||||
interface of that protocol on that handle is another output.
|
||||
|
||||
Arguments:
|
||||
|
||||
Protocol - The protocol to search for
|
||||
|
||||
FilePath - The specified device path
|
||||
|
||||
Interface - Interface of the protocol on the handle
|
||||
|
||||
Handle - The handle to the device on the specified device path that supports the protocol.
|
||||
|
||||
Returns:
|
||||
|
||||
Status code.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
CoreLoadPeImage (
|
||||
IN VOID *Pe32Handle,
|
||||
IN LOADED_IMAGE_PRIVATE_DATA *Image,
|
||||
IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,
|
||||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,
|
||||
IN UINT32 Attribute
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Loads, relocates, and invokes a PE/COFF image
|
||||
|
||||
Arguments:
|
||||
|
||||
Pe32Handle - The handle of PE32 image
|
||||
Image - PE image to be loaded
|
||||
DstBuffer - The buffer to store the image
|
||||
EntryPoint - A pointer to the entry point
|
||||
Attribute - The bit mask of attributes to set for the load PE image
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The file was loaded, relocated, and invoked
|
||||
|
||||
EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file
|
||||
|
||||
EFI_INVALID_PARAMETER - Invalid parameter
|
||||
|
||||
EFI_BUFFER_TOO_SMALL - Buffer for image is too small
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
LOADED_IMAGE_PRIVATE_DATA *
|
||||
CoreLoadedImageInfo (
|
||||
IN EFI_HANDLE ImageHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
CoreUnloadAndCloseImage (
|
||||
IN LOADED_IMAGE_PRIVATE_DATA *Image,
|
||||
IN BOOLEAN FreePage
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Unloads EFI image from memory.
|
||||
|
||||
Arguments:
|
||||
|
||||
Image - EFI image
|
||||
FreePage - Free allocated pages
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
//
|
||||
// Exported Image functions
|
||||
//
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreLoadImageEx (
|
||||
IN EFI_PE32_IMAGE_PROTOCOL *This,
|
||||
IN EFI_HANDLE ParentImageHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
|
||||
IN VOID *SourceBuffer OPTIONAL,
|
||||
IN UINTN SourceSize,
|
||||
IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,
|
||||
OUT UINTN *NumberOfPages OPTIONAL,
|
||||
OUT EFI_HANDLE *ImageHandle,
|
||||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,
|
||||
IN UINT32 Attribute
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Loads an EFI image into memory and returns a handle to the image with extended parameters.
|
||||
|
||||
Arguments:
|
||||
|
||||
ParentImageHandle - The caller's image handle.
|
||||
FilePath - The specific file path from which the image is loaded.
|
||||
SourceBuffer - If not NULL, a pointer to the memory location containing a copy of
|
||||
the image to be loaded.
|
||||
SourceSize - The size in bytes of SourceBuffer.
|
||||
DstBuffer - The buffer to store the image.
|
||||
NumberOfPages - For input, specifies the space size of the image by caller if not NULL.
|
||||
For output, specifies the actual space size needed.
|
||||
ImageHandle - Image handle for output.
|
||||
EntryPoint - Image entry point for output.
|
||||
Attribute - The bit mask of attributes to set for the load PE image.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The image was loaded into memory.
|
||||
EFI_NOT_FOUND - The FilePath was not found.
|
||||
EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
|
||||
EFI_UNSUPPORTED - The image type is not supported, or the device path cannot be
|
||||
parsed to locate the proper protocol for loading the file.
|
||||
EFI_OUT_OF_RESOURCES - Image was not loaded due to insufficient resources.
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreUnloadImageEx (
|
||||
IN EFI_PE32_IMAGE_PROTOCOL *This,
|
||||
IN EFI_HANDLE ImageHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Unload the specified image.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - Indicates the calling context.
|
||||
|
||||
ImageHandle - The specified image handle.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_INVALID_PARAMETER - Image handle is NULL.
|
||||
|
||||
EFI_UNSUPPORTED - Attempt to unload an unsupported image.
|
||||
|
||||
EFI_SUCCESS - Image successfully unloaded.
|
||||
|
||||
--*/
|
||||
;
|
||||
#endif
|
1390
MdeModulePkg/Core/Dxe/Image/Image.c
Normal file
1390
MdeModulePkg/Core/Dxe/Image/Image.c
Normal file
File diff suppressed because it is too large
Load Diff
499
MdeModulePkg/Core/Dxe/Image/ImageFile.c
Normal file
499
MdeModulePkg/Core/Dxe/Image/ImageFile.c
Normal file
@ -0,0 +1,499 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
ImageFile.c
|
||||
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
EFI_STATUS
|
||||
CoreOpenImageFile (
|
||||
IN BOOLEAN BootPolicy,
|
||||
IN VOID *SourceBuffer OPTIONAL,
|
||||
IN UINTN SourceSize,
|
||||
IN OUT EFI_DEVICE_PATH_PROTOCOL *FilePath,
|
||||
OUT EFI_HANDLE *DeviceHandle,
|
||||
IN IMAGE_FILE_HANDLE *ImageFileHandle,
|
||||
OUT UINT32 *AuthenticationStatus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Opens a file for (simple) reading. The simple read abstraction
|
||||
will access the file either from a memory copy, from a file
|
||||
system interface, or from the load file interface.
|
||||
|
||||
Arguments:
|
||||
|
||||
BootPolicy - Policy for Open Image File.
|
||||
SourceBuffer - Pointer to the memory location containing copy
|
||||
of the image to be loaded.
|
||||
SourceSize - The size in bytes of SourceBuffer.
|
||||
FilePath - The specific file path from which the image is loaded
|
||||
DeviceHandle - Pointer to the return device handle.
|
||||
ImageFileHandle - Pointer to the image file handle.
|
||||
AuthenticationStatus - Pointer to a caller-allocated UINT32 in which the authentication status is returned.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Image file successfully opened.
|
||||
|
||||
EFI_LOAD_ERROR - If the caller passed a copy of the file, and SourceSize is 0.
|
||||
|
||||
EFI_INVALID_PARAMETER - File path is not valid.
|
||||
|
||||
EFI_NOT_FOUND - File not found.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_DEVICE_PATH_PROTOCOL *TempFilePath;
|
||||
FILEPATH_DEVICE_PATH *FilePathNode;
|
||||
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FwVolFilePathNode;
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
|
||||
EFI_FILE_HANDLE FileHandle;
|
||||
EFI_FILE_HANDLE LastHandle;
|
||||
EFI_LOAD_FILE_PROTOCOL *LoadFile;
|
||||
EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol;
|
||||
EFI_SECTION_TYPE SectionType;
|
||||
UINT8 *Pe32Buffer;
|
||||
UINTN Pe32BufferSize;
|
||||
EFI_FV_FILETYPE Type;
|
||||
EFI_FV_FILE_ATTRIBUTES Attrib;
|
||||
EFI_FILE_INFO *FileInfo;
|
||||
UINTN FileInfoSize;
|
||||
EFI_GUID *NameGuid;
|
||||
|
||||
*AuthenticationStatus = 0;
|
||||
ZeroMem (ImageFileHandle, sizeof (IMAGE_FILE_HANDLE));
|
||||
ImageFileHandle->Signature = IMAGE_FILE_HANDLE_SIGNATURE;
|
||||
|
||||
//
|
||||
// If the caller passed a copy of the file, then just use it
|
||||
//
|
||||
if (SourceBuffer != NULL) {
|
||||
ImageFileHandle->Source = SourceBuffer;
|
||||
ImageFileHandle->SourceSize = SourceSize;
|
||||
*DeviceHandle = NULL;
|
||||
if (SourceSize > 0) {
|
||||
Status = EFI_SUCCESS;
|
||||
} else {
|
||||
Status = EFI_LOAD_ERROR;
|
||||
}
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure FilePath is valid
|
||||
//
|
||||
if (FilePath == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Check to see if it's in a Firmware Volume
|
||||
//
|
||||
FwVolFilePathNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)FilePath;
|
||||
Status = CoreDevicePathToInterface (
|
||||
&gEfiFirmwareVolumeProtocolGuid,
|
||||
(EFI_DEVICE_PATH_PROTOCOL **)&FwVolFilePathNode,
|
||||
(VOID*)&FwVol,
|
||||
DeviceHandle
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// For FwVol File system there is only a single file name that is a GUID.
|
||||
//
|
||||
NameGuid = EfiGetNameGuidFromFwVolDevicePathNode (FwVolFilePathNode);
|
||||
if (NameGuid != NULL) {
|
||||
|
||||
SectionType = EFI_SECTION_PE32;
|
||||
Pe32Buffer = NULL;
|
||||
Status = FwVol->ReadSection (
|
||||
FwVol,
|
||||
NameGuid,
|
||||
SectionType,
|
||||
0,
|
||||
(VOID **)&Pe32Buffer,
|
||||
&Pe32BufferSize,
|
||||
AuthenticationStatus
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Try a raw file, since a PE32 SECTION does not exist
|
||||
//
|
||||
if (Pe32Buffer != NULL) {
|
||||
CoreFreePool (Pe32Buffer);
|
||||
*AuthenticationStatus = 0;
|
||||
}
|
||||
Pe32Buffer = NULL;
|
||||
Status = FwVol->ReadFile (
|
||||
FwVol,
|
||||
NameGuid,
|
||||
(VOID **)&Pe32Buffer,
|
||||
&Pe32BufferSize,
|
||||
&Type,
|
||||
&Attrib,
|
||||
AuthenticationStatus
|
||||
);
|
||||
}
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// One of the reads passed so we are done
|
||||
//
|
||||
ImageFileHandle->Source = Pe32Buffer;
|
||||
ImageFileHandle->SourceSize = Pe32BufferSize;
|
||||
ImageFileHandle->FreeBuffer = TRUE;
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Attempt to access the file via a file system interface
|
||||
//
|
||||
FilePathNode = (FILEPATH_DEVICE_PATH *) FilePath;
|
||||
Status = CoreDevicePathToInterface (
|
||||
&gEfiSimpleFileSystemProtocolGuid,
|
||||
(EFI_DEVICE_PATH_PROTOCOL **)&FilePathNode,
|
||||
(VOID*)&Volume,
|
||||
DeviceHandle
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Open the Volume to get the File System handle
|
||||
//
|
||||
Status = Volume->OpenVolume (Volume, &FileHandle);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
|
||||
//
|
||||
// Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the
|
||||
// directory information and filename can be seperate. The goal is to inch
|
||||
// our way down each device path node and close the previous node
|
||||
//
|
||||
while (!IsDevicePathEnd (&FilePathNode->Header)) {
|
||||
if (DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH ||
|
||||
DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP) {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Exit loop on Error
|
||||
//
|
||||
break;
|
||||
}
|
||||
|
||||
LastHandle = FileHandle;
|
||||
FileHandle = NULL;
|
||||
Status = LastHandle->Open (
|
||||
LastHandle,
|
||||
&FileHandle,
|
||||
FilePathNode->PathName,
|
||||
EFI_FILE_MODE_READ,
|
||||
0
|
||||
);
|
||||
|
||||
//
|
||||
// Close the previous node
|
||||
//
|
||||
LastHandle->Close (LastHandle);
|
||||
|
||||
FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header);
|
||||
}
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// We have found the file. Now we need to read it. Before we can read the file we need to
|
||||
// figure out how big the file is.
|
||||
//
|
||||
FileInfo = NULL;
|
||||
FileInfoSize = sizeof (EFI_FILE_INFO);
|
||||
while (CoreGrowBuffer (&Status, (VOID **)&FileInfo, FileInfoSize)) {
|
||||
//
|
||||
// Automatically allocate buffer of the correct size and make the call
|
||||
//
|
||||
Status = FileHandle->GetInfo (
|
||||
FileHandle,
|
||||
&gEfiFileInfoGuid,
|
||||
&FileInfoSize,
|
||||
FileInfo
|
||||
);
|
||||
}
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Allocate space for the file
|
||||
//
|
||||
ImageFileHandle->Source = CoreAllocateBootServicesPool ((UINTN)FileInfo->FileSize);
|
||||
if (ImageFileHandle->Source != NULL) {
|
||||
//
|
||||
// Read the file into the buffer we allocated
|
||||
//
|
||||
ImageFileHandle->SourceSize = (UINTN)FileInfo->FileSize;
|
||||
ImageFileHandle->FreeBuffer = TRUE;
|
||||
Status = FileHandle->Read (FileHandle, &ImageFileHandle->SourceSize, ImageFileHandle->Source);
|
||||
|
||||
//
|
||||
// Close the file since we are done
|
||||
//
|
||||
FileHandle->Close (FileHandle);
|
||||
} else {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Try LoadFile style
|
||||
//
|
||||
|
||||
TempFilePath = FilePath;
|
||||
Status = CoreDevicePathToInterface (
|
||||
&gEfiLoadFileProtocolGuid,
|
||||
&TempFilePath,
|
||||
(VOID*)&LoadFile,
|
||||
DeviceHandle
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Call LoadFile with the correct buffer size
|
||||
//
|
||||
while (CoreGrowBuffer (&Status, (VOID **)&ImageFileHandle->Source, ImageFileHandle->SourceSize)) {
|
||||
Status = LoadFile->LoadFile (
|
||||
LoadFile,
|
||||
TempFilePath,
|
||||
BootPolicy,
|
||||
&ImageFileHandle->SourceSize,
|
||||
ImageFileHandle->Source
|
||||
);
|
||||
//
|
||||
// If success or other error happens, stop loop
|
||||
//
|
||||
if (Status != EFI_BUFFER_TOO_SMALL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!EFI_ERROR (Status) || Status == EFI_ALREADY_STARTED) {
|
||||
ImageFileHandle->FreeBuffer = TRUE;
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Nothing else to try
|
||||
//
|
||||
DEBUG ((EFI_D_LOAD|EFI_D_WARN, "CoreOpenImageFile: Device did not support a known load protocol\n"));
|
||||
Status = EFI_NOT_FOUND;
|
||||
|
||||
Done:
|
||||
|
||||
//
|
||||
// If the file was not accessed, clean up
|
||||
//
|
||||
if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
|
||||
if (ImageFileHandle->FreeBuffer) {
|
||||
//
|
||||
// Free the source buffer if we allocated it
|
||||
//
|
||||
CoreFreePool (ImageFileHandle->Source);
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreReadImageFile (
|
||||
IN VOID *UserHandle,
|
||||
IN UINTN Offset,
|
||||
IN OUT UINTN *ReadSize,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Read image file (specified by UserHandle) into user specified buffer with specified offset
|
||||
and length.
|
||||
|
||||
Arguments:
|
||||
|
||||
UserHandle - Image file handle
|
||||
|
||||
Offset - Offset to the source file
|
||||
|
||||
ReadSize - For input, pointer of size to read;
|
||||
For output, pointer of size actually read.
|
||||
|
||||
Buffer - Buffer to write into
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Successfully read the specified part of file into buffer.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN EndPosition;
|
||||
IMAGE_FILE_HANDLE *FHand;
|
||||
|
||||
FHand = (IMAGE_FILE_HANDLE *)UserHandle;
|
||||
ASSERT (FHand->Signature == IMAGE_FILE_HANDLE_SIGNATURE);
|
||||
|
||||
//
|
||||
// Move data from our local copy of the file
|
||||
//
|
||||
EndPosition = Offset + *ReadSize;
|
||||
if (EndPosition > FHand->SourceSize) {
|
||||
*ReadSize = (UINT32)(FHand->SourceSize - Offset);
|
||||
}
|
||||
if (Offset >= FHand->SourceSize) {
|
||||
*ReadSize = 0;
|
||||
}
|
||||
|
||||
CopyMem (Buffer, (CHAR8 *)FHand->Source + Offset, *ReadSize);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
CoreDevicePathToInterface (
|
||||
IN EFI_GUID *Protocol,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL **FilePath,
|
||||
OUT VOID **Interface,
|
||||
OUT EFI_HANDLE *Handle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Search a handle to a device on a specified device path that supports a specified protocol,
|
||||
interface of that protocol on that handle is another output.
|
||||
|
||||
Arguments:
|
||||
|
||||
Protocol - The protocol to search for
|
||||
|
||||
FilePath - The specified device path
|
||||
|
||||
Interface - Interface of the protocol on the handle
|
||||
|
||||
Handle - The handle to the device on the specified device path that supports the protocol.
|
||||
|
||||
Returns:
|
||||
|
||||
Status code.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = CoreLocateDevicePath (Protocol, FilePath, Handle);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = CoreHandleProtocol (*Handle, Protocol, Interface);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
CoreGrowBuffer (
|
||||
IN OUT EFI_STATUS *Status,
|
||||
IN OUT VOID **Buffer,
|
||||
IN UINTN BufferSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Helper function called as part of the code needed
|
||||
to allocate the proper sized buffer for various
|
||||
EFI interfaces.
|
||||
|
||||
Arguments:
|
||||
|
||||
Status - Current status
|
||||
|
||||
Buffer - Current allocated buffer, or NULL
|
||||
|
||||
BufferSize - Current buffer size needed
|
||||
|
||||
Returns:
|
||||
|
||||
TRUE - if the buffer was reallocated and the caller
|
||||
should try the API again.
|
||||
|
||||
FALSE - buffer could not be allocated and the caller
|
||||
should not try the API again.
|
||||
|
||||
--*/
|
||||
{
|
||||
BOOLEAN TryAgain;
|
||||
|
||||
TryAgain = FALSE;
|
||||
//
|
||||
// If this is an initial request, buffer will be null with a new buffer size
|
||||
//
|
||||
if (*Buffer == NULL) {
|
||||
*Status = EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (BufferSize == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// If the status code is "buffer too small", resize the buffer
|
||||
//
|
||||
|
||||
if (*Status == EFI_BUFFER_TOO_SMALL) {
|
||||
if (*Buffer != NULL) {
|
||||
CoreFreePool (*Buffer);
|
||||
}
|
||||
|
||||
*Buffer = CoreAllocateBootServicesPool (BufferSize);
|
||||
if (*Buffer != NULL) {
|
||||
TryAgain = TRUE;
|
||||
} else {
|
||||
*Status = EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// If there's an error, free the buffer
|
||||
//
|
||||
if ((!TryAgain) && (EFI_ERROR (*Status)) && (*Buffer)) {
|
||||
CoreFreePool (*Buffer);
|
||||
*Buffer = NULL;
|
||||
}
|
||||
|
||||
return TryAgain;
|
||||
}
|
||||
|
407
MdeModulePkg/Core/Dxe/Library.h
Normal file
407
MdeModulePkg/Core/Dxe/Library.h
Normal file
@ -0,0 +1,407 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
Library.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _DXE_LIBRARY_H_
|
||||
#define _DXE_LIBRARY_H_
|
||||
|
||||
|
||||
VOID
|
||||
CoreReportProgressCode (
|
||||
IN EFI_STATUS_CODE_VALUE Value
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Report status code of type EFI_PROGRESS_CODE by caller ID gEfiDxeServicesTableGuid.
|
||||
|
||||
Arguments:
|
||||
|
||||
Value - Describes the class/subclass/operation of the hardware or software entity
|
||||
that the Status Code relates to.
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
CoreReportProgressCodeSpecific (
|
||||
IN EFI_STATUS_CODE_VALUE Value,
|
||||
IN EFI_HANDLE Handle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Report status code of type EFI_PROGRESS_CODE by caller ID gEfiDxeServicesTableGuid,
|
||||
with a handle as additional information.
|
||||
|
||||
Arguments:
|
||||
|
||||
Value - Describes the class/subclass/operation of the hardware or software entity
|
||||
that the Status Code relates to.
|
||||
|
||||
Handle - Additional information.
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
CoreAcquireLock (
|
||||
IN EFI_LOCK *Lock
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Raising to the task priority level of the mutual exclusion
|
||||
lock, and then acquires ownership of the lock.
|
||||
|
||||
Arguments:
|
||||
|
||||
Lock - The lock to acquire
|
||||
|
||||
Returns:
|
||||
|
||||
Lock owned
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
CoreAcquireLockOrFail (
|
||||
IN EFI_LOCK *Lock
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Initialize a basic mutual exclusion lock. Each lock
|
||||
provides mutual exclusion access at it's task priority
|
||||
level. Since there is no-premption (at any TPL) or
|
||||
multiprocessor support, acquiring the lock only consists
|
||||
of raising to the locks TPL.
|
||||
|
||||
Arguments:
|
||||
|
||||
Lock - The EFI_LOCK structure to initialize
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Lock Owned.
|
||||
EFI_ACCESS_DENIED - Reentrant Lock Acquisition, Lock not Owned.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
CoreReleaseLock (
|
||||
IN EFI_LOCK *Lock
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Releases ownership of the mutual exclusion lock, and
|
||||
restores the previous task priority level.
|
||||
|
||||
Arguments:
|
||||
|
||||
Lock - The lock to release
|
||||
|
||||
Returns:
|
||||
|
||||
Lock unowned
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
//
|
||||
// Device Path functions
|
||||
//
|
||||
|
||||
UINTN
|
||||
CoreDevicePathSize (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Calculate the size of a whole device path.
|
||||
|
||||
Arguments:
|
||||
|
||||
DevicePath - The pointer to the device path data.
|
||||
|
||||
Returns:
|
||||
|
||||
Size of device path data structure..
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
BOOLEAN
|
||||
CoreIsDevicePathMultiInstance (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Return TRUE is this is a multi instance device path.
|
||||
|
||||
Arguments:
|
||||
DevicePath - A pointer to a device path data structure.
|
||||
|
||||
|
||||
Returns:
|
||||
TRUE - If DevicePath is multi instance. FALSE - If DevicePath is not multi
|
||||
instance.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
EFI_DEVICE_PATH_PROTOCOL *
|
||||
CoreDuplicateDevicePath (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Duplicate a new device path data structure from the old one.
|
||||
|
||||
Arguments:
|
||||
DevicePath - A pointer to a device path data structure.
|
||||
|
||||
Returns:
|
||||
A pointer to the new allocated device path data.
|
||||
Caller must free the memory used by DevicePath if it is no longer needed.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_DEVICE_PATH_PROTOCOL *
|
||||
CoreAppendDevicePath (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *Src1,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *Node
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Function is used to append a Src1 and Src2 together.
|
||||
|
||||
Arguments:
|
||||
Src1 - A pointer to a device path data structure.
|
||||
|
||||
Node - A pointer to a device path data structure.
|
||||
|
||||
Returns:
|
||||
|
||||
A pointer to the new device path is returned.
|
||||
NULL is returned if space for the new device path could not be allocated from pool.
|
||||
It is up to the caller to free the memory used by Src1 and Src2 if they are no longer needed.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID *
|
||||
CoreAllocateBootServicesPool (
|
||||
IN UINTN AllocationSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Allocate pool of type EfiBootServicesData, the size is specified with AllocationSize.
|
||||
|
||||
Arguments:
|
||||
|
||||
AllocationSize - Size to allocate.
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer of the allocated pool.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID *
|
||||
CoreAllocateZeroBootServicesPool (
|
||||
IN UINTN AllocationSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Allocate pool of type EfiBootServicesData and zero it, the size is specified with AllocationSize.
|
||||
|
||||
Arguments:
|
||||
|
||||
AllocationSize - Size to allocate.
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer of the allocated pool.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
CoreGetConfigTable (
|
||||
IN EFI_GUID *Guid,
|
||||
IN OUT VOID **Table
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Find a config table by name in system table's ConfigurationTable.
|
||||
|
||||
Arguments:
|
||||
|
||||
Guid - The table name to look for
|
||||
|
||||
Table - Pointer of the config table
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_NOT_FOUND - Could not find the table in system table's ConfigurationTable.
|
||||
|
||||
EFI_SUCCESS - Table successfully found.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID *
|
||||
CoreAllocateRuntimeCopyPool (
|
||||
IN UINTN AllocationSize,
|
||||
IN VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Allocate pool of specified size with EfiRuntimeServicesData type, and copy specified buffer to this pool.
|
||||
|
||||
Arguments:
|
||||
|
||||
AllocationSize - Size to allocate.
|
||||
|
||||
Buffer - Specified buffer that will be copy to the allocated pool
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer of the allocated pool.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID *
|
||||
CoreAllocateRuntimePool (
|
||||
IN UINTN AllocationSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Allocate pool of type EfiRuntimeServicesData, the size is specified with AllocationSize.
|
||||
|
||||
Arguments:
|
||||
|
||||
AllocationSize - Size to allocate.
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer of the allocated pool.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID *
|
||||
CoreAllocateCopyPool (
|
||||
IN UINTN AllocationSize,
|
||||
IN VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Allocate pool of specified size with EfiBootServicesData type, and copy specified buffer to this pool.
|
||||
|
||||
Arguments:
|
||||
|
||||
AllocationSize - Size to allocate.
|
||||
|
||||
Buffer - Specified buffer that will be copy to the allocated pool
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer of the allocated pool.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_EVENT
|
||||
CoreCreateProtocolNotifyEvent (
|
||||
IN EFI_GUID *ProtocolGuid,
|
||||
IN EFI_TPL NotifyTpl,
|
||||
IN EFI_EVENT_NOTIFY NotifyFunction,
|
||||
IN VOID *NotifyContext,
|
||||
OUT VOID **Registration,
|
||||
IN BOOLEAN SignalFlag
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Create a protocol notification event and return it.
|
||||
|
||||
Arguments:
|
||||
|
||||
ProtocolGuid - Protocol to register notification event on.
|
||||
|
||||
NotifyTpl - Maximum TPL to signal the NotifyFunction.
|
||||
|
||||
NotifyFuncition - EFI notification routine.
|
||||
|
||||
NotifyContext - Context passed into Event when it is created.
|
||||
|
||||
Registration - Registration key returned from RegisterProtocolNotify().
|
||||
|
||||
SignalFlag - Boolean value to decide whether kick the event after register or not.
|
||||
|
||||
Returns:
|
||||
|
||||
The EFI_EVENT that has been registered to be signaled when a ProtocolGuid
|
||||
is added to the system.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
#endif
|
613
MdeModulePkg/Core/Dxe/Library/Library.c
Normal file
613
MdeModulePkg/Core/Dxe/Library/Library.c
Normal file
@ -0,0 +1,613 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
Library.c
|
||||
|
||||
Abstract:
|
||||
|
||||
DXE Core library services.
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
UINTN mErrorLevel = EFI_D_ERROR | EFI_D_LOAD;
|
||||
|
||||
EFI_DEVICE_HANDLE_EXTENDED_DATA mStatusCodeData = {
|
||||
{
|
||||
sizeof (EFI_STATUS_CODE_DATA),
|
||||
0,
|
||||
EFI_STATUS_CODE_SPECIFIC_DATA_GUID
|
||||
},
|
||||
NULL
|
||||
};
|
||||
|
||||
VOID
|
||||
CoreReportProgressCodeSpecific (
|
||||
IN EFI_STATUS_CODE_VALUE Value,
|
||||
IN EFI_HANDLE Handle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Report status code of type EFI_PROGRESS_CODE by caller ID gEfiDxeServicesTableGuid,
|
||||
with a handle as additional information.
|
||||
|
||||
Arguments:
|
||||
|
||||
Value - Describes the class/subclass/operation of the hardware or software entity
|
||||
that the Status Code relates to.
|
||||
|
||||
Handle - Additional information.
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
mStatusCodeData.DataHeader.Size = sizeof (EFI_DEVICE_HANDLE_EXTENDED_DATA) - sizeof (EFI_STATUS_CODE_DATA);
|
||||
mStatusCodeData.Handle = Handle;
|
||||
|
||||
if ((gStatusCode != NULL) && (gStatusCode->ReportStatusCode != NULL) ) {
|
||||
gStatusCode->ReportStatusCode (
|
||||
EFI_PROGRESS_CODE,
|
||||
Value,
|
||||
0,
|
||||
&gEfiDxeServicesTableGuid,
|
||||
(EFI_STATUS_CODE_DATA *) &mStatusCodeData
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
CoreReportProgressCode (
|
||||
IN EFI_STATUS_CODE_VALUE Value
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Report status code of type EFI_PROGRESS_CODE by caller ID gEfiDxeServicesTableGuid.
|
||||
|
||||
Arguments:
|
||||
|
||||
Value - Describes the class/subclass/operation of the hardware or software entity
|
||||
that the Status Code relates to.
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
if ((gStatusCode != NULL) && (gStatusCode->ReportStatusCode != NULL) ) {
|
||||
gStatusCode->ReportStatusCode (
|
||||
EFI_PROGRESS_CODE,
|
||||
Value,
|
||||
0,
|
||||
&gEfiDxeServicesTableGuid,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID *
|
||||
CoreAllocateBootServicesPool (
|
||||
IN UINTN AllocationSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Allocate pool of type EfiBootServicesData, the size is specified with AllocationSize.
|
||||
|
||||
Arguments:
|
||||
|
||||
AllocationSize - Size to allocate.
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer of the allocated pool.
|
||||
|
||||
--*/
|
||||
{
|
||||
VOID *Memory;
|
||||
|
||||
CoreAllocatePool (EfiBootServicesData, AllocationSize, &Memory);
|
||||
return Memory;
|
||||
}
|
||||
|
||||
|
||||
VOID *
|
||||
CoreAllocateZeroBootServicesPool (
|
||||
IN UINTN AllocationSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Allocate pool of type EfiBootServicesData and zero it, the size is specified with AllocationSize.
|
||||
|
||||
Arguments:
|
||||
|
||||
AllocationSize - Size to allocate.
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer of the allocated pool.
|
||||
|
||||
--*/
|
||||
{
|
||||
VOID *Memory;
|
||||
|
||||
Memory = CoreAllocateBootServicesPool (AllocationSize);
|
||||
SetMem (Memory, (Memory == NULL) ? 0 : AllocationSize, 0);
|
||||
return Memory;
|
||||
}
|
||||
|
||||
|
||||
VOID *
|
||||
CoreAllocateCopyPool (
|
||||
IN UINTN AllocationSize,
|
||||
IN VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Allocate pool of specified size with EfiBootServicesData type, and copy specified buffer to this pool.
|
||||
|
||||
Arguments:
|
||||
|
||||
AllocationSize - Size to allocate.
|
||||
|
||||
Buffer - Specified buffer that will be copy to the allocated pool
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer of the allocated pool.
|
||||
|
||||
--*/
|
||||
{
|
||||
VOID *Memory;
|
||||
|
||||
Memory = CoreAllocateBootServicesPool (AllocationSize);
|
||||
CopyMem (Memory, Buffer, (Memory == NULL) ? 0 : AllocationSize);
|
||||
|
||||
return Memory;
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID *
|
||||
CoreAllocateRuntimePool (
|
||||
IN UINTN AllocationSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Allocate pool of type EfiRuntimeServicesData, the size is specified with AllocationSize.
|
||||
|
||||
Arguments:
|
||||
|
||||
AllocationSize - Size to allocate.
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer of the allocated pool.
|
||||
|
||||
--*/
|
||||
{
|
||||
VOID *Memory;
|
||||
|
||||
CoreAllocatePool (EfiRuntimeServicesData, AllocationSize, &Memory);
|
||||
return Memory;
|
||||
}
|
||||
|
||||
VOID *
|
||||
CoreAllocateRuntimeCopyPool (
|
||||
IN UINTN AllocationSize,
|
||||
IN VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Allocate pool of specified size with EfiRuntimeServicesData type, and copy specified buffer to this pool.
|
||||
|
||||
Arguments:
|
||||
|
||||
AllocationSize - Size to allocate.
|
||||
|
||||
Buffer - Specified buffer that will be copy to the allocated pool
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer of the allocated pool.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
VOID *Memory;
|
||||
|
||||
Memory = CoreAllocateRuntimePool (AllocationSize);
|
||||
CopyMem (Memory, Buffer, (Memory == NULL) ? 0 : AllocationSize);
|
||||
|
||||
return Memory;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Lock Stuff
|
||||
//
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
CoreAcquireLockOrFail (
|
||||
IN EFI_LOCK *Lock
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Initialize a basic mutual exclusion lock. Each lock
|
||||
provides mutual exclusion access at it's task priority
|
||||
level. Since there is no-premption (at any TPL) or
|
||||
multiprocessor support, acquiring the lock only consists
|
||||
of raising to the locks TPL.
|
||||
|
||||
Arguments:
|
||||
|
||||
Lock - The EFI_LOCK structure to initialize
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Lock Owned.
|
||||
EFI_ACCESS_DENIED - Reentrant Lock Acquisition, Lock not Owned.
|
||||
|
||||
--*/
|
||||
{
|
||||
ASSERT (Lock != NULL);
|
||||
ASSERT (Lock->Lock != EfiLockUninitialized);
|
||||
|
||||
if (Lock->Lock == EfiLockAcquired) {
|
||||
//
|
||||
// Lock is already owned, so bail out
|
||||
//
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
Lock->OwnerTpl = CoreRaiseTpl (Lock->Tpl);
|
||||
|
||||
Lock->Lock = EfiLockAcquired;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CoreAcquireLock (
|
||||
IN EFI_LOCK *Lock
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Raising to the task priority level of the mutual exclusion
|
||||
lock, and then acquires ownership of the lock.
|
||||
|
||||
Arguments:
|
||||
|
||||
Lock - The lock to acquire
|
||||
|
||||
Returns:
|
||||
|
||||
Lock owned
|
||||
|
||||
--*/
|
||||
{
|
||||
ASSERT (Lock != NULL);
|
||||
ASSERT (Lock->Lock == EfiLockReleased);
|
||||
|
||||
Lock->OwnerTpl = CoreRaiseTpl (Lock->Tpl);
|
||||
Lock->Lock = EfiLockAcquired;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CoreReleaseLock (
|
||||
IN EFI_LOCK *Lock
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Releases ownership of the mutual exclusion lock, and
|
||||
restores the previous task priority level.
|
||||
|
||||
Arguments:
|
||||
|
||||
Lock - The lock to release
|
||||
|
||||
Returns:
|
||||
|
||||
Lock unowned
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_TPL Tpl;
|
||||
|
||||
ASSERT (Lock != NULL);
|
||||
ASSERT (Lock->Lock == EfiLockAcquired);
|
||||
|
||||
Tpl = Lock->OwnerTpl;
|
||||
|
||||
Lock->Lock = EfiLockReleased;
|
||||
|
||||
CoreRestoreTpl (Tpl);
|
||||
}
|
||||
|
||||
|
||||
UINTN
|
||||
CoreDevicePathSize (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Calculate the size of a whole device path.
|
||||
|
||||
Arguments:
|
||||
|
||||
DevicePath - The pointer to the device path data.
|
||||
|
||||
Returns:
|
||||
|
||||
Size of device path data structure..
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_DEVICE_PATH_PROTOCOL *Start;
|
||||
|
||||
if (DevicePath == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Search for the end of the device path structure
|
||||
//
|
||||
Start = DevicePath;
|
||||
while (!EfiIsDevicePathEnd (DevicePath)) {
|
||||
DevicePath = EfiNextDevicePathNode (DevicePath);
|
||||
}
|
||||
|
||||
//
|
||||
// Compute the size and add back in the size of the end device path structure
|
||||
//
|
||||
return ((UINTN)DevicePath - (UINTN)Start) + sizeof(EFI_DEVICE_PATH_PROTOCOL);
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
CoreIsDevicePathMultiInstance (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Return TRUE is this is a multi instance device path.
|
||||
|
||||
Arguments:
|
||||
DevicePath - A pointer to a device path data structure.
|
||||
|
||||
|
||||
Returns:
|
||||
TRUE - If DevicePath is multi instance. FALSE - If DevicePath is not multi
|
||||
instance.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_DEVICE_PATH_PROTOCOL *Node;
|
||||
|
||||
if (DevicePath == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Node = DevicePath;
|
||||
while (!EfiIsDevicePathEnd (Node)) {
|
||||
if (EfiIsDevicePathEndInstance (Node)) {
|
||||
return TRUE;
|
||||
}
|
||||
Node = EfiNextDevicePathNode (Node);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_DEVICE_PATH_PROTOCOL *
|
||||
CoreDuplicateDevicePath (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Duplicate a new device path data structure from the old one.
|
||||
|
||||
Arguments:
|
||||
DevicePath - A pointer to a device path data structure.
|
||||
|
||||
Returns:
|
||||
A pointer to the new allocated device path data.
|
||||
Caller must free the memory used by DevicePath if it is no longer needed.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
|
||||
UINTN Size;
|
||||
|
||||
if (DevicePath == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Compute the size
|
||||
//
|
||||
Size = CoreDevicePathSize (DevicePath);
|
||||
|
||||
//
|
||||
// Allocate space for duplicate device path
|
||||
//
|
||||
NewDevicePath = CoreAllocateCopyPool (Size, DevicePath);
|
||||
|
||||
return NewDevicePath;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_DEVICE_PATH_PROTOCOL *
|
||||
CoreAppendDevicePath (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *Src1,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *Src2
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Function is used to append a Src1 and Src2 together.
|
||||
|
||||
Arguments:
|
||||
Src1 - A pointer to a device path data structure.
|
||||
|
||||
Src2 - A pointer to a device path data structure.
|
||||
|
||||
Returns:
|
||||
|
||||
A pointer to the new device path is returned.
|
||||
NULL is returned if space for the new device path could not be allocated from pool.
|
||||
It is up to the caller to free the memory used by Src1 and Src2 if they are no longer needed.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN Size;
|
||||
UINTN Size1;
|
||||
UINTN Size2;
|
||||
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
|
||||
EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath;
|
||||
|
||||
if (Src1 == NULL && Src2 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate space for the combined device path. It only has one end node of
|
||||
// length EFI_DEVICE_PATH_PROTOCOL
|
||||
//
|
||||
Size1 = CoreDevicePathSize (Src1);
|
||||
Size2 = CoreDevicePathSize (Src2);
|
||||
Size = Size1 + Size2 - sizeof(EFI_DEVICE_PATH_PROTOCOL);
|
||||
|
||||
NewDevicePath = CoreAllocateCopyPool (Size, Src1);
|
||||
if (NewDevicePath != NULL) {
|
||||
|
||||
//
|
||||
// Over write Src1 EndNode and do the copy
|
||||
//
|
||||
SecondDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)((CHAR8 *)NewDevicePath + (Size1 - sizeof(EFI_DEVICE_PATH_PROTOCOL)));
|
||||
CopyMem (SecondDevicePath, Src2, Size2);
|
||||
}
|
||||
|
||||
return NewDevicePath;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_EVENT
|
||||
CoreCreateProtocolNotifyEvent (
|
||||
IN EFI_GUID *ProtocolGuid,
|
||||
IN EFI_TPL NotifyTpl,
|
||||
IN EFI_EVENT_NOTIFY NotifyFunction,
|
||||
IN VOID *NotifyContext,
|
||||
OUT VOID **Registration,
|
||||
IN BOOLEAN SignalFlag
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Create a protocol notification event and return it.
|
||||
|
||||
Arguments:
|
||||
|
||||
ProtocolGuid - Protocol to register notification event on.
|
||||
|
||||
NotifyTpl - Maximum TPL to signal the NotifyFunction.
|
||||
|
||||
NotifyFuncition - EFI notification routine.
|
||||
|
||||
NotifyContext - Context passed into Event when it is created.
|
||||
|
||||
Registration - Registration key returned from RegisterProtocolNotify().
|
||||
|
||||
SignalFlag - Boolean value to decide whether kick the event after register or not.
|
||||
|
||||
Returns:
|
||||
|
||||
The EFI_EVENT that has been registered to be signaled when a ProtocolGuid
|
||||
is added to the system.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_EVENT Event;
|
||||
|
||||
//
|
||||
// Create the event
|
||||
//
|
||||
|
||||
Status = CoreCreateEvent (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
NotifyTpl,
|
||||
NotifyFunction,
|
||||
NotifyContext,
|
||||
&Event
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Register for protocol notifactions on this event
|
||||
//
|
||||
|
||||
Status = CoreRegisterProtocolNotify (
|
||||
ProtocolGuid,
|
||||
Event,
|
||||
Registration
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
if (SignalFlag) {
|
||||
//
|
||||
// Kick the event so we will perform an initial pass of
|
||||
// current installed drivers
|
||||
//
|
||||
CoreSignalEvent (Event);
|
||||
}
|
||||
|
||||
return Event;
|
||||
}
|
||||
|
1656
MdeModulePkg/Core/Dxe/Mem/Page.c
Normal file
1656
MdeModulePkg/Core/Dxe/Mem/Page.c
Normal file
File diff suppressed because it is too large
Load Diff
41
MdeModulePkg/Core/Dxe/Mem/memdata.c
Normal file
41
MdeModulePkg/Core/Dxe/Mem/memdata.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
memdata.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Global data used in memory service
|
||||
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
|
||||
//
|
||||
// MemoryLock - synchronizes access to the memory map and pool lists
|
||||
//
|
||||
EFI_LOCK gMemoryLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
|
||||
|
||||
//
|
||||
// MemoryMap - the current memory map
|
||||
//
|
||||
LIST_ENTRY gMemoryMap = INITIALIZE_LIST_HEAD_VARIABLE (gMemoryMap);
|
||||
|
||||
//
|
||||
// MemoryLastConvert - the last memory descriptor used for a conversion request
|
||||
//
|
||||
MEMORY_MAP *gMemoryLastConvert;
|
613
MdeModulePkg/Core/Dxe/Mem/pool.c
Normal file
613
MdeModulePkg/Core/Dxe/Mem/pool.c
Normal file
@ -0,0 +1,613 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
pool.c
|
||||
|
||||
Abstract:
|
||||
|
||||
EFI Memory pool management
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
#define POOL_FREE_SIGNATURE EFI_SIGNATURE_32('p','f','r','0')
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
UINT32 Index;
|
||||
LIST_ENTRY Link;
|
||||
} POOL_FREE;
|
||||
|
||||
|
||||
#define POOL_HEAD_SIGNATURE EFI_SIGNATURE_32('p','h','d','0')
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
UINT32 Size;
|
||||
EFI_MEMORY_TYPE Type;
|
||||
UINTN Reserved;
|
||||
CHAR8 Data[1];
|
||||
} POOL_HEAD;
|
||||
|
||||
#define SIZE_OF_POOL_HEAD EFI_FIELD_OFFSET(POOL_HEAD,Data)
|
||||
|
||||
#define POOL_TAIL_SIGNATURE EFI_SIGNATURE_32('p','t','a','l')
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
UINT32 Size;
|
||||
} POOL_TAIL;
|
||||
|
||||
|
||||
#define POOL_SHIFT 7
|
||||
|
||||
#define POOL_OVERHEAD (SIZE_OF_POOL_HEAD + sizeof(POOL_TAIL))
|
||||
|
||||
#define HEAD_TO_TAIL(a) \
|
||||
((POOL_TAIL *) (((CHAR8 *) (a)) + (a)->Size - sizeof(POOL_TAIL)));
|
||||
|
||||
|
||||
#define SIZE_TO_LIST(a) ((a) >> POOL_SHIFT)
|
||||
#define LIST_TO_SIZE(a) ((a+1) << POOL_SHIFT)
|
||||
|
||||
#define MAX_POOL_LIST SIZE_TO_LIST(DEFAULT_PAGE_ALLOCATION)
|
||||
|
||||
#define MAX_POOL_SIZE (MAX_ADDRESS - POOL_OVERHEAD)
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
|
||||
#define POOL_SIGNATURE EFI_SIGNATURE_32('p','l','s','t')
|
||||
typedef struct {
|
||||
INTN Signature;
|
||||
UINTN Used;
|
||||
EFI_MEMORY_TYPE MemoryType;
|
||||
LIST_ENTRY FreeList[MAX_POOL_LIST];
|
||||
LIST_ENTRY Link;
|
||||
} POOL;
|
||||
|
||||
|
||||
POOL PoolHead[EfiMaxMemoryType];
|
||||
LIST_ENTRY PoolHeadList;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
VOID
|
||||
CoreInitializePool (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Called to initialize the pool.
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN Type;
|
||||
UINTN Index;
|
||||
|
||||
for (Type=0; Type < EfiMaxMemoryType; Type++) {
|
||||
PoolHead[Type].Signature = 0;
|
||||
PoolHead[Type].Used = 0;
|
||||
PoolHead[Type].MemoryType = (EFI_MEMORY_TYPE) Type;
|
||||
for (Index=0; Index < MAX_POOL_LIST; Index++) {
|
||||
InitializeListHead (&PoolHead[Type].FreeList[Index]);
|
||||
}
|
||||
}
|
||||
InitializeListHead (&PoolHeadList);
|
||||
}
|
||||
|
||||
STATIC
|
||||
POOL *
|
||||
LookupPoolHead (
|
||||
IN EFI_MEMORY_TYPE MemoryType
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Look up pool head for specified memory type.
|
||||
|
||||
Arguments:
|
||||
|
||||
MemoryType - Memory type of which pool head is looked for
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer of Corresponding pool head.
|
||||
|
||||
--*/
|
||||
{
|
||||
LIST_ENTRY *Link;
|
||||
POOL *Pool;
|
||||
UINTN Index;
|
||||
|
||||
if (MemoryType >= 0 && MemoryType < EfiMaxMemoryType) {
|
||||
return &PoolHead[MemoryType];
|
||||
}
|
||||
|
||||
if (MemoryType < 0) {
|
||||
|
||||
for (Link = PoolHeadList.ForwardLink; Link != &PoolHeadList; Link = Link->ForwardLink) {
|
||||
Pool = CR(Link, POOL, Link, POOL_SIGNATURE);
|
||||
if (Pool->MemoryType == MemoryType) {
|
||||
return Pool;
|
||||
}
|
||||
}
|
||||
|
||||
Pool = CoreAllocatePoolI (EfiBootServicesData, sizeof (POOL));
|
||||
if (Pool == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Pool->Signature = POOL_SIGNATURE;
|
||||
Pool->Used = 0;
|
||||
Pool->MemoryType = MemoryType;
|
||||
for (Index=0; Index < MAX_POOL_LIST; Index++) {
|
||||
InitializeListHead (&Pool->FreeList[Index]);
|
||||
}
|
||||
|
||||
InsertHeadList (&PoolHeadList, &Pool->Link);
|
||||
|
||||
return Pool;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreAllocatePool (
|
||||
IN EFI_MEMORY_TYPE PoolType,
|
||||
IN UINTN Size,
|
||||
OUT VOID **Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Allocate pool of a particular type.
|
||||
|
||||
Arguments:
|
||||
|
||||
PoolType - Type of pool to allocate
|
||||
|
||||
Size - The amount of pool to allocate
|
||||
|
||||
Buffer - The address to return a pointer to the allocated pool
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_INVALID_PARAMETER - PoolType not valid
|
||||
|
||||
EFI_OUT_OF_RESOURCES - Size exceeds max pool size or allocation failed.
|
||||
|
||||
EFI_SUCCESS - Pool successfully allocated.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// If it's not a valid type, fail it
|
||||
//
|
||||
if ((PoolType >= EfiMaxMemoryType && PoolType <= 0x7fffffff) ||
|
||||
PoolType == EfiConventionalMemory) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*Buffer = NULL;
|
||||
|
||||
//
|
||||
// If size is too large, fail it
|
||||
// Base on the EFI spec, return status of EFI_OUT_OF_RESOURCES
|
||||
//
|
||||
if (Size > MAX_POOL_SIZE) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Acquire the memory lock and make the allocation
|
||||
//
|
||||
Status = CoreAcquireLockOrFail (&gMemoryLock);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
*Buffer = CoreAllocatePoolI (PoolType, Size);
|
||||
CoreReleaseMemoryLock ();
|
||||
return (*Buffer != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
|
||||
VOID *
|
||||
CoreAllocatePoolI (
|
||||
IN EFI_MEMORY_TYPE PoolType,
|
||||
IN UINTN Size
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Internal function to allocate pool of a particular type.
|
||||
|
||||
Caller must have the memory lock held
|
||||
|
||||
|
||||
Arguments:
|
||||
|
||||
PoolType - Type of pool to allocate
|
||||
|
||||
Size - The amount of pool to allocate
|
||||
|
||||
Returns:
|
||||
|
||||
The allocate pool, or NULL
|
||||
|
||||
--*/
|
||||
{
|
||||
POOL *Pool;
|
||||
POOL_FREE *Free;
|
||||
POOL_HEAD *Head;
|
||||
POOL_TAIL *Tail;
|
||||
CHAR8 *NewPage;
|
||||
VOID *Buffer;
|
||||
UINTN Index;
|
||||
UINTN FSize;
|
||||
UINTN offset;
|
||||
UINTN Adjustment;
|
||||
UINTN NoPages;
|
||||
|
||||
ASSERT_LOCKED (&gMemoryLock);
|
||||
|
||||
//
|
||||
// Adjust the size by the pool header & tail overhead
|
||||
//
|
||||
|
||||
//
|
||||
// Adjusting the Size to be of proper alignment so that
|
||||
// we don't get an unaligned access fault later when
|
||||
// pool_Tail is being initialized
|
||||
//
|
||||
ALIGN_VARIABLE (Size, Adjustment);
|
||||
|
||||
Size += POOL_OVERHEAD;
|
||||
Index = SIZE_TO_LIST(Size);
|
||||
Pool = LookupPoolHead (PoolType);
|
||||
if (Pool== NULL) {
|
||||
return NULL;
|
||||
}
|
||||
Head = NULL;
|
||||
|
||||
//
|
||||
// If allocation is over max size, just allocate pages for the request
|
||||
// (slow)
|
||||
//
|
||||
if (Index >= MAX_POOL_LIST) {
|
||||
NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1;
|
||||
NoPages &= ~(EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1);
|
||||
Head = CoreAllocatePoolPages (PoolType, NoPages, DEFAULT_PAGE_ALLOCATION);
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// If there's no free pool in the proper list size, go get some more pages
|
||||
//
|
||||
if (IsListEmpty (&Pool->FreeList[Index])) {
|
||||
|
||||
//
|
||||
// Get another page
|
||||
//
|
||||
NewPage = CoreAllocatePoolPages(PoolType, EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION), DEFAULT_PAGE_ALLOCATION);
|
||||
if (NewPage == NULL) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Carve up new page into free pool blocks
|
||||
//
|
||||
offset = 0;
|
||||
while (offset < DEFAULT_PAGE_ALLOCATION) {
|
||||
ASSERT (Index < MAX_POOL_LIST);
|
||||
FSize = LIST_TO_SIZE(Index);
|
||||
|
||||
while (offset + FSize <= DEFAULT_PAGE_ALLOCATION) {
|
||||
Free = (POOL_FREE *) &NewPage[offset];
|
||||
Free->Signature = POOL_FREE_SIGNATURE;
|
||||
Free->Index = (UINT32)Index;
|
||||
InsertHeadList (&Pool->FreeList[Index], &Free->Link);
|
||||
offset += FSize;
|
||||
}
|
||||
|
||||
Index -= 1;
|
||||
}
|
||||
|
||||
ASSERT (offset == DEFAULT_PAGE_ALLOCATION);
|
||||
Index = SIZE_TO_LIST(Size);
|
||||
}
|
||||
|
||||
//
|
||||
// Remove entry from free pool list
|
||||
//
|
||||
Free = CR (Pool->FreeList[Index].ForwardLink, POOL_FREE, Link, POOL_FREE_SIGNATURE);
|
||||
RemoveEntryList (&Free->Link);
|
||||
|
||||
Head = (POOL_HEAD *) Free;
|
||||
|
||||
Done:
|
||||
Buffer = NULL;
|
||||
|
||||
if (Head != NULL) {
|
||||
|
||||
//
|
||||
// If we have a pool buffer, fill in the header & tail info
|
||||
//
|
||||
Head->Signature = POOL_HEAD_SIGNATURE;
|
||||
Head->Size = (UINT32) Size;
|
||||
Head->Type = (EFI_MEMORY_TYPE) PoolType;
|
||||
Tail = HEAD_TO_TAIL (Head);
|
||||
Tail->Signature = POOL_TAIL_SIGNATURE;
|
||||
Tail->Size = (UINT32) Size;
|
||||
Buffer = Head->Data;
|
||||
DEBUG_CLEAR_MEMORY (Buffer, Size - POOL_OVERHEAD);
|
||||
|
||||
DEBUG (
|
||||
(EFI_D_POOL,
|
||||
"AllcocatePoolI: Type %x, Addr %x (len %x) %,d\n",
|
||||
PoolType,
|
||||
Buffer,
|
||||
Size - POOL_OVERHEAD,
|
||||
Pool->Used)
|
||||
);
|
||||
|
||||
//
|
||||
// Account the allocation
|
||||
//
|
||||
Pool->Used += Size;
|
||||
|
||||
} else {
|
||||
DEBUG ((EFI_D_ERROR | EFI_D_POOL, "AllocatePool: failed to allocate %d bytes\n", Size));
|
||||
}
|
||||
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreFreePool (
|
||||
IN VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Frees pool.
|
||||
|
||||
Arguments:
|
||||
|
||||
Buffer - The allocated pool entry to free
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_INVALID_PARAMETER - Buffer is not a valid value.
|
||||
|
||||
EFI_SUCCESS - Pool successfully freed.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (NULL == Buffer) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
CoreAcquireMemoryLock ();
|
||||
Status = CoreFreePoolI (Buffer);
|
||||
CoreReleaseMemoryLock ();
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
CoreFreePoolI (
|
||||
IN VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Internal function to free a pool entry.
|
||||
|
||||
Caller must have the memory lock held
|
||||
|
||||
|
||||
Arguments:
|
||||
|
||||
Buffer - The allocated pool entry to free
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_INVALID_PARAMETER - Buffer not valid
|
||||
|
||||
EFI_SUCCESS - Buffer successfully freed.
|
||||
|
||||
--*/
|
||||
{
|
||||
POOL *Pool;
|
||||
POOL_HEAD *Head;
|
||||
POOL_TAIL *Tail;
|
||||
POOL_FREE *Free;
|
||||
UINTN Index;
|
||||
UINTN NoPages;
|
||||
UINTN Size;
|
||||
CHAR8 *NewPage;
|
||||
UINTN FSize;
|
||||
UINTN offset;
|
||||
BOOLEAN AllFree;
|
||||
|
||||
ASSERT(NULL != Buffer);
|
||||
//
|
||||
// Get the head & tail of the pool entry
|
||||
//
|
||||
Head = CR (Buffer, POOL_HEAD, Data, POOL_HEAD_SIGNATURE);
|
||||
ASSERT(NULL != Head);
|
||||
|
||||
if (Head->Signature != POOL_HEAD_SIGNATURE) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Tail = HEAD_TO_TAIL (Head);
|
||||
ASSERT(NULL != Tail);
|
||||
|
||||
//
|
||||
// Debug
|
||||
//
|
||||
ASSERT (Tail->Signature == POOL_TAIL_SIGNATURE);
|
||||
ASSERT (Head->Size == Tail->Size);
|
||||
ASSERT_LOCKED (&gMemoryLock);
|
||||
|
||||
if (Tail->Signature != POOL_TAIL_SIGNATURE) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Head->Size != Tail->Size) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Determine the pool type and account for it
|
||||
//
|
||||
Size = Head->Size;
|
||||
Pool = LookupPoolHead (Head->Type);
|
||||
if (Pool == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
Pool->Used -= Size;
|
||||
DEBUG ((EFI_D_POOL, "FreePool: %x (len %x) %,d\n", Head->Data, Head->Size - POOL_OVERHEAD, Pool->Used));
|
||||
|
||||
//
|
||||
// Determine the pool list
|
||||
//
|
||||
Index = SIZE_TO_LIST(Size);
|
||||
DEBUG_CLEAR_MEMORY (Head, Size);
|
||||
|
||||
//
|
||||
// If it's not on the list, it must be pool pages
|
||||
//
|
||||
if (Index >= MAX_POOL_LIST) {
|
||||
|
||||
//
|
||||
// Return the memory pages back to free memory
|
||||
//
|
||||
NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1;
|
||||
NoPages &= ~(EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1);
|
||||
CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN) Head, NoPages);
|
||||
|
||||
} else {
|
||||
|
||||
//
|
||||
// Put the pool entry onto the free pool list
|
||||
//
|
||||
Free = (POOL_FREE *) Head;
|
||||
ASSERT(NULL != Free);
|
||||
Free->Signature = POOL_FREE_SIGNATURE;
|
||||
Free->Index = (UINT32)Index;
|
||||
InsertHeadList (&Pool->FreeList[Index], &Free->Link);
|
||||
|
||||
//
|
||||
// See if all the pool entries in the same page as Free are freed pool
|
||||
// entries
|
||||
//
|
||||
NewPage = (CHAR8 *)((UINTN)Free & ~((DEFAULT_PAGE_ALLOCATION) -1));
|
||||
Free = (POOL_FREE *) &NewPage[0];
|
||||
ASSERT(NULL != Free);
|
||||
|
||||
if (Free->Signature == POOL_FREE_SIGNATURE) {
|
||||
|
||||
Index = Free->Index;
|
||||
|
||||
AllFree = TRUE;
|
||||
offset = 0;
|
||||
|
||||
while ((offset < DEFAULT_PAGE_ALLOCATION) && (AllFree)) {
|
||||
FSize = LIST_TO_SIZE(Index);
|
||||
while (offset + FSize <= DEFAULT_PAGE_ALLOCATION) {
|
||||
Free = (POOL_FREE *) &NewPage[offset];
|
||||
ASSERT(NULL != Free);
|
||||
if (Free->Signature != POOL_FREE_SIGNATURE) {
|
||||
AllFree = FALSE;
|
||||
}
|
||||
offset += FSize;
|
||||
}
|
||||
Index -= 1;
|
||||
}
|
||||
|
||||
if (AllFree) {
|
||||
|
||||
//
|
||||
// All of the pool entries in the same page as Free are free pool
|
||||
// entries
|
||||
// Remove all of these pool entries from the free loop lists.
|
||||
//
|
||||
Free = (POOL_FREE *) &NewPage[0];
|
||||
ASSERT(NULL != Free);
|
||||
Index = Free->Index;
|
||||
offset = 0;
|
||||
|
||||
while (offset < DEFAULT_PAGE_ALLOCATION) {
|
||||
FSize = LIST_TO_SIZE(Index);
|
||||
while (offset + FSize <= DEFAULT_PAGE_ALLOCATION) {
|
||||
Free = (POOL_FREE *) &NewPage[offset];
|
||||
ASSERT(NULL != Free);
|
||||
RemoveEntryList (&Free->Link);
|
||||
offset += FSize;
|
||||
}
|
||||
Index -= 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Free the page
|
||||
//
|
||||
CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN)NewPage, EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// If this is an OS specific memory type, then check to see if the last
|
||||
// portion of that memory type has been freed. If it has, then free the
|
||||
// list entry for that memory type
|
||||
//
|
||||
if (Pool->MemoryType < 0 && Pool->Used == 0) {
|
||||
RemoveEntryList (&Pool->Link);
|
||||
CoreFreePoolI (Pool);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
260
MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c
Normal file
260
MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c
Normal file
@ -0,0 +1,260 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
DebugImageInfo.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Support functions for managing debug image info table when loading and unloading
|
||||
images.
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
|
||||
static EFI_DEBUG_IMAGE_INFO_TABLE_HEADER mDebugInfoTableHeader = {
|
||||
0, // volatile UINT32 UpdateStatus;
|
||||
0, // UINT32 TableSize;
|
||||
NULL // EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable;
|
||||
};
|
||||
|
||||
static EFI_SYSTEM_TABLE_POINTER *mDebugTable = NULL;
|
||||
|
||||
|
||||
VOID
|
||||
CoreInitializeDebugImageInfoTable (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Creates and initializes the DebugImageInfo Table. Also creates the configuration
|
||||
table and registers it into the system table.
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Returns:
|
||||
NA
|
||||
|
||||
Notes:
|
||||
This function allocates memory, frees it, and then allocates memory at an
|
||||
address within the initial allocation. Since this function is called early
|
||||
in DXE core initialization (before drivers are dispatched), this should not
|
||||
be a problem.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS Mem;
|
||||
UINTN NumberOfPages;
|
||||
|
||||
//
|
||||
// Allocate boot services memory for the structure. It's required to be aligned on
|
||||
// a 4M boundary, so allocate a 4M block (plus what we require), free it up, calculate
|
||||
// a 4M aligned address within the memory we just freed, and then allocate memory at that
|
||||
// address for our initial structure.
|
||||
//
|
||||
NumberOfPages = FOUR_MEG_PAGES + EFI_SIZE_TO_PAGES(sizeof (EFI_SYSTEM_TABLE_POINTER));
|
||||
|
||||
Status = CoreAllocatePages (AllocateAnyPages, EfiBootServicesData, NumberOfPages , &Mem);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return;
|
||||
}
|
||||
Status = CoreFreePages (Mem, NumberOfPages);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
// Now get a 4M aligned address within the memory range we were given.
|
||||
// Then allocate memory at that address
|
||||
//
|
||||
Mem = (Mem + FOUR_MEG_MASK) & (~FOUR_MEG_MASK);
|
||||
|
||||
Status = CoreAllocatePages (AllocateAddress, EfiBootServicesData, NumberOfPages - FOUR_MEG_PAGES, &Mem);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
// We now have a 4M aligned page allocated, so fill in the data structure.
|
||||
// Ideally we would update the CRC now as well, but the service may not yet be available.
|
||||
// See comments in the CoreUpdateDebugTableCrc32() function below for details.
|
||||
//
|
||||
mDebugTable = (EFI_SYSTEM_TABLE_POINTER *)(UINTN)Mem;
|
||||
mDebugTable->Signature = EFI_SYSTEM_TABLE_SIGNATURE;
|
||||
mDebugTable->EfiSystemTableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) gDxeCoreST;
|
||||
mDebugTable->Crc32 = 0;
|
||||
Status = CoreInstallConfigurationTable (&gEfiDebugImageInfoTableGuid, &mDebugInfoTableHeader);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
VOID
|
||||
CoreUpdateDebugTableCrc32 (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Update the CRC32 in the Debug Table.
|
||||
Since the CRC32 service is made available by the Runtime driver, we have to
|
||||
wait for the Runtime Driver to be installed before the CRC32 can be computed.
|
||||
This function is called elsewhere by the core when the runtime architectural
|
||||
protocol is produced.
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Returns:
|
||||
NA
|
||||
|
||||
--*/
|
||||
{
|
||||
ASSERT(mDebugTable != NULL);
|
||||
mDebugTable->Crc32 = 0;
|
||||
gDxeCoreBS->CalculateCrc32 ((VOID *)mDebugTable, sizeof (EFI_SYSTEM_TABLE_POINTER), &mDebugTable->Crc32);
|
||||
}
|
||||
|
||||
VOID
|
||||
CoreNewDebugImageInfoEntry (
|
||||
IN UINT32 ImageInfoType,
|
||||
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
|
||||
IN EFI_HANDLE ImageHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates
|
||||
the table if it's not large enough to accomidate another entry.
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageInfoType - type of debug image information
|
||||
LoadedImage - pointer to the loaded image protocol for the image being loaded
|
||||
ImageHandle - image handle for the image being loaded
|
||||
|
||||
Returns:
|
||||
NA
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_DEBUG_IMAGE_INFO *Table;
|
||||
EFI_DEBUG_IMAGE_INFO *NewTable;
|
||||
UINTN Index;
|
||||
UINTN MaxTableIndex;
|
||||
UINTN TableSize;
|
||||
|
||||
//
|
||||
// Set the flag indicating that we're in the process of updating the table.
|
||||
//
|
||||
mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
|
||||
|
||||
Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;
|
||||
MaxTableIndex = mDebugInfoTableHeader.TableSize;
|
||||
|
||||
for (Index = 0; Index < MaxTableIndex; Index++) {
|
||||
if (Table[Index].NormalImage == NULL) {
|
||||
//
|
||||
// We have found a free entry so exit the loop
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Index == MaxTableIndex) {
|
||||
//
|
||||
// Table is full, so re-allocate another page for a larger table...
|
||||
//
|
||||
TableSize = MaxTableIndex * EFI_DEBUG_TABLE_ENTRY_SIZE;
|
||||
NewTable = CoreAllocateZeroBootServicesPool (TableSize + EFI_PAGE_SIZE);
|
||||
if (NewTable == NULL) {
|
||||
mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
|
||||
return;
|
||||
}
|
||||
//
|
||||
// Copy the old table into the new one
|
||||
//
|
||||
CopyMem (NewTable, Table, TableSize);
|
||||
//
|
||||
// Free the old table
|
||||
//
|
||||
CoreFreePool (Table);
|
||||
//
|
||||
// Update the table header
|
||||
//
|
||||
Table = NewTable;
|
||||
mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable;
|
||||
mDebugInfoTableHeader.TableSize += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;
|
||||
}
|
||||
//
|
||||
// Allocate data for new entry
|
||||
//
|
||||
Table[Index].NormalImage = CoreAllocateZeroBootServicesPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL));
|
||||
if (Table[Index].NormalImage != NULL) {
|
||||
//
|
||||
// Update the entry
|
||||
//
|
||||
Table[Index].NormalImage->ImageInfoType = (UINT32) ImageInfoType;
|
||||
Table[Index].NormalImage->LoadedImageProtocolInstance = LoadedImage;
|
||||
Table[Index].NormalImage->ImageHandle = ImageHandle;
|
||||
}
|
||||
mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CoreRemoveDebugImageInfoEntry (
|
||||
EFI_HANDLE ImageHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Removes and frees an entry from the DebugImageInfo Table.
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle - image handle for the image being unloaded
|
||||
|
||||
Returns:
|
||||
|
||||
NA
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_DEBUG_IMAGE_INFO *Table;
|
||||
UINTN Index;
|
||||
|
||||
mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
|
||||
|
||||
Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;
|
||||
|
||||
for (Index = 0; Index < mDebugInfoTableHeader.TableSize; Index++) {
|
||||
if (Table[Index].NormalImage != NULL && Table[Index].NormalImage->ImageHandle == ImageHandle) {
|
||||
//
|
||||
// Found a match. Free up the record, then NULL the pointer to indicate the slot
|
||||
// is free.
|
||||
//
|
||||
CoreFreePool (Table[Index].NormalImage);
|
||||
Table[Index].NormalImage = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
|
||||
}
|
||||
|
225
MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c
Normal file
225
MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c
Normal file
@ -0,0 +1,225 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
InstallConfigurationTable.c
|
||||
|
||||
|
||||
Abstract:
|
||||
|
||||
Tiano Miscellaneous Services InstallConfigurationTable service
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
#define CONFIG_TABLE_SIZE_INCREASED 0x10
|
||||
|
||||
UINTN mSystemTableAllocateSize = 0;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
CoreGetConfigTable (
|
||||
IN EFI_GUID *Guid,
|
||||
OUT VOID **Table
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Find a config table by name in system table's ConfigurationTable.
|
||||
|
||||
Arguments:
|
||||
|
||||
Guid - The table name to look for
|
||||
|
||||
Table - Pointer of the config table
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_NOT_FOUND - Could not find the table in system table's ConfigurationTable.
|
||||
|
||||
EFI_SUCCESS - Table successfully found.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
for (Index = 0; Index < gDxeCoreST->NumberOfTableEntries; Index++) {
|
||||
if (CompareGuid (Guid, &(gDxeCoreST->ConfigurationTable[Index].VendorGuid))) {
|
||||
*Table = gDxeCoreST->ConfigurationTable[Index].VendorTable;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreInstallConfigurationTable (
|
||||
IN EFI_GUID *Guid,
|
||||
IN VOID *Table
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Boot Service called to add, modify, or remove a system configuration table from
|
||||
the EFI System Table.
|
||||
|
||||
Arguments:
|
||||
|
||||
Guid - Pointer to the GUID for the entry to add, update, or remove
|
||||
Table - Pointer to the configuration table for the entry to add, update, or
|
||||
remove, may be NULL.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS Guid, Table pair added, updated, or removed.
|
||||
EFI_INVALID_PARAMETER Input GUID not valid.
|
||||
EFI_NOT_FOUND Attempted to delete non-existant entry
|
||||
EFI_OUT_OF_RESOURCES Not enough memory available
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN Index;
|
||||
EFI_CONFIGURATION_TABLE *EfiConfigurationTable;
|
||||
|
||||
//
|
||||
// If Guid is NULL, then this operation cannot be performed
|
||||
//
|
||||
if (Guid == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
EfiConfigurationTable = gDxeCoreST->ConfigurationTable;
|
||||
|
||||
//
|
||||
// Search all the table for an entry that matches Guid
|
||||
//
|
||||
for (Index = 0; Index < gDxeCoreST->NumberOfTableEntries; Index++) {
|
||||
if (CompareGuid (Guid, &(gDxeCoreST->ConfigurationTable[Index].VendorGuid))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Index < gDxeCoreST->NumberOfTableEntries) {
|
||||
//
|
||||
// A match was found, so this is either a modify or a delete operation
|
||||
//
|
||||
if (Table != NULL) {
|
||||
//
|
||||
// If Table is not NULL, then this is a modify operation.
|
||||
// Modify the table enty and return.
|
||||
//
|
||||
gDxeCoreST->ConfigurationTable[Index].VendorTable = Table;
|
||||
|
||||
//
|
||||
// Signal Configuration Table change
|
||||
//
|
||||
CoreNotifySignalList (Guid);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// A match was found and Table is NULL, so this is a delete operation.
|
||||
//
|
||||
gDxeCoreST->NumberOfTableEntries--;
|
||||
|
||||
//
|
||||
// Copy over deleted entry
|
||||
//
|
||||
CopyMem (
|
||||
&(EfiConfigurationTable[Index]),
|
||||
&(gDxeCoreST->ConfigurationTable[Index + 1]),
|
||||
(gDxeCoreST->NumberOfTableEntries - Index) * sizeof (EFI_CONFIGURATION_TABLE)
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
//
|
||||
// No matching GUIDs were found, so this is an add operation.
|
||||
//
|
||||
|
||||
if (Table == NULL) {
|
||||
//
|
||||
// If Table is NULL on an add operation, then return an error.
|
||||
//
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Assume that Index == gDxeCoreST->NumberOfTableEntries
|
||||
//
|
||||
if ((Index * sizeof (EFI_CONFIGURATION_TABLE)) >= mSystemTableAllocateSize) {
|
||||
//
|
||||
// Allocate a table with one additional entry.
|
||||
//
|
||||
mSystemTableAllocateSize += (CONFIG_TABLE_SIZE_INCREASED * sizeof (EFI_CONFIGURATION_TABLE));
|
||||
EfiConfigurationTable = CoreAllocateRuntimePool (mSystemTableAllocateSize);
|
||||
if (EfiConfigurationTable == NULL) {
|
||||
//
|
||||
// If a new table could not be allocated, then return an error.
|
||||
//
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
if (gDxeCoreST->ConfigurationTable != NULL) {
|
||||
//
|
||||
// Copy the old table to the new table.
|
||||
//
|
||||
CopyMem (
|
||||
EfiConfigurationTable,
|
||||
gDxeCoreST->ConfigurationTable,
|
||||
Index * sizeof (EFI_CONFIGURATION_TABLE)
|
||||
);
|
||||
|
||||
//
|
||||
// Free Old Table
|
||||
//
|
||||
CoreFreePool (gDxeCoreST->ConfigurationTable);
|
||||
}
|
||||
|
||||
//
|
||||
// Update System Table
|
||||
//
|
||||
gDxeCoreST->ConfigurationTable = EfiConfigurationTable;
|
||||
}
|
||||
|
||||
//
|
||||
// Fill in the new entry
|
||||
//
|
||||
CopyMem ((VOID *)&EfiConfigurationTable[Index].VendorGuid, Guid, sizeof (EFI_GUID));
|
||||
EfiConfigurationTable[Index].VendorTable = Table;
|
||||
|
||||
//
|
||||
// This is an add operation, so increment the number of table entries
|
||||
//
|
||||
gDxeCoreST->NumberOfTableEntries++;
|
||||
}
|
||||
|
||||
//
|
||||
// Fix up the CRC-32 in the EFI System Table
|
||||
//
|
||||
CalculateEfiHdrCrc (&gDxeCoreST->Hdr);
|
||||
|
||||
//
|
||||
// Signal Configuration Table change
|
||||
//
|
||||
CoreNotifySignalList (Guid);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
83
MdeModulePkg/Core/Dxe/Misc/SetWatchdogTimer.c
Normal file
83
MdeModulePkg/Core/Dxe/Misc/SetWatchdogTimer.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
SetWatchdogTimer.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Tiano Miscellaneous Services SetWatchdogTimer service implementation
|
||||
|
||||
--*/
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
#define WATCHDOG_TIMER_CALIBRATE_PER_SECOND 10000000
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreSetWatchdogTimer (
|
||||
IN UINTN Timeout,
|
||||
IN UINT64 WatchdogCode,
|
||||
IN UINTN DataSize,
|
||||
IN CHAR16 *WatchdogData OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Sets the system's watchdog timer.
|
||||
|
||||
Arguments:
|
||||
|
||||
Timeout The number of seconds. Zero disables the timer.
|
||||
|
||||
///////following three parameters are left for platform specific using
|
||||
|
||||
WatchdogCode The numberic code to log. 0x0 to 0xffff are firmware
|
||||
DataSize Size of the optional data
|
||||
WatchdogData Optional Null terminated unicode string followed by binary
|
||||
data.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS Timeout has been set
|
||||
EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet
|
||||
EFI_UNSUPPORTED System does not have a timer (currently not used)
|
||||
EFI_DEVICE_ERROR Could not complete due to hardware error
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Check our architectural protocol
|
||||
//
|
||||
if (gWatchdogTimer == NULL) {
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
}
|
||||
|
||||
//
|
||||
// Attempt to set the timeout
|
||||
//
|
||||
Status = gWatchdogTimer->SetTimerPeriod (gWatchdogTimer, MultU64x32 (Timeout, WATCHDOG_TIMER_CALIBRATE_PER_SECOND));
|
||||
|
||||
//
|
||||
// Check for errors
|
||||
//
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
82
MdeModulePkg/Core/Dxe/Misc/Stall.c
Normal file
82
MdeModulePkg/Core/Dxe/Misc/Stall.c
Normal file
@ -0,0 +1,82 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
Stall.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Tiano Miscellaneous Services Stall service implementation
|
||||
|
||||
--*/
|
||||
|
||||
//
|
||||
// Include statements
|
||||
//
|
||||
|
||||
#include <DxeMain.h>
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CoreStall (
|
||||
IN UINTN Microseconds
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Introduces a fine-grained stall.
|
||||
|
||||
Arguments:
|
||||
|
||||
Microseconds The number of microseconds to stall execution
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Execution was stalled for at least the requested amount
|
||||
of microseconds.
|
||||
|
||||
EFI_NOT_AVAILABLE_YET - gMetronome is not available yet
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT32 Counter;
|
||||
UINT32 Remainder;
|
||||
|
||||
if (gMetronome == NULL) {
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate the number of ticks by dividing the number of microseconds by
|
||||
// the TickPeriod.
|
||||
// Calcullation is based on 100ns unit.
|
||||
//
|
||||
Counter = (UINT32) DivU64x32Remainder (
|
||||
Microseconds * 10,
|
||||
gMetronome->TickPeriod,
|
||||
&Remainder
|
||||
);
|
||||
|
||||
//
|
||||
// Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick
|
||||
// periods, thus attempting to ensure Microseconds of stall time.
|
||||
//
|
||||
if (Remainder != 0) {
|
||||
Counter++;
|
||||
}
|
||||
|
||||
gMetronome->WaitForTick (gMetronome, Counter);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
1341
MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c
Normal file
1341
MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c
Normal file
File diff suppressed because it is too large
Load Diff
51
MdeModulePkg/Core/Dxe/gcd.h
Normal file
51
MdeModulePkg/Core/Dxe/gcd.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
gcd.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _GCD_H
|
||||
#define _GCD_H
|
||||
|
||||
//
|
||||
// GCD Operations
|
||||
//
|
||||
#define GCD_MEMORY_SPACE_OPERATION 0x20
|
||||
#define GCD_IO_SPACE_OPERATION 0x40
|
||||
|
||||
#define GCD_ADD_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 0)
|
||||
#define GCD_ALLOCATE_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 1)
|
||||
#define GCD_FREE_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 2)
|
||||
#define GCD_REMOVE_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 3)
|
||||
#define GCD_SET_ATTRIBUTES_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 4)
|
||||
|
||||
#define GCD_ADD_IO_OPERATION (GCD_IO_SPACE_OPERATION | 0)
|
||||
#define GCD_ALLOCATE_IO_OPERATION (GCD_IO_SPACE_OPERATION | 1)
|
||||
#define GCD_FREE_IO_OPERATION (GCD_IO_SPACE_OPERATION | 2)
|
||||
#define GCD_REMOVE_IO_OPERATION (GCD_IO_SPACE_OPERATION | 3)
|
||||
|
||||
//
|
||||
// The data structure used to convert from GCD attributes to EFI Memory Map attributes
|
||||
//
|
||||
typedef struct {
|
||||
UINT64 Attribute;
|
||||
UINT64 Capability;
|
||||
BOOLEAN Memory;
|
||||
} GCD_ATTRIBUTE_CONVERSION_ENTRY;
|
||||
|
||||
#endif
|
337
MdeModulePkg/Core/Dxe/hand.h
Normal file
337
MdeModulePkg/Core/Dxe/hand.h
Normal file
@ -0,0 +1,337 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
hand.h
|
||||
|
||||
Abstract:
|
||||
|
||||
EFI internal protocol definitions
|
||||
|
||||
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _HAND_H_
|
||||
#define _HAND_H_
|
||||
|
||||
|
||||
//
|
||||
// IHANDLE - contains a list of protocol handles
|
||||
//
|
||||
|
||||
#define EFI_HANDLE_SIGNATURE EFI_SIGNATURE_32('h','n','d','l')
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
LIST_ENTRY AllHandles; // All handles list of IHANDLE
|
||||
LIST_ENTRY Protocols; // List of PROTOCOL_INTERFACE's for this handle
|
||||
UINTN LocateRequest; //
|
||||
UINT64 Key; // The Handle Database Key value when this handle was last created or modified
|
||||
} IHANDLE;
|
||||
|
||||
#define ASSERT_IS_HANDLE(a) ASSERT((a)->Signature == EFI_HANDLE_SIGNATURE)
|
||||
|
||||
|
||||
//
|
||||
// PROTOCOL_ENTRY - each different protocol has 1 entry in the protocol
|
||||
// database. Each handler that supports this protocol is listed, along
|
||||
// with a list of registered notifies.
|
||||
//
|
||||
|
||||
#define PROTOCOL_ENTRY_SIGNATURE EFI_SIGNATURE_32('p','r','t','e')
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
LIST_ENTRY AllEntries; // All entries
|
||||
EFI_GUID ProtocolID; // ID of the protocol
|
||||
LIST_ENTRY Protocols; // All protocol interfaces
|
||||
LIST_ENTRY Notify; // Registerd notification handlers
|
||||
} PROTOCOL_ENTRY;
|
||||
|
||||
//
|
||||
// PROTOCOL_INTERFACE - each protocol installed on a handle is tracked
|
||||
// with a protocol interface structure
|
||||
//
|
||||
|
||||
#define PROTOCOL_INTERFACE_SIGNATURE EFI_SIGNATURE_32('p','i','f','c')
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
EFI_HANDLE Handle; // Back pointer
|
||||
LIST_ENTRY Link; // Link on IHANDLE.Protocols
|
||||
LIST_ENTRY ByProtocol; // Link on PROTOCOL_ENTRY.Protocols
|
||||
PROTOCOL_ENTRY *Protocol; // The protocol ID
|
||||
VOID *Interface; // The interface value
|
||||
|
||||
LIST_ENTRY OpenList; // OPEN_PROTOCOL_DATA list.
|
||||
UINTN OpenListCount;
|
||||
|
||||
EFI_HANDLE ControllerHandle;
|
||||
|
||||
} PROTOCOL_INTERFACE;
|
||||
|
||||
#define OPEN_PROTOCOL_DATA_SIGNATURE EFI_SIGNATURE_32('p','o','d','l')
|
||||
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
LIST_ENTRY Link;
|
||||
|
||||
EFI_HANDLE AgentHandle;
|
||||
EFI_HANDLE ControllerHandle;
|
||||
UINT32 Attributes;
|
||||
UINT32 OpenCount;
|
||||
} OPEN_PROTOCOL_DATA;
|
||||
|
||||
|
||||
//
|
||||
// PROTOCOL_NOTIFY - used for each register notification for a protocol
|
||||
//
|
||||
|
||||
#define PROTOCOL_NOTIFY_SIGNATURE EFI_SIGNATURE_32('p','r','t','n')
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
PROTOCOL_ENTRY *Protocol;
|
||||
LIST_ENTRY Link; // All notifications for this protocol
|
||||
EFI_EVENT Event; // Event to notify
|
||||
LIST_ENTRY *Position; // Last position notified
|
||||
} PROTOCOL_NOTIFY;
|
||||
|
||||
//
|
||||
// Internal prototypes
|
||||
//
|
||||
|
||||
|
||||
PROTOCOL_ENTRY *
|
||||
CoreFindProtocolEntry (
|
||||
IN EFI_GUID *Protocol,
|
||||
IN BOOLEAN Create
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Finds the protocol entry for the requested protocol.
|
||||
|
||||
The gProtocolDatabaseLock must be owned
|
||||
|
||||
Arguments:
|
||||
|
||||
Protocol - The ID of the protocol
|
||||
|
||||
Create - Create a new entry if not found
|
||||
|
||||
Returns:
|
||||
|
||||
Protocol entry
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
CoreNotifyProtocolEntry (
|
||||
IN PROTOCOL_ENTRY *ProtEntry
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Signal event for every protocol in protocol entry.
|
||||
|
||||
Arguments:
|
||||
|
||||
ProtEntry - Protocol entry
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
PROTOCOL_INTERFACE *
|
||||
CoreFindProtocolInterface (
|
||||
IN IHANDLE *Handle,
|
||||
IN EFI_GUID *Protocol,
|
||||
IN VOID *Interface
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Finds the protocol instance for the requested handle and protocol.
|
||||
|
||||
Note: This function doesn't do parameters checking, it's caller's responsibility
|
||||
to pass in valid parameters.
|
||||
|
||||
Arguments:
|
||||
|
||||
Handle - The handle to search the protocol on
|
||||
|
||||
Protocol - GUID of the protocol
|
||||
|
||||
Interface - The interface for the protocol being searched
|
||||
|
||||
Returns:
|
||||
|
||||
Protocol instance (NULL: Not found)
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
PROTOCOL_INTERFACE *
|
||||
CoreRemoveInterfaceFromProtocol (
|
||||
IN IHANDLE *Handle,
|
||||
IN EFI_GUID *Protocol,
|
||||
IN VOID *Interface
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Removes Protocol from the protocol list (but not the handle list).
|
||||
|
||||
Arguments:
|
||||
|
||||
Handle - The handle to remove protocol on.
|
||||
|
||||
Protocol - GUID of the protocol to be moved
|
||||
|
||||
Interface - The interface of the protocol
|
||||
|
||||
Returns:
|
||||
|
||||
Protocol Entry
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
CoreUnregisterProtocolNotify (
|
||||
IN EFI_EVENT Event
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Removes all the events in the protocol database that match Event.
|
||||
|
||||
Arguments:
|
||||
|
||||
Event - The event to search for in the protocol database.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS when done searching the entire database.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
CoreDisconnectControllersUsingProtocolInterface (
|
||||
IN EFI_HANDLE UserHandle,
|
||||
IN PROTOCOL_INTERFACE *Prot
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Attempts to disconnect all drivers that are using the protocol interface being queried.
|
||||
If failed, reconnect all drivers disconnected.
|
||||
|
||||
Note: This function doesn't do parameters checking, it's caller's responsibility
|
||||
to pass in valid parameters.
|
||||
|
||||
Arguments:
|
||||
|
||||
UserHandle - The handle on which the protocol is installed
|
||||
Prot - The protocol to disconnect drivers from
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Drivers using the protocol interface are all disconnected
|
||||
EFI_ACCESS_DENIED - Failed to disconnect one or all of the drivers
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
CoreAcquireProtocolLock (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Acquire lock on gProtocolDatabaseLock.
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
CoreReleaseProtocolLock (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Release lock on gProtocolDatabaseLock.
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
CoreValidateHandle (
|
||||
IN EFI_HANDLE UserHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Check whether a handle is a valid EFI_HANDLE
|
||||
|
||||
Arguments:
|
||||
|
||||
UserHandle - The handle to check
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_INVALID_PARAMETER - The handle is NULL or not a valid EFI_HANDLE.
|
||||
|
||||
EFI_SUCCESS - The handle is valid EFI_HANDLE.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
//
|
||||
// Externs
|
||||
//
|
||||
|
||||
extern EFI_LOCK gProtocolDatabaseLock;
|
||||
extern LIST_ENTRY gHandleList;
|
||||
extern UINT64 gHandleDatabaseKey;
|
||||
|
||||
#endif
|
227
MdeModulePkg/Core/Dxe/imem.h
Normal file
227
MdeModulePkg/Core/Dxe/imem.h
Normal file
@ -0,0 +1,227 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
imem.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Head file to imem.h
|
||||
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _IMEM_H_
|
||||
#define _IMEM_H_
|
||||
|
||||
#if defined (MDE_CPU_IPF)
|
||||
//
|
||||
// For Itanium machines make the default allocations 8K aligned
|
||||
//
|
||||
#define EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT (EFI_PAGE_SIZE * 2)
|
||||
#define DEFAULT_PAGE_ALLOCATION (EFI_PAGE_SIZE * 2)
|
||||
|
||||
#else
|
||||
//
|
||||
// For genric EFI machines make the default allocations 4K aligned
|
||||
//
|
||||
#define EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT (EFI_PAGE_SIZE)
|
||||
#define DEFAULT_PAGE_ALLOCATION (EFI_PAGE_SIZE)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// MEMORY_MAP_ENTRY
|
||||
//
|
||||
|
||||
#define MEMORY_MAP_SIGNATURE EFI_SIGNATURE_32('m','m','a','p')
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
LIST_ENTRY Link;
|
||||
BOOLEAN FromPages;
|
||||
|
||||
EFI_MEMORY_TYPE Type;
|
||||
UINT64 Start;
|
||||
UINT64 End;
|
||||
|
||||
UINT64 VirtualStart;
|
||||
UINT64 Attribute;
|
||||
} MEMORY_MAP;
|
||||
|
||||
//
|
||||
// Internal prototypes
|
||||
//
|
||||
|
||||
VOID *
|
||||
CoreAllocatePoolPages (
|
||||
IN EFI_MEMORY_TYPE PoolType,
|
||||
IN UINTN NumberOfPages,
|
||||
IN UINTN Alignment
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Internal function. Used by the pool functions to allocate pages
|
||||
to back pool allocation requests.
|
||||
|
||||
Arguments:
|
||||
|
||||
PoolType - The type of memory for the new pool pages
|
||||
|
||||
NumberOfPages - No of pages to allocate
|
||||
|
||||
Alignment - Bits to align.
|
||||
|
||||
Returns:
|
||||
|
||||
The allocated memory, or NULL
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
VOID
|
||||
CoreFreePoolPages (
|
||||
IN EFI_PHYSICAL_ADDRESS Memory,
|
||||
IN UINTN NumberOfPages
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Internal function. Frees pool pages allocated via AllocatePoolPages ()
|
||||
|
||||
Arguments:
|
||||
|
||||
Memory - The base address to free
|
||||
|
||||
NumberOfPages - The number of pages to free
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
VOID *
|
||||
CoreAllocatePoolI (
|
||||
IN EFI_MEMORY_TYPE PoolType,
|
||||
IN UINTN Size
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Internal function to allocate pool of a particular type.
|
||||
|
||||
Caller must have the memory lock held
|
||||
|
||||
|
||||
Arguments:
|
||||
|
||||
PoolType - Type of pool to allocate
|
||||
|
||||
Size - The amount of pool to allocate
|
||||
|
||||
Returns:
|
||||
|
||||
The allocate pool, or NULL
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
CoreFreePoolI (
|
||||
IN VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Internal function to free a pool entry.
|
||||
|
||||
Caller must have the memory lock held
|
||||
|
||||
|
||||
Arguments:
|
||||
|
||||
Buffer - The allocated pool entry to free
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_INVALID_PARAMETER - Buffer not valid
|
||||
|
||||
EFI_SUCCESS - Buffer successfully freed.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
VOID
|
||||
CoreAcquireMemoryLock (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Enter critical section by gaining lock on gMemoryLock
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
CoreReleaseMemoryLock (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Exit critical section by releasing lock on gMemoryLock
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
//
|
||||
// Internal Global data
|
||||
//
|
||||
|
||||
extern EFI_LOCK gMemoryLock;
|
||||
extern LIST_ENTRY gMemoryMap;
|
||||
extern MEMORY_MAP *gMemoryLastConvert;
|
||||
extern LIST_ENTRY mGcdMemorySpaceMap;
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user