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:
qwang12
2007-06-28 07:00:39 +00:00
parent 30d4a0c7ec
commit 3eb9473ea9
1433 changed files with 266617 additions and 0 deletions

View File

@@ -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]

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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++);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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
}
}

View File

@@ -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:
}
}

View File

@@ -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:
}
}

View File

@@ -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:
}
}

View File

@@ -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:
}
}

View File

@@ -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:
}
}

View File

@@ -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:
}
}

View File

@@ -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:
}
}

View File

@@ -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:
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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:
}
}

View File

@@ -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:
}
}

View 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;
}

View 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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View 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;
}
}

View File

@@ -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;
}

View 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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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