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:
yshang1 2007-07-04 10:51:54 +00:00
parent db6c5cc103
commit 28a0029718
42 changed files with 24972 additions and 0 deletions

View 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

File diff suppressed because it is too large Load Diff

View 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;
}

File diff suppressed because it is too large Load Diff

View 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

View 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>

View 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);
}

View 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;
}
}
}
}
}

View 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;
}

View 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);

View 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;
}

View 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);
}
}

View 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

View 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;
}
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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

View 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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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 ;
}

View 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;
}

File diff suppressed because it is too large Load Diff

View 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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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;
}

View 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

View 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;
}

File diff suppressed because it is too large Load Diff

View 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;

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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