Add in the 1st version of ECP.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2832 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
#/*++
|
||||
#
|
||||
# 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:
|
||||
#
|
||||
# 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.c
|
||||
Ia32\EfiSetMem.c
|
||||
Ia32\EfiZeroMem.c
|
||||
Ia32\LShiftU64.c
|
||||
Ia32\RShiftU64.c
|
||||
Ia32\MultU64x32.c
|
||||
Ia32\DivU64x32.c
|
||||
Ia32\Power10U64.c
|
||||
Ia32\Log2.c
|
||||
Ia32\GetPowerOfTwo.c
|
||||
|
||||
[sources.ipf]
|
||||
EfiCopyMem.c
|
||||
EfiSetMem.c
|
||||
EfiZeroMem.c
|
||||
Math.c
|
||||
|
||||
[sources.ebc]
|
||||
EfiCopyMem.c
|
||||
EfiSetMem.c
|
||||
EfiZeroMem.c
|
||||
Math.c
|
||||
|
||||
[sources.x64]
|
||||
x64\EfiCopyMem.asm
|
||||
x64\EfiSetMem.asm
|
||||
x64\EfiZeroMem.asm
|
||||
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\Framework\Ppi\CpuIo
|
||||
$(EDK_SOURCE)\Foundation\Framework
|
||||
|
||||
[libraries.common]
|
||||
EdkFrameworkGuidLib
|
||||
|
||||
[nmake.common]
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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++);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
DivU64x32.c
|
||||
|
||||
Abstract:
|
||||
|
||||
64-bit division function for IA-32
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
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!!
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
xor edx, edx ; Clear EDX
|
||||
|
||||
mov eax, dword ptr Dividend[4] ; Put high 32 bits of 64-bit dividend in EAX
|
||||
mov ecx, Divisor ; Put 32 bits divisor in ECX
|
||||
div ecx ; Dividend Divisor Quoitent...Remainder
|
||||
; 0:EAX / ECX = EAX EDX
|
||||
|
||||
push eax ; Push quoitent in stack
|
||||
|
||||
mov eax, dword ptr Dividend[0] ; Put low 32 bits of 64-bit dividend in EAX
|
||||
div ecx ; Leave the REMAINDER in EDX as High 32-bit of new dividend
|
||||
; Dividend Divisor Quoitent...Remainder
|
||||
; EDX:EAX / ECX = EAX EDX
|
||||
|
||||
mov ecx, Remainder ; Put &REMAINDER to ecx
|
||||
|
||||
jecxz Label1 ; If ecx == 0, no remainder exist, return with quoitent in EDX directly
|
||||
mov dword ptr [ecx], edx ; Put EDX through REMAINDER pointer in ECX
|
||||
|
||||
Label1:
|
||||
pop edx ; Pop High 32-bit QUOITENT to EDX
|
||||
}
|
||||
}
|
@@ -0,0 +1,184 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
EfiCopyMem.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This is the code that supports IA32-optimized CopyMem service
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
VOID
|
||||
EfiCommonLibCopyMem (
|
||||
IN VOID *Destination,
|
||||
IN VOID *Source,
|
||||
IN UINTN Count
|
||||
)
|
||||
/*++
|
||||
|
||||
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
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT64 MmxSave;
|
||||
__asm {
|
||||
|
||||
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
|
||||
|
||||
; 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:
|
||||
}
|
||||
}
|
@@ -0,0 +1,169 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
EfiCopyMemSSE2.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This is the code that supports IA32-optimized CopyMem service
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
VOID
|
||||
EfiCommonLibCopyMem (
|
||||
IN VOID *Destination,
|
||||
IN VOID *Source,
|
||||
IN UINTN Count
|
||||
)
|
||||
/*++
|
||||
|
||||
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
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
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 QWORD PTR ds:[edi], xmm0
|
||||
movdqu xmm1, OWORD PTR ds:[esi+16]
|
||||
movdqu QWORD PTR ds:[edi+16], xmm1
|
||||
movdqu xmm2, OWORD PTR ds:[esi+32]
|
||||
movdqu QWORD PTR ds:[edi+32], xmm2
|
||||
movdqu xmm3, OWORD PTR ds:[esi+48]
|
||||
movdqu QWORD 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:
|
||||
}
|
||||
}
|
@@ -0,0 +1,139 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
EfiSetMem.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This is the code that supports IA32-optimized SetMem service
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
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 set-memory function.
|
||||
|
||||
Notes: This function tries to set 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.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT64 QWordValue;
|
||||
UINT64 MmxSave;
|
||||
__asm {
|
||||
mov edx, Count
|
||||
test edx, edx
|
||||
je _SetMemDone
|
||||
|
||||
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
|
||||
|
||||
_B:
|
||||
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
|
||||
|
||||
_SetMemDone:
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,141 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
EfiSetMemSSE2.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This is the code that supports IA32-optimized SetMem service
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
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 set-memory function.
|
||||
|
||||
Notes: This function tries to set 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.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT64 QWordValue;
|
||||
UINT64 MmxSave;
|
||||
__asm {
|
||||
mov edx, Count
|
||||
test edx, edx
|
||||
je _SetMemDone
|
||||
|
||||
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
|
||||
|
||||
_Loop:
|
||||
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 _Loop
|
||||
|
||||
; 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
|
||||
|
||||
_SetMemDone:
|
||||
}
|
||||
}
|
@@ -0,0 +1,122 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
EfiZeroMem.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This is the code that supports IA32-optimized ZeroMem service
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
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.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT64 MmxSave;
|
||||
__asm {
|
||||
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
|
||||
|
||||
_B:
|
||||
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:
|
||||
}
|
||||
}
|
@@ -0,0 +1,111 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
EfiZeroMemSSE2.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This is the code that supports IA32-optimized ZeroMem service
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
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.
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
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
|
||||
|
||||
_B:
|
||||
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:
|
||||
}
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
GetPowerOfTwo.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Calculates the largest integer that is both
|
||||
a power of two and less than Input
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
UINT64
|
||||
GetPowerOfTwo (
|
||||
IN UINT64 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
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
xor eax, eax
|
||||
mov edx, eax
|
||||
mov ecx, dword ptr Input[4]
|
||||
jecxz _F
|
||||
bsr ecx, ecx
|
||||
bts edx, ecx
|
||||
jmp _Exit
|
||||
_F:
|
||||
mov ecx, dword ptr Input[0]
|
||||
jecxz _Exit
|
||||
bsr ecx, ecx
|
||||
bts eax, ecx
|
||||
_Exit:
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
LShiftU64.c
|
||||
|
||||
Abstract:
|
||||
|
||||
64-bit left shift function for IA-32
|
||||
|
||||
--*/
|
||||
|
||||
#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.
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
|
||||
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:
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
Log2.c
|
||||
|
||||
Abstract:
|
||||
|
||||
64-bit integer logarithm function for IA-32
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
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
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
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
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
MultU64x32.c
|
||||
|
||||
Abstract:
|
||||
|
||||
64-bit Multiplication function for IA-32
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
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
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
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
|
||||
}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
Power10U64.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Calculates Operand * 10 ^ Power
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
UINT64
|
||||
MultU64x32 (
|
||||
IN UINT64 Multiplicand,
|
||||
IN UINTN Multiplier
|
||||
);
|
||||
|
||||
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
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
mov ecx, Power
|
||||
jcxz _Power10U64_Done
|
||||
|
||||
_Power10U64_Wend:
|
||||
push 10
|
||||
push dword ptr Operand[4]
|
||||
push dword ptr Operand[0]
|
||||
call MultU64x32
|
||||
mov dword ptr Operand[0], eax
|
||||
mov dword ptr Operand[4], edx
|
||||
loop _Power10U64_Wend
|
||||
|
||||
_Power10U64_Done:
|
||||
}
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
RShiftU64.c
|
||||
|
||||
Abstract:
|
||||
|
||||
64-bit right shift function for IA-32
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
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.
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
|
||||
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:
|
||||
}
|
||||
}
|
216
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Math.c
Normal file
216
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Math.c
Normal file
@@ -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;
|
||||
}
|
384
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Misc.c
Normal file
384
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Misc.c
Normal file
@@ -0,0 +1,384 @@
|
||||
/*++
|
||||
|
||||
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 "pcicfg.h"
|
||||
#include "pcicfg2.h"
|
||||
#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)
|
||||
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
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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.Read (
|
||||
RootBridgeIo,
|
||||
Width,
|
||||
Address,
|
||||
Count,
|
||||
Buffer
|
||||
);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -0,0 +1,338 @@
|
||||
/*++
|
||||
|
||||
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.
|
||||
|
||||
The Format string might be truncated to fit into the status code struture
|
||||
which has the max size of EFI_STATUS_CODE_DATA_MAX_SIZE.
|
||||
|
||||
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_SUCCESS - Successfully printed
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN Index;
|
||||
UINTN FormatStrLen;
|
||||
UINTN RemainingStrLen;
|
||||
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;
|
||||
|
||||
//
|
||||
// 12 * sizeof (UINT64) 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
|
||||
// Truncate it to fit into the status code structure
|
||||
//
|
||||
FormatStrLen = EfiAsciiStrLen (Format);
|
||||
RemainingStrLen = EFI_STATUS_CODE_DATA_MAX_SIZE
|
||||
- sizeof (EFI_STATUS_CODE_DATA)
|
||||
- sizeof (EFI_DEBUG_INFO)
|
||||
- 12 * sizeof (UINT64) - 1;
|
||||
if (FormatStrLen > RemainingStrLen) {
|
||||
FormatStrLen = RemainingStrLen;
|
||||
}
|
||||
EfiCommonLibCopyMem (Ptr, Format, FormatStrLen);
|
||||
*((CHAR8 *) Ptr + FormatStrLen) = '\0';
|
||||
|
||||
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;
|
||||
}
|
802
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/String.c
Normal file
802
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/String.c
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
356
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/linkedlist.c
Normal file
356
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/linkedlist.c
Normal file
@@ -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);
|
||||
}
|
||||
|
@@ -0,0 +1,74 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; 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:
|
||||
;
|
||||
; CopyMem.asm
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
; CopyMem function
|
||||
;
|
||||
; Notes:
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.code
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; VOID *
|
||||
; EFIAPI
|
||||
; 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
|
||||
mov rax, rdi ; rax <- Destination as return value
|
||||
jae @F
|
||||
cmp r9, rdi
|
||||
jae @CopyBackward ; Copy backward if overlapped
|
||||
@@:
|
||||
mov rcx, r8
|
||||
and r8, 7
|
||||
shr rcx, 3 ; rcx <- # of Qwords to copy
|
||||
jz @CopyBytes
|
||||
DB 49h, 0fh, 7eh, 0c2h ; movd r10, mm0 (Save mm0 in r10)
|
||||
@@:
|
||||
DB 0fh, 6fh, 06h ; movd mm0, [rsi]
|
||||
DB 48h, 0fh, 7eh, 07h ; movd [rdi], mm0
|
||||
add rsi, 8
|
||||
add rdi, 8
|
||||
loop @B
|
||||
DB 49h, 0fh, 6eh, 0c2h ; movd mm0, r10 (Restore mm0)
|
||||
jmp @CopyBytes
|
||||
@CopyBackward:
|
||||
mov rsi, r9 ; rsi <- End of Source
|
||||
lea rdi, [rdi + r8 - 1] ; rdi <- End of Destination
|
||||
std ; set direction flag
|
||||
@CopyBytes:
|
||||
mov rcx, r8
|
||||
rep movsb ; Copy bytes backward
|
||||
cld
|
||||
@CopyMemDone:
|
||||
ret
|
||||
EfiCommonLibCopyMem ENDP
|
||||
|
||||
END
|
@@ -0,0 +1,80 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; 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:
|
||||
;
|
||||
; CopyMem.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
|
||||
mov rax, rdi ; rax <- Destination as return value
|
||||
jae @F ; Copy forward if Source > Destination
|
||||
cmp r9, rdi ; Overlapped?
|
||||
jae @CopyBackward ; Copy backward if overlapped
|
||||
@@:
|
||||
xor rcx, rcx
|
||||
sub rcx, rdi ; rcx <- -rdi
|
||||
and rcx, 15 ; rcx + rsi should be 16 bytes aligned
|
||||
jz @F ; skip if rcx == 0
|
||||
cmp rcx, r8
|
||||
cmova rcx, r8
|
||||
sub r8, rcx
|
||||
rep movsb
|
||||
@@:
|
||||
mov rcx, r8
|
||||
and r8, 15
|
||||
shr rcx, 4 ; rcx <- # of DQwords to copy
|
||||
jz @CopyBytes
|
||||
@@:
|
||||
movdqu xmm0, [rsi] ; rsi may not be 16-byte aligned
|
||||
movdqa [rdi], xmm0 ; rdi should be 16-byte aligned
|
||||
add rsi, 16
|
||||
add rdi, 16
|
||||
loop @B
|
||||
jmp @CopyBytes ; copy remaining bytes
|
||||
@CopyBackward:
|
||||
mov rsi, r9 ; rsi <- Last byte of Source
|
||||
lea rdi, [rdi + r8 - 1] ; rdi <- Last byte of Destination
|
||||
std
|
||||
@CopyBytes:
|
||||
mov rcx, r8
|
||||
rep movsb
|
||||
cld
|
||||
@CopyMemDone:
|
||||
ret
|
||||
EfiCommonLibCopyMem ENDP
|
||||
|
||||
END
|
@@ -0,0 +1,60 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; 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:
|
||||
;
|
||||
; SetMem.asm
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
; SetMem function
|
||||
;
|
||||
; Notes:
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.code
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; VOID *
|
||||
; EFIAPI
|
||||
; EfiCommonLibSetMem (
|
||||
; OUT VOID *Buffer,
|
||||
; IN UINTN Size,
|
||||
; IN UINT8 Value
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
EfiCommonLibSetMem PROC USES rdi
|
||||
cmp rdx, 0 ; if Size == 0, do nothing
|
||||
je @SetDone
|
||||
mov rax, r8
|
||||
mov ah, al
|
||||
DB 48h, 0fh, 6eh, 0c0h ; movd mm0, rax
|
||||
mov r8, rcx
|
||||
mov rdi, r8 ; rdi <- Buffer
|
||||
mov rcx, rdx
|
||||
and edx, 7
|
||||
shr rcx, 3
|
||||
jz @SetBytes
|
||||
DB 0fh, 70h, 0C0h, 00h ; pshufw mm0, mm0, 0h
|
||||
@@:
|
||||
DB 48h, 0fh, 7eh, 07h ; movd [rdi], mm0
|
||||
add rdi, 8
|
||||
loop @B
|
||||
@SetBytes:
|
||||
mov ecx, edx
|
||||
rep stosb
|
||||
mov rax, r8
|
||||
@SetDone:
|
||||
ret
|
||||
EfiCommonLibSetMem ENDP
|
||||
|
||||
END
|
@@ -0,0 +1,67 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; 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:
|
||||
;
|
||||
; SetMem.asm
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
; SetMem function
|
||||
;
|
||||
; Notes:
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.code
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; VOID
|
||||
; EfiCommonLibSetMem (
|
||||
; OUT VOID *Buffer,
|
||||
; IN UINTN Size,
|
||||
; IN UINT8 Value
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
EfiCommonLibSetMem PROC USES rdi
|
||||
cmp rdx, 0 ; if Size == 0, do nothing
|
||||
je @SetDone
|
||||
mov rdi, rcx ; rdi <- Buffer
|
||||
mov al, r8b ; al <- Value
|
||||
xor rcx, rcx
|
||||
sub rcx, rdi
|
||||
and rcx, 15 ; rcx + rdi aligns on 16-byte boundary
|
||||
jz @F
|
||||
cmp rcx, rdx
|
||||
cmova rcx, rdx
|
||||
sub rdx, rcx
|
||||
rep stosb
|
||||
@@:
|
||||
mov rcx, rdx
|
||||
and rdx, 15
|
||||
shr rcx, 4
|
||||
jz @SetBytes
|
||||
mov ah, al ; ax <- Value repeats twice
|
||||
movd xmm0, eax ; xmm0[0..16] <- Value repeats twice
|
||||
pshuflw xmm0, xmm0, 0 ; xmm0[0..63] <- Value repeats 8 times
|
||||
movlhps xmm0, xmm0 ; xmm0 <- Value repeats 16 times
|
||||
@@:
|
||||
movdqa [rdi], xmm0 ; rdi should be 16-byte aligned
|
||||
add rdi, 16
|
||||
loop @B
|
||||
@SetBytes:
|
||||
mov ecx, edx ; high 32 bits of rcx are always zero
|
||||
rep stosb
|
||||
@SetDone:
|
||||
ret
|
||||
EfiCommonLibSetMem ENDP
|
||||
|
||||
END
|
@@ -0,0 +1,53 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; 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:
|
||||
;
|
||||
; ZeroMem.asm
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
; ZeroMem function
|
||||
;
|
||||
; Notes:
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.code
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; VOID *
|
||||
; EfiCommonLibZeroMem (
|
||||
; IN VOID *Buffer,
|
||||
; IN UINTN Size
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
EfiCommonLibZeroMem PROC USES rdi
|
||||
mov rdi, rcx
|
||||
mov rcx, rdx
|
||||
mov r8, rdi
|
||||
and edx, 7
|
||||
shr rcx, 3
|
||||
jz @ZeroBytes
|
||||
DB 0fh, 0efh, 0c0h ; pxor mm0, mm0
|
||||
@@:
|
||||
DB 48h, 0fh, 7eh, 07h ; movd [rdi], mm0
|
||||
add rdi, 8
|
||||
loop @B
|
||||
@ZeroBytes:
|
||||
xor eax, eax
|
||||
mov ecx, edx
|
||||
rep stosb
|
||||
mov rax, r8
|
||||
ret
|
||||
EfiCommonLibZeroMem ENDP
|
||||
|
||||
END
|
@@ -0,0 +1,60 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; 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:
|
||||
;
|
||||
; ZeroMem.asm
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
; ZeroMem function
|
||||
;
|
||||
; Notes:
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.code
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; VOID
|
||||
; EfiCommonLibZeroMem (
|
||||
; IN VOID *Buffer,
|
||||
; IN UINTN Size
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
EfiCommonLibZeroMem PROC USES rdi
|
||||
mov rdi, rcx
|
||||
xor rcx, rcx
|
||||
xor eax, eax
|
||||
sub rcx, rdi
|
||||
and rcx, 15
|
||||
jz @F
|
||||
cmp rcx, rdx
|
||||
cmova rcx, rdx
|
||||
sub rdx, rcx
|
||||
rep stosb
|
||||
@@:
|
||||
mov rcx, rdx
|
||||
and edx, 15
|
||||
shr rcx, 4
|
||||
jz @ZeroBytes
|
||||
pxor xmm0, xmm0
|
||||
@@:
|
||||
movdqa [rdi], xmm0 ; rdi should be 16-byte aligned
|
||||
add rdi, 16
|
||||
loop @B
|
||||
@ZeroBytes:
|
||||
mov ecx, edx
|
||||
rep stosb
|
||||
ret
|
||||
EfiCommonLibZeroMem ENDP
|
||||
|
||||
END
|
Reference in New Issue
Block a user