From b7c51c9cf4864df6aabb99a1ae843becd577237c Mon Sep 17 00:00:00 2001 From: raywu Date: Fri, 15 Jun 2018 00:00:50 +0800 Subject: init. 1AQQW051 --- .../Library/EfiCommonLib/EfiCommonLib.cif | 36 + .../Library/EfiCommonLib/EfiCommonLib.inf | 85 +++ .../Library/EfiCommonLib/EfiCommonLib.mak | 123 ++++ .../Library/EfiCommonLib/EfiCommonLib.sdl | 31 + .../Library/EfiCommonLib/EfiCompareGuid.c | 59 ++ .../Library/EfiCommonLib/EfiCompareMem.c | 76 ++ EDK/Foundation/Library/EfiCommonLib/EfiCopyMem.c | 69 ++ EDK/Foundation/Library/EfiCommonLib/EfiSetMem.c | 65 ++ EDK/Foundation/Library/EfiCommonLib/EfiZeroMem.c | 57 ++ .../Library/EfiCommonLib/Ia32/DivU64x32.asm | 99 +++ .../Library/EfiCommonLib/Ia32/EfiCopyMem.asm | 183 +++++ .../Library/EfiCommonLib/Ia32/EfiCopyMemSSE2.asm | 169 +++++ .../Library/EfiCommonLib/Ia32/EfiSetMem.asm | 154 ++++ .../Library/EfiCommonLib/Ia32/EfiSetMemSSE2.asm | 158 ++++ .../Library/EfiCommonLib/Ia32/EfiZeroMem.asm | 138 ++++ .../Library/EfiCommonLib/Ia32/EfiZeroMemSSE2.asm | 127 ++++ .../Library/EfiCommonLib/Ia32/GetPowerOfTwo.asm | 67 ++ .../Library/EfiCommonLib/Ia32/LShiftU64.asm | 86 +++ EDK/Foundation/Library/EfiCommonLib/Ia32/Log2.asm | 87 +++ .../Library/EfiCommonLib/Ia32/MultU64x32.asm | 74 ++ .../Library/EfiCommonLib/Ia32/Power10U64.asm | 72 ++ .../Library/EfiCommonLib/Ia32/RShiftU64.asm | 86 +++ EDK/Foundation/Library/EfiCommonLib/Math.c | 216 ++++++ EDK/Foundation/Library/EfiCommonLib/Misc.c | 385 ++++++++++ EDK/Foundation/Library/EfiCommonLib/PostCode.c | 62 ++ .../Library/EfiCommonLib/ReportStatusCode.c | 333 +++++++++ EDK/Foundation/Library/EfiCommonLib/String.c | 802 +++++++++++++++++++++ .../Library/EfiCommonLib/ValueToString.c | 213 ++++++ EDK/Foundation/Library/EfiCommonLib/linkedlist.c | 356 +++++++++ .../Library/EfiCommonLib/x64/EfiCopyMemRep4.asm | 65 ++ 30 files changed, 4533 insertions(+) create mode 100644 EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.cif create mode 100644 EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.inf create mode 100644 EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.mak create mode 100644 EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.sdl create mode 100644 EDK/Foundation/Library/EfiCommonLib/EfiCompareGuid.c create mode 100644 EDK/Foundation/Library/EfiCommonLib/EfiCompareMem.c create mode 100644 EDK/Foundation/Library/EfiCommonLib/EfiCopyMem.c create mode 100644 EDK/Foundation/Library/EfiCommonLib/EfiSetMem.c create mode 100644 EDK/Foundation/Library/EfiCommonLib/EfiZeroMem.c create mode 100644 EDK/Foundation/Library/EfiCommonLib/Ia32/DivU64x32.asm create mode 100644 EDK/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMem.asm create mode 100644 EDK/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMemSSE2.asm create mode 100644 EDK/Foundation/Library/EfiCommonLib/Ia32/EfiSetMem.asm create mode 100644 EDK/Foundation/Library/EfiCommonLib/Ia32/EfiSetMemSSE2.asm create mode 100644 EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.asm create mode 100644 EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMemSSE2.asm create mode 100644 EDK/Foundation/Library/EfiCommonLib/Ia32/GetPowerOfTwo.asm create mode 100644 EDK/Foundation/Library/EfiCommonLib/Ia32/LShiftU64.asm create mode 100644 EDK/Foundation/Library/EfiCommonLib/Ia32/Log2.asm create mode 100644 EDK/Foundation/Library/EfiCommonLib/Ia32/MultU64x32.asm create mode 100644 EDK/Foundation/Library/EfiCommonLib/Ia32/Power10U64.asm create mode 100644 EDK/Foundation/Library/EfiCommonLib/Ia32/RShiftU64.asm create mode 100644 EDK/Foundation/Library/EfiCommonLib/Math.c create mode 100644 EDK/Foundation/Library/EfiCommonLib/Misc.c create mode 100644 EDK/Foundation/Library/EfiCommonLib/PostCode.c create mode 100644 EDK/Foundation/Library/EfiCommonLib/ReportStatusCode.c create mode 100644 EDK/Foundation/Library/EfiCommonLib/String.c create mode 100644 EDK/Foundation/Library/EfiCommonLib/ValueToString.c create mode 100644 EDK/Foundation/Library/EfiCommonLib/linkedlist.c create mode 100644 EDK/Foundation/Library/EfiCommonLib/x64/EfiCopyMemRep4.asm (limited to 'EDK/Foundation/Library/EfiCommonLib') diff --git a/EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.cif b/EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.cif new file mode 100644 index 0000000..fbc1774 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.cif @@ -0,0 +1,36 @@ + + name = "EfiCommonLib" + category = ModulePart + LocalRoot = "EDK\Foundation\Library\EfiCommonLib\" + RefName = "EfiCommonLib" +[files] +"EfiCommonLib.sdl" +"EfiCommonLib.mak" +"EfiCompareGuid.c" +"EfiCompareMem.c" +"linkedlist.c" +"PostCode.c" +"ReportStatusCode.c" +"String.c" +"ValueToString.c" +"EfiCopyMem.c" +"EfiSetMem.c" +"EfiZeroMem.c" +"Math.c" +"Misc.c" +"x64\EfiCopyMemRep4.asm" +"Ia32\DivU64x32.asm" +"Ia32\EfiCopyMem.asm" +"Ia32\EfiCopyMemSSE2.asm" +"Ia32\EfiSetMem.asm" +"Ia32\EfiSetMemSSE2.asm" +"Ia32\EfiZeroMem.asm" +"Ia32\EfiZeroMemSSE2.asm" +"Ia32\GetPowerOfTwo.asm" +"Ia32\Log2.asm" +"Ia32\LShiftU64.asm" +"Ia32\MultU64x32.asm" +"Ia32\Power10U64.asm" +"Ia32\RShiftU64.asm" +"EfiCommonLib.inf" + diff --git a/EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.inf b/EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.inf new file mode 100644 index 0000000..1410b80 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.inf @@ -0,0 +1,85 @@ +#/*++ +# +# 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: +# +# EfiCommonLib.inf +# +# Abstract: +# +# Component description file for the EFI common library. +# +#--*/ + +[defines] +BASE_NAME = EfiCommonLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + EfiCompareGuid.c + EfiCompareMem.c + ReportStatusCode.c + PostCode.c + String.c + ValueToString.c + LinkedList.c + +[sources.ia32] + Ia32\EfiCopyMem.asm + Ia32\EfiSetMem.asm + Ia32\EfiZeroMem.asm + Ia32\LShiftU64.asm + Ia32\RShiftU64.asm + Ia32\MultU64x32.asm + Ia32\DivU64x32.asm + Ia32\Power10U64.asm + Ia32\Log2.asm + Ia32\GetPowerOfTwo.asm + +[sources.ipf] + EfiCopyMem.c + EfiSetMem.c + EfiZeroMem.c + Math.c + +[sources.ebc] + EfiCopyMem.c + EfiSetMem.c + EfiZeroMem.c + Math.c +[sources.x64] + x64\EfiCopyMemRep4.asm + EfiSetMem.c + EfiZeroMem.c + Math.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) + $(EDK_SOURCE)\Foundation\Core\Dxe + $(EDK_SOURCE)\Foundation\Library\Dxe\Include + $(EDK_SOURCE)\Foundation\Include\Pei + $(EDK_SOURCE)\Foundation\Library\Pei\Include + $(EDK_SOURCE)\Foundation\Core\Pei\Include + $(EDK_SOURCE)\Foundation\Framework\Ppi\CpuIo + $(EDK_SOURCE)\Foundation\Framework + +[libraries.common] + EdkFrameworkGuidLib + +[nmake.common] + C_STD_INCLUDE= diff --git a/EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.mak b/EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.mak new file mode 100644 index 0000000..e7ba070 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.mak @@ -0,0 +1,123 @@ +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** + +#********************************************************************** +# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelEDK/EfiCommonLib/EfiCommonLib.mak 1 1/20/12 4:10a Jeffch $ +# +# $Revision: 1 $ +# +# $Date: 1/20/12 4:10a $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelEDK/EfiCommonLib/EfiCommonLib.mak $ +# +# 1 1/20/12 4:10a Jeffch +# Create Intel EDK 1117 Patch 7. +# +# 1 9/27/11 6:31a Wesleychen +# Intel EDK initially releases. +# +# 3 11/06/09 4:28a Iminglin +# Edk-Dev-Snapshot-20090928 +# +# 2 9/02/09 3:56a Iminglin +# EIP24919 +# +#********************************************************************** +# +# +# Name: EfiCommonLib.mak +# +# Description: +# +# +#********************************************************************** +$(EFICOMMONLIB) : EfiCommonLib + +EFI_COMMON_LIB_OBJECTS=\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\EfiCompareGuid.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\EfiCompareMem.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\linkedlist.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\PostCode.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\ReportStatusCode.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\String.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\ValueToString.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\Misc.obj + +EFI_COMMON_LIB_IA32_OBJECTS=\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\Ia32\EfiCopyMemSSE2.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\Ia32\EfiSetMemSSE2.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\Ia32\EfiZeroMemSSE2.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\Ia32\LShiftU64.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\Ia32\RShiftU64.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\Ia32\MultU64x32.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\Ia32\DivU64x32.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\Ia32\Power10U64.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\Ia32\Log2.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\Ia32\GetPowerOfTwo.obj + +!IF "$(PROCESSOR)"=="IA32" +EFI_COMMON_LIB_OBJECTS=$(EFI_COMMON_LIB_OBJECTS) $(EFI_COMMON_LIB_IA32_OBJECTS) +!ELSEIF "$(PROCESSOR)"=="x64" +EFI_COMMON_LIB_PEI_OBJECTS=$(EFI_COMMON_LIB_OBJECTS) $(EFI_COMMON_LIB_IA32_OBJECTS) +EFI_COMMON_LIB_DXE_OBJECTS=$(EFI_COMMON_LIB_OBJECTS)\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\x64\EfiCopyMemRep4.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\EfiSetMem.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\EfiZeroMem.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\Math.obj +!ELSEIF "$(PROCESSOR)"=="IPF" || "$(PROCESSOR)"=="EBC" +EFI_COMMON_LIB_OBJECTS=$(EFI_COMMON_LIB_OBJECTS)\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\EfiCopyMem.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\EfiSetMem.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\EfiZeroMem.obj\ +$$(BUILD_DIR)\$(EfiCommonLib_DIR)\Math.obj +!ENDIF + +$(EFICOMMONLIB) : EfiCommonLib + +EfiCommonLib : $(BUILD_DIR)\EfiCommonLib.mak EfiCommonLibBin + +$(BUILD_DIR)\EfiCommonLib.mak : $(EfiCommonLib_DIR)\$(@B).cif $(EfiCommonLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(EfiCommonLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +EfiCommonLibBin : $(EDKFRAMEWORKGUIDLIB) $(COMPILERSTUB) +!IF "$(PROCESSOR)"=="x64" + $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS)\ + /f $(BUILD_DIR)\EfiCommonLib.mak all\ + "MY_INCLUDES=/I$(EDK_SOURCE)\Foundation\Framework\Ppi\CpuIo" \ + TYPE=LIBRARY "OBJECTS=$(EFI_COMMON_LIB_DXE_OBJECTS)" + $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\ + /f $(BUILD_DIR)\EfiCommonLib.mak all\ + "MY_INCLUDES=/I$(EDK_SOURCE)\Foundation\Framework\Ppi\CpuIo" \ + TYPE=PEI_LIBRARY "OBJECTS=$(EFI_COMMON_LIB_PEI_OBJECTS)" +!ELSE + $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS)\ + /f $(BUILD_DIR)\EfiCommonLib.mak all\ + "MY_INCLUDES=/I$(EDK_SOURCE)\Foundation\Framework\Ppi\CpuIo" \ + TYPE=LIBRARY "OBJECTS=$(EFI_COMMON_LIB_OBJECTS)" +!ENDIF +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2009, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** \ No newline at end of file diff --git a/EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.sdl b/EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.sdl new file mode 100644 index 0000000..c6b970e --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/EfiCommonLib.sdl @@ -0,0 +1,31 @@ +TOKEN + Name = "EfiCommonLib_SUPPORT" + Value = "1" + Help = "Main switch to enable EfiCommonLib support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +TOKEN + Name = "EFICOMMONLIB" + Value = "$$(LIB_BUILD_DIR)\EfiCommonLib.lib" + TokenType = Expression + TargetMAK = Yes +End + +PATH + Name = "EfiCommonLib_DIR" +End + +MODULE + Help = "Includes EfiCommonLib.mak to Project" + File = "EfiCommonLib.mak" +End + +ELINK + Name = "/D SUPPORT_DEPRECATED_PCI_CFG_PPI" + Parent = "GLOBAL_DEFINES" + InvokeOrder = AfterParent +End diff --git a/EDK/Foundation/Library/EfiCommonLib/EfiCompareGuid.c b/EDK/Foundation/Library/EfiCommonLib/EfiCompareGuid.c new file mode 100644 index 0000000..138aad6 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/EfiCompareGuid.c @@ -0,0 +1,59 @@ +/*++ + +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: + + EfiCompareGuid.c + +Abstract: + + Driver library routine to compare two GUIDs. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" + +BOOLEAN +EfiCompareGuid ( + IN EFI_GUID *Guid1, + IN EFI_GUID *Guid2 + ) +/*++ + +Routine Description: + + Compares two GUIDs + +Arguments: + + Guid1 - guid to compare + + Guid2 - guid to compare + +Returns: + TRUE if Guid1 == Guid2 + FALSE if Guid1 != Guid2 + +--*/ +{ + UINTN Index; + + // + // compare byte by byte + // + for (Index = 0; Index < 16; ++Index) { + if (*(((UINT8*) Guid1) + Index) != *(((UINT8*) Guid2) + Index)) { + return FALSE; + } + } + return TRUE; +} diff --git a/EDK/Foundation/Library/EfiCommonLib/EfiCompareMem.c b/EDK/Foundation/Library/EfiCommonLib/EfiCompareMem.c new file mode 100644 index 0000000..4a43026 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/EfiCompareMem.c @@ -0,0 +1,76 @@ +/*++ + +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: + + EfiCompareMem.c + +Abstract: + + Generic compare-memory routine. + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" + + +INTN +EfiCompareMem ( + IN VOID *MemOne, + IN VOID *MemTwo, + IN UINTN Length + ) +/*++ + +Routine Description: + + Compares two memory buffers of a given length. + +Arguments: + + MemOne - First memory buffer + + MemTwo - Second memory buffer + + Len - Length of Mem1 and Mem2 memory regions to compare + +Returns: + + = 0 if MemOne == MemTwo + +--*/ +{ + INTN ReturnValue; + + if (!(EFI_UINTN_ALIGNED (MemOne) || EFI_UINTN_ALIGNED (MemTwo) || EFI_UINTN_ALIGNED (Length))) { + // + // If Destination/Source/Length are aligned do UINTN conpare + // + for (; Length > 0; Length -= sizeof (INTN), MemOne = (VOID *)((UINTN)MemOne + sizeof (INTN)), MemTwo = (VOID *)((UINTN)MemTwo + sizeof (INTN))) { + if (*(INTN *)MemOne != *(INTN *)MemTwo) { + break; + } + } + } + + // + // If Destination/Source/Length not aligned do byte compare + // + for (; Length > 0; Length--, MemOne = (VOID *)((UINTN)MemOne + 1), MemTwo = (VOID *)((UINTN)MemTwo + 1)) { + ReturnValue = (INTN)(*(INT8 *)MemOne - *(INT8 *)MemTwo); + if (ReturnValue != 0) { + return ReturnValue; + } + } + + return 0; +} diff --git a/EDK/Foundation/Library/EfiCommonLib/EfiCopyMem.c b/EDK/Foundation/Library/EfiCommonLib/EfiCopyMem.c new file mode 100644 index 0000000..6028b19 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/EfiCopyMem.c @@ -0,0 +1,69 @@ +/*++ + +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: + + EfiCopyMem.c + +Abstract: + + Implementation of the EfiCopyMem routine. This function is broken + out into its own source file so that it can be excluded from a + build for a particular platform easily if an optimized version + is desired. + +--*/ + +#include "Tiano.h" + +VOID +EfiCommonLibCopyMem ( + IN VOID *Destination, + IN VOID *Source, + IN UINTN Length + ) +/*++ + +Routine Description: + + Copy Length bytes from Source to Destination. + +Arguments: + + Destination - Target of copy + + Source - Place to copy from + + Length - Number of bytes to copy + +Returns: + + None + +--*/ +{ + CHAR8 *Destination8; + CHAR8 *Source8; + + if (Source < Destination) { + Destination8 = (CHAR8 *) Destination + Length - 1; + Source8 = (CHAR8 *) Source + Length - 1; + while (Length--) { + *(Destination8--) = *(Source8--); + } + } else { + Destination8 = (CHAR8 *) Destination; + Source8 = (CHAR8 *) Source; + while (Length--) { + *(Destination8++) = *(Source8++); + } + } +} diff --git a/EDK/Foundation/Library/EfiCommonLib/EfiSetMem.c b/EDK/Foundation/Library/EfiCommonLib/EfiSetMem.c new file mode 100644 index 0000000..058ebeb --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/EfiSetMem.c @@ -0,0 +1,65 @@ +/*++ + +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: + + EfiSetMem.c + +Abstract: + + Implementation of the EfiSetMem routine. This function is broken + out into its own source file so that it can be excluded from a + build for a particular platform easily if an optimized version + is desired. + +--*/ + +#include "Tiano.h" +#include "EfiCommonLib.h" + + +VOID +EfiCommonLibSetMem ( + IN VOID *Buffer, + IN UINTN Size, + IN UINT8 Value + ) +/*++ + +Routine Description: + + Set Buffer to Value for Size bytes. + +Arguments: + + Buffer - Memory to set. + + Size - Number of bytes to set + + Value - Value of the set operation. + +Returns: + + None + +--*/ +{ + INT8 *Ptr; + + if (Value == 0) { + EfiCommonLibZeroMem (Buffer, Size); + } else { + Ptr = Buffer; + while (Size--) { + *(Ptr++) = Value; + } + } +} diff --git a/EDK/Foundation/Library/EfiCommonLib/EfiZeroMem.c b/EDK/Foundation/Library/EfiCommonLib/EfiZeroMem.c new file mode 100644 index 0000000..d6e50db --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/EfiZeroMem.c @@ -0,0 +1,57 @@ +/*++ + +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: + + EfiZeroMem.c + +Abstract: + + Implementation of the EfiSetMem routine. This function is broken + out into its own source file so that it can be excluded from a + build for a particular platform easily if an optimized version + is desired. + +--*/ + +#include "Tiano.h" + + +VOID +EfiCommonLibZeroMem ( + IN VOID *Buffer, + IN UINTN Size + ) +/*++ + +Routine Description: + + Set Buffer to 0 for Size bytes. + +Arguments: + + Buffer - Memory to set. + + Size - Number of bytes to set + +Returns: + + None + +--*/ +{ + INT8 *Ptr; + + Ptr = Buffer; + while (Size--) { + *(Ptr++) = 0; + } +} diff --git a/EDK/Foundation/Library/EfiCommonLib/Ia32/DivU64x32.asm b/EDK/Foundation/Library/EfiCommonLib/Ia32/DivU64x32.asm new file mode 100644 index 0000000..5fc399f --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Ia32/DivU64x32.asm @@ -0,0 +1,99 @@ + TITLE DivU64x32.asm: 64-bit division function for IA-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: +; +; DivU64x32.asm +; +; Abstract: +; +; 64-bit division function for IA-32 +; +;------------------------------------------------------------------------------ + + .686P + .XMM + .MODEL SMALL + .CODE + +DivU64x32 PROTO C Dividend: QWORD, Divisor: DWORD, Remainder: DWORD + +DivU64x32 PROC C Dividend: QWORD, Divisor: DWORD, Remainder: DWORD + +;------------------------------------------------------------------------------ +; UINT64 +; DivU64x32 ( +; IN UINT64 Dividend, +; IN UINTN Divisor, +; OUT UINTN *Remainder OPTIONAL +; ) +; +; Routine Description: +; +; This routine allows a 64 bit value to be divided with a 32 bit value returns +; 64bit result and the Remainder. +; +; Arguments: +; +; Dividend - dividend +; Divisor - divisor +; Remainder - buffer for remainder +; +; Returns: +; +; Dividend / Divisor +; Remainder = Dividend mod Divisor +; +; N.B. only works for 31bit divisors!! +;------------------------------------------------------------------------------ + + push ecx + ; + ; let edx contain the intermediate result of remainder + ; + xor edx, edx + mov ecx, 64 + +_DivU64x32_Wend: + shl dword ptr Dividend[0], 1 + rcl dword ptr Dividend[4], 1 + rcl edx, 1 + + ; + ; If intermediate result of remainder is larger than + ; or equal to divisor, then set the lowest bit of dividend, + ; and subtract divisor from intermediate remainder + ; + cmp edx, Divisor + jb _DivU64x32_Cont + bts dword ptr Dividend[0], 0 + sub edx, Divisor + +_DivU64x32_Cont: + loop _DivU64x32_Wend + + cmp Remainder, 0 + je _DivU64x32_Done + mov eax, Remainder + mov dword ptr [eax], edx + +_DivU64x32_Done: + mov eax, dword ptr Dividend[0] + mov edx, dword ptr Dividend[4] + pop ecx + ret + +DivU64x32 ENDP + + +END diff --git a/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMem.asm b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMem.asm new file mode 100644 index 0000000..504c08a --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMem.asm @@ -0,0 +1,183 @@ + TITLE EfiCopyMem.asm: Optimized memory-copy routine + +;------------------------------------------------------------------------------ +; +; 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: +; +; EfiCopyMem.asm +; +; Abstract: +; +; This is the code that supports IA32-optimized CopyMem service +; +;------------------------------------------------------------------------------ + +; PROC:PRIVATE + .686P + .MMX + .MODEL SMALL + .CODE + +EfiCommonLibCopyMem PROTO C Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD + +;------------------------------------------------------------------------------ +; VOID +; EfiCommonLibCopyMem ( +; IN VOID *Destination, +; IN VOID *Source, +; IN UINTN Count +; ) +;------------------------------------------------------------------------------ + +EfiCommonLibCopyMem PROC C Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD + LOCAL MmxSave:QWORD + + ; Put source and destination pointers in esi/edi + push esi + push edi + mov ecx, Count + mov esi, Source + mov edi, Destination + + ; First off, make sure we have no overlap. That is to say, + ; if (Source == Destination) => do nothing + ; if (Source + Count <= Destination) => regular copy + ; if (Destination + Count <= Source) => regular copy + ; otherwise, do a reverse copy + mov eax, esi + add eax, ecx ; Source + Count + cmp eax, edi + jbe _StartByteCopy + + mov eax, edi + add eax, ecx ; Dest + Count + cmp eax, esi + jbe _StartByteCopy + + cmp esi, edi + je _CopyMemDone + jb _CopyOverlapped ; too bad -- overlaps + + ; Pick up misaligned start bytes to get destination pointer 4-byte aligned +_StartByteCopy: + cmp ecx, 0 + je _CopyMemDone ; Count == 0, all done + mov edx, edi + and dl, 3 ; check lower 2 bits of address + test dl, dl + je SHORT _CopyBlocks ; already aligned? + + ; Copy a byte + mov al, BYTE PTR [esi] ; get byte from Source + mov BYTE PTR [edi], al ; write byte to Destination + dec ecx + inc edi + inc esi + jmp _StartByteCopy ; back to top of loop + +_CopyBlocks: + ; Compute how many 64-byte blocks we can clear + mov eax, ecx ; get Count in eax + shr eax, 6 ; convert to 64-byte count + shl eax, 6 ; convert back to bytes + sub ecx, eax ; subtract from the original count + shr eax, 6 ; and this is how many 64-byte blocks + + ; If no 64-byte blocks, then skip + cmp eax, 0 + je _CopyRemainingDWords + + ; Save mm0 + movq MmxSave, mm0 + +copymmx: + + movq mm0, QWORD PTR ds:[esi] + movq QWORD PTR ds:[edi], mm0 + movq mm0, QWORD PTR ds:[esi+8] + movq QWORD PTR ds:[edi+8], mm0 + movq mm0, QWORD PTR ds:[esi+16] + movq QWORD PTR ds:[edi+16], mm0 + movq mm0, QWORD PTR ds:[esi+24] + movq QWORD PTR ds:[edi+24], mm0 + movq mm0, QWORD PTR ds:[esi+32] + movq QWORD PTR ds:[edi+32], mm0 + movq mm0, QWORD PTR ds:[esi+40] + movq QWORD PTR ds:[edi+40], mm0 + movq mm0, QWORD PTR ds:[esi+48] + movq QWORD PTR ds:[edi+48], mm0 + movq mm0, QWORD PTR ds:[esi+56] + movq QWORD PTR ds:[edi+56], mm0 + + add edi, 64 + add esi, 64 + dec eax + jnz copymmx + +; Restore mm0 + movq mm0, MmxSave + emms ; Exit MMX Instruction + + ; Copy as many DWORDS as possible +_CopyRemainingDWords: + cmp ecx, 4 + jb _CopyRemainingBytes + + mov eax, DWORD PTR [esi] ; get data from Source + mov DWORD PTR [edi], eax ; write byte to Destination + sub ecx, 4 ; decrement Count + add esi, 4 ; advance Source pointer + add edi, 4 ; advance Destination pointer + jmp _CopyRemainingDWords ; back to top + +_CopyRemainingBytes: + cmp ecx, 0 + je _CopyMemDone + mov al, BYTE PTR [esi] ; get byte from Source + mov BYTE PTR [edi], al ; write byte to Destination + dec ecx + inc esi + inc edi ; advance Destination pointer + jmp SHORT _CopyRemainingBytes ; back to top of loop + + ; + ; We do this block if the source and destination buffers overlap. To + ; handle it, copy starting at the end of the source buffer and work + ; your way back. Since this is the atypical case, this code has not + ; been optimized, and thus simply copies bytes. + ; +_CopyOverlapped: + + ; Move the source and destination pointers to the end of the range + add esi, ecx ; Source + Count + dec esi + add edi, ecx ; Dest + Count + dec edi + +_CopyOverlappedLoop: + cmp ecx, 0 + je _CopyMemDone + mov al, BYTE PTR [esi] ; get byte from Source + mov BYTE PTR [edi], al ; write byte to Destination + dec ecx + dec esi + dec edi + jmp _CopyOverlappedLoop ; back to top of loop + +_CopyMemDone: + pop edi + pop esi + + ret + +EfiCommonLibCopyMem ENDP + END diff --git a/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMemSSE2.asm b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMemSSE2.asm new file mode 100644 index 0000000..d5000d0 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMemSSE2.asm @@ -0,0 +1,169 @@ + TITLE EfiCopyMem.asm: Optimized memory-copy routine + +;------------------------------------------------------------------------------ +; +; 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: +; +; EfiCopyMem.asm +; +; Abstract: +; +; This is the code that supports IA32-optimized CopyMem service +; +;------------------------------------------------------------------------------ + +; PROC:PRIVATE + .686P + .XMM + .MODEL SMALL + .CODE + +EfiCommonLibCopyMem PROTO C Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD + +;------------------------------------------------------------------------------ +; VOID +; EfiCommonLibCopyMem ( +; IN VOID *Destination, +; IN VOID *Source, +; IN UINTN Count +; ) +;------------------------------------------------------------------------------ + +EfiCommonLibCopyMem PROC C Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD + + ; Put source and destination pointers in esi/edi + push esi + push edi + mov ecx, Count + mov esi, Source + mov edi, Destination + + ; First off, make sure we have no overlap. That is to say, + ; if (Source == Destination) => do nothing + ; if (Source + Count <= Destination) => regular copy + ; if (Destination + Count <= Source) => regular copy + ; otherwise, do a reverse copy + mov eax, esi + add eax, ecx ; Source + Count + cmp eax, edi + jle _StartByteCopy + + mov eax, edi + add eax, ecx ; Dest + Count + cmp eax, esi + jle _StartByteCopy + + cmp esi, edi + je _CopyMemDone + jl _CopyOverlapped ; too bad -- overlaps + + ; Pick up misaligned start bytes to get destination pointer 4-byte aligned +_StartByteCopy: + cmp ecx, 0 + je _CopyMemDone ; Count == 0, all done + mov edx, edi + and dl, 3 ; check lower 2 bits of address + test dl, dl + je SHORT _CopyBlocks ; already aligned? + + ; Copy a byte + mov al, BYTE PTR [esi] ; get byte from Source + mov BYTE PTR [edi], al ; write byte to Destination + dec ecx + inc edi + inc esi + jmp _StartByteCopy ; back to top of loop + +_CopyBlocks: + ; Compute how many 64-byte blocks we can clear + mov eax, ecx ; get Count in eax + shr eax, 6 ; convert to 64-byte count + shl eax, 6 ; convert back to bytes + sub ecx, eax ; subtract from the original count + shr eax, 6 ; and this is how many 64-byte blocks + + ; If no 64-byte blocks, then skip + cmp eax, 0 + je _CopyRemainingDWords + + +copyxmm: + + movdqu xmm0, OWORD PTR ds:[esi] + movdqu OWORD PTR ds:[edi], xmm0 + movdqu xmm1, OWORD PTR ds:[esi+16] + movdqu OWORD PTR ds:[edi+16], xmm1 + movdqu xmm2, OWORD PTR ds:[esi+32] + movdqu OWORD PTR ds:[edi+32], xmm2 + movdqu xmm3, OWORD PTR ds:[esi+48] + movdqu OWORD PTR ds:[edi+48], xmm3 + + add edi, 64 + add esi, 64 + dec eax + jnz copyxmm + + + ; Copy as many DWORDS as possible +_CopyRemainingDWords: + cmp ecx, 4 + jb _CopyRemainingBytes + + mov eax, DWORD PTR [esi] ; get data from Source + mov DWORD PTR [edi], eax ; write byte to Destination + sub ecx, 4 ; decrement Count + add esi, 4 ; advance Source pointer + add edi, 4 ; advance Destination pointer + jmp _CopyRemainingDWords ; back to top + +_CopyRemainingBytes: + cmp ecx, 0 + je _CopyMemDone + mov al, BYTE PTR [esi] ; get byte from Source + mov BYTE PTR [edi], al ; write byte to Destination + dec ecx + inc esi + inc edi ; advance Destination pointer + jmp SHORT _CopyRemainingBytes ; back to top of loop + + ; + ; We do this block if the source and destination buffers overlap. To + ; handle it, copy starting at the end of the source buffer and work + ; your way back. Since this is the atypical case, this code has not + ; been optimized, and thus simply copies bytes. + ; +_CopyOverlapped: + + ; Move the source and destination pointers to the end of the range + add esi, ecx ; Source + Count + dec esi + add edi, ecx ; Dest + Count + dec edi + +_CopyOverlappedLoop: + cmp ecx, 0 + je _CopyMemDone + mov al, BYTE PTR [esi] ; get byte from Source + mov BYTE PTR [edi], al ; write byte to Destination + dec ecx + dec esi + dec edi + jmp _CopyOverlappedLoop ; back to top of loop + +_CopyMemDone: + pop edi + pop esi + + ret + +EfiCommonLibCopyMem ENDP + END diff --git a/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiSetMem.asm b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiSetMem.asm new file mode 100644 index 0000000..3b08c37 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiSetMem.asm @@ -0,0 +1,154 @@ + TITLE EfiSetMem.asm: Optimized setmemory routine + +;------------------------------------------------------------------------------ +; +; 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: +; +; EfiSetMem.asm +; +; Abstract: +; +; This is the code that supports IA32-optimized SetMem service +; +;------------------------------------------------------------------------------ + +; PROC:PRIVATE + .686P + .MMX + .MODEL SMALL + .CODE + +EfiCommonLibSetMem PROTO C Buffer:PTR DWORD, Count:DWORD, Value:BYTE + +;------------------------------------------------------------------------------ +; Procedure: EfiCommonLibSetMem +; +; VOID +; EfiCommonLibSetMem ( +; IN VOID *Buffer, +; IN UINTN Count, +; IN UINT8 Value +; ) +; +; Input: VOID *Buffer - Pointer to buffer to write +; UINTN Count - Number of bytes to write +; UINT8 Value - Value to write +; +; Output: None. +; +; Saves: +; +; Modifies: +; +; Description: This function is an optimized zero-memory function. +; +; Notes: This function tries to zero memory 8 bytes at a time. As a result, +; it first picks up any misaligned bytes, then words, before getting +; in the main loop that does the 8-byte clears. +; +;------------------------------------------------------------------------------ +EfiCommonLibSetMem PROC C Buffer:PTR DWORD, Count:DWORD, Value:BYTE + LOCAL QWordValue:QWORD + LOCAL MmxSave:QWORD + + + mov edx, Count + test edx, edx + je _SetMemDone + + push edi + push ebx + + mov eax, Buffer + mov bl, Value + mov edi, eax + mov bh, bl + + cmp edx, 256 + jb _SetRemindingByte + + and al, 07h + test al, al + je _SetBlock + + mov eax, edi + shr eax, 3 + inc eax + shl eax, 3 + sub eax, edi + cmp eax, edx + jnb _SetRemindingByte + + sub edx, eax + mov ecx, eax + + mov al, bl + rep stosb + +_SetBlock: + mov eax, edx + shr eax, 6 + test eax, eax + je _SetRemindingByte + + shl eax, 6 + sub edx, eax + shr eax, 6 + + mov WORD PTR QWordValue[0], bx + mov WORD PTR QWordValue[2], bx + mov WORD PTR QWordValue[4], bx + mov WORD PTR QWordValue[6], bx + + + movq MmxSave, mm0 + movq mm0, QWordValue + +@@: + movq QWORD PTR ds:[edi], mm0 + movq QWORD PTR ds:[edi+8], mm0 + movq QWORD PTR ds:[edi+16], mm0 + movq QWORD PTR ds:[edi+24], mm0 + movq QWORD PTR ds:[edi+32], mm0 + movq QWORD PTR ds:[edi+40], mm0 + movq QWORD PTR ds:[edi+48], mm0 + movq QWORD PTR ds:[edi+56], mm0 + add edi, 64 + dec eax + jnz @B + +; Restore mm0 + movq mm0, MmxSave + emms ; Exit MMX Instruction + +_SetRemindingByte: + mov ecx, edx + + mov eax, ebx + shl eax, 16 + mov ax, bx + shr ecx, 2 + rep stosd + + mov ecx, edx + and ecx, 3 + rep stosb + + pop ebx + pop edi + +_SetMemDone: + ret 0 + +EfiCommonLibSetMem ENDP + END + \ No newline at end of file diff --git a/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiSetMemSSE2.asm b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiSetMemSSE2.asm new file mode 100644 index 0000000..5d6652d --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiSetMemSSE2.asm @@ -0,0 +1,158 @@ + TITLE EfiSetMem.asm: Optimized setmemory routine + +;------------------------------------------------------------------------------ +; +; 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: +; +; EfiCommonLibSetMem.asm +; +; Abstract: +; +; This is the code that supports IA32-optimized SetMem service +; +;------------------------------------------------------------------------------ + +; PROC:PRIVATE + .686P + .MMX + .XMM + .MODEL SMALL + .CODE + +EfiCommonLibSetMem PROTO C Buffer:PTR DWORD, Count:DWORD, Value:BYTE + +;------------------------------------------------------------------------------ +; Procedure: EfiCommonLibSetMem +; +; VOID +; EfiCommonLibSetMem ( +; IN VOID *Buffer, +; IN UINTN Count, +; IN UINT8 Value +; ) +; +; Input: VOID *Buffer - Pointer to buffer to write +; UINTN Count - Number of bytes to write +; UINT8 Value - Value to write +; +; Output: None. +; +; Saves: +; +; Modifies: +; +; Description: This function is an optimized zero-memory function. +; +; Notes: This function tries to zero memory 8 bytes at a time. As a result, +; it first picks up any misaligned bytes, then words, before getting +; in the main loop that does the 8-byte clears. +; +;------------------------------------------------------------------------------ +EfiCommonLibSetMem PROC C Buffer:PTR DWORD, Count:DWORD, Value:BYTE + LOCAL QWordValue:QWORD + LOCAL MmxSave:QWORD + + + mov edx, Count + test edx, edx + je _SetMemDone + + push edi + push ebx + + mov eax, Buffer + mov bl, Value + mov edi, eax + mov bh, bl + + cmp edx, 256 + jb _SetRemindingByte + + and al, 0fh + test al, al + je _SetBlock + + mov eax, edi + shr eax, 4 + inc eax + shl eax, 4 + sub eax, edi + cmp eax, edx + jnb _SetRemindingByte + + sub edx, eax + mov ecx, eax + + mov al, bl + rep stosb + +_SetBlock: + mov eax, edx + shr eax, 7 + test eax, eax + je _SetRemindingByte + + shl eax, 7 + sub edx, eax + shr eax, 7 + + mov WORD PTR QWordValue[0], bx + mov WORD PTR QWordValue[2], bx + mov WORD PTR QWordValue[4], bx + mov WORD PTR QWordValue[6], bx + + + movq MmxSave, mm0 + movq mm0, QWordValue + + movq2dq xmm1, mm0 + pshufd xmm1, xmm1, 0 + +@@: + movdqa OWORD PTR ds:[edi], xmm1 + movdqa OWORD PTR ds:[edi+16], xmm1 + movdqa OWORD PTR ds:[edi+32], xmm1 + movdqa OWORD PTR ds:[edi+48], xmm1 + movdqa OWORD PTR ds:[edi+64], xmm1 + movdqa OWORD PTR ds:[edi+80], xmm1 + movdqa OWORD PTR ds:[edi+96], xmm1 + movdqa OWORD PTR ds:[edi+112], xmm1 + add edi, 128 + dec eax + jnz @B + +; Restore mm0 + movq mm0, MmxSave + emms ; Exit MMX Instruction + +_SetRemindingByte: + mov ecx, edx + + mov eax, ebx + shl eax, 16 + mov ax, bx + shr ecx, 2 + rep stosd + + mov ecx, edx + and ecx, 3 + rep stosb + + pop ebx + pop edi + +_SetMemDone: + ret 0 + +EfiCommonLibSetMem ENDP + END + \ No newline at end of file diff --git a/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.asm b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.asm new file mode 100644 index 0000000..7188e29 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.asm @@ -0,0 +1,138 @@ + TITLE EfiZeroMem.asm: Optimized memory-zero routine + +;------------------------------------------------------------------------------ +; +; 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: +; +; EfiZeroMem.asm +; +; Abstract: +; +; This is the code that supports IA32-optimized ZeroMem service +; +;------------------------------------------------------------------------------ + +; PROC:PRIVATE + .686P + .MMX + .MODEL SMALL + .CODE + +EfiCommonLibZeroMem PROTO C Buffer:PTR DWORD, Count:DWORD + +;------------------------------------------------------------------------------ +; Procedure: EfiCommonLibZeroMem +; +; VOID +; EfiCommonLibZeroMem ( +; IN VOID *Buffer, +; IN UINTN Count +; ) +; +; Input: VOID *Buffer - Pointer to buffer to clear +; UINTN Count - Number of bytes to clear +; +; Output: None. +; +; Saves: +; +; Modifies: +; +; Description: This function is an optimized zero-memory function. +; +; Notes: This function tries to zero memory 8 bytes at a time. As a result, +; it first picks up any misaligned bytes, then words, before getting +; in the main loop that does the 8-byte clears. +; +;------------------------------------------------------------------------------ +EfiCommonLibZeroMem PROC C Buffer:PTR DWORD, Count:DWORD + LOCAL MmxSave:QWORD + + ; Save edi, then put the buffer pointer into it. + push edi + mov ecx, Count + mov edi, Buffer + + ; Pick up misaligned start bytes (get pointer 4-byte aligned) +_StartByteZero: + mov eax, edi + and al, 3 ; check lower 2 bits of address + test al, al + je _ZeroBlocks ; already aligned? + cmp ecx, 0 + je _ZeroMemDone + + ; Clear the byte memory location + mov BYTE PTR [edi], 0 + inc edi + + ; Decrement our count + dec ecx + jmp _StartByteZero ; back to top of loop + +_ZeroBlocks: + + ; Compute how many 64-byte blocks we can clear + mov edx, ecx + shr ecx, 6 ; convert to 64-byte count + shl ecx, 6 ; convert back to bytes + sub edx, ecx ; subtract from the original count + shr ecx, 6 ; and this is how many 64-byte blocks + + ; If no 64-byte blocks, then skip + cmp ecx, 0 + je _ZeroRemaining + + ; Save mm0 + movq MmxSave, mm0 + + pxor mm0, mm0 ; Clear mm0 + +@@: + movq QWORD PTR ds:[edi], mm0 + movq QWORD PTR ds:[edi+8], mm0 + movq QWORD PTR ds:[edi+16], mm0 + movq QWORD PTR ds:[edi+24], mm0 + movq QWORD PTR ds:[edi+32], mm0 + movq QWORD PTR ds:[edi+40], mm0 + movq QWORD PTR ds:[edi+48], mm0 + movq QWORD PTR ds:[edi+56], mm0 + + add edi, 64 + dec ecx + jnz @B + +; Restore mm0 + movq mm0, MmxSave + emms ; Exit MMX Instruction + +_ZeroRemaining: + ; Zero out as many DWORDS as possible + mov ecx, edx + shr ecx, 2 + xor eax, eax + + rep stosd + + ; Zero out remaining as bytes + mov ecx, edx + and ecx, 03 + + rep stosb + +_ZeroMemDone: + pop edi + + ret + +EfiCommonLibZeroMem ENDP + END diff --git a/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMemSSE2.asm b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMemSSE2.asm new file mode 100644 index 0000000..a5efd4d --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMemSSE2.asm @@ -0,0 +1,127 @@ + TITLE EfiZeroMem.asm: Optimized memory-zero routine + +;------------------------------------------------------------------------------ +; +; 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: +; +; EfiZeroMem.asm +; +; Abstract: +; +; This is the code that supports IA32-optimized ZeroMem service +; +;------------------------------------------------------------------------------ + +; PROC:PRIVATE + .686P + .XMM + .MODEL SMALL + .CODE + +EfiCommonLibZeroMem PROTO C Buffer:PTR DWORD, Count:DWORD + +;------------------------------------------------------------------------------ +; Procedure: EfiCommonLibZeroMem +; +; VOID +; EfiCommonLibZeroMem ( +; IN VOID *Buffer, +; IN UINTN Count +; ) +; +; Input: VOID *Buffer - Pointer to buffer to clear +; UINTN Count - Number of bytes to clear +; +; Output: None. +; +; Saves: +; +; Modifies: +; +; Description: This function is an optimized zero-memory function. +; +; Notes: This function tries to zero memory 8 bytes at a time. As a result, +; it first picks up any misaligned bytes, then words, before getting +; in the main loop that does the 8-byte clears. +; +;------------------------------------------------------------------------------ +EfiCommonLibZeroMem PROC C Buffer:PTR DWORD, Count:DWORD + + ; Save edi, then put the buffer pointer into it. + push edi + mov ecx, Count + mov edi, Buffer + + ; Pick up misaligned start bytes (get pointer 4-byte aligned) +_StartByteZero: + mov eax, edi + and al, 3 ; check lower 2 bits of address + test al, al + je _ZeroBlocks ; already aligned? + cmp ecx, 0 + je _ZeroMemDone + + ; Clear the byte memory location + mov BYTE PTR [edi], 0 + inc edi + + ; Decrement our count + dec ecx + jmp _StartByteZero ; back to top of loop + +_ZeroBlocks: + + ; Compute how many 64-byte blocks we can clear + mov edx, ecx + shr ecx, 6 ; convert to 64-byte count + shl ecx, 6 ; convert back to bytes + sub edx, ecx ; subtract from the original count + shr ecx, 6 ; and this is how many 64-byte blocks + + ; If no 64-byte blocks, then skip + cmp ecx, 0 + je _ZeroRemaining + + xorps xmm1, xmm1 + +@@: + movdqu OWORD PTR ds:[edi], xmm1 + movdqu OWORD PTR ds:[edi+16], xmm1 + movdqu OWORD PTR ds:[edi+32], xmm1 + movdqu OWORD PTR ds:[edi+48], xmm1 + + add edi, 64 + dec ecx + jnz @B + + +_ZeroRemaining: + ; Zero out as many DWORDS as possible + mov ecx, edx + shr ecx, 2 + xor eax, eax + + rep stosd + + ; Zero out remaining as bytes + mov ecx, edx + and ecx, 03 + + rep stosb + +_ZeroMemDone: + pop edi + + ret + +EfiCommonLibZeroMem ENDP + END diff --git a/EDK/Foundation/Library/EfiCommonLib/Ia32/GetPowerOfTwo.asm b/EDK/Foundation/Library/EfiCommonLib/Ia32/GetPowerOfTwo.asm new file mode 100644 index 0000000..9f0d962 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Ia32/GetPowerOfTwo.asm @@ -0,0 +1,67 @@ + TITLE GetPowerOfTwo.asm: Calculates the power of two value just below input + +;------------------------------------------------------------------------------ +; +; 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: +; +; GetPowerOfTwo.asm +; +; Abstract: +; +; Calculates the largest integer that is both +; a power of two and less than Input +; +;------------------------------------------------------------------------------ + + .686P + .XMM + .MODEL SMALL + .CODE + +_GetPowerOfTwo PROC +;------------------------------------------------------------------------------ +; UINT32 +; _GetPowerOfTwo ( +; IN UINT32 Input +; ) +; +; Routine Description: +; +; Calculates the largest integer that is both +; a power of two and less than Input +; +; Arguments: +; +; Input - value to calculate power of two +; +; Returns: +; +; the largest integer that is both a power of +; two and less than Input +;------------------------------------------------------------------------------ + xor eax, eax + mov edx, eax + mov ecx, [esp + 8] + jecxz @F + bsr ecx, ecx + bts edx, ecx + jmp @Exit +@@: + mov ecx, [esp + 4] + jecxz @Exit + bsr ecx, ecx + bts eax, ecx +@Exit: + ret +_GetPowerOfTwo ENDP + +END diff --git a/EDK/Foundation/Library/EfiCommonLib/Ia32/LShiftU64.asm b/EDK/Foundation/Library/EfiCommonLib/Ia32/LShiftU64.asm new file mode 100644 index 0000000..de6d17e --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Ia32/LShiftU64.asm @@ -0,0 +1,86 @@ + TITLE LShiftU64.asm: 64-bit left shift function for IA-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: +; +; LShiftU64.asm +; +; Abstract: +; +; 64-bit left shift function for IA-32 +; +;------------------------------------------------------------------------------ + + .686P + .XMM + .MODEL SMALL + .CODE + +LShiftU64 PROTO C Operand: QWORD, Count: DWORD + +LShiftU64 PROC C Operand: QWORD, Count: DWORD + +;------------------------------------------------------------------------------ +; UINT64 +; LShiftU64 ( +; IN UINT64 Operand, +; IN UINTN Count +; ) +; +; Routine Description: +; +; This routine allows a 64 bit value to be left shifted by 32 bits and +; returns the shifted value. +; Count is valid up 63. (Only Bits 0-5 is valid for Count) +; +; Arguments: +; +; Operand - Value to be shifted +; Count - Number of times to shift left. +; +; Returns: +; +; Value shifted left identified by the Count. +;------------------------------------------------------------------------------ + + push ecx + + mov eax, dword ptr Operand[0] + mov edx, dword ptr Operand[4] + + ; + ; CL is valid from 0 - 31. shld will move EDX:EAX by CL times but EAX is not touched + ; For CL of 32 - 63, it will be shifted 0 - 31 so we will move eax to edx later. + ; + mov ecx, Count + and ecx, 63 + shld edx, eax, cl + shl eax, cl + + ; + ; Since Count is 32 - 63, eax will have been shifted by 0 - 31 + ; If shifted by 32 or more, set lower 32 bits to zero. + ; + cmp ecx, 32 + jc short _LShiftU64_Done + + mov edx, eax + xor eax, eax + +_LShiftU64_Done: + pop ecx + ret + +LShiftU64 ENDP + +END diff --git a/EDK/Foundation/Library/EfiCommonLib/Ia32/Log2.asm b/EDK/Foundation/Library/EfiCommonLib/Ia32/Log2.asm new file mode 100644 index 0000000..167086e --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Ia32/Log2.asm @@ -0,0 +1,87 @@ + TITLE Log2.asm: 64-bit integer logarithm function for IA-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: +; +; Log2.asm +; +; Abstract: +; +; 64-bit integer logarithm function for IA-32 +; +;------------------------------------------------------------------------------ + + .686P + .XMM + .MODEL SMALL + .CODE + +Log2 PROTO C Operand: QWORD + +Log2 PROC C Operand: QWORD + +;------------------------------------------------------------------------------ +; UINT8 +; Log2 ( +; IN UINT64 Operand +; ) +; +; Routine Description: +; +; Calculates and floors logarithms based on 2 +; +; Arguments: +; +; Operand - value to calculate logarithm +; +; Returns: +; +; The largest integer that is less than or equal +; to the logarithm of Operand based on 2 +;------------------------------------------------------------------------------ + + push ecx + + mov ecx, 64 + + cmp dword ptr Operand[0], 0 + jne _Log2_Wend + cmp dword ptr Operand[4], 0 + jne _Log2_Wend + mov cl, 0FFH + jmp _Log2_Done + +_Log2_Wend: + dec ecx + cmp ecx, 32 + jae _Log2_Higher + bt dword ptr Operand[0], ecx + jmp _Log2_Bit + +_Log2_Higher: + mov eax, ecx + sub eax, 32 + bt dword ptr Operand[4], eax + +_Log2_Bit: + jc _Log2_Done + jmp _Log2_Wend + +_Log2_Done: + mov al, cl + pop ecx + ret + +Log2 ENDP + +END diff --git a/EDK/Foundation/Library/EfiCommonLib/Ia32/MultU64x32.asm b/EDK/Foundation/Library/EfiCommonLib/Ia32/MultU64x32.asm new file mode 100644 index 0000000..351020e --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Ia32/MultU64x32.asm @@ -0,0 +1,74 @@ + TITLE MultU64x32.asm: 64-bit Multiplication function for IA-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: +; +; MultU64x32.asm +; +; Abstract: +; +; 64-bit Multiplication function for IA-32 +; +;------------------------------------------------------------------------------ + + .686P + .XMM + .MODEL SMALL, C + .CODE + +MultU64x32 PROTO C Multiplicand: QWORD, Multiplier: DWORD + +MultU64x32 PROC C Multiplicand: QWORD, Multiplier: DWORD + +;------------------------------------------------------------------------------ +; UINT64 +; MultU64x32 ( +; IN UINT64 Multiplicand, +; IN UINTN Multiplier +; ) +; +; Routine Description: +; +; This routine allows a 64 bit value to be multiplied with a 32 bit +; value returns 64bit result. +; No checking if the result is greater than 64bits +; +; Arguments: +; +; Multiplicand - multiplicand +; Multiplier - multiplier +; +; Returns: +; +; Multiplicand * Multiplier +;------------------------------------------------------------------------------ + + mov eax, dword ptr Multiplicand[0] + mul Multiplier + push eax + push edx + mov eax, dword ptr Multiplicand[4] + mul Multiplier + ; + ; The value in edx stored by second multiplication overflows + ; the output and should be discarded. So here we overwrite it + ; with the edx value of first multiplication. + ; + pop edx + add edx, eax + pop eax + ret + +MultU64x32 ENDP + +END diff --git a/EDK/Foundation/Library/EfiCommonLib/Ia32/Power10U64.asm b/EDK/Foundation/Library/EfiCommonLib/Ia32/Power10U64.asm new file mode 100644 index 0000000..0346e03 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Ia32/Power10U64.asm @@ -0,0 +1,72 @@ + TITLE Power10U64.asm: calculates Operand * 10 ^ Power + +;------------------------------------------------------------------------------ +; +; 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: +; +; Power10U64.asm +; +; Abstract: +; +; Calculates Operand * 10 ^ Power +; +;------------------------------------------------------------------------------ + + .686P + .XMM + .MODEL SMALL + .CODE + +Power10U64 PROTO C Operand: QWORD, Power: DWORD +MultU64x32 PROTO C Multiplicand: QWORD, Multiplier: DWORD + +Power10U64 PROC C Operand: QWORD, Power: DWORD + +;------------------------------------------------------------------------------ +; UINT64 +; Power10U64 ( +; IN UINT64 Operand, +; IN UINTN Power +; ) +; +; Routine Description: +; +; Raise 10 to the power of Power, and multiply the result with Operand +; +; Arguments: +; +; Operand - multiplicand +; Power - power +; +; Returns: +; +; Operand * 10 ^ Power +;------------------------------------------------------------------------------ + + push ecx + + mov ecx, Power + jcxz _Power10U64_Done + +_Power10U64_Wend: + invoke MultU64x32, Operand, 10 + mov dword ptr Operand[0], eax + mov dword ptr Operand[4], edx + loop _Power10U64_Wend + +_Power10U64_Done: + pop ecx + ret + +Power10U64 ENDP + +END diff --git a/EDK/Foundation/Library/EfiCommonLib/Ia32/RShiftU64.asm b/EDK/Foundation/Library/EfiCommonLib/Ia32/RShiftU64.asm new file mode 100644 index 0000000..de05d20 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Ia32/RShiftU64.asm @@ -0,0 +1,86 @@ + TITLE RShiftU64.asm: 64-bit right shift function for IA-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: +; +; RShiftU64.asm +; +; Abstract: +; +; 64-bit right shift function for IA-32 +; +;------------------------------------------------------------------------------ + + .686P + .XMM + .MODEL SMALL + .CODE + +RShiftU64 PROTO C Operand: QWORD, Count: DWORD + +RShiftU64 PROC C Operand: QWORD, Count: DWORD + +;------------------------------------------------------------------------------ +; UINT64 +; RShiftU64 ( +; IN UINT64 Operand, +; IN UINTN Count +; ) +; +; Routine Description: +; +; This routine allows a 64 bit value to be right shifted by 32 bits and returns the +; shifted value. +; Count is valid up 63. (Only Bits 0-5 is valid for Count) +; +; Arguments: +; +; Operand - Value to be shifted +; Count - Number of times to shift right. +; +; Returns: +; +; Value shifted right identified by the Count. +;------------------------------------------------------------------------------ + + push ecx + + mov eax, dword ptr Operand[0] + mov edx, dword ptr Operand[4] + + ; + ; CL is valid from 0 - 31. shld will move EDX:EAX by CL times but EDX is not touched + ; For CL of 32 - 63, it will be shifted 0 - 31 so we will move edx to eax later. + ; + mov ecx, Count + and ecx, 63 + shrd eax, edx, cl + shr edx, cl + + cmp ecx, 32 + jc short _RShiftU64_Done + + ; + ; Since Count is 32 - 63, edx will have been shifted by 0 - 31 + ; If shifted by 32 or more, set upper 32 bits to zero. + ; + mov eax, edx + xor edx, edx + +_RShiftU64_Done: + pop ecx + ret + +RShiftU64 ENDP + +END diff --git a/EDK/Foundation/Library/EfiCommonLib/Math.c b/EDK/Foundation/Library/EfiCommonLib/Math.c new file mode 100644 index 0000000..8767fa6 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Math.c @@ -0,0 +1,216 @@ +/*++ + +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: + + Math.c + +Abstract: + + Math worker functions. + +--*/ + +#include "Tiano.h" + +UINT64 +LShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +/*++ + +Routine Description: + + This routine allows a 64 bit value to be left shifted by 32 bits and + returns the shifted value. + Count is valid up 63. (Only Bits 0-5 is valid for Count) + +Arguments: + + Operand - Value to be shifted + Count - Number of times to shift left. + +Returns: + + Value shifted left identified by the Count. + +--*/ +{ + return Operand << Count; +} + +UINT64 +MultU64x32 ( + IN UINT64 Multiplicand, + IN UINTN Multiplier + ) +/*++ + +Routine Description: + + This routine allows a 64 bit value to be multiplied with a 32 bit + value returns 64bit result. + No checking if the result is greater than 64bits + +Arguments: + + Multiplicand - multiplicand + Multiplier - multiplier + +Returns: + + Multiplicand * Multiplier + +--*/ +{ + return Multiplicand * Multiplier; +} + +UINT64 +RShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +/*++ + +Routine Description: + + This routine allows a 64 bit value to be right shifted by 32 bits and returns the + shifted value. + Count is valid up 63. (Only Bits 0-5 is valid for Count) + +Arguments: + + Operand - Value to be shifted + Count - Number of times to shift right. + +Returns: + + Value shifted right identified by the Count. + +--*/ +{ + return Operand >> Count; +} + +UINT64 +DivU64x32 ( + IN UINT64 Dividend, + IN UINTN Divisor, + OUT UINTN *Remainder OPTIONAL + ) +/*++ + +Routine Description: + + This routine allows a 64 bit value to be divided with a 32 bit value returns + 64bit result and the Remainder. + +Arguments: + + Dividend - dividend + Divisor - divisor + Remainder - buffer for remainder + +Returns: + + Dividend / Divisor + Remainder = Dividend mod Divisor + +--*/ +{ + if (Remainder != NULL) { + *Remainder = Dividend % Divisor; + } + + return Dividend / Divisor; +} + +UINT8 +Log2 ( + IN UINT64 Operand + ) +/*++ + +Routine Description: + + This function computes rounded down log2 of the Operand. This is an equivalent + of the position of the highest bit set in the Operand treated as a mask. + E.g., Log2 (0x0001) == 0, Log2 (0x0002) == 1, Log2 (0x0003) == 1, Log2 (0x0005) == 2 + Log2 (0x4000) == 14, Log2 (0x8000) == 15, Log2 (0xC000) == 15, Log2 (0xFFFF) == 15, etc. + +Arguments: + Operand - value of which the Log2 is to be computed. + +Returns: + Rounded down log2 of the Operand or 0xFF if zero passed in. + +--*/ +{ + UINT8 Bitpos; + Bitpos = 0; + + if (Operand == 0) { + return (0xff); + } + + while (Operand != 0) { + Operand >>= 1; + Bitpos++; + } + return (Bitpos - 1); + +} + +UINT64 +GetPowerOfTwo ( + IN UINT64 Operand + ) +/*++ + +Routine Description: + + Calculates the largest integer that is both + a power of two and less than Input + +Arguments: + + Operand - value to calculate power of two + +Returns: + + the largest integer that is both a power of + two and less than Input + +--*/ +{ + UINT8 Bitpos; + Bitpos = 0; + + if (Operand == 0) { + return 0; + } + + while (Operand != 0) { + Operand >>= 1; + Bitpos++; + } + + Operand = 1; + Bitpos--; + while (Bitpos != 0) { + Operand <<= 1; + Bitpos--; + } + + return Operand; +} diff --git a/EDK/Foundation/Library/EfiCommonLib/Misc.c b/EDK/Foundation/Library/EfiCommonLib/Misc.c new file mode 100644 index 0000000..ef4fe58 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Misc.c @@ -0,0 +1,385 @@ +/*++ + +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: + + misc.c + +Abstract: + +--*/ + +#include "Tiano.h" +#include "pei.h" +#include "cpuio.h" +#include EFI_PPI_CONSUMER (PciCfg) //;;## ...AMI_OVERRIDE... Support PI1.x +#include EFI_PPI_CONSUMER (PciCfg2) //;;## ...AMI_OVERRIDE... Support PI1.x +#include EFI_PROTOCOL_CONSUMER (PciRootBridgeIo) + +// +// Modular variable used by common libiary in PEI phase +// +EFI_GUID mPeiCpuIoPpiGuid = PEI_CPU_IO_PPI_GUID; +#if (PI_SPECIFICATION_VERSION < 0x00010000) //;;## ...AMI_OVERRIDE... Support PI1.x +EFI_GUID mPeiPciCfgPpiGuid = PEI_PCI_CFG_PPI_GUID; +PEI_PCI_CFG_PPI *PciCfgPpi = NULL; +#else +EFI_GUID mPeiPciCfgPpiGuid = EFI_PEI_PCI_CFG2_PPI_GUID; +EFI_PEI_PCI_CFG2_PPI *PciCfgPpi = NULL; +#endif +EFI_PEI_SERVICES **mPeiServices = NULL; +PEI_CPU_IO_PPI *CpuIoPpi = NULL; + +// +// Modular variable used by common libiary in DXE phase +// +EFI_SYSTEM_TABLE *mST = NULL; +EFI_BOOT_SERVICES *mBS = NULL; +EFI_RUNTIME_SERVICES *mRT = NULL; + +EFI_STATUS +EfiInitializeCommonDriverLib ( + IN EFI_HANDLE ImageHandle, + IN VOID *SystemTable + ) +/*++ + +Routine Description: + + Initialize lib function calling phase: PEI or DXE + +Arguments: + + ImageHandle - The firmware allocated handle for the EFI image. + + SystemTable - A pointer to the EFI System Table. + +Returns: + + EFI_STATUS always returns EFI_SUCCESS + +--*/ +{ + mPeiServices = NULL; + CpuIoPpi = NULL; + PciCfgPpi = NULL; + + if (ImageHandle == NULL) { + // + // The function is called in PEI phase, use PEI interfaces + // + mPeiServices = (EFI_PEI_SERVICES **) SystemTable; + + ASSERT (mPeiServices != NULL); + + CpuIoPpi = (**mPeiServices).CpuIo; + PciCfgPpi = (**mPeiServices).PciCfg; + + } else { + // + // ImageHandle is not NULL. The function is called in DXE phase + // + mST = SystemTable; + ASSERT (mST != NULL); + + mBS = mST->BootServices; + mRT = mST->RuntimeServices; + ASSERT (mBS != NULL); + ASSERT (mRT != NULL); + + // + // Should be at EFI_D_INFO, but lets us know things are running + // + DEBUG ((EFI_D_INFO, "EfiInitializeCommonDriverLib: Started in DXE\n")); + return EFI_SUCCESS; + } + + return EFI_SUCCESS; +} + + +EFI_STATUS +EfiCommonIoWrite ( + IN UINT8 Width, + IN UINTN Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Io write operation. + +Arguments: + + Width - Width of write operation + Address - Start IO address to write + Count - Write count + Buffer - Buffer to write to the address + +Returns: + + Status code + +--*/ +{ + EFI_STATUS Status; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo; + + if (mPeiServices != NULL) { + // + // The function is called in PEI phase, use PEI interfaces + // + Status = CpuIoPpi->Io.Write ( + mPeiServices, + CpuIoPpi, + Width, + Address, + Count, + Buffer + ); + } else { + // + // The function is called in DXE phase + // + Status = mBS->LocateProtocol ( + &gEfiPciRootBridgeIoProtocolGuid, + NULL, + (VOID **) &RootBridgeIo + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = RootBridgeIo->Io.Write (RootBridgeIo, Width, Address, Count, Buffer); + } + + return Status; +} + + +EFI_STATUS +EfiCommonIoRead ( + IN UINT8 Width, + IN UINTN Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Io read operation. + +Arguments: + + Width - Width of read operation + Address - Start IO address to read + Count - Read count + Buffer - Buffer to store result + +Returns: + + Status code + +--*/ +{ + EFI_STATUS Status; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo; + + if (mPeiServices != NULL) { + // + // The function is called in PEI phase, use PEI interfaces + // + Status = CpuIoPpi->Io.Read ( + mPeiServices, + CpuIoPpi, + Width, + Address, + Count, + Buffer + ); + } else { + // + // The function is called in DXE phase + // + Status = mBS->LocateProtocol ( + &gEfiPciRootBridgeIoProtocolGuid, + NULL, + (VOID **) &RootBridgeIo + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = RootBridgeIo->Io.Read (RootBridgeIo, Width, Address, Count, Buffer); + } + + return Status; +} + + +EFI_STATUS +EfiCommonPciWrite ( + IN UINT8 Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Pci write operation + +Arguments: + + Width - Width of PCI write + Address - PCI address to write + Count - Write count + Buffer - Buffer to write to the address + +Returns: + + Status code + +--*/ +{ + EFI_STATUS Status; + UINTN Index; + UINT8 *Buffer8; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo; + + if (mPeiServices != NULL) { + // + // The function is called in PEI phase, use PEI interfaces + // + Buffer8 = Buffer; + for (Index = 0; Index < Count; Index++) { + Status = PciCfgPpi->Write ( + mPeiServices, + PciCfgPpi, + Width, + Address, + Buffer8 + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + Buffer8 += Width; + } + + } else { + // + // The function is called in DXE phase + // + Status = mBS->LocateProtocol ( + &gEfiPciRootBridgeIoProtocolGuid, + NULL, + (VOID **) &RootBridgeIo + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = RootBridgeIo->Pci.Write ( + RootBridgeIo, + Width, + Address, + Count, + Buffer + ); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EfiCommonPciRead ( + IN UINT8 Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Pci read operation + +Arguments: + + Width - Width of PCI read + Address - PCI address to read + Count - Read count + Buffer - Output buffer for the read + +Returns: + + Status code + +--*/ +{ + EFI_STATUS Status; + UINTN Index; + UINT8 *Buffer8; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo; + + if (mPeiServices != NULL) { + // + // The function is called in PEI phase, use PEI interfaces + // + Buffer8 = Buffer; + for (Index = 0; Index < Count; Index++) { + Status = PciCfgPpi->Read ( + mPeiServices, + PciCfgPpi, + Width, + Address, + Buffer8 + ); + + if (EFI_ERROR (Status)) { + return Status; + } +//*** AMI PORTING BEGIN ***// +// Buffer8 += Width; + Buffer8 += (UINTN)1 << Width; +//*** AMI PORTING END ***// + } + + } else { + // + // The function is called in DXE phase + // + Status = mBS->LocateProtocol ( + &gEfiPciRootBridgeIoProtocolGuid, + NULL, + (VOID **) &RootBridgeIo + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = RootBridgeIo->Pci.Read ( + RootBridgeIo, + Width, + Address, + Count, + Buffer + ); + } + + return EFI_SUCCESS; +} diff --git a/EDK/Foundation/Library/EfiCommonLib/PostCode.c b/EDK/Foundation/Library/EfiCommonLib/PostCode.c new file mode 100644 index 0000000..bf9c544 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/PostCode.c @@ -0,0 +1,62 @@ +/*++ + +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: + + PostCode.c + +Abstract: + + Worker functions for PostCode + +--*/ + +#include "TianoCommon.h" +#include "EfiCommonLib.h" + +BOOLEAN +CodeTypeToPostCode ( + IN EFI_STATUS_CODE_TYPE CodeType, + IN EFI_STATUS_CODE_VALUE Value, + OUT UINT8 *PostCode + ) +/*++ + +Routine Description: + + Convert code value to an 8 bit post code + +Arguments: + + CodeType - Code type + Value - Code value + PostCode - Post code as output + +Returns: + + TRUE - Successfully converted + + FALSE - Convertion failed + +--*/ +{ + // + // Convert Value to an 8 bit post code + // + if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) || + ((CodeType & EFI_STATUS_CODE_TYPE_MASK)== EFI_ERROR_CODE)) { + *PostCode = (UINT8) (((Value & EFI_STATUS_CODE_CLASS_MASK) >> 24) << 5); + *PostCode |= (UINT8) (((Value & EFI_STATUS_CODE_SUBCLASS_MASK) >> 16) & 0x1f); + return TRUE; + } + + return FALSE; +} diff --git a/EDK/Foundation/Library/EfiCommonLib/ReportStatusCode.c b/EDK/Foundation/Library/EfiCommonLib/ReportStatusCode.c new file mode 100644 index 0000000..8214d00 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/ReportStatusCode.c @@ -0,0 +1,333 @@ +/*++ + +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: + + ReportStatusCode.c + +Abstract: + + Worker functions for ReportStatusCode + +--*/ + +#include "TianoCommon.h" +#include "EfiCommonLib.h" +#include EFI_GUID_DEFINITION (StatusCodeCallerId) +#include EFI_GUID_DEFINITION (StatusCodeDataTypeId) + + +VOID * +EfiConstructStatusCodeData ( + IN UINT16 DataSize, + IN EFI_GUID *TypeGuid, + IN OUT EFI_STATUS_CODE_DATA *Data + ) +/*++ + +Routine Description: + + Construct stanader header for optional data passed into ReportStatusCode + +Arguments: + + DataSize - Size of optional data. Does not include EFI_STATUS_CODE_DATA header + TypeGuid - GUID to place in EFI_STATUS_CODE_DATA + Data - Buffer to use. + +Returns: + + Return pointer to Data buffer pointing past the end of EFI_STATUS_CODE_DATA + +--*/ +{ + Data->HeaderSize = sizeof (EFI_STATUS_CODE_DATA); + Data->Size = (UINT16)(DataSize - sizeof (EFI_STATUS_CODE_DATA)); + EfiCommonLibCopyMem (&Data->Type, TypeGuid, sizeof (EFI_GUID)); + + return (VOID *)(Data + 1); +} + +EFI_STATUS +EfiDebugVPrintWorker ( + IN UINTN ErrorLevel, + IN CHAR8 *Format, + IN VA_LIST Marker, + IN UINTN BufferSize, + IN OUT VOID *Buffer + ) +/*++ + +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 + + BufferSize - Size of Buffer. + + Buffer - Caller allocated buffer, contains ReportStatusCode extended data + +Returns: + + Status code + + EFI_BUFFER_TOO_SMALL - Format too big to fit in buffer + + EFI_SUCCESS - Successfully printed + +--*/ +{ + UINTN Index; + UINTN FormatStrLen; + UINT64 *Ptr; + EFI_DEBUG_INFO *EfiDebug; + + + // + // Build the type specific EFI_STATUS_CODE_DATA in order + // + + // + // Fill in EFI_STATUS_CODE_DATA to Buffer. + // + EfiDebug = (EFI_DEBUG_INFO *)EfiConstructStatusCodeData ( + (UINT16)BufferSize, + &gEfiStatusCodeDataTypeDebugGuid, + Buffer + ); + + // + // Then EFI_DEBUG_INFO + // + EfiDebug->ErrorLevel = (UINT32)ErrorLevel; + + // + // 256 byte mini Var Arg stack. That is followed by the format string. + // + for (Index = 0, Ptr = (UINT64 *)(EfiDebug + 1); Index < 12; Index++, Ptr++) { + *Ptr = VA_ARG (Marker, UINT64); + } + + // + // Place Ascii Format string at the end + // + FormatStrLen = EfiAsciiStrLen (Format) + 1; + if (FormatStrLen > EFI_STATUS_CODE_DATA_MAX_SIZE) { + // + // Format too big to fit in our buffer, so do nothing. + // + return EFI_BUFFER_TOO_SMALL; + } else { + EfiCommonLibCopyMem (Ptr, Format, FormatStrLen); + } + + return EFI_SUCCESS; +} + + + +EFI_STATUS +EfiDebugAssertWorker ( + IN CHAR8 *Filename, + IN INTN LineNumber, + IN CHAR8 *Description, + IN UINTN BufferSize, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Worker function for ASSERT (). If Error Logging hub is loaded log ASSERT + information. If Error Logging hub is not loaded DEADLOOP (). + + We use UINT64 buffers due to IPF alignment concerns. + +Arguments: + + Filename - File name of failing routine. + + LineNumber - Line number of failing ASSERT(). + + Description - Description, usually the assertion, + + BufferSize - Size of Buffer. + + Buffer - Caller allocated buffer, contains ReportStatusCode extendecd data + +Returns: + + Status code + + EFI_BUFFER_TOO_SMALL - Buffer not large enough + + EFI_SUCCESS - Function successfully done. + +--*/ +{ + EFI_DEBUG_ASSERT_DATA *AssertData; + UINTN TotalSize; + CHAR8 *EndOfStr; + + // + // Make sure it will all fit in the passed in buffer + // + TotalSize = sizeof (EFI_STATUS_CODE_DATA) + sizeof (EFI_DEBUG_ASSERT_DATA); + TotalSize += EfiAsciiStrLen (Filename) + EfiAsciiStrLen (Description); + if (TotalSize > BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + // + // Fill in EFI_STATUS_CODE_DATA + // + AssertData = (EFI_DEBUG_ASSERT_DATA *) + EfiConstructStatusCodeData ( + (UINT16)(TotalSize - sizeof (EFI_STATUS_CODE_DATA)), + &gEfiStatusCodeDataTypeAssertGuid, + Buffer + ); + + // + // Fill in EFI_DEBUG_ASSERT_DATA + // + AssertData->LineNumber = (UINT32)LineNumber; + + // + // Copy Ascii FileName including NULL. + // + EndOfStr = EfiAsciiStrCpy ((CHAR8 *)(AssertData + 1), Filename); + + // + // Copy Ascii Description + // + EfiAsciiStrCpy (EndOfStr, Description); + return EFI_SUCCESS; +} + + + +BOOLEAN +ReportStatusCodeExtractAssertInfo ( + IN EFI_STATUS_CODE_TYPE CodeType, + IN EFI_STATUS_CODE_VALUE Value, + IN EFI_STATUS_CODE_DATA *Data, + OUT CHAR8 **Filename, + OUT CHAR8 **Description, + OUT UINT32 *LineNumber + ) +/*++ + +Routine Description: + + Extract assert information from status code data. + +Arguments: + + CodeType - Code type + Value - Code value + Data - Optional data associated with this status code. + Filename - Filename extracted from Data + Description - Description extracted from Data + LineNumber - Line number extracted from Data + +Returns: + + TRUE - Successfully extracted + + FALSE - Extraction failed + +--*/ +{ + EFI_DEBUG_ASSERT_DATA *AssertData; + + if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) && + ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED)) { + // + // Assume if we have an uncontained unrecoverable error that the data hub + // may not work. So we will print out data here. If we had an IPMI controller, + // or error log we could wack the hardware here. + // + if ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE && (Data != NULL)) { + // + // ASSERT (Expresion) - + // ExtendedData == FileName + // Instance == Line Nuber + // NULL == String of Expresion + // + AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1); + *Filename = (CHAR8 *)(AssertData + 1); + *Description = *Filename + EfiAsciiStrLen (*Filename) + 1; + *LineNumber = AssertData->LineNumber; + return TRUE; + } + } + return FALSE; +} + + +BOOLEAN +ReportStatusCodeExtractDebugInfo ( + IN EFI_STATUS_CODE_DATA *Data, + OUT UINT32 *ErrorLevel, + OUT VA_LIST *Marker, + OUT CHAR8 **Format + ) +/*++ + +Routine Description: + + Extract debug information from status code data. + +Arguments: + + Data - Optional data associated with status code. + ErrorLevel - Error level extracted from Data + Marker - VA_LIST extracted from Data + Format - Format string extracted from Data + +Returns: + + TRUE - Successfully extracted + + FALSE - Extraction failed + +--*/ +{ + EFI_DEBUG_INFO *DebugInfo; + + if ((Data == NULL) || (!EfiCompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid))) { + return FALSE; + } + + DebugInfo = (EFI_DEBUG_INFO *)(Data + 1); + + *ErrorLevel = DebugInfo->ErrorLevel; + + // + // The first 12 * UINTN bytes of the string are really an + // arguement stack to support varargs on the Format string. + // + *Marker = (VA_LIST) (DebugInfo + 1); + *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12); + + return TRUE; +} diff --git a/EDK/Foundation/Library/EfiCommonLib/String.c b/EDK/Foundation/Library/EfiCommonLib/String.c new file mode 100644 index 0000000..435bc66 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/String.c @@ -0,0 +1,802 @@ +/*++ + +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: + + String.c + +Abstract: + + Unicode string primatives + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" +#include "EfiCommonLib.h" + +VOID +EfiStrCpy ( + IN CHAR16 *Destination, + IN CHAR16 *Source + ) +/*++ + +Routine Description: + Copy the Unicode string Source to Destination. + +Arguments: + Destination - Location to copy string + Source - String to copy + +Returns: + NONE + +--*/ +{ + while (*Source) { + *(Destination++) = *(Source++); + } + *Destination = 0; +} + +VOID +EfiStrnCpy ( + OUT CHAR16 *Dst, + IN CHAR16 *Src, + IN UINTN Length + ) +/*++ + +Routine Description: + Copy a string from source to destination + +Arguments: + Dst Destination string + Src Source string + Length Length of destination string + +Returns: + +--*/ +{ + UINTN Index; + UINTN SrcLen; + + SrcLen = EfiStrLen (Src); + + Index = 0; + while (Index < Length && Index < SrcLen) { + Dst[Index] = Src[Index]; + Index++; + } + for (Index = SrcLen; Index < Length; Index++) { + Dst[Index] = 0; + } +} + +UINTN +EfiStrLen ( + IN CHAR16 *String + ) +/*++ + +Routine Description: + Return the number of Unicode characters in String. This is not the same as + the length of the string in bytes. + +Arguments: + String - String to process + +Returns: + Number of Unicode characters in String + +--*/ +{ + UINTN Length; + + for (Length=0; *String; String++, Length++); + return Length; +} + + +UINTN +EfiStrSize ( + IN CHAR16 *String + ) +/*++ + +Routine Description: + Return the number bytes in the Unicode String. This is not the same as + the length of the string in characters. The string size includes the NULL + +Arguments: + String - String to process + +Returns: + Number of bytes in String + +--*/ +{ + return ((EfiStrLen (String) + 1) * sizeof (CHAR16)); +} + + +INTN +EfiStrCmp ( + IN CHAR16 *String, + IN CHAR16 *String2 + ) +/*++ + +Routine Description: + Compare the Unicode string pointed by String to the string pointed by String2. + +Arguments: + String - String to process + + String2 - The other string to process + +Returns: + Return a positive integer if String is lexicall greater than String2; Zero if + the two strings are identical; and a negative interger if String is lexically + less than String2. + +--*/ +{ + while (*String) { + if (*String != *String2) { + break; + } + + String += 1; + String2 += 1; + } + + return *String - *String2; +} + +INTN +EfiStrnCmp ( + IN CHAR16 *String, + IN CHAR16 *String2, + IN UINTN Length + ) +/*++ + +Routine Description: + This function compares the Unicode string String to the Unicode + string String2 for len characters. If the first len characters + of String is identical to the first len characters of String2, + then 0 is returned. If substring of String sorts lexicographically + after String2, the function returns a number greater than 0. If + substring of String sorts lexicographically before String2, the + function returns a number less than 0. + +Arguments: + String - Compare to String2 + String2 - Compare to String + Length - Number of Unicode characters to compare + +Returns: + 0 - The substring of String and String2 is identical. + > 0 - The substring of String sorts lexicographically after String2 + < 0 - The substring of String sorts lexicographically before String2 + +--*/ +{ + while (*String && Length != 0) { + if (*String != *String2) { + break; + } + String += 1; + String2 += 1; + Length -= 1; + } + return Length > 0 ? *String - *String2 : 0; +} + +VOID +EfiStrCat ( + IN CHAR16 *Destination, + IN CHAR16 *Source + ) +/*++ + +Routine Description: + Concatinate Source on the end of Destination + +Arguments: + Destination - String to added to the end of. + Source - String to concatinate. + +Returns: + NONE + +--*/ +{ + EfiStrCpy (Destination + EfiStrLen (Destination), Source); +} + +VOID +EfiStrnCat ( + IN CHAR16 *Dest, + IN CHAR16 *Src, + IN UINTN Length + ) +/*++ + +Routine Description: + Concatinate Source on the end of Destination + +Arguments: + Dst Destination string + Src Source string + Length Length of destination string + +Returns: + +--*/ +{ + EfiStrnCpy (Dest + EfiStrLen (Dest), Src, Length); +} + +UINTN +EfiAsciiStrLen ( + IN CHAR8 *String + ) +/*++ + +Routine Description: + Return the number of Ascii characters in String. This is not the same as + the length of the string in bytes. + +Arguments: + String - String to process + +Returns: + Number of Ascii characters in String + +--*/ +{ + UINTN Length; + + for (Length=0; *String; String++, Length++); + return Length; +} + + +CHAR8 * +EfiAsciiStrCpy ( + IN CHAR8 *Destination, + IN CHAR8 *Source + ) +/*++ + +Routine Description: + Copy the Ascii string Source to Destination. + +Arguments: + Destination - Location to copy string + Source - String to copy + +Returns: + Pointer just pass the end of Destination + +--*/ +{ + while (*Source) { + *(Destination++) = *(Source++); + } + *Destination = 0; + return Destination + 1; +} + +VOID +EfiAsciiStrnCpy ( + OUT CHAR8 *Dst, + IN CHAR8 *Src, + IN UINTN Length + ) +/*++ + +Routine Description: + Copy the Ascii string from source to destination + +Arguments: + Dst Destination string + Src Source string + Length Length of destination string + +Returns: + +--*/ +{ + UINTN Index; + UINTN SrcLen; + + SrcLen = EfiAsciiStrLen (Src); + + Index = 0; + while (Index < Length && Index < SrcLen) { + Dst[Index] = Src[Index]; + Index++; + } + for (Index = SrcLen; Index < Length; Index++) { + Dst[Index] = 0; + } +} + +UINTN +EfiAsciiStrSize ( + IN CHAR8 *String + ) +/*++ + +Routine Description: + Return the number bytes in the Ascii String. This is not the same as + the length of the string in characters. The string size includes the NULL + +Arguments: + String - String to process + +Returns: + Number of bytes in String + +--*/ +{ + return (EfiAsciiStrLen (String) + 1); +} + + +INTN +EfiAsciiStrCmp ( + IN CHAR8 *String, + IN CHAR8 *String2 + ) +/*++ + +Routine Description: + Compare the Ascii string pointed by String to the string pointed by String2. + +Arguments: + String - String to process + + String2 - The other string to process + +Returns: + Return a positive integer if String is lexicall greater than String2; Zero if + the two strings are identical; and a negative interger if String is lexically + less than String2. +--*/ +{ + while (*String) { + if (*String != *String2) { + break; + } + + String += 1; + String2 += 1; + } + + return *String - *String2; +} + +INTN +EfiAsciiStrnCmp ( + IN CHAR8 *String, + IN CHAR8 *String2, + IN UINTN Length + ) +{ + if (Length == 0) { + return 0; + } + + while ((*String != '\0') && + (*String == *String2) && + (Length > 1)) { + String++; + String2++; + Length--; + } + return *String - *String2; +} + +VOID +EfiAsciiStrCat ( + IN CHAR8 *Destination, + IN CHAR8 *Source + ) +/*++ + +Routine Description: + Concatinate Source on the end of Destination + +Arguments: + Destination - String to added to the end of. + Source - String to concatinate. + +Returns: + NONE + +--*/ +{ + EfiAsciiStrCpy (Destination + EfiAsciiStrLen (Destination), Source); +} + +VOID +EfiAsciiStrnCat ( + IN CHAR8 *Destination, + IN CHAR8 *Source, + IN UINTN Length + ) +/*++ + +Routine Description: + Concatinate Source on the end of Destination + +Arguments: + Destination - String to added to the end of. + Source - String to concatinate. + +Returns: + NONE + +--*/ +{ + EfiAsciiStrnCpy (Destination + EfiAsciiStrLen (Destination), Source, Length); +} + +BOOLEAN +IsHexDigit ( + OUT UINT8 *Digit, + IN CHAR16 Char + ) +/*++ + + Routine Description: + Determines if a Unicode character is a hexadecimal digit. + The test is case insensitive. + + Arguments: + Digit - Pointer to byte that receives the value of the hex character. + Char - Unicode character to test. + + Returns: + TRUE - If the character is a hexadecimal digit. + FALSE - Otherwise. + +--*/ +{ + if ((Char >= L'0') && (Char <= L'9')) { + *Digit = (UINT8) (Char - L'0'); + return TRUE; + } + + if ((Char >= L'A') && (Char <= L'F')) { + *Digit = (UINT8) (Char - L'A' + 0x0A); + return TRUE; + } + + if ((Char >= L'a') && (Char <= L'f')) { + *Digit = (UINT8) (Char - L'a' + 0x0A); + return TRUE; + } + + return FALSE; +} + +CHAR16 +NibbleToHexChar ( + IN UINT8 Nibble + ) +/*++ + + Routine Description: + Converts the low nibble of a byte to hex unicode character. + + Arguments: + Nibble - lower nibble of a byte. + + Returns: + Hex unicode character. + +--*/ +{ + Nibble &= 0x0F; + if (Nibble <= 0x9) { + return (CHAR16)(Nibble + L'0'); + } + + return (CHAR16)(Nibble - 0xA + L'A'); +} + +EFI_STATUS +HexStringToBuf ( + IN OUT UINT8 *Buf, + IN OUT UINTN *Len, + IN CHAR16 *Str, + OUT UINTN *ConvertedStrLen OPTIONAL + ) +/*++ + + Routine Description: + Converts Unicode string to binary buffer. + The conversion may be partial. + The first character in the string that is not hex digit stops the conversion. + At a minimum, any blob of data could be represented as a hex string. + + Arguments: + Buf - Pointer to buffer that receives the data. + Len - Length in bytes of the buffer to hold converted data. + If routine return with EFI_SUCCESS, containing length of converted data. + If routine return with EFI_BUFFER_TOO_SMALL, containg length of buffer desired. + Str - String to be converted from. + ConvertedStrLen - Length of the Hex String consumed. + + Returns: + EFI_SUCCESS: Routine Success. + EFI_BUFFER_TOO_SMALL: The buffer is too small to hold converted data. + EFI_ + +--*/ +{ + UINTN HexCnt; + UINTN Idx; + UINTN BufferLength; + UINT8 Digit; + UINT8 Byte; + + // + // Find out how many hex characters the string has. + // + for (Idx = 0, HexCnt = 0; IsHexDigit (&Digit, Str[Idx]); Idx++, HexCnt++); + + if (HexCnt == 0) { + *Len = 0; + return EFI_SUCCESS; + } + // + // Two Unicode characters make up 1 buffer byte. Round up. + // + BufferLength = (HexCnt + 1) / 2; + + // + // Test if buffer is passed enough. + // + if (BufferLength > (*Len)) { + *Len = BufferLength; + return EFI_BUFFER_TOO_SMALL; + } + + *Len = BufferLength; + + for (Idx = 0; Idx < HexCnt; Idx++) { + + IsHexDigit (&Digit, Str[HexCnt - 1 - Idx]); + + // + // For odd charaters, write the lower nibble for each buffer byte, + // and for even characters, the upper nibble. + // + if ((Idx & 1) == 0) { + Byte = Digit; + } else { + Byte = Buf[Idx / 2]; + Byte &= 0x0F; + Byte |= Digit << 4; + } + + Buf[Idx / 2] = Byte; + } + + if (ConvertedStrLen != NULL) { + *ConvertedStrLen = HexCnt; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +BufToHexString ( + IN OUT CHAR16 *Str, + IN OUT UINTN *HexStringBufferLength, + IN UINT8 *Buf, + IN UINTN Len + ) +/*++ + + Routine Description: + Converts binary buffer to Unicode string. + At a minimum, any blob of data could be represented as a hex string. + + Arguments: + Str - Pointer to the string. + HexStringBufferLength - Length in bytes of buffer to hold the hex string. Includes tailing '\0' character. + If routine return with EFI_SUCCESS, containing length of hex string buffer. + If routine return with EFI_BUFFER_TOO_SMALL, containg length of hex string buffer desired. + Buf - Buffer to be converted from. + Len - Length in bytes of the buffer to be converted. + + Returns: + EFI_SUCCESS: Routine success. + EFI_BUFFER_TOO_SMALL: The hex string buffer is too small. + +--*/ +{ + UINTN Idx; + UINT8 Byte; + UINTN StrLen; + + // + // Make sure string is either passed or allocate enough. + // It takes 2 Unicode characters (4 bytes) to represent 1 byte of the binary buffer. + // Plus the Unicode termination character. + // + StrLen = Len * 2; + if (StrLen > ((*HexStringBufferLength) - 1)) { + *HexStringBufferLength = StrLen + 1; + return EFI_BUFFER_TOO_SMALL; + } + + *HexStringBufferLength = StrLen + 1; + // + // Ends the string. + // + Str[StrLen] = L'\0'; + + for (Idx = 0; Idx < Len; Idx++) { + + Byte = Buf[Idx]; + Str[StrLen - 1 - Idx * 2] = NibbleToHexChar (Byte); + Str[StrLen - 2 - Idx * 2] = NibbleToHexChar ((UINT8)(Byte >> 4)); + } + + return EFI_SUCCESS; +} + +VOID +EfiStrTrim ( + IN OUT CHAR16 *str, + IN CHAR16 CharC + ) +/*++ + +Routine Description: + + Removes (trims) specified leading and trailing characters from a string. + +Arguments: + + str - Pointer to the null-terminated string to be trimmed. On return, + str will hold the trimmed string. + CharC - Character will be trimmed from str. + +Returns: + +--*/ +{ + CHAR16 *p1; + CHAR16 *p2; + + if (*str == 0) { + return; + } + + // + // Trim off the leading and trailing characters c + // + for (p1 = str; *p1 && *p1 == CharC; p1++) { + ; + } + + p2 = str; + if (p2 == p1) { + while (*p1) { + p2++; + p1++; + } + } else { + while (*p1) { + *p2 = *p1; + p1++; + p2++; + } + *p2 = 0; + } + + + for (p1 = str + EfiStrLen(str) - 1; p1 >= str && *p1 == CharC; p1--) { + ; + } + if (p1 != str + EfiStrLen(str) - 1) { + *(p1 + 1) = 0; + } +} +CHAR16* +EfiStrStr ( + IN CHAR16 *String, + IN CHAR16 *StrCharSet + ) +/*++ + +Routine Description: + + Find a substring. + +Arguments: + + String - Null-terminated string to search. + StrCharSet - Null-terminated string to search for. + +Returns: + The address of the first occurrence of the matching substring if successful, or NULL otherwise. +--*/ +{ + CHAR16 *Src; + CHAR16 *Sub; + + Src = String; + Sub = StrCharSet; + + while ((*String != L'\0') && (*StrCharSet != L'\0')) { + if (*String++ != *StrCharSet++) { + String = ++Src; + StrCharSet = Sub; + } + } + if (*StrCharSet == L'\0') { + return Src; + } else { + return NULL; + } +} + +CHAR8* +EfiAsciiStrStr ( + IN CHAR8 *String, + IN CHAR8 *StrCharSet + ) +/*++ + +Routine Description: + + Find a Ascii substring. + +Arguments: + + String - Null-terminated Ascii string to search. + StrCharSet - Null-terminated Ascii string to search for. + +Returns: + The address of the first occurrence of the matching Ascii substring if successful, or NULL otherwise. +--*/ +{ + CHAR8 *Src; + CHAR8 *Sub; + + Src = String; + Sub = StrCharSet; + + while ((*String != '\0') && (*StrCharSet != '\0')) { + if (*String++ != *StrCharSet++) { + String = ++Src; + StrCharSet = Sub; + } + } + if (*StrCharSet == '\0') { + return Src; + } else { + return NULL; + } +} + diff --git a/EDK/Foundation/Library/EfiCommonLib/ValueToString.c b/EDK/Foundation/Library/EfiCommonLib/ValueToString.c new file mode 100644 index 0000000..f31b0de --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/ValueToString.c @@ -0,0 +1,213 @@ +/*++ + +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: + + ValueToString.c + +Abstract: + + Routines changing value to Hex or Dec string + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" + +static CHAR16 mHexStr[] = { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', + L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F' }; + +UINTN +EfiValueToHexStr ( + IN OUT CHAR16 *Buffer, + IN UINT64 Value, + IN UINTN Flags, + IN UINTN Width + ) +/*++ + +Routine Description: + + VSPrint worker function that prints a Value as a hex number in Buffer + +Arguments: + + Buffer - Location to place ascii hex string of Value. + + Value - Hex value to convert to a string in Buffer. + + Flags - Flags to use in printing Hex string, see file header for details. + + Width - Width of hex value. + +Returns: + + Number of characters printed. + +--*/ +{ + CHAR16 TempBuffer[CHARACTER_NUMBER_FOR_VALUE]; + CHAR16 *TempStr; + CHAR16 Prefix; + CHAR16 *BufferPtr; + UINTN Count; + UINTN Index; + + TempStr = TempBuffer; + BufferPtr = Buffer; + + // + // Count starts at one since we will null terminate. Each iteration of the + // loop picks off one nibble. Oh yea TempStr ends up backwards + // + Count = 0; + + if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) { + Width = CHARACTER_NUMBER_FOR_VALUE - 1; + } + + do { + Index = ((UINTN)Value & 0xf); + *(TempStr++) = mHexStr[Index]; + Value = RShiftU64 (Value, 4); + Count++; + } while (Value != 0); + + if (Flags & PREFIX_ZERO) { + Prefix = '0'; + } else { + Prefix = ' '; + } + + Index = Count; + if (!(Flags & LEFT_JUSTIFY)) { + for (; Index < Width; Index++) { + *(TempStr++) = Prefix; + } + } + + // + // Reverse temp string into Buffer. + // + if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) { + TempStr = TempBuffer + Width; + } + Index = 0; + while (TempStr != TempBuffer) { + *(BufferPtr++) = *(--TempStr); + Index++; + } + + *BufferPtr = 0; + return Index; +} + + +UINTN +EfiValueToString ( + IN OUT CHAR16 *Buffer, + IN INT64 Value, + IN UINTN Flags, + IN UINTN Width + ) +/*++ + +Routine Description: + + VSPrint worker function that prints a Value as a decimal number in Buffer + +Arguments: + + Buffer - Location to place ascii decimal number string of Value. + + Value - Decimal value to convert to a string in Buffer. + + Flags - Flags to use in printing decimal string, see file header for details. + + Width - Width of hex value. + +Returns: + + Number of characters printed. + +--*/ +{ + CHAR16 TempBuffer[CHARACTER_NUMBER_FOR_VALUE]; + CHAR16 *TempStr; + CHAR16 *BufferPtr; + UINTN Count; + UINTN ValueCharNum; + UINTN Remainder; + CHAR16 Prefix; + UINTN Index; + BOOLEAN ValueIsNegative; + + TempStr = TempBuffer; + BufferPtr = Buffer; + Count = 0; + ValueCharNum = 0; + ValueIsNegative = FALSE; + + if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) { + Width = CHARACTER_NUMBER_FOR_VALUE - 1; + } + + if (Value < 0) { + Value = -Value; + ValueIsNegative = TRUE; + } + + do { + Value = (INT64)DivU64x32 ((UINT64)Value, 10, &Remainder); + *(TempStr++) = (CHAR16)(Remainder + '0'); + ValueCharNum++; + Count++; + if ((Flags & COMMA_TYPE) == COMMA_TYPE) { + if (ValueCharNum % 3 == 0 && Value != 0) { + *(TempStr++) = ','; + Count++; + } + } + } while (Value != 0); + + if (ValueIsNegative) { + *(TempStr++) = '-'; + Count++; + } + + if ((Flags & PREFIX_ZERO) && !ValueIsNegative) { + Prefix = '0'; + } else { + Prefix = ' '; + } + + Index = Count; + if (!(Flags & LEFT_JUSTIFY)) { + for (; Index < Width; Index++) { + *(TempStr++) = Prefix; + } + } + + // + // Reverse temp string into Buffer. + // + if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) { + TempStr = TempBuffer + Width; + } + Index = 0; + while (TempStr != TempBuffer) { + *(BufferPtr++) = *(--TempStr); + Index++; + } + + *BufferPtr = 0; + return Index; +} diff --git a/EDK/Foundation/Library/EfiCommonLib/linkedlist.c b/EDK/Foundation/Library/EfiCommonLib/linkedlist.c new file mode 100644 index 0000000..fcec55f --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/linkedlist.c @@ -0,0 +1,356 @@ +/*++ + +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: + + LinkedList.c + +Abstract: + + Linked List Library Functions + +--*/ + +#include "Tiano.h" +#include "EfiDriverLib.h" + + +VOID +InitializeListHead ( + EFI_LIST_ENTRY *List + ) +/*++ + +Routine Description: + + Initialize the head of the List. The caller must allocate the memory + for the EFI_LIST. This function must be called before the other linked + list macros can be used. + +Arguments: + + List - Pointer to list head to initialize + +Returns: + + None. + +--*/ + +{ + List->ForwardLink = List; + List->BackLink = List; +} + + +BOOLEAN +IsListEmpty ( + EFI_LIST_ENTRY *List + ) +/*++ + +Routine Description: + + Return TRUE is the list contains zero nodes. Otherzise return FALSE. + The list must have been initialized with InitializeListHead () before using + this function. + +Arguments: + + List - Pointer to list head to test + + +Returns: + + Return TRUE is the list contains zero nodes. Otherzise return FALSE. + +--*/ +{ + return (BOOLEAN)(List->ForwardLink == List); +} + + +VOID +RemoveEntryList ( + EFI_LIST_ENTRY *Entry + ) +/*++ + +Routine Description: + + Remove Node from the doubly linked list. It is the caller's responsibility + to free any memory used by the entry if needed. The list must have been + initialized with InitializeListHead () before using this function. + +Arguments: + + Entry - Element to remove from the list. + +Returns: + + None + +--*/ +{ + EFI_LIST_ENTRY *_ForwardLink; + EFI_LIST_ENTRY *_BackLink; + + _ForwardLink = Entry->ForwardLink; + _BackLink = Entry->BackLink; + _BackLink->ForwardLink = _ForwardLink; + _ForwardLink->BackLink = _BackLink; + + DEBUG_CODE ( + Entry->ForwardLink = (EFI_LIST_ENTRY *) EFI_BAD_POINTER; + Entry->BackLink = (EFI_LIST_ENTRY *) EFI_BAD_POINTER; + ) +} + + +VOID +InsertTailList ( + EFI_LIST_ENTRY *ListHead, + EFI_LIST_ENTRY *Entry + ) +/*++ + +Routine Description: + + Insert a Node into the end of a doubly linked list. The list must have + been initialized with InitializeListHead () before using this function. + +Arguments: + + ListHead - Head of doubly linked list + + Entry - Element to insert at the end of the list. + +Returns: + + None + +--*/ +{ + EFI_LIST_ENTRY *_ListHead; + EFI_LIST_ENTRY *_BackLink; + + _ListHead = ListHead; + _BackLink = _ListHead->BackLink; + Entry->ForwardLink = _ListHead; + Entry->BackLink = _BackLink; + _BackLink->ForwardLink = Entry; + _ListHead->BackLink = Entry; +} + + + +VOID +InsertHeadList ( + EFI_LIST_ENTRY *ListHead, + EFI_LIST_ENTRY *Entry + ) +/*++ + +Routine Description: + + Insert a Node into the start of a doubly linked list. The list must have + been initialized with InitializeListHead () before using this function. + +Arguments: + + ListHead - Head of doubly linked list + + Entry - Element to insert to beginning of list + +Returns: + + None + +--*/ +{ + EFI_LIST_ENTRY *_ListHead; + EFI_LIST_ENTRY *_ForwardLink; + + _ListHead = ListHead; + _ForwardLink = _ListHead->ForwardLink; + Entry->ForwardLink = _ForwardLink; + Entry->BackLink = _ListHead; + _ForwardLink->BackLink = Entry; + _ListHead->ForwardLink = Entry; +} + +VOID +SwapListEntries ( + EFI_LIST_ENTRY *Entry1, + EFI_LIST_ENTRY *Entry2 + ) +/*++ + +Routine Description: + + Swap the location of the two elements of a doubly linked list. Node2 + is placed in front of Node1. The list must have been initialized with + InitializeListHead () before using this function. + +Arguments: + + Entry1 - Element in the doubly linked list in front of Node2. + + Entry2 - Element in the doubly linked list behind Node1. + +Returns: + + None + +--*/ +{ + EFI_LIST_ENTRY *Entry1ForwardLink; + EFI_LIST_ENTRY *Entry1BackLink; + EFI_LIST_ENTRY *Entry2ForwardLink; + EFI_LIST_ENTRY *Entry2BackLink; + + Entry2ForwardLink = Entry2->ForwardLink; + Entry2BackLink = Entry2->BackLink; + Entry1ForwardLink = Entry1->ForwardLink; + Entry1BackLink = Entry1->BackLink; + Entry2BackLink->ForwardLink = Entry2ForwardLink; + Entry2ForwardLink->BackLink = Entry2BackLink; + Entry2->ForwardLink = Entry1; + Entry2->BackLink = Entry1BackLink; + Entry1BackLink->ForwardLink = Entry2; + Entry1->BackLink = Entry2; +} + + +EFI_LIST_ENTRY * +GetFirstNode ( + EFI_LIST_ENTRY *List + ) +/*++ + +Routine Description: + + Return the first node pointed to by the list head. The list must + have been initialized with InitializeListHead () before using this + function and must contain data. + +Arguments: + + List - The head of the doubly linked list. + +Returns: + + Pointer to the first node, if the list contains nodes. The list will + return a null value--that is, the value of List--when the list is empty. + See the description of IsNull for more information. + + +--*/ +{ + return List->ForwardLink; +} + + +EFI_LIST_ENTRY * +GetNextNode ( + EFI_LIST_ENTRY *List, + EFI_LIST_ENTRY *Node + ) +/*++ + +Routine Description: + + Returns the node following Node in the list. The list must + have been initialized with InitializeListHead () before using this + function and must contain data. + +Arguments: + + List - The head of the list. MUST NOT be the literal value NULL. + Node - The node in the list. This value MUST NOT be the literal value NULL. + See the description of IsNull for more information. + +Returns: + + Pointer to the next node, if one exists. Otherwise, returns a null value, + which is actually a pointer to List. + See the description of IsNull for more information. + +--*/ +{ + if (Node == List) { + return List; + } + return Node->ForwardLink; +} + + +BOOLEAN +IsNull ( + EFI_LIST_ENTRY *List, + EFI_LIST_ENTRY *Node + ) +/*++ + +Routine Description: + + Determines whether the given node is null. Note that Node is null + when its value is equal to the value of List. It is an error for + Node to be the literal value NULL [(VOID*)0x0]. + +Arguments: + + List - The head of the list. MUST NOT be the literal value NULL. + Node - The node to test. MUST NOT be the literal value NULL. See + the description above. + +Returns: + + Returns true if the node is null. + +--*/ +{ + return (BOOLEAN)(Node == List); +} + + +BOOLEAN +IsNodeAtEnd ( + EFI_LIST_ENTRY *List, + EFI_LIST_ENTRY *Node + ) +/*++ + +Routine Description: + + Determines whether the given node is at the end of the list. Used + to walk the list. The list must have been initialized with + InitializeListHead () before using this function and must contain + data. + +Arguments: + + List - The head of the list. MUST NOT be the literal value NULL. + Node - The node to test. MUST NOT be the literal value NULL. + See the description of IsNull for more information. + +Returns: + + Returns true if the list is the tail. + +--*/ +{ + if (IsNull (List, Node)) { + return FALSE; + } + return (BOOLEAN)(List->BackLink == Node); +} + diff --git a/EDK/Foundation/Library/EfiCommonLib/x64/EfiCopyMemRep4.asm b/EDK/Foundation/Library/EfiCommonLib/x64/EfiCopyMemRep4.asm new file mode 100644 index 0000000..62e377c --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/x64/EfiCopyMemRep4.asm @@ -0,0 +1,65 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 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: +; +; EfiCopyMemRep4.asm +; +; Abstract: +; +; CopyMem function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EfiCommonLibCopyMem ( +; OUT VOID *Destination, +; IN VOID *Source, +; IN UINTN Count +; ); +;------------------------------------------------------------------------------ +EfiCommonLibCopyMem PROC USES rsi rdi + cmp rdx, rcx ; if Source == Destination, do nothing + je @CopyMemDone + cmp r8, 0 ; if Count == 0, do nothing + je @CopyMemDone + mov rsi, rdx ; rsi <- Source + mov rdi, rcx ; rdi <- Destination + lea r9, [rsi + r8 - 1] ; r9 <- End of Source + cmp rsi, rdi + jae @F + cmp r9, rdi + jae @CopyBackward ; Copy backward if overlapped +@@: + mov rcx, r8 + and r8, 3 + shr rcx, 2 + rep movsd ; Copy as many Dwords as possible + jmp @CopyBytes +@CopyBackward: + mov rsi, r9 ; rsi <- End of Source + lea rdi, [rdi + r8 - 1] ; esi <- End of Destination + std ; set direction flag +@CopyBytes: + mov rcx, r8 + rep movsb ; Copy bytes backward + cld +@CopyMemDone: + ret +EfiCommonLibCopyMem ENDP + + END + -- cgit v1.2.3