diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /EDK/Foundation/Library/Dxe/EfiDriverLib | |
download | zprj-master.tar.xz |
Diffstat (limited to 'EDK/Foundation/Library/Dxe/EfiDriverLib')
25 files changed, 4603 insertions, 0 deletions
diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/Debug.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/Debug.c new file mode 100644 index 0000000..446d229 --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/Debug.c @@ -0,0 +1,173 @@ +/*++ + +Copyright (c) 2004 - 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: + + Debug.c + +Abstract: + + Support for Debug primatives. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" +#include "EfiPrintLib.h" +#include "EfiStatusCode.h" +#include EFI_GUID_DEFINITION (StatusCodeCallerId) +#include EFI_GUID_DEFINITION (StatusCodeDataTypeId) +#include EFI_PROTOCOL_DEFINITION (DEBUGMASK) + +// +// You would think you should divid by sizeof (UINT64), but EBC does not like +// that! +// +#define EFI_STATUS_CODE_DATA_MAX_SIZE64 (EFI_STATUS_CODE_DATA_MAX_SIZE / 8) + +VOID +EfiDebugAssert ( + IN CHAR8 *FileName, + IN INTN LineNumber, + IN CHAR8 *Description + ) +/*++ + +Routine Description: + + Worker function for ASSERT(). If Error Logging hub is loaded log ASSERT + information. If Error Logging hub is not loaded BREAKPOINT(). + + We use UINT64 buffers due to IPF alignment concerns. + +Arguments: + + FileName - File name of failing routine. + + LineNumber - Line number of failing ASSERT(). + + Description - Descritption, usally the assertion, + +Returns: + + None + +--*/ +{ + UINT64 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE]; + + EfiDebugAssertWorker (FileName, LineNumber, Description, sizeof (Buffer), Buffer); + + EfiLibReportStatusCode ( + (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED), + (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE), + 0, + &gEfiCallerIdGuid, + (EFI_STATUS_CODE_DATA *) Buffer + ); + + // + // Put break point in module that contained the error. + // + EFI_BREAKPOINT (); +} + +VOID +EfiDebugVPrint ( + IN UINTN ErrorLevel, + IN CHAR8 *Format, + IN VA_LIST Marker + ) +/*++ + +Routine Description: + + Worker function for DEBUG(). If Error Logging hub is loaded log ASSERT + information. If Error Logging hub is not loaded do nothing. + + We use UINT64 buffers due to IPF alignment concerns. + +Arguments: + + ErrorLevel - If error level is set do the debug print. + + Format - String to use for the print, followed by Print arguments. + + Marker - VarArgs + +Returns: + + None + +--*/ +{ + UINT64 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE]; + UINTN ImageDebugMask; + + // + // Check driver debug mask value and global mask + // + if (gDebugMaskInterface != NULL) { + gDebugMaskInterface->GetDebugMask (gDebugMaskInterface, &ImageDebugMask); + if (!(ErrorLevel & ImageDebugMask)) { + return ; + } + } else if (!(gErrorLevel & ErrorLevel)) { + return ; + } + + EfiDebugVPrintWorker (ErrorLevel, Format, Marker, sizeof (Buffer), Buffer); + + ASSERT (NULL != gRT); + EfiLibReportStatusCode ( + EFI_DEBUG_CODE, + (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_DC_UNSPECIFIED), + 0, + &gEfiCallerIdGuid, + (EFI_STATUS_CODE_DATA *) Buffer + ); + + return ; +} + +VOID +EfiDebugPrint ( + IN UINTN ErrorLevel, + IN CHAR8 *Format, + ... + ) +/*++ + +Routine Description: + + Wrapper for EfiDebugVPrint () + +Arguments: + + ErrorLevel - If error level is set do the debug print. + + Format - String to use for the print, followed by Print arguments. + + ... - Print arguments. + + +Returns: + + None + +--*/ +{ + VA_LIST Marker; + + VA_START (Marker, Format); + EfiDebugVPrint (ErrorLevel, Format, Marker); + VA_END (Marker); +} diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/DevicePath.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/DevicePath.c new file mode 100644 index 0000000..8eb411f --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/DevicePath.c @@ -0,0 +1,551 @@ +/*++ + +Copyright (c) 2004 - 2008, 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: + + DevicePath.c + +Abstract: + + Device Path services. The thing to remember is device paths are built out of + nodes. The device path is terminated by an end node that is length + sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL) + all over this file. + + The only place where multi-instance device paths are supported is in + environment varibles. Multi-instance device paths should never be placed + on a Handle. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" +#include EFI_PROTOCOL_DEFINITION (DevicePath) + +EFI_DEVICE_PATH_PROTOCOL * +EfiDevicePathInstance ( + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, + OUT UINTN *Size + ) +/*++ + +Routine Description: + Function retrieves the next device path instance from a device path data structure. + +Arguments: + DevicePath - A pointer to a device path data structure. + + Size - A pointer to the size of a device path instance in bytes. + +Returns: + + This function returns a pointer to the current device path instance. + In addition, it returns the size in bytes of the current device path instance in Size, + and a pointer to the next device path instance in DevicePath. + If there are no more device path instances in DevicePath, then DevicePath will be set to NULL. + +--*/ +{ + EFI_DEVICE_PATH_PROTOCOL *DevPath; + EFI_DEVICE_PATH_PROTOCOL *ReturnValue; + UINT8 Temp; + + if (*DevicePath == NULL) { + if (Size != NULL) { + *Size = 0; + } + + return NULL; + } + + // + // Find the end of the device path instance + // + DevPath = *DevicePath; + while (!IsDevicePathEndType (DevPath)) { + DevPath = NextDevicePathNode (DevPath); + } + + // + // Compute the size of the device path instance + // + if (Size != NULL) { + *Size = ((UINTN) DevPath - (UINTN) (*DevicePath)) + sizeof (EFI_DEVICE_PATH_PROTOCOL); + } + + // + // Make a copy and return the device path instance + // + Temp = DevPath->SubType; + DevPath->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; + ReturnValue = EfiDuplicateDevicePath (*DevicePath); + DevPath->SubType = Temp; + + // + // If DevPath is the end of an entire device path, then another instance + // does not follow, so *DevicePath is set to NULL. + // + if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) { + *DevicePath = NULL; + } else { + *DevicePath = NextDevicePathNode (DevPath); + } + + return ReturnValue; +} + +BOOLEAN +EfiIsDevicePathMultiInstance ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +/*++ + +Routine Description: + Return TRUE is this is a multi instance device path. + +Arguments: + DevicePath - A pointer to a device path data structure. + + +Returns: + TRUE - If DevicePath is multi instance. FALSE - If DevicePath is not multi + instance. + +--*/ +{ + EFI_DEVICE_PATH_PROTOCOL *Node; + + if (DevicePath == NULL) { + return FALSE; + } + + Node = DevicePath; + while (!EfiIsDevicePathEnd (Node)) { + if (EfiIsDevicePathEndInstance (Node)) { + return TRUE; + } + + Node = EfiNextDevicePathNode (Node); + } + + return FALSE; +} + +UINTN +EfiDevicePathSize ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +/*++ + +Routine Description: + + Calculate the space size of a device path. + +Arguments: + + DevicePath - A specified device path + +Returns: + + The size. + +--*/ +{ + EFI_DEVICE_PATH_PROTOCOL *Start; + + if (DevicePath == NULL) { + return 0; + } + + // + // Search for the end of the device path structure + // + Start = DevicePath; + while (!EfiIsDevicePathEnd (DevicePath)) { + DevicePath = EfiNextDevicePathNode (DevicePath); + } + + // + // Compute the size and add back in the size of the end device path structure + // + return ((UINTN) DevicePath - (UINTN) Start) + sizeof (EFI_DEVICE_PATH_PROTOCOL); +} + +EFI_DEVICE_PATH_PROTOCOL * +EfiDevicePathFromHandle ( + IN EFI_HANDLE Handle + ) +/*++ + +Routine Description: + + Get the device path protocol interface installed on a specified handle. + +Arguments: + + Handle - a specified handle + +Returns: + + The device path protocol interface installed on that handle. + +--*/ +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + DevicePath = NULL; + gBS->HandleProtocol ( + Handle, + &gEfiDevicePathProtocolGuid, + (VOID *) &DevicePath + ); + return DevicePath; +} + +EFI_DEVICE_PATH_PROTOCOL * +EfiDuplicateDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +/*++ + +Routine Description: + + Duplicate a device path structure. + +Arguments: + + DevicePath - The device path to duplicated. + +Returns: + + The duplicated device path. + +--*/ +{ + EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + UINTN Size; + + if (DevicePath == NULL) { + return NULL; + } + + // + // Compute the size + // + Size = EfiDevicePathSize (DevicePath); + if (Size == 0) { + return NULL; + } + + // + // Allocate space for duplicate device path + // + NewDevicePath = EfiLibAllocateCopyPool (Size, DevicePath); + + return NewDevicePath; +} + +EFI_DEVICE_PATH_PROTOCOL * +EfiAppendDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *Src1, + IN EFI_DEVICE_PATH_PROTOCOL *Src2 + ) +/*++ + +Routine Description: + Function is used to append a Src1 and Src2 together. + +Arguments: + Src1 - A pointer to a device path data structure. + + Src2 - A pointer to a device path data structure. + +Returns: + + A pointer to the new device path is returned. + NULL is returned if space for the new device path could not be allocated from pool. + It is up to the caller to free the memory used by Src1 and Src2 if they are no longer needed. + +--*/ +{ + UINTN Size; + UINTN Size1; + UINTN Size2; + EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath; + + // + // If there's only 1 path, just duplicate it + // + if (!Src1) { + ASSERT (!IsDevicePathUnpacked (Src2)); + return EfiDuplicateDevicePath (Src2); + } + + if (!Src2) { + ASSERT (!IsDevicePathUnpacked (Src1)); + return EfiDuplicateDevicePath (Src1); + } + + // + // Allocate space for the combined device path. It only has one end node of + // length EFI_DEVICE_PATH_PROTOCOL + // + Size1 = EfiDevicePathSize (Src1); + Size2 = EfiDevicePathSize (Src2); + Size = Size1 + Size2 - sizeof (EFI_DEVICE_PATH_PROTOCOL); + + NewDevicePath = EfiLibAllocateCopyPool (Size, Src1); + + if (NewDevicePath != NULL) { + + // + // Over write Src1 EndNode and do the copy + // + SecondDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + (Size1 - sizeof (EFI_DEVICE_PATH_PROTOCOL))); + EfiCopyMem (SecondDevicePath, Src2, Size2); + } + + return NewDevicePath; +} + +EFI_DEVICE_PATH_PROTOCOL * +EfiAppendDevicePathNode ( + IN EFI_DEVICE_PATH_PROTOCOL *Src1, + IN EFI_DEVICE_PATH_PROTOCOL *Node + ) +/*++ + +Routine Description: + Function is used to append a device path node to the end of another device path. + +Arguments: + Src1 - A pointer to a device path data structure. + + Node - A pointer to a device path data structure. + +Returns: + This function returns a pointer to the new device path. + If there is not enough temporary pool memory available to complete this function, + then NULL is returned. + + +--*/ +{ + EFI_DEVICE_PATH_PROTOCOL *Temp; + EFI_DEVICE_PATH_PROTOCOL *NextNode; + EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + UINTN NodeLength; + + // + // Build a Node that has a terminator on it + // + NodeLength = DevicePathNodeLength (Node); + + Temp = EfiLibAllocateCopyPool (NodeLength + sizeof (EFI_DEVICE_PATH_PROTOCOL), Node); + if (Temp == NULL) { + return NULL; + } + + // + // Add and end device path node to convert Node to device path + // + NextNode = NextDevicePathNode (Temp); + SetDevicePathEndNode (NextNode); + + // + // Append device paths + // + NewDevicePath = EfiAppendDevicePath (Src1, Temp); + gBS->FreePool (Temp); + return NewDevicePath; +} + +EFI_DEVICE_PATH_PROTOCOL * +EfiFileDevicePath ( + IN EFI_HANDLE Device OPTIONAL, + IN CHAR16 *FileName + ) +/*++ + +Routine Description: + + This function allocates a device path for a file and appends it to an existiong + device path. + +Arguments: + Device - A pointer to a device handle. + + FileName - A pointer to a Null-terminated Unicodestring. + +Returns: + A device path contain the file name. + +--*/ +{ + UINTN Size; + FILEPATH_DEVICE_PATH *FilePath; + EFI_DEVICE_PATH_PROTOCOL *Eop; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + for (Size = 0; FileName[Size] != 0; Size++) + ; + Size = (Size + 1) * 2; + + FilePath = EfiLibAllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof (EFI_DEVICE_PATH_PROTOCOL)); + + DevicePath = NULL; + + if (FilePath != NULL) { + + // + // Build a file path + // + FilePath->Header.Type = MEDIA_DEVICE_PATH; + FilePath->Header.SubType = MEDIA_FILEPATH_DP; + SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH); + EfiCopyMem (FilePath->PathName, FileName, Size); + Eop = NextDevicePathNode (&FilePath->Header); + SetDevicePathEndNode (Eop); + + // + // Append file path to device's device path + // + + DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) FilePath; + if (Device != NULL) { + DevicePath = EfiAppendDevicePath ( + EfiDevicePathFromHandle (Device), + DevicePath + ); + + gBS->FreePool (FilePath); + } + } + + return DevicePath; +} + +EFI_DEVICE_PATH_PROTOCOL * +EfiAppendDevicePathInstance ( + IN EFI_DEVICE_PATH_PROTOCOL *Src, + IN EFI_DEVICE_PATH_PROTOCOL *Instance + ) +/*++ + +Routine Description: + + Append a device path instance to another. + +Arguments: + + Src - The device path instance to be appended with. + Instance - The device path instance appending the other. + +Returns: + + The contaction of these two. + +--*/ +{ + UINT8 *Ptr; + EFI_DEVICE_PATH_PROTOCOL *DevPath; + UINTN SrcSize; + UINTN InstanceSize; + + if (Src == NULL) { + return EfiDuplicateDevicePath (Instance); + } + + SrcSize = EfiDevicePathSize (Src); + InstanceSize = EfiDevicePathSize (Instance); + + Ptr = EfiLibAllocateCopyPool (SrcSize + InstanceSize, Src); + if (Ptr != NULL) { + + DevPath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr; + + while (!IsDevicePathEnd (DevPath)) { + DevPath = NextDevicePathNode (DevPath); + } + // + // Convert the End to an End Instance, since we are + // appending another instacne after this one its a good + // idea. + // + DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; + + DevPath = NextDevicePathNode (DevPath); + EfiCopyMem (DevPath, Instance, InstanceSize); + } + + return (EFI_DEVICE_PATH_PROTOCOL *) Ptr; +} + +VOID +EFIAPI +EfiInitializeFwVolDevicepathNode ( + IN MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvDevicePathNode, + IN EFI_GUID *NameGuid + ) +/*++ + +Routine Description: + + Initialize a Firmware Volume (FV) Media Device Path node. + +Arguments: + + FvDevicePathNode - Pointer to a FV device path node to initialize + NameGuid - FV file name to use in FvDevicePathNode + +Returns: + + None + +--*/ +{ + FvDevicePathNode->Header.Type = MEDIA_DEVICE_PATH; + FvDevicePathNode->Header.SubType = MEDIA_FV_FILEPATH_DP; + SetDevicePathNodeLength (&FvDevicePathNode->Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH)); + + EfiCopyMem (&FvDevicePathNode->NameGuid, NameGuid, sizeof(EFI_GUID)); +} + +EFI_GUID * +EFIAPI +EfiGetNameGuidFromFwVolDevicePathNode ( + IN MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvDevicePathNode + ) +/*++ + +Routine Description: + + Check to see if the Firmware Volume (FV) Media Device Path is valid. + +Arguments: + + FvDevicePathNode - Pointer to FV device path to check + +Returns: + + NULL - FvDevicePathNode is not valid. + Other - FvDevicePathNode is valid and pointer to NameGuid was returned. + +--*/ +{ + if (DevicePathType (&FvDevicePathNode->Header) == MEDIA_DEVICE_PATH && + DevicePathSubType (&FvDevicePathNode->Header) == MEDIA_FV_FILEPATH_DP) { + return &FvDevicePathNode->NameGuid; + } + + return NULL; +} diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/DxeDriverLib.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/DxeDriverLib.c new file mode 100644 index 0000000..0d5b36e --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/DxeDriverLib.c @@ -0,0 +1,56 @@ +/*++ + +Copyright (c) 2004, 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: + + DxeDriverLib.c + +Abstract: + + Light weight lib to support EFI drivers. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" + +EFI_STATUS +DxeInitializeDriverLib ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + + Intialize Driver Lib if it has not yet been initialized. + +Arguments: + + ImageHandle - Standard EFI Image entry parameter + + SystemTable - Standard EFI Image entry parameter + +Returns: + + EFI_STATUS always returns EFI_SUCCESS + +--*/ +{ + EFI_STATUS Status; + + Status = EfiInitializeDriverLib (ImageHandle, SystemTable); + if (!EFI_ERROR (Status)) { + Status = EfiLibGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS); + } + + return Status; +} diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/Ebc/PerformancePrimitives.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/Ebc/PerformancePrimitives.c new file mode 100644 index 0000000..7e77a2e --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/Ebc/PerformancePrimitives.c @@ -0,0 +1,52 @@ +/*++ + +Copyright (c) 2004, 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: + + PerformancePrimitives.c + +Abstract: + + Support for Performance library + +--*/ + +#include "Tiano.h" // for ASSERT macro +#include "TianoCommon.h" + +EFI_STATUS +GetTimerValue ( + OUT UINT64 *TimerValue + ) +/*++ + +Routine Description: + + Set TimerValue to 0, which is not expected to be run. + +Arguments: + + TimerValue - Timer value for output + +Returns: + + EFI_SUCCESS - Should not be reached. + +--*/ +{ + // + // Should not be used for EBC, so assert. + // + *TimerValue = 0; + ASSERT (FALSE); + + return EFI_SUCCESS; +} diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.c new file mode 100644 index 0000000..674bf4c --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.c @@ -0,0 +1,506 @@ +/*++ + +Copyright (c) 2004 - 2008, 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: + + EfiDriverLib.c + +Abstract: + + Light weight lib to support EFI drivers. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" + +// +// Global Interface for Debug Mask Protocol +// +EFI_DEBUG_MASK_PROTOCOL *gDebugMaskInterface = NULL; + +EFI_STATUS +EfiInitializeDriverLib ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + + Intialize Driver Lib if it has not yet been initialized. + +Arguments: + + ImageHandle - Standard EFI Image entry parameter + + SystemTable - Standard EFI Image entry parameter + +Returns: + + EFI_STATUS always returns EFI_SUCCESS + +--*/ +{ + gST = SystemTable; + + ASSERT (gST != NULL); + + gBS = gST->BootServices; + gRT = gST->RuntimeServices; + + ASSERT (gBS != NULL); + ASSERT (gRT != NULL); + + // + // Get driver debug mask protocol interface + // +#ifdef EFI_DEBUG + gBS->HandleProtocol ( + ImageHandle, + &gEfiDebugMaskProtocolGuid, + (VOID *) &gDebugMaskInterface + ); +#endif + // + // Should be at EFI_D_INFO, but lets us know things are running + // + DEBUG ((EFI_D_INFO, "EfiInitializeDriverLib: Started\n")); + + return EFI_SUCCESS; +} + +STATIC +BOOLEAN +IsIso639LanguageCode ( + IN CHAR8 *Languages + ) +/*++ + +Routine Description: + + Tests whether a language code has format of ISO639-2. + +Arguments: + + Languages - The language code to be tested. + +Returns: + + TRUE - Language code format is ISO 639-2. + FALSE - Language code format is not ISO 639-2. + +--*/ +{ + UINTN Index; + + // + // Find out format of Languages + // + for (Index = 0; Languages[Index] != 0 && Languages[Index] != ';' && Languages[Index] != '-'; Index++); + if (Languages[Index] != 0) { + // + // RFC4646 language code + // + return FALSE; + } + + // + // No ';' and '-', it's either ISO639-2 code (list) or single RFC4646 code + // + if (Index == 2) { + // + // Single RFC4646 language code without country code, e.g. "en" + // + return FALSE; + } + + // + // Languages in format of ISO639-2 + // + return TRUE; +} + +BOOLEAN +EfiLibCompareLanguage ( + IN CHAR8 *Language1, + IN CHAR8 *Language2 + ) +/*++ + +Routine Description: + + Compare the first language instance of two language codes, either could be a + single language code or a language code list. This function assume Language1 + and Language2 has the same language code format, i.e. either ISO639-2 or RFC4646. + +Arguments: + + Language1 - The first language code to be tested. + Language2 - The second language code to be tested. + +Returns: + + TRUE - Language code match. + FALSE - Language code mismatch. + +--*/ +{ + UINTN Index; + + // + // Compare first two bytes of language tag + // + if ((Language1[0] != Language2[0]) || (Language1[1] != Language2[1])) { + return FALSE; + } + + if (IsIso639LanguageCode (Language1)) { + // + // ISO639-2 language code, compare the third byte of language tag + // + return (Language1[2] == Language2[2]) ? TRUE : FALSE; + } + + // + // RFC4646 language code + // + for (Index = 0; Language1[Index] != 0 && Language1[Index] != ';'; Index++); + if ((EfiAsciiStrnCmp (Language1, Language2, Index) == 0) && (Language2[Index] == 0 || Language2[Index] == ';')) { + return TRUE; +} + + return FALSE; +} + +STATIC +CHAR8 * +NextSupportedLanguage ( + IN CHAR8 *Languages + ) +/*++ + +Routine Description: + + Step to next language code of a language code list. + +Arguments: + + Languages - The language code list to traverse. + +Returns: + + Pointer to next language code or NULL terminator if it's the last one. + +--*/ +{ + UINTN Index; + + if (IsIso639LanguageCode (Languages)) { + // + // ISO639-2 language code + // + return (Languages + 3); + } + + // + // Search in RFC4646 language code list + // + for (Index = 0; Languages[Index] != 0 && Languages[Index] != ';'; Index++); + if (Languages[Index] == ';') { + Index++; + } + return (Languages + Index); +} + +EFI_STATUS +EfiLibLookupUnicodeString ( + IN CHAR8 *Language, + IN CHAR8 *SupportedLanguages, + IN EFI_UNICODE_STRING_TABLE *UnicodeStringTable, + OUT CHAR16 **UnicodeString + ) +/*++ + +Routine Description: + + Translate a unicode string to a specified language if supported. + +Arguments: + + Language - The name of language to translate to + SupportedLanguages - Supported languages set + UnicodeStringTable - Pointer of one item in translation dictionary + UnicodeString - The translated string + +Returns: + + EFI_INVALID_PARAMETER - Invalid parameter + EFI_UNSUPPORTED - System not supported this language or this string translation + EFI_SUCCESS - String successfully translated + +--*/ +{ + // + // Make sure the parameters are valid + // + if (Language == NULL || UnicodeString == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // If there are no supported languages, or the Unicode String Table is empty, then the + // Unicode String specified by Language is not supported by this Unicode String Table + // + if (SupportedLanguages == NULL || UnicodeStringTable == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure Language is in the set of Supported Languages + // + while (*SupportedLanguages != 0) { + if (EfiLibCompareLanguage (Language, SupportedLanguages)) { + + // + // Search the Unicode String Table for the matching Language specifier + // + while (UnicodeStringTable->Language != NULL) { + if (EfiLibCompareLanguage (Language, UnicodeStringTable->Language)) { + + // + // A matching string was found, so return it + // + *UnicodeString = UnicodeStringTable->UnicodeString; + return EFI_SUCCESS; + } + + UnicodeStringTable++; + } + + return EFI_UNSUPPORTED; + } + + SupportedLanguages = NextSupportedLanguage (SupportedLanguages); + } + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EfiLibAddUnicodeString ( + IN CHAR8 *Language, + IN CHAR8 *SupportedLanguages, + IN OUT EFI_UNICODE_STRING_TABLE **UnicodeStringTable, + IN CHAR16 *UnicodeString + ) +/*++ + +Routine Description: + + Add an translation to the dictionary if this language if supported. + +Arguments: + + Language - The name of language to translate to + SupportedLanguages - Supported languages set + UnicodeStringTable - Translation dictionary + UnicodeString - The corresponding string for the language to be translated to + +Returns: + + EFI_INVALID_PARAMETER - Invalid parameter + EFI_UNSUPPORTED - System not supported this language + EFI_ALREADY_STARTED - Already has a translation item of this language + EFI_OUT_OF_RESOURCES - No enough buffer to be allocated + EFI_SUCCESS - String successfully translated + +--*/ +{ + UINTN NumberOfEntries; + EFI_UNICODE_STRING_TABLE *OldUnicodeStringTable; + EFI_UNICODE_STRING_TABLE *NewUnicodeStringTable; + UINTN UnicodeStringLength; + + // + // Make sure the parameter are valid + // + if (Language == NULL || UnicodeString == NULL || UnicodeStringTable == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // If there are no supported languages, then a Unicode String can not be added + // + if (SupportedLanguages == NULL) { + return EFI_UNSUPPORTED; + } + + // + // If the Unicode String is empty, then a Unicode String can not be added + // + if (UnicodeString[0] == 0) { + return EFI_INVALID_PARAMETER; + } + + // + // Make sure Language is a member of SupportedLanguages + // + while (*SupportedLanguages != 0) { + if (EfiLibCompareLanguage (Language, SupportedLanguages)) { + + // + // Determine the size of the Unicode String Table by looking for a NULL Language entry + // + NumberOfEntries = 0; + if (*UnicodeStringTable != NULL) { + OldUnicodeStringTable = *UnicodeStringTable; + while (OldUnicodeStringTable->Language != NULL) { + if (EfiLibCompareLanguage (Language, OldUnicodeStringTable->Language)) { + return EFI_ALREADY_STARTED; + } + + OldUnicodeStringTable++; + NumberOfEntries++; + } + } + + // + // Allocate space for a new Unicode String Table. It must hold the current number of + // entries, plus 1 entry for the new Unicode String, plus 1 entry for the end of table + // marker + // + NewUnicodeStringTable = EfiLibAllocatePool ((NumberOfEntries + 2) * sizeof (EFI_UNICODE_STRING_TABLE)); + if (NewUnicodeStringTable == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // If the current Unicode String Table contains any entries, then copy them to the + // newly allocated Unicode String Table. + // + if (*UnicodeStringTable != NULL) { + EfiCopyMem ( + NewUnicodeStringTable, + *UnicodeStringTable, + NumberOfEntries * sizeof (EFI_UNICODE_STRING_TABLE) + ); + } + + // + // Allocate space for a copy of the Language specifier + // + NewUnicodeStringTable[NumberOfEntries].Language = EfiLibAllocateCopyPool (EfiAsciiStrSize (Language), Language); + if (NewUnicodeStringTable[NumberOfEntries].Language == NULL) { + gBS->FreePool (NewUnicodeStringTable); + return EFI_OUT_OF_RESOURCES; + } + + // + // Compute the length of the Unicode String + // + for (UnicodeStringLength = 0; UnicodeString[UnicodeStringLength] != 0; UnicodeStringLength++) + ; + + // + // Allocate space for a copy of the Unicode String + // + NewUnicodeStringTable[NumberOfEntries].UnicodeString = EfiLibAllocateCopyPool ( + (UnicodeStringLength + 1) * sizeof (CHAR16), + UnicodeString + ); + if (NewUnicodeStringTable[NumberOfEntries].UnicodeString == NULL) { + gBS->FreePool (NewUnicodeStringTable[NumberOfEntries].Language); + gBS->FreePool (NewUnicodeStringTable); + return EFI_OUT_OF_RESOURCES; + } + + // + // Mark the end of the Unicode String Table + // + NewUnicodeStringTable[NumberOfEntries + 1].Language = NULL; + NewUnicodeStringTable[NumberOfEntries + 1].UnicodeString = NULL; + + // + // Free the old Unicode String Table + // + if (*UnicodeStringTable != NULL) { + gBS->FreePool (*UnicodeStringTable); + } + + // + // Point UnicodeStringTable at the newly allocated Unicode String Table + // + *UnicodeStringTable = NewUnicodeStringTable; + + return EFI_SUCCESS; + } + + SupportedLanguages = NextSupportedLanguage (SupportedLanguages); + } + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EfiLibFreeUnicodeStringTable ( + IN OUT EFI_UNICODE_STRING_TABLE *UnicodeStringTable + ) +/*++ + +Routine Description: + + Free a string table. + +Arguments: + + UnicodeStringTable - The string table to be freed. + +Returns: + + EFI_SUCCESS - The table successfully freed. + +--*/ +{ + UINTN Index; + + // + // If the Unicode String Table is NULL, then it is already freed + // + if (UnicodeStringTable == NULL) { + return EFI_SUCCESS; + } + + // + // Loop through the Unicode String Table until we reach the end of table marker + // + for (Index = 0; UnicodeStringTable[Index].Language != NULL; Index++) { + + // + // Free the Language string from the Unicode String Table + // + gBS->FreePool (UnicodeStringTable[Index].Language); + + // + // Free the Unicode String from the Unicode String Table + // + if (UnicodeStringTable[Index].UnicodeString != NULL) { + gBS->FreePool (UnicodeStringTable[Index].UnicodeString); + } + } + + // + // Free the Unicode String Table itself + // + gBS->FreePool (UnicodeStringTable); + + return EFI_SUCCESS; +} diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.cif b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.cif new file mode 100644 index 0000000..701a0b9 --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.cif @@ -0,0 +1,32 @@ +<component> + name = "EfiDriverLib" + category = ModulePart + LocalRoot = "EDK\Foundation\Library\Dxe\EfiDriverLib\" + RefName = "EfiDriverLib" +[files] +"EfiDriverLib.sdl" +"EfiDriverLib.mak" +"Debug.c" +"DevicePath.c" +"EfiDriverLib.c" +"DxeDriverLib.c" +"EfiGetConfigTable.c" +"EfiDriverModelLib.c" +"Event.c" +"Handle.c" +"LibGlobalSt.c" +"LibGlobalDs.c" +"LibGlobalErrorLevel.c" +"Lock.c" +"EfiLibAllocate.c" +"Perf.c" +"ReportStatusCode.c" +"GetImage.c" +"..\hob\hob.c" +"IA32\PerformancePrimitives.c" +"x64\PerformancePrimitives.c" +"Ipf\PerformancePrimitives.s" +"Ebc\PerformancePrimitives.c" +"EfiDriverLib.inf" +"HobLib.inf" +<endComponent> diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.inf b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.inf new file mode 100644 index 0000000..83226e9 --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.inf @@ -0,0 +1,90 @@ +#/*++ +# +# Copyright (c) 2004 - 2012, 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: +# +# EfiDriverLib.inf +# +# Abstract: +# +# Component description file for the EFI driver library. +# +#--*/ + +[defines] +BASE_NAME = EfiDriverLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + Debug.c + DevicePath.c + EfiDriverLib.c + DxeDriverLib.c + EfiGetConfigTable.c + EfiDriverModelLib.c + Event.c + Handle.c + LibGlobalSt.c + LibGlobalDs.c + LibGlobalErrorLevel.c + Lock.c + EfiLibAllocate.c + Perf.c + ReportStatusCode.c + GetImage.c + + ..\hob\hob.c + +[sources.ia32] + ia32\PerformancePrimitives.c + +[sources.x64] + x64\PerformancePrimitives.c + +[sources.ipf] + ipf\PerformancePrimitives.s + +[sources.ebc] + Ebc\PerformancePrimitives.c + +[includes.common] + $(EDK_SOURCE)\Foundation + $(EDK_SOURCE)\Foundation\Framework + $(EDK_SOURCE)\Foundation\Efi + $(EDK_SOURCE)\Foundation\Include + $(EDK_SOURCE)\Foundation\Efi\Include + $(EDK_SOURCE)\Foundation\Framework\Include + $(EDK_SOURCE)\Foundation\Include\IndustryStandard + $(EDK_SOURCE)\Foundation\Core\Dxe + $(EDK_SOURCE)\Foundation\Library\Dxe\Include + $(EDK_SOURCE)\Foundation\Cpu\Pentium\Include + +[libraries.common] + EdkGuidLib + EdkProtocolLib + EdkFrameworkProtocolLib + EfiGuidLib + EfiProtocolLib + ArchProtocolLib + EfiCommonLib + PrintLib + +[libraries.ia32] + CpuIA32Lib + +[libraries.x64] + CpuIA32Lib + +[libraries.ipf] + CpuIA64Lib + +[nmake.common] + C_STD_INCLUDE= diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.mak b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.mak new file mode 100644 index 0000000..ac43c21 --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.mak @@ -0,0 +1,75 @@ +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** + +#********************************************************************** +# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelEDK/EfiDriverLib/EfiDriverLib.mak 1 1/20/12 4:06a Jeffch $ +# +# $Revision: 1 $ +# +# $Date: 1/20/12 4:06a $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelEDK/EfiDriverLib/EfiDriverLib.mak $ +# +# 1 1/20/12 4:06a Jeffch +# Create Intel EDK 1117 Patch 7. +# +# 1 9/27/11 6:30a Wesleychen +# Intel EDK initially releases. +# +# 2 9/02/09 3:44a Iminglin +# EIP24919 +# +#********************************************************************** +#<AMI_FHDR_START> +# +# Name: EfiDriverLib.mak +# +# Description: +# +#<AMI_FHDR_END> +#********************************************************************** +$(EFIDRIVERLIB) : EfiDriverLib + +$(BUILD_DIR)\EfiDriverLib.lib : EfiDriverLib + +EfiDriverLib : $(BUILD_DIR)\EfiDriverLib.mak EfiDriverLibBin + +$(BUILD_DIR)\EfiDriverLib.mak : $(EfiDriverLib_DIR)\$(@B).cif $(EfiDriverLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(EfiDriverLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +!IF "$(PROCESSOR)"!="IPF" +EfiDriverLibBin : $(CPUIA32LIB) +!ELSE +EfiDriverLibBin : $(CPUIA64LIB) +!ENDIF + +EfiDriverLibBin : $(EDKGUIDLIB) $(EDKPROTOCOLLIB) $(EDKFRAMEWORKPROTOCOLLIB) $(EFIGUIDLIB) $(EFIPROTOCOLLIB) $(ARCHPROTOCOLLIB) $(EFICOMMONLIB) + $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS)\ + /f $(BUILD_DIR)\EfiDriverLib.mak all\ + TYPE=LIBRARY +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#**********************************************************************
\ No newline at end of file diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.sdl b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.sdl new file mode 100644 index 0000000..9c3fc8d --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.sdl @@ -0,0 +1,26 @@ +TOKEN + Name = "EfiDriverLib_SUPPORT" + Value = "1" + Help = "Main switch to enable EfiDriverLib support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +TOKEN + Name = "EFIDRIVERLIB" + Value = "$(BUILD_DIR)\EfiDriverLib.lib" + TokenType = Expression + TargetMAK = Yes +End + +PATH + Name = "EfiDriverLib_DIR" +End + +MODULE + Help = "Includes EfiDriverLib.mak to Project" + File = "EfiDriverLib.mak" +End + diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverModelLib.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverModelLib.c new file mode 100644 index 0000000..eb3d7ae --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiDriverModelLib.c @@ -0,0 +1,444 @@ +/*++ + +Copyright (c) 2004 - 2008, 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: + + EfiDriverModelLib.c + +Abstract: + + Light weight lib to support EFI drivers. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" + +EFI_STATUS +EfiLibInstallDriverBinding ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable, + IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, + IN EFI_HANDLE DriverBindingHandle + ) +/*++ + +Routine Description: + + Intialize a driver by installing the Driver Binding Protocol onto the + driver's DriverBindingHandle. This is typically the same as the driver's + ImageHandle, but it can be different if the driver produces multiple + DriverBinding Protocols. This function also initializes the EFI Driver + Library that initializes the global variables gST, gBS, gRT. + +Arguments: + + ImageHandle - The image handle of the driver + + SystemTable - The EFI System Table that was passed to the driver's entry point + + DriverBinding - A Driver Binding Protocol instance that this driver is producing + + DriverBindingHandle - The handle that DriverBinding is to be installe onto. If this + parameter is NULL, then a new handle is created. + +Returns: + + EFI_SUCCESS is DriverBinding is installed onto DriverBindingHandle + + Otherwise, then return status from gBS->InstallProtocolInterface() + +--*/ +{ + EfiInitializeDriverLib (ImageHandle, SystemTable); + + DriverBinding->ImageHandle = ImageHandle; + + DriverBinding->DriverBindingHandle = DriverBindingHandle; + + return gBS->InstallProtocolInterface ( + &DriverBinding->DriverBindingHandle, + &gEfiDriverBindingProtocolGuid, + EFI_NATIVE_INTERFACE, + DriverBinding + ); +} + +EFI_STATUS +InstallAllDriverProtocolsWorker ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE * SystemTable, + IN EFI_DRIVER_BINDING_PROTOCOL * DriverBinding, + IN EFI_HANDLE DriverBindingHandle, + IN EFI_COMPONENT_NAME_PROTOCOL * ComponentName, OPTIONAL + IN EFI_COMPONENT_NAME2_PROTOCOL * ComponentName2, OPTIONAL + IN EFI_DRIVER_CONFIGURATION_PROTOCOL * DriverConfiguration, OPTIONAL + IN EFI_DRIVER_CONFIGURATION2_PROTOCOL * DriverConfiguration2, OPTIONAL + IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL * DriverDiagnostics, OPTIONAL + IN EFI_DRIVER_DIAGNOSTICS2_PROTOCOL * DriverDiagnostics2 OPTIONAL + ) +/*++ + +Routine Description: + + Intialize a driver by installing the Driver Binding Protocol onto the + driver's DriverBindingHandle. This is typically the same as the driver's + ImageHandle, but it can be different if the driver produces multiple + DriverBinding Protocols. This function also initializes the EFI Driver + Library that initializes the global variables gST, gBS, gRT. + +Arguments: + + ImageHandle - The image handle of the driver + + SystemTable - The EFI System Table that was passed to the driver's entry point + + DriverBinding - A Driver Binding Protocol instance that this driver is producing + + DriverBindingHandle - The handle that DriverBinding is to be installe onto. If this + parameter is NULL, then a new handle is created. + + ComponentName - A Component Name Protocol instance that this driver is producing + + ComponentName2 - A Component Name2 Protocol instance that this driver is producing + + DriverConfiguration - A Driver Configuration Protocol instance that this driver is producing + + DriverConfiguration2- A Driver Configuration2 Protocol instance that this driver is producing + + DriverDiagnostics - A Driver Diagnostics Protocol instance that this driver is producing + + DriverDiagnostics2 - A Driver Diagnostics2 Protocol instance that this driver is producing + +Returns: + + EFI_SUCCESS if all the protocols were installed onto DriverBindingHandle + + Otherwise, then return status from gBS->InstallProtocolInterface() + +--*/ +{ + EFI_STATUS Status; + + Status = EfiLibInstallDriverBinding (ImageHandle, SystemTable, DriverBinding, DriverBindingHandle); + if (EFI_ERROR (Status)) { + return Status; + } + + if (ComponentName != NULL) { + Status = gBS->InstallProtocolInterface ( + &DriverBinding->DriverBindingHandle, + &gEfiComponentNameProtocolGuid, + EFI_NATIVE_INTERFACE, + ComponentName + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + if (ComponentName2 != NULL) { + Status = gBS->InstallProtocolInterface ( + &DriverBinding->DriverBindingHandle, + &gEfiComponentName2ProtocolGuid, + EFI_NATIVE_INTERFACE, + ComponentName2 + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + if (DriverConfiguration != NULL) { + Status = gBS->InstallProtocolInterface ( + &DriverBinding->DriverBindingHandle, + &gEfiDriverConfigurationProtocolGuid, + EFI_NATIVE_INTERFACE, + DriverConfiguration + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + if (DriverConfiguration2 != NULL) { + Status = gBS->InstallProtocolInterface ( + &DriverBinding->DriverBindingHandle, + &gEfiDriverConfiguration2ProtocolGuid, + EFI_NATIVE_INTERFACE, + DriverConfiguration2 + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + if (DriverDiagnostics != NULL) { + Status = gBS->InstallProtocolInterface ( + &DriverBinding->DriverBindingHandle, + &gEfiDriverDiagnosticsProtocolGuid, + EFI_NATIVE_INTERFACE, + DriverDiagnostics + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + if (DriverDiagnostics2 != NULL) { + Status = gBS->InstallProtocolInterface ( + &DriverBinding->DriverBindingHandle, + &gEfiDriverDiagnostics2ProtocolGuid, + EFI_NATIVE_INTERFACE, + DriverDiagnostics2 + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EfiLibInstallAllDriverProtocols ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE * SystemTable, + IN EFI_DRIVER_BINDING_PROTOCOL * DriverBinding, + IN EFI_HANDLE DriverBindingHandle, + IN EFI_COMPONENT_NAME_PROTOCOL * ComponentName, OPTIONAL + IN EFI_DRIVER_CONFIGURATION_PROTOCOL * DriverConfiguration, OPTIONAL + IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL * DriverDiagnostics OPTIONAL + ) +/*++ + +Routine Description: + + Intialize a driver by installing the Driver Binding Protocol onto the + driver's DriverBindingHandle. This is typically the same as the driver's + ImageHandle, but it can be different if the driver produces multiple + DriverBinding Protocols. This function also initializes the EFI Driver + Library that initializes the global variables gST, gBS, gRT. + +Arguments: + + ImageHandle - The image handle of the driver + + SystemTable - The EFI System Table that was passed to the driver's entry point + + DriverBinding - A Driver Binding Protocol instance that this driver is producing + + DriverBindingHandle - The handle that DriverBinding is to be installe onto. If this + parameter is NULL, then a new handle is created. + + ComponentName - A Component Name Protocol instance that this driver is producing + + DriverConfiguration - A Driver Configuration Protocol instance that this driver is producing + + DriverDiagnostics - A Driver Diagnostics Protocol instance that this driver is producing + +Returns: + + EFI_SUCCESS if all the protocols were installed onto DriverBindingHandle + + Otherwise, then return status from gBS->InstallProtocolInterface() + +--*/ +{ + return InstallAllDriverProtocolsWorker ( + ImageHandle, + SystemTable, + DriverBinding, + DriverBindingHandle, + ComponentName, + NULL, + DriverConfiguration, + NULL, + DriverDiagnostics, + NULL + ); +} + +EFI_STATUS +EfiLibInstallAllDriverProtocols2 ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE * SystemTable, + IN EFI_DRIVER_BINDING_PROTOCOL * DriverBinding, + IN EFI_HANDLE DriverBindingHandle, + IN EFI_COMPONENT_NAME2_PROTOCOL * ComponentName2, OPTIONAL + IN EFI_DRIVER_CONFIGURATION2_PROTOCOL * DriverConfiguration2, OPTIONAL + IN EFI_DRIVER_DIAGNOSTICS2_PROTOCOL * DriverDiagnostics2 OPTIONAL + ) +/*++ + +Routine Description: + + Intialize a driver by installing the Driver Binding Protocol onto the + driver's DriverBindingHandle. This is typically the same as the driver's + ImageHandle, but it can be different if the driver produces multiple + DriverBinding Protocols. This function also initializes the EFI Driver + Library that initializes the global variables gST, gBS, gRT. + +Arguments: + + ImageHandle - The image handle of the driver + + SystemTable - The EFI System Table that was passed to the driver's entry point + + DriverBinding - A Driver Binding Protocol instance that this driver is producing + + DriverBindingHandle - The handle that DriverBinding is to be installe onto. If this + parameter is NULL, then a new handle is created. + + ComponentName2 - A Component Name2 Protocol instance that this driver is producing + + DriverConfiguration2- A Driver Configuration2 Protocol instance that this driver is producing + + DriverDiagnostics2 - A Driver Diagnostics2 Protocol instance that this driver is producing + +Returns: + + EFI_SUCCESS if all the protocols were installed onto DriverBindingHandle + + Otherwise, then return status from gBS->InstallProtocolInterface() + +--*/ +{ + return InstallAllDriverProtocolsWorker ( + ImageHandle, + SystemTable, + DriverBinding, + DriverBindingHandle, + NULL, + ComponentName2, + NULL, + DriverConfiguration2, + NULL, + DriverDiagnostics2 + ); +} + +EFI_STATUS +EfiLibTestManagedDevice ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverBindingHandle, + IN EFI_GUID *ManagedProtocolGuid + ) +/*++ + +Routine Description: + + Test to see if the controller is managed by a specific driver. + +Arguments: + + ControllerHandle - Handle for controller to test + + DriverBindingHandle - Driver binding handle for controller + + ManagedProtocolGuid - The protocol guid the driver opens on controller + +Returns: + + EFI_SUCCESS - The controller is managed by the driver + + EFI_UNSUPPORTED - The controller is not managed by the driver + +--*/ +{ + EFI_STATUS Status; + VOID *ManagedInterface; + + Status = gBS->OpenProtocol ( + ControllerHandle, + ManagedProtocolGuid, + &ManagedInterface, + DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (!EFI_ERROR (Status)) { + gBS->CloseProtocol ( + ControllerHandle, + ManagedProtocolGuid, + DriverBindingHandle, + ControllerHandle + ); + return EFI_UNSUPPORTED; + } + + if (Status != EFI_ALREADY_STARTED) { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EfiLibTestChildHandle ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle, + IN EFI_GUID *ConsumedGuid + ) +/*++ + +Routine Description: + + Test to see if the child handle is the child of the controller + +Arguments: + + ControllerHandle - Handle for controller (parent) + + ChildHandle - Child handle to test + + ConsumsedGuid - Protocol guid consumed by child from controller + +Returns: + + EFI_SUCCESS - The child handle is the child of the controller + + EFI_UNSUPPORTED - The child handle is not the child of the controller + +--*/ +{ + EFI_STATUS Status; + EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; + UINTN EntryCount; + UINTN Index; + + // + // Retrieve the list of agents that are consuming one of the protocols + // on ControllerHandle that the children consume + // + Status = gBS->OpenProtocolInformation ( + ControllerHandle, + ConsumedGuid, + &OpenInfoBuffer, + &EntryCount + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + // + // See if one of the agents is ChildHandle + // + Status = EFI_UNSUPPORTED; + for (Index = 0; Index < EntryCount; Index++) { + if (OpenInfoBuffer[Index].ControllerHandle == ChildHandle && + OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) { + Status = EFI_SUCCESS; + } + } + gBS->FreePool (OpenInfoBuffer); + return Status; +} diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiGetConfigTable.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiGetConfigTable.c new file mode 100644 index 0000000..619f1b2 --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiGetConfigTable.c @@ -0,0 +1,61 @@ +/*++ + +Copyright (c) 2004, 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: + + EfiGetConfigTable.c + +Abstract: + + Light weight lib to support EFI drivers. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" + +EFI_STATUS +EfiLibGetSystemConfigurationTable ( + IN EFI_GUID *TableGuid, + IN OUT VOID **Table + ) +/*++ + +Routine Description: + + Get table from configuration table by name + +Arguments: + + TableGuid - Table name to search + + Table - Pointer to the table caller wants + +Returns: + + EFI_NOT_FOUND - Not found the table + + EFI_SUCCESS - Found the table + +--*/ +{ + UINTN Index; + + *Table = NULL; + for (Index = 0; Index < gST->NumberOfTableEntries; Index++) { + if (EfiCompareGuid (TableGuid, &(gST->ConfigurationTable[Index].VendorGuid))) { + *Table = gST->ConfigurationTable[Index].VendorTable; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiLibAllocate.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiLibAllocate.c new file mode 100644 index 0000000..373d2df --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/EfiLibAllocate.c @@ -0,0 +1,233 @@ +/*++ + +Copyright (c) 2004 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiLibAllocate.c + +Abstract: + + Support routines for memory allocation routines for use with drivers. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" + +VOID * +EfiLibAllocatePool ( + IN UINTN AllocationSize + ) +/*++ + +Routine Description: + + Allocate BootServicesData pool. + +Arguments: + + AllocationSize - The size to allocate + +Returns: + + Pointer of the buffer allocated. + +--*/ +{ + VOID *Memory; + + Memory = NULL; + gBS->AllocatePool (EfiBootServicesData, AllocationSize, &Memory); + return Memory; +} + +VOID * +EfiLibAllocateRuntimePool ( + IN UINTN AllocationSize + ) +/*++ + +Routine Description: + + Allocate RuntimeServicesData pool. + +Arguments: + + AllocationSize - The size to allocate + +Returns: + + Pointer of the buffer allocated. + +--*/ +{ + VOID *Memory; + + Memory = NULL; + gBS->AllocatePool (EfiRuntimeServicesData, AllocationSize, &Memory); + return Memory; +} + +VOID * +EfiLibAllocateZeroPool ( + IN UINTN AllocationSize + ) +/*++ + +Routine Description: + + Allocate BootServicesData pool and zero it. + +Arguments: + + AllocationSize - The size to allocate + +Returns: + + Pointer of the buffer allocated. + +--*/ +{ + VOID *Memory; + + Memory = EfiLibAllocatePool (AllocationSize); + if (Memory != NULL) { + gBS->SetMem (Memory, AllocationSize, 0); + } + + return Memory; +} + +VOID * +EfiLibAllocateRuntimeZeroPool ( + IN UINTN AllocationSize + ) +/*++ + +Routine Description: + + Allocate RuntimeServicesData pool and zero it. + +Arguments: + + AllocationSize - The size to allocate + +Returns: + + Pointer of the buffer allocated. + +--*/ +{ + VOID *Memory; + + Memory = EfiLibAllocateRuntimePool (AllocationSize); + if (Memory != NULL) { + gBS->SetMem (Memory, AllocationSize, 0); + } + + return Memory; +} + +VOID * +EfiLibAllocateCopyPool ( + IN UINTN AllocationSize, + IN VOID *Buffer + ) +/*++ + +Routine Description: + + Allocate BootServicesData pool and use a buffer provided by + caller to fill it. + +Arguments: + + AllocationSize - The size to allocate + + Buffer - Buffer that will be filled into the buffer allocated + +Returns: + + Pointer of the buffer allocated. + +--*/ +{ + VOID *Memory; + + Memory = NULL; + gBS->AllocatePool (EfiBootServicesData, AllocationSize, &Memory); + if (Memory != NULL) { + gBS->CopyMem (Memory, Buffer, AllocationSize); + } + + return Memory; +} + +VOID * +EfiLibAllocateRuntimeCopyPool ( + IN UINTN AllocationSize, + IN VOID *Buffer + ) +/*++ + +Routine Description: + + Allocate RuntimeServicesData pool and use a buffer provided by + caller to fill it. + +Arguments: + + AllocationSize - The size to allocate + + Buffer - Buffer that will be filled into the buffer allocated + +Returns: + + Pointer of the buffer allocated. + +--*/ +{ + VOID *Memory; + + Memory = NULL; + gBS->AllocatePool (EfiRuntimeServicesData, AllocationSize, &Memory); + if (Memory != NULL) { + gBS->CopyMem (Memory, Buffer, AllocationSize); + } + + return Memory; +} + + +VOID +EfiLibSafeFreePool ( + IN VOID *Buffer + ) +/*++ + +Routine Description: + + Free pool safely (without setting back Buffer to NULL). + +Arguments: + + Buffer - The allocated pool entry to free + +Returns: + + Pointer of the buffer allocated. + +--*/ +{ + if (Buffer != NULL) { + gBS->FreePool (Buffer); + } +}
\ No newline at end of file diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/Event.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/Event.c new file mode 100644 index 0000000..c341d82 --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/Event.c @@ -0,0 +1,371 @@ +/*++ + +Copyright (c) 2004 - 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: + + Event.c + +Abstract: + + Support for Event lib fucntions. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" + +EFI_EVENT +EfiLibCreateProtocolNotifyEvent ( + IN EFI_GUID *ProtocolGuid, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, + IN VOID *NotifyContext, + OUT VOID **Registration + ) +/*++ + +Routine Description: + + Create a protocol notification event and return it. + +Arguments: + + ProtocolGuid - Protocol to register notification event on. + + NotifyTpl - Maximum TPL to single the NotifyFunction. + + NotifyFunction - EFI notification routine. + + NotifyContext - Context passed into Event when it is created. + + Registration - Registration key returned from RegisterProtocolNotify(). + +Returns: + + The EFI_EVENT that has been registered to be signaled when a ProtocolGuid + is added to the system. + +--*/ +{ + EFI_STATUS Status; + EFI_EVENT Event; + + // + // Create the event + // + + Status = gBS->CreateEvent ( + EFI_EVENT_NOTIFY_SIGNAL, + NotifyTpl, + NotifyFunction, + NotifyContext, + &Event + ); + ASSERT (!EFI_ERROR (Status)); + + // + // Register for protocol notifactions on this event + // + + Status = gBS->RegisterProtocolNotify ( + ProtocolGuid, + Event, + Registration + ); + + ASSERT (!EFI_ERROR (Status)); + + // + // Kick the event so we will perform an initial pass of + // current installed drivers + // + + gBS->SignalEvent (Event); + return Event; +} + +EFI_STATUS +EfiLibNamedEventListen ( + IN EFI_GUID * Name, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, + IN VOID *NotifyContext + ) +/*++ + +Routine Description: + Listenes to signals on the name. + EfiLibNamedEventSignal() signals the event. + + NOTE: For now, the named listening/signalling is implemented + on a protocol interface being installed and uninstalled. + In the future, this maybe implemented based on a dedicated mechanism. + +Arguments: + Name - Name to register the listener on. + NotifyTpl - Maximum TPL to singnal the NotifyFunction. + NotifyFunction - The listener routine. + NotifyContext - Context passed into the listener routine. + +Returns: + EFI_SUCCESS if successful. + +--*/ +{ + EFI_STATUS Status; + EFI_EVENT Event; + VOID *RegistrationLocal; + + // + // Create event + // + Status = gBS->CreateEvent ( + EFI_EVENT_NOTIFY_SIGNAL, + NotifyTpl, + NotifyFunction, + NotifyContext, + &Event + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->RegisterProtocolNotify ( + Name, + Event, + &RegistrationLocal + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + +EFI_STATUS +EfiLibNamedEventSignal ( + IN EFI_GUID *Name + ) +/*++ + +Routine Description: + Signals a named event. All registered listeners will run. + The listeners should register using EfiLibNamedEventListen() function. + + NOTE: For now, the named listening/signalling is implemented + on a protocol interface being installed and uninstalled. + In the future, this maybe implemented based on a dedicated mechanism. + +Arguments: + Name - Name to perform the signaling on. The name is a GUID. + +Returns: + EFI_SUCCESS if successfull. + +--*/ +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + Handle = NULL; + Status = gBS->InstallProtocolInterface ( + &Handle, + Name, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->UninstallProtocolInterface ( + Handle, + Name, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + +#if (EFI_SPECIFICATION_VERSION >= 0x00020000) + +static +VOID +EFIAPI +EventNotifySignalAllNullEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // This null event is a size efficent way to enusre that + // EFI_EVENT_NOTIFY_SIGNAL_ALL is error checked correctly. + // EFI_EVENT_NOTIFY_SIGNAL_ALL is now mapped into + // CreateEventEx() and this function is used to make the + // old error checking in CreateEvent() for Tiano extensions + // function. + // + return; +} + +#endif + +EFI_STATUS +EFIAPI +EfiCreateEventLegacyBoot ( + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, + IN VOID *NotifyContext, + OUT EFI_EVENT *LegacyBootEvent + ) +/*++ + +Routine Description: + Create a Legacy Boot Event. + Tiano extended the CreateEvent Type enum to add a legacy boot event type. + This was bad as Tiano did not own the enum. In UEFI 2.0 CreateEventEx was + added and now it's possible to not voilate the UEFI specification by + declaring a GUID for the legacy boot event class. This library supports + the R8.5/EFI 1.10 form and R8.6/UEFI 2.0 form and allows common code to + work both ways. + +Arguments: + LegacyBootEvent Returns the EFI event returned from gBS->CreateEvent(Ex) + +Returns: + EFI_SUCCESS Event was created. + Other Event was not created. + +--*/ +{ + EFI_STATUS Status; + UINT32 EventType; + EFI_EVENT_NOTIFY WorkerNotifyFunction; + +#if (EFI_SPECIFICATION_VERSION < 0x00020000) + + if (NotifyFunction == NULL) { + EventType = EFI_EVENT_SIGNAL_LEGACY_BOOT | EFI_EVENT_NOTIFY_SIGNAL_ALL; + } else { + EventType = EFI_EVENT_SIGNAL_LEGACY_BOOT; + } + WorkerNotifyFunction = NotifyFunction; + + // + // prior to UEFI 2.0 use Tiano extension to EFI + // + Status = gBS->CreateEvent ( + EventType, + NotifyTpl, + WorkerNotifyFunction, + NotifyContext, + LegacyBootEvent + ); +#else + + EventType = EFI_EVENT_NOTIFY_SIGNAL; + if (NotifyFunction == NULL) { + // + // CreatEventEx will check NotifyFunction is NULL or not + // + WorkerNotifyFunction = EventNotifySignalAllNullEvent; + } else { + WorkerNotifyFunction = NotifyFunction; + } + + // + // For UEFI 2.0 and the future use an Event Group + // + Status = gBS->CreateEventEx ( + EventType, + NotifyTpl, + WorkerNotifyFunction, + NotifyContext, + &gEfiEventLegacyBootGuid, + LegacyBootEvent + ); +#endif + return Status; +} + +EFI_STATUS +EFIAPI +EfiCreateEventReadyToBoot ( + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, + IN VOID *NotifyContext, + OUT EFI_EVENT *ReadyToBootEvent + ) +/*++ + +Routine Description: + Create a Read to Boot Event. + + Tiano extended the CreateEvent Type enum to add a ready to boot event type. + This was bad as Tiano did not own the enum. In UEFI 2.0 CreateEventEx was + added and now it's possible to not voilate the UEFI specification and use + the ready to boot event class defined in UEFI 2.0. This library supports + the R8.5/EFI 1.10 form and R8.6/UEFI 2.0 form and allows common code to + work both ways. + +Arguments: + @param LegacyBootEvent Returns the EFI event returned from gBS->CreateEvent(Ex) + +Return: + EFI_SUCCESS - Event was created. + Other - Event was not created. + +--*/ +{ + EFI_STATUS Status; + UINT32 EventType; + EFI_EVENT_NOTIFY WorkerNotifyFunction; + +#if (EFI_SPECIFICATION_VERSION < 0x00020000) + + if (NotifyFunction == NULL) { + EventType = EFI_EVENT_SIGNAL_READY_TO_BOOT | EFI_EVENT_NOTIFY_SIGNAL_ALL; + } else { + EventType = EFI_EVENT_SIGNAL_READY_TO_BOOT; + } + WorkerNotifyFunction = NotifyFunction; + + // + // prior to UEFI 2.0 use Tiano extension to EFI + // + Status = gBS->CreateEvent ( + EventType, + NotifyTpl, + WorkerNotifyFunction, + NotifyContext, + ReadyToBootEvent + ); +#else + + EventType = EFI_EVENT_NOTIFY_SIGNAL; + if (NotifyFunction == NULL) { + // + // CreatEventEx will check NotifyFunction is NULL or not + // + WorkerNotifyFunction = EventNotifySignalAllNullEvent; + } else { + WorkerNotifyFunction = NotifyFunction; + } + + // + // For UEFI 2.0 and the future use an Event Group + // + Status = gBS->CreateEventEx ( + EventType, + NotifyTpl, + WorkerNotifyFunction, + NotifyContext, + &gEfiEventReadyToBootGuid, + ReadyToBootEvent + ); +#endif + return Status; +} diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/GetImage.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/GetImage.c new file mode 100644 index 0000000..20493b3 --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/GetImage.c @@ -0,0 +1,220 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GetImage.c + +Abstract: + + Image data extraction support for common use. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" +#include "EfiImageFormat.h" + +#include EFI_PROTOCOL_CONSUMER (LoadedImage) + +EFI_STATUS +GetImageFromFv ( +#if (PI_SPECIFICATION_VERSION < 0x00010000) //;;## ...AMI_OVERRIDE... Support PI1.x + IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv, +#else + IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv, +#endif + IN EFI_GUID *NameGuid, + IN EFI_SECTION_TYPE SectionType, + OUT VOID **Buffer, + OUT UINTN *Size + ) +{ + EFI_STATUS Status; + EFI_FV_FILETYPE FileType; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINT32 AuthenticationStatus; + + // + // Read desired section content in NameGuid file + // + *Buffer = NULL; + *Size = 0; + Status = Fv->ReadSection ( + Fv, + NameGuid, + SectionType, + 0, + Buffer, + Size, + &AuthenticationStatus + ); + + if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) { + // + // Try reading PE32 section, since the TE section does not exist + // + *Buffer = NULL; + *Size = 0; + Status = Fv->ReadSection ( + Fv, + NameGuid, + EFI_SECTION_PE32, + 0, + Buffer, + Size, + &AuthenticationStatus + ); + } + + if (EFI_ERROR (Status) && + ((SectionType == EFI_SECTION_TE) || (SectionType == EFI_SECTION_PE32))) { + // + // Try reading raw file, since the desired section does not exist + // + *Buffer = NULL; + *Size = 0; + Status = Fv->ReadFile ( + Fv, + NameGuid, + Buffer, + Size, + &FileType, + &Attributes, + &AuthenticationStatus + ); + } + + return Status; +} + +EFI_STATUS +GetImage ( + IN EFI_GUID *NameGuid, + IN EFI_SECTION_TYPE SectionType, + OUT VOID **Buffer, + OUT UINTN *Size + ) +{ + return GetImageEx (NULL, NameGuid, SectionType, Buffer, Size, FALSE); +} + +EFI_STATUS +GetImageEx ( + IN EFI_HANDLE ImageHandle, + IN EFI_GUID *NameGuid, + IN EFI_SECTION_TYPE SectionType, + OUT VOID **Buffer, + OUT UINTN *Size, + BOOLEAN WithinImageFv + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN HandleCount; + UINTN Index; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; +#if (PI_SPECIFICATION_VERSION < 0x00010000) //;;## ...AMI_OVERRIDE... Support PI1.x + EFI_FIRMWARE_VOLUME_PROTOCOL *ImageFv; + EFI_FIRMWARE_VOLUME_PROTOCOL *Fv; +#else + EFI_FIRMWARE_VOLUME2_PROTOCOL *ImageFv; + EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; +#endif + + if (ImageHandle == NULL && WithinImageFv) { + return EFI_INVALID_PARAMETER; + } + + Status = EFI_NOT_FOUND; + ImageFv = NULL; + if (ImageHandle != NULL) { + Status = gBS->HandleProtocol ( + ImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **) &LoadedImage + ); + if (EFI_ERROR (Status)) { + return Status; + } + Status = gBS->HandleProtocol ( + LoadedImage->DeviceHandle, + #if (PI_SPECIFICATION_VERSION < 0x00010000) + &gEfiFirmwareVolumeProtocolGuid, + #else + &gEfiFirmwareVolume2ProtocolGuid, + #endif + (VOID **) &ImageFv + ); + if (!EFI_ERROR (Status)) { + Status = GetImageFromFv (ImageFv, NameGuid, SectionType, Buffer, Size); + } + } + + if (Status == EFI_SUCCESS || WithinImageFv) { + return Status; + } + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + #if (PI_SPECIFICATION_VERSION < 0x00010000) + &gEfiFirmwareVolumeProtocolGuid, + #else + &gEfiFirmwareVolume2ProtocolGuid, + #endif + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Find desired image in all Fvs + // + for (Index = 0; Index < HandleCount; ++Index) { + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + #if (PI_SPECIFICATION_VERSION < 0x00010000) + &gEfiFirmwareVolumeProtocolGuid, + #else + &gEfiFirmwareVolume2ProtocolGuid, + #endif + (VOID**)&Fv + ); + + if (EFI_ERROR (Status)) { + gBS->FreePool(HandleBuffer); + return Status; + } + + if (ImageFv != NULL && Fv == ImageFv) { + continue; + } + + Status = GetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size); + + if (!EFI_ERROR (Status)) { + break; + } + } + gBS->FreePool(HandleBuffer); + + // + // Not found image + // + if (Index == HandleCount) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/Handle.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/Handle.c new file mode 100644 index 0000000..b440a10 --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/Handle.c @@ -0,0 +1,176 @@ +/*++ + +Copyright (c) 2004, 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: + + Handle.c + +Abstract: + + Support for Handle lib fucntions. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" + +EFI_STATUS +EfiLibLocateHandleProtocolByProtocols ( + IN OUT EFI_HANDLE * Handle, OPTIONAL + OUT VOID **Interface, OPTIONAL + ... + ) +/*++ +Routine Description: + + Function locates Protocol and/or Handle on which all Protocols specified + as a variable list are installed. + It supports continued search. The caller must assure that no handles are added + or removed while performing continued search, by e.g., rising the TPL and not + calling any handle routines. Otherwise the behavior is undefined. + +Arguments: + + Handle - The address of handle to receive the handle on which protocols + indicated by the variable list are installed. + If points to NULL, all handles are searched. If pointing to a + handle returned from previous call, searches starting from next handle. + If NULL, the parameter is ignored. + + Interface - The address of a pointer to a protocol interface that will receive + the interface indicated by first variable argument. + If NULL, the parameter is ignored. + + ... - A variable argument list containing protocol GUIDs. Must end with NULL. + +Returns: + + EFI_SUCCESS - All the protocols where found on same handle. + EFI_NOT_FOUND - A Handle with all the protocols installed was not found. + Other values as may be returned from LocateHandleBuffer() or HandleProtocol(). + +--*/ +{ + VA_LIST args; + EFI_STATUS Status; + EFI_GUID *Protocol; + EFI_GUID *ProtocolFirst; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + UINTN Idx; + VOID *AnInterface; + + AnInterface = NULL; + VA_START (args, Interface); + ProtocolFirst = VA_ARG (args, EFI_GUID *); + + // + // Get list of all handles that support the first protocol. + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + ProtocolFirst, + NULL, + &NumberOfHandles, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Check if this is a countinuation of handle searching. + // + Idx = 0; + if ((Handle != NULL) && (*Handle != NULL)) { + // + // Leave the Idx just beyond the matching handle. + // + for (; Idx < NumberOfHandles;) { + if (*Handle == HandleBuffer[Idx++]) { + break; + } + } + } + + // + // Iterate handles testing for presence of remaining protocols. + // + for (; Idx < NumberOfHandles; Idx++) { + + // + // Start with the second protocol, the first one is sure on this handle. + // + VA_START (args, Interface); + VA_ARG (args, EFI_GUID *); + + // + // Iterate protocols from the variable list. + // + while (TRUE) { + + Protocol = VA_ARG (args, EFI_GUID *); + + if (Protocol == NULL) { + + // + // If here, the list was iterated successfully + // finding each protocol on a single handle. + // + + Status = EFI_SUCCESS; + + // + // OPTIONAL parameter returning the Handle. + // + if (Handle != NULL) { + *Handle = HandleBuffer[Idx]; + } + + // + // OPTIONAL parameter returning the first rotocol's Interface. + // + if (Interface != NULL) { + Status = gBS->HandleProtocol ( + HandleBuffer[Idx], + ProtocolFirst, + Interface + ); + } + + goto lbl_out; + } + + Status = gBS->HandleProtocol ( + HandleBuffer[Idx], + Protocol, + &AnInterface + ); + if (EFI_ERROR (Status)) { + + // + // This handle does not have the iterated protocol. + // + break; + } + } + + } + + // + // If here, no handle that bears all the protocols was found. + // + Status = EFI_NOT_FOUND; + +lbl_out: + gBS->FreePool (HandleBuffer); + return Status; +} diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/HobLib.inf b/EDK/Foundation/Library/Dxe/EfiDriverLib/HobLib.inf new file mode 100644 index 0000000..aecf5b7 --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/HobLib.inf @@ -0,0 +1,47 @@ +#/*++ +# +# Copyright (c) 2004, 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: +# +# HobLib.inf +# +# Abstract: +# +# Component description file. +# +#--*/ + +[defines] +BASE_NAME = HobLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + Hob.c + + +[includes.common] + $(EDK_SOURCE)\Foundation + $(EDK_SOURCE)\Foundation\Framework + $(EDK_SOURCE)\Foundation\Efi + . + $(EDK_SOURCE)\Foundation\Include + $(EDK_SOURCE)\Foundation\Efi\Include + $(EDK_SOURCE)\Foundation\Framework\Include + $(EDK_SOURCE)\Foundation\Include\IndustryStandard + $(EDK_SOURCE)\Foundation\Library\Dxe\Include + $(EDK_SOURCE)\Foundation\Core\Dxe + +[libraries.common] + EdkGuidLib + EdkFrameworkGuidLib + +[nmake.common] + C_STD_INCLUDE= diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/IA32/PerformancePrimitives.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/IA32/PerformancePrimitives.c new file mode 100644 index 0000000..d3a437c --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/IA32/PerformancePrimitives.c @@ -0,0 +1,47 @@ +/*++ + +Copyright (c) 2004, 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: + + PerformancePrimitives.c + +Abstract: + + Support for Performance library + +--*/ + +#include "TianoCommon.h" +#include "CpuIA32.h" + +EFI_STATUS +GetTimerValue ( + OUT UINT64 *TimerValue + ) +/*++ + +Routine Description: + + Set TimerValue with current tick. + +Arguments: + + TimerValue - Timer value to be set + +Returns: + + EFI_SUCCESS - TimerValue is set. + +--*/ +{ + *TimerValue = EfiReadTsc (); + return EFI_SUCCESS; +} diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/Ipf/PerformancePrimitives.s b/EDK/Foundation/Library/Dxe/EfiDriverLib/Ipf/PerformancePrimitives.s new file mode 100644 index 0000000..5aeb886 --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/Ipf/PerformancePrimitives.s @@ -0,0 +1,61 @@ +//++ +// Copyright (c) 2004, 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: +// +// PerformancePrimitives.s +// +// Abstract: +// +// +// Revision History: +// +//-- + +.file "PerformancePrimitives.s" + +#include "IpfMacro.i" + +//----------------------------------------------------------------------------- +//++ +// GetTimerValue +// +// Implementation of CPU-based time service +// +// On Entry : +// EFI_STATUS +// GetTimerValue ( +// OUT UINT64 *TimerValue +// ) +// +// Return Value: +// r8 = Status +// r9 = 0 +// r10 = 0 +// r11 = 0 +// +// As per static calling conventions. +// +//-- +//--------------------------------------------------------------------------- +PROCEDURE_ENTRY (GetTimerValue) + + NESTED_SETUP (1,8,0,0) + mov r8 = ar.itc;; + st8 [r32]= r8 + mov r8 = r0 + mov r9 = r0 + mov r10 = r0 + mov r11 = r0 + NESTED_RETURN + +PROCEDURE_EXIT (GetTimerValue) +//--------------------------------------------------------------------------- + diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/LibGlobalDs.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/LibGlobalDs.c new file mode 100644 index 0000000..2edd766 --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/LibGlobalDs.c @@ -0,0 +1,32 @@ +/*++ + +Copyright (c) 2004, 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: + + LibGlobalDs.c + +Abstract: + + Globals used in EFI Driver Lib. They are initialized in EfiDriverLib.c. + Each seperatly linked module has it's own copy of these globals. + + gBS - Boot Services table pointer + gRT - Runt Time services table pointer + gST - System Table pointer + + gErrorLevel - Debug error level. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" + +EFI_DXE_SERVICES *gDS = NULL; diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/LibGlobalErrorLevel.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/LibGlobalErrorLevel.c new file mode 100644 index 0000000..82bea32 --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/LibGlobalErrorLevel.c @@ -0,0 +1,34 @@ +/*++ + +Copyright (c) 2004, 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: + + LibGlobalErrorLevel.c + +Abstract: + + Globals used in EFI Driver Lib. They are initialized in EfiDriverLib.c. + Each seperatly linked module has it's own copy of these globals. + + gBS - Boot Services table pointer + gRT - Runt Time services table pointer + gST - System Table pointer + + gErrorLevel - Debug error level. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" +#include EFI_GUID_DEFINITION (StatusCodeCallerId) +#include EFI_GUID_DEFINITION (StatusCodeDataTypeId) + +UINTN gErrorLevel = EFI_DBUG_MASK | EFI_D_LOAD | EFI_D_INFO; //;;## ...AMI_OVERRIDE... Aptio not support gEfiDebugMaskPpiGuid. diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/LibGlobalSt.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/LibGlobalSt.c new file mode 100644 index 0000000..cd866ba --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/LibGlobalSt.c @@ -0,0 +1,34 @@ +/*++ + +Copyright (c) 2004, 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: + + LibGlobalSt.c + +Abstract: + + Globals used in EFI Driver Lib. They are initialized in EfiDriverLib.c. + Each seperatly linked module has it's own copy of these globals. + + gBS - Boot Services table pointer + gRT - Runt Time services table pointer + gST - System Table pointer + + gErrorLevel - Debug error level. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" + +EFI_SYSTEM_TABLE *gST = NULL; +EFI_BOOT_SERVICES *gBS = NULL; +EFI_RUNTIME_SERVICES *gRT = NULL; diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/Lock.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/Lock.c new file mode 100644 index 0000000..f9d1006 --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/Lock.c @@ -0,0 +1,159 @@ +/*++ + +Copyright (c) 2004, 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: + + Lock.c + +Abstract: + + Support for locking lib services. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" + +VOID +EfiInitializeLock ( + IN OUT EFI_LOCK *Lock, + IN EFI_TPL Priority + ) +/*++ + +Routine Description: + + Initialize a basic mutual exclusion lock. Each lock + provides mutual exclusion access at it's task priority + level. Since there is no-premption (at any TPL) or + multiprocessor support, acquiring the lock only consists + of raising to the locks TPL. + + Note on a check build ASSERT()s are used to ensure proper + lock usage. + +Arguments: + + Lock - The EFI_LOCK structure to initialize + + Priority - The task priority level of the lock + + +Returns: + + An initialized Efi Lock structure. + +--*/ +{ + Lock->Tpl = Priority; + Lock->OwnerTpl = 0; + Lock->Lock = 0; +} + +EFI_STATUS +EfiAcquireLockOrFail ( + IN EFI_LOCK *Lock + ) +/*++ + +Routine Description: + + Initialize a basic mutual exclusion lock. Each lock + provides mutual exclusion access at it's task priority + level. Since there is no-premption (at any TPL) or + multiprocessor support, acquiring the lock only consists + of raising to the locks TPL. + +Arguments: + + Lock - The EFI_LOCK structure to initialize + +Returns: + + EFI_SUCCESS - Lock Owned. + EFI_ACCESS_DENIED - Reentrant Lock Acquisition, Lock not Owned. + +--*/ +{ + if (Lock->Lock != 0) { + // + // Lock is already owned, so bail out + // + return EFI_ACCESS_DENIED; + } + + Lock->OwnerTpl = gBS->RaiseTPL (Lock->Tpl); + + Lock->Lock += 1; + return EFI_SUCCESS; +} + +VOID +EfiAcquireLock ( + IN EFI_LOCK *Lock + ) +/*++ + +Routine Description: + + Raising to the task priority level of the mutual exclusion + lock, and then acquires ownership of the lock. + +Arguments: + + Lock - The lock to acquire + +Returns: + + Lock owned + +--*/ +{ + EFI_STATUS Status; + + Status = EfiAcquireLockOrFail (Lock); + + // + // Lock was already locked. + // + ASSERT_EFI_ERROR (Status); +} + +VOID +EfiReleaseLock ( + IN EFI_LOCK *Lock + ) +/*++ + +Routine Description: + + Releases ownership of the mutual exclusion lock, and + restores the previous task priority level. + +Arguments: + + Lock - The lock to release + +Returns: + + Lock unowned + +--*/ +{ + EFI_TPL Tpl; + + Tpl = Lock->OwnerTpl; + + ASSERT (Lock->Lock == 1); + Lock->Lock -= 1; + + gBS->RestoreTPL (Tpl); +} diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/Perf.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/Perf.c new file mode 100644 index 0000000..9bed854 --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/Perf.c @@ -0,0 +1,946 @@ +/*++ + +Copyright (c) 2004 - 2012, 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: + + Perf.c + +Abstract: + + Support library for DXE Firmware Performance logging. + +--*/ + +#include "Tiano.h" + +#include EFI_PROTOCOL_DEFINITION (FirmwarePerformance) +#include EFI_GUID_DEFINITION (PeiPerformanceHob) +#include EFI_PROTOCOL_DEFINITION (LoadedImage) +#include EFI_PROTOCOL_DEFINITION (DriverBinding) +#include EFI_GUID_DEFINITION (Hob) + +#include "EfiDriverLib.h" +#include "EfiHobLib.h" +#include "EfiImage.h" +#include "EfiCommonLib.h" +#include "CpuIA32.h" + +EFI_GUID gNullGuid = EFI_NULL_GUID; +FIRMWARE_PERFORMANCE_PROTOCOL *FirmwarePerformance; + +static UINT32 *mPerformancePointer; +static UINT32 mPerformanceLength; +UINT16 BdsAttemptNumber = 0; + +#define LOCAL_APIC_BASE 0xfee00000 +#define APIC_ID_REGISTER 0x20 +#define MSR_EXT_XAPIC_LOGICAL_APIC_ID 0x802 +#define MSR_XAPIC_BASE 0x1B +#define MSR_XAPIC_BASE_MASK 0x0c00 +#define MAX_NON_TURBO_RATIO_OFFSET 8 +#define MAX_NON_TURBO_RATIO_MASK 0xff +#define PLATFORM_INFO_MSR 0xce + +EFI_STATUS +GetTimerValue ( + OUT UINT64 *TimerValue + ); + +EFI_STATUS +GetPeiFirmwarePerformanceHob ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +UINT64 GetTimeInNanoSec ( + UINT64 Ticker + ) +/*++ + +Routine Description: + + Internal routine to convert TSC value into nano second value + +Arguments: + + Ticker - OPTIONAL. TSC value supplied by caller function + +Returns: + + UINT64 - returns calculated timer value + +--*/ +{ + UINT64 Tick, pi; + UINT8 Ratio; + + if(Ticker != 0){ + Tick = Ticker; + } else { + GetTimerValue (&Tick); + } + + pi = EfiReadMsr(PLATFORM_INFO_MSR); + Ratio = (UINT8)( ((UINT32)(UINTN)RShiftU64(pi, MAX_NON_TURBO_RATIO_OFFSET)) & MAX_NON_TURBO_RATIO_MASK); + + return (UINT64)DivU64x32((UINT64)MultU64x32(Tick, 10), (UINTN)(Ratio), NULL); +} + +UINT32 GetApicId ( + VOID + ) +/*++ + +Routine Description: + + Internal routine to retrieve current APIC Id + +Arguments: + + None + +Returns: + + UINT32 - returns Apic Id value + +--*/ +{ + BOOLEAN x2ApicEnabled; + UINT32 ApicId; + + x2ApicEnabled = (BOOLEAN)(((EfiReadMsr (MSR_XAPIC_BASE)) & (MSR_XAPIC_BASE_MASK)) == MSR_XAPIC_BASE_MASK); + if (x2ApicEnabled) { + ApicId = (UINT32) EfiReadMsr (MSR_EXT_XAPIC_LOGICAL_APIC_ID); + } else { + ApicId = (UINT8) (*(volatile UINT32 *) (UINTN) (LOCAL_APIC_BASE + APIC_ID_REGISTER) >> 24); + } + + return ApicId; +} + +STATIC +VOID +GetShortPdbFileName ( + CHAR8 *PdbFileName, + CHAR8 *GaugeString + ) +/*++ + +Routine Description: + + Shotens PDB path name + +Arguments: + + PdbFileName - PdbFileName + +Returns: + GaugeString - GaugeString + +--*/ +{ + UINTN Index; + UINTN Index1; + UINTN StartIndex; + UINTN EndIndex; + + if (PdbFileName == NULL) { + EfiAsciiStrCpy (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 == STRING_EVENT_RECORD_NAME_LENGTH - 1) { + break; + } + } + + GaugeString[Index1] = 0; + } + + return ; +} + +STATIC +CHAR8 * +GetPdbPath ( + VOID *ImageBase + ) +/*++ + +Routine Description: + + Locate 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. + +--*/ +{ + CHAR8 *PdbPath; + UINT32 DirCount; + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_NT_HEADERS *NtHdr; + UINT16 Magic; + EFI_IMAGE_OPTIONAL_HEADER32 *OptionalHdr32; + EFI_IMAGE_OPTIONAL_HEADER64 *OptionalHdr64; + EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; + EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; + VOID *CodeViewEntryPointer; + + CodeViewEntryPointer = NULL; + PdbPath = NULL; + DosHdr = ImageBase; + if (DosHdr && DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + NtHdr = (EFI_IMAGE_NT_HEADERS *) ((UINT8 *) DosHdr + DosHdr->e_lfanew); + // + // NOTE: We use Machine to identify PE32/PE32+, instead of Magic. + // It is for backward-compatibility consideration, because + // some system will generate PE32+ image with PE32 Magic. + // + if (NtHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) { + Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; + } else if (NtHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) { + Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; + } else if (NtHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) { + Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; + } else { + Magic = NtHdr->OptionalHeader.Magic; + } + if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + OptionalHdr32 = (VOID *) &NtHdr->OptionalHeader; + DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHdr32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); + } else { + OptionalHdr64 = (VOID *) &NtHdr->OptionalHeader; + DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHdr64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); + } + + if (DirectoryEntry->VirtualAddress != 0) { + for (DirCount = 0; + (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && CodeViewEntryPointer == NULL; + DirCount++ + ) { + DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (DirectoryEntry->VirtualAddress + (UINTN) ImageBase + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)); + if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { + CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageBase); + switch (*(UINT32 *) CodeViewEntryPointer) { + case CODEVIEW_SIGNATURE_NB10: + PdbPath = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY); + break; + + case CODEVIEW_SIGNATURE_RSDS: + PdbPath = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY); + break; + + default: + break; + } + } + } + } + } + + return PdbPath; +} + +STATIC +VOID +GetNameFromHandle ( + IN EFI_HANDLE Handle, + OUT CHAR8 *GaugeString + ) +/*++ + +Routine Description: + + retrieves PDB path name from Handle + +Arguments: + + Handle - Handle of image + +Returns: + + Pointer to PDB Filename +--*/ +{ + EFI_STATUS Status; + EFI_LOADED_IMAGE_PROTOCOL *Image; + CHAR8 *PdbFileName; + EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; + + EfiAsciiStrCpy (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 ; +} + +EFI_GUID * +GetGuidFromHandle ( + EFI_HANDLE Handle + ) +/*++ + +Routine Description: + + retrieves GUID name from Handle + +Arguments: + + Handle - Handle of image + +Returns: + + Pointer to GUID name +--*/ +{ + EFI_STATUS Status; + EFI_LOADED_IMAGE_PROTOCOL *pImage; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath; + + if (Handle!=NULL){ + Status = gBS->HandleProtocol(Handle, + &gEfiLoadedImageProtocolGuid, + &pImage + ); + if (!EFI_ERROR(Status)){ + if (pImage->FilePath->Type==MEDIA_DEVICE_PATH && pImage->FilePath->SubType==MEDIA_FV_FILEPATH_DP) { + // + // Determine GUID associated with module logging performance + // + FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)pImage->FilePath; + + return &FvFilePath->NameGuid; + } + } + } + + return NULL; +} + +EFI_STATUS +LocatePerformanceProtocol( + VOID + ) +/*++ + +Routine Description: + + locates Performance protocol interface + +Arguments: + + None + +Returns: + EFI_STATUS + +--*/ +{ + EFI_STATUS Status; + + FirmwarePerformance = NULL; + Status = gBS->LocateProtocol (&gFirmwarePerformanceProtocolGuid, NULL, (VOID **) &FirmwarePerformance); + + return Status; +} + +EFI_STATUS +EFIAPI +InsertMeasurement ( + IN FIRMWARE_PERFORMANCE_PROTOCOL *This, + IN EFI_HANDLE Handle, + IN UINT16 RecordType, + IN UINT64 Ticker, + IN UINT16 Identifier OPTIONAL + ) +/*++ + +Routine Description: + + Logs performance data according to Record Type into pre-allocated buffer + +Arguments: + + This - Calling context + Handle - Handle of gauge data + RecordType - Type of FPDT record + Ticker - Set event's Tick. If 0, Tick is current timer. + Identifier - Identifier of event records and other types of records + +Returns: + + EFI_SUCCESS - Successfully create and initialized a guage data node. + EFI_OUT_OF_RESOURCES - No enough resource to create a guage data node. + +--*/ +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + HARDWARE_BOOT_REC *HardwareBootRec; + STRING_EVENT_REC *StringEvent; + GUID_EVENT_REC *GuidEvent; + BDS_ATTEMPT_REC *BdsAttemptRec; + EFI_GUID *GuidName; + + UINT8 PdbFileName[STRING_EVENT_RECORD_NAME_LENGTH] = {0}; + UINT8 NullFileName[STRING_EVENT_RECORD_NAME_LENGTH] = {0}; + DevicePath = NULL; + + // + // buffer overflow check + // + if (mPerformanceLength + sizeof(STRING_EVENT_REC) > FIRMWARE_MAX_BUFFER) { + return EFI_OUT_OF_RESOURCES; + } + + switch (RecordType) { + case HARDWARE_BOOT_TYPE: + // + // Hardware Boot Record Table + // + HardwareBootRec = (HARDWARE_BOOT_REC*) ((UINT8*)mPerformancePointer + mPerformanceLength); + + HardwareBootRec->RecType = RecordType; + HardwareBootRec->RecLength = sizeof(HARDWARE_BOOT_REC); + HardwareBootRec->Revision = RECORD_REVISION_1; + HardwareBootRec->HardwareBoot = GetTimeInNanoSec(Ticker); + + mPerformanceLength += sizeof(HARDWARE_BOOT_REC); + break; + + case GUID_EVENT_REC_TYPE: + case STRING_EVENT_REC_TYPE: + // + // Determine Pdb FileName associated with module logging performance + // + if (Handle != NULL){ + GetNameFromHandle (Handle, PdbFileName); + } + + GuidName = GetGuidFromHandle(Handle); + if (EfiCompareMem (PdbFileName,NullFileName, STRING_EVENT_RECORD_NAME_LENGTH)){ + // + // String Event Record + // + StringEvent = (STRING_EVENT_REC*) ((UINT8*)mPerformancePointer + mPerformanceLength); + StringEvent->RecType = STRING_EVENT_REC_TYPE; + StringEvent->RecLength = sizeof(STRING_EVENT_REC); + StringEvent->Revision = RECORD_REVISION_1; + StringEvent->ProgressID = Identifier; + StringEvent->ApicID = GetApicId(); + StringEvent->Timestamp = GetTimeInNanoSec(Ticker); + if (GuidName != NULL) { + gBS->CopyMem(&(StringEvent->Guid),GuidName,sizeof(EFI_GUID)); + } + + (gBS->CopyMem) (StringEvent->NameString, PdbFileName, STRING_EVENT_RECORD_NAME_LENGTH); + + mPerformanceLength += sizeof(STRING_EVENT_REC); + + } else { + // + // GUID Event Record + // + GuidEvent = (GUID_EVENT_REC*) ((UINT8*)mPerformancePointer + mPerformanceLength); + GuidEvent->RecType = GUID_EVENT_REC_TYPE; + GuidEvent->RecLength = sizeof(GUID_EVENT_REC); + GuidEvent->Revision = RECORD_REVISION_1; + GuidEvent->ProgressID = Identifier; + GuidEvent->ApicID = GetApicId(); + GuidEvent->Timestamp = GetTimeInNanoSec(Ticker); + if (GuidName != NULL) { + gBS->CopyMem(&(GuidEvent->Guid),GuidName,sizeof(EFI_GUID)); + } + + mPerformanceLength += sizeof(GUID_EVENT_REC); + } + break; + + case BDS_ATTEMPT_EVENT_REC_TYPE: + // + // BDS Boot Attempt Record + // + DevicePath = EfiDevicePathFromHandle (Handle); + + BdsAttemptRec = (BDS_ATTEMPT_REC*) ((UINT8*)mPerformancePointer + mPerformanceLength); + BdsAttemptRec->RecType = BDS_ATTEMPT_EVENT_REC_TYPE; + BdsAttemptRec->RecLength = sizeof(BDS_ATTEMPT_REC); + BdsAttemptRec->Revision = RECORD_REVISION_1; + BdsAttemptRec->ApicID = GetApicId(); + BdsAttemptRec->BdsAttemptNo = BdsAttemptNumber + 1; + BdsAttemptRec->Timestamp = GetTimeInNanoSec(Ticker); + ASPrint ((CHAR8*)(&BdsAttemptRec->UEFIBootVar), sizeof(BdsAttemptRec->UEFIBootVar)+1, "BOOT%04x", Identifier); + BdsAttemptRec->DevicePathString = '0'; + mPerformanceLength += sizeof(BDS_ATTEMPT_REC); + break; + + default: + // + // Record is undefined, return EFI_ABORTED + // + return EFI_ABORTED; + break; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +GetPerfBufferAddr ( + IN FIRMWARE_PERFORMANCE_PROTOCOL *This, + OUT UINT32 *PerformanceBuffer + ) +{ + EFI_STATUS Status; + + *PerformanceBuffer = 0; + + Status = LocatePerformanceProtocol(); + if(EFI_ERROR(Status)) { + return EFI_NOT_FOUND; + } + + if (mPerformancePointer == NULL) { + return EFI_NOT_FOUND; + } + + *PerformanceBuffer = (UINT32)((UINTN)mPerformancePointer); + + return Status; +} + + +UINT32 +GetPerfBufferLength ( + IN FIRMWARE_PERFORMANCE_PROTOCOL *This + ) +{ + EFI_STATUS Status; + + Status = LocatePerformanceProtocol(); + if(EFI_ERROR(Status)) { + return 0; + } + + return mPerformanceLength; +} + +FIRMWARE_PERFORMANCE_PROTOCOL FirmwarePerformanceProtocol = { + InsertMeasurement, + GetPerfBufferAddr, + GetPerfBufferLength +}; + +// +// Driver entry point +// +EFI_STATUS +InitializePerformanceInfrastructure ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable, + IN UINT64 Ticker + ) +/*++ + +Routine Description: + + Install gFirmwarePerformanceProtocolGuid protocol and transfer PEI performance to gauge data nodes. + +Arguments: + + ImageHandle - Standard driver entry point parameter + SystemTable - Standard driver entry point parameter + Ticker - End tick for PEI performance + +Returns: + + EFI_OUT_OF_RESOURCES - No enough buffer to allocate + EFI_SUCCESS - Protocol installed. + +--*/ +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + // + //A buffer of MAX size + // + mPerformancePointer = EfiLibAllocateZeroPool (FIRMWARE_MAX_BUFFER); + if (mPerformancePointer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + mPerformanceLength = 0; + // + // Install the protocol interfaces + // + Status = gBS->InstallProtocolInterface ( + &ImageHandle, + &gFirmwarePerformanceProtocolGuid, + EFI_NATIVE_INTERFACE, + &FirmwarePerformanceProtocol + ); + if (!EFI_ERROR (Status)) { + // + // Get PEI performance hob and convert into FPDT structure + // + GetPeiFirmwarePerformanceHob (ImageHandle, SystemTable); + } + + return EFI_SUCCESS; +} + + +EFI_STATUS +StartMeasure ( + EFI_HANDLE Handle, + IN UINT16 *Token, + IN UINT16 *Host, + IN UINT64 Ticker + ) +/*++ + +Routine Description: + + Start measurement according to token field and insert into pre-allocated buffer + +Arguments: + + Handle - Handle to measure + Token - Token to measure + Host - Host to measure + Ticker - Ticker as start tick + +Returns: + + Status code. + +--*/ +{ + EFI_STATUS Status; + UINT16 RecordType; + UINT16 Identifier; + + Status = LocatePerformanceProtocol(); + if(EFI_ERROR(Status)) { + return Status; + } + + if (!EfiStrCmp (Token, START_IMAGE_TOK)) { + RecordType = STRING_EVENT_REC_TYPE; + Identifier = MODULE_START_ID; + } else if (!EfiStrCmp (Token, LOAD_IMAGE_TOK)) { + RecordType = STRING_EVENT_REC_TYPE; + Identifier = MODULE_LOADIMAGE_START_ID; + } else if (!EfiStrCmp (Token, DRIVERBINDING_START_TOK)) { + RecordType = STRING_EVENT_REC_TYPE; + Identifier = MODULE_DRIVERBINDING_START_ID; + } else if (!EfiStrCmp (Token, DXE_TOK)) { + RecordType = STRING_EVENT_REC_TYPE; + Identifier = DXE_START_ID; + } else if (!EfiStrCmp (Token, DXE_CORE_DISP_INIT_TOK)) { + RecordType = STRING_EVENT_REC_TYPE; + Identifier = DXE_CORE_DISP_START_ID; + } else if (!EfiStrCmp (Token, COREDISPATCHER_TOK)) { + RecordType = STRING_EVENT_REC_TYPE; + Identifier = COREDISPATCHER_START_ID; + } else { + RecordType = PERFORMANCE_RECORD_TYPE_MAX; + Identifier = 0; + } + + Status = FirmwarePerformance->InsertMeasurement (FirmwarePerformance, Handle, RecordType, Ticker, Identifier); + + return Status; +} + +EFI_STATUS +EndMeasure ( + EFI_HANDLE Handle, + IN UINT16 *Token, + IN UINT16 *Host, + IN UINT64 Ticker + ) +/*++ + +Routine Description: + + End measurement according to token field and insert into pre-allocated buffer + +Arguments: + + Handle - Handle to stop + Token - Token to stop + Host - Host to stop + Ticker - Ticker as end tick + +Returns: + + Status code. + +--*/ +{ + EFI_STATUS Status; + UINT16 RecordType; + UINT16 Identifier; + + Status = LocatePerformanceProtocol(); + if(EFI_ERROR(Status)) { + return Status; + } + + if (!EfiStrCmp (Token, START_IMAGE_TOK)) { + RecordType = STRING_EVENT_REC_TYPE; + Identifier = MODULE_END_ID; + } else if (!EfiStrCmp (Token, LOAD_IMAGE_TOK)) { + RecordType = STRING_EVENT_REC_TYPE; + Identifier = MODULE_LOADIMAGE_END_ID; + } else if (!EfiStrCmp (Token, DRIVERBINDING_START_TOK)) { + RecordType = STRING_EVENT_REC_TYPE; + Identifier = MODULE_DRIVERBINDING_END_ID; + } else if (!EfiStrCmp (Token, DXE_TOK)) { + RecordType = STRING_EVENT_REC_TYPE; + Identifier = DXE_END_ID; + } else if (!EfiStrCmp (Token, DXE_CORE_DISP_INIT_TOK)) { + RecordType = STRING_EVENT_REC_TYPE; + Identifier = DXE_CORE_DISP_END_ID; + } else if (!EfiStrCmp (Token, COREDISPATCHER_TOK)) { + RecordType = STRING_EVENT_REC_TYPE; + Identifier = COREDISPATCHER_END_ID; + } else { + RecordType = PERFORMANCE_RECORD_TYPE_MAX; + Identifier = 0; + } + + Status = FirmwarePerformance->InsertMeasurement (FirmwarePerformance, Handle, RecordType, Ticker, Identifier); + + return Status; +} + +EFI_STATUS +StartMeasureEx ( + IN EFI_HANDLE Handle, + IN UINT16 *Token, + IN UINT16 *Host, + IN UINT64 Ticker, + IN UINT16 Identifier + ) +/*++ + +Routine Description: + + Start extended measurement according to token field and insert into pre-allocated buffer + +Arguments: + + Handle - Handle to stop + Token - Token to stop + Host - Host to stop + Ticker - Ticker as end tick + Identifier - Identifier for a given record +Returns: + + Status code. + +--*/ +{ + EFI_STATUS Status; + UINT16 RecordType; + + Status = LocatePerformanceProtocol(); + if(EFI_ERROR(Status)) { + return Status; + } + + if (!EfiStrCmp (Token, EVENT_REC_TOK)) { + RecordType = STRING_EVENT_REC_TYPE; + } else if (!EfiStrCmp (Token, BDS_ATTEMPT_TOK)) { + RecordType = BDS_ATTEMPT_EVENT_REC_TYPE; + } else if (!EfiStrCmp (Token, HARDWARE_BOOT_TOK)) { + RecordType = HARDWARE_BOOT_TYPE; + } else { + RecordType = PERFORMANCE_RECORD_TYPE_MAX; + } + Status = FirmwarePerformance->InsertMeasurement (FirmwarePerformance, Handle, RecordType, Ticker, Identifier); + + return Status; +} + +EFI_STATUS +EndMeasureEx ( + IN EFI_HANDLE Handle, + IN UINT16 *Token, + IN UINT16 *Host, + IN UINT64 Ticker, + IN UINT16 Identifier + ) +/*++ + +Routine Description: + + End extended measurement according to token field and insert into pre-allocated buffer + +Arguments: + + Handle - Handle to stop + Token - Token to stop + Host - Host to stop + Ticker - Ticker as end tick + Identifier - Identifier for a given record +Returns: + + Status code. + +--*/ +{ + EFI_STATUS Status; + UINT16 RecordType; + + Status = LocatePerformanceProtocol(); + if(EFI_ERROR(Status)) { + return Status; + } + + if (!EfiStrCmp (Token, EVENT_REC_TOK)) { + RecordType = STRING_EVENT_REC_TYPE; + } else if (!EfiStrCmp (Token, BDS_ATTEMPT_TOK)) { + RecordType = BDS_ATTEMPT_EVENT_REC_TYPE; + } else if (!EfiStrCmp (Token, HARDWARE_BOOT_TOK)) { + RecordType = HARDWARE_BOOT_TYPE; + } else { + RecordType = PERFORMANCE_RECORD_TYPE_MAX; + } + + Status = FirmwarePerformance->InsertMeasurement (FirmwarePerformance, Handle, RecordType, Ticker, Identifier); + + return Status; +} + +EFI_STATUS +GetPeiFirmwarePerformanceHob ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + + Transfer PEI performance data to pre-allocated memory into FPDT format. + +Arguments: + + ImageHandle - Standard entry point parameter + SystemTable - Standard entry point parameter + +Returns: + + EFI_OUT_OF_RESOURCES - No enough resource to create data node. + EFI_SUCCESS - Transfer done successfully. + +--*/ +{ + EFI_STATUS Status; + UINT32 Index; + VOID *HobList; + PEI_FIRMWARE_PERFORMANCE_HOB *PeiFirmwarePerformanceHob; + PEI_GUID_EVENT_REC *PeiGuidRec; + GUID_EVENT_REC *GuidEvent; + + // + // Locate installed Performance HOB + // + PeiFirmwarePerformanceHob = NULL; + + EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, &HobList); + + do { + Status = GetNextGuidHob (&HobList, &gPeiFirmwarePerformanceGuid, (VOID **) &PeiFirmwarePerformanceHob, NULL); + if (EFI_ERROR (Status) || (PeiFirmwarePerformanceHob == NULL)) { + break; + } + + for (Index = 0; Index < PeiFirmwarePerformanceHob->NumberOfEntries; Index++) { + PeiGuidRec = &(PeiFirmwarePerformanceHob->GuidEventRecord[Index]); + // + // GUID Event Records from PEI phase + // + GuidEvent = (GUID_EVENT_REC*)((UINT8*)mPerformancePointer + mPerformanceLength); + GuidEvent->RecType = GUID_EVENT_REC_TYPE; + GuidEvent->RecLength = sizeof(GUID_EVENT_REC); + GuidEvent->Revision = RECORD_REVISION_1; + GuidEvent->ProgressID = PeiGuidRec->ProgressID; + GuidEvent->ApicID = PeiGuidRec->ApicID; + GuidEvent->Timestamp = PeiGuidRec->Timestamp; + GuidEvent->Guid = PeiGuidRec->Guid; + + mPerformanceLength += sizeof(GUID_EVENT_REC); + } + } while (!EFI_ERROR (Status)); + + return Status; +}
\ No newline at end of file diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/ReportStatusCode.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/ReportStatusCode.c new file mode 100644 index 0000000..31da17b --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/ReportStatusCode.c @@ -0,0 +1,130 @@ +/*++ + +Copyright (c) 2004 - 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: + + ReportStatusCode.c + +Abstract: + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" +#include EFI_PROTOCOL_DEFINITION (DevicePath) +#include EFI_GUID_DEFINITION (StatusCodeDataTypeId) +#include EFI_ARCH_PROTOCOL_DEFINITION (StatusCode) + +#if (EFI_SPECIFICATION_VERSION >= 0x00020000) +STATIC EFI_STATUS_CODE_PROTOCOL *gStatusCode = NULL; +#endif + +EFI_STATUS +EfiLibReportStatusCode ( + IN EFI_STATUS_CODE_TYPE Type, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN EFI_GUID *CallerId OPTIONAL, + IN EFI_STATUS_CODE_DATA *Data OPTIONAL + ) +/*++ + +Routine Description: + + Report device path through status code. + +Arguments: + + Type - Code type + Value - Code value + Instance - Instance number + CallerId - Caller name + DevicePath - Device path that to be reported + +Returns: + + Status code. + + EFI_OUT_OF_RESOURCES - No enough buffer could be allocated + +--*/ +{ + EFI_STATUS Status; + +#if (EFI_SPECIFICATION_VERSION >= 0x00020000) + if (gStatusCode == NULL) { + if (gBS == NULL) { + return EFI_UNSUPPORTED; + } + Status = gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL, (VOID **)&gStatusCode); + if (EFI_ERROR (Status) || gStatusCode == NULL) { + return EFI_UNSUPPORTED; + } + } + Status = gStatusCode->ReportStatusCode (Type, Value, Instance, CallerId, Data); + return Status; +#else + Status = gRT->ReportStatusCode (Type, Value, Instance, CallerId, Data); + return Status; +#endif +} + +EFI_STATUS +ReportStatusCodeWithDevicePath ( + IN EFI_STATUS_CODE_TYPE Type, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN EFI_GUID * CallerId OPTIONAL, + IN EFI_DEVICE_PATH_PROTOCOL * DevicePath + ) +/*++ + +Routine Description: + + Report device path through status code. + +Arguments: + + Type - Code type + Value - Code value + Instance - Instance number + CallerId - Caller name + DevicePath - Device path that to be reported + +Returns: + + Status code. + + EFI_OUT_OF_RESOURCES - No enough buffer could be allocated + +--*/ +{ + UINT16 Size; + UINT16 DevicePathSize; + EFI_STATUS_CODE_DATA *ExtendedData; + EFI_DEVICE_PATH_PROTOCOL *ExtendedDevicePath; + EFI_STATUS Status; + + DevicePathSize = (UINT16) EfiDevicePathSize (DevicePath); + Size = DevicePathSize + sizeof (EFI_STATUS_CODE_DATA); + ExtendedData = (EFI_STATUS_CODE_DATA *) EfiLibAllocatePool (Size); + if (ExtendedData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ExtendedDevicePath = EfiConstructStatusCodeData (Size, &gEfiStatusCodeSpecificDataGuid, ExtendedData); + EfiCopyMem (ExtendedDevicePath, DevicePath, DevicePathSize); + + Status = EfiLibReportStatusCode (Type, Value, Instance, CallerId, (EFI_STATUS_CODE_DATA *) ExtendedData); + + gBS->FreePool (ExtendedData); + return Status; +} diff --git a/EDK/Foundation/Library/Dxe/EfiDriverLib/x64/PerformancePrimitives.c b/EDK/Foundation/Library/Dxe/EfiDriverLib/x64/PerformancePrimitives.c new file mode 100644 index 0000000..b8b5f8b --- /dev/null +++ b/EDK/Foundation/Library/Dxe/EfiDriverLib/x64/PerformancePrimitives.c @@ -0,0 +1,47 @@ +/*++ + +Copyright (c) 2005, 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: + + PerformancePrimitives.c + +Abstract: + + Support for Performance library + +--*/ + +#include "TianoCommon.h" +#include "CpuIA32.h" + +EFI_STATUS +GetTimerValue ( + OUT UINT64 *TimerValue + ) +/*++ + +Routine Description: + + Set TimerValue with current tick. + +Arguments: + + TimerValue - Timer value to be set + +Returns: + + EFI_SUCCESS - TimerValue is set. + +--*/ +{ + *TimerValue = EfiReadTsc (); + return EFI_SUCCESS; +} |