Move BdsDxe and GenericBdsLib to IntelFrameworkModulePkg, these modules need dependent on gEfiLegacyBiosProtocol to provide legacy boot support. But legacy boot is not described by PI/UEFI specification.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7354 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
494
IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BmLib.c
Normal file
494
IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BmLib.c
Normal file
@@ -0,0 +1,494 @@
|
||||
/** @file
|
||||
Utility routines used by boot maintenance modules.
|
||||
|
||||
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "BootMaint.h"
|
||||
|
||||
/**
|
||||
|
||||
Find the first instance of this Protocol
|
||||
in the system and return it's interface.
|
||||
|
||||
|
||||
@param ProtocolGuid Provides the protocol to search for
|
||||
@param Interface On return, a pointer to the first interface
|
||||
that matches ProtocolGuid
|
||||
|
||||
@retval EFI_SUCCESS A protocol instance matching ProtocolGuid was found
|
||||
@retval EFI_NOT_FOUND No protocol instances were found that match ProtocolGuid
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EfiLibLocateProtocol (
|
||||
IN EFI_GUID *ProtocolGuid,
|
||||
OUT VOID **Interface
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = gBS->LocateProtocol (
|
||||
ProtocolGuid,
|
||||
NULL,
|
||||
(VOID **) Interface
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Function opens and returns a file handle to the root directory of a volume.
|
||||
|
||||
@param DeviceHandle A handle for a device
|
||||
|
||||
@return A valid file handle or NULL is returned
|
||||
|
||||
**/
|
||||
EFI_FILE_HANDLE
|
||||
EfiLibOpenRoot (
|
||||
IN EFI_HANDLE DeviceHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
|
||||
EFI_FILE_HANDLE File;
|
||||
|
||||
File = NULL;
|
||||
|
||||
//
|
||||
// File the file system interface to the device
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
DeviceHandle,
|
||||
&gEfiSimpleFileSystemProtocolGuid,
|
||||
(VOID *) &Volume
|
||||
);
|
||||
|
||||
//
|
||||
// Open the root directory of the volume
|
||||
//
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = Volume->OpenVolume (
|
||||
Volume,
|
||||
&File
|
||||
);
|
||||
}
|
||||
//
|
||||
// Done
|
||||
//
|
||||
return EFI_ERROR (Status) ? NULL : File;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Helper function called as part of the code needed
|
||||
to allocate the proper sized buffer for various
|
||||
EFI interfaces.
|
||||
|
||||
|
||||
@param Status Current status
|
||||
@param Buffer Current allocated buffer, or NULL
|
||||
@param BufferSize Current buffer size needed
|
||||
|
||||
@retval TRUE if the buffer was reallocated and the caller
|
||||
should try the API again.
|
||||
@retval FALSE The caller should not call this function again.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EfiGrowBuffer (
|
||||
IN OUT EFI_STATUS *Status,
|
||||
IN OUT VOID **Buffer,
|
||||
IN UINTN BufferSize
|
||||
)
|
||||
{
|
||||
BOOLEAN TryAgain;
|
||||
|
||||
//
|
||||
// If this is an initial request, buffer will be null with a new buffer size
|
||||
//
|
||||
if ((*Buffer == NULL) && (BufferSize != 0)) {
|
||||
*Status = EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
//
|
||||
// If the status code is "buffer too small", resize the buffer
|
||||
//
|
||||
TryAgain = FALSE;
|
||||
if (*Status == EFI_BUFFER_TOO_SMALL) {
|
||||
|
||||
if (*Buffer != NULL) {
|
||||
FreePool (*Buffer);
|
||||
}
|
||||
|
||||
*Buffer = AllocateZeroPool (BufferSize);
|
||||
|
||||
if (*Buffer != NULL) {
|
||||
TryAgain = TRUE;
|
||||
} else {
|
||||
*Status = EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
}
|
||||
//
|
||||
// If there's an error, free the buffer
|
||||
//
|
||||
if (!TryAgain && EFI_ERROR (*Status) && (*Buffer != NULL)) {
|
||||
FreePool (*Buffer);
|
||||
*Buffer = NULL;
|
||||
}
|
||||
|
||||
return TryAgain;
|
||||
}
|
||||
|
||||
/**
|
||||
Function returns the value of the specified variable.
|
||||
|
||||
|
||||
@param Name A Null-terminated Unicode string that is
|
||||
the name of the vendor's variable.
|
||||
@param VendorGuid A unique identifier for the vendor.
|
||||
|
||||
@return The payload of the variable.
|
||||
@retval NULL If the variable can't be read.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EfiLibGetVariable (
|
||||
IN CHAR16 *Name,
|
||||
IN EFI_GUID *VendorGuid
|
||||
)
|
||||
{
|
||||
UINTN VarSize;
|
||||
|
||||
return BdsLibGetVariableAndSize (Name, VendorGuid, &VarSize);
|
||||
}
|
||||
|
||||
/**
|
||||
Function deletes the variable specified by VarName and VarGuid.
|
||||
|
||||
@param VarName A Null-terminated Unicode string that is
|
||||
the name of the vendor's variable.
|
||||
|
||||
@param VarGuid A unique identifier for the vendor.
|
||||
|
||||
@retval EFI_SUCCESS The variable was found and removed
|
||||
@retval EFI_UNSUPPORTED The variable store was inaccessible
|
||||
@retval EFI_OUT_OF_RESOURCES The temporary buffer was not available
|
||||
@retval EFI_NOT_FOUND The variable was not found
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EfiLibDeleteVariable (
|
||||
IN CHAR16 *VarName,
|
||||
IN EFI_GUID *VarGuid
|
||||
)
|
||||
{
|
||||
VOID *VarBuf;
|
||||
EFI_STATUS Status;
|
||||
|
||||
VarBuf = EfiLibGetVariable (VarName, VarGuid);
|
||||
Status = EFI_NOT_FOUND;
|
||||
|
||||
if (VarBuf != NULL) {
|
||||
//
|
||||
// Delete variable from Storage
|
||||
//
|
||||
Status = gRT->SetVariable (VarName, VarGuid, VAR_FLAG, 0, NULL);
|
||||
ASSERT (!EFI_ERROR (Status));
|
||||
FreePool (VarBuf);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Function gets the file system information from an open file descriptor,
|
||||
and stores it in a buffer allocated from pool.
|
||||
|
||||
|
||||
@param FHand The file handle.
|
||||
|
||||
@return A pointer to a buffer with file information.
|
||||
@retval NULL is returned if failed to get Vaolume Label Info.
|
||||
|
||||
**/
|
||||
EFI_FILE_SYSTEM_VOLUME_LABEL *
|
||||
EfiLibFileSystemVolumeLabelInfo (
|
||||
IN EFI_FILE_HANDLE FHand
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FILE_SYSTEM_VOLUME_LABEL *Buffer;
|
||||
UINTN BufferSize;
|
||||
//
|
||||
// Initialize for GrowBuffer loop
|
||||
//
|
||||
Buffer = NULL;
|
||||
BufferSize = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL + 200;
|
||||
|
||||
//
|
||||
// Call the real function
|
||||
//
|
||||
while (EfiGrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
|
||||
Status = FHand->GetInfo (
|
||||
FHand,
|
||||
&gEfiFileSystemVolumeLabelInfoIdGuid,
|
||||
&BufferSize,
|
||||
Buffer
|
||||
);
|
||||
}
|
||||
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
Duplicate a string.
|
||||
|
||||
@param Src The source.
|
||||
|
||||
@return A new string which is duplicated copy of the source.
|
||||
@retval NULL If there is not enough memory.
|
||||
|
||||
**/
|
||||
CHAR16 *
|
||||
EfiStrDuplicate (
|
||||
IN CHAR16 *Src
|
||||
)
|
||||
{
|
||||
CHAR16 *Dest;
|
||||
UINTN Size;
|
||||
|
||||
Size = StrSize (Src);
|
||||
Dest = AllocateZeroPool (Size);
|
||||
ASSERT (Dest != NULL);
|
||||
if (Dest != NULL) {
|
||||
CopyMem (Dest, Src, Size);
|
||||
}
|
||||
|
||||
return Dest;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Function gets the file information from an open file descriptor, and stores it
|
||||
in a buffer allocated from pool.
|
||||
|
||||
@param FHand File Handle.
|
||||
|
||||
@return A pointer to a buffer with file information or NULL is returned
|
||||
|
||||
**/
|
||||
EFI_FILE_INFO *
|
||||
EfiLibFileInfo (
|
||||
IN EFI_FILE_HANDLE FHand
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FILE_INFO *Buffer;
|
||||
UINTN BufferSize;
|
||||
|
||||
//
|
||||
// Initialize for GrowBuffer loop
|
||||
//
|
||||
Buffer = NULL;
|
||||
BufferSize = SIZE_OF_EFI_FILE_INFO + 200;
|
||||
|
||||
//
|
||||
// Call the real function
|
||||
//
|
||||
while (EfiGrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
|
||||
Status = FHand->GetInfo (
|
||||
FHand,
|
||||
&gEfiFileInfoGuid,
|
||||
&BufferSize,
|
||||
Buffer
|
||||
);
|
||||
}
|
||||
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
Function is used to determine the number of device path instances
|
||||
that exist in a device path.
|
||||
|
||||
|
||||
@param DevicePath A pointer to a device path data structure.
|
||||
|
||||
@return This function counts and returns the number of device path instances
|
||||
in DevicePath.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
EfiDevicePathInstanceCount (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||
)
|
||||
{
|
||||
UINTN Count;
|
||||
UINTN Size;
|
||||
|
||||
Count = 0;
|
||||
while (GetNextDevicePathInstance (&DevicePath, &Size)) {
|
||||
Count += 1;
|
||||
}
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
/**
|
||||
Adjusts the size of a previously allocated buffer.
|
||||
|
||||
|
||||
@param OldPool - A pointer to the buffer whose size is being adjusted.
|
||||
@param OldSize - The size of the current buffer.
|
||||
@param NewSize - The size of the new buffer.
|
||||
|
||||
@return The newly allocated buffer.
|
||||
@retval NULL Allocation failed.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EfiReallocatePool (
|
||||
IN VOID *OldPool,
|
||||
IN UINTN OldSize,
|
||||
IN UINTN NewSize
|
||||
)
|
||||
{
|
||||
VOID *NewPool;
|
||||
|
||||
NewPool = NULL;
|
||||
if (NewSize != 0) {
|
||||
NewPool = AllocateZeroPool (NewSize);
|
||||
}
|
||||
|
||||
if (OldPool != NULL) {
|
||||
if (NewPool != NULL) {
|
||||
CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
|
||||
}
|
||||
|
||||
FreePool (OldPool);
|
||||
}
|
||||
|
||||
return NewPool;
|
||||
}
|
||||
|
||||
/**
|
||||
Compare two EFI_TIME data.
|
||||
|
||||
|
||||
@param FirstTime - A pointer to the first EFI_TIME data.
|
||||
@param SecondTime - A pointer to the second EFI_TIME data.
|
||||
|
||||
@retval TRUE The FirstTime is not later than the SecondTime.
|
||||
@retval FALSE The FirstTime is later than the SecondTime.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
TimeCompare (
|
||||
IN EFI_TIME *FirstTime,
|
||||
IN EFI_TIME *SecondTime
|
||||
)
|
||||
{
|
||||
if (FirstTime->Year != SecondTime->Year) {
|
||||
return (BOOLEAN) (FirstTime->Year < SecondTime->Year);
|
||||
} else if (FirstTime->Month != SecondTime->Month) {
|
||||
return (BOOLEAN) (FirstTime->Month < SecondTime->Month);
|
||||
} else if (FirstTime->Day != SecondTime->Day) {
|
||||
return (BOOLEAN) (FirstTime->Day < SecondTime->Day);
|
||||
} else if (FirstTime->Hour != SecondTime->Hour) {
|
||||
return (BOOLEAN) (FirstTime->Hour < SecondTime->Hour);
|
||||
} else if (FirstTime->Minute != SecondTime->Minute) {
|
||||
return (BOOLEAN) (FirstTime->Minute < FirstTime->Minute);
|
||||
} else if (FirstTime->Second != SecondTime->Second) {
|
||||
return (BOOLEAN) (FirstTime->Second < SecondTime->Second);
|
||||
}
|
||||
|
||||
return (BOOLEAN) (FirstTime->Nanosecond <= SecondTime->Nanosecond);
|
||||
}
|
||||
|
||||
/**
|
||||
Get a string from the Data Hub record based on
|
||||
a device path.
|
||||
|
||||
@param DevPath The device Path.
|
||||
|
||||
@return A string located from the Data Hub records based on
|
||||
the device path.
|
||||
@retval NULL If failed to get the String from Data Hub.
|
||||
|
||||
**/
|
||||
UINT16 *
|
||||
EfiLibStrFromDatahub (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DevPath
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT16 *Desc;
|
||||
EFI_DATA_HUB_PROTOCOL *Datahub;
|
||||
UINT64 Count;
|
||||
EFI_DATA_RECORD_HEADER *Record;
|
||||
EFI_SUBCLASS_TYPE1_HEADER *DataHdr;
|
||||
EFI_GUID MiscGuid;
|
||||
EFI_MISC_ONBOARD_DEVICE_DATA *Ob;
|
||||
EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *Port;
|
||||
EFI_TIME CurTime;
|
||||
|
||||
CopyGuid (&MiscGuid, &gEfiMiscSubClassGuid);
|
||||
|
||||
Status = gBS->LocateProtocol (
|
||||
&gEfiDataHubProtocolGuid,
|
||||
NULL,
|
||||
(VOID **) &Datahub
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Status = gRT->GetTime (&CurTime, NULL);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Count = 0;
|
||||
do {
|
||||
Status = Datahub->GetNextRecord (Datahub, &Count, NULL, &Record);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA && CompareGuid (&Record->DataRecordGuid, &MiscGuid)) {
|
||||
//
|
||||
// This record is what we need
|
||||
//
|
||||
DataHdr = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);
|
||||
if (EFI_MISC_ONBOARD_DEVICE_RECORD_NUMBER == DataHdr->RecordType) {
|
||||
Ob = (EFI_MISC_ONBOARD_DEVICE_DATA *) (DataHdr + 1);
|
||||
if (BdsLibMatchDevicePaths ((EFI_DEVICE_PATH_PROTOCOL *) &Ob->OnBoardDevicePath, DevPath)) {
|
||||
GetProducerString (&Record->ProducerName, Ob->OnBoardDeviceDescription, &Desc);
|
||||
return Desc;
|
||||
}
|
||||
}
|
||||
|
||||
if (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_RECORD_NUMBER == DataHdr->RecordType) {
|
||||
Port = (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *) (DataHdr + 1);
|
||||
if (BdsLibMatchDevicePaths ((EFI_DEVICE_PATH_PROTOCOL *) &Port->PortPath, DevPath)) {
|
||||
GetProducerString (&Record->ProducerName, Port->PortExternalConnectorDesignator, &Desc);
|
||||
return Desc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} while (TimeCompare (&Record->LogTime, &CurTime) && Count != 0);
|
||||
|
||||
return NULL;
|
||||
}
|
Reference in New Issue
Block a user