Unix version of EFI emulator

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2182 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
tgingold
2007-01-06 14:59:06 +00:00
parent 8ba7afaf2e
commit c9093a06e7
187 changed files with 54299 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
<MsaHeader>
<ModuleName>DxeUnixLib</ModuleName>
<ModuleType>DXE_DRIVER</ModuleType>
<GuidValue>f39efc84-8985-11db-ad67-0040d02b1835</GuidValue>
<Version>1.0</Version>
<Abstract>A library to produce the global variable 'gUnix'</Abstract>
<Description>This library contains a single global variable 'gUnix' along with a constructor to initialize that global.</Description>
<Copyright>Copyright (c) 2006, 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>DxeUnixLib</OutputFileBasename>
</ModuleDefinitions>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_PRODUCED">
<Keyword>UnixLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>DebugLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>HobLib</Keyword>
</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>UnixLib.c</Filename>
</SourceFiles>
<PackageDependencies>
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
<Package PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835"/>
</PackageDependencies>
<Protocols>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiUnixThunkProtocolGuid</ProtocolCName>
</Protocol>
</Protocols>
<Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
<Extern>
<Constructor>UnixLibConstructor</Constructor>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,48 @@
/*++
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:
UnixLib.c
Abstract:
Unix Library
--*/
EFI_UNIX_THUNK_PROTOCOL *gUnix;
EFI_STATUS
UnixLibConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Arguments:
Returns:
--*/
{
EFI_HOB_GUID_TYPE *GuidHob;
GuidHob = GetFirstGuidHob (&gEfiUnixThunkProtocolGuid);
ASSERT (GuidHob != NULL);
gUnix = (EFI_UNIX_THUNK_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob)));
ASSERT (gUnix != NULL);
return EFI_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,798 @@
/*++
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:
BdsBoot.c
Abstract:
BDS Lib functions which relate with create or process the boot
option.
--*/
#include "Performance.h"
BOOLEAN mEnumBootDevice = FALSE;
EFI_STATUS
BdsLibDoLegacyBoot (
IN BDS_COMMON_OPTION *Option
)
/*++
Routine Description:
Boot the legacy system with the boot option
Arguments:
Option - The legacy boot option which have BBS device path
Returns:
EFI_UNSUPPORTED - There is no legacybios protocol, do not support
legacy boot.
EFI_STATUS - Return the status of LegacyBios->LegacyBoot ().
--*/
{
EFI_STATUS Status;
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL,
(void **)&LegacyBios);
if (EFI_ERROR (Status)) {
//
// If no LegacyBios protocol we do not support legacy boot
//
return EFI_UNSUPPORTED;
}
//
// Notes: if we seperate the int 19, then we don't need to refresh BBS
//
BdsRefreshBbsTableForBoot (Option);
//
// Write boot to OS performance data to a file
//
PERF_CODE (
WriteBootToOsPerformanceData ();
);
DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Legacy Boot: %S\n", Option->Description));
return LegacyBios->LegacyBoot (
LegacyBios,
(BBS_BBS_DEVICE_PATH *) Option->DevicePath,
Option->LoadOptionsSize,
Option->LoadOptions
);
}
EFI_STATUS
BdsLibBootViaBootOption (
IN BDS_COMMON_OPTION * Option,
IN EFI_DEVICE_PATH_PROTOCOL * DevicePath,
OUT UINTN *ExitDataSize,
OUT CHAR16 **ExitData OPTIONAL
)
/*++
Routine Description:
Process the boot option follow the EFI 1.1 specification and
special treat the legacy boot option with BBS_DEVICE_PATH.
Arguments:
Option - The boot option need to be processed
DevicePath - The device path which describe where to load
the boot image or the legcy BBS device path
to boot the legacy OS
ExitDataSize - Returned directly from gBS->StartImage ()
ExitData - Returned directly from gBS->StartImage ()
Returns:
EFI_SUCCESS - Status from gBS->StartImage (),
or BdsBootByDiskSignatureAndPartition ()
EFI_NOT_FOUND - If the Device Path is not found in the system
--*/
{
EFI_STATUS Status;
EFI_HANDLE Handle;
EFI_HANDLE ImageHandle;
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
EFI_DEVICE_PATH_PROTOCOL *FilePath;
EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;
*ExitDataSize = 0;
*ExitData = NULL;
//
// Notes: put EFI64 ROM Shadow Solution
//
EFI64_SHADOW_ALL_LEGACY_ROM ();
//
// Notes: this code can be remove after the s3 script table
// hook on the event EFI_EVENT_SIGNAL_READY_TO_BOOT or
// EFI_EVENT_SIGNAL_LEGACY_BOOT
//
Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL,
(VOID **)&AcpiS3Save);
if (!EFI_ERROR (Status)) {
AcpiS3Save->S3Save (AcpiS3Save, NULL);
}
//
// If it's Device Path that starts with a hard drive path,
// this routine will do the booting.
//
Status = BdsBootByDiskSignatureAndPartition (
Option,
(HARDDRIVE_DEVICE_PATH *) DevicePath,
Option->LoadOptionsSize,
Option->LoadOptions,
ExitDataSize,
ExitData
);
if (!EFI_ERROR (Status)) {
//
// If we found a disk signature and partition device path return success
//
return EFI_SUCCESS;
}
EfiSignalEventReadyToBoot ();
//
// Set Boot Current
//
gRT->SetVariable (
L"BootCurrent",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof (UINT16),
&Option->BootCurrent
);
if ((DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) &&
(DevicePathSubType (Option->DevicePath) == BBS_BBS_DP)
) {
//
// Check to see if we should legacy BOOT. If yes then do the legacy boot
//
return BdsLibDoLegacyBoot (Option);
}
DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Booting EFI 1.1 way %S\n", Option->Description));
Status = gBS->LoadImage (
TRUE,
mBdsImageHandle,
DevicePath,
NULL,
0,
&ImageHandle
);
//
// If we didn't find an image, we may need to load the default
// boot behavior for the device.
//
if (EFI_ERROR (Status)) {
//
// Find a Simple File System protocol on the device path. If the remaining
// device path is set to end then no Files are being specified, so try
// the removable media file name.
//
TempDevicePath = DevicePath;
Status = gBS->LocateDevicePath (
&gEfiSimpleFileSystemProtocolGuid,
&TempDevicePath,
&Handle
);
if (!EFI_ERROR (Status) && IsDevicePathEnd (TempDevicePath)) {
FilePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);
if (FilePath) {
Status = gBS->LoadImage (
TRUE,
mBdsImageHandle,
FilePath,
NULL,
0,
&ImageHandle
);
if (EFI_ERROR (Status)) {
//
// The DevicePath failed, and it's not a valid
// removable media device.
//
goto Done;
}
}
} else {
Status = EFI_NOT_FOUND;
}
}
if (EFI_ERROR (Status)) {
//
// It there is any error from the Boot attempt exit now.
//
goto Done;
}
//
// Provide the image with it's load options
//
Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid,
(VOID **) &ImageInfo);
ASSERT_EFI_ERROR (Status);
if (Option->LoadOptionsSize != 0) {
ImageInfo->LoadOptionsSize = Option->LoadOptionsSize;
ImageInfo->LoadOptions = Option->LoadOptions;
}
//
// Before calling the image, enable the Watchdog Timer for
// the 5 Minute period
//
gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
Status = gBS->StartImage (ImageHandle, ExitDataSize, ExitData);
DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Image Return Status = %r\n", Status));
//
// Clear the Watchdog Timer after the image returns
//
gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
Done:
//
// Clear Boot Current
//
gRT->SetVariable (
L"BootCurrent",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
0,
&Option->BootCurrent
);
return Status;
}
EFI_STATUS
BdsBootByDiskSignatureAndPartition (
IN BDS_COMMON_OPTION * Option,
IN HARDDRIVE_DEVICE_PATH * HardDriveDevicePath,
IN UINT32 LoadOptionsSize,
IN VOID *LoadOptions,
OUT UINTN *ExitDataSize,
OUT CHAR16 **ExitData OPTIONAL
)
/*++
Routine Description:
Check to see if a hard ware device path was passed in. If it was then search
all the block IO devices for the passed in hard drive device path.
Arguments:
Option - The current processing boot option.
HardDriveDevicePath - EFI Device Path to boot, if it starts with a hard
drive device path.
LoadOptionsSize - Passed into gBS->StartImage ()
via the loaded image protocol.
LoadOptions - Passed into gBS->StartImage ()
via the loaded image protocol.
ExitDataSize - returned directly from gBS->StartImage ()
ExitData - returned directly from gBS->StartImage ()
Returns:
EFI_SUCCESS - Status from gBS->StartImage (),
or BootByDiskSignatureAndPartition ()
EFI_NOT_FOUND - If the Device Path is not found in the system
--*/
{
EFI_STATUS Status;
UINTN BlockIoHandleCount;
EFI_HANDLE *BlockIoBuffer;
EFI_DEVICE_PATH_PROTOCOL *BlockIoDevicePath;
EFI_DEVICE_PATH_PROTOCOL *BlockIoHdDevicePath;
HARDDRIVE_DEVICE_PATH *TmpHdPath;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
UINTN Index;
BOOLEAN DevicePathMatch;
HARDDRIVE_DEVICE_PATH *TempPath;
*ExitDataSize = 0;
*ExitData = NULL;
if ( !((DevicePathType (&HardDriveDevicePath->Header) == MEDIA_DEVICE_PATH) &&
(DevicePathSubType (&HardDriveDevicePath->Header) == MEDIA_HARDDRIVE_DP))
) {
//
// If the HardDriveDevicePath does not start with a Hard Drive Device Path
// exit.
//
return EFI_NOT_FOUND;
}
//
// The boot device have already been connected
//
Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &BlockIoHandleCount, &BlockIoBuffer);
if (EFI_ERROR (Status) || BlockIoHandleCount == 0) {
//
// If there was an error or there are no device handles that support
// the BLOCK_IO Protocol, then return.
//
return EFI_NOT_FOUND;
}
//
// Loop through all the device handles that support the BLOCK_IO Protocol
//
for (Index = 0; Index < BlockIoHandleCount; Index++) {
Status = gBS->HandleProtocol (BlockIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID *) &BlockIoDevicePath);
if (EFI_ERROR (Status) || BlockIoDevicePath == NULL) {
continue;
}
//
// Make PreviousDevicePath == the device path node before the end node
//
DevicePath = BlockIoDevicePath;
BlockIoHdDevicePath = NULL;
//
// find HardDriver device path node
//
while (!IsDevicePathEnd (DevicePath)) {
if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
(DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)
) {
BlockIoHdDevicePath = DevicePath;
break;
}
DevicePath = NextDevicePathNode (DevicePath);
}
if (BlockIoHdDevicePath == NULL) {
continue;
}
//
// See if the harddrive device path in blockio matches the orig Hard Drive Node
//
DevicePathMatch = FALSE;
TmpHdPath = (HARDDRIVE_DEVICE_PATH *) BlockIoHdDevicePath;
TempPath = (HARDDRIVE_DEVICE_PATH *) BdsLibUnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath);
//
// Only several fields will be checked. NOT whole NODE
//
if ( TmpHdPath->PartitionNumber == TempPath->PartitionNumber &&
TmpHdPath->MBRType == TempPath->MBRType &&
TmpHdPath->SignatureType == TempPath->SignatureType &&
CompareGuid ((EFI_GUID *) TmpHdPath->Signature, (EFI_GUID *) TempPath->Signature)) {
//
// Get the matched device path
//
DevicePathMatch = TRUE;
}
//
// Only do the boot, when devicepath match
//
if (DevicePathMatch) {
//
// Combine the Block IO and Hard Drive Device path together and try
// to boot from it.
//
DevicePath = NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath);
NewDevicePath = AppendDevicePath (BlockIoDevicePath, DevicePath);
//
// Recursive boot with new device path
//
Status = BdsLibBootViaBootOption (Option, NewDevicePath, ExitDataSize, ExitData);
if (!EFI_ERROR (Status)) {
break;
}
}
}
gBS->FreePool (BlockIoBuffer);
return Status;
}
EFI_STATUS
BdsLibEnumerateAllBootOption (
IN OUT LIST_ENTRY *BdsBootOptionList
)
/*++
Routine Description:
This function will enumerate all possible boot device in the system,
it will only excute once of every boot.
Arguments:
BdsBootOptionList - The header of the link list which indexed all
current boot options
Returns:
EFI_SUCCESS - Finished all the boot device enumerate and create
the boot option base on that boot device
--*/
{
EFI_STATUS Status;
UINT16 BootOptionNumber;
UINTN NumberFileSystemHandles;
EFI_HANDLE *FileSystemHandles;
UINTN NumberBlkIoHandles;
EFI_HANDLE *BlkIoHandles;
EFI_BLOCK_IO_PROTOCOL *BlkIo;
UINTN Index;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
UINTN NumberLoadFileHandles;
EFI_HANDLE *LoadFileHandles;
VOID *ProtocolInstance;
EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
UINTN FvHandleCount;
EFI_HANDLE *FvHandleBuffer;
EFI_FV_FILETYPE Type;
UINTN Size;
EFI_FV_FILE_ATTRIBUTES Attributes;
UINT32 AuthenticationStatus;
BootOptionNumber = 0;
//
// If the boot device enumerate happened, just get the boot
// device from the boot order variable
//
if (mEnumBootDevice) {
BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
return EFI_SUCCESS;
}
//
// Notes: this dirty code is to get the legacy boot option from the
// BBS table and create to variable as the EFI boot option, it should
// be removed after the CSM can provide legacy boot option directly
//
REFRESH_LEGACY_BOOT_OPTIONS;
//
// Check all the block IO to create boot option
//
gBS->LocateHandleBuffer (
ByProtocol,
&gEfiBlockIoProtocolGuid,
NULL,
&NumberBlkIoHandles,
&BlkIoHandles
);
for (Index = 0; Index < NumberBlkIoHandles; Index++) {
Status = gBS->HandleProtocol (
BlkIoHandles[Index],
&gEfiBlockIoProtocolGuid,
(VOID **) &BlkIo
);
if (EFI_ERROR (Status)) {
continue;
}
if (!BlkIo->Media->RemovableMedia) {
//
// Skip fixed Media device on first loop interration
//
continue;
}
DevicePath = DevicePathFromHandle (BlkIoHandles[Index]);
if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
(DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)
) {
//
// Build the boot option
//
BdsLibBuildOptionFromHandle (BlkIoHandles[Index], BdsBootOptionList);
BootOptionNumber++;
}
}
if (NumberBlkIoHandles) {
gBS->FreePool (BlkIoHandles);
}
//
// Parse Fixed Disk Devices.
//
gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleFileSystemProtocolGuid,
NULL,
&NumberFileSystemHandles,
&FileSystemHandles
);
for (Index = 0; Index < NumberFileSystemHandles; Index++) {
Status = gBS->HandleProtocol (
FileSystemHandles[Index],
&gEfiBlockIoProtocolGuid,
(VOID **) &BlkIo
);
if (!EFI_ERROR (Status)) {
if (BlkIo->Media->RemovableMedia) {
//
// If the file system handle supports a BlkIo protocol,
// skip the removable media devices
//
continue;
}
}
DevicePath = DevicePathFromHandle (FileSystemHandles[Index]);
if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
(DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)
) {
//
// If the FileSystem protocol does not contain a BlkIo protocol,
// then build it
//
BdsLibBuildOptionFromHandle (FileSystemHandles[Index], BdsBootOptionList);
BootOptionNumber++;
}
}
if (NumberFileSystemHandles) {
gBS->FreePool (FileSystemHandles);
}
//
// Parse Network Boot Device
//
gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleNetworkProtocolGuid,
NULL,
&NumberLoadFileHandles,
&LoadFileHandles
);
for (Index = 0; Index < NumberLoadFileHandles; Index++) {
Status = gBS->HandleProtocol (
LoadFileHandles[Index],
&gEfiLoadFileProtocolGuid,
(VOID **) &ProtocolInstance
);
if (EFI_ERROR (Status)) {
continue;
}
BdsLibBuildOptionFromHandle (LoadFileHandles[Index], BdsBootOptionList);
BootOptionNumber++;
}
if (NumberLoadFileHandles) {
gBS->FreePool (LoadFileHandles);
}
//
// Check if we have on flash shell
//
gBS->LocateHandleBuffer (
ByProtocol,
&gEfiFirmwareVolumeProtocolGuid,
NULL,
&FvHandleCount,
&FvHandleBuffer
);
for (Index = 0; Index < FvHandleCount; Index++) {
gBS->HandleProtocol (
FvHandleBuffer[Index],
&gEfiFirmwareVolumeProtocolGuid,
(VOID **) &Fv
);
Status = Fv->ReadFile (
Fv,
&gEfiShellFileGuid,
NULL,
&Size,
&Type,
&Attributes,
&AuthenticationStatus
);
if (EFI_ERROR (Status)) {
//
// Skip if no shell file in the FV
//
continue;
}
//
// Build the shell boot option
//
BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);
BootOptionNumber++;
}
if (FvHandleCount) {
gBS->FreePool (FvHandleBuffer);
}
//
// Make sure every boot only have one time
// boot device enumerate
//
BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
mEnumBootDevice = TRUE;
return EFI_SUCCESS;
}
VOID
BdsLibBuildOptionFromHandle (
IN EFI_HANDLE Handle,
IN LIST_ENTRY *BdsBootOptionList
)
/*++
Routine Description:
Build the boot option with the handle parsed in
Arguments:
Handle - The handle which present the device path to create boot option
BdsBootOptionList - The header of the link list which indexed all current
boot options
Returns:
VOID
--*/
{
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
CHAR16 *TempString;
DevicePath = DevicePathFromHandle (Handle);
TempString = DevicePathToStr (DevicePath);
//
// Create and register new boot option
//
BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, TempString, L"BootOrder");
}
VOID
BdsLibBuildOptionFromShell (
IN EFI_HANDLE Handle,
IN OUT LIST_ENTRY *BdsBootOptionList
)
/*++
Routine Description:
Build the on flash shell boot option with the handle parsed in
Arguments:
Handle - The handle which present the device path to create on flash shell
boot option
BdsBootOptionList - The header of the link list which indexed all current
boot options
Returns:
None
--*/
{
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode;
DevicePath = DevicePathFromHandle (Handle);
//
// Build the shell device path
//
EfiInitializeFwVolDevicepathNode (&ShellNode, &gEfiShellFileGuid);
DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &ShellNode);
//
// Create and register the shell boot option
//
BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, L"Internal EFI Shell", L"BootOrder");
}
VOID
BdsLibBootNext (
VOID
)
/*++
Routine Description:
Boot from the EFI1.1 spec defined "BootNext" variable
Arguments:
None
Returns:
None
--*/
{
UINT16 *BootNext;
UINTN BootNextSize;
CHAR16 Buffer[20];
BDS_COMMON_OPTION *BootOption;
LIST_ENTRY TempList;
UINTN ExitDataSize;
CHAR16 *ExitData;
//
// Init the boot option name buffer and temp link list
//
InitializeListHead (&TempList);
ZeroMem (Buffer, sizeof (Buffer));
BootNext = BdsLibGetVariableAndSize (
L"BootNext",
&gEfiGlobalVariableGuid,
&BootNextSize
);
//
// Clear the boot next variable first
//
if (BootNext != NULL) {
gRT->SetVariable (
L"BootNext",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
BootNext
);
//
// Start to build the boot option and try to boot
//
UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *BootNext);
BootOption = BdsLibVariableToOption (&TempList, Buffer);
BdsLibConnectDevicePath (BootOption->DevicePath);
BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);
}
}

View File

@@ -0,0 +1,357 @@
/*++
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:
BdsConnect.c
Abstract:
BDS Lib functions which relate with connect the device
--*/
VOID
BdsLibConnectAll (
VOID
)
/*++
Routine Description:
This function will connect all the system driver to controller
first, and then special connect the default console, this make
sure all the system controller avialbe and the platform default
console connected.
Arguments:
None
Returns:
None
--*/
{
//
// Connect the platform console first
//
BdsLibConnectAllDefaultConsoles ();
//
// Generic way to connect all the drivers
//
BdsLibConnectAllDriversToAllControllers ();
//
// Here we have the assumption that we have already had
// platform default console
//
BdsLibConnectAllDefaultConsoles ();
}
VOID
BdsLibGenericConnectAll (
VOID
)
/*++
Routine Description:
This function will connect all the system drivers to all controllers
first, and then connect all the console devices the system current
have. After this we should get all the device work and console avariable
if the system have console device.
Arguments:
None
Returns:
None
--*/
{
//
// Most generic way to connect all the drivers
//
BdsLibConnectAllDriversToAllControllers ();
BdsLibConnectAllConsoles ();
}
EFI_STATUS
BdsLibConnectDevicePath (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect
)
/*++
Routine Description:
This function will create all handles associate with every device
path node. If the handle associate with one device path node can not
be created success, then still give one chance to do the dispatch,
which load the missing drivers if possible.
Arguments:
DevicePathToConnect - The device path which will be connected, it can
be a multi-instance device path
Returns:
EFI_SUCCESS - All handles associate with every device path
node have been created
EFI_OUT_OF_RESOURCES - There is no resource to create new handles
EFI_NOT_FOUND - Create the handle associate with one device
path node failed
--*/
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;
EFI_DEVICE_PATH_PROTOCOL *Instance;
EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
EFI_DEVICE_PATH_PROTOCOL *Next;
EFI_HANDLE Handle;
EFI_HANDLE PreviousHandle;
UINTN Size;
if (DevicePathToConnect == NULL) {
return EFI_SUCCESS;
}
DevicePath = DuplicateDevicePath (DevicePathToConnect);
CopyOfDevicePath = DevicePath;
if (DevicePath == NULL) {
return EFI_OUT_OF_RESOURCES;
}
do {
//
// The outer loop handles multi instance device paths.
// Only console variables contain multiple instance device paths.
//
// After this call DevicePath points to the next Instance
//
Instance = GetNextDevicePathInstance (&DevicePath, &Size);
Next = Instance;
while (!IsDevicePathEndType (Next)) {
Next = NextDevicePathNode (Next);
}
SetDevicePathEndNode (Next);
//
// Start the real work of connect with RemainingDevicePath
//
PreviousHandle = NULL;
do {
//
// Find the handle that best matches the Device Path. If it is only a
// partial match the remaining part of the device path is returned in
// RemainingDevicePath.
//
RemainingDevicePath = Instance;
Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle);
if (!EFI_ERROR (Status)) {
if (Handle == PreviousHandle) {
//
// If no forward progress is made try invoking the Dispatcher.
// A new FV may have been added to the system an new drivers
// may now be found.
// Status == EFI_SUCCESS means a driver was dispatched
// Status == EFI_NOT_FOUND means no new drivers were dispatched
//
Status = gDS->Dispatch ();
}
if (!EFI_ERROR (Status)) {
PreviousHandle = Handle;
//
// Connect all drivers that apply to Handle and RemainingDevicePath,
// the Recursive flag is FALSE so only one level will be expanded.
//
// Do not check the connect status here, if the connect controller fail,
// then still give the chance to do dispatch, because partial
// RemainingDevicepath may be in the new FV
//
// 1. If the connect fail, RemainingDevicepath and handle will not
// change, so next time will do the dispatch, then dispatch's status
// will take effect
// 2. If the connect success, the RemainingDevicepath and handle will
// change, then avoid the dispatch, we have chance to continue the
// next connection
//
gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);
}
}
//
// Loop until RemainingDevicePath is an empty device path
//
} while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));
} while (DevicePath != NULL);
if (CopyOfDevicePath != NULL) {
gBS->FreePool (CopyOfDevicePath);
}
//
// All handle with DevicePath exists in the handle database
//
return Status;
}
EFI_STATUS
BdsLibConnectAllEfi (
VOID
)
/*++
Routine Description:
This function will connect all current system handles recursively. The
connection will finish until every handle's child handle created if it have.
Arguments:
None
Returns:
EFI_SUCCESS - All handles and it's child handle have been connected
EFI_STATUS - Return the status of gBS->LocateHandleBuffer().
--*/
{
EFI_STATUS Status;
UINTN HandleCount;
EFI_HANDLE *HandleBuffer;
UINTN Index;
Status = gBS->LocateHandleBuffer (
AllHandles,
NULL,
NULL,
&HandleCount,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return Status;
}
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
}
gBS->FreePool (HandleBuffer);
return EFI_SUCCESS;
}
EFI_STATUS
BdsLibDisconnectAllEfi (
VOID
)
/*++
Routine Description:
This function will disconnect all current system handles. The disconnection
will finish until every handle have been disconnected.
Arguments:
None
Returns:
EFI_SUCCESS - All handles have been disconnected
EFI_STATUS - Return the status of gBS->LocateHandleBuffer().
--*/
{
EFI_STATUS Status;
UINTN HandleCount;
EFI_HANDLE *HandleBuffer;
UINTN Index;
//
// Disconnect all
//
Status = gBS->LocateHandleBuffer (
AllHandles,
NULL,
NULL,
&HandleCount,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return Status;
}
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
}
gBS->FreePool (HandleBuffer);
return EFI_SUCCESS;
}
VOID
BdsLibConnectAllDriversToAllControllers (
VOID
)
/*++
Routine Description:
Connects all drivers to all controllers.
This function make sure all the current system driver will manage
the correspoinding controllers if have. And at the same time, make
sure all the system controllers have driver to manage it if have.
Arguments:
None
Returns:
None
--*/
{
EFI_STATUS Status;
do {
//
// Connect All EFI 1.10 drivers following EFI 1.10 algorithm
//
BdsLibConnectAllEfi ();
//
// Check to see if it's possible to dispatch an more DXE drivers.
// The BdsLibConnectAllEfi () may have made new DXE drivers show up.
// If anything is Dispatched Status == EFI_SUCCESS and we will try
// the connect again.
//
Status = gDS->Dispatch ();
} while (!EFI_ERROR (Status));
}

View File

@@ -0,0 +1,370 @@
/*++
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:
BdsConsole.c
Abstract:
BDS Lib functions which contain all the code to connect console device
--*/
EFI_STATUS
BdsLibUpdateConsoleVariable (
IN CHAR16 *ConVarName,
IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath,
IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath
)
/*++
Routine Description:
This function update console variable based on ConVarName, it can
add or remove one specific console device path from the variable
Arguments:
ConVarName - Console related variable name, ConIn, ConOut, ErrOut.
CustomizedConDevicePath - The console device path which will be added to
the console variable ConVarName, this parameter
can not be multi-instance.
ExclusiveDevicePath - The console device path which will be removed
from the console variable ConVarName, this
parameter can not be multi-instance.
Returns:
EFI_UNSUPPORTED - Add or remove the same device path.
EFI_SUCCESS - Success add or remove the device path from
the console variable.
--*/
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *VarConsole;
UINTN DevicePathSize;
EFI_DEVICE_PATH_PROTOCOL *Instance;
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
VarConsole = NULL;
DevicePathSize = 0;
NewDevicePath = NULL;
Status = EFI_UNSUPPORTED;
//
// Notes: check the device path point, here should check
// with compare memory
//
if (CustomizedConDevicePath == ExclusiveDevicePath) {
return EFI_UNSUPPORTED;
}
//
// Delete the ExclusiveDevicePath from current default console
//
VarConsole = BdsLibGetVariableAndSize (
ConVarName,
&gEfiGlobalVariableGuid,
&DevicePathSize
);
if (ExclusiveDevicePath != NULL && VarConsole != NULL) {
if (BdsLibMatchDevicePaths (VarConsole, ExclusiveDevicePath)) {
Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);
while (VarConsole != NULL) {
if (CompareMem (
Instance,
ExclusiveDevicePath,
DevicePathSize - sizeof (EFI_DEVICE_PATH_PROTOCOL)
) == 0) {
//
// Remove the match part
//
NewDevicePath = AppendDevicePathInstance (NewDevicePath, VarConsole);
break;
} else {
//
// Continue the next instance
//
NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);
}
Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);
}
//
// Reset the console variable with new device path
//
gRT->SetVariable (
ConVarName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
GetDevicePathSize (NewDevicePath),
NewDevicePath
);
}
}
//
// Try to append customized device path
//
VarConsole = BdsLibGetVariableAndSize (
ConVarName,
&gEfiGlobalVariableGuid,
&DevicePathSize
);
if (CustomizedConDevicePath != NULL) {
if (!BdsLibMatchDevicePaths (VarConsole, CustomizedConDevicePath)) {
//
// In the first check, the default console variable will be null,
// just append current customized device path
//
VarConsole = AppendDevicePathInstance (VarConsole, CustomizedConDevicePath);
//
// Update the variable of the default console
//
gRT->SetVariable (
ConVarName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
GetDevicePathSize (VarConsole),
VarConsole
);
}
}
return EFI_SUCCESS;
}
EFI_STATUS
BdsLibConnectConsoleVariable (
IN CHAR16 *ConVarName
)
/*++
Routine Description:
Connect the console device base on the variable ConVarName, if
device path of the ConVarName is multi-instance device path, if
anyone of the instances is connected success, then this function
will return success.
Arguments:
ConVarName - Console related variable name, ConIn, ConOut, ErrOut.
Returns:
EFI_NOT_FOUND - There is not any console devices connected success
EFI_SUCCESS - Success connect any one instance of the console
device path base on the variable ConVarName.
--*/
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *StartDevicePath;
UINTN VariableSize;
EFI_DEVICE_PATH_PROTOCOL *Instance;
EFI_DEVICE_PATH_PROTOCOL *Next;
EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;
UINTN Size;
BOOLEAN DeviceExist;
Status = EFI_SUCCESS;
DeviceExist = FALSE;
//
// Check if the console variable exist
//
StartDevicePath = BdsLibGetVariableAndSize (
ConVarName,
&gEfiGlobalVariableGuid,
&VariableSize
);
if (StartDevicePath == NULL) {
return EFI_UNSUPPORTED;
}
CopyOfDevicePath = DuplicateDevicePath (StartDevicePath);
do {
//
// Check every instance of the console variable
//
Instance = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);
Next = Instance;
while (!IsDevicePathEndType (Next)) {
Next = NextDevicePathNode (Next);
}
SetDevicePathEndNode (Next);
//
// Connect the instance device path
//
Status = BdsLibConnectDevicePath (Instance);
if (EFI_ERROR (Status)) {
//
// Delete the instance from the console varialbe
//
BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);
} else {
DeviceExist = TRUE;
}
} while (CopyOfDevicePath != NULL);
gBS->FreePool (StartDevicePath);
if (DeviceExist == FALSE) {
return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
VOID
BdsLibConnectAllConsoles (
VOID
)
/*++
Routine Description:
This function will search every simpletxt devive in current system,
and make every simpletxt device as pertantial console device.
Arguments:
None
Returns:
None
--*/
{
EFI_STATUS Status;
UINTN Index;
EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;
UINTN HandleCount;
EFI_HANDLE *HandleBuffer;
Index = 0;
HandleCount = 0;
HandleBuffer = NULL;
ConDevicePath = NULL;
//
// Update all the console varables
//
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleTextInProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiDevicePathProtocolGuid,
(VOID **) &ConDevicePath
);
BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);
}
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleTextOutProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiDevicePathProtocolGuid,
(VOID **) &ConDevicePath
);
BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);
BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);
}
//
// Connect all console variables
//
BdsLibConnectAllDefaultConsoles ();
}
EFI_STATUS
BdsLibConnectAllDefaultConsoles (
VOID
)
/*++
Routine Description:
This function will connect console device base on the console
device variable ConIn, ConOut and ErrOut.
Arguments:
None
Returns:
EFI_SUCCESS - At least one of the ConIn and ConOut device have
been connected success.
EFI_STATUS - Return the status of BdsLibConnectConsoleVariable ().
--*/
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *VarErrout;
UINTN DevicePathSize;
//
// Connect all default console variables
//
Status = BdsLibConnectConsoleVariable (L"ConIn");
if (EFI_ERROR (Status)) {
return Status;
}
Status = BdsLibConnectConsoleVariable (L"ConOut");
if (EFI_ERROR (Status)) {
return Status;
}
//
// Special treat the err out device, becaues the null
// err out var is legal.
//
VarErrout = BdsLibGetVariableAndSize (
L"ErrOut",
&gEfiGlobalVariableGuid,
&DevicePathSize
);
if (VarErrout != NULL) {
BdsLibConnectConsoleVariable (L"ErrOut");
}
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,978 @@
/*++
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:
BdsMisc.c
Abstract:
Misc BDS library function
--*/
#define MAX_STRING_LEN 200
static BOOLEAN mFeaturerSwitch = TRUE;
static BOOLEAN mResetRequired = FALSE;
extern UINT16 gPlatformBootTimeOutDefault;
UINT16
BdsLibGetTimeout (
VOID
)
/*++
Routine Description:
Return the default value for system Timeout variable.
Arguments:
None
Returns:
Timeout value.
--*/
{
UINT16 Timeout;
UINTN Size;
EFI_STATUS Status;
//
// Return Timeout variable or 0xffff if no valid
// Timeout variable exists.
//
Size = sizeof (UINT16);
Status = gRT->GetVariable (L"Timeout", &gEfiGlobalVariableGuid, NULL, &Size, &Timeout);
if (!EFI_ERROR (Status)) {
return Timeout;
}
//
// To make the current EFI Automatic-Test activity possible, just add
// following code to make AutoBoot enabled when this variable is not
// present.
// This code should be removed later.
//
Timeout = gPlatformBootTimeOutDefault;
//
// Notes: Platform should set default variable if non exists on all error cases!!!
//
Status = gRT->SetVariable (
L"Timeout",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (UINT16),
&Timeout
);
return Timeout;
}
VOID
BdsLibLoadDrivers (
IN LIST_ENTRY *BdsDriverLists
)
/*++
Routine Description:
The function will go through the driver optoin link list, load and start
every driver the driver optoin device path point to.
Arguments:
BdsDriverLists - The header of the current driver option link list
Returns:
None
--*/
{
EFI_STATUS Status;
LIST_ENTRY *Link;
BDS_COMMON_OPTION *Option;
EFI_HANDLE ImageHandle;
EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
UINTN ExitDataSize;
CHAR16 *ExitData;
BOOLEAN ReconnectAll;
ReconnectAll = FALSE;
//
// Process the driver option
//
for (Link = BdsDriverLists->ForwardLink; Link != BdsDriverLists; Link = Link->ForwardLink) {
Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
//
// If a load option is not marked as LOAD_OPTION_ACTIVE,
// the boot manager will not automatically load the option.
//
if (!IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_ACTIVE)) {
continue;
}
//
// If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,
// then all of the EFI drivers in the system will be disconnected and
// reconnected after the last driver load option is processed.
//
if (IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_FORCE_RECONNECT)) {
ReconnectAll = TRUE;
}
//
// Make sure the driver path is connected.
//
BdsLibConnectDevicePath (Option->DevicePath);
//
// Load and start the image that Driver#### describes
//
Status = gBS->LoadImage (
FALSE,
mBdsImageHandle,
Option->DevicePath,
NULL,
0,
&ImageHandle
);
if (!EFI_ERROR (Status)) {
gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid,
(VOID **)&ImageInfo);
//
// Verify whether this image is a driver, if not,
// exit it and continue to parse next load option
//
if (ImageInfo->ImageCodeType != EfiBootServicesCode && ImageInfo->ImageCodeType != EfiRuntimeServicesCode) {
gBS->Exit (ImageHandle, EFI_INVALID_PARAMETER, 0, NULL);
continue;
}
if (Option->LoadOptionsSize != 0) {
ImageInfo->LoadOptionsSize = Option->LoadOptionsSize;
ImageInfo->LoadOptions = Option->LoadOptions;
}
//
// Before calling the image, enable the Watchdog Timer for
// the 5 Minute period
//
gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);
DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Driver Return Status = %r\n", Status));
//
// Clear the Watchdog Timer after the image returns
//
gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
}
}
//
// Process the LOAD_OPTION_FORCE_RECONNECT driver option
//
if (ReconnectAll) {
BdsLibDisconnectAllEfi ();
BdsLibConnectAll ();
}
}
EFI_STATUS
BdsLibRegisterNewOption (
IN LIST_ENTRY *BdsOptionList,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN CHAR16 *String,
IN CHAR16 *VariableName
)
/*++
Routine Description:
This function will register the new boot#### or driver#### option base on
the VariableName. The new registered boot#### or driver#### will be linked
to BdsOptionList and also update to the VariableName. After the boot#### or
driver#### updated, the BootOrder or DriverOrder will also be updated.
Arguments:
BdsOptionList - The header of the boot#### or driver#### link list
DevicePath - The device path which the boot####
or driver#### option present
String - The description of the boot#### or driver####
VariableName - Indicate if the boot#### or driver#### option
Returns:
EFI_SUCCESS - The boot#### or driver#### have been success registered
EFI_STATUS - Return the status of gRT->SetVariable ().
--*/
{
EFI_STATUS Status;
UINTN Index;
UINT16 MaxOptionNumber;
UINT16 RegisterOptionNumber;
UINT16 *TempOptionPtr;
UINTN TempOptionSize;
UINT16 *OptionOrderPtr;
VOID *OptionPtr;
UINTN OptionSize;
UINT8 *TempPtr;
EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath;
CHAR16 *Description;
CHAR16 OptionName[10];
BOOLEAN UpdateBootDevicePath;
OptionPtr = NULL;
OptionSize = 0;
TempPtr = NULL;
OptionDevicePath = NULL;
Description = NULL;
MaxOptionNumber = 0;
OptionOrderPtr = NULL;
UpdateBootDevicePath = FALSE;
ZeroMem (OptionName, sizeof (OptionName));
TempOptionSize = 0;
TempOptionPtr = BdsLibGetVariableAndSize (
VariableName,
&gEfiGlobalVariableGuid,
&TempOptionSize
);
//
// Compare with current option variable
//
for (Index = 0; Index < TempOptionSize / sizeof (UINT16); Index++) {
//
// Got the max option#### number
//
if (MaxOptionNumber < TempOptionPtr[Index]) {
MaxOptionNumber = TempOptionPtr[Index];
}
if (*VariableName == 'B') {
UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", TempOptionPtr[Index]);
} else {
UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", TempOptionPtr[Index]);
}
OptionPtr = BdsLibGetVariableAndSize (
OptionName,
&gEfiGlobalVariableGuid,
&OptionSize
);
TempPtr = OptionPtr;
TempPtr += sizeof (UINT32) + sizeof (UINT16);
Description = (CHAR16 *) TempPtr;
TempPtr += StrSize ((CHAR16 *) TempPtr);
OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
//
// Notes: the description may will change base on the GetStringToken
//
if (CompareMem (Description, String, StrSize (Description)) == 0) {
if (CompareMem (OptionDevicePath, DevicePath, GetDevicePathSize (OptionDevicePath)) == 0) {
//
// Got the option, so just return
//
gBS->FreePool (OptionPtr);
gBS->FreePool (TempOptionPtr);
return EFI_SUCCESS;
} else {
//
// Boot device path changed, need update.
//
UpdateBootDevicePath = TRUE;
break;
}
}
gBS->FreePool (OptionPtr);
}
OptionSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (String) + GetDevicePathSize (DevicePath);
OptionPtr = AllocateZeroPool (OptionSize);
TempPtr = OptionPtr;
*(UINT32 *) TempPtr = LOAD_OPTION_ACTIVE;
TempPtr += sizeof (UINT32);
*(UINT16 *) TempPtr = (UINT16) GetDevicePathSize (DevicePath);
TempPtr += sizeof (UINT16);
CopyMem (TempPtr, String, StrSize (String));
TempPtr += StrSize (String);
CopyMem (TempPtr, DevicePath, GetDevicePathSize (DevicePath));
if (UpdateBootDevicePath) {
//
// The number in option#### to be updated
//
RegisterOptionNumber = TempOptionPtr[Index];
} else {
//
// The new option#### number
//
RegisterOptionNumber = MaxOptionNumber + 1;
}
if (*VariableName == 'B') {
UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", RegisterOptionNumber);
} else {
UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", RegisterOptionNumber);
}
Status = gRT->SetVariable (
OptionName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
OptionSize,
OptionPtr
);
if (EFI_ERROR (Status) || UpdateBootDevicePath) {
gBS->FreePool (OptionPtr);
gBS->FreePool (TempOptionPtr);
return Status;
}
gBS->FreePool (OptionPtr);
//
// Update the option order variable
//
OptionOrderPtr = AllocateZeroPool ((Index + 1) * sizeof (UINT16));
CopyMem (OptionOrderPtr, TempOptionPtr, Index * sizeof (UINT16));
OptionOrderPtr[Index] = RegisterOptionNumber;
Status = gRT->SetVariable (
VariableName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
(Index + 1) * sizeof (UINT16),
OptionOrderPtr
);
if (EFI_ERROR (Status)) {
gBS->FreePool (TempOptionPtr);
gBS->FreePool (OptionOrderPtr);
return Status;
}
gBS->FreePool (TempOptionPtr);
gBS->FreePool (OptionOrderPtr);
return EFI_SUCCESS;
}
BDS_COMMON_OPTION *
BdsLibVariableToOption (
IN OUT LIST_ENTRY *BdsCommonOptionList,
IN CHAR16 *VariableName
)
/*++
Routine Description:
Build the boot#### or driver#### option from the VariableName, the
build boot#### or driver#### will also be linked to BdsCommonOptionList
Arguments:
BdsCommonOptionList - The header of the boot#### or driver#### option link list
VariableName - EFI Variable name indicate if it is boot#### or driver####
Returns:
BDS_COMMON_OPTION - Get the option just been created
NULL - Failed to get the new option
--*/
{
UINT32 Attribute;
UINT16 FilePathSize;
UINT8 *Variable;
UINT8 *TempPtr;
UINTN VariableSize;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
BDS_COMMON_OPTION *Option;
VOID *LoadOptions;
UINT32 LoadOptionsSize;
CHAR16 *Description;
//
// Read the variable. We will never free this data.
//
Variable = BdsLibGetVariableAndSize (
VariableName,
&gEfiGlobalVariableGuid,
&VariableSize
);
if (Variable == NULL) {
return NULL;
}
//
// Notes: careful defined the variable of Boot#### or
// Driver####, consider use some macro to abstract the code
//
//
// Get the option attribute
//
TempPtr = Variable;
Attribute = *(UINT32 *) Variable;
TempPtr += sizeof (UINT32);
//
// Get the option's device path size
//
FilePathSize = *(UINT16 *) TempPtr;
TempPtr += sizeof (UINT16);
//
// Get the option's description string
//
Description = (CHAR16 *) TempPtr;
//
// Get the option's description string size
//
TempPtr += StrSize ((CHAR16 *) TempPtr);
//
// Get the option's device path
//
DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
TempPtr += FilePathSize;
LoadOptions = TempPtr;
LoadOptionsSize = (UINT32) (VariableSize - (UINTN) (TempPtr - Variable));
//
// The Console variables may have multiple device paths, so make
// an Entry for each one.
//
Option = AllocateZeroPool (sizeof (BDS_COMMON_OPTION));
if (Option == NULL) {
return NULL;
}
Option->Signature = BDS_LOAD_OPTION_SIGNATURE;
Option->DevicePath = AllocateZeroPool (GetDevicePathSize (DevicePath));
CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));
Option->Attribute = Attribute;
Option->Description = AllocateZeroPool (StrSize (Description));
CopyMem (Option->Description, Description, StrSize (Description));
Option->LoadOptions = AllocateZeroPool (LoadOptionsSize);
CopyMem (Option->LoadOptions, LoadOptions, LoadOptionsSize);
Option->LoadOptionsSize = LoadOptionsSize;
//
// Insert active entry to BdsDeviceList
//
if ((Option->Attribute & LOAD_OPTION_ACTIVE) == LOAD_OPTION_ACTIVE) {
InsertTailList (BdsCommonOptionList, &Option->Link);
gBS->FreePool (Variable);
return Option;
}
gBS->FreePool (Variable);
gBS->FreePool (Option);
return NULL;
}
EFI_STATUS
BdsLibBuildOptionFromVar (
IN LIST_ENTRY *BdsCommonOptionList,
IN CHAR16 *VariableName
)
/*++
Routine Description:
Process BootOrder, or DriverOrder variables, by calling
BdsLibVariableToOption () for each UINT16 in the variables.
Arguments:
BdsCommonOptionList - The header of the option list base on variable
VariableName
VariableName - EFI Variable name indicate the BootOrder or DriverOrder
Returns:
EFI_SUCCESS - Success create the boot option or driver option list
EFI_OUT_OF_RESOURCES - Failed to get the boot option or driver option list
--*/
{
UINT16 *OptionOrder;
UINTN OptionOrderSize;
UINTN Index;
BDS_COMMON_OPTION *Option;
CHAR16 OptionName[20];
//
// Zero Buffer in order to get all BOOT#### variables
//
ZeroMem (OptionName, sizeof (OptionName));
//
// Read the BootOrder, or DriverOrder variable.
//
OptionOrder = BdsLibGetVariableAndSize (
VariableName,
&gEfiGlobalVariableGuid,
&OptionOrderSize
);
if (OptionOrder == NULL) {
return EFI_OUT_OF_RESOURCES;
}
for (Index = 0; Index < OptionOrderSize / sizeof (UINT16); Index++) {
if (*VariableName == 'B') {
UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionOrder[Index]);
} else {
UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", OptionOrder[Index]);
}
Option = BdsLibVariableToOption (BdsCommonOptionList, OptionName);
Option->BootCurrent = OptionOrder[Index];
}
gBS->FreePool (OptionOrder);
return EFI_SUCCESS;
}
EFI_STATUS
BdsLibGetBootMode (
OUT EFI_BOOT_MODE *BootMode
)
/*++
Routine Description:
Get boot mode by looking up configuration table and parsing HOB list
Arguments:
BootMode - Boot mode from PEI handoff HOB.
Returns:
EFI_SUCCESS - Successfully get boot mode
EFI_NOT_FOUND - Can not find the current system boot mode
--*/
{
EFI_HOB_HANDOFF_INFO_TABLE *HobList;
HobList = GetHobList ();
ASSERT (HobList->Header.HobType == EFI_HOB_TYPE_HANDOFF);
*BootMode = HobList->BootMode;
return EFI_SUCCESS;
}
VOID *
BdsLibGetVariableAndSize (
IN CHAR16 *Name,
IN EFI_GUID *VendorGuid,
OUT UINTN *VariableSize
)
/*++
Routine Description:
Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
buffer, and the size of the buffer. If failure return NULL.
Arguments:
Name - String part of EFI variable name
VendorGuid - GUID part of EFI variable name
VariableSize - Returns the size of the EFI variable that was read
Returns:
Dynamically allocated memory that contains a copy of the EFI variable.
Caller is responsible freeing the buffer.
NULL - Variable was not read
--*/
{
EFI_STATUS Status;
UINTN BufferSize;
VOID *Buffer;
Buffer = NULL;
//
// Pass in a zero size buffer to find the required buffer size.
//
BufferSize = 0;
Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
if (Status == EFI_BUFFER_TOO_SMALL) {
//
// Allocate the buffer to return
//
Buffer = AllocateZeroPool (BufferSize);
if (Buffer == NULL) {
return NULL;
}
//
// Read variable into the allocated buffer.
//
Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
if (EFI_ERROR (Status)) {
BufferSize = 0;
}
}
*VariableSize = BufferSize;
return Buffer;
}
BOOLEAN
BdsLibMatchDevicePaths (
IN EFI_DEVICE_PATH_PROTOCOL *Multi,
IN EFI_DEVICE_PATH_PROTOCOL *Single
)
/*++
Routine Description:
Function compares a device path data structure to that of all the nodes of a
second device path instance.
Arguments:
Multi - A pointer to a multi-instance device path data structure.
Single - A pointer to a single-instance device path data structure.
Returns:
TRUE - If the Single is contained within Multi
FALSE - The Single is not match within Multi
--*/
{
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
UINTN Size;
if (!Multi || !Single) {
return FALSE;
}
DevicePath = Multi;
DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
//
// Search for the match of 'Single' in 'Multi'
//
while (DevicePathInst != NULL) {
//
// If the single device path is found in multiple device paths,
// return success
//
if (CompareMem (Single, DevicePathInst, Size) == 0) {
gBS->FreePool (DevicePathInst);
return TRUE;
}
gBS->FreePool (DevicePathInst);
DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
}
return FALSE;
}
EFI_STATUS
BdsLibOutputStrings (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *ConOut,
...
)
/*++
Routine Description:
This function prints a series of strings.
Arguments:
ConOut - Pointer to EFI_SIMPLE_TEXT_OUT_PROTOCOL
... - A variable argument list containing series of strings,
the last string must be NULL.
Returns:
EFI_SUCCESS - Success print out the string using ConOut.
EFI_STATUS - Return the status of the ConOut->OutputString ().
--*/
{
VA_LIST args;
EFI_STATUS Status;
CHAR16 *String;
Status = EFI_SUCCESS;
VA_START (args, ConOut);
while (!EFI_ERROR (Status)) {
//
// If String is NULL, then it's the end of the list
//
String = VA_ARG (args, CHAR16 *);
if (!String) {
break;
}
Status = ConOut->OutputString (ConOut, String);
if (EFI_ERROR (Status)) {
break;
}
}
return Status;
}
//
// Following are BDS Lib functions which contain all the code about setup browser reset reminder feature.
// Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if
// user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection.
//
VOID
EnableResetReminderFeature (
VOID
)
/*++
Routine Description:
Enable the setup browser reset reminder feature.
This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it.
Arguments:
VOID
Returns:
VOID
--*/
{
mFeaturerSwitch = TRUE;
}
VOID
DisableResetReminderFeature (
VOID
)
/*++
Routine Description:
Disable the setup browser reset reminder feature.
This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it.
Arguments:
VOID
Returns:
VOID
--*/
{
mFeaturerSwitch = FALSE;
}
VOID
EnableResetRequired (
VOID
)
/*++
Routine Description:
Record the info that a reset is required.
A module boolean variable is used to record whether a reset is required.
Arguments:
VOID
Returns:
VOID
--*/
{
mResetRequired = TRUE;
}
VOID
DisableResetRequired (
VOID
)
/*++
Routine Description:
Record the info that no reset is required.
A module boolean variable is used to record whether a reset is required.
Arguments:
VOID
Returns:
VOID
--*/
{
mResetRequired = FALSE;
}
BOOLEAN
IsResetReminderFeatureEnable (
VOID
)
/*++
Routine Description:
Check whether platform policy enable the reset reminder feature. The default is enabled.
Arguments:
VOID
Returns:
VOID
--*/
{
return mFeaturerSwitch;
}
BOOLEAN
IsResetRequired (
VOID
)
/*++
Routine Description:
Check if user changed any option setting which needs a system reset to be effective.
Arguments:
VOID
Returns:
VOID
--*/
{
return mResetRequired;
}
VOID
SetupResetReminder (
VOID
)
/*++
Routine Description:
Check whether a reset is needed, and finish the reset reminder feature.
If a reset is needed, Popup a menu to notice user, and finish the feature
according to the user selection.
Arguments:
VOID
Returns:
VOID
--*/
{
EFI_STATUS Status;
EFI_FORM_BROWSER_PROTOCOL *Browser;
EFI_INPUT_KEY Key;
CHAR16 *StringBuffer1;
CHAR16 *StringBuffer2;
//
//check any reset required change is applied? if yes, reset system
//
if (IsResetReminderFeatureEnable ()) {
if (IsResetRequired ()) {
Status = gBS->LocateProtocol (
&gEfiFormBrowserProtocolGuid,
NULL,
(VOID **)&Browser
);
StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
ASSERT (StringBuffer1 != NULL);
StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
ASSERT (StringBuffer2 != NULL);
StrCpy (StringBuffer1, L"Configuration changed. Reset to apply it Now ? ");
StrCpy (StringBuffer2, L"Enter (YES) / Esc (NO)");
//
// Popup a menu to notice user
//
do {
Browser->CreatePopUp (2, TRUE, 0, NULL, &Key, StringBuffer1, StringBuffer2);
} while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
gBS->FreePool (StringBuffer1);
gBS->FreePool (StringBuffer2);
//
// If the user hits the YES Response key, reset
//
if ((Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) {
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
}
gST->ConOut->ClearScreen (gST->ConOut);
}
}
}

View File

@@ -0,0 +1,983 @@
/*++
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:
BdsMisc.c
Abstract:
Misc BDS library function
--*/
#define MAX_STRING_LEN 200
static BOOLEAN mFeaturerSwitch = TRUE;
static BOOLEAN mResetRequired = FALSE;
extern UINT16 gPlatformBootTimeOutDefault;
UINT16
BdsLibGetTimeout (
VOID
)
/*++
Routine Description:
Return the default value for system Timeout variable.
Arguments:
None
Returns:
Timeout value.
--*/
{
UINT16 Timeout;
UINTN Size;
EFI_STATUS Status;
//
// Return Timeout variable or 0xffff if no valid
// Timeout variable exists.
//
Size = sizeof (UINT16);
Status = gRT->GetVariable (L"Timeout", &gEfiGlobalVariableGuid, NULL, &Size, &Timeout);
if (!EFI_ERROR (Status)) {
return Timeout;
}
//
// To make the current EFI Automatic-Test activity possible, just add
// following code to make AutoBoot enabled when this variable is not
// present.
// This code should be removed later.
//
Timeout = gPlatformBootTimeOutDefault;
//
// Notes: Platform should set default variable if non exists on all error cases!!!
//
Status = gRT->SetVariable (
L"Timeout",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (UINT16),
&Timeout
);
return Timeout;
}
VOID
BdsLibLoadDrivers (
IN LIST_ENTRY *BdsDriverLists
)
/*++
Routine Description:
The function will go through the driver optoin link list, load and start
every driver the driver optoin device path point to.
Arguments:
BdsDriverLists - The header of the current driver option link list
Returns:
None
--*/
{
EFI_STATUS Status;
LIST_ENTRY *Link;
BDS_COMMON_OPTION *Option;
EFI_HANDLE ImageHandle;
EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
UINTN ExitDataSize;
CHAR16 *ExitData;
BOOLEAN ReconnectAll;
ReconnectAll = FALSE;
//
// Process the driver option
//
for (Link = BdsDriverLists->ForwardLink; Link != BdsDriverLists; Link = Link->ForwardLink) {
Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
//
// If a load option is not marked as LOAD_OPTION_ACTIVE,
// the boot manager will not automatically load the option.
//
if (!IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_ACTIVE)) {
continue;
}
//
// If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,
// then all of the EFI drivers in the system will be disconnected and
// reconnected after the last driver load option is processed.
//
if (IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_FORCE_RECONNECT)) {
ReconnectAll = TRUE;
}
//
// Make sure the driver path is connected.
//
BdsLibConnectDevicePath (Option->DevicePath);
//
// Load and start the image that Driver#### describes
//
Status = gBS->LoadImage (
FALSE,
mBdsImageHandle,
Option->DevicePath,
NULL,
0,
&ImageHandle
);
if (!EFI_ERROR (Status)) {
gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid,
(VOID **)&ImageInfo);
//
// Verify whether this image is a driver, if not,
// exit it and continue to parse next load option
//
if (ImageInfo->ImageCodeType != EfiBootServicesCode && ImageInfo->ImageCodeType != EfiRuntimeServicesCode) {
gBS->Exit (ImageHandle, EFI_INVALID_PARAMETER, 0, NULL);
continue;
}
if (Option->LoadOptionsSize != 0) {
ImageInfo->LoadOptionsSize = Option->LoadOptionsSize;
ImageInfo->LoadOptions = Option->LoadOptions;
}
//
// Before calling the image, enable the Watchdog Timer for
// the 5 Minute period
//
gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);
DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Driver Return Status = %r\n", Status));
//
// Clear the Watchdog Timer after the image returns
//
gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
}
}
//
// Process the LOAD_OPTION_FORCE_RECONNECT driver option
//
if (ReconnectAll) {
BdsLibDisconnectAllEfi ();
BdsLibConnectAll ();
}
}
EFI_STATUS
BdsLibRegisterNewOption (
IN LIST_ENTRY *BdsOptionList,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN CHAR16 *String,
IN CHAR16 *VariableName
)
/*++
Routine Description:
This function will register the new boot#### or driver#### option base on
the VariableName. The new registered boot#### or driver#### will be linked
to BdsOptionList and also update to the VariableName. After the boot#### or
driver#### updated, the BootOrder or DriverOrder will also be updated.
Arguments:
BdsOptionList - The header of the boot#### or driver#### link list
DevicePath - The device path which the boot####
or driver#### option present
String - The description of the boot#### or driver####
VariableName - Indicate if the boot#### or driver#### option
Returns:
EFI_SUCCESS - The boot#### or driver#### have been success registered
EFI_STATUS - Return the status of gRT->SetVariable ().
--*/
{
EFI_STATUS Status;
UINTN Index;
UINT16 MaxOptionNumber;
UINT16 RegisterOptionNumber;
UINT16 *TempOptionPtr;
UINTN TempOptionSize;
UINT16 *OptionOrderPtr;
VOID *OptionPtr;
UINTN OptionSize;
UINT8 *TempPtr;
EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath;
CHAR16 *Description;
CHAR16 OptionName[10];
BOOLEAN UpdateBootDevicePath;
OptionPtr = NULL;
OptionSize = 0;
TempPtr = NULL;
OptionDevicePath = NULL;
Description = NULL;
MaxOptionNumber = 0;
OptionOrderPtr = NULL;
UpdateBootDevicePath = FALSE;
ZeroMem (OptionName, sizeof (OptionName));
TempOptionSize = 0;
TempOptionPtr = BdsLibGetVariableAndSize (
VariableName,
&gEfiGlobalVariableGuid,
&TempOptionSize
);
//
// Compare with current option variable
//
for (Index = 0; Index < TempOptionSize / sizeof (UINT16); Index++) {
//
// Got the max option#### number
//
if (MaxOptionNumber < TempOptionPtr[Index]) {
MaxOptionNumber = TempOptionPtr[Index];
}
if (*VariableName == 'B') {
UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", TempOptionPtr[Index]);
} else {
UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", TempOptionPtr[Index]);
}
OptionPtr = BdsLibGetVariableAndSize (
OptionName,
&gEfiGlobalVariableGuid,
&OptionSize
);
TempPtr = OptionPtr;
TempPtr += sizeof (UINT32) + sizeof (UINT16);
Description = (CHAR16 *) TempPtr;
TempPtr += StrSize ((CHAR16 *) TempPtr);
OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
//
// Notes: the description may will change base on the GetStringToken
//
if (CompareMem (Description, String, StrSize (Description)) == 0) {
if (CompareMem (OptionDevicePath, DevicePath, GetDevicePathSize (OptionDevicePath)) == 0) {
//
// Got the option, so just return
//
gBS->FreePool (OptionPtr);
gBS->FreePool (TempOptionPtr);
return EFI_SUCCESS;
} else {
//
// Boot device path changed, need update.
//
UpdateBootDevicePath = TRUE;
break;
}
}
gBS->FreePool (OptionPtr);
}
OptionSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (String) + GetDevicePathSize (DevicePath);
OptionPtr = AllocateZeroPool (OptionSize);
TempPtr = OptionPtr;
*(UINT32 *) TempPtr = LOAD_OPTION_ACTIVE;
TempPtr += sizeof (UINT32);
*(UINT16 *) TempPtr = (UINT16) GetDevicePathSize (DevicePath);
TempPtr += sizeof (UINT16);
CopyMem (TempPtr, String, StrSize (String));
TempPtr += StrSize (String);
CopyMem (TempPtr, DevicePath, GetDevicePathSize (DevicePath));
if (UpdateBootDevicePath) {
//
// The number in option#### to be updated
//
RegisterOptionNumber = TempOptionPtr[Index];
} else {
//
// The new option#### number
//
RegisterOptionNumber = MaxOptionNumber + 1;
}
if (*VariableName == 'B') {
UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", RegisterOptionNumber);
} else {
UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", RegisterOptionNumber);
}
Status = gRT->SetVariable (
OptionName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
OptionSize,
OptionPtr
);
if (EFI_ERROR (Status) || UpdateBootDevicePath) {
gBS->FreePool (OptionPtr);
gBS->FreePool (TempOptionPtr);
return Status;
}
gBS->FreePool (OptionPtr);
//
// Update the option order variable
//
OptionOrderPtr = AllocateZeroPool ((Index + 1) * sizeof (UINT16));
CopyMem (OptionOrderPtr, TempOptionPtr, Index * sizeof (UINT16));
OptionOrderPtr[Index] = RegisterOptionNumber;
Status = gRT->SetVariable (
VariableName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
(Index + 1) * sizeof (UINT16),
OptionOrderPtr
);
if (EFI_ERROR (Status)) {
gBS->FreePool (TempOptionPtr);
gBS->FreePool (OptionOrderPtr);
return Status;
}
gBS->FreePool (TempOptionPtr);
gBS->FreePool (OptionOrderPtr);
return EFI_SUCCESS;
}
BDS_COMMON_OPTION *
BdsLibVariableToOption (
IN OUT LIST_ENTRY *BdsCommonOptionList,
IN CHAR16 *VariableName
)
/*++
Routine Description:
Build the boot#### or driver#### option from the VariableName, the
build boot#### or driver#### will also be linked to BdsCommonOptionList
Arguments:
BdsCommonOptionList - The header of the boot#### or driver#### option link list
VariableName - EFI Variable name indicate if it is boot#### or driver####
Returns:
BDS_COMMON_OPTION - Get the option just been created
NULL - Failed to get the new option
--*/
{
UINT32 Attribute;
UINT16 FilePathSize;
UINT8 *Variable;
UINT8 *TempPtr;
UINTN VariableSize;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
BDS_COMMON_OPTION *Option;
VOID *LoadOptions;
UINT32 LoadOptionsSize;
CHAR16 *Description;
//
// Read the variable. We will never free this data.
//
Variable = BdsLibGetVariableAndSize (
VariableName,
&gEfiGlobalVariableGuid,
&VariableSize
);
if (Variable == NULL) {
return NULL;
}
//
// Notes: careful defined the variable of Boot#### or
// Driver####, consider use some macro to abstract the code
//
//
// Get the option attribute
//
TempPtr = Variable;
Attribute = *(UINT32 *) Variable;
TempPtr += sizeof (UINT32);
//
// Get the option's device path size
//
FilePathSize = *(UINT16 *) TempPtr;
TempPtr += sizeof (UINT16);
//
// Get the option's description string
//
Description = (CHAR16 *) TempPtr;
//
// Get the option's description string size
//
TempPtr += StrSize ((CHAR16 *) TempPtr);
//
// Get the option's device path
//
DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
TempPtr += FilePathSize;
LoadOptions = TempPtr;
LoadOptionsSize = (UINT32) (VariableSize - (UINTN) (TempPtr - Variable));
//
// The Console variables may have multiple device paths, so make
// an Entry for each one.
//
Option = AllocateZeroPool (sizeof (BDS_COMMON_OPTION));
if (Option == NULL) {
return NULL;
}
Option->Signature = BDS_LOAD_OPTION_SIGNATURE;
Option->DevicePath = AllocateZeroPool (GetDevicePathSize (DevicePath));
CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));
Option->Attribute = Attribute;
Option->Description = AllocateZeroPool (StrSize (Description));
CopyMem (Option->Description, Description, StrSize (Description));
Option->LoadOptions = AllocateZeroPool (LoadOptionsSize);
CopyMem (Option->LoadOptions, LoadOptions, LoadOptionsSize);
Option->LoadOptionsSize = LoadOptionsSize;
//
// Insert active entry to BdsDeviceList
//
if ((Option->Attribute & LOAD_OPTION_ACTIVE) == LOAD_OPTION_ACTIVE) {
InsertTailList (BdsCommonOptionList, &Option->Link);
gBS->FreePool (Variable);
return Option;
}
gBS->FreePool (Variable);
gBS->FreePool (Option);
return NULL;
}
EFI_STATUS
BdsLibBuildOptionFromVar (
IN LIST_ENTRY *BdsCommonOptionList,
IN CHAR16 *VariableName
)
/*++
Routine Description:
Process BootOrder, or DriverOrder variables, by calling
BdsLibVariableToOption () for each UINT16 in the variables.
Arguments:
BdsCommonOptionList - The header of the option list base on variable
VariableName
VariableName - EFI Variable name indicate the BootOrder or DriverOrder
Returns:
EFI_SUCCESS - Success create the boot option or driver option list
EFI_OUT_OF_RESOURCES - Failed to get the boot option or driver option list
--*/
{
UINT16 *OptionOrder;
UINTN OptionOrderSize;
UINTN Index;
BDS_COMMON_OPTION *Option;
CHAR16 OptionName[20];
//
// Zero Buffer in order to get all BOOT#### variables
//
ZeroMem (OptionName, sizeof (OptionName));
//
// Read the BootOrder, or DriverOrder variable.
//
OptionOrder = BdsLibGetVariableAndSize (
VariableName,
&gEfiGlobalVariableGuid,
&OptionOrderSize
);
if (OptionOrder == NULL) {
return EFI_OUT_OF_RESOURCES;
}
for (Index = 0; Index < OptionOrderSize / sizeof (UINT16); Index++) {
if (*VariableName == 'B') {
UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionOrder[Index]);
} else {
UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", OptionOrder[Index]);
}
Option = BdsLibVariableToOption (BdsCommonOptionList, OptionName);
Option->BootCurrent = OptionOrder[Index];
}
gBS->FreePool (OptionOrder);
return EFI_SUCCESS;
}
EFI_STATUS
BdsLibGetBootMode (
OUT EFI_BOOT_MODE *BootMode
)
/*++
Routine Description:
Get boot mode by looking up configuration table and parsing HOB list
Arguments:
BootMode - Boot mode from PEI handoff HOB.
Returns:
EFI_SUCCESS - Successfully get boot mode
EFI_NOT_FOUND - Can not find the current system boot mode
--*/
{
EFI_HOB_HANDOFF_INFO_TABLE *HobList;
HobList = GetHobList ();
ASSERT (HobList->Header.HobType == EFI_HOB_TYPE_HANDOFF);
*BootMode = HobList->BootMode;
return EFI_SUCCESS;
}
VOID *
BdsLibGetVariableAndSize (
IN CHAR16 *Name,
IN EFI_GUID *VendorGuid,
OUT UINTN *VariableSize
)
/*++
Routine Description:
Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
buffer, and the size of the buffer. If failure return NULL.
Arguments:
Name - String part of EFI variable name
VendorGuid - GUID part of EFI variable name
VariableSize - Returns the size of the EFI variable that was read
Returns:
Dynamically allocated memory that contains a copy of the EFI variable.
Caller is responsible freeing the buffer.
NULL - Variable was not read
--*/
{
EFI_STATUS Status;
UINTN BufferSize;
VOID *Buffer;
Buffer = NULL;
//
// Pass in a zero size buffer to find the required buffer size.
//
BufferSize = 0;
Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
if (Status == EFI_BUFFER_TOO_SMALL) {
//
// Allocate the buffer to return
//
Buffer = AllocateZeroPool (BufferSize);
if (Buffer == NULL) {
return NULL;
}
//
// Read variable into the allocated buffer.
//
Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
if (EFI_ERROR (Status)) {
BufferSize = 0;
}
}
*VariableSize = BufferSize;
return Buffer;
}
BOOLEAN
BdsLibMatchDevicePaths (
IN EFI_DEVICE_PATH_PROTOCOL *Multi,
IN EFI_DEVICE_PATH_PROTOCOL *Single
)
/*++
Routine Description:
Function compares a device path data structure to that of all the nodes of a
second device path instance.
Arguments:
Multi - A pointer to a multi-instance device path data structure.
Single - A pointer to a single-instance device path data structure.
Returns:
TRUE - If the Single is contained within Multi
FALSE - The Single is not match within Multi
--*/
{
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
UINTN Size;
if (!Multi || !Single) {
return FALSE;
}
DevicePath = Multi;
DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
Size -= sizeof (EFI_DEVICE_PATH_PROTOCOL);
//
// Search for the match of 'Single' in 'Multi'
//
while (DevicePathInst != NULL) {
//
// If the single device path is found in multiple device paths,
// return success
//
if (Size == 0) {
return FALSE;
}
if (CompareMem (Single, DevicePathInst, Size) == 0) {
return TRUE;
}
gBS->FreePool (DevicePathInst);
DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
Size -= sizeof (EFI_DEVICE_PATH_PROTOCOL);
}
return FALSE;
}
EFI_STATUS
BdsLibOutputStrings (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *ConOut,
...
)
/*++
Routine Description:
This function prints a series of strings.
Arguments:
ConOut - Pointer to EFI_SIMPLE_TEXT_OUT_PROTOCOL
... - A variable argument list containing series of strings,
the last string must be NULL.
Returns:
EFI_SUCCESS - Success print out the string using ConOut.
EFI_STATUS - Return the status of the ConOut->OutputString ().
--*/
{
VA_LIST args;
EFI_STATUS Status;
CHAR16 *String;
Status = EFI_SUCCESS;
VA_START (args, ConOut);
while (!EFI_ERROR (Status)) {
//
// If String is NULL, then it's the end of the list
//
String = VA_ARG (args, CHAR16 *);
if (!String) {
break;
}
Status = ConOut->OutputString (ConOut, String);
if (EFI_ERROR (Status)) {
break;
}
}
return Status;
}
//
// Following are BDS Lib functions which contain all the code about setup browser reset reminder feature.
// Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if
// user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection.
//
VOID
EnableResetReminderFeature (
VOID
)
/*++
Routine Description:
Enable the setup browser reset reminder feature.
This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it.
Arguments:
VOID
Returns:
VOID
--*/
{
mFeaturerSwitch = TRUE;
}
VOID
DisableResetReminderFeature (
VOID
)
/*++
Routine Description:
Disable the setup browser reset reminder feature.
This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it.
Arguments:
VOID
Returns:
VOID
--*/
{
mFeaturerSwitch = FALSE;
}
VOID
EnableResetRequired (
VOID
)
/*++
Routine Description:
Record the info that a reset is required.
A module boolean variable is used to record whether a reset is required.
Arguments:
VOID
Returns:
VOID
--*/
{
mResetRequired = TRUE;
}
VOID
DisableResetRequired (
VOID
)
/*++
Routine Description:
Record the info that no reset is required.
A module boolean variable is used to record whether a reset is required.
Arguments:
VOID
Returns:
VOID
--*/
{
mResetRequired = FALSE;
}
BOOLEAN
IsResetReminderFeatureEnable (
VOID
)
/*++
Routine Description:
Check whether platform policy enable the reset reminder feature. The default is enabled.
Arguments:
VOID
Returns:
VOID
--*/
{
return mFeaturerSwitch;
}
BOOLEAN
IsResetRequired (
VOID
)
/*++
Routine Description:
Check if user changed any option setting which needs a system reset to be effective.
Arguments:
VOID
Returns:
VOID
--*/
{
return mResetRequired;
}
VOID
SetupResetReminder (
VOID
)
/*++
Routine Description:
Check whether a reset is needed, and finish the reset reminder feature.
If a reset is needed, Popup a menu to notice user, and finish the feature
according to the user selection.
Arguments:
VOID
Returns:
VOID
--*/
{
EFI_STATUS Status;
EFI_FORM_BROWSER_PROTOCOL *Browser;
EFI_INPUT_KEY Key;
CHAR16 *StringBuffer1;
CHAR16 *StringBuffer2;
//
//check any reset required change is applied? if yes, reset system
//
if (IsResetReminderFeatureEnable ()) {
if (IsResetRequired ()) {
Status = gBS->LocateProtocol (
&gEfiFormBrowserProtocolGuid,
NULL,
(VOID **)&Browser
);
StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
ASSERT (StringBuffer1 != NULL);
StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
ASSERT (StringBuffer2 != NULL);
StrCpy (StringBuffer1, L"Configuration changed. Reset to apply it Now ? ");
StrCpy (StringBuffer2, L"Enter (YES) / Esc (NO)");
//
// Popup a menu to notice user
//
do {
Browser->CreatePopUp (2, TRUE, 0, NULL, &Key, StringBuffer1, StringBuffer2);
} while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
gBS->FreePool (StringBuffer1);
gBS->FreePool (StringBuffer2);
//
// If the user hits the YES Response key, reset
//
if ((Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) {
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
}
gST->ConOut->ClearScreen (gST->ConOut);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
<MsaHeader>
<ModuleName>EdkGenericBdsLib</ModuleName>
<ModuleType>DXE_DRIVER</ModuleType>
<GuidValue>f3aaea62-8985-11db-baff-0040d02b1835</GuidValue>
<Version>1.0</Version>
<Abstract>EDK Generic BDS Common APIs Library Instance.</Abstract>
<Description>The library instance provides common library routines help in
performance measurement, device path debug print, boot device selections,
boot device connection, console supports in BDS phase and boot from boot
device.
</Description>
<Copyright>Copyright (c) 2006, 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>EdkGenericBdsLib</OutputFileBasename>
</ModuleDefinitions>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_PRODUCED">
<Keyword>EdkGenericBdsLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>DxeServicesTableLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>DebugLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>PrintLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>HobLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseMemoryLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>MemoryAllocationLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiBootServicesTableLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiRuntimeServicesTableLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>DevicePathLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>PerformanceLib</Keyword>
</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>BdsBoot.c</Filename>
<Filename>BdsConsole.c</Filename>
<Filename>BdsConnect.c</Filename>
<Filename>DevicePath.c</Filename>
<Filename>Performance.h</Filename>
<Filename>Performance.c</Filename>
<Filename>BdsMisc.c</Filename>
<Filename SupArchList="IPF">Ipf/ShadowRom.c</Filename>
</SourceFiles>
<PackageDependencies>
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
<Package PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835"/>
</PackageDependencies>
<Protocols>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiLoadedImageProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiFirmwareVolumeProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiAcpiS3SaveProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiSimpleTextOutProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiSimpleTextInProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiSimpleNetworkProtocolGuid</ProtocolCName>
</Protocol>
</Protocols>
<Guids>
<GuidCNames Usage="ALWAYS_CONSUMED">
<GuidCName>gEfiShellFileGuid</GuidCName>
</GuidCNames>
</Guids>
<Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
</Externs>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,53 @@
/*++
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:
ShadowRom.c
Abstract:
Shadow all option rom
Revision History
--*/
#include "Tiano.h"
#include "EfiDriverLib.h"
#include EFI_PROTOCOL_DEFINITION (LegacyBios)
UINT8 mShadowRomFlag = 0;
VOID
ShadowAllOptionRom()
{
EFI_STATUS Status;
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
//
// Rom shadow only do once.
//
if (mShadowRomFlag == 0) {
Status = gBS->LocateProtocol (
&gEfiLegacyBiosProtocolGuid,
NULL,
&LegacyBios
);
if (!EFI_ERROR (Status)) {
LegacyBios->PrepareToBootEfi (LegacyBios, NULL, NULL);
}
mShadowRomFlag = 1;
}
return ;
}

View File

@@ -0,0 +1,399 @@
/*++
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:
Performance.c
Abstract:
This file include the file which can help to get the system
performance, all the function will only include if the performance
switch is set.
--*/
#include "Performance.h"
VOID
ClearDebugRegisters (
VOID
)
{
//
// BugBug: We should not need to do this. We need to root cause this bug!!!!
//
AsmWriteDr0 (0);
AsmWriteDr1 (0);
}
STATIC
VOID
GetShortPdbFileName (
CHAR8 *PdbFileName,
CHAR8 *GaugeString
)
/*++
Routine Description:
Arguments:
Returns:
--*/
{
UINTN Index;
UINTN Index1;
UINTN StartIndex;
UINTN EndIndex;
if (PdbFileName == NULL) {
AsciiStrCpy (GaugeString, " ");
} else {
StartIndex = 0;
for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)
;
for (Index = 0; PdbFileName[Index] != 0; Index++) {
if (PdbFileName[Index] == '\\') {
StartIndex = Index + 1;
}
if (PdbFileName[Index] == '.') {
EndIndex = Index;
}
}
Index1 = 0;
for (Index = StartIndex; Index < EndIndex; Index++) {
GaugeString[Index1] = PdbFileName[Index];
Index1++;
if (Index1 == PERF_TOKEN_LENGTH - 1) {
break;
}
}
GaugeString[Index1] = 0;
}
return ;
}
STATIC
CHAR8 *
GetPdbPath (
VOID *ImageBase
)
/*++
Routine Description:
Located PDB path name in PE image
Arguments:
ImageBase - base of PE to search
Returns:
Pointer into image at offset of PDB file name if PDB file name is found,
Otherwise a pointer to an empty string.
--*/
{
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
ZeroMem (&ImageContext, sizeof (ImageContext));
ImageContext.Handle = ImageBase;
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
PeCoffLoaderGetImageInfo (&ImageContext);
return ImageContext.PdbPointer;
}
STATIC
VOID
GetNameFromHandle (
IN EFI_HANDLE Handle,
OUT CHAR8 *GaugeString
)
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *Image;
CHAR8 *PdbFileName;
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
AsciiStrCpy (GaugeString, " ");
//
// Get handle name from image protocol
//
Status = gBS->HandleProtocol (
Handle,
&gEfiLoadedImageProtocolGuid,
(VOID **)&Image
);
if (EFI_ERROR (Status)) {
Status = gBS->OpenProtocol (
Handle,
&gEfiDriverBindingProtocolGuid,
(VOID **) &DriverBinding,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return ;
}
//
// Get handle name from image protocol
//
Status = gBS->HandleProtocol (
DriverBinding->ImageHandle,
&gEfiLoadedImageProtocolGuid,
(VOID **)&Image
);
}
PdbFileName = GetPdbPath (Image->ImageBase);
if (PdbFileName != NULL) {
GetShortPdbFileName (PdbFileName, GaugeString);
}
return ;
}
VOID
WriteBootToOsPerformanceData (
VOID
)
/*++
Routine Description:
Allocates a block of memory and writes performance data of booting to OS into it.
Arguments:
None
Returns:
None
--*/
{
EFI_STATUS Status;
EFI_CPU_ARCH_PROTOCOL *Cpu;
EFI_PHYSICAL_ADDRESS mAcpiLowMemoryBase;
UINT32 mAcpiLowMemoryLength;
UINT32 LimitCount;
PERF_HEADER mPerfHeader;
PERF_DATA mPerfData;
EFI_HANDLE *Handles;
UINTN NoHandles;
CHAR8 GaugeString[PERF_TOKEN_LENGTH];
UINT8 *Ptr;
UINT32 mIndex;
UINT64 Ticker;
UINT64 Freq;
UINT32 Duration;
UINT64 CurrentTicker;
UINT64 TimerPeriod;
UINTN LogEntryKey;
CONST VOID *Handle;
CONST CHAR8 *Token;
CONST CHAR8 *Module;
UINT64 StartTicker;
UINT64 EndTicker;
//
// Retrive time stamp count as early as possilbe
//
Ticker = AsmReadTsc ();
//
// Allocate a block of memory that contain performance data to OS
//
mAcpiLowMemoryBase = 0xFFFFFFFF;
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiReservedMemoryType,
4,
&mAcpiLowMemoryBase
);
if (EFI_ERROR (Status)) {
return ;
}
mAcpiLowMemoryLength = EFI_PAGES_TO_SIZE(4);
Ptr = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (PERF_HEADER));
LimitCount = (mAcpiLowMemoryLength - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);
//
// Initialize performance data structure
//
ZeroMem (&mPerfHeader, sizeof (PERF_HEADER));
//
// Get CPU frequency
//
Status = gBS->LocateProtocol (
&gEfiCpuArchProtocolGuid,
NULL,
(VOID **)&Cpu
);
if (EFI_ERROR (Status)) {
gBS->FreePages (mAcpiLowMemoryBase, 4);
return ;
}
//
// Get Cpu Frequency
//
Status = Cpu->GetTimerValue (Cpu, 0, &(CurrentTicker), &TimerPeriod);
if (EFI_ERROR (Status)) {
gBS->FreePages (mAcpiLowMemoryBase, 4);
return ;
}
Freq = DivU64x32 (1000000000000UL, (UINTN) TimerPeriod);
mPerfHeader.CpuFreq = Freq;
//
// Record BDS raw performance data
//
mPerfHeader.BDSRaw = Ticker;
//
// Put Detailed performance data into memory
//
Handles = NULL;
Status = gBS->LocateHandleBuffer (
AllHandles,
NULL,
NULL,
&NoHandles,
&Handles
);
if (EFI_ERROR (Status)) {
gBS->FreePages (mAcpiLowMemoryBase, 4);
return ;
}
//
// Get DXE drivers performance
//
for (mIndex = 0; mIndex < NoHandles; mIndex++) {
Ticker = 0;
LogEntryKey = 0;
while ((LogEntryKey = GetPerformanceMeasurement (
LogEntryKey,
&Handle,
&Token,
&Module,
&StartTicker,
&EndTicker)) != 0) {
if ((Handle == Handles[mIndex]) && (StartTicker < EndTicker)) {
Ticker += (EndTicker - StartTicker);
}
}
Duration = (UINT32) DivU64x32 (
Ticker,
(UINT32) Freq
);
if (Duration > 0) {
ZeroMem (&mPerfData, sizeof (PERF_DATA));
GetNameFromHandle (Handles[mIndex], GaugeString);
AsciiStrCpy (mPerfData.Token, GaugeString);
mPerfData.Duration = Duration;
CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));
Ptr += sizeof (PERF_DATA);
mPerfHeader.Count++;
if (mPerfHeader.Count == LimitCount) {
goto Done;
}
}
}
gBS->FreePool (Handles);
//
// Get inserted performance data
//
LogEntryKey = 0;
while ((LogEntryKey = GetPerformanceMeasurement (
LogEntryKey,
&Handle,
&Token,
&Module,
&StartTicker,
&EndTicker)) != 0) {
if ((Handle == NULL) && (StartTicker <= EndTicker)) {
ZeroMem (&mPerfData, sizeof (PERF_DATA));
AsciiStrnCpy (mPerfData.Token, Token, DXE_PERFORMANCE_STRING_SIZE);
mPerfData.Duration = (UINT32) DivU64x32 (
EndTicker - StartTicker,
(UINT32) Freq
);
CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));
Ptr += sizeof (PERF_DATA);
mPerfHeader.Count++;
if (mPerfHeader.Count == LimitCount) {
goto Done;
}
}
}
Done:
ClearDebugRegisters ();
mPerfHeader.Signiture = 0x66726550;
//
// Put performance data to memory
//
CopyMem (
(UINT32 *) (UINT32) mAcpiLowMemoryBase,
&mPerfHeader,
sizeof (PERF_HEADER)
);
gRT->SetVariable (
L"PerfDataMemAddr",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof (UINT32),
(VOID *) &mAcpiLowMemoryBase
);
return ;
}

View File

@@ -0,0 +1,55 @@
/*++
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:
Performance.h
Abstract:
This file included the performance relete function header and
definition.
--*/
#ifndef _PERF_H_
#define _PERF_H_
#define PERF_TOKEN_LENGTH 28
#define PERF_PEI_ENTRY_MAX_NUM 50
typedef struct {
CHAR8 Token[PERF_TOKEN_LENGTH];
UINT32 Duration;
} PERF_DATA;
typedef struct {
UINT64 BootToOs;
UINT64 S3Resume;
UINT32 S3EntryNum;
PERF_DATA S3Entry[PERF_PEI_ENTRY_MAX_NUM];
UINT64 CpuFreq;
UINT64 BDSRaw;
UINT32 Count;
UINT32 Signiture;
} PERF_HEADER;
VOID
WriteBootToOsPerformanceData (
VOID
);
VOID
ClearDebugRegisters (
VOID
);
#endif

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
<MsaHeader>
<ModuleName>EdkUnixPeiPeCoffGetEntryPointLib</ModuleName>
<ModuleType>PEIM</ModuleType>
<GuidValue>f3b702e8-8985-11db-9558-0040d02b1835</GuidValue>
<Version>1.0</Version>
<Abstract>Component description file for the EdkNt32PeiPeCoffGetEntryPointLib library.</Abstract>
<Description>PeCoffGetEntryPointLib library class for NT32 instance implemented by use NTPeiLoadFile PPI.</Description>
<Copyright>Copyright (c) 2006, 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>EdkUnixPeiPeCoffGetEntryPointLib</OutputFileBasename>
</ModuleDefinitions>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_PRODUCED">
<Keyword>PeCoffGetEntryPointLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>PeiServicesLib</Keyword>
</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>PeCoffGetEntryPoint.c</Filename>
</SourceFiles>
<PackageDependencies>
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Package PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835"/>
</PackageDependencies>
<PPIs>
<Ppi Usage="ALWAYS_CONSUMED">
<PpiCName>gUnixPeiLoadFilePpiGuid</PpiCName>
</Ppi>
</PPIs>
<Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
</Externs>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,75 @@
/*++
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:
PeCoffGetEntryPoint.c
Abstract:
Tiano PE/COFF loader
Revision History
--*/
RETURN_STATUS
EFIAPI
PeCoffLoaderGetEntryPoint (
IN VOID *Pe32Data,
IN OUT VOID **EntryPoint
)
/*++
Routine Description:
Loads a PE/COFF image into memory
Arguments:
Pe32Data - Pointer to a PE/COFF Image
EntryPoint - Pointer to the entry point of the PE/COFF image
Returns:
EFI_SUCCESS if the EntryPoint was returned
EFI_INVALID_PARAMETER if the EntryPoint could not be found from Pe32Data
--*/
{
EFI_STATUS Status;
EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor;
UNIX_PEI_LOAD_FILE_PPI *PeiUnixService;
EFI_PHYSICAL_ADDRESS ImageAddress;
UINT64 ImageSize;
EFI_PHYSICAL_ADDRESS ImageEntryPoint;
Status = PeiServicesLocatePpi (
&gUnixPeiLoadFilePpiGuid,
0,
&PpiDescriptor,
(void **)&PeiUnixService
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = PeiUnixService->PeiLoadFileService (
Pe32Data,
&ImageAddress,
&ImageSize,
&ImageEntryPoint
);
*EntryPoint = (VOID*)(UINTN)ImageEntryPoint;
return Status;
}

View File

@@ -0,0 +1,246 @@
/** @file
OEM hook status code library functions with no library constructor/destructor
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: UnixOemHookStatusCodeLib.c
**/
//
// Cache of UnixThunk protocol
//
STATIC
EFI_UNIX_THUNK_PROTOCOL *mUnix;
//
// Cache of standard output handle .
//
STATIC
int mStdOut;
/**
Initialize OEM status code device .
@return Always return EFI_SUCCESS.
**/
EFI_STATUS
EFIAPI
OemHookStatusCodeInitialize (
VOID
)
{
PEI_UNIX_THUNK_PPI *UnixThunkPpi;
EFI_STATUS Status;
if (FeaturePcdGet (PcdUnixStatusCodeLibUseForPei)) {
//
// Locate NtThunkPpi for retrieving standard output handle
//
Status = PeiServicesLocatePpi (
&gPeiUnixThunkPpiGuid,
0,
NULL,
(VOID **) &UnixThunkPpi
);
ASSERT_EFI_ERROR (Status);
mUnix = (EFI_UNIX_THUNK_PROTOCOL *) UnixThunkPpi->UnixThunk ();
} else {
EFI_HOB_GUID_TYPE *GuidHob;
//
// Retrieve UnixThunkProtocol from GUID'ed HOB
//
GuidHob = GetFirstGuidHob (&gEfiUnixThunkProtocolGuid);
ASSERT (GuidHob != NULL);
mUnix = (EFI_UNIX_THUNK_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob)));
ASSERT (mUnix != NULL);
}
//
// Cache standard output handle.
//
mStdOut = 1;
return EFI_SUCCESS;
}
/**
Report status code to OEM device.
@param CodeType Indicates the type of status code being reported. Type EFI_STATUS_CODE_TYPE is defined in "Related Definitions" below.
@param Value Describes the current status of a hardware or software entity.
This included information about the class and subclass that is used to classify the entity
as well as an operation. For progress codes, the operation is the current activity.
For error codes, it is the exception. For debug codes, it is not defined at this time.
Type EFI_STATUS_CODE_VALUE is defined in "Related Definitions" below.
Specific values are discussed in the Intel? Platform Innovation Framework for EFI Status Code Specification.
@param Instance The enumeration of a hardware or software entity within the system.
A system may contain multiple entities that match a class/subclass pairing.
The instance differentiates between them. An instance of 0 indicates that instance information is unavailable,
not meaningful, or not relevant. Valid instance numbers start with 1.
@param CallerId This optional parameter may be used to identify the caller.
This parameter allows the status code driver to apply different rules to different callers.
Type EFI_GUID is defined in InstallProtocolInterface() in the EFI 1.10 Specification.
@param Data This optional parameter may be used to pass additional data
@return The function always return EFI_SUCCESS.
**/
EFI_STATUS
EFIAPI
OemHookStatusCodeReport (
IN EFI_STATUS_CODE_TYPE CodeType,
IN EFI_STATUS_CODE_VALUE Value,
IN UINT32 Instance,
IN EFI_GUID *CallerId, OPTIONAL
IN EFI_STATUS_CODE_DATA *Data OPTIONAL
)
{
CHAR8 *Filename;
CHAR8 *Description;
CHAR8 *Format;
CHAR8 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
UINT32 ErrorLevel;
UINT32 LineNumber;
UINTN CharCount;
VA_LIST Marker;
EFI_DEBUG_INFO *DebugInfo;
Buffer[0] = '\0';
if (Data != NULL &&
ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
//
// Print ASSERT() information into output buffer.
//
CharCount = AsciiSPrint (
Buffer,
EFI_STATUS_CODE_DATA_MAX_SIZE,
"\n\rASSERT!: %a (%d): %a\n\r",
Filename,
LineNumber,
Description
);
//
// Callout to standard output.
//
mUnix->Write (
mStdOut,
Buffer,
CharCount
);
return EFI_SUCCESS;
} else if (Data != NULL &&
ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
//
// Print DEBUG() information into output buffer.
//
CharCount = AsciiVSPrint (
Buffer,
EFI_STATUS_CODE_DATA_MAX_SIZE,
Format,
Marker
);
} else if (Data != NULL &&
CompareGuid (&Data->Type, &gEfiStatusCodeSpecificDataGuid) &&
(CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {
//
// Print specific data into output buffer.
//
DebugInfo = (EFI_DEBUG_INFO *) (Data + 1);
Marker = (VA_LIST) (DebugInfo + 1);
Format = (CHAR8 *) (((UINT64 *) Marker) + 12);
CharCount = AsciiVSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, Marker);
} else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
//
// Print ERROR information into output buffer.
//
CharCount = AsciiSPrint (
Buffer,
EFI_STATUS_CODE_DATA_MAX_SIZE,
"ERROR: C%x:V%x I%x",
CodeType,
Value,
Instance
);
//
// Make sure we don't try to print values that weren't intended to be printed, especially NULL GUID pointers.
//
if (CallerId != NULL) {
CharCount += AsciiSPrint (
&Buffer[CharCount - 1],
(EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),
" %g",
CallerId
);
}
if (Data != NULL) {
CharCount += AsciiSPrint (
&Buffer[CharCount - 1],
(EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),
" %x",
Data
);
}
CharCount += AsciiSPrint (
&Buffer[CharCount - 1],
(EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),
"\n\r"
);
} else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
CharCount = AsciiSPrint (
Buffer,
EFI_STATUS_CODE_DATA_MAX_SIZE,
"PROGRESS CODE: V%x I%x\n\r",
Value,
Instance
);
} else {
CharCount = AsciiSPrint (
Buffer,
EFI_STATUS_CODE_DATA_MAX_SIZE,
"Undefined: C%x:V%x I%x\n\r",
CodeType,
Value,
Instance
);
}
//
// Callout to standard output.
//
mUnix->Write (
mStdOut,
Buffer,
CharCount
);
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
<MsaHeader>
<ModuleName>UnixOemHookStatusCodeLib</ModuleName>
<ModuleType>PEIM</ModuleType>
<GuidValue>f3c32014-8985-11db-bae7-0040d02b1835</GuidValue>
<Version>1.0</Version>
<Abstract>Memory Status Code Library for UEFI drivers</Abstract>
<Description>Lib to provide memory journal status code reporting Routines</Description>
<Copyright>Copyright (c) 2006, Intel Corporation.</Copyright>
<License>
All rights reserved.
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
</License>
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
</MsaHeader>
<ModuleDefinitions>
<SupportedArchitectures>IA32</SupportedArchitectures>
<BinaryModule>false</BinaryModule>
<OutputFileBasename>UnixOemHookStatusCodeLib</OutputFileBasename>
</ModuleDefinitions>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_PRODUCED">
<Keyword>OemHookStatusCodeLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>DebugLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>PcdLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>HobLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>PrintLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseMemoryLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>ReportStatusCodeLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>PeiServicesLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UnixLib</Keyword>
</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>UnixOemHookStatusCodeLib.c</Filename>
</SourceFiles>
<PackageDependencies>
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
<Package PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835"/>
</PackageDependencies>
<Protocols>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiUnixThunkProtocolGuid</ProtocolCName>
</Protocol>
</Protocols>
<PPIs>
<Ppi Usage="ALWAYS_CONSUMED">
<PpiCName>gPeiUnixThunkPpiGuid</PpiCName>
</Ppi>
</PPIs>
<Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
</Externs>
<PcdCoded xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PcdEntry PcdItemType="FEATURE_FLAG">
<C_Name>PcdUnixStatusCodeLibUseForPei</C_Name>
<TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
<HelpText>Select which type of driver the library links against.</HelpText>
</PcdEntry>
</PcdCoded>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,52 @@
/*++
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:
TianoPeCoffLoader.c
Abstract:
Wrap the Base PE/COFF loader with the PE COFF Protocol
--*/
EFI_PEI_PE_COFF_LOADER_PROTOCOL *mPeiEfiPeiPeCoffLoader;
EFI_STATUS
EFIAPI
PeCoffLoaderConstructor (
IN EFI_FFS_FILE_HEADER *FfsHeader,
IN EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
Status = (*PeiServices)->LocatePpi (
PeiServices,
&gEfiPeiPeCoffLoaderGuid,
0,
NULL,
(VOID **)&mPeiEfiPeiPeCoffLoader
);
return Status;
}
EFI_PEI_PE_COFF_LOADER_PROTOCOL *
EFIAPI
GetPeCoffLoaderProtocol (
)
{
return mPeiEfiPeiPeCoffLoader;
}

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
<MsaHeader>
<ModuleName>UnixPeCoffLoaderLib</ModuleName>
<ModuleType>PEIM</ModuleType>
<GuidValue>f3cf597e-8985-11db-95f6-0040d02b1835</GuidValue>
<Version>1.0</Version>
<Abstract>Component description file for the Nt32PeCoffLoaderLib library.</Abstract>
<Description>EdkPeCoffLoaderLib library class for NT32 instance implemented by PeiPeCoffLoader PPI.</Description>
<Copyright>Copyright (c) 2006, 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>UnixPeCoffLoaderLib</OutputFileBasename>
</ModuleDefinitions>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_PRODUCED">
<Keyword>EdkPeCoffLoaderLib</Keyword>
</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>UnixPeCoffLoader.c</Filename>
</SourceFiles>
<PackageDependencies>
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
<Package PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835"/>
</PackageDependencies>
<Guids>
<GuidCNames Usage="SOMETIMES_CONSUMED">
<GuidCName>gEfiPeiPeCoffLoaderGuid</GuidCName>
</GuidCNames>
</Guids>
<Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
<Extern>
<Constructor>PeCoffLoaderConstructor</Constructor>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,113 @@
/** @file
Timer Library functions for Unix platform.
@bug Still no complete implementation for time library function for Unix platform.
Copyright (c) 2006, Intel Corporation<BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name: UnixTimerLib.c
**/
/**
Stalls the CPU for at least the given number of microseconds.
Stalls the CPU for the number of microseconds specified by MicroSeconds.
@param MicroSeconds The minimum number of microseconds to delay.
@return MicroSeconds
**/
UINTN
EFIAPI
MicroSecondDelay (
IN UINTN MicroSeconds
)
{
ASSERT (FALSE);
return MicroSeconds;
}
/**
Stalls the CPU for at least the given number of nanoseconds.
Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
@param NanoSeconds The minimum number of nanoseconds to delay.
@return NanoSeconds
**/
UINTN
EFIAPI
NanoSecondDelay (
IN UINTN NanoSeconds
)
{
ASSERT (FALSE);
return 0;
}
/**
Retrieves the current value of a 64-bit free running performance counter.
Retrieves the current value of a 64-bit free running performance counter. The
counter can either count up by 1 or count down by 1. If the physical
performance counter counts by a larger increment, then the counter values
must be translated. The properties of the counter can be retrieved from
GetPerformanceCounterProperties().
@return The current value of the free running performance counter.
**/
UINT64
EFIAPI
GetPerformanceCounter (
VOID
)
{
ASSERT (FALSE);
return 0;
}
/**
Retrieves the 64-bit frequency in Hz and the range of performance counter
values.
If StartValue is not NULL, then the value that the performance counter starts
with immediately after is it rolls over is returned in StartValue. If
EndValue is not NULL, then the value that the performance counter end with
immediately before it rolls over is returned in EndValue. The 64-bit
frequency of the performance counter in Hz is always returned. If StartValue
is less than EndValue, then the performance counter counts up. If StartValue
is greater than EndValue, then the performance counter counts down. For
example, a 64-bit free running counter that counts up would have a StartValue
of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
@param StartValue The value the performance counter starts with when it
rolls over.
@param EndValue The value that the performance counter ends with before
it rolls over.
@return The frequency in Hz.
**/
UINT64
EFIAPI
GetPerformanceCounterProperties (
OUT UINT64 *StartValue, OPTIONAL
OUT UINT64 *EndValue OPTIONAL
)
{
ASSERT (FALSE);
return 0;
}

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
<MsaHeader>
<ModuleName>UnixTimerLib</ModuleName>
<ModuleType>BASE</ModuleType>
<GuidValue>f3db5724-8985-11db-acbc-0040d02b1835</GuidValue>
<Version>1.0</Version>
<Abstract>Component description file for Nt32Timer Library</Abstract>
<Description>Timer Library provide API of TimerLib library class for Nt32 platform,
Now this library do not impletement functionality completely.</Description>
<Copyright>Copyright (c) 2006, 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>UnixTimerLib</OutputFileBasename>
</ModuleDefinitions>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_PRODUCED">
<Keyword>TimerLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>DebugLib</Keyword>
</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename SupArchList="IA32">UnixTimerLib.c</Filename>
</SourceFiles>
<PackageDependencies>
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Package PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835"/>
</PackageDependencies>
<Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
</Externs>
</ModuleSurfaceArea>