summaryrefslogtreecommitdiff
path: root/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib
diff options
context:
space:
mode:
authorqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>2007-06-28 07:00:39 +0000
committerqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>2007-06-28 07:00:39 +0000
commit3eb9473ea9a949badfe06ae61d2d3fcfa53651c7 (patch)
treee9d8c368dbb1e58794b2c00acefe4bbad270f8c4 /EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib
parent30d4a0c7ec19938196b1308006b990e0945150da (diff)
downloadedk2-platforms-3eb9473ea9a949badfe06ae61d2d3fcfa53651c7.tar.xz
Add in the 1st version of ECP.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2832 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib')
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Debug.c172
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/DevicePath.c607
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/DxeDriverLib.c56
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Ebc/PerformancePrimitives.c52
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.c429
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.inf88
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiDriverModelLib.c289
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiGetConfigTable.c61
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiLibAllocate.c233
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Event.c371
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/GetImage.c220
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Handle.c176
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Ipf/PerformancePrimitives.s61
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/LibGlobalDs.c32
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/LibGlobalErrorLevel.c34
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/LibGlobalSt.c34
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Lock.c159
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Perf.c861
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/ReportStatusCode.c141
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/ia32/PerformancePrimitives.c47
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/x64/PerformancePrimitives.c47
21 files changed, 4170 insertions, 0 deletions
diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Debug.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Debug.c
new file mode 100644
index 0000000000..a968f407b7
--- /dev/null
+++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Debug.c
@@ -0,0 +1,172 @@
+/*++
+
+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);
+
+ EfiLibReportStatusCode (
+ EFI_DEBUG_CODE,
+ (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_DC_UNSPECIFIED),
+ (UINT32) ErrorLevel,
+ &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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/DevicePath.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/DevicePath.c
new file mode 100644
index 0000000000..1a827c1935
--- /dev/null
+++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/DevicePath.c
@@ -0,0 +1,607 @@
+/*++
+
+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:
+
+ 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.
+
+ Tiano extended the EFI 1.10 device path nodes. Tiano does not own this enum
+ so as we move to UEFI 2.0 support we must use a mechanism that conforms with
+ the UEFI 2.0 specification to define the FV device path. An UEFI GUIDed
+ device path is defined for PIWG extensions of device path. If the code
+ is compiled to conform with the UEFI 2.0 specification use the new device path
+ else use the old form for backwards compatability.
+
+Arguments:
+
+ FvDevicePathNode - Pointer to a FV device path node to initialize
+ NameGuid - FV file name to use in FvDevicePathNode
+
+Returns:
+
+ None
+
+--*/
+{
+#if (EFI_SPECIFICATION_VERSION != 0x00020000)
+ //
+ // Use old Device Path
+ //
+ FvDevicePathNode->Header.Type = MEDIA_DEVICE_PATH;
+ FvDevicePathNode->Header.SubType = MEDIA_FV_FILEPATH_DP;
+ SetDevicePathNodeLength (&FvDevicePathNode->Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH));
+
+#else
+ //
+ // Use the new Device path that does not conflict with the UEFI 2.0
+ //
+ FvDevicePathNode->Piwg.Header.Type = MEDIA_DEVICE_PATH;
+ FvDevicePathNode->Piwg.Header.SubType = MEDIA_VENDOR_DP;
+ SetDevicePathNodeLength (&FvDevicePathNode->Piwg.Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH));
+
+ //
+ // Add the GUID for generic PIWG device paths
+ //
+ EfiCopyMem (&FvDevicePathNode->Piwg.PiwgSpecificDevicePath, &gEfiFrameworkDevicePathGuid, sizeof(EFI_GUID));
+
+ //
+ // Add in the FW Vol File Path PIWG defined inforation
+ //
+ FvDevicePathNode->Piwg.Type = PIWG_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH_TYPE;
+
+#endif
+ 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.
+
+ Tiano extended the EFI 1.10 device path nodes. Tiano does not own this enum
+ so as we move to UEFI 2.0 support we must use a mechanism that conforms with
+ the UEFI 2.0 specification to define the FV device path. An UEFI GUIDed
+ device path is defined for PIWG extensions of device path. If the code
+ is compiled to conform with the UEFI 2.0 specification use the new device path
+ else use the old form for backwards compatability. The return value to this
+ function points to a location in FvDevicePathNode and it does not allocate
+ new memory for the GUID pointer that is returned.
+
+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 (EFI_SPECIFICATION_VERSION != 0x00020000)
+ //
+ // Use old Device Path
+ //
+ if (DevicePathType (&FvDevicePathNode->Header) == MEDIA_DEVICE_PATH &&
+ DevicePathSubType (&FvDevicePathNode->Header) == MEDIA_FV_FILEPATH_DP) {
+ return &FvDevicePathNode->NameGuid;
+ }
+
+#else
+ //
+ // Use the new Device path that does not conflict with the UEFI 2.0
+ //
+ if (DevicePathType (&FvDevicePathNode->Piwg.Header) == MEDIA_DEVICE_PATH &&
+ DevicePathSubType (&FvDevicePathNode->Piwg.Header) == MEDIA_VENDOR_DP) {
+ if (EfiCompareGuid (&gEfiFrameworkDevicePathGuid, &FvDevicePathNode->Piwg.PiwgSpecificDevicePath)) {
+ if (FvDevicePathNode->Piwg.Type == PIWG_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH_TYPE) {
+ return &FvDevicePathNode->NameGuid;
+ }
+ }
+ }
+#endif
+ return NULL;
+}
diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/DxeDriverLib.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/DxeDriverLib.c
new file mode 100644
index 0000000000..ecce5f05e6
--- /dev/null
+++ b/EdkCompatibilityPkg/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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Ebc/PerformancePrimitives.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Ebc/PerformancePrimitives.c
new file mode 100644
index 0000000000..bfe034975f
--- /dev/null
+++ b/EdkCompatibilityPkg/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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.c
new file mode 100644
index 0000000000..f1af8cc74d
--- /dev/null
+++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.c
@@ -0,0 +1,429 @@
+/*++
+
+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:
+
+ 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;
+}
+
+BOOLEAN
+EfiLibCompareLanguage (
+ IN CHAR8 *Language1,
+ IN CHAR8 *Language2
+ )
+/*++
+
+Routine Description:
+
+ Compare whether two names of languages are identical.
+
+Arguments:
+
+ Language1 - Name of language 1
+ Language2 - Name of language 2
+
+Returns:
+
+ TRUE - same
+ FALSE - not same
+
+--*/
+{
+ UINTN Index;
+
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+ for (Index = 0; (Language1[Index] != 0) && (Language2[Index] != 0); Index++) {
+ if (Language1[Index] != Language2[Index]) {
+ return FALSE;
+ }
+ }
+
+ if (((Language1[Index] == 0) && (Language2[Index] == 0)) ||
+ ((Language1[Index] == 0) && (Language2[Index] != ';')) ||
+ ((Language1[Index] == ';') && (Language2[Index] != 0)) ||
+ ((Language1[Index] == ';') && (Language2[Index] != ';'))) {
+ return TRUE;
+ }
+
+ return FALSE;
+#else
+ for (Index = 0; Index < 3; Index++) {
+ if (Language1[Index] != Language2[Index]) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+#endif
+}
+
+STATIC
+CHAR8 *
+NextSupportedLanguage (
+ IN CHAR8 *Languages
+ )
+{
+#ifdef LANGUAGE_RFC_3066 // LANGUAGE_RFC_3066
+ for (; (*Languages != 0) && (*Languages != ';'); Languages++)
+ ;
+ return Languages;
+#else // LANGUAGE_ISO_639_2
+ return (Languages + 3);
+#endif
+}
+
+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 (EfiAsciiStrLen(Language) + 1, 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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.inf b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.inf
new file mode 100644
index 0000000000..32425744aa
--- /dev/null
+++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.inf
@@ -0,0 +1,88 @@
+#/*++
+#
+# 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:
+#
+# 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
+
+[libraries.ia32]
+ CpuIA32Lib
+
+[libraries.x64]
+ CpuIA32Lib
+
+[libraries.ipf]
+ CpuIA64Lib
+
+[nmake.common]
diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiDriverModelLib.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiDriverModelLib.c
new file mode 100644
index 0000000000..5c2b47b66e
--- /dev/null
+++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiDriverModelLib.c
@@ -0,0 +1,289 @@
+/*++
+
+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:
+
+ 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
+EfiLibInstallAllDriverProtocols (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * SystemTable,
+ IN EFI_DRIVER_BINDING_PROTOCOL * DriverBinding,
+ IN EFI_HANDLE DriverBindingHandle,
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+ IN EFI_COMPONENT_NAME2_PROTOCOL * ComponentName, OPTIONAL
+#else
+ IN EFI_COMPONENT_NAME_PROTOCOL * ComponentName, OPTIONAL
+#endif
+ 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()
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = EfiLibInstallDriverBinding (ImageHandle, SystemTable, DriverBinding, DriverBindingHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (ComponentName != NULL) {
+ Status = gBS->InstallProtocolInterface (
+ &DriverBinding->DriverBindingHandle,
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+ &gEfiComponentName2ProtocolGuid,
+#else
+ &gEfiComponentNameProtocolGuid,
+#endif
+ EFI_NATIVE_INTERFACE,
+ ComponentName
+ );
+ 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 (DriverDiagnostics != NULL) {
+ Status = gBS->InstallProtocolInterface (
+ &DriverBinding->DriverBindingHandle,
+ &gEfiDriverDiagnosticsProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ DriverDiagnostics
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiGetConfigTable.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiGetConfigTable.c
new file mode 100644
index 0000000000..7fdbb8d8f4
--- /dev/null
+++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiGetConfigTable.c
@@ -0,0 +1,61 @@
+/*++
+
+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:
+
+ EfiGetConfigTable.c
+
+Abstract:
+
+ Light weight lib to support EFI drivers.
+
+--*/
+
+#include "Tiano.h"
+#include "EfiDriverLib.h"
+
+EFI_STATUS
+EfiLibGetSystemConfigurationTable (
+ IN EFI_GUID *TableGuid,
+ 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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiLibAllocate.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiLibAllocate.c
new file mode 100644
index 0000000000..6558e3da0e
--- /dev/null
+++ b/EdkCompatibilityPkg/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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Event.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Event.c
new file mode 100644
index 0000000000..3cb668e966
--- /dev/null
+++ b/EdkCompatibilityPkg/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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/GetImage.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/GetImage.c
new file mode 100644
index 0000000000..3d44562ecf
--- /dev/null
+++ b/EdkCompatibilityPkg/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)
+ 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)
+ 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,
+ &LoadedImage
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Status = gBS->HandleProtocol (
+ LoadedImage->DeviceHandle,
+ #if (PI_SPECIFICATION_VERSION < 0x00010000)
+ &gEfiFirmwareVolumeProtocolGuid,
+ #else
+ &gEfiFirmwareVolume2ProtocolGuid,
+ #endif
+ &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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Handle.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Handle.c
new file mode 100644
index 0000000000..179079d3db
--- /dev/null
+++ b/EdkCompatibilityPkg/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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Ipf/PerformancePrimitives.s b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Ipf/PerformancePrimitives.s
new file mode 100644
index 0000000000..5814bb71b7
--- /dev/null
+++ b/EdkCompatibilityPkg/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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/LibGlobalDs.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/LibGlobalDs.c
new file mode 100644
index 0000000000..328e465e45
--- /dev/null
+++ b/EdkCompatibilityPkg/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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/LibGlobalErrorLevel.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/LibGlobalErrorLevel.c
new file mode 100644
index 0000000000..64ed94ced4
--- /dev/null
+++ b/EdkCompatibilityPkg/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;
diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/LibGlobalSt.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/LibGlobalSt.c
new file mode 100644
index 0000000000..5a6528588f
--- /dev/null
+++ b/EdkCompatibilityPkg/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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Lock.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Lock.c
new file mode 100644
index 0000000000..5667a34020
--- /dev/null
+++ b/EdkCompatibilityPkg/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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Perf.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Perf.c
new file mode 100644
index 0000000000..55d1a1d14e
--- /dev/null
+++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Perf.c
@@ -0,0 +1,861 @@
+/*++
+
+Copyright (c) 2004 - 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:
+
+ Perf.c
+
+Abstract:
+
+ Support for Performance primatives.
+
+--*/
+
+#include "Tiano.h"
+#include "EfiDriverLib.h"
+#include EFI_PROTOCOL_DEFINITION (Performance)
+#include EFI_PROTOCOL_DEFINITION (LoadedImage)
+#include EFI_GUID_DEFINITION (Hob)
+#include EFI_GUID_DEFINITION (PeiPerformanceHob)
+#include "linkedlist.h"
+#include "EfiHobLib.h"
+#include "EfiImage.h"
+
+EFI_STATUS
+GetTimerValue (
+ OUT UINT64 *TimerValue
+ );
+
+EFI_STATUS
+GetPeiPerformance (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN UINT64 Ticker
+ );
+
+#define EFI_PERFORMANCE_DATA_SIGNATURE EFI_SIGNATURE_32 ('P', 'E', 'D', 'A')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_LIST_ENTRY Link;
+ EFI_GAUGE_DATA GaugeData;
+} EFI_PERF_DATA_LIST;
+
+#define GAUGE_DATA_FROM_LINK(_link) \
+ CR(_link, EFI_PERF_DATA_LIST, Link, EFI_PERFORMANCE_DATA_SIGNATURE)
+
+#define GAUGE_DATA_FROM_GAUGE(_GaugeData) \
+ CR(_GaugeData, EFI_PERF_DATA_LIST, GaugeData, EFI_PERFORMANCE_DATA_SIGNATURE)
+
+#define EFI_PERFORMANCE_SIGNATURE EFI_SIGNATURE_32 ('P', 'E', 'R', 'F')
+
+//
+// Performance protocol instance data structure
+//
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ EFI_PERFORMANCE_PROTOCOL Perf;
+ UINT8 Phase;
+} EFI_PERFORMANCE_INSTANCE;
+
+//
+// Performace protocol instance containing record macro
+//
+
+#define EFI_PERFORMANCE_FROM_THIS(a) \
+ CR(a, EFI_PERFORMANCE_INSTANCE, Perf, EFI_PERFORMANCE_SIGNATURE)
+
+EFI_LIST_ENTRY mPerfDataHead = INITIALIZE_LIST_HEAD_VARIABLE(mPerfDataHead);
+
+STATIC
+VOID
+GetShortPdbFileName (
+ CHAR8 *PdbFileName,
+ CHAR8 *GaugeString
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ 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 == EFI_PERF_PDBFILENAME_LENGTH - 1) {
+ break;
+ }
+ }
+
+ GaugeString[Index1] = 0;
+ }
+
+ return ;
+}
+
+STATIC
+CHAR8 *
+GetPdbPath (
+ VOID *ImageBase
+ )
+/*++
+
+Routine Description:
+
+ Located PDB path name in PE image
+
+Arguments:
+
+ ImageBase - base of PE to search
+
+Returns:
+
+ Pointer into image at offset of PDB file name if PDB file name is found,
+ Otherwise a pointer to an empty string.
+
+--*/
+{
+ 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
+ )
+{
+ 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_PERF_DATA_LIST *
+CreateDataNode (
+ IN EFI_HANDLE Handle,
+ IN UINT16 *Token,
+ IN UINT16 *Host
+ )
+/*++
+
+Routine Description:
+
+ Create a EFI_PERF_DATA_LIST data node.
+
+Arguments:
+
+ Handle - Handle of gauge data
+ Token - Token of gauge data
+ Host - Host of gauge data
+
+Returns:
+
+ Pointer to a data node created.
+
+--*/
+{
+ EFI_PERF_DATA_LIST *Node;
+
+ //
+ // Al\ a new image structure
+ //
+ Node = EfiLibAllocateZeroPool (sizeof (EFI_PERF_DATA_LIST));
+ if (Node != NULL) {
+
+ Node->Signature = EFI_PERFORMANCE_DATA_SIGNATURE;
+
+ Node->GaugeData.Handle = Handle;
+
+ if (Token != NULL) {
+ EfiStrCpy ((Node->GaugeData).Token, Token);
+ }
+
+ if (Host != NULL) {
+ EfiStrCpy ((Node->GaugeData).Host, Host);
+ }
+
+ if (Handle != NULL) {
+ GetNameFromHandle (Handle, Node->GaugeData.PdbFileName);
+ }
+ }
+
+ return Node;
+}
+
+
+EFI_PERF_DATA_LIST *
+GetDataNode (
+ IN EFI_HANDLE Handle,
+ IN UINT16 *Token,
+ IN UINT16 *Host,
+ IN EFI_GUID *GuidName,
+ IN EFI_GAUGE_DATA *PrevGauge
+ )
+/*++
+
+Routine Description:
+
+ Search gauge node list to find one node with matched handle, token, host and Guid name.
+
+Arguments:
+
+ Handle - Handle to match
+ Token - Token to match
+ Host - Host to match
+ GuidName - Guid name to match
+ PrevGauge - Start node, start from list head if NULL
+
+Returns:
+
+ Return pointer to the node found, NULL if not found.
+
+--*/
+{
+ EFI_PERF_DATA_LIST *Node;
+ EFI_PERF_DATA_LIST *Temp;
+ EFI_PERF_DATA_LIST *Temp2;
+ EFI_LIST_ENTRY *CurrentLink;
+ EFI_GUID NullGuid = EFI_NULL_GUID;
+
+ Node = NULL;
+ Temp = NULL;
+ Temp2 = NULL;
+
+ if (PrevGauge == NULL) {
+ CurrentLink = mPerfDataHead.ForwardLink;
+ } else {
+ Temp2 = GAUGE_DATA_FROM_GAUGE (PrevGauge);
+ CurrentLink = (Temp2->Link).ForwardLink;
+ }
+
+ while (CurrentLink && CurrentLink != &mPerfDataHead) {
+ Node = GAUGE_DATA_FROM_LINK (CurrentLink);
+
+ if (Handle == 0 && Token == NULL && Host == NULL && GuidName == NULL) {
+ return Node;
+ }
+
+ if (Handle != (Node->GaugeData).Handle) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ if (GuidName == NULL && !EfiCompareGuid (&((Node->GaugeData).GuidName), &NullGuid)) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ if (GuidName && !EfiCompareGuid (&((Node->GaugeData).GuidName), GuidName)) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ if (Token == NULL && EfiStrCmp (Node->GaugeData.Token, L"")) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ if (Token && EfiStrCmp (Node->GaugeData.Token, Token)) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ if (Host == NULL && EfiStrCmp (Node->GaugeData.Host, L"")) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ if (Host && EfiStrCmp (Node->GaugeData.Host, Host)) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ Temp = Node;
+ break;
+ }
+
+ return Temp;
+}
+
+
+EFI_STATUS
+EFIAPI
+StartGauge (
+ IN EFI_PERFORMANCE_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINT16 *Token,
+ IN UINT16 *Host,
+ IN UINT64 Ticker
+ )
+/*++
+
+Routine Description:
+
+ Create a guage data node and initialized it.
+
+Arguments:
+
+ This - Calling context
+ Handle - Handle of gauge data
+ Token - Token of gauge data
+ Host - Host of gauge data
+ Ticker - Set gauge data's StartTick. If 0, StartTick is current timer.
+
+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_PERFORMANCE_INSTANCE *PerfInstance;
+ EFI_PERF_DATA_LIST *Node;
+ UINT64 TimerValue;
+
+ TimerValue = 0;
+ PerfInstance = EFI_PERFORMANCE_FROM_THIS (This);
+
+ Node = CreateDataNode (Handle, Token, Host);
+ if (!Node) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (Ticker != 0) {
+ TimerValue = Ticker;
+ } else {
+ GetTimerValue (&TimerValue);
+ }
+
+ Node->GaugeData.StartTick = TimerValue;
+
+ if (!EfiStrCmp (Token, DXE_TOK)) {
+ PerfInstance->Phase = DXE_PHASE;
+ }
+
+ if (!EfiStrCmp (Token, SHELL_TOK)) {
+ PerfInstance->Phase = SHELL_PHASE;
+ }
+
+ Node->GaugeData.Phase = PerfInstance->Phase;
+
+ InsertTailList (&mPerfDataHead, &(Node->Link));
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+EndGauge (
+ IN EFI_PERFORMANCE_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINT16 *Token,
+ IN UINT16 *Host,
+ IN UINT64 Ticker
+ )
+/*++
+
+Routine Description:
+
+ End all unfinished gauge data node that match specified handle, token and host.
+
+Arguments:
+
+ This - Calling context
+ Handle - Handle to stop
+ Token - Token to stop
+ Host - Host to stop
+ Ticker - End tick, if 0 then get current timer
+
+Returns:
+
+ EFI_NOT_FOUND - Node not found
+ EFI_SUCCESS - Gauge data node successfully ended.
+
+--*/
+{
+ EFI_PERFORMANCE_INSTANCE *PerfInstance;
+ EFI_PERF_DATA_LIST *Node;
+ UINT64 TimerValue;
+
+ TimerValue = 0;
+ PerfInstance = EFI_PERFORMANCE_FROM_THIS (This);
+
+ Node = GetDataNode (Handle, Token, Host, NULL, NULL);
+ if (!Node) {
+ return EFI_NOT_FOUND;
+ }
+
+ while (Node->GaugeData.EndTick != 0) {
+ Node = GetDataNode (Handle, Token, Host, NULL, &(Node->GaugeData));
+ if (!Node) {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ if (Ticker != 0) {
+ TimerValue = Ticker;
+ } else {
+ GetTimerValue (&TimerValue);
+ }
+
+ Node->GaugeData.EndTick = TimerValue;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_GAUGE_DATA *
+EFIAPI
+GetGauge (
+ IN EFI_PERFORMANCE_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINT16 *Token,
+ IN UINT16 *Host,
+ IN EFI_GAUGE_DATA *PrevGauge
+ )
+/*++
+
+Routine Description:
+ Get gauge.
+
+Arguments:
+ This - A pointer to the EFI_PERFORMANCE_PROTOCOL.
+ Handle - A pointer of a efi handle.
+ Token - A pointer to the token.
+ Host - A pointer to the host.
+ PrevGauge - A pointer to the EFI_GAUGE_DATA structure.
+
+
+Returns:
+ Status code.
+
+--*/
+{
+ EFI_PERFORMANCE_INSTANCE *PerfInstance;
+ EFI_PERF_DATA_LIST *Node;
+
+ PerfInstance = EFI_PERFORMANCE_FROM_THIS (This);
+
+ Node = GetDataNode (Handle, Token, Host, NULL, PrevGauge);
+ if (Node != NULL) {
+ return &(Node->GaugeData);
+ } else {
+ return NULL;
+ }
+}
+
+//
+// Driver entry point
+//
+EFI_STATUS
+InitializePerformanceInfrastructure (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN UINT64 Ticker
+ )
+/*++
+
+Routine Description:
+
+ Install gEfiPerformanceProtocolGuid 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;
+ EFI_PERFORMANCE_INSTANCE *PerfInstance;
+
+ //
+ // Allocate a new image structure
+ //
+ PerfInstance = EfiLibAllocateZeroPool (sizeof (EFI_PERFORMANCE_INSTANCE));
+ if (PerfInstance == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ PerfInstance->Signature = EFI_PERFORMANCE_SIGNATURE;
+ PerfInstance->Perf.StartGauge = StartGauge;
+ PerfInstance->Perf.EndGauge = EndGauge;
+ PerfInstance->Perf.GetGauge = GetGauge;
+
+ //
+ // Install the protocol interfaces
+ //
+ Status = gBS->InstallProtocolInterface (
+ &PerfInstance->Handle,
+ &gEfiPerformanceProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &PerfInstance->Perf
+ );
+
+ if (!EFI_ERROR (Status)) {
+ GetPeiPerformance (ImageHandle, SystemTable, Ticker);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+StartMeasure (
+ EFI_HANDLE Handle,
+ IN UINT16 *Token,
+ IN UINT16 *Host,
+ IN UINT64 Ticker
+ )
+/*++
+
+Routine Description:
+
+ Start to gauge on a specified handle, token and host, with Ticker as start tick.
+
+Arguments:
+
+ Handle - Handle to measure
+ Token - Token to measure
+ Host - Host to measure
+ Ticker - Ticker as start tick
+
+Returns:
+
+ Status code.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PERFORMANCE_PROTOCOL *Perf;
+
+ Status = gBS->LocateProtocol (&gEfiPerformanceProtocolGuid, NULL, (VOID **) &Perf);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Perf->StartGauge (Perf, Handle, Token, Host, Ticker);
+
+}
+
+
+EFI_STATUS
+EndMeasure (
+ EFI_HANDLE Handle,
+ IN UINT16 *Token,
+ IN UINT16 *Host,
+ IN UINT64 Ticker
+ )
+/*++
+
+Routine Description:
+
+ End gauging on a specified handle, token and host, with Ticker as end tick.
+
+Arguments:
+
+ Handle - Handle to stop
+ Token - Token to stop
+ Host - Host to stop
+ Ticker - Ticker as end tick
+
+Returns:
+
+ Status code.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PERFORMANCE_PROTOCOL *Perf;
+
+ Status = gBS->LocateProtocol (&gEfiPerformanceProtocolGuid, NULL, (VOID **) &Perf);
+ if (Status != EFI_SUCCESS) {
+ return Status;
+ }
+
+ return (Perf->EndGauge( Perf, Handle, Token, Host, Ticker)) ;
+}
+
+
+EFI_STATUS
+UpdateMeasure (
+ EFI_HANDLE Handle,
+ IN UINT16 *Token,
+ IN UINT16 *Host,
+ EFI_HANDLE HandleNew,
+ IN UINT16 *TokenNew,
+ IN UINT16 *HostNew
+ )
+/*++
+
+Routine Description:
+ Update measure.
+
+Arguments:
+ Handle - A pointer of an efi handle.
+ Token - A pointer to the token.
+ Host - A pointer to the host.
+ HandleNew - A pointer of an new efi handle.
+ TokenNew - A pointer to the new token.
+ HostNew - A pointer to the new host.
+
+Returns:
+ Status code.
+
+ EFI_NOT_FOUND - The speicified gauge data node not found.
+
+ EFI_SUCCESS - Update successfully.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_GAUGE_DATA *GaugeData;
+ EFI_PERFORMANCE_PROTOCOL *Perf;
+
+ Status = gBS->LocateProtocol (&gEfiPerformanceProtocolGuid, NULL, (VOID **) &Perf);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ GaugeData = Perf->GetGauge (Perf, Handle, Token, Host, NULL);
+ if (!GaugeData) {
+ return EFI_NOT_FOUND;
+ }
+
+ GaugeData->Handle = HandleNew;
+ if (HostNew != NULL) {
+ EfiStrCpy (GaugeData->Host, HostNew);
+ } else {
+ EfiStrCpy (GaugeData->Host, L"");
+ }
+
+ if (TokenNew != NULL) {
+ EfiStrCpy (GaugeData->Token, TokenNew);
+ } else {
+ EfiStrCpy (GaugeData->Token, L"");
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+GetPeiPerformance (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN UINT64 Ticker
+ )
+/*++
+
+Routine Description:
+
+ Transfer PEI performance data to gauge data node.
+
+Arguments:
+
+ ImageHandle - Standard entry point parameter
+ SystemTable - Standard entry point parameter
+ Ticker - Start tick
+
+Returns:
+
+ EFI_OUT_OF_RESOURCES - No enough resource to create data node.
+ EFI_SUCCESS - Transfer done successfully.
+
+--*/
+{
+ EFI_STATUS Status;
+ VOID *HobList;
+ EFI_HOB_GUID_DATA_PERFORMANCE_LOG *LogHob;
+ PEI_PERFORMANCE_MEASURE_LOG_ENTRY *LogEntry;
+ UINT32 Index;
+ EFI_PERF_DATA_LIST *Node;
+ UINT64 TimerValue;
+
+ Node = CreateDataNode (0, PEI_TOK, NULL);
+ if (!Node) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (Ticker != 0) {
+ TimerValue = Ticker;
+ } else {
+ GetTimerValue (&TimerValue);
+ }
+ (Node->GaugeData).EndTick = TimerValue;
+
+ InsertTailList (&mPerfDataHead, &(Node->Link));
+
+ EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
+ do {
+ Status = GetNextGuidHob (&HobList, &gEfiPeiPerformanceHobGuid, (VOID **) &LogHob, NULL);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ for (Index = 0; Index < LogHob->NumberOfEntries; Index++) {
+ LogEntry = &(LogHob->Log[Index]);
+ Node = CreateDataNode (0, LogEntry->DescriptionString, NULL);
+ if (!Node) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ (Node->GaugeData).StartTick = LogEntry->StartTimeCount;
+
+ EfiCopyMem (&(Node->GaugeData.GuidName), &LogEntry->Name, sizeof (EFI_GUID));
+
+ InsertTailList (&mPerfDataHead, &(Node->Link));
+
+ (Node->GaugeData).EndTick = LogEntry->StopTimeCount;
+ }
+ } while (!EFI_ERROR (Status));
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/ReportStatusCode.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/ReportStatusCode.c
new file mode 100644
index 0000000000..72efa4c45d
--- /dev/null
+++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/ReportStatusCode.c
@@ -0,0 +1,141 @@
+/*++
+
+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
+ if (gRT == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Check whether EFI_RUNTIME_SERVICES has Tiano Extension
+ //
+ Status = EFI_UNSUPPORTED;
+ if (gRT->Hdr.Revision == EFI_SPECIFICATION_VERSION &&
+ gRT->Hdr.HeaderSize == sizeof (EFI_RUNTIME_SERVICES) &&
+ gRT->ReportStatusCode != NULL) {
+ 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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/ia32/PerformancePrimitives.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/ia32/PerformancePrimitives.c
new file mode 100644
index 0000000000..02d5ff8d81
--- /dev/null
+++ b/EdkCompatibilityPkg/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/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/x64/PerformancePrimitives.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/x64/PerformancePrimitives.c
new file mode 100644
index 0000000000..929ddf1807
--- /dev/null
+++ b/EdkCompatibilityPkg/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;
+}