[chore] Use gnu-efi as a part of project

This commit is contained in:
2026-05-29 19:06:37 +08:00
Unverified
parent 990c2a6295
commit d31cd01771
94 changed files with 22988 additions and 33 deletions
+173
View File
@@ -0,0 +1,173 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
BoxDraw.c
Abstract:
Lib functions to support Box Draw Unicode code pages.
Revision History
--*/
#include "lib.h"
typedef struct {
CHAR16 Unicode;
CHAR8 PcAnsi;
CHAR8 Ascii;
} UNICODE_TO_CHAR;
//
// This list is used to define the valid extend chars.
// It also provides a mapping from Unicode to PCANSI or
// ASCII. The ASCII mapping we just made up.
//
//
STATIC UNICODE_TO_CHAR UnicodeToPcAnsiOrAscii[] = {
{ BOXDRAW_HORIZONTAL, 0xc4, u'-'},
{ BOXDRAW_VERTICAL, 0xb3, u'|'},
{ BOXDRAW_DOWN_RIGHT, 0xda, u'/'},
{ BOXDRAW_DOWN_LEFT, 0xbf, u'\\'},
{ BOXDRAW_UP_RIGHT, 0xc0, u'\\'},
{ BOXDRAW_UP_LEFT, 0xd9, u'/'},
{ BOXDRAW_VERTICAL_RIGHT, 0xc3, u'|'},
{ BOXDRAW_VERTICAL_LEFT, 0xb4, u'|'},
{ BOXDRAW_DOWN_HORIZONTAL, 0xc2, u'+'},
{ BOXDRAW_UP_HORIZONTAL, 0xc1, u'+'},
{ BOXDRAW_VERTICAL_HORIZONTAL, 0xc5, u'+'},
{ BOXDRAW_DOUBLE_HORIZONTAL, 0xcd, u'-'},
{ BOXDRAW_DOUBLE_VERTICAL, 0xba, u'|'},
{ BOXDRAW_DOWN_RIGHT_DOUBLE, 0xd5, u'/'},
{ BOXDRAW_DOWN_DOUBLE_RIGHT, 0xd6, u'/'},
{ BOXDRAW_DOUBLE_DOWN_RIGHT, 0xc9, u'/'},
{ BOXDRAW_DOWN_LEFT_DOUBLE, 0xb8, u'\\'},
{ BOXDRAW_DOWN_DOUBLE_LEFT, 0xb7, u'\\'},
{ BOXDRAW_DOUBLE_DOWN_LEFT, 0xbb, u'\\'},
{ BOXDRAW_UP_RIGHT_DOUBLE, 0xd4, u'\\'},
{ BOXDRAW_UP_DOUBLE_RIGHT, 0xd3, u'\\'},
{ BOXDRAW_DOUBLE_UP_RIGHT, 0xc8, u'\\'},
{ BOXDRAW_UP_LEFT_DOUBLE, 0xbe, u'/'},
{ BOXDRAW_UP_DOUBLE_LEFT, 0xbd, u'/'},
{ BOXDRAW_DOUBLE_UP_LEFT, 0xbc, u'/'},
{ BOXDRAW_VERTICAL_RIGHT_DOUBLE, 0xc6, u'|'},
{ BOXDRAW_VERTICAL_DOUBLE_RIGHT, 0xc7, u'|'},
{ BOXDRAW_DOUBLE_VERTICAL_RIGHT, 0xcc, u'|'},
{ BOXDRAW_VERTICAL_LEFT_DOUBLE, 0xb5, u'|'},
{ BOXDRAW_VERTICAL_DOUBLE_LEFT, 0xb6, u'|'},
{ BOXDRAW_DOUBLE_VERTICAL_LEFT, 0xb9, u'|'},
{ BOXDRAW_DOWN_HORIZONTAL_DOUBLE, 0xd1, u'+'},
{ BOXDRAW_DOWN_DOUBLE_HORIZONTAL, 0xd2, u'+'},
{ BOXDRAW_DOUBLE_DOWN_HORIZONTAL, 0xcb, u'+'},
{ BOXDRAW_UP_HORIZONTAL_DOUBLE, 0xcf, u'+'},
{ BOXDRAW_UP_DOUBLE_HORIZONTAL, 0xd0, u'+'},
{ BOXDRAW_DOUBLE_UP_HORIZONTAL, 0xca, u'+'},
{ BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE, 0xd8, u'+'},
{ BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL, 0xd7, u'+'},
{ BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL, 0xce, u'+'},
{ BLOCKELEMENT_FULL_BLOCK, 0xdb, u'*'},
{ BLOCKELEMENT_LIGHT_SHADE, 0xb0, u'+'},
{ GEOMETRICSHAPE_UP_TRIANGLE, 0x1e, u'^'},
{ GEOMETRICSHAPE_RIGHT_TRIANGLE, 0x10, u'>'},
{ GEOMETRICSHAPE_DOWN_TRIANGLE, 0x1f, u'v'},
{ GEOMETRICSHAPE_LEFT_TRIANGLE, 0x11, u'<'},
/* BugBug: Left Arrow is an ESC. We can not make it print
on a PCANSI terminal. If we can make left arrow
come out on PC ANSI we can add it back.
{ ARROW_LEFT, 0x1b, u'<'},
*/
{ ARROW_UP, 0x18, u'^'},
/* BugBut: Took out left arrow so right has to go too.
{ ARROW_RIGHT, 0x1a, u'>'},
*/
{ ARROW_DOWN, 0x19, u'v'},
{ 0x0000, 0x00, u'\0' }
};
BOOLEAN
LibIsValidTextGraphics (
IN CHAR16 Graphic,
OUT CHAR8 *PcAnsi, OPTIONAL
OUT CHAR8 *Ascii OPTIONAL
)
/*++
Routine Description:
Detects if a Unicode char is for Box Drawing text graphics.
Arguments:
Grphic - Unicode char to test.
PcAnsi - Optional pointer to return PCANSI equivalent of Graphic.
Asci - Optional pointer to return Ascii equivalent of Graphic.
Returns:
TRUE if Gpaphic is a supported Unicode Box Drawing character.
--*/{
UNICODE_TO_CHAR *Table;
if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {
//
// Unicode drawing code charts are all in the 0x25xx range,
// arrows are 0x21xx
//
return FALSE;
}
for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {
if (Graphic == Table->Unicode) {
if (PcAnsi) {
*PcAnsi = Table->PcAnsi;
}
if (Ascii) {
*Ascii = Table->Ascii;
}
return TRUE;
}
}
return FALSE;
}
BOOLEAN
IsValidAscii (
IN CHAR16 Ascii
)
{
if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {
return TRUE;
}
return FALSE;
}
BOOLEAN
IsValidEfiCntlChar (
IN CHAR16 c
)
{
if (c == CHAR_NULL || c == CHAR_BACKSPACE || c == CHAR_LINEFEED || c == CHAR_CARRIAGE_RETURN) {
return TRUE;
}
return FALSE;
}
+119
View File
@@ -0,0 +1,119 @@
#include "lib.h"
#include "efiprot.h"
#include "efishell.h"
#include "efishellintf.h"
#ifndef MAX_ARGV_CONTENTS_SIZE
# define MAX_CMDLINE_SIZE 1024
#endif
#ifndef MAX_ARGC
# define MAX_CMDLINE_ARGC 32
#endif
/*
Parse LoadedImage options area, called only in case the regular
shell protos are not available.
Format of LoadedImage->LoadOptions appears to be a
single-space-separated list of args (looks like the shell already
pre-parses the input, it apparently folds several consecutive spaces
into one):
argv[0] space argv[1] (etc.) argv[N] space \0 cwd \0 other data
For safety, we support the trailing \0 without a space before, as
well as several consecutive spaces (-> several args).
*/
static
INTN
GetShellArgcArgvFromLoadedImage(
EFI_HANDLE ImageHandle,
CHAR16 **ResultArgv[]
)
{
EFI_STATUS Status;
void *LoadedImage = NULL;
static CHAR16 ArgvContents[MAX_CMDLINE_SIZE];
static CHAR16 *Argv[MAX_CMDLINE_ARGC], *ArgStart, *c;
UINTN Argc = 0, BufLen;
Status = uefi_call_wrapper(BS->OpenProtocol, 6,
ImageHandle,
&LoadedImageProtocol,
&LoadedImage,
ImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR(Status))
return -1;
BufLen = ((EFI_LOADED_IMAGE *)LoadedImage)->LoadOptionsSize;
if (BufLen < 2) /* We are expecting at least a \0 */
return -1;
else if (BufLen > sizeof(ArgvContents))
BufLen = sizeof(ArgvContents);
CopyMem(ArgvContents, ((EFI_LOADED_IMAGE *)LoadedImage)->LoadOptions, BufLen);
ArgvContents[MAX_CMDLINE_SIZE - 1] = u'\0';
for (c = ArgStart = ArgvContents ; *c != u'\0' ; ++c) {
if (*c == u' ') {
*c = u'\0';
if (Argc < MAX_CMDLINE_ARGC) Argv[Argc++] = ArgStart;
ArgStart = c + 1;
}
}
if ((*ArgStart != u'\0') && (Argc < MAX_CMDLINE_ARGC))
Argv[Argc++] = ArgStart;
// Print(u"Got argc/argv from loaded image proto\n");
*ResultArgv = Argv;
return Argc;
}
INTN GetShellArgcArgv(EFI_HANDLE ImageHandle, CHAR16 **Argv[])
{
// Code inspired from EDK2's
// ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.c (BSD)
EFI_STATUS Status;
static const EFI_GUID ShellInterfaceProtocolGuid
= SHELL_INTERFACE_PROTOCOL_GUID;
EFI_SHELL_PARAMETERS_PROTOCOL *EfiShellParametersProtocol = NULL;
EFI_SHELL_INTERFACE *EfiShellInterfaceProtocol = NULL;
Status = uefi_call_wrapper(BS->OpenProtocol, 6,
ImageHandle,
(EFI_GUID*)&ShellParametersProtocolGuid,
(VOID **)&EfiShellParametersProtocol,
ImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR(Status))
{
// use shell 2.0 interface
// Print(u"Got argc/argv from shell intf proto\n");
*Argv = EfiShellParametersProtocol->Argv;
return EfiShellParametersProtocol->Argc;
}
// try to get shell 1.0 interface instead.
Status = uefi_call_wrapper(BS->OpenProtocol, 6,
ImageHandle,
(EFI_GUID*)&ShellInterfaceProtocolGuid,
(VOID **)&EfiShellInterfaceProtocol,
ImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR(Status))
{
// Print(u"Got argc/argv from shell params proto\n");
*Argv = EfiShellInterfaceProtocol->Argv;
return EfiShellInterfaceProtocol->Argc;
}
// shell 1.0 and 2.0 interfaces failed
return GetShellArgcArgvFromLoadedImage(ImageHandle, Argv);
}
+104
View File
@@ -0,0 +1,104 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
console.c
Abstract:
Revision History
--*/
#include "lib.h"
VOID
Output (
IN CHAR16 *Str
)
// Write a string to the console at the current cursor location
{
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, Str);
}
VOID
Input (
IN CHAR16 *Prompt OPTIONAL,
OUT CHAR16 *InStr,
IN UINTN StrLen
)
// Input a string at the current cursor location, for StrLen
{
IInput (
ST->ConOut,
ST->ConIn,
Prompt,
InStr,
StrLen
);
}
VOID
IInput (
IN SIMPLE_TEXT_OUTPUT_INTERFACE *ConOut,
IN SIMPLE_INPUT_INTERFACE *ConIn,
IN CHAR16 *Prompt OPTIONAL,
OUT CHAR16 *InStr,
IN UINTN StrLen
)
// Input a string at the current cursor location, for StrLen
{
EFI_INPUT_KEY Key;
EFI_STATUS Status;
UINTN Len;
if (Prompt) {
ConOut->OutputString (ConOut, Prompt);
}
Len = 0;
for (; ;) {
WaitForSingleEvent (ConIn->WaitForKey, 0);
Status = uefi_call_wrapper(ConIn->ReadKeyStroke, 2, ConIn, &Key);
if (EFI_ERROR(Status)) {
DEBUG((D_ERROR, "Input: error return from ReadKey %x\n", Status));
break;
}
if (Key.UnicodeChar == '\n' ||
Key.UnicodeChar == '\r') {
break;
}
if (Key.UnicodeChar == '\b') {
if (Len) {
uefi_call_wrapper(ConOut->OutputString, 2, ConOut, u"\b \b");
Len -= 1;
}
continue;
}
if (Key.UnicodeChar >= ' ') {
if (Len < StrLen-1) {
InStr[Len] = Key.UnicodeChar;
InStr[Len+1] = 0;
uefi_call_wrapper(ConOut->OutputString, 2, ConOut, &InStr[Len]);
Len += 1;
}
continue;
}
}
InStr[Len] = 0;
}
+218
View File
@@ -0,0 +1,218 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
crc.c
Abstract:
CRC32 functions
Revision History
--*/
#include "lib.h"
UINT32 CRCTable[256] = {
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};
VOID
SetCrc (
IN OUT EFI_TABLE_HEADER *Hdr
)
/*++
Routine Description:
Updates the CRC32 value in the table header
Arguments:
Hdr - The table to update
Returns:
None
--*/
{
SetCrcAltSize (Hdr->HeaderSize, Hdr);
}
VOID
SetCrcAltSize (
IN UINTN Size,
IN OUT EFI_TABLE_HEADER *Hdr
)
/*++
Routine Description:
Updates the CRC32 value in the table header
Arguments:
Hdr - The table to update
Returns:
None
--*/
{
Hdr->CRC32 = 0;
Hdr->CRC32 = CalculateCrc((UINT8 *)Hdr, Size);
}
BOOLEAN
CheckCrc (
IN UINTN MaxSize,
IN OUT EFI_TABLE_HEADER *Hdr
)
/*++
Routine Description:
Checks the CRC32 value in the table header
Arguments:
Hdr - The table to check
Returns:
TRUE if the CRC is OK in the table
--*/
{
return CheckCrcAltSize (MaxSize, Hdr->HeaderSize, Hdr);
}
BOOLEAN
CheckCrcAltSize (
IN UINTN MaxSize,
IN UINTN Size,
IN OUT EFI_TABLE_HEADER *Hdr
)
/*++
Routine Description:
Checks the CRC32 value in the table header
Arguments:
Hdr - The table to check
Returns:
TRUE if the CRC is OK in the table
--*/
{
UINT32 Crc;
UINT32 OrgCrc;
BOOLEAN f;
if (Size == 0) {
//
// If header size is 0 CRC will pass so return FALSE here
//
return FALSE;
}
if (MaxSize && Size > MaxSize) {
DEBUG((D_ERROR, "CheckCrc32: Size > MaxSize\n"));
return FALSE;
}
// clear old crc from header
OrgCrc = Hdr->CRC32;
Hdr->CRC32 = 0;
Crc = CalculateCrc((UINT8 *)Hdr, Size);
// set restults
Hdr->CRC32 = OrgCrc;
// return status
f = OrgCrc == (UINT32) Crc;
if (!f) {
DEBUG((D_ERROR, "CheckCrc32: Crc check failed\n"));
}
return f;
}
UINT32
CalculateCrc (
UINT8 *pt,
UINTN Size
)
{
UINTN Crc;
// compute crc
Crc = 0xffffffff;
while (Size) {
Crc = (Crc >> 8) ^ CRCTable[(UINT8) Crc ^ *pt];
pt += 1;
Size -= 1;
}
Crc = Crc ^ 0xffffffff;
return (UINT32)Crc;
}
+55
View File
@@ -0,0 +1,55 @@
/*
* Try to define the minimal empty init/ctor/dtor/fini_arrays so building with
* older or out-of-tree linker scripts will still work.
*/
/*
* Note that these aren't using the GNU "CONSTRUCTOR" output section
* command, so they don't start with a size. Because of p2align and the
* end/END definitions, and the fact that they're mergeable, they can also
* have NULLs which aren't guaranteed to be at the end.
*/
#if defined(__ELF__)
.section .init_array,"aw",%init_array
#else
.section .init_array,"aw"
#endif
.p2align 4, 0
.globl __init_array_start
__init_array_start:
.globl __init_array_end
__init_array_end:
#if defined(__ELF__)
.section .ctors,"aw",%progbits
#else
.section .ctors,"aw"
#endif
.p2align 4, 0
.globl __CTOR_LIST__
__CTOR_LIST__:
.globl __CTOR_END__
__CTOR_END__:
#if defined(__ELF__)
.section .dtors,"aw",%progbits
#else
.section .dtors,"aw"
#endif
.p2align 4, 0
.globl __DTOR_LIST__
__DTOR_LIST__:
.globl __DTOR_END__
__DTOR_END__:
#if defined(__ELF__)
.section .fini_array,"aw",%fini_array
#else
.section .fini_array,"aw"
#endif
.p2align 4, 0
.globl __fini_array_start
__fini_array_start:
.globl __fini_array_end
__fini_array_end:
#if defined(__ELF__) && defined(__linux__)
.section .note.GNU-stack,"",%progbits
#endif
+226
View File
@@ -0,0 +1,226 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
data.c
Abstract:
EFI library global data
Revision History
--*/
#include "lib.h"
//
// LibInitialized - TRUE once InitializeLib() is called for the first time
//
BOOLEAN LibInitialized = FALSE;
//
// ImageHandle - Current ImageHandle, as passed to InitializeLib
//
EFI_HANDLE LibImageHandle;
//
// ST - pointer to the EFI system table
//
EFI_SYSTEM_TABLE *ST;
//
// BS - pointer to the boot services table
//
EFI_BOOT_SERVICES *BS;
//
// Default pool allocation type
//
EFI_MEMORY_TYPE PoolAllocationType = EfiBootServicesData;
//
// Unicode collation functions that are in use
//
EFI_UNICODE_COLLATION_INTERFACE LibStubUnicodeInterface = {
LibStubStriCmp,
LibStubMetaiMatch,
LibStubStrLwrUpr,
LibStubStrLwrUpr,
NULL, // FatToStr
NULL, // StrToFat
NULL // SupportedLanguages
};
EFI_UNICODE_COLLATION_INTERFACE *UnicodeInterface = &LibStubUnicodeInterface;
//
// Root device path
//
EFI_DEVICE_PATH RootDevicePath[] = {
{END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, {END_DEVICE_PATH_LENGTH,0}}
};
EFI_DEVICE_PATH EndDevicePath[] = {
{END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, {END_DEVICE_PATH_LENGTH, 0}}
};
EFI_DEVICE_PATH EndInstanceDevicePath[] = {
{END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, {END_DEVICE_PATH_LENGTH, 0}}
};
//
// EFI IDs
//
EFI_GUID gEfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE;
EFI_GUID gZeroGuid = EFI_ZERO_GUID;
//
// Protocol IDs
//
EFI_GUID gEfiDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
EFI_GUID gEfiDevicePathToTextProtocolGuid = EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID;
EFI_GUID gEfiDevicePathFromTextProtocolGuid = EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID;
EFI_GUID gEfiDevicePathUtilitiesProtocolGuid = EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID;
EFI_GUID gEfiLoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
EFI_GUID gEfiSimpleTextInProtocolGuid = EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID;
EFI_GUID gEfiSimpleTextOutProtocolGuid = EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID;
EFI_GUID gEfiBlockIoProtocolGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
EFI_GUID gEfiBlockIo2ProtocolGuid = EFI_BLOCK_IO2_PROTOCOL_GUID;
EFI_GUID gEfiDiskIoProtocolGuid = EFI_DISK_IO_PROTOCOL_GUID;
EFI_GUID gEfiDiskIo2ProtocolGuid = EFI_DISK_IO2_PROTOCOL_GUID;
EFI_GUID gEfiDxeServicesTableGuid = DXE_SERVICES_TABLE_GUID;
EFI_GUID gEfiSimpleFileSystemProtocolGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
EFI_GUID gEfiLoadedImageDevicePathProtocolGuid = EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID;
EFI_GUID gEfiLoadFileProtocolGuid = EFI_LOAD_FILE_PROTOCOL_GUID;
EFI_GUID gEfiLoadFile2ProtocolGuid = EFI_LOAD_FILE2_PROTOCOL_GUID;
EFI_GUID gEfiDeviceIoProtocolGuid = EFI_DEVICE_IO_PROTOCOL_GUID;
EFI_GUID gEfiUnicodeCollationProtocolGuid = EFI_UNICODE_COLLATION_PROTOCOL_GUID;
EFI_GUID gEfiSerialIoProtocolGuid = EFI_SERIAL_IO_PROTOCOL_GUID;
EFI_GUID gEfiSimpleNetworkProtocolGuid = EFI_SIMPLE_NETWORK_PROTOCOL_GUID;
EFI_GUID gEfiPxeBaseCodeProtocolGuid = EFI_PXE_BASE_CODE_PROTOCOL_GUID;
EFI_GUID gEfiPxeBaseCodeCallbackProtocolGuid = EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_GUID;
EFI_GUID gEfiNetworkInterfaceIdentifierProtocolGuid = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID;
EFI_GUID gEFiUiInterfaceProtocolGuid = EFI_UI_INTERFACE_PROTOCOL_GUID;
EFI_GUID gEfiPciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID;
EFI_GUID gEfiPciRootBridgeIoProtocolGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
EFI_GUID gEfiDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
EFI_GUID gEfiComponentNameProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
EFI_GUID gEfiComponentName2ProtocolGuid = EFI_COMPONENT_NAME2_PROTOCOL_GUID;
EFI_GUID gEfiHashProtocolGuid = EFI_HASH_PROTOCOL_GUID;
EFI_GUID gEfiPlatformDriverOverrideProtocolGuid = EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL_GUID;
EFI_GUID gEfiBusSpecificDriverOverrideProtocolGuid = EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID;
EFI_GUID gEfiDriverFamilyOverrideProtocolGuid = EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL_GUID;
EFI_GUID gEfiEbcProtocolGuid = EFI_EBC_PROTOCOL_GUID;
//
// File system information IDs
//
EFI_GUID gEfiFileInfoGuid = EFI_FILE_INFO_ID;
EFI_GUID gEfiFileSystemInfoGuid = EFI_FILE_SYSTEM_INFO_ID;
EFI_GUID gEfiFileSystemVolumeLabelInfoIdGuid = EFI_FILE_SYSTEM_VOLUME_LABEL_ID;
//
// Multi-Processing protocol IDs.
//
EFI_GUID gEfiMpServicesProtocolGuid = EFI_MP_SERVICES_PROTOCOL_GUID;
//
// Reference implementation public protocol IDs
//
EFI_GUID InternalShellProtocol = INTERNAL_SHELL_GUID;
EFI_GUID VariableStoreProtocol = VARIABLE_STORE_PROTOCOL;
EFI_GUID LegacyBootProtocol = LEGACY_BOOT_PROTOCOL;
EFI_GUID VgaClassProtocol = VGA_CLASS_DRIVER_PROTOCOL;
EFI_GUID TextOutSpliterProtocol = TEXT_OUT_SPLITER_PROTOCOL;
EFI_GUID ErrorOutSpliterProtocol = ERROR_OUT_SPLITER_PROTOCOL;
EFI_GUID TextInSpliterProtocol = TEXT_IN_SPLITER_PROTOCOL;
/* Added for GOP support */
EFI_GUID gEfiGraphicsOutputProtocolGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
EFI_GUID gEfiEdidDiscoveredProtocolGuid = EFI_EDID_DISCOVERED_PROTOCOL_GUID;
EFI_GUID gEfiEdidActiveProtocolGuid = EFI_EDID_ACTIVE_PROTOCOL_GUID;
EFI_GUID gEfiEdidOverrideProtocolGuid = EFI_EDID_OVERRIDE_PROTOCOL_GUID;
EFI_GUID AdapterDebugProtocol = ADAPTER_DEBUG_PROTOCOL;
//
// Device path media protocol IDs
//
EFI_GUID gEfiPcAnsiGuid = EFI_PC_ANSI_GUID;
EFI_GUID gEfiVT100Guid = EFI_VT_100_GUID;
EFI_GUID gEfiVT100PlusGuid = EFI_VT_100_PLUS_GUID;
EFI_GUID gEfiVTUTF8Guid = EFI_VT_UTF8_GUID;
//
// EFI GPT Partition Type GUIDs
//
EFI_GUID EfiPartTypeSystemPartitionGuid = EFI_PART_TYPE_EFI_SYSTEM_PART_GUID;
EFI_GUID EfiPartTypeLegacyMbrGuid = EFI_PART_TYPE_LEGACY_MBR_GUID;
//
// Reference implementation Vendor Device Path Guids
//
EFI_GUID UnknownDevice = UNKNOWN_DEVICE_GUID;
//
// Configuration Table GUIDs
//
EFI_GUID MpsTableGuid = MPS_TABLE_GUID;
EFI_GUID AcpiTableGuid = ACPI_TABLE_GUID;
EFI_GUID gEfiSmbiosTableGuid = SMBIOS_TABLE_GUID;
EFI_GUID gEfiSmbios3TableGuid = SMBIOS3_TABLE_GUID;
EFI_GUID SalSystemTableGuid = SAL_SYSTEM_TABLE_GUID;
EFI_GUID EfiDtbTableGuid = EFI_DTB_TABLE_GUID;
//
// Network protocol GUIDs
//
EFI_GUID Ip4ServiceBindingProtocol = EFI_IP4_SERVICE_BINDING_PROTOCOL;
EFI_GUID Ip4Protocol = EFI_IP4_PROTOCOL;
EFI_GUID Udp4ServiceBindingProtocol = EFI_UDP4_SERVICE_BINDING_PROTOCOL;
EFI_GUID Udp4Protocol = EFI_UDP4_PROTOCOL;
EFI_GUID Tcp4ServiceBindingProtocol = EFI_TCP4_SERVICE_BINDING_PROTOCOL;
EFI_GUID Tcp4Protocol = EFI_TCP4_PROTOCOL;
//
// Pointer protocol GUIDs
//
EFI_GUID SimplePointerProtocol = EFI_SIMPLE_POINTER_PROTOCOL_GUID;
EFI_GUID AbsolutePointerProtocol = EFI_ABSOLUTE_POINTER_PROTOCOL_GUID;
//
// Debugger protocol GUIDs
//
EFI_GUID gEfiDebugImageInfoTableGuid = EFI_DEBUG_IMAGE_INFO_TABLE_GUID;
EFI_GUID gEfiDebugSupportProtocolGuid = EFI_DEBUG_SUPPORT_PROTOCOL_GUID;
//
// Console extension protocol GUIDs
//
EFI_GUID SimpleTextInputExProtocol = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
//
// Shell protocol GUIDs
//
EFI_GUID ShellProtocolGuid = EFI_SHELL_PROTOCOL_GUID;
EFI_GUID ShellParametersProtocolGuid = EFI_SHELL_PARAMETERS_PROTOCOL_GUID;
EFI_GUID ShellDynamicCommandProtocolGuid = EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL_GUID;
+43
View File
@@ -0,0 +1,43 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
debug.c
Abstract:
Debug library functions
Revision History
--*/
#include "lib.h"
//
// Declare runtime functions
//
//
//
//
INTN
DbgAssert (
IN CONST CHAR8 *FileName,
IN INTN LineNo,
IN CONST CHAR8 *Description
)
{
DbgPrint (D_ERROR, (CHAR8 *)"%EASSERT FAILED: %a(%d): %a%N\n", FileName, LineNo, Description);
BREAKPOINT();
return 0;
}
+1263
View File
File diff suppressed because it is too large Load Diff
+73
View File
@@ -0,0 +1,73 @@
/*
* ctors.c
* Copyright 2019 Peter Jones <pjones@redhat.com>
*
*/
#include <efi.h>
#include <efilib.h>
typedef void (*funcp)(void);
/*
* Note that these aren't the using the GNU "CONSTRUCTOR" output section
* command, so they don't start with a size. Because of p2align and the
* end/END definitions, and the fact that they're mergeable, they can also
* have NULLs which aren't guaranteed to be at the end.
*/
extern funcp __init_array_start[], __init_array_end[];
extern funcp __CTOR_LIST__[], __CTOR_END__[];
extern funcp __fini_array_start[], __fini_array_end[];
extern funcp __DTOR_LIST__[], __DTOR_END__[];
static void ctors(void)
{
size_t __init_array_length = __init_array_end - __init_array_start;
for (size_t i = 0; i < __init_array_length; i++) {
funcp func = __init_array_start[i];
if (func != NULL)
func();
}
size_t __CTOR_length = __CTOR_END__ - __CTOR_LIST__;
for (size_t i = 0; i < __CTOR_length; i++) {
size_t current = __CTOR_length - i - 1;
funcp func = __CTOR_LIST__[current];
if (func != NULL)
func();
}
}
static void dtors(void)
{
size_t __DTOR_length = __DTOR_END__ - __DTOR_LIST__;
for (size_t i = 0; i < __DTOR_length; i++) {
funcp func = __DTOR_LIST__[i];
if (func != NULL)
func();
}
size_t __fini_array_length = __fini_array_end - __fini_array_start;
for (size_t i = 0; i < __fini_array_length; i++) {
size_t current = __fini_array_length - i - 1;
funcp func = __fini_array_start[current];
if (func != NULL)
func();
}
}
extern EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab);
EFI_STATUS _entry(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
{
EFI_STATUS status;
InitializeLib(image, systab);
ctors();
status = efi_main(image, systab);
dtors();
return status;
}
// vim:fenc=utf-8:tw=75:noet
+89
View File
@@ -0,0 +1,89 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
error.c
Abstract:
Revision History
--*/
#include "lib.h"
typedef struct {
EFI_STATUS Code;
WCHAR *Desc;
} ErrorCodeTable_Type;
ErrorCodeTable_Type ErrorCodeTable[] = {
{ EFI_SUCCESS, u"Success"},
{ EFI_LOAD_ERROR, u"Load Error"},
{ EFI_INVALID_PARAMETER, u"Invalid Parameter"},
{ EFI_UNSUPPORTED, u"Unsupported"},
{ EFI_BAD_BUFFER_SIZE, u"Bad Buffer Size"},
{ EFI_BUFFER_TOO_SMALL, u"Buffer Too Small"},
{ EFI_NOT_READY, u"Not Ready"},
{ EFI_DEVICE_ERROR, u"Device Error"},
{ EFI_WRITE_PROTECTED, u"Write Protected"},
{ EFI_OUT_OF_RESOURCES, u"Out of Resources"},
{ EFI_VOLUME_CORRUPTED, u"Volume Corrupt"},
{ EFI_VOLUME_FULL, u"Volume Full"},
{ EFI_NO_MEDIA, u"No Media"},
{ EFI_MEDIA_CHANGED, u"Media changed"},
{ EFI_NOT_FOUND, u"Not Found"},
{ EFI_ACCESS_DENIED, u"Access Denied"},
{ EFI_NO_RESPONSE, u"No Response"},
{ EFI_NO_MAPPING, u"No mapping"},
{ EFI_TIMEOUT, u"Time out"},
{ EFI_NOT_STARTED, u"Not started"},
{ EFI_ALREADY_STARTED, u"Already started"},
{ EFI_ABORTED, u"Aborted"},
{ EFI_ICMP_ERROR, u"ICMP Error"},
{ EFI_TFTP_ERROR, u"TFTP Error"},
{ EFI_PROTOCOL_ERROR, u"Protocol Error"},
{ EFI_INCOMPATIBLE_VERSION, u"Incompatible Version"},
{ EFI_SECURITY_VIOLATION, u"Security Policy Violation"},
{ EFI_CRC_ERROR, u"CRC Error"},
{ EFI_END_OF_MEDIA, u"End of Media"},
{ EFI_END_OF_FILE, u"End of File"},
{ EFI_INVALID_LANGUAGE, u"Invalid Languages"},
{ EFI_COMPROMISED_DATA, u"Compromised Data"},
{ EFI_IP_ADDRESS_CONFLICT, u"IP Address Conflict"},
{ EFI_HTTP_ERROR, u"HTTP Error"},
// warnings
{ EFI_WARN_UNKNOWN_GLYPH, u"Warning Unknown Glyph"},
{ EFI_WARN_DELETE_FAILURE, u"Warning Delete Failure"},
{ EFI_WARN_WRITE_FAILURE, u"Warning Write Failure"},
{ EFI_WARN_BUFFER_TOO_SMALL, u"Warning Buffer Too Small"},
{ EFI_WARN_STALE_DATA, u"Warning Stale Data"},
{ EFI_WARN_FILE_SYSTEM, u"Warning File System"},
{ EFI_WARN_RESET_REQUIRED, u"Warning Reset Required"},
{ 0, NULL}
} ;
VOID
StatusToString (
OUT CHAR16 *Buffer,
IN EFI_STATUS Status
)
{
UINTN Index;
for (Index = 0; ErrorCodeTable[Index].Desc; Index +=1) {
if (ErrorCodeTable[Index].Code == Status) {
StrCpy (Buffer, ErrorCodeTable[Index].Desc);
return;
}
}
UnicodeSPrint (Buffer, 0, u"%X", Status);
}
+154
View File
@@ -0,0 +1,154 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
event.c
Abstract:
Revision History
--*/
#include "lib.h"
EFI_EVENT
LibCreateProtocolNotifyEvent (
IN EFI_GUID *ProtocolGuid,
IN EFI_TPL NotifyTpl,
IN EFI_EVENT_NOTIFY NotifyFunction,
IN VOID *NotifyContext,
OUT VOID *Registration
)
{
EFI_STATUS Status;
EFI_EVENT Event;
//
// Create the event
//
Status = uefi_call_wrapper(
BS->CreateEvent,
5,
EVT_NOTIFY_SIGNAL,
NotifyTpl,
NotifyFunction,
NotifyContext,
&Event
);
if ( EFI_ERROR( Status ) ) return NULL ;
ASSERT (!EFI_ERROR(Status));
//
// Register for protocol notifactions on this event
//
Status = uefi_call_wrapper(
BS->RegisterProtocolNotify,
3,
ProtocolGuid,
Event,
Registration
);
if ( EFI_ERROR( Status ) ) return NULL ;
ASSERT (!EFI_ERROR(Status));
//
// Kick the event so we will perform an initial pass of
// current installed drivers
//
uefi_call_wrapper(BS->SignalEvent, 1, Event);
return Event;
}
EFI_STATUS
WaitForSingleEvent (
IN EFI_EVENT Event,
IN UINT64 Timeout OPTIONAL
)
{
EFI_STATUS Status;
UINTN Index;
EFI_EVENT TimerEvent;
EFI_EVENT WaitList[2];
if (Timeout) {
//
// Create a timer event
//
Status = uefi_call_wrapper(BS->CreateEvent, 5, EVT_TIMER, 0, NULL, NULL, &TimerEvent);
if (!EFI_ERROR(Status)) {
//
// Set the timer event
//
uefi_call_wrapper(BS->SetTimer, 3, TimerEvent, TimerRelative, Timeout);
//
// Wait for the original event or the timer
//
WaitList[0] = Event;
WaitList[1] = TimerEvent;
Status = uefi_call_wrapper(BS->WaitForEvent, 3, 2, WaitList, &Index);
uefi_call_wrapper(BS->CloseEvent, 1, TimerEvent);
//
// If the timer expired, change the return to timed out
//
if (!EFI_ERROR(Status) && Index == 1) {
Status = EFI_TIMEOUT;
}
}
} else {
//
// No timeout... just wait on the event
//
Status = uefi_call_wrapper(BS->WaitForEvent, 3, 1, &Event, &Index);
ASSERT (!EFI_ERROR(Status));
ASSERT (Index == 0);
}
return Status;
}
VOID
WaitForEventWithTimeout (
IN EFI_EVENT Event,
IN UINTN Timeout,
IN UINTN Row,
IN UINTN Column,
IN CHAR16 *String,
IN EFI_INPUT_KEY TimeoutKey,
OUT EFI_INPUT_KEY *Key
)
{
EFI_STATUS Status;
do {
PrintAt (Column, Row, String, Timeout);
Status = WaitForSingleEvent (Event, 10000000);
if (Status == EFI_SUCCESS) {
if (!EFI_ERROR(uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, Key))) {
return;
}
}
} while (Timeout > 0);
CopyMem(Key, &TimeoutKey, sizeof(EFI_INPUT_KEY));
}
+19
View File
@@ -0,0 +1,19 @@
#include "lib.h"
VOID
Exit(
IN EFI_STATUS ExitStatus,
IN UINTN ExitDataSize,
IN CHAR16 *ExitData OPTIONAL
)
{
uefi_call_wrapper(BS->Exit,
4,
LibImageHandle,
ExitStatus,
ExitDataSize,
ExitData);
// Uh oh, Exit() returned?!
for (;;) { }
}
+191
View File
@@ -0,0 +1,191 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
misc.c
Abstract:
Misc EFI support functions
Revision History
--*/
#include "lib.h"
//
// Additional Known guids
//
#define SHELL_INTERFACE_PROTOCOL \
{ 0x47c7b223, 0xc42a, 0x11d2, {0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
#define ENVIRONMENT_VARIABLE_ID \
{ 0x47c7b224, 0xc42a, 0x11d2, {0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
#define DEVICE_PATH_MAPPING_ID \
{ 0x47c7b225, 0xc42a, 0x11d2, {0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
#define PROTOCOL_ID_ID \
{ 0x47c7b226, 0xc42a, 0x11d2, {0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
#define ALIAS_ID \
{ 0x47c7b227, 0xc42a, 0x11d2, {0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
static EFI_GUID ShellInterfaceProtocol = SHELL_INTERFACE_PROTOCOL;
static EFI_GUID SEnvId = ENVIRONMENT_VARIABLE_ID;
static EFI_GUID SMapId = DEVICE_PATH_MAPPING_ID;
static EFI_GUID SProtId = PROTOCOL_ID_ID;
static EFI_GUID SAliasId = ALIAS_ID;
static struct {
EFI_GUID *Guid;
WCHAR *GuidName;
} KnownGuids[] = {
{ &gZeroGuid, u"NullGuid" },
{ &gEfiGlobalVariableGuid, u"EfiVar" },
{ &VariableStoreProtocol, u"VarStore" },
{ &gEfiDevicePathProtocolGuid, u"DevPath" },
{ &gEfiLoadedImageProtocolGuid, u"LdImg" },
{ &gEfiSimpleTextInProtocolGuid, u"TxtIn" },
{ &gEfiSimpleTextOutProtocolGuid, u"TxtOut" },
{ &gEfiBlockIoProtocolGuid, u"BlkIo" },
{ &gEfiBlockIo2ProtocolGuid, u"BlkIo2" },
{ &gEfiDiskIoProtocolGuid, u"DskIo" },
{ &gEfiDiskIo2ProtocolGuid, u"DskIo2" },
{ &gEfiSimpleFileSystemProtocolGuid, u"Fs" },
{ &gEfiLoadFileProtocolGuid, u"LdFile" },
{ &gEfiDeviceIoProtocolGuid, u"DevIo" },
{ &gEfiComponentNameProtocolGuid, u"CName" },
{ &gEfiComponentName2ProtocolGuid, u"CName2" },
{ &gEfiMpServicesProtocolGuid, u"Mp" },
{ &gEfiFileInfoGuid, u"FileInfo" },
{ &gEfiFileSystemInfoGuid, u"FsInfo" },
{ &gEfiFileSystemVolumeLabelInfoIdGuid, u"FsVolInfo" },
{ &gEfiUnicodeCollationProtocolGuid, u"Unicode" },
{ &LegacyBootProtocol, u"LegacyBoot" },
{ &gEfiSerialIoProtocolGuid, u"SerIo" },
{ &VgaClassProtocol, u"VgaClass"},
{ &gEfiSimpleNetworkProtocolGuid, u"Net" },
{ &gEfiNetworkInterfaceIdentifierProtocolGuid, u"Nii" },
{ &gEfiPxeBaseCodeProtocolGuid, u"Pxe" },
{ &gEfiPxeBaseCodeCallbackProtocolGuid, u"PxeCb" },
{ &TextOutSpliterProtocol, u"TxtOutSplit" },
{ &ErrorOutSpliterProtocol, u"ErrOutSplit" },
{ &TextInSpliterProtocol, u"TxtInSplit" },
{ &gEfiPcAnsiGuid, u"PcAnsi" },
{ &gEfiVT100Guid, u"Vt100" },
{ &gEfiVT100PlusGuid, u"Vt100Plus" },
{ &gEfiVTUTF8Guid, u"VtUtf8" },
{ &UnknownDevice, u"UnknownDev" },
{ &EfiPartTypeSystemPartitionGuid, u"ESP" },
{ &EfiPartTypeLegacyMbrGuid, u"GPT MBR" },
{ &ShellInterfaceProtocol, u"ShellInt" },
{ &SEnvId, u"SEnv" },
{ &SProtId, u"ShellProtId" },
{ &SMapId, u"ShellDevPathMap" },
{ &SAliasId, u"ShellAlias" },
{ NULL, u"" }
};
//
//
//
LIST_ENTRY GuidList;
VOID
InitializeGuid (
VOID
)
{
}
BOOLEAN
EFIAPI
CompareGuid_1 (
IN CONST EFI_GUID *Guid1,
IN CONST EFI_GUID *Guid2
)
/*++
Routine Description:
Compares to GUIDs
Arguments:
Guid1 - guid to compare
Guid2 - guid to compare
Returns:
= 1 if Guid1 == Guid2
--*/
{
return RtCompareGuid (Guid1, Guid2);
}
BOOLEAN
EFIAPI
IsZeroGuid (
IN CONST EFI_GUID *Guid1
)
{
return RtIsZeroGuid(Guid1);
}
VOID
GuidToString (
OUT CHAR16 *Buffer,
IN EFI_GUID *Guid
)
{
UINTN Index;
//
// Else, (for now) use additional internal function for mapping guids
//
for (Index=0; KnownGuids[Index].Guid; Index++) {
if (CompareGuid(Guid, KnownGuids[Index].Guid)) {
UnicodeSPrint (Buffer, 0, KnownGuids[Index].GuidName);
return ;
}
}
//
// Else dump it
//
UnicodeSPrint (Buffer, 0, u"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
Guid->Data1,
Guid->Data2,
Guid->Data3,
Guid->Data4[0],
Guid->Data4[1],
Guid->Data4[2],
Guid->Data4[3],
Guid->Data4[4],
Guid->Data4[5],
Guid->Data4[6],
Guid->Data4[7]
);
}
+641
View File
@@ -0,0 +1,641 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
hand.c
Abstract:
Revision History
--*/
#include "lib.h"
#include "efistdarg.h" // !!!
EFI_STATUS
LibLocateProtocol (
IN EFI_GUID *ProtocolGuid,
OUT VOID **Interface
)
//
// Find the first instance of this Protocol in the system and return it's interface
//
{
EFI_STATUS Status;
UINTN NumberHandles, Index;
EFI_HANDLE *Handles;
*Interface = NULL;
Status = LibLocateHandle (ByProtocol, ProtocolGuid, NULL, &NumberHandles, &Handles);
if (EFI_ERROR(Status)) {
DEBUG((D_INFO, "LibLocateProtocol: Handle not found\n"));
return Status;
}
for (Index=0; Index < NumberHandles; Index++) {
Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handles[Index], ProtocolGuid, Interface);
if (!EFI_ERROR(Status)) {
break;
}
}
if (Handles) {
FreePool (Handles);
}
return Status;
}
EFI_STATUS
LibLocateHandle (
IN EFI_LOCATE_SEARCH_TYPE SearchType,
IN EFI_GUID *Protocol OPTIONAL,
IN VOID *SearchKey OPTIONAL,
IN OUT UINTN *NoHandles,
OUT EFI_HANDLE **Buffer
)
{
EFI_STATUS Status;
UINTN BufferSize;
//
// Initialize for GrowBuffer loop
//
Status = EFI_SUCCESS;
*Buffer = NULL;
BufferSize = 50 * sizeof(EFI_HANDLE);
//
// Call the real function
//
while (GrowBuffer (&Status, (VOID **) Buffer, BufferSize)) {
Status = uefi_call_wrapper(
BS->LocateHandle,
5,
SearchType,
Protocol,
SearchKey,
&BufferSize,
*Buffer
);
}
*NoHandles = BufferSize / sizeof (EFI_HANDLE);
if (EFI_ERROR(Status)) {
*NoHandles = 0;
}
return Status;
}
EFI_STATUS
LibLocateHandleByDiskSignature (
IN UINT8 MBRType,
IN UINT8 SignatureType,
IN VOID *Signature,
IN OUT UINTN *NoHandles,
OUT EFI_HANDLE **Buffer
)
{
EFI_STATUS Status;
UINTN BufferSize;
UINTN NoBlockIoHandles;
EFI_HANDLE *BlockIoBuffer;
EFI_DEVICE_PATH *DevicePath;
UINTN Index;
EFI_DEVICE_PATH *Next, *DevPath;
HARDDRIVE_DEVICE_PATH *HardDriveDevicePath;
BOOLEAN Match;
BOOLEAN PreviousNodeIsHardDriveDevicePath;
//
// Initialize for GrowBuffer loop
//
Status = EFI_SUCCESS;
BlockIoBuffer = NULL;
BufferSize = 50 * sizeof(EFI_HANDLE);
//
// Call the real function
//
while (GrowBuffer (&Status, (VOID **)&BlockIoBuffer, BufferSize)) {
//
// Get list of device handles that support the BLOCK_IO Protocol.
//
Status = uefi_call_wrapper(
BS->LocateHandle,
5,
ByProtocol,
&BlockIoProtocol,
NULL,
&BufferSize,
BlockIoBuffer
);
}
NoBlockIoHandles = BufferSize / sizeof (EFI_HANDLE);
if (EFI_ERROR(Status)) {
NoBlockIoHandles = 0;
}
//
// If there was an error or there are no device handles that support
// the BLOCK_IO Protocol, then return.
//
if (NoBlockIoHandles == 0) {
FreePool(BlockIoBuffer);
*NoHandles = 0;
*Buffer = NULL;
return Status;
}
//
// Loop through all the device handles that support the BLOCK_IO Protocol
//
*NoHandles = 0;
for(Index=0;Index<NoBlockIoHandles;Index++) {
Status = uefi_call_wrapper(
BS->HandleProtocol,
3,
BlockIoBuffer[Index],
&DevicePathProtocol,
(VOID*)&DevicePath
);
//
// Search DevicePath for a Hard Drive Media Device Path node.
// If one is found, then see if it matches the signature that was
// passed in. If it does match, and the next node is the End of the
// device path, and the previous node is not a Hard Drive Media Device
// Path, then we have found a match.
//
Match = FALSE;
if (DevicePath != NULL) {
PreviousNodeIsHardDriveDevicePath = FALSE;
DevPath = DevicePath;
//
// Check for end of device path type
//
for (; ;) {
if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&
(DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {
HardDriveDevicePath = (HARDDRIVE_DEVICE_PATH *)(DevPath);
if (PreviousNodeIsHardDriveDevicePath == FALSE) {
Next = NextDevicePathNode(DevPath);
if (IsDevicePathEndType(Next)) {
if ((HardDriveDevicePath->MBRType == MBRType) &&
(HardDriveDevicePath->SignatureType == SignatureType)) {
switch(SignatureType) {
case SIGNATURE_TYPE_MBR:
if (*((UINT32 *)(Signature)) == *(UINT32 *)(&(HardDriveDevicePath->Signature[0]))) {
Match = TRUE;
}
break;
case SIGNATURE_TYPE_GUID:
if (CompareGuid((EFI_GUID *)Signature,(EFI_GUID *)(&(HardDriveDevicePath->Signature[0])))) {
Match = TRUE;
}
break;
}
}
}
}
PreviousNodeIsHardDriveDevicePath = TRUE;
} else {
PreviousNodeIsHardDriveDevicePath = FALSE;
}
if (IsDevicePathEnd(DevPath)) {
break;
}
DevPath = NextDevicePathNode(DevPath);
}
}
if (Match == FALSE) {
BlockIoBuffer[Index] = NULL;
} else {
*NoHandles = *NoHandles + 1;
}
}
//
// If there are no matches, then return
//
if (*NoHandles == 0) {
FreePool(BlockIoBuffer);
*NoHandles = 0;
*Buffer = NULL;
return EFI_SUCCESS;
}
//
// Allocate space for the return buffer of device handles.
//
*Buffer = AllocatePool(*NoHandles * sizeof(EFI_HANDLE));
if (*Buffer == NULL) {
FreePool(BlockIoBuffer);
*NoHandles = 0;
*Buffer = NULL;
return EFI_OUT_OF_RESOURCES;
}
//
// Build list of matching device handles.
//
*NoHandles = 0;
for(Index=0;Index<NoBlockIoHandles;Index++) {
if (BlockIoBuffer[Index] != NULL) {
(*Buffer)[*NoHandles] = BlockIoBuffer[Index];
*NoHandles = *NoHandles + 1;
}
}
FreePool(BlockIoBuffer);
return EFI_SUCCESS;
}
EFI_FILE_HANDLE
LibOpenRoot (
IN EFI_HANDLE DeviceHandle
)
{
EFI_STATUS Status;
EFI_FILE_IO_INTERFACE *Volume;
EFI_FILE_HANDLE File;
//
// File the file system interface to the device
//
Status = uefi_call_wrapper(BS->HandleProtocol, 3, DeviceHandle, &FileSystemProtocol, (VOID*)&Volume);
//
// Open the root directory of the volume
//
if (!EFI_ERROR(Status)) {
Status = uefi_call_wrapper(Volume->OpenVolume, 2, Volume, &File);
}
//
// Done
//
return EFI_ERROR(Status) ? NULL : File;
}
EFI_FILE_INFO *
LibFileInfo (
IN EFI_FILE_HANDLE FHand
)
{
EFI_STATUS Status;
EFI_FILE_INFO *Buffer;
UINTN BufferSize;
//
// Initialize for GrowBuffer loop
//
Status = EFI_SUCCESS;
Buffer = NULL;
BufferSize = SIZE_OF_EFI_FILE_INFO + 200;
//
// Call the real function
//
while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
Status = uefi_call_wrapper(
FHand->GetInfo,
4,
FHand,
&GenericFileInfo,
&BufferSize,
Buffer
);
}
return Buffer;
}
EFI_FILE_SYSTEM_INFO *
LibFileSystemInfo (
IN EFI_FILE_HANDLE FHand
)
{
EFI_STATUS Status;
EFI_FILE_SYSTEM_INFO *Buffer;
UINTN BufferSize;
//
// Initialize for GrowBuffer loop
//
Status = EFI_SUCCESS;
Buffer = NULL;
BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + 200;
//
// Call the real function
//
while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
Status = uefi_call_wrapper(
FHand->GetInfo,
4,
FHand,
&FileSystemInfo,
&BufferSize,
Buffer
);
}
return Buffer;
}
EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *
LibFileSystemVolumeLabelInfo (
IN EFI_FILE_HANDLE FHand
)
{
EFI_STATUS Status;
EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *Buffer;
UINTN BufferSize;
//
// Initialize for GrowBuffer loop
//
Status = EFI_SUCCESS;
Buffer = NULL;
BufferSize = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO + 200;
//
// Call the real function
//
while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
Status = uefi_call_wrapper(
FHand->GetInfo,
4,
FHand,
&FileSystemVolumeLabelInfo,
&BufferSize,
Buffer
);
}
return Buffer;
}
EFI_STATUS
LibInstallProtocolInterfaces (
IN OUT EFI_HANDLE *Handle,
...
)
{
va_list args;
EFI_STATUS Status;
EFI_GUID *Protocol;
VOID *Interface;
EFI_TPL OldTpl;
UINTN Index;
EFI_HANDLE OldHandle;
//
// Syncronize with notifcations
//
OldTpl = uefi_call_wrapper(BS->RaiseTPL, 1, TPL_NOTIFY);
OldHandle = *Handle;
//
// Install the protocol interfaces
//
Index = 0;
Status = EFI_SUCCESS;
va_start (args, Handle);
while (!EFI_ERROR(Status)) {
//
// If protocol is NULL, then it's the end of the list
//
Protocol = va_arg(args, EFI_GUID *);
if (!Protocol) {
break;
}
Interface = va_arg(args, VOID *);
//
// Install it
//
DEBUG((D_INFO, "LibInstallProtocolInterface: %d %x\n", Protocol, Interface));
Status = uefi_call_wrapper(BS->InstallProtocolInterface, 4, Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
if (EFI_ERROR(Status)) {
break;
}
Index += 1;
}
va_end (args);
//
// If there was an error, remove all the interfaces that were
// installed without any errors
//
if (EFI_ERROR(Status)) {
va_start (args, Handle);
while (Index) {
Protocol = va_arg(args, EFI_GUID *);
Interface = va_arg(args, VOID *);
uefi_call_wrapper(BS->UninstallProtocolInterface, 3, *Handle, Protocol, Interface);
Index -= 1;
}
*Handle = OldHandle;
va_end (args);
}
//
// Done
//
uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl);
return Status;
}
VOID
LibUninstallProtocolInterfaces (
IN EFI_HANDLE Handle,
...
)
{
va_list args;
EFI_STATUS Status;
EFI_GUID *Protocol;
VOID *Interface;
va_start (args, Handle);
for (; ;) {
//
// If protocol is NULL, then it's the end of the list
//
Protocol = va_arg(args, EFI_GUID *);
if (!Protocol) {
break;
}
Interface = va_arg(args, VOID *);
//
// Uninstall it
//
Status = uefi_call_wrapper(BS->UninstallProtocolInterface, 3, Handle, Protocol, Interface);
if (EFI_ERROR(Status)) {
DEBUG((D_ERROR, "LibUninstallProtocolInterfaces: failed %g, %r\n", Protocol, Handle));
}
}
va_end (args);
}
EFI_STATUS
LibReinstallProtocolInterfaces (
IN OUT EFI_HANDLE *Handle,
...
)
{
va_list args;
EFI_STATUS Status;
EFI_GUID *Protocol;
VOID *OldInterface, *NewInterface;
EFI_TPL OldTpl;
UINTN Index;
//
// Syncronize with notifcations
//
OldTpl = uefi_call_wrapper(BS->RaiseTPL, 1, TPL_NOTIFY);
//
// Install the protocol interfaces
//
Index = 0;
Status = EFI_SUCCESS;
va_start (args, Handle);
while (!EFI_ERROR(Status)) {
//
// If protocol is NULL, then it's the end of the list
//
Protocol = va_arg(args, EFI_GUID *);
if (!Protocol) {
break;
}
OldInterface = va_arg(args, VOID *);
NewInterface = va_arg(args, VOID *);
//
// Reinstall it
//
Status = uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, OldInterface, NewInterface);
if (EFI_ERROR(Status)) {
break;
}
Index += 1;
}
va_end (args);
//
// If there was an error, undo all the interfaces that were
// reinstalled without any errors
//
if (EFI_ERROR(Status)) {
va_start (args, Handle);
while (Index) {
Protocol = va_arg(args, EFI_GUID *);
OldInterface = va_arg(args, VOID *);
NewInterface = va_arg(args, VOID *);
uefi_call_wrapper(BS->ReinstallProtocolInterface, 4, Handle, Protocol, NewInterface, OldInterface);
Index -= 1;
}
va_end (args);
}
//
// Done
//
uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl);
return Status;
}
+132
View File
@@ -0,0 +1,132 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
hw.c
Abstract:
Debug library functions for Hardware IO access
Revision History
--*/
#include "lib.h"
EFI_STATUS
InitializeGlobalIoDevice (
IN EFI_DEVICE_PATH *DevicePath,
IN EFI_GUID *Protocol,
IN CHAR8 *ErrorStr EFI_UNUSED,
OUT EFI_DEVICE_IO_INTERFACE **GlobalIoFncs
)
/*++
Routine Description:
Check to see if DevicePath exists for a given Protocol. Return Error if it
exists. Return GlobalIoFuncs set match the DevicePath
Arguments:
DevicePath - to operate on
Protocol - to check the DevicePath against
ErrorStr - ASCII string to display on error
GlobalIoFncs - Returned with DeviceIoProtocol for the DevicePath
Returns:
Pass or Fail based on wether GlobalIoFncs where found
--*/
{
EFI_STATUS Status;
EFI_HANDLE Handle;
//
// Check to see if this device path already has Protocol on it.
// if so we are loading recursivly and should exit with an error
//
Status = uefi_call_wrapper(BS->LocateDevicePath, 3, Protocol, &DevicePath, &Handle);
if (!EFI_ERROR(Status)) {
DEBUG ((D_INIT, "Device Already Loaded for %a device\n", ErrorStr));
return EFI_LOAD_ERROR;
}
Status = uefi_call_wrapper(BS->LocateDevicePath, 3, &DeviceIoProtocol, &DevicePath, &Handle);
if (!EFI_ERROR(Status)) {
Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handle, &DeviceIoProtocol, (VOID*)GlobalIoFncs);
}
ASSERT (!EFI_ERROR(Status));
return Status;
}
UINT32
ReadPort (
IN EFI_DEVICE_IO_INTERFACE *GlobalIoFncs,
IN EFI_IO_WIDTH Width,
IN UINTN Port
)
{
UINT32 Data;
EFI_STATUS Status EFI_UNUSED;
Status = uefi_call_wrapper(GlobalIoFncs->Io.Read, 5, GlobalIoFncs, Width, (UINT64)Port, 1, &Data);
ASSERT(!EFI_ERROR(Status));
return Data;
}
UINT32
WritePort (
IN EFI_DEVICE_IO_INTERFACE *GlobalIoFncs,
IN EFI_IO_WIDTH Width,
IN UINTN Port,
IN UINTN Data
)
{
EFI_STATUS Status EFI_UNUSED;
Status = uefi_call_wrapper(GlobalIoFncs->Io.Write, 5, GlobalIoFncs, Width, (UINT64)Port, 1, &Data);
ASSERT(!EFI_ERROR(Status));
return (UINT32)Data;
}
UINT32
ReadPciConfig (
IN EFI_DEVICE_IO_INTERFACE *GlobalIoFncs,
IN EFI_IO_WIDTH Width,
IN UINTN Address
)
{
UINT32 Data;
EFI_STATUS Status EFI_UNUSED;
Status = uefi_call_wrapper(GlobalIoFncs->Pci.Read, 5, GlobalIoFncs, Width, (UINT64)Address, 1, &Data);
ASSERT(!EFI_ERROR(Status));
return Data;
}
UINT32
WritePciConfig (
IN EFI_DEVICE_IO_INTERFACE *GlobalIoFncs,
IN EFI_IO_WIDTH Width,
IN UINTN Address,
IN UINTN Data
)
{
EFI_STATUS Status EFI_UNUSED;
Status = uefi_call_wrapper(GlobalIoFncs->Pci.Write, 5, GlobalIoFncs, Width, (UINT64)Address, 1, &Data);
ASSERT(!EFI_ERROR(Status));
return (UINT32)Data;
}
+209
View File
@@ -0,0 +1,209 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
Abstract:
Revision History
--*/
#include "lib.h"
VOID
EFIDebugVariable (
VOID
);
VOID
InitializeLib (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Initializes EFI library for use
Arguments:
Firmware's EFI system table
Returns:
None
--*/
{
EFI_LOADED_IMAGE *LoadedImage;
EFI_STATUS Status;
CHAR8 *LangCode;
if (LibInitialized)
return;
LibInitialized = TRUE;
LibFwInstance = FALSE;
LibImageHandle = ImageHandle;
//
// Set up global pointer to the system table, boot services table,
// and runtime services table
//
ST = SystemTable;
BS = SystemTable->BootServices;
RT = SystemTable->RuntimeServices;
// ASSERT (CheckCrc(0, &ST->Hdr));
// ASSERT (CheckCrc(0, &BS->Hdr));
// ASSERT (CheckCrc(0, &RT->Hdr));
//
// Initialize pool allocation type
//
if (ImageHandle) {
Status = uefi_call_wrapper(
BS->HandleProtocol,
3,
ImageHandle,
&LoadedImageProtocol,
(VOID*)&LoadedImage
);
if (!EFI_ERROR(Status)) {
PoolAllocationType = LoadedImage->ImageDataType;
}
EFIDebugVariable ();
}
//
// Initialize Guid table
//
InitializeGuid();
InitializeLibPlatform(ImageHandle,SystemTable);
if (ImageHandle && UnicodeInterface == &LibStubUnicodeInterface) {
LangCode = LibGetVariable (VarLanguage, &EfiGlobalVariable);
InitializeUnicodeSupport (LangCode);
if (LangCode) {
FreePool (LangCode);
}
}
}
VOID
InitializeUnicodeSupport (
CHAR8 *LangCode
)
{
EFI_UNICODE_COLLATION_INTERFACE *Ui;
EFI_STATUS Status;
CHAR8 *Languages;
UINTN Index, Position, Length;
UINTN NoHandles;
EFI_HANDLE *Handles;
//
// If we don't know it, lookup the current language code
//
LibLocateHandle (ByProtocol, &UnicodeCollationProtocol, NULL, &NoHandles, &Handles);
if (!LangCode || !NoHandles) {
goto Done;
}
//
// Check all driver's for a matching language code
//
for (Index=0; Index < NoHandles; Index++) {
Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handles[Index], &UnicodeCollationProtocol, (VOID*)&Ui);
if (EFI_ERROR(Status)) {
continue;
}
//
// Check for a matching language code
//
Languages = Ui->SupportedLanguages;
Length = strlena(Languages);
for (Position=0; Position < Length; Position += ISO_639_2_ENTRY_SIZE) {
//
// If this code matches, use this driver
//
if (CompareMem (Languages+Position, LangCode, ISO_639_2_ENTRY_SIZE) == 0) {
UnicodeInterface = Ui;
goto Done;
}
}
}
Done:
//
// Cleanup
//
if (Handles) {
FreePool (Handles);
}
}
VOID
EFIDebugVariable (
VOID
)
{
EFI_STATUS Status;
UINT32 Attributes;
UINTN DataSize;
UINTN NewEFIDebug;
DataSize = sizeof(EFIDebug);
Status = uefi_call_wrapper(RT->GetVariable, 5, u"EFIDebug", &EfiGlobalVariable, &Attributes, &DataSize, &NewEFIDebug);
if (!EFI_ERROR(Status)) {
EFIDebug = NewEFIDebug;
}
}
/*
* Calls to memset/memcpy may be emitted implicitly by GCC or MSVC
* even when -ffreestanding or /NODEFAULTLIB are in effect.
*/
#ifndef __SIZE_TYPE__
#define __SIZE_TYPE__ UINTN
#endif
void *memset(void *s, int c, __SIZE_TYPE__ n)
{
unsigned char *p = s;
while (n--)
*p++ = c;
return s;
}
void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n)
{
const unsigned char *q = src;
unsigned char *p = dest;
while (n--)
*p++ = *q++;
return dest;
}
+107
View File
@@ -0,0 +1,107 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
lock.c
Abstract:
Implements FLOCK
Revision History
--*/
#include "lib.h"
VOID
InitializeLock (
IN OUT FLOCK *Lock,
IN EFI_TPL Priority
)
/*++
Routine Description:
Initialize a basic mutual exclusion lock. Each lock
provides mutual exclusion access at it's task priority
level. Since there is no-premption (at any TPL) or
multiprocessor support, acquiring the lock only consists
of raising to the locks TPL.
Note on a debug build the lock is acquired and released
to help ensure proper usage.
Arguments:
Lock - The FLOCK structure to initialize
Priority - The task priority level of the lock
Returns:
An initialized F Lock structure.
--*/
{
Lock->Tpl = Priority;
Lock->OwnerTpl = 0;
Lock->Lock = 0;
}
VOID
AcquireLock (
IN FLOCK *Lock
)
/*++
Routine Description:
Raising to the task priority level of the mutual exclusion
lock, and then acquires ownership of the lock.
Arguments:
Lock - The lock to acquire
Returns:
Lock owned
--*/
{
RtAcquireLock (Lock);
}
VOID
ReleaseLock (
IN FLOCK *Lock
)
/*++
Routine Description:
Releases ownership of the mutual exclusion lock, and
restores the previous task priority level.
Arguments:
Lock - The lock to release
Returns:
Lock unowned
--*/
{
RtReleaseLock (Lock);
}
+574
View File
@@ -0,0 +1,574 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
misc.c
Abstract:
Revision History
--*/
#include "lib.h"
//
//
//
VOID *
AllocatePool (
IN UINTN Size
)
{
EFI_STATUS Status;
VOID *p;
Status = uefi_call_wrapper(BS->AllocatePool, 3, PoolAllocationType, Size, &p);
if (EFI_ERROR(Status)) {
DEBUG((D_ERROR, "AllocatePool: out of pool %x\n", Status));
p = NULL;
}
return p;
}
VOID *
AllocateZeroPool (
IN UINTN Size
)
{
VOID *p;
p = AllocatePool (Size);
if (p) {
ZeroMem (p, Size);
}
return p;
}
VOID *
EFIAPI
ReallocatePool_1 (
IN UINTN OldSize,
IN UINTN NewSize,
IN VOID *OldPool OPTIONAL
)
{
VOID *NewPool;
NewPool = NULL;
if (NewSize) {
NewPool = AllocatePool (NewSize);
}
if (OldPool) {
if (NewPool) {
CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
}
FreePool (OldPool);
}
return NewPool;
}
VOID
FreePool (
IN VOID *Buffer
)
{
uefi_call_wrapper(BS->FreePool, 1, Buffer);
}
VOID
ZeroMem (
IN VOID *Buffer,
IN UINTN Size
)
{
RtZeroMem (Buffer, Size);
}
VOID EFIAPI
SetMem (
IN VOID *Buffer,
IN UINTN Size,
IN UINT8 Value
)
{
RtSetMem (Buffer, Size, Value);
}
VOID EFIAPI
CopyMem_1 (
IN VOID *Dest,
IN VOID *Src,
IN UINTN len
)
{
RtCopyMem (Dest, Src, len);
}
VOID EFIAPI
CopyMemC (
IN VOID *Dest,
IN CONST VOID *Src,
IN UINTN len
)
{
RtCopyMemC (Dest, Src, len);
}
INTN
CompareMem (
IN CONST VOID *Dest,
IN CONST VOID *Src,
IN UINTN len
)
{
return RtCompareMem (Dest, Src, len);
}
BOOLEAN
GrowBuffer(
IN OUT EFI_STATUS *Status,
IN OUT VOID **Buffer,
IN UINTN BufferSize
)
/*++
Routine Description:
Helper function called as part of the code needed
to allocate the proper sized buffer for various
EFI interfaces.
Arguments:
Status - Current status
Buffer - Current allocated buffer, or NULL
BufferSize - Current buffer size needed
Returns:
TRUE - if the buffer was reallocated and the caller
should try the API again.
--*/
{
BOOLEAN TryAgain;
//
// If this is an initial request, buffer will be null with a new buffer size
//
if (!*Buffer && BufferSize) {
*Status = EFI_BUFFER_TOO_SMALL;
}
//
// If the status code is "buffer too small", resize the buffer
//
TryAgain = FALSE;
if (*Status == EFI_BUFFER_TOO_SMALL) {
if (*Buffer) {
FreePool (*Buffer);
}
*Buffer = AllocatePool (BufferSize);
if (*Buffer) {
TryAgain = TRUE;
} else {
*Status = EFI_OUT_OF_RESOURCES;
}
}
//
// If there's an error, free the buffer
//
if (!TryAgain && EFI_ERROR(*Status) && *Buffer) {
FreePool (*Buffer);
*Buffer = NULL;
}
return TryAgain;
}
EFI_MEMORY_DESCRIPTOR *
LibMemoryMap (
OUT UINTN *NoEntries,
OUT UINTN *MapKey,
OUT UINTN *DescriptorSize,
OUT UINT32 *DescriptorVersion
)
{
EFI_STATUS Status;
EFI_MEMORY_DESCRIPTOR *Buffer;
UINTN BufferSize;
//
// Initialize for GrowBuffer loop
//
Status = EFI_SUCCESS;
Buffer = NULL;
BufferSize = sizeof(EFI_MEMORY_DESCRIPTOR);
//
// Call the real function
//
while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
Status = uefi_call_wrapper(BS->GetMemoryMap, 5, &BufferSize, Buffer, MapKey, DescriptorSize, DescriptorVersion);
}
//
// Convert buffer size to NoEntries
//
if (!EFI_ERROR(Status)) {
*NoEntries = BufferSize / *DescriptorSize;
}
return Buffer;
}
VOID *
LibGetVariableAndSize (
IN CHAR16 *Name,
IN EFI_GUID *VendorGuid,
OUT UINTN *VarSize
)
{
EFI_STATUS Status = EFI_SUCCESS;
VOID *Buffer;
UINTN BufferSize;
//
// Initialize for GrowBuffer loop
//
Buffer = NULL;
BufferSize = 100;
//
// Call the real function
//
while (GrowBuffer (&Status, &Buffer, BufferSize)) {
Status = uefi_call_wrapper(
RT->GetVariable,
5,
Name,
VendorGuid,
NULL,
&BufferSize,
Buffer
);
}
if (Buffer) {
*VarSize = BufferSize;
} else {
*VarSize = 0;
}
return Buffer;
}
VOID *
LibGetVariable (
IN CHAR16 *Name,
IN EFI_GUID *VendorGuid
)
{
UINTN VarSize;
return LibGetVariableAndSize (Name, VendorGuid, &VarSize);
}
EFI_STATUS
LibDeleteVariable (
IN CHAR16 *VarName,
IN EFI_GUID *VarGuid
)
{
VOID *VarBuf;
EFI_STATUS Status;
VarBuf = LibGetVariable(VarName,VarGuid);
Status = EFI_NOT_FOUND;
if (VarBuf) {
//
// Delete variable from Storage
//
Status = uefi_call_wrapper(
RT->SetVariable,
5,
VarName, VarGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0, NULL
);
ASSERT (!EFI_ERROR(Status));
FreePool(VarBuf);
}
return (Status);
}
EFI_STATUS
LibSetNVVariable (
IN CHAR16 *VarName,
IN EFI_GUID *VarGuid,
IN UINTN DataSize,
IN VOID *Data
)
{
EFI_STATUS Status;
Status = uefi_call_wrapper(
RT->SetVariable,
5,
VarName, VarGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
DataSize, Data
);
ASSERT (!EFI_ERROR(Status));
return (Status);
}
EFI_STATUS
LibSetVariable (
IN CHAR16 *VarName,
IN EFI_GUID *VarGuid,
IN UINTN DataSize,
IN VOID *Data
)
{
EFI_STATUS Status;
Status = uefi_call_wrapper(
RT->SetVariable,
5,
VarName, VarGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
DataSize, Data
);
ASSERT (!EFI_ERROR(Status));
return (Status);
}
EFI_STATUS
LibInsertToTailOfBootOrder (
IN UINT16 BootOption,
IN BOOLEAN OnlyInsertIfEmpty
)
{
UINT16 *BootOptionArray;
UINT16 *NewBootOptionArray;
UINTN VarSize;
UINTN Index;
EFI_STATUS Status;
BootOptionArray = LibGetVariableAndSize (VarBootOrder, &EfiGlobalVariable, &VarSize);
if (VarSize != 0 && OnlyInsertIfEmpty) {
if (BootOptionArray) {
FreePool (BootOptionArray);
}
return EFI_UNSUPPORTED;
}
VarSize += sizeof(UINT16);
NewBootOptionArray = AllocatePool (VarSize);
if (!NewBootOptionArray)
return EFI_OUT_OF_RESOURCES;
for (Index = 0; Index < ((VarSize/sizeof(UINT16)) - 1); Index++) {
NewBootOptionArray[Index] = BootOptionArray[Index];
}
//
// Insert in the tail of the array
//
NewBootOptionArray[Index] = BootOption;
Status = uefi_call_wrapper(
RT->SetVariable,
5,
VarBootOrder, &EfiGlobalVariable,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
VarSize, (VOID*) NewBootOptionArray
);
FreePool (NewBootOptionArray);
if (BootOptionArray) {
FreePool (BootOptionArray);
}
return Status;
}
BOOLEAN
ValidMBR(
IN MASTER_BOOT_RECORD *Mbr,
IN EFI_BLOCK_IO *BlkIo
)
{
UINT32 StartingLBA, EndingLBA;
UINT32 NewEndingLBA;
INTN i, j;
BOOLEAN ValidMbr;
if (Mbr->Signature != MBR_SIGNATURE) {
//
// The BPB also has this signature, so it can not be used alone.
//
return FALSE;
}
ValidMbr = FALSE;
for (i=0; i<MAX_MBR_PARTITIONS; i++) {
if ( Mbr->Partition[i].OSIndicator == 0x00 || EXTRACT_UINT32(Mbr->Partition[i].SizeInLBA) == 0 ) {
continue;
}
ValidMbr = TRUE;
StartingLBA = EXTRACT_UINT32(Mbr->Partition[i].StartingLBA);
EndingLBA = StartingLBA + EXTRACT_UINT32(Mbr->Partition[i].SizeInLBA) - 1;
if (EndingLBA > BlkIo->Media->LastBlock) {
//
// Compatability Errata:
// Some systems try to hide drive space with thier INT 13h driver
// This does not hide space from the OS driver. This means the MBR
// that gets created from DOS is smaller than the MBR created from
// a real OS (NT & Win98). This leads to BlkIo->LastBlock being
// wrong on some systems FDISKed by the OS.
//
//
if (BlkIo->Media->LastBlock < MIN_MBR_DEVICE_SIZE) {
//
// If this is a very small device then trust the BlkIo->LastBlock
//
return FALSE;
}
if (EndingLBA > (BlkIo->Media->LastBlock + MBR_ERRATA_PAD)) {
return FALSE;
}
}
for (j=i+1; j<MAX_MBR_PARTITIONS; j++) {
if (Mbr->Partition[j].OSIndicator == 0x00 || EXTRACT_UINT32(Mbr->Partition[j].SizeInLBA) == 0) {
continue;
}
if ( EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) >= StartingLBA &&
EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) <= EndingLBA ) {
//
// The Start of this region overlaps with the i'th region
//
return FALSE;
}
NewEndingLBA = EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) + EXTRACT_UINT32(Mbr->Partition[j].SizeInLBA) - 1;
if ( NewEndingLBA >= StartingLBA && NewEndingLBA <= EndingLBA ) {
//
// The End of this region overlaps with the i'th region
//
return FALSE;
}
}
}
//
// Non of the regions overlapped so MBR is O.K.
//
return ValidMbr;
}
UINT8
DecimaltoBCD(
IN UINT8 DecValue
)
{
return RtDecimaltoBCD (DecValue);
}
UINT8
BCDtoDecimal(
IN UINT8 BcdValue
)
{
return RtBCDtoDecimal (BcdValue);
}
EFI_STATUS
LibGetSystemConfigurationTable(
IN EFI_GUID *TableGuid,
IN OUT VOID **Table
)
{
UINTN Index;
for(Index=0;Index<ST->NumberOfTableEntries;Index++) {
if (CompareGuid(TableGuid,&(ST->ConfigurationTable[Index].VendorGuid))) {
*Table = ST->ConfigurationTable[Index].VendorTable;
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
CHAR16 *
LibGetUiString (
IN EFI_HANDLE Handle,
IN UI_STRING_TYPE StringType,
IN ISO_639_2 *LangCode,
IN BOOLEAN ReturnDevicePathStrOnMismatch
)
{
UI_INTERFACE *Ui;
UI_STRING_TYPE Index;
UI_STRING_ENTRY *Array;
EFI_STATUS Status;
Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handle, &UiProtocol, (VOID *)&Ui);
if (EFI_ERROR(Status)) {
return (ReturnDevicePathStrOnMismatch) ? DevicePathToStr(DevicePathFromHandle(Handle)) : NULL;
}
//
// Skip the first strings
//
for (Index = UiDeviceString, Array = Ui->Entry; Index < StringType; Index++, Array++) {
while (Array->LangCode) {
Array++;
}
}
//
// Search for the match
//
while (Array->LangCode) {
if (strcmpa (Array->LangCode, LangCode) == 0) {
return Array->UiString;
}
}
return (ReturnDevicePathStrOnMismatch) ? DevicePathToStr(DevicePathFromHandle(Handle)) : NULL;
}
+15
View File
@@ -0,0 +1,15 @@
#include "lib.h"
VOID
Pause(
VOID
)
// Pause until any key is pressed
{
EFI_INPUT_KEY Key;
EFI_STATUS Status EFI_UNUSED;
WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
Status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &Key);
ASSERT(!EFI_ERROR(Status));
}
+805
View File
@@ -0,0 +1,805 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
print.c
Abstract:
Revision History
--*/
#include "lib.h"
#include "internal/print.h"
#include "internal/va_print.h"
/* VA types/functions can be used if used internally so we can use default va_list always here */
//
// Declare runtime functions
//
#ifdef RUNTIME_CODE
#ifndef __GNUC__
#pragma RUNTIME_CODE(DbgPrint)
// For debugging..
/*
#pragma RUNTIME_CODE(ValueToHex)
#pragma RUNTIME_CODE(ValueToString)
#pragma RUNTIME_CODE(TimeToString)
*/
#endif /* !defined(__GNUC__) */
#endif
//
//
//
INTN
DbgPrint (
IN INTN mask,
IN CONST CHAR8 *fmt,
...
)
/*++
Routine Description:
Prints a formatted unicode string to the default StandardError console
Arguments:
mask - Bit mask of debug string. If a bit is set in the
mask that is also set in EFIDebug the string is
printed; otherwise, the string is not printed
fmt - Format string
Returns:
Length of string printed to the StandardError console
--*/
{
SIMPLE_TEXT_OUTPUT_INTERFACE *DbgOut;
PRINT_STATE ps;
va_list args;
UINTN back;
UINTN attr;
UINTN SavedAttribute;
if (!(EFIDebug & mask)) {
return 0;
}
va_start (args, fmt);
ZeroMem (&ps, sizeof(ps));
ps.Output = _DbgOut;
ps.fmt.Ascii = TRUE;
ps.fmt.pc = fmt;
va_copy(ps.args, args);
ps.Attr = EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_RED);
DbgOut = LibRuntimeDebugOut;
if (!DbgOut) {
DbgOut = ST->StdErr;
}
if (DbgOut) {
ps.Attr = DbgOut->Mode->Attribute;
ps.Context = DbgOut;
ps.SetAttr = (INTN (EFIAPI *)(VOID *, UINTN)) DbgOut->SetAttribute;
}
SavedAttribute = ps.Attr;
back = (ps.Attr >> 4) & 0xf;
ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back);
ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back);
ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back);
attr = ps.AttrNorm;
if (mask & D_WARN) {
attr = ps.AttrHighlight;
}
if (mask & D_ERROR) {
attr = ps.AttrError;
}
if (ps.SetAttr) {
ps.Attr = attr;
uefi_call_wrapper(ps.SetAttr, 2, ps.Context, attr);
}
_Print (&ps);
va_end (ps.args);
va_end (args);
//
// Restore original attributes
//
if (ps.SetAttr) {
uefi_call_wrapper(ps.SetAttr, 2, ps.Context, SavedAttribute);
}
return 0;
}
INTN EFIAPI
_DbgOut (
IN VOID *Context,
IN CHAR16 *Buffer
)
// Append string worker for DbgPrint
{
SIMPLE_TEXT_OUTPUT_INTERFACE *DbgOut;
DbgOut = Context;
// if (!DbgOut && ST && ST->ConOut) {
// DbgOut = ST->ConOut;
// }
if (DbgOut) {
if (IsLocalPrint(DbgOut->OutputString))
DbgOut->OutputString(DbgOut, Buffer);
else
uefi_call_wrapper(DbgOut->OutputString, 2, DbgOut, Buffer);
}
return 0;
}
INTN EFIAPI
_SPrint (
IN VOID *Context,
IN CHAR16 *Buffer
)
// Append string worker for UnicodeSPrint, PoolPrint and CatPrint
{
UINTN len;
POOL_PRINT *spc;
spc = Context;
len = StrLen(Buffer);
//
// Is the string is over the max truncate it
//
if (spc->len + len > spc->maxlen) {
len = spc->maxlen - spc->len;
}
//
// Append the new text
//
CopyMem (spc->str + spc->len, Buffer, len * sizeof(CHAR16));
spc->len += len;
//
// Null terminate it
//
if (spc->len < spc->maxlen) {
spc->str[spc->len] = 0;
} else if (spc->maxlen) {
spc->str[spc->maxlen] = 0;
}
return 0;
}
INTN EFIAPI
_PoolPrint (
IN VOID *Context,
IN CHAR16 *Buffer
)
// Append string worker for PoolPrint and CatPrint
{
UINTN newlen;
POOL_PRINT *spc;
spc = Context;
newlen = spc->len + StrLen(Buffer) + 1;
//
// Is the string is over the max, grow the buffer
//
if (newlen > spc->maxlen) {
//
// Grow the pool buffer
//
newlen += PRINT_STRING_LEN;
spc->maxlen = newlen;
spc->str = ReallocatePool (
spc->len * sizeof(CHAR16),
spc->maxlen * sizeof(CHAR16),
spc->str
);
if (!spc->str) {
spc->len = 0;
spc->maxlen = 0;
}
}
//
// Append the new text
//
return _SPrint (Context, Buffer);
}
UINTN
UnicodeSPrint (
OUT CHAR16 *Str,
IN UINTN StrSize,
IN CONST CHAR16 *fmt,
...
)
/*++
Routine Description:
Prints a formatted unicode string to a buffer
Arguments:
Str - Output buffer to print the formatted string into
StrSize - Size of Str. String is truncated to this size.
A size of 0 means there is no limit
fmt - The format string
Returns:
String length returned in buffer
--*/
{
va_list args;
UINTN len;
va_start (args, fmt);
len = UnicodeVSPrint(Str, StrSize, fmt, args);
va_end (args);
return len;
}
UINTN
AsciiSPrint (
OUT CHAR8 *Str,
IN UINTN StrSize,
IN CONST CHAR8 *fmt,
...
)
/*++
Routine Description:
Prints a formatted unicode string to a buffer
Arguments:
Str - Output buffer to print the formatted string into
StrSize - Size of Str. String is truncated to this size.
A size of 0 means there is no limit
fmt - The format string
Returns:
String length returned in buffer
--*/
{
va_list args;
UINTN len;
va_start (args, fmt);
len = AsciiVSPrint(Str, StrSize, fmt, args);
va_end (args);
return len;
}
CHAR16 *
PoolPrint (
IN CONST CHAR16 *fmt,
...
)
/*++
Routine Description:
Prints a formatted unicode string to allocated pool. The caller
must free the resulting buffer.
Arguments:
fmt - The format string
Returns:
Allocated buffer with the formatted string printed in it.
The caller must free the allocated buffer. The buffer
allocation is not packed.
--*/
{
va_list args;
CHAR16 *pool;
va_start (args, fmt);
pool = VPoolPrint(fmt, args);
va_end (args);
return pool;
}
CHAR16 *
CatPrint (
IN OUT POOL_PRINT *Str,
IN CONST CHAR16 *fmt,
...
)
/*++
Routine Description:
Concatenates a formatted unicode string to allocated pool.
The caller must free the resulting buffer.
Arguments:
Str - Tracks the allocated pool, size in use, and
amount of pool allocated.
fmt - The format string
Returns:
Allocated buffer with the formatted string printed in it.
The caller must free the allocated buffer. The buffer
allocation is not packed.
--*/
{
va_list args;
va_start (args, fmt);
_PoolCatPrint (fmt, args, Str, _PoolPrint);
va_end (args);
return Str->str;
}
UINTN
Print (
IN CONST CHAR16 *fmt,
...
)
/*++
Routine Description:
Prints a formatted unicode string to the default console
Arguments:
fmt - Format string
Returns:
Length of string printed to the console
--*/
{
va_list args;
UINTN back;
va_start (args, fmt);
back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args);
va_end (args);
return back;
}
UINTN
PrintAt (
IN UINTN Column,
IN UINTN Row,
IN CONST CHAR16 *fmt,
...
)
/*++
Routine Description:
Prints a formatted unicode string to the default console, at
the supplied cursor position
Arguments:
Column, Row - The cursor position to print the string at
fmt - Format string
Returns:
Length of string printed to the console
--*/
{
va_list args;
UINTN back;
va_start (args, fmt);
back = _IPrint (Column, Row, ST->ConOut, fmt, NULL, args);
va_end (args);
return back;
}
UINTN
IPrint (
IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
IN CONST CHAR16 *fmt,
...
)
/*++
Routine Description:
Prints a formatted unicode string to the specified console
Arguments:
Out - The console to print the string too
fmt - Format string
Returns:
Length of string printed to the console
--*/
{
va_list args;
UINTN back;
va_start (args, fmt);
back = _IPrint ((UINTN) -1, (UINTN) -1, Out, fmt, NULL, args);
va_end (args);
return back;
}
UINTN
IPrintAt (
IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
IN UINTN Column,
IN UINTN Row,
IN CONST CHAR16 *fmt,
...
)
/*++
Routine Description:
Prints a formatted unicode string to the specified console, at
the supplied cursor position
Arguments:
Out - The console to print the string to
Column, Row - The cursor position to print the string at
fmt - Format string
Returns:
Length of string printed to the console
--*/
{
va_list args;
UINTN back;
va_start (args, fmt);
back = _IPrint (Column, Row, Out, fmt, NULL, args);
va_end (args);
return back;
}
UINTN
AsciiPrint (
IN CONST CHAR8 *fmt,
...
)
/*++
Routine Description:
For those whom really can't deal with unicode, a print
function that takes an ascii format string
Arguments:
fmt - ascii format string
Returns:
Length of string printed to the console
--*/
{
va_list args;
UINTN back;
va_start (args, fmt);
back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, NULL, fmt, args);
va_end (args);
return back;
}
STATIC CHAR8 Hex[] = {'0','1','2','3','4','5','6','7',
'8','9','A','B','C','D','E','F'};
VOID
ValueToHex (
IN CHAR16 *Buffer,
IN UINT64 v
)
{
CHAR8 str[30], *p1;
CHAR16 *p2;
if (!v) {
Buffer[0] = '0';
Buffer[1] = 0;
return ;
}
p1 = str;
p2 = Buffer;
while (v) {
// Without the cast, the MSVC compiler may insert a reference to __allmull
*(p1++) = Hex[(UINTN)(v & 0xf)];
v = RShiftU64 (v, 4);
}
while (p1 != str) {
*(p2++) = *(--p1);
}
*p2 = 0;
}
VOID
ValueToString (
IN CHAR16 *Buffer,
IN BOOLEAN Comma,
IN INT64 v
)
{
STATIC CHAR8 ca[] = { 3, 1, 2 };
CHAR8 str[40], *p1;
CHAR16 *p2;
UINTN c, r;
if (!v) {
Buffer[0] = '0';
Buffer[1] = 0;
return ;
}
p1 = str;
p2 = Buffer;
if (v < 0) {
*(p2++) = '-';
v = -v;
}
while (v) {
v = (INT64)DivU64x32 ((UINT64)v, 10, &r);
*(p1++) = (CHAR8)r + '0';
}
c = (UINTN) (Comma ? ca[(p1 - str) % 3] : 999) + 1;
while (p1 != str) {
c -= 1;
if (!c) {
*(p2++) = ',';
c = 3;
}
*(p2++) = *(--p1);
}
*p2 = 0;
}
// Having this call inlined by VS2022 on Release builds produces an
// "Undefined OpCode Exception" on ARM32 whenever Print() is invoked,
// even when no part of the code below is actually being executed...
// For safety, add an explicit clause to prevent inlining on all platforms.
EFI_NOINLINE
VOID
FloatToString (
IN CHAR16 *Buffer,
IN BOOLEAN Comma,
IN double v
)
{
/*
* Integer part.
*/
INTN i = (INTN)v;
ValueToString(Buffer, Comma, i);
/*
* Decimal point.
*/
UINTN x = StrLen(Buffer);
Buffer[x] = u'.';
x++;
/*
* Keep fractional part.
*/
float f = (float)(v - i);
if (f < 0) f = -f;
/*
* Leading fractional zeroes.
*/
f *= 10.0;
while ( (f != 0)
&& ((INTN)f == 0))
{
Buffer[x] = u'0';
x++;
f *= 10.0;
}
/*
* Fractional digits.
*/
while ((float)(INTN)f != f)
{
f *= 10;
}
ValueToString(Buffer + x, FALSE, (INTN)f);
return;
}
VOID
TimeToString (
OUT CHAR16 *Buffer,
IN EFI_TIME *Time
)
{
UINTN Hour, Year;
CHAR16 AmPm;
AmPm = 'a';
Hour = Time->Hour;
if (Time->Hour == 0) {
Hour = 12;
} else if (Time->Hour >= 12) {
AmPm = 'p';
if (Time->Hour >= 13) {
Hour -= 12;
}
}
Year = Time->Year % 100;
// bugbug: for now just print it any old way
UnicodeSPrint (Buffer, 0, u"%02d/%02d/%02d %02d:%02d%c",
Time->Month,
Time->Day,
Year,
Hour,
Time->Minute,
AmPm
);
}
VOID
DumpHex (
IN UINTN Indent,
IN UINTN Offset,
IN UINTN DataSize,
IN VOID *UserData
)
{
CHAR8 *Data, Val[50], Str[20], c;
UINTN Size, Index;
UINTN ScreenCount;
UINTN TempColumn;
UINTN ScreenSize;
CHAR16 ReturnStr[1];
uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, &TempColumn, &ScreenSize);
ScreenCount = 0;
ScreenSize -= 2;
Data = UserData;
while (DataSize) {
Size = 16;
if (Size > DataSize) {
Size = DataSize;
}
for (Index=0; Index < Size; Index += 1) {
c = Data[Index];
Val[Index*3+0] = Hex[c>>4];
Val[Index*3+1] = Hex[c&0xF];
Val[Index*3+2] = (Index == 7)?'-':' ';
Str[Index] = (c < ' ' || c > 'z') ? '.' : c;
}
Val[Index*3] = 0;
Str[Index] = 0;
Print (u"%*a%X: %-.48a *%a*\n", Indent, "", Offset, Val, Str);
Data += Size;
Offset += Size;
DataSize -= Size;
ScreenCount++;
if (ScreenCount >= ScreenSize && ScreenSize != 0) {
//
// If ScreenSize == 0 we have the console redirected so don't
// block updates
//
ScreenCount = 0;
Print (u"Press Enter to continue :");
Input (u"", ReturnStr, sizeof(ReturnStr)/sizeof(CHAR16));
Print (u"\n");
}
}
}
+203
View File
@@ -0,0 +1,203 @@
/*++
Copyright (c) 1999 Intel Corporation
Module Name:
EfiRtLib.h
Abstract:
EFI Runtime library functions
Revision History
--*/
#include "efi.h"
#include "efilib.h"
#include "efirtlib.h"
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtZeroMem)
#endif
VOID
RUNTIMEFUNCTION
RtZeroMem (
IN VOID *Buffer,
IN UINTN Size
)
{
UINT8 *pt;
pt = Buffer;
while (Size--) {
*(pt++) = 0;
}
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtSetMem)
#endif
VOID
EFIAPI
RUNTIMEFUNCTION
RtSetMem (
IN VOID *Buffer,
IN UINTN Size,
IN UINT8 Value
)
{
UINT8 *pt;
pt = Buffer;
while (Size--) {
*(pt++) = Value;
}
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtCopyMem)
#endif
VOID
EFIAPI
RUNTIMEFUNCTION
RtCopyMem (
IN VOID *Dest,
IN VOID *Src,
IN UINTN len
)
{
UINT8 *d, *s;
d = Dest;
s = Src;
if (d == NULL || s == NULL || s == d)
return;
// If the beginning of the destination range overlaps with the end of
// the source range, make sure to start the copy from the end so that
// we don't end up overwriting source data that we need for the copy.
if ((d > s) && (d < s + len)) {
for (d += len, s += len; len--; )
*--d = *--s;
} else {
while (len--)
*d++ = *s++;
}
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtCopyMemC)
#endif
VOID
EFIAPI
RUNTIMEFUNCTION
RtCopyMemC (
IN VOID *Dest,
IN CONST VOID *Src,
IN UINTN len
)
{
/* CopyMem matches ISO C apart from the change to NON-CONST Src
Overwriting Src is an intended outcome if overlapping occurs (per memmove)
This function is useful to avoid GCC dying in changing pointer setup
*/
RtCopyMem(Dest, (VOID*)Src, len);
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtCompareMem)
#endif
INTN
RUNTIMEFUNCTION
RtCompareMem (
IN CONST VOID *Dest,
IN CONST VOID *Src,
IN UINTN len
)
{
CONST UINT8 *d, *s;
d = Dest;
s = Src;
while (len--) {
if (*d != *s) {
return *d - *s;
}
d += 1;
s += 1;
}
return 0;
}
typedef UINT32 QUAD_UINT32[4]; /* EFI_GUID is 128 bits so 32 x 4 */
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtCompareGuid)
#endif
BOOLEAN
EFIAPI
RUNTIMEFUNCTION
RtCompareGuid (
IN CONST EFI_GUID *Guid1,
IN CONST EFI_GUID *Guid2
)
/*++
Routine Description:
Compares two GUIDs
Arguments:
Guid1 - guid to compare
Guid2 - guid to compare
Returns:
= 1 if Guid1 == Guid2
--*/
{
CONST QUAD_UINT32 *g1, *g2;
UINT32 r;
//
// Compare 32 bits at a time
//
g1 = (CONST QUAD_UINT32*)Guid1;
g2 = (CONST QUAD_UINT32*)Guid2;
r = (*g1)[0] - (*g2)[0];
r |= (*g1)[1] - (*g2)[1];
r |= (*g1)[2] - (*g2)[2];
r |= (*g1)[3] - (*g2)[3];
if (r==0) {
return 1;
} else {
return 0;
}
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtIsZeroGuid)
#endif
BOOLEAN
EFIAPI
RUNTIMEFUNCTION
RtIsZeroGuid (
IN CONST EFI_GUID *Guid1
)
{
return RtCompareGuid(Guid1, &gZeroGuid);
}
+65
View File
@@ -0,0 +1,65 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
data.c
Abstract:
EFI library global data
Revision History
--*/
#include "lib.h"
//
// These globals are runtime globals
//
// N.B. The Microsoft C compiler will only put the data in the
// right data section if it is explicitly initialized..
//
#ifndef __GNUC__
#pragma BEGIN_RUNTIME_DATA()
#endif
//
// RT - pointer to the runtime table
//
EFI_RUNTIME_SERVICES *RT;
//
// LibStandalone - TRUE if lib is linked in as part of the firmware.
// N.B. The EFI fw sets this value directly
//
BOOLEAN LibFwInstance;
//
// EFIDebug - Debug mask
//
UINTN EFIDebug = EFI_DBUG_MASK;
//
// LibRuntimeDebugOut - Runtime Debug Output device
//
SIMPLE_TEXT_OUTPUT_INTERFACE *LibRuntimeDebugOut;
//
// LibRuntimeRaiseTPL, LibRuntimeRestoreTPL - pointers to Runtime functions from the
// Boot Services Table
//
EFI_RAISE_TPL LibRuntimeRaiseTPL = NULL;
EFI_RESTORE_TPL LibRuntimeRestoreTPL = NULL;
+102
View File
@@ -0,0 +1,102 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
lock.c
Abstract:
Implements FLOCK
Revision History
--*/
#include "lib.h"
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtAcquireLock)
#endif
VOID
RtAcquireLock (
IN FLOCK *Lock
)
/*++
Routine Description:
Raising to the task priority level of the mutual exclusion
lock, and then acquires ownership of the lock.
Arguments:
Lock - The lock to acquire
Returns:
Lock owned
--*/
{
if (BS) {
if (BS->RaiseTPL != NULL) {
Lock->OwnerTpl = uefi_call_wrapper(BS->RaiseTPL, 1, Lock->Tpl);
}
}
else {
if (LibRuntimeRaiseTPL != NULL) {
Lock->OwnerTpl = LibRuntimeRaiseTPL(Lock->Tpl);
}
}
Lock->Lock += 1;
ASSERT (Lock->Lock == 1);
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtAcquireLock)
#endif
VOID
RtReleaseLock (
IN FLOCK *Lock
)
/*++
Routine Description:
Releases ownership of the mutual exclusion lock, and
restores the previous task priority level.
Arguments:
Lock - The lock to release
Returns:
Lock unowned
--*/
{
EFI_TPL Tpl;
Tpl = Lock->OwnerTpl;
ASSERT(Lock->Lock == 1);
Lock->Lock -= 1;
if (BS) {
if (BS->RestoreTPL != NULL) {
uefi_call_wrapper(BS->RestoreTPL, 1, Tpl);
}
}
else {
if (LibRuntimeRestoreTPL != NULL) {
LibRuntimeRestoreTPL(Tpl);
}
}
}
+233
View File
@@ -0,0 +1,233 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
str.c
Abstract:
String runtime functions
Revision History
--*/
#include "lib.h"
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtStrCmp)
#endif
INTN
RUNTIMEFUNCTION
RtStrCmp (
IN CONST CHAR16 *s1,
IN CONST CHAR16 *s2
)
// compare strings
{
while (*s1) {
if (*s1 != *s2) {
break;
}
s1 += 1;
s2 += 1;
}
return *s1 - *s2;
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtStrCpy)
#endif
VOID
RUNTIMEFUNCTION
RtStrCpy (
IN CHAR16 *Dest,
IN CONST CHAR16 *Src
)
// copy strings
{
while (*Src) {
*(Dest++) = *(Src++);
}
*Dest = 0;
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtStrnCpy)
#endif
VOID
RUNTIMEFUNCTION
RtStrnCpy (
IN CHAR16 *Dest,
IN CONST CHAR16 *Src,
IN UINTN Len
)
// copy strings
{
UINTN Size = RtStrnLen(Src, Len);
if (Size != Len)
RtSetMem(Dest + Size, (Len - Size) * sizeof(CHAR16), '\0');
RtCopyMemC(Dest, Src, Size * sizeof(CHAR16));
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtStpCpy)
#endif
CHAR16 *
RUNTIMEFUNCTION
RtStpCpy (
IN CHAR16 *Dest,
IN CONST CHAR16 *Src
)
// copy strings
{
while (*Src) {
*(Dest++) = *(Src++);
}
*Dest = 0;
return Dest;
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtStpnCpy)
#endif
CHAR16 *
RUNTIMEFUNCTION
RtStpnCpy (
IN CHAR16 *Dest,
IN CONST CHAR16 *Src,
IN UINTN Len
)
// copy strings
{
UINTN Size = RtStrnLen(Src, Len);
if (Size != Len)
RtSetMem(Dest + Size, (Len - Size) * sizeof(CHAR16), '\0');
RtCopyMemC(Dest, Src, Size * sizeof(CHAR16));
return Dest + Size;
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtStrCat)
#endif
VOID
RUNTIMEFUNCTION
RtStrCat (
IN CHAR16 *Dest,
IN CONST CHAR16 *Src
)
{
RtStrCpy(Dest+RtStrLen(Dest), Src);
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtStrnCat)
#endif
VOID
RUNTIMEFUNCTION
RtStrnCat (
IN CHAR16 *Dest,
IN CONST CHAR16 *Src,
IN UINTN Len
)
{
UINTN DestSize, Size;
DestSize = RtStrLen(Dest);
Size = RtStrnLen(Src, Len);
RtCopyMemC(Dest + DestSize, Src, Size * sizeof(CHAR16));
Dest[DestSize + Size] = '\0';
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtStrLen)
#endif
UINTN
RUNTIMEFUNCTION
RtStrLen (
IN CONST CHAR16 *s1
)
// string length
{
UINTN len;
for (len=0; *s1; s1+=1, len+=1) ;
return len;
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtStrnLen)
#endif
UINTN
RUNTIMEFUNCTION
RtStrnLen (
IN CONST CHAR16 *s1,
IN UINTN Len
)
// string length
{
UINTN i;
for (i = 0; *s1 && i < Len; i++)
s1++;
return i;
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtStrSize)
#endif
UINTN
RUNTIMEFUNCTION
RtStrSize (
IN CONST CHAR16 *s1
)
// string size
{
UINTN len;
for (len=0; *s1; s1+=1, len+=1) ;
return (len + 1) * sizeof(CHAR16);
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtBCDtoDecimal)
#endif
UINT8
RUNTIMEFUNCTION
RtBCDtoDecimal(
IN UINT8 BcdValue
)
{
UINTN High, Low;
High = BcdValue >> 4;
Low = BcdValue - (High << 4);
return ((UINT8)(Low + (High * 10)));
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtDecimaltoBCD)
#endif
UINT8
RUNTIMEFUNCTION
RtDecimaltoBCD (
IN UINT8 DecValue
)
{
UINTN High, Low;
High = DecValue / 10;
Low = DecValue - (High * 10);
return ((UINT8)(Low + (High << 4)));
}
+105
View File
@@ -0,0 +1,105 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
vm.c
Abstract:
EFI Hell to remap runtime address into the new virual address space
that was registered by the OS for RT calls.
So the code image needs to be relocated. All pointers need to be
manually fixed up since the address map changes.
GOOD LUCK NOT HAVING BUGS IN YOUR CODE! PLEASE TEST A LOT. MAKE SURE
EXIT BOOTSERVICES OVER WRITES ALL BOOTSERVICE MEMORY & DATA SPACES WHEN
YOU TEST.
Revision History
--*/
#include "lib.h"
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtLibEnableVirtualMappings)
#endif
VOID
RUNTIMEFUNCTION
RtLibEnableVirtualMappings (
VOID
)
{
EFI_CONVERT_POINTER ConvertPointer;
//
// If this copy of the lib is linked into the firmware, then
// do not update the pointers yet.
//
if (!LibFwInstance) {
//
// Different components are updating to the new virtual
// mappings at differnt times. The only function that
// is safe to call at this notification is ConvertAddress
//
ConvertPointer = RT->ConvertPointer;
//
// Fix any pointers that the lib created, that may be needed
// during runtime.
//
ConvertPointer (EFI_INTERNAL_PTR, (VOID **)&RT);
ConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&LibRuntimeDebugOut);
ConvertPointer (EFI_INTERNAL_PTR, (VOID **)&LibRuntimeRaiseTPL);
ConvertPointer (EFI_INTERNAL_PTR, (VOID **)&LibRuntimeRestoreTPL);
// that was it :^)
}
}
#ifndef __GNUC__
#pragma RUNTIME_CODE(RtConvertList)
#endif
VOID
RUNTIMEFUNCTION
RtConvertList (
IN UINTN DebugDisposition,
IN OUT LIST_ENTRY *ListHead
)
{
LIST_ENTRY *Link;
LIST_ENTRY *NextLink;
EFI_CONVERT_POINTER ConvertPointer;
ConvertPointer = RT->ConvertPointer;
//
// Convert all the Flink & Blink pointers in the list
//
Link = ListHead;
do {
NextLink = Link->Flink;
ConvertPointer (
Link->Flink == ListHead ? DebugDisposition : 0,
(VOID **)&Link->Flink
);
ConvertPointer (
Link->Blink == ListHead ? DebugDisposition : 0,
(VOID **)&Link->Blink
);
Link = NextLink;
} while (Link != ListHead);
}
+135
View File
@@ -0,0 +1,135 @@
/*++
Copyright (c) 2000 Intel Corporation
Module Name:
Smbios.c
Abstract:
Lib fucntions for SMBIOS. Used to get system serial number and GUID
Revision History
--*/
#include "lib.h"
/*
* We convert 32 bit values to pointers. In 64 bit mode the compiler will issue a
* warning stating that the value is too small for the pointer:
* "warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]"
* we can safely ignore them here.
*/
#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
#endif
EFI_STATUS
LibGetSmbiosSystemGuidAndSerialNumber (
IN EFI_GUID *SystemGuid,
OUT CHAR8 **SystemSerialNumber
)
{
EFI_STATUS Status;
SMBIOS_STRUCTURE_TABLE *SmbiosTable;
SMBIOS_STRUCTURE_POINTER Smbios;
SMBIOS_STRUCTURE_POINTER SmbiosEnd;
UINT16 Index;
Status = LibGetSystemConfigurationTable(&SMBIOSTableGuid, (VOID**)&SmbiosTable);
if (EFI_ERROR(Status)) {
return EFI_NOT_FOUND;
}
Smbios.Hdr = (SMBIOS_HEADER *)SmbiosTable->TableAddress;
SmbiosEnd.Raw = (UINT8 *)((UINTN)SmbiosTable->TableAddress + SmbiosTable->TableLength);
for (Index = 0; Index < SmbiosTable->TableLength ; Index++) {
if (Smbios.Hdr->Type == 1) {
if (Smbios.Hdr->Length < 0x19) {
//
// Older version did not support Guid and Serial number
//
continue;
}
//
// SMBIOS tables are byte packed so we need to do a byte copy to
// prevend alignment faults on IA-64.
CopyMem (SystemGuid, &Smbios.Type1->Uuid, sizeof(EFI_GUID));
*SystemSerialNumber = LibGetSmbiosString(&Smbios, Smbios.Type1->SerialNumber);
return EFI_SUCCESS;
}
//
// Make Smbios point to the next record
//
LibGetSmbiosString (&Smbios, -1);
if (Smbios.Raw >= SmbiosEnd.Raw) {
//
// SMBIOS 2.1 incorrectly stated the length of SmbiosTable as 0x1e.
// given this we must double check against the lenght of
/// the structure. My home PC has this bug.ruthard
//
return EFI_SUCCESS;
}
}
return EFI_SUCCESS;
}
CHAR8*
LibGetSmbiosString (
IN SMBIOS_STRUCTURE_POINTER *Smbios,
IN UINT16 StringNumber
)
/*++
Return SMBIOS string given the string number.
Arguments:
Smbios - Pointer to SMBIOS structure
StringNumber - String number to return. -1 is used to skip all strings and
point to the next SMBIOS structure.
Returns:
Pointer to string, or pointer to next SMBIOS strcuture if StringNumber == -1
--*/
{
UINT16 Index;
CHAR8 *String;
//
// Skip over formatted section
//
String = (CHAR8 *)(Smbios->Raw + Smbios->Hdr->Length);
//
// Look through unformated section
//
for (Index = 1; Index <= StringNumber; Index++) {
if (StringNumber == Index) {
return String;
}
//
// Skip string
//
for (; *String != 0; String++);
String++;
if (*String == 0) {
//
// If double NULL then we are done.
// Retrun pointer to next structure in Smbios.
// if you pass in a -1 you will always get here
//
Smbios->Raw = (UINT8 *)++String;
return NULL;
}
}
return NULL;
}
+358
View File
@@ -0,0 +1,358 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
sread.c
Abstract:
Simple read file access
Revision History
--*/
#include "lib.h"
#define SIMPLE_READ_SIGNATURE EFI_SIGNATURE_32('s','r','d','r')
typedef struct _SIMPLE_READ_FILE {
UINTN Signature;
BOOLEAN FreeBuffer;
VOID *Source;
UINTN SourceSize;
EFI_FILE_HANDLE FileHandle;
} SIMPLE_READ_HANDLE;
EFI_STATUS
OpenSimpleReadFile (
IN BOOLEAN BootPolicy,
IN VOID *SourceBuffer OPTIONAL,
IN UINTN SourceSize,
IN OUT EFI_DEVICE_PATH **FilePath,
OUT EFI_HANDLE *DeviceHandle,
OUT SIMPLE_READ_FILE *SimpleReadHandle
)
/*++
Routine Description:
Opens a file for (simple) reading. The simple read abstraction
will access the file either from a memory copy, from a file
system interface, or from the load file interface.
Arguments:
Returns:
A handle to access the file
--*/
{
SIMPLE_READ_HANDLE *FHand;
EFI_DEVICE_PATH *UserFilePath;
EFI_DEVICE_PATH *TempFilePath;
EFI_DEVICE_PATH *TempFilePathPtr;
FILEPATH_DEVICE_PATH *FilePathNode;
EFI_FILE_HANDLE FileHandle, LastHandle;
EFI_STATUS Status;
EFI_LOAD_FILE_INTERFACE *LoadFile;
FHand = NULL;
UserFilePath = *FilePath;
//
// Allocate a new simple read handle structure
//
FHand = AllocateZeroPool (sizeof(SIMPLE_READ_HANDLE));
if (!FHand) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
*SimpleReadHandle = (SIMPLE_READ_FILE) FHand;
FHand->Signature = SIMPLE_READ_SIGNATURE;
//
// If the caller passed a copy of the file, then just use it
//
if (SourceBuffer) {
FHand->Source = SourceBuffer;
FHand->SourceSize = SourceSize;
*DeviceHandle = NULL;
Status = EFI_SUCCESS;
goto Done;
}
//
// Attempt to access the file via a file system interface
//
FileHandle = NULL;
Status = uefi_call_wrapper(BS->LocateDevicePath, 3, &FileSystemProtocol, FilePath, DeviceHandle);
if (!EFI_ERROR(Status)) {
FileHandle = LibOpenRoot (*DeviceHandle);
}
Status = FileHandle ? EFI_SUCCESS : EFI_UNSUPPORTED;
//
// To access as a filesystem, the filepath should only
// contain filepath components. Follow the filepath nodes
// and find the target file
//
FilePathNode = (FILEPATH_DEVICE_PATH *) *FilePath;
while (!IsDevicePathEnd(&FilePathNode->Header)) {
//
// For filesystem access each node should be a filepath component
//
if (DevicePathType(&FilePathNode->Header) != MEDIA_DEVICE_PATH ||
DevicePathSubType(&FilePathNode->Header) != MEDIA_FILEPATH_DP) {
Status = EFI_UNSUPPORTED;
}
//
// If there's been an error, stop
//
if (EFI_ERROR(Status)) {
break;
}
//
// Open this file path node
//
LastHandle = FileHandle;
FileHandle = NULL;
Status = uefi_call_wrapper(
LastHandle->Open,
5,
LastHandle,
&FileHandle,
FilePathNode->PathName,
EFI_FILE_MODE_READ,
0
);
//
// Close the last node
//
uefi_call_wrapper(LastHandle->Close, 1, LastHandle);
//
// Get the next node
//
FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode(&FilePathNode->Header);
}
//
// If success, return the FHand
//
if (!EFI_ERROR(Status)) {
ASSERT(FileHandle);
FHand->FileHandle = FileHandle;
goto Done;
}
//
// Cleanup from filesystem access
//
if (FileHandle) {
uefi_call_wrapper(FileHandle->Close, 1, FileHandle);
FileHandle = NULL;
*FilePath = UserFilePath;
}
//
// If the error is something other then unsupported, return it
//
if (Status != EFI_UNSUPPORTED) {
goto Done;
}
//
// Attempt to access the file via the load file protocol
//
Status = LibDevicePathToInterface (&LoadFileProtocol, *FilePath, (VOID*)&LoadFile);
if (!EFI_ERROR(Status)) {
TempFilePath = DuplicateDevicePath (*FilePath);
TempFilePathPtr = TempFilePath;
Status = uefi_call_wrapper(BS->LocateDevicePath, 3, &LoadFileProtocol, &TempFilePath, DeviceHandle);
FreePool (TempFilePathPtr);
//
// Determine the size of buffer needed to hold the file
//
SourceSize = 0;
Status = uefi_call_wrapper(
LoadFile->LoadFile,
5,
LoadFile,
*FilePath,
BootPolicy,
&SourceSize,
NULL
);
//
// We expect a buffer too small error to inform us
// of the buffer size needed
//
if (Status == EFI_BUFFER_TOO_SMALL) {
SourceBuffer = AllocatePool (SourceSize);
if (SourceBuffer) {
FHand->FreeBuffer = TRUE;
FHand->Source = SourceBuffer;
FHand->SourceSize = SourceSize;
Status = uefi_call_wrapper(
LoadFile->LoadFile,
5,
LoadFile,
*FilePath,
BootPolicy,
&SourceSize,
SourceBuffer
);
}
}
//
// If success, return FHand
//
if (!EFI_ERROR(Status) || Status == EFI_ALREADY_STARTED) {
goto Done;
}
}
//
// Nothing else to try
//
DEBUG ((D_LOAD|D_WARN, "OpenSimpleReadFile: Device did not support a known load protocol\n"));
Status = EFI_UNSUPPORTED;
Done:
//
// If the file was not accessed, clean up
//
if (EFI_ERROR(Status) && (Status != EFI_ALREADY_STARTED)) {
if (FHand) {
if (FHand->FreeBuffer) {
FreePool (FHand->Source);
}
FreePool (FHand);
}
}
return Status;
}
EFI_STATUS
ReadSimpleReadFile (
IN SIMPLE_READ_FILE UserHandle,
IN UINTN Offset,
IN OUT UINTN *ReadSize,
OUT VOID *Buffer
)
{
UINTN EndPos;
SIMPLE_READ_HANDLE *FHand;
EFI_STATUS Status;
FHand = UserHandle;
ASSERT (FHand->Signature == SIMPLE_READ_SIGNATURE);
if (FHand->Source) {
//
// Move data from our local copy of the file
//
EndPos = Offset + *ReadSize;
if (EndPos > FHand->SourceSize) {
*ReadSize = FHand->SourceSize - Offset;
if (Offset >= FHand->SourceSize) {
*ReadSize = 0;
}
}
CopyMem (Buffer, (CHAR8 *) FHand->Source + Offset, *ReadSize);
Status = EFI_SUCCESS;
} else {
//
// Read data from the file
//
Status = uefi_call_wrapper(FHand->FileHandle->SetPosition, 2, FHand->FileHandle, Offset);
if (!EFI_ERROR(Status)) {
Status = uefi_call_wrapper(FHand->FileHandle->Read, 3, FHand->FileHandle, ReadSize, Buffer);
}
}
return Status;
}
VOID
CloseSimpleReadFile (
IN SIMPLE_READ_FILE UserHandle
)
{
SIMPLE_READ_HANDLE *FHand;
FHand = UserHandle;
ASSERT (FHand->Signature == SIMPLE_READ_SIGNATURE);
//
// Free any file handle we opened
//
if (FHand->FileHandle) {
uefi_call_wrapper(FHand->FileHandle->Close, 1, FHand->FileHandle);
}
//
// If we allocated the Source buffer, free it
//
if (FHand->FreeBuffer) {
FreePool (FHand->Source);
}
//
// Done with this simple read file handle
//
FreePool (FHand);
}
+432
View File
@@ -0,0 +1,432 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
str.c
Abstract:
Revision History
--*/
#include "lib.h"
INTN
StrCmp (
IN CONST CHAR16 *s1,
IN CONST CHAR16 *s2
)
// compare strings
{
return RtStrCmp(s1, s2);
}
INTN
StrnCmp (
IN CONST CHAR16 *s1,
IN CONST CHAR16 *s2,
IN UINTN len
)
// compare strings
{
while (*s1 && len) {
if (*s1 != *s2) {
break;
}
s1 += 1;
s2 += 1;
len -= 1;
}
return len ? *s1 - *s2 : 0;
}
INTN EFIAPI
LibStubStriCmp (
IN EFI_UNICODE_COLLATION_INTERFACE *This EFI_UNUSED,
IN CHAR16 *s1,
IN CHAR16 *s2
)
{
return StrCmp (s1, s2);
}
VOID EFIAPI
LibStubStrLwrUpr (
IN EFI_UNICODE_COLLATION_INTERFACE *This EFI_UNUSED,
IN CHAR16 *Str EFI_UNUSED
)
{
}
INTN
StriCmp (
IN CONST CHAR16 *s1,
IN CONST CHAR16 *s2
)
// compare strings
{
if (UnicodeInterface == &LibStubUnicodeInterface)
return UnicodeInterface->StriColl(UnicodeInterface, (CHAR16 *)s1, (CHAR16 *)s2);
else
return uefi_call_wrapper(UnicodeInterface->StriColl, 3, UnicodeInterface, (CHAR16 *)s1, (CHAR16 *)s2);
}
VOID
StrLwr (
IN CHAR16 *Str
)
// lwoer case string
{
if (UnicodeInterface == &LibStubUnicodeInterface)
UnicodeInterface->StrLwr(UnicodeInterface, Str);
else uefi_call_wrapper(UnicodeInterface->StrLwr, 2, UnicodeInterface, Str);
}
VOID
StrUpr (
IN CHAR16 *Str
)
// upper case string
{
if (UnicodeInterface == &LibStubUnicodeInterface)
UnicodeInterface->StrUpr(UnicodeInterface, Str);
else uefi_call_wrapper(UnicodeInterface->StrUpr, 2, UnicodeInterface, Str);
}
VOID
StrCpy (
IN CHAR16 *Dest,
IN CONST CHAR16 *Src
)
// copy strings
{
RtStrCpy (Dest, Src);
}
VOID
StrnCpy (
IN CHAR16 *Dest,
IN CONST CHAR16 *Src,
IN UINTN Len
)
// copy strings
{
RtStrnCpy (Dest, Src, Len);
}
CHAR16 *
StpCpy (
IN CHAR16 *Dest,
IN CONST CHAR16 *Src
)
// copy strings
{
return RtStpCpy (Dest, Src);
}
CHAR16 *
StpnCpy (
IN CHAR16 *Dest,
IN CONST CHAR16 *Src,
IN UINTN Len
)
// copy strings
{
return RtStpnCpy (Dest, Src, Len);
}
VOID
StrCat (
IN CHAR16 *Dest,
IN CONST CHAR16 *Src
)
{
RtStrCat(Dest, Src);
}
VOID
StrnCat (
IN CHAR16 *Dest,
IN CONST CHAR16 *Src,
IN UINTN Len
)
{
RtStrnCat(Dest, Src, Len);
}
UINTN
StrnLen (
IN CONST CHAR16 *s1,
IN UINTN Len
)
// string length
{
return RtStrnLen(s1, Len);
}
UINTN
StrLen (
IN CONST CHAR16 *s1
)
// string length
{
return RtStrLen(s1);
}
UINTN
StrSize (
IN CONST CHAR16 *s1
)
// string size
{
return RtStrSize(s1);
}
CHAR16 *
StrDuplicate (
IN CONST CHAR16 *Src
)
// duplicate a string
{
CHAR16 *Dest;
UINTN Size;
Size = StrSize(Src);
Dest = AllocatePool (Size);
if (Dest) {
CopyMemC (Dest, Src, Size);
}
return Dest;
}
UINTN
AsciiStrLen (
IN CONST CHAR8 *s1
)
// string length
{
UINTN len;
for (len=0; *s1; s1+=1, len+=1) ;
return len;
}
UINTN
AsciiStrCmp (
IN CONST CHAR8 *s1,
IN CONST CHAR8 *s2
)
// compare strings
{
while (*s1) {
if (*s1 != *s2) {
break;
}
s1 += 1;
s2 += 1;
}
return *s1 - *s2;
}
UINTN
AsciiStrnCmp (
IN CONST CHAR8 *s1,
IN CONST CHAR8 *s2,
IN UINTN len
)
// compare strings
{
while (*s1 && len) {
if (*s1 != *s2) {
break;
}
s1 += 1;
s2 += 1;
len -= 1;
}
return len ? *s1 - *s2 : 0;
}
UINTN
xtoi (
CONST CHAR16 *str
)
// convert hex string to uint
{
UINTN u;
CHAR16 c;
// skip preceeding white space
while (*str == ' ') {
str += 1;
}
// convert hex digits
u = 0;
while ((c = *(str++))) {
if (c >= 'a' && c <= 'f') {
c -= 'a' - 'A';
}
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
u = (u << 4) | ((UINTN)c - (c >= 'A' ? 'A'-10 : '0'));
} else {
break;
}
}
return u;
}
UINTN
Atoi (
CONST CHAR16 *str
)
// convert hex string to uint
{
UINTN u;
CHAR16 c;
// skip preceeding white space
while (*str == ' ') {
str += 1;
}
// convert digits
u = 0;
while ((c = *(str++))) {
if (c >= '0' && c <= '9') {
u = (u * 10) + c - '0';
} else {
break;
}
}
return u;
}
BOOLEAN
MetaMatch (
IN CHAR16 *String,
IN CHAR16 *Pattern
)
{
CHAR16 c, p, l;
for (; ;) {
p = *Pattern;
Pattern += 1;
switch (p) {
case 0:
// End of pattern. If end of string, TRUE match
return *String ? FALSE : TRUE;
case '*':
// Match zero or more chars
while (*String) {
if (MetaMatch (String, Pattern)) {
return TRUE;
}
String += 1;
}
return MetaMatch (String, Pattern);
case '?':
// Match any one char
if (!*String) {
return FALSE;
}
String += 1;
break;
case '[':
// Match char set
c = *String;
if (!c) {
return FALSE; // syntax problem
}
l = 0;
while ((p = *Pattern++)) {
if (p == ']') {
return FALSE;
}
if (p == '-') { // if range of chars,
p = *Pattern; // get high range
if (p == 0 || p == ']') {
return FALSE; // syntax problem
}
if (c >= l && c <= p) { // if in range,
break; // it's a match
}
}
l = p;
if (c == p) { // if char matches
break; // move on
}
}
// skip to end of match char set
while (p && p != ']') {
p = *Pattern;
Pattern += 1;
}
String += 1;
break;
default:
c = *String;
if (c != p) {
return FALSE;
}
String += 1;
break;
}
}
}
BOOLEAN EFIAPI
LibStubMetaiMatch (
IN EFI_UNICODE_COLLATION_INTERFACE *This EFI_UNUSED,
IN CHAR16 *String,
IN CHAR16 *Pattern
)
{
return MetaMatch (String, Pattern);
}
BOOLEAN
MetaiMatch (
IN CHAR16 *String,
IN CHAR16 *Pattern
)
{
if (UnicodeInterface == &LibStubUnicodeInterface)
return UnicodeInterface->MetaiMatch(UnicodeInterface, String, Pattern);
else return uefi_call_wrapper(UnicodeInterface->MetaiMatch, 3, UnicodeInterface, String, Pattern);
}
+227
View File
@@ -0,0 +1,227 @@
#include "lib.h"
#include "internal/print.h"
#include "internal/va_print.h"
VOID
CALL_CONV
FUNCTION_NAME(_PoolCatPrint) (
IN CONST CHAR16 *fmt,
IN VA_LIST args,
IN OUT POOL_PRINT *spc,
IN INTN (EFIAPI *Output)(VOID *context, CHAR16 *str)
)
// Dispatch function for UnicodeSPrint, PoolPrint, and CatPrint
{
FUNCTION_NAME(PRINT_STATE) ps;
ZeroMem (&ps, sizeof(ps));
ps.Output = Output;
ps.Context = spc;
ps.fmt.pw = fmt;
VA_COPY(ps.args, args);
FUNCTION_NAME(_Print) (&ps);
VA_END(ps.args);
}
UINTN
CALL_CONV
FUNCTION_NAME(UnicodeVSPrint) (
OUT CHAR16 *Str,
IN UINTN StrSize,
IN CONST CHAR16 *fmt,
VA_LIST args
)
/*++
Routine Description:
Prints a formatted unicode string to a buffer using a VA_LIST
Arguments:
Str - Output buffer to print the formatted string into
StrSize - Size of Str (in bytes). String is truncated to this size.
A size of 0 means there is no limit
fmt - The format string
args - VA_LIST
Returns:
String length returned in buffer
--*/
{
POOL_PRINT spc;
spc.str = Str;
spc.maxlen = StrSize / sizeof(CHAR16) - 1;
spc.len = 0;
FUNCTION_NAME(_PoolCatPrint) (fmt, args, &spc, _SPrint);
return spc.len;
}
CHAR16 *
CALL_CONV
FUNCTION_NAME(VPoolPrint) (
IN CONST CHAR16 *fmt,
VA_LIST args
)
/*++
Routine Description:
Prints a formatted unicode string to allocated pool using VA_LIST argument.
The caller must free the resulting buffer.
Arguments:
fmt - The format string
args - The arguments in VA_LIST form
Returns:
Allocated buffer with the formatted string printed in it.
The caller must free the allocated buffer. The buffer
allocation is not packed.
--*/
{
POOL_PRINT spc;
ZeroMem (&spc, sizeof(spc));
FUNCTION_NAME(_PoolCatPrint) (fmt, args, &spc, _PoolPrint);
return spc.str;
}
UINTN
CALL_CONV
FUNCTION_NAME(VPrint) (
IN CONST CHAR16 *fmt,
VA_LIST args
)
/*++
Routine Description:
Prints a formatted unicode string to the default console using a VA_LIST
Arguments:
fmt - Format string
args - VA_LIST
Returns:
Length of string printed to the console
--*/
{
return FUNCTION_NAME(_IPrint) ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args);
}
UINTN
CALL_CONV
FUNCTION_NAME(_IPrint) (
IN UINTN Column,
IN UINTN Row,
IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
IN CONST CHAR16 *fmt,
IN CONST CHAR8 *fmta,
IN VA_LIST args
)
// Display string worker for: Print, PrintAt, IPrint, IPrintAt
{
FUNCTION_NAME(PRINT_STATE) ps;
UINTN back;
ZeroMem (&ps, sizeof(ps));
ps.Context = Out;
ps.Output = (INTN (EFIAPI *)(VOID *, CHAR16 *)) Out->OutputString;
ps.SetAttr = (INTN (EFIAPI *)(VOID *, UINTN)) Out->SetAttribute;
ps.Attr = Out->Mode->Attribute;
back = (ps.Attr >> 4) & 0xF;
ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back);
ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back);
ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back);
if (fmt) {
ps.fmt.pw = fmt;
} else {
ps.fmt.Ascii = TRUE;
ps.fmt.pc = fmta;
}
VA_COPY(ps.args, args);
if (Column != (UINTN) -1) {
uefi_call_wrapper(Out->SetCursorPosition, 3, Out, Column, Row);
}
back = FUNCTION_NAME(_Print) (&ps);
VA_END(ps.args);
return back;
}
UINTN
CALL_CONV
FUNCTION_NAME(AsciiVSPrint) (
OUT CHAR8 *Str,
IN UINTN StrSize,
IN CONST CHAR8 *fmt,
VA_LIST args
)
/*++
Routine Description:
Prints a formatted ascii string to a buffer using a VA_LIST
Arguments:
Str - Output buffer to print the formatted string into
StrSize - Size of Str (in bytes). String is truncated to this size.
A size of 0 means there is no limit
fmt - The format string
args - VA_LIST
Returns:
String length returned in buffer
--*/
// Use FUNCTION_NAME(UnicodeVSPrint)() and convert back to ASCII
{
CHAR16 *UnicodeStr, *UnicodeFmt;
UINTN i, Len;
UnicodeStr = AllocatePool(StrSize * sizeof(CHAR16));
if (!UnicodeStr)
return 0;
UnicodeFmt = PoolPrint(u"%a", fmt);
if (!UnicodeFmt) {
FreePool(UnicodeStr);
return 0;
}
Len = FUNCTION_NAME(UnicodeVSPrint)(UnicodeStr, StrSize * sizeof(CHAR16), UnicodeFmt, args);
FreePool(UnicodeFmt);
// The strings are ASCII so just do a plain Unicode conversion
for (i = 0; i < Len; i++)
Str[i] = (CHAR8)UnicodeStr[i];
Str[Len] = 0;
FreePool(UnicodeStr);
return Len;
}
+40
View File
@@ -0,0 +1,40 @@
/*
* Convert SysV calling convention to EFI x86_64 calling convention
*
* Copyright (C) 2007-2010 Intel Corp
* Bibo Mao <bibo.mao@intel.com>
* Chandramouli Narayanan<mouli@linux.intel.com>
* Huang Ying <ying.huang@intel.com>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
* - Neither the name of Hewlett-Packard Co. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* uefi_call_wrapper() is a macro in efibind.h */
+193
View File
@@ -0,0 +1,193 @@
/*
* Function calling ABI conversion from Linux to EFI for x86_64
*
* Copyright (C) 2007 Intel Corp
* Bibo Mao <bibo.mao@intel.com>
* Huang Ying <ying.huang@intel.com>
* Copyright (C) 2012 Felipe Contreras <felipe.contreras@gmail.com>
*/
#if !defined(HAVE_USE_MS_ABI)
/*
* EFI calling conventions are documented at:
* http://msdn.microsoft.com/en-us/library/ms235286%28v=vs.80%29.aspx
* ELF calling conventions are documented at:
* http://www.x86-64.org/documentation/abi.pdf
*
* Basically here are the conversion rules:
* a) our function pointer is in %rdi
* b) rsi through r8 (elf) aka rcx through r9 (ms) require stack space
* on the MS side even though it's not getting used at all.
* c) 8(%rsp) is always aligned to 16 in ELF, so %rsp is shifted 8 bytes extra
* d) arguments are as follows: (elf -> ms)
* 1) rdi -> rcx (32 saved)
* 2) rsi -> rdx (32 saved)
* 3) rdx -> r8 (32 saved)
* 4) rcx -> r9 (32 saved)
* 5) r8 -> 32(%rsp) (32 saved)
* 6) r9 -> 40(%rsp) (48 saved)
* 7) 8(%rsp) -> 48(%rsp) (48 saved)
* 8) 16(%rsp) -> 56(%rsp) (64 saved)
* 9) 24(%rsp) -> 64(%rsp) (64 saved)
* 10) 32(%rsp) -> 72(%rsp) (80 saved)
* e) because the first argument we recieve in a thunker is actually the
* function to be called, arguments are offset as such:
* 0) rdi -> caller
* 1) rsi -> rcx (32 saved)
* 2) rdx -> rdx (32 saved)
* 3) rcx -> r8 (32 saved)
* 4) r8 -> r9 (32 saved)
* 5) r9 -> 32(%rsp) (32 saved)
* 6) 8(%rsp) -> 40(%rsp) (48 saved)
* 7) 16(%rsp) -> 48(%rsp) (48 saved)
* 8) 24(%rsp) -> 56(%rsp) (64 saved)
* 9) 32(%rsp) -> 64(%rsp) (64 saved)
* 10) 40(%rsp) -> 72(%rsp) (80 saved)
* f) arguments need to be moved in opposite order to avoid clobbering
*/
#define ENTRY(name) \
.globl name; \
name:
ENTRY(efi_call0)
subq $40, %rsp
call *%rdi
addq $40, %rsp
ret
ENTRY(efi_call1)
subq $40, %rsp
mov %rsi, %rcx
call *%rdi
addq $40, %rsp
ret
ENTRY(efi_call2)
subq $40, %rsp
/* mov %rdx, %rdx */
mov %rsi, %rcx
call *%rdi
addq $40, %rsp
ret
ENTRY(efi_call3)
subq $40, %rsp
mov %rcx, %r8
/* mov %rdx, %rdx */
mov %rsi, %rcx
call *%rdi
addq $40, %rsp
ret
ENTRY(efi_call4)
subq $40, %rsp
mov %r8, %r9
mov %rcx, %r8
/* mov %rdx, %rdx */
mov %rsi, %rcx
call *%rdi
addq $40, %rsp
ret
ENTRY(efi_call5)
subq $40, %rsp
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
/* mov %rdx, %rdx */
mov %rsi, %rcx
call *%rdi
addq $40, %rsp
ret
ENTRY(efi_call6)
subq $56, %rsp
mov 56+8(%rsp), %rax
mov %rax, 40(%rsp)
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
/* mov %rdx, %rdx */
mov %rsi, %rcx
call *%rdi
addq $56, %rsp
ret
ENTRY(efi_call7)
subq $56, %rsp
mov 56+16(%rsp), %rax
mov %rax, 48(%rsp)
mov 56+8(%rsp), %rax
mov %rax, 40(%rsp)
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
/* mov %rdx, %rdx */
mov %rsi, %rcx
call *%rdi
addq $56, %rsp
ret
ENTRY(efi_call8)
subq $72, %rsp
mov 72+24(%rsp), %rax
mov %rax, 56(%rsp)
mov 72+16(%rsp), %rax
mov %rax, 48(%rsp)
mov 72+8(%rsp), %rax
mov %rax, 40(%rsp)
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
/* mov %rdx, %rdx */
mov %rsi, %rcx
call *%rdi
addq $72, %rsp
ret
ENTRY(efi_call9)
subq $72, %rsp
mov 72+32(%rsp), %rax
mov %rax, 64(%rsp)
mov 72+24(%rsp), %rax
mov %rax, 56(%rsp)
mov 72+16(%rsp), %rax
mov %rax, 48(%rsp)
mov 72+8(%rsp), %rax
mov %rax, 40(%rsp)
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
/* mov %rdx, %rdx */
mov %rsi, %rcx
call *%rdi
addq $72, %rsp
ret
ENTRY(efi_call10)
subq $88, %rsp
mov 88+40(%rsp), %rax
mov %rax, 72(%rsp)
mov 88+32(%rsp), %rax
mov %rax, 64(%rsp)
mov 88+24(%rsp), %rax
mov %rax, 56(%rsp)
mov 88+16(%rsp), %rax
mov %rax, 48(%rsp)
mov 88+8(%rsp), %rax
mov %rax, 40(%rsp)
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
/* mov %rdx, %rdx */
mov %rsi, %rcx
call *%rdi
addq $88, %rsp
ret
#endif
#if defined(__ELF__) && defined(__linux__)
.section .note.GNU-stack,"",%progbits
#endif
+27
View File
@@ -0,0 +1,27 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
initplat.c
Abstract:
Revision History
--*/
#include "lib.h"
VOID
InitializeLibPlatform (
IN EFI_HANDLE ImageHandle EFI_UNUSED,
IN EFI_SYSTEM_TABLE *SystemTable EFI_UNUSED
)
{
}
+181
View File
@@ -0,0 +1,181 @@
/*++
Copyright (c) 1998 Intel Corporation
Module Name:
math.c
Abstract:
Revision History
--*/
#include "lib.h"
//
// Declare runtime functions
//
#ifdef RUNTIME_CODE
#ifndef __GNUC__
#pragma RUNTIME_CODE(LShiftU64)
#pragma RUNTIME_CODE(RShiftU64)
#pragma RUNTIME_CODE(MultU64x32)
#pragma RUNTIME_CODE(DivU64x32)
#endif
#endif
//
//
//
UINT64
LShiftU64 (
IN UINT64 Operand,
IN UINTN Count
)
// Left shift 64bit by 32bit and get a 64bit result
{
#if defined(__GNUC__) || defined(_MSC_EXTENSIONS)
return Operand << Count;
#else
UINT64 Result;
_asm {
mov eax, dword ptr Operand[0]
mov edx, dword ptr Operand[4]
mov ecx, Count
and ecx, 63
shld edx, eax, cl
shl eax, cl
cmp ecx, 32
jc short ls10
mov edx, eax
xor eax, eax
ls10:
mov dword ptr Result[0], eax
mov dword ptr Result[4], edx
}
return Result;
#endif
}
UINT64
RShiftU64 (
IN UINT64 Operand,
IN UINTN Count
)
// Right shift 64bit by 32bit and get a 64bit result
{
#if defined(__GNUC__) || defined(_MSC_EXTENSIONS)
return Operand >> Count;
#else
UINT64 Result;
_asm {
mov eax, dword ptr Operand[0]
mov edx, dword ptr Operand[4]
mov ecx, Count
and ecx, 63
shrd eax, edx, cl
shr edx, cl
cmp ecx, 32
jc short rs10
mov eax, edx
xor edx, edx
rs10:
mov dword ptr Result[0], eax
mov dword ptr Result[4], edx
}
return Result;
#endif
}
UINT64
MultU64x32 (
IN UINT64 Multiplicand,
IN UINTN Multiplier
)
// Multiple 64bit by 32bit and get a 64bit result
{
#if defined(__GNUC__) || defined(_MSC_EXTENSIONS)
return Multiplicand * Multiplier;
#else
UINT64 Result;
_asm {
mov eax, dword ptr Multiplicand[0]
mul Multiplier
mov dword ptr Result[0], eax
mov dword ptr Result[4], edx
mov eax, dword ptr Multiplicand[4]
mul Multiplier
add dword ptr Result[4], eax
}
return Result;
#endif
}
UINT64
DivU64x32 (
IN UINT64 Dividend,
IN UINTN Divisor,
OUT UINTN *Remainder OPTIONAL
)
// divide 64bit by 32bit and get a 64bit result
// N.B. only works for 31bit divisors!!
{
#if defined(__GNUC__) || defined(_MSC_EXTENSIONS)
if (Remainder)
*Remainder = Dividend % Divisor;
return Dividend / Divisor;
#else
UINT32 Rem;
UINT32 bit;
ASSERT (Divisor != 0);
ASSERT ((Divisor >> 31) == 0);
//
// For each bit in the dividend
//
Rem = 0;
for (bit=0; bit < 64; bit++) {
_asm {
shl dword ptr Dividend[0], 1 ; shift rem:dividend left one
rcl dword ptr Dividend[4], 1
rcl dword ptr Rem, 1
mov eax, Rem
cmp eax, Divisor ; Is Rem >= Divisor?
cmc ; No - do nothing
sbb eax, eax ; Else,
sub dword ptr Dividend[0], eax ; set low bit in dividen
and eax, Divisor ; and
sub Rem, eax ; subtract divisor
}
}
if (Remainder) {
*Remainder = Rem;
}
return Dividend;
#endif
}
+45
View File
@@ -0,0 +1,45 @@
.text
.globl base_setjmp
#ifndef __MINGW32__
.type base_setjmp, @function
#else
.def base_setjmp; .scl 2; .type 32; .endef
#endif
base_setjmp:
pop %rsi
movq %rbx,0x00(%rdi)
movq %rsp,0x08(%rdi)
push %rsi
movq %rbp,0x10(%rdi)
movq %r12,0x18(%rdi)
movq %r13,0x20(%rdi)
movq %r14,0x28(%rdi)
movq %r15,0x30(%rdi)
movq %rsi,0x38(%rdi)
xor %rax,%rax
ret
.globl base_longjmp
#ifndef __MINGW32__
.type base_longjmp, @function
#else
.def base_longjmp; .scl 2; .type 32; .endef
#endif
base_longjmp:
movl %esi, %eax
movq 0x00(%rdi), %rbx
movq 0x08(%rdi), %rsp
movq 0x10(%rdi), %rbp
movq 0x18(%rdi), %r12
movq 0x20(%rdi), %r13
movq 0x28(%rdi), %r14
movq 0x30(%rdi), %r15
xor %rdx,%rdx
mov $1,%rcx
cmp %rax,%rdx
cmove %rcx,%rax
jmp *0x38(%rdi)
#if defined(__ELF__) && defined(__linux__)
.section .note.GNU-stack,"",%progbits
#endif