diff options
Diffstat (limited to 'gnu-efi-3.0/lib')
37 files changed, 8111 insertions, 0 deletions
diff --git a/gnu-efi-3.0/lib/Makefile b/gnu-efi-3.0/lib/Makefile new file mode 100644 index 0000000..fcccced --- /dev/null +++ b/gnu-efi-3.0/lib/Makefile @@ -0,0 +1,80 @@ +# +# Copyright (C) 1999-2001 Hewlett-Packard Co. +# Contributed by David Mosberger <davidm@hpl.hp.com> +# Contributed by Stephane Eranian <eranian@hpl.hp.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. +# + +SRCDIR = . + +VPATH = $(SRCDIR) + +include $(SRCDIR)/../Make.defaults + +TOPDIR = $(SRCDIR)/.. + +CDIR = $(TOPDIR)/.. +FILES = boxdraw smbios console crc data debug dpath \ + error event guid hand hw init lock \ + misc print sread str \ + runtime/rtlock runtime/efirtlib runtime/rtstr runtime/vm runtime/rtdata \ + $(ARCH)/initplat $(ARCH)/math + +ifeq ($(ARCH),ia64) +FILES += $(ARCH)/salpal $(ARCH)/palproc +endif + +ifeq ($(ARCH),x86_64) +FILES += $(ARCH)/callwrap $(ARCH)/efi_stub +endif + +OBJS = $(FILES:%=%.o) + +SUBDIRS = ia32 x86_64 ia64 runtime + +all: libsubdirs libefi.a + +libsubdirs: + for sdir in $(SUBDIRS); do mkdir -p $$sdir; done + +libefi.a: libefi.a($(OBJS)) + +clean: + rm -f libefi.a *~ $(OBJS) */*.o + +install: libefi.a + mkdir -p $(INSTALLROOT)/$(LIBDIR) + $(INSTALL) -m 644 libefi.a $(INSTALLROOT)/$(LIBDIR) + +include $(SRCDIR)/../Make.rules + +.PHONY: libsubdirs diff --git a/gnu-efi-3.0/lib/boxdraw.c b/gnu-efi-3.0/lib/boxdraw.c new file mode 100644 index 0000000..ec3490a --- /dev/null +++ b/gnu-efi-3.0/lib/boxdraw.c @@ -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, L'-'}, + { BOXDRAW_VERTICAL, 0xb3, L'|'}, + { BOXDRAW_DOWN_RIGHT, 0xda, L'/'}, + { BOXDRAW_DOWN_LEFT, 0xbf, L'\\'}, + { BOXDRAW_UP_RIGHT, 0xc0, L'\\'}, + { BOXDRAW_UP_LEFT, 0xd9, L'/'}, + { BOXDRAW_VERTICAL_RIGHT, 0xc3, L'|'}, + { BOXDRAW_VERTICAL_LEFT, 0xb4, L'|'}, + { BOXDRAW_DOWN_HORIZONTAL, 0xc2, L'+'}, + { BOXDRAW_UP_HORIZONTAL, 0xc1, L'+'}, + { BOXDRAW_VERTICAL_HORIZONTAL, 0xc5, L'+'}, + { BOXDRAW_DOUBLE_HORIZONTAL, 0xcd, L'-'}, + { BOXDRAW_DOUBLE_VERTICAL, 0xba, L'|'}, + { BOXDRAW_DOWN_RIGHT_DOUBLE, 0xd5, L'/'}, + { BOXDRAW_DOWN_DOUBLE_RIGHT, 0xd6, L'/'}, + { BOXDRAW_DOUBLE_DOWN_RIGHT, 0xc9, L'/'}, + { BOXDRAW_DOWN_LEFT_DOUBLE, 0xb8, L'\\'}, + { BOXDRAW_DOWN_DOUBLE_LEFT, 0xb7, L'\\'}, + { BOXDRAW_DOUBLE_DOWN_LEFT, 0xbb, L'\\'}, + { BOXDRAW_UP_RIGHT_DOUBLE, 0xd4, L'\\'}, + { BOXDRAW_UP_DOUBLE_RIGHT, 0xd3, L'\\'}, + { BOXDRAW_DOUBLE_UP_RIGHT, 0xc8, L'\\'}, + { BOXDRAW_UP_LEFT_DOUBLE, 0xbe, L'/'}, + { BOXDRAW_UP_DOUBLE_LEFT, 0xbd, L'/'}, + { BOXDRAW_DOUBLE_UP_LEFT, 0xbc, L'/'}, + { BOXDRAW_VERTICAL_RIGHT_DOUBLE, 0xc6, L'|'}, + { BOXDRAW_VERTICAL_DOUBLE_RIGHT, 0xc7, L'|'}, + { BOXDRAW_DOUBLE_VERTICAL_RIGHT, 0xcc, L'|'}, + { BOXDRAW_VERTICAL_LEFT_DOUBLE, 0xb5, L'|'}, + { BOXDRAW_VERTICAL_DOUBLE_LEFT, 0xb6, L'|'}, + { BOXDRAW_DOUBLE_VERTICAL_LEFT, 0xb9, L'|'}, + { BOXDRAW_DOWN_HORIZONTAL_DOUBLE, 0xd1, L'+'}, + { BOXDRAW_DOWN_DOUBLE_HORIZONTAL, 0xd2, L'+'}, + { BOXDRAW_DOUBLE_DOWN_HORIZONTAL, 0xcb, L'+'}, + { BOXDRAW_UP_HORIZONTAL_DOUBLE, 0xcf, L'+'}, + { BOXDRAW_UP_DOUBLE_HORIZONTAL, 0xd0, L'+'}, + { BOXDRAW_DOUBLE_UP_HORIZONTAL, 0xca, L'+'}, + { BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE, 0xd8, L'+'}, + { BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL, 0xd7, L'+'}, + { BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL, 0xce, L'+'}, + + { BLOCKELEMENT_FULL_BLOCK, 0xdb, L'*'}, + { BLOCKELEMENT_LIGHT_SHADE, 0xb0, L'+'}, + + { GEOMETRICSHAPE_UP_TRIANGLE, 0x1e, L'^'}, + { GEOMETRICSHAPE_RIGHT_TRIANGLE, 0x10, L'>'}, + { GEOMETRICSHAPE_DOWN_TRIANGLE, 0x1f, L'v'}, + { GEOMETRICSHAPE_LEFT_TRIANGLE, 0x11, L'<'}, + + /* 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, L'<'}, + */ + + { ARROW_UP, 0x18, L'^'}, + + /* BugBut: Took out left arrow so right has to go too. + { ARROW_RIGHT, 0x1a, L'>'}, + */ + { ARROW_DOWN, 0x19, L'v'}, + + { 0x0000, 0x00 } +}; + + +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; +} + diff --git a/gnu-efi-3.0/lib/console.c b/gnu-efi-3.0/lib/console.c new file mode 100644 index 0000000..5ca47ef --- /dev/null +++ b/gnu-efi-3.0/lib/console.c @@ -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, L"\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; +} diff --git a/gnu-efi-3.0/lib/crc.c b/gnu-efi-3.0/lib/crc.c new file mode 100644 index 0000000..4367ed1 --- /dev/null +++ b/gnu-efi-3.0/lib/crc.c @@ -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; +} diff --git a/gnu-efi-3.0/lib/data.c b/gnu-efi-3.0/lib/data.c new file mode 100644 index 0000000..bcb2d67 --- /dev/null +++ b/gnu-efi-3.0/lib/data.c @@ -0,0 +1,157 @@ +/*++ + +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; + +// +// 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 EfiGlobalVariable = EFI_GLOBAL_VARIABLE; +EFI_GUID NullGuid = { 0,0,0,{0,0,0,0,0,0,0,0} }; + +// +// Protocol IDs +// + +EFI_GUID DevicePathProtocol = DEVICE_PATH_PROTOCOL; +EFI_GUID LoadedImageProtocol = LOADED_IMAGE_PROTOCOL; +EFI_GUID TextInProtocol = SIMPLE_TEXT_INPUT_PROTOCOL; +EFI_GUID TextOutProtocol = SIMPLE_TEXT_OUTPUT_PROTOCOL; +EFI_GUID BlockIoProtocol = BLOCK_IO_PROTOCOL; +EFI_GUID DiskIoProtocol = DISK_IO_PROTOCOL; +EFI_GUID FileSystemProtocol = SIMPLE_FILE_SYSTEM_PROTOCOL; +EFI_GUID LoadFileProtocol = LOAD_FILE_PROTOCOL; +EFI_GUID DeviceIoProtocol = DEVICE_IO_PROTOCOL; +EFI_GUID UnicodeCollationProtocol = UNICODE_COLLATION_PROTOCOL; +EFI_GUID SerialIoProtocol = SERIAL_IO_PROTOCOL; +EFI_GUID SimpleNetworkProtocol = EFI_SIMPLE_NETWORK_PROTOCOL; +EFI_GUID PxeBaseCodeProtocol = EFI_PXE_BASE_CODE_PROTOCOL; +EFI_GUID PxeCallbackProtocol = EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL; +EFI_GUID NetworkInterfaceIdentifierProtocol = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL; +EFI_GUID UiProtocol = EFI_UI_PROTOCOL; +EFI_GUID PciIoProtocol = EFI_PCI_IO_PROTOCOL; +// +// File system information IDs +// + +EFI_GUID GenericFileInfo = EFI_FILE_INFO_ID; +EFI_GUID FileSystemInfo = EFI_FILE_SYSTEM_INFO_ID; +EFI_GUID FileSystemVolumeLabelInfo = EFI_FILE_SYSTEM_VOLUME_LABEL_INFO_ID; + +// +// 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 GraphicsOutputProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; + +EFI_GUID AdapterDebugProtocol = ADAPTER_DEBUG_PROTOCOL; + +// +// Device path media protocol IDs +// +EFI_GUID PcAnsiProtocol = DEVICE_PATH_MESSAGING_PC_ANSI; +EFI_GUID Vt100Protocol = DEVICE_PATH_MESSAGING_VT_100; + +// +// 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 SMBIOSTableGuid = SMBIOS_TABLE_GUID; +EFI_GUID SalSystemTableGuid = SAL_SYSTEM_TABLE_GUID; diff --git a/gnu-efi-3.0/lib/debug.c b/gnu-efi-3.0/lib/debug.c new file mode 100644 index 0000000..e31e8d4 --- /dev/null +++ b/gnu-efi-3.0/lib/debug.c @@ -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 CHAR8 *FileName, + IN INTN LineNo, + IN CHAR8 *Description + ) +{ + DbgPrint (D_ERROR, (CHAR8 *)"%EASSERT FAILED: %a(%d): %a%N\n", FileName, LineNo, Description); + + BREAKPOINT(); + return 0; +} + diff --git a/gnu-efi-3.0/lib/dpath.c b/gnu-efi-3.0/lib/dpath.c new file mode 100644 index 0000000..863da7a --- /dev/null +++ b/gnu-efi-3.0/lib/dpath.c @@ -0,0 +1,1035 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + dpath.c + +Abstract: + MBR & Device Path functions + + + +Revision History + +--*/ + +#include "lib.h" + +#define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0) + + + +EFI_DEVICE_PATH * +DevicePathFromHandle ( + IN EFI_HANDLE Handle + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH *DevicePath; + + Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handle, &DevicePathProtocol, (VOID*)&DevicePath); + if (EFI_ERROR(Status)) { + DevicePath = NULL; + } + + return DevicePath; +} + + +EFI_DEVICE_PATH * +DevicePathInstance ( + IN OUT EFI_DEVICE_PATH **DevicePath, + OUT UINTN *Size + ) +{ + EFI_DEVICE_PATH *Start, *Next, *DevPath; + UINTN Count; + + DevPath = *DevicePath; + Start = DevPath; + + if (!DevPath) { + return NULL; + } + + // + // Check for end of device path type + // + + for (Count = 0; ; Count++) { + Next = NextDevicePathNode(DevPath); + + if (IsDevicePathEndType(DevPath)) { + break; + } + + if (Count > 01000) { + // + // BugBug: Debug code to catch bogus device paths + // + DEBUG((D_ERROR, "DevicePathInstance: DevicePath %x Size %d", *DevicePath, ((UINT8 *) DevPath) - ((UINT8 *) Start) )); + DumpHex (0, 0, ((UINT8 *) DevPath) - ((UINT8 *) Start), Start); + break; + } + + DevPath = Next; + } + + ASSERT (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE || + DevicePathSubType(DevPath) == END_INSTANCE_DEVICE_PATH_SUBTYPE); + + // + // Set next position + // + + if (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) { + Next = NULL; + } + + *DevicePath = Next; + + // + // Return size and start of device path instance + // + + *Size = ((UINT8 *) DevPath) - ((UINT8 *) Start); + return Start; +} + +UINTN +DevicePathInstanceCount ( + IN EFI_DEVICE_PATH *DevicePath + ) +{ + UINTN Count, Size; + + Count = 0; + while (DevicePathInstance(&DevicePath, &Size)) { + Count += 1; + } + + return Count; +} + + +EFI_DEVICE_PATH * +AppendDevicePath ( + IN EFI_DEVICE_PATH *Src1, + IN EFI_DEVICE_PATH *Src2 + ) +// Src1 may have multiple "instances" and each instance is appended +// Src2 is appended to each instance is Src1. (E.g., it's possible +// to append a new instance to the complete device path by passing +// it in Src2) +{ + UINTN Src1Size, Src1Inst, Src2Size, Size; + EFI_DEVICE_PATH *Dst, *Inst; + UINT8 *DstPos; + + // + // If there's only 1 path, just duplicate it + // + + if (!Src1) { + ASSERT (!IsDevicePathUnpacked (Src2)); + return DuplicateDevicePath (Src2); + } + + if (!Src2) { + ASSERT (!IsDevicePathUnpacked (Src1)); + return DuplicateDevicePath (Src1); + } + + // + // Verify we're not working with unpacked paths + // + +// ASSERT (!IsDevicePathUnpacked (Src1)); +// ASSERT (!IsDevicePathUnpacked (Src2)); + + // + // Append Src2 to every instance in Src1 + // + + Src1Size = DevicePathSize(Src1); + Src1Inst = DevicePathInstanceCount(Src1); + Src2Size = DevicePathSize(Src2); + Size = Src1Size * Src1Inst + Src2Size; + + Dst = AllocatePool (Size); + if (Dst) { + DstPos = (UINT8 *) Dst; + + // + // Copy all device path instances + // + + while ((Inst = DevicePathInstance (&Src1, &Size))) { + + CopyMem(DstPos, Inst, Size); + DstPos += Size; + + CopyMem(DstPos, Src2, Src2Size); + DstPos += Src2Size; + + CopyMem(DstPos, EndInstanceDevicePath, sizeof(EFI_DEVICE_PATH)); + DstPos += sizeof(EFI_DEVICE_PATH); + } + + // Change last end marker + DstPos -= sizeof(EFI_DEVICE_PATH); + CopyMem(DstPos, EndDevicePath, sizeof(EFI_DEVICE_PATH)); + } + + return Dst; +} + + +EFI_DEVICE_PATH * +AppendDevicePathNode ( + IN EFI_DEVICE_PATH *Src1, + IN EFI_DEVICE_PATH *Src2 + ) +// Src1 may have multiple "instances" and each instance is appended +// Src2 is a signal device path node (without a terminator) that is +// appended to each instance is Src1. +{ + EFI_DEVICE_PATH *Temp, *Eop; + UINTN Length; + + // + // Build a Src2 that has a terminator on it + // + + Length = DevicePathNodeLength(Src2); + Temp = AllocatePool (Length + sizeof(EFI_DEVICE_PATH)); + if (!Temp) { + return NULL; + } + + CopyMem (Temp, Src2, Length); + Eop = NextDevicePathNode(Temp); + SetDevicePathEndNode(Eop); + + // + // Append device paths + // + + Src1 = AppendDevicePath (Src1, Temp); + FreePool (Temp); + return Src1; +} + + +EFI_DEVICE_PATH * +FileDevicePath ( + IN EFI_HANDLE Device OPTIONAL, + IN CHAR16 *FileName + ) +/*++ + + N.B. Results are allocated from pool. The caller must FreePool + the resulting device path structure + +--*/ +{ + UINTN Size; + FILEPATH_DEVICE_PATH *FilePath; + EFI_DEVICE_PATH *Eop, *DevicePath; + + Size = StrSize(FileName); + FilePath = AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof(EFI_DEVICE_PATH)); + DevicePath = NULL; + + if (FilePath) { + + // + // Build a file path + // + + FilePath->Header.Type = MEDIA_DEVICE_PATH; + FilePath->Header.SubType = MEDIA_FILEPATH_DP; + SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH); + CopyMem (FilePath->PathName, FileName, Size); + Eop = NextDevicePathNode(&FilePath->Header); + SetDevicePathEndNode(Eop); + + // + // Append file path to device's device path + // + + DevicePath = (EFI_DEVICE_PATH *) FilePath; + if (Device) { + DevicePath = AppendDevicePath ( + DevicePathFromHandle(Device), + DevicePath + ); + + FreePool(FilePath); + } + } + + return DevicePath; +} + + + +UINTN +DevicePathSize ( + IN EFI_DEVICE_PATH *DevPath + ) +{ + EFI_DEVICE_PATH *Start; + + // + // Search for the end of the device path structure + // + + Start = DevPath; + while (!IsDevicePathEnd(DevPath)) { + DevPath = NextDevicePathNode(DevPath); + } + + // + // Compute the size + // + + return ((UINTN) DevPath - (UINTN) Start) + sizeof(EFI_DEVICE_PATH); +} + +EFI_DEVICE_PATH * +DuplicateDevicePath ( + IN EFI_DEVICE_PATH *DevPath + ) +{ + EFI_DEVICE_PATH *NewDevPath; + UINTN Size; + + + // + // Compute the size + // + + Size = DevicePathSize (DevPath); + + // + // Make a copy + // + + NewDevPath = AllocatePool (Size); + if (NewDevPath) { + CopyMem (NewDevPath, DevPath, Size); + } + + return NewDevPath; +} + +EFI_DEVICE_PATH * +UnpackDevicePath ( + IN EFI_DEVICE_PATH *DevPath + ) +{ + EFI_DEVICE_PATH *Src, *Dest, *NewPath; + UINTN Size; + + // + // Walk device path and round sizes to valid boundries + // + + Src = DevPath; + Size = 0; + for (; ;) { + Size += DevicePathNodeLength(Src); + Size += ALIGN_SIZE(Size); + + if (IsDevicePathEnd(Src)) { + break; + } + + Src = NextDevicePathNode(Src); + } + + + // + // Allocate space for the unpacked path + // + + NewPath = AllocateZeroPool (Size); + if (NewPath) { + + ASSERT (((UINTN)NewPath) % MIN_ALIGNMENT_SIZE == 0); + + // + // Copy each node + // + + Src = DevPath; + Dest = NewPath; + for (; ;) { + Size = DevicePathNodeLength(Src); + CopyMem (Dest, Src, Size); + Size += ALIGN_SIZE(Size); + SetDevicePathNodeLength (Dest, Size); + Dest->Type |= EFI_DP_TYPE_UNPACKED; + Dest = (EFI_DEVICE_PATH *) (((UINT8 *) Dest) + Size); + + if (IsDevicePathEnd(Src)) { + break; + } + + Src = NextDevicePathNode(Src); + } + } + + return NewPath; +} + + +EFI_DEVICE_PATH* +AppendDevicePathInstance ( + IN EFI_DEVICE_PATH *Src, + IN EFI_DEVICE_PATH *Instance + ) +{ + UINT8 *Ptr; + EFI_DEVICE_PATH *DevPath; + UINTN SrcSize; + UINTN InstanceSize; + + if (Src == NULL) { + return DuplicateDevicePath (Instance); + } + SrcSize = DevicePathSize(Src); + InstanceSize = DevicePathSize(Instance); + Ptr = AllocatePool (SrcSize + InstanceSize); + DevPath = (EFI_DEVICE_PATH *)Ptr; + ASSERT(DevPath); + + CopyMem (Ptr, Src, SrcSize); +// FreePool (Src); + + while (!IsDevicePathEnd(DevPath)) { + DevPath = NextDevicePathNode(DevPath); + } + // + // Convert the End to an End Instance, since we are + // appending another instacne after this one its a good + // idea. + // + DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; + + DevPath = NextDevicePathNode(DevPath); + CopyMem (DevPath, Instance, InstanceSize); + return (EFI_DEVICE_PATH *)Ptr; +} + +EFI_STATUS +LibDevicePathToInterface ( + IN EFI_GUID *Protocol, + IN EFI_DEVICE_PATH *FilePath, + OUT VOID **Interface + ) +{ + EFI_STATUS Status; + EFI_HANDLE Device; + + Status = uefi_call_wrapper(BS->LocateDevicePath, 3, Protocol, &FilePath, &Device); + + if (!EFI_ERROR(Status)) { + + // If we didn't get a direct match return not found + Status = EFI_NOT_FOUND; + + if (IsDevicePathEnd(FilePath)) { + + // + // It was a direct match, lookup the protocol interface + // + + Status =uefi_call_wrapper(BS->HandleProtocol, 3, Device, Protocol, Interface); + } + } + + // + // If there was an error, do not return an interface + // + + if (EFI_ERROR(Status)) { + *Interface = NULL; + } + + return Status; +} + +VOID +_DevPathPci ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + PCI_DEVICE_PATH *Pci; + + Pci = DevPath; + CatPrint(Str, L"Pci(%x|%x)", Pci->Device, Pci->Function); +} + +VOID +_DevPathPccard ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + PCCARD_DEVICE_PATH *Pccard; + + Pccard = DevPath; + CatPrint(Str, L"Pccard(Socket%x)", Pccard->SocketNumber); +} + +VOID +_DevPathMemMap ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + MEMMAP_DEVICE_PATH *MemMap; + + MemMap = DevPath; + CatPrint(Str, L"MemMap(%d:%x-%x)", + MemMap->MemoryType, + MemMap->StartingAddress, + MemMap->EndingAddress + ); +} + +VOID +_DevPathController ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + CONTROLLER_DEVICE_PATH *Controller; + + Controller = DevPath; + CatPrint(Str, L"Ctrl(%d)", + Controller->Controller + ); +} + +VOID +_DevPathVendor ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + VENDOR_DEVICE_PATH *Vendor; + CHAR16 *Type; + UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownDevPath; + + Vendor = DevPath; + switch (DevicePathType(&Vendor->Header)) { + case HARDWARE_DEVICE_PATH: Type = L"Hw"; break; + case MESSAGING_DEVICE_PATH: Type = L"Msg"; break; + case MEDIA_DEVICE_PATH: Type = L"Media"; break; + default: Type = L"?"; break; + } + + CatPrint(Str, L"Ven%s(%g", Type, &Vendor->Guid); + if (CompareGuid (&Vendor->Guid, &UnknownDevice) == 0) { + // + // GUID used by EFI to enumerate an EDD 1.1 device + // + UnknownDevPath = (UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *)Vendor; + CatPrint(Str, L":%02x)", UnknownDevPath->LegacyDriveLetter); + } else { + CatPrint(Str, L")"); + } +} + + +VOID +_DevPathAcpi ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + ACPI_HID_DEVICE_PATH *Acpi; + + Acpi = DevPath; + if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) { + CatPrint(Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID); + } else { + CatPrint(Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID); + } +} + + +VOID +_DevPathAtapi ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + ATAPI_DEVICE_PATH *Atapi; + + Atapi = DevPath; + CatPrint(Str, L"Ata(%s,%s)", + Atapi->PrimarySecondary ? L"Secondary" : L"Primary", + Atapi->SlaveMaster ? L"Slave" : L"Master" + ); +} + +VOID +_DevPathScsi ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + SCSI_DEVICE_PATH *Scsi; + + Scsi = DevPath; + CatPrint(Str, L"Scsi(Pun%x,Lun%x)", Scsi->Pun, Scsi->Lun); +} + + +VOID +_DevPathFibre ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + FIBRECHANNEL_DEVICE_PATH *Fibre; + + Fibre = DevPath; + CatPrint(Str, L"Fibre(%lx)", Fibre->WWN); +} + +VOID +_DevPath1394 ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + F1394_DEVICE_PATH *F1394; + + F1394 = DevPath; + CatPrint(Str, L"1394(%g)", &F1394->Guid); +} + + + +VOID +_DevPathUsb ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + USB_DEVICE_PATH *Usb; + + Usb = DevPath; + CatPrint(Str, L"Usb(%x)", Usb->Port); +} + + +VOID +_DevPathI2O ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + I2O_DEVICE_PATH *I2O; + + I2O = DevPath; + CatPrint(Str, L"I2O(%x)", I2O->Tid); +} + +VOID +_DevPathMacAddr ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + MAC_ADDR_DEVICE_PATH *MAC; + UINTN HwAddressSize; + UINTN Index; + + MAC = DevPath; + + HwAddressSize = sizeof(EFI_MAC_ADDRESS); + if (MAC->IfType == 0x01 || MAC->IfType == 0x00) { + HwAddressSize = 6; + } + + CatPrint(Str, L"Mac("); + + for(Index = 0; Index < HwAddressSize; Index++) { + CatPrint(Str, L"%02x",MAC->MacAddress.Addr[Index]); + } + CatPrint(Str, L")"); +} + +VOID +_DevPathIPv4 ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + IPv4_DEVICE_PATH *IP; + + IP = DevPath; + CatPrint(Str, L"IPv4(not-done)"); +} + +VOID +_DevPathIPv6 ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + IPv6_DEVICE_PATH *IP; + + IP = DevPath; + CatPrint(Str, L"IP-v6(not-done)"); +} + +VOID +_DevPathInfiniBand ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + INFINIBAND_DEVICE_PATH *InfiniBand; + + InfiniBand = DevPath; + CatPrint(Str, L"InfiniBand(not-done)"); +} + +VOID +_DevPathUart ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + UART_DEVICE_PATH *Uart; + CHAR8 Parity; + + Uart = DevPath; + switch (Uart->Parity) { + case 0 : Parity = 'D'; break; + case 1 : Parity = 'N'; break; + case 2 : Parity = 'E'; break; + case 3 : Parity = 'O'; break; + case 4 : Parity = 'M'; break; + case 5 : Parity = 'S'; break; + default : Parity = 'x'; break; + } + + if (Uart->BaudRate == 0) { + CatPrint(Str, L"Uart(DEFAULT %c",Uart->BaudRate,Parity); + } else { + CatPrint(Str, L"Uart(%d %c",Uart->BaudRate,Parity); + } + + if (Uart->DataBits == 0) { + CatPrint(Str, L"D"); + } else { + CatPrint(Str, L"%d",Uart->DataBits); + } + + switch (Uart->StopBits) { + case 0 : CatPrint(Str, L"D)"); break; + case 1 : CatPrint(Str, L"1)"); break; + case 2 : CatPrint(Str, L"1.5)"); break; + case 3 : CatPrint(Str, L"2)"); break; + default : CatPrint(Str, L"x)"); break; + } +} + + +VOID +_DevPathHardDrive ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + HARDDRIVE_DEVICE_PATH *Hd; + + Hd = DevPath; + switch (Hd->SignatureType) { + case SIGNATURE_TYPE_MBR: + CatPrint(Str, L"HD(Part%d,Sig%08X)", + Hd->PartitionNumber, + *((UINT32 *)(&(Hd->Signature[0]))) + ); + break; + case SIGNATURE_TYPE_GUID: + CatPrint(Str, L"HD(Part%d,Sig%g)", + Hd->PartitionNumber, + (EFI_GUID *) &(Hd->Signature[0]) + ); + break; + default: + CatPrint(Str, L"HD(Part%d,MBRType=%02x,SigType=%02x)", + Hd->PartitionNumber, + Hd->MBRType, + Hd->SignatureType + ); + break; + } +} + +VOID +_DevPathCDROM ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + CDROM_DEVICE_PATH *Cd; + + Cd = DevPath; + CatPrint(Str, L"CDROM(Entry%x)", Cd->BootEntry); +} + +VOID +_DevPathFilePath ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + FILEPATH_DEVICE_PATH *Fp; + + Fp = DevPath; + CatPrint(Str, L"%s", Fp->PathName); +} + +VOID +_DevPathMediaProtocol ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + MEDIA_PROTOCOL_DEVICE_PATH *MediaProt; + + MediaProt = DevPath; + CatPrint(Str, L"%g", &MediaProt->Protocol); +} + +VOID +_DevPathBssBss ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + BBS_BBS_DEVICE_PATH *Bss; + CHAR16 *Type; + + Bss = DevPath; + switch (Bss->DeviceType) { + case BBS_TYPE_FLOPPY: Type = L"Floppy"; break; + case BBS_TYPE_HARDDRIVE: Type = L"Harddrive"; break; + case BBS_TYPE_CDROM: Type = L"CDROM"; break; + case BBS_TYPE_PCMCIA: Type = L"PCMCIA"; break; + case BBS_TYPE_USB: Type = L"Usb"; break; + case BBS_TYPE_EMBEDDED_NETWORK: Type = L"Net"; break; + default: Type = L"?"; break; + } + + CatPrint(Str, L"Bss-%s(%a)", Type, Bss->String); +} + + +VOID +_DevPathEndInstance ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + CatPrint(Str, L","); +} + +VOID +_DevPathNodeUnknown ( + IN OUT POOL_PRINT *Str, + IN VOID *DevPath + ) +{ + CatPrint(Str, L"?"); +} + + +struct { + UINT8 Type; + UINT8 SubType; + VOID (*Function)(POOL_PRINT *, VOID *); +} DevPathTable[] = { + { HARDWARE_DEVICE_PATH, HW_PCI_DP, _DevPathPci}, + { HARDWARE_DEVICE_PATH, HW_PCCARD_DP, _DevPathPccard}, + { HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, _DevPathMemMap}, + { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, _DevPathVendor}, + { HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, _DevPathController}, + { ACPI_DEVICE_PATH, ACPI_DP, _DevPathAcpi}, + { MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, _DevPathAtapi}, + { MESSAGING_DEVICE_PATH, MSG_SCSI_DP, _DevPathScsi}, + { MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, _DevPathFibre}, + { MESSAGING_DEVICE_PATH, MSG_1394_DP, _DevPath1394}, + { MESSAGING_DEVICE_PATH, MSG_USB_DP, _DevPathUsb}, + { MESSAGING_DEVICE_PATH, MSG_I2O_DP, _DevPathI2O}, + { MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, _DevPathMacAddr}, + { MESSAGING_DEVICE_PATH, MSG_IPv4_DP, _DevPathIPv4}, + { MESSAGING_DEVICE_PATH, MSG_IPv6_DP, _DevPathIPv6}, + { MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, _DevPathInfiniBand}, + { MESSAGING_DEVICE_PATH, MSG_UART_DP, _DevPathUart}, + { MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, _DevPathVendor}, + { MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, _DevPathHardDrive}, + { MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, _DevPathCDROM}, + { MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, _DevPathVendor}, + { MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, _DevPathFilePath}, + { MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, _DevPathMediaProtocol}, + { BBS_DEVICE_PATH, BBS_BBS_DP, _DevPathBssBss}, + { END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, _DevPathEndInstance}, + { 0, 0, NULL} +}; + + +CHAR16 * +DevicePathToStr ( + EFI_DEVICE_PATH *DevPath + ) +/*++ + + Turns the Device Path into a printable string. Allcoates + the string from pool. The caller must FreePool the returned + string. + +--*/ +{ + POOL_PRINT Str; + EFI_DEVICE_PATH *DevPathNode; + VOID (*DumpNode)(POOL_PRINT *, VOID *); + UINTN Index, NewSize; + + ZeroMem(&Str, sizeof(Str)); + + // + // Unpacked the device path + // + + DevPath = UnpackDevicePath(DevPath); + ASSERT (DevPath); + + + // + // Process each device path node + // + + DevPathNode = DevPath; + while (!IsDevicePathEnd(DevPathNode)) { + // + // Find the handler to dump this device path node + // + + DumpNode = NULL; + for (Index = 0; DevPathTable[Index].Function; Index += 1) { + + if (DevicePathType(DevPathNode) == DevPathTable[Index].Type && + DevicePathSubType(DevPathNode) == DevPathTable[Index].SubType) { + DumpNode = DevPathTable[Index].Function; + break; + } + } + + // + // If not found, use a generic function + // + + if (!DumpNode) { + DumpNode = _DevPathNodeUnknown; + } + + // + // Put a path seperator in if needed + // + + if (Str.len && DumpNode != _DevPathEndInstance) { + CatPrint (&Str, L"/"); + } + + // + // Print this node of the device path + // + + DumpNode (&Str, DevPathNode); + + // + // Next device path node + // + + DevPathNode = NextDevicePathNode(DevPathNode); + } + + // + // Shrink pool used for string allocation + // + + FreePool (DevPath); + NewSize = (Str.len + 1) * sizeof(CHAR16); + Str.str = ReallocatePool (Str.str, NewSize, NewSize); + Str.str[Str.len] = 0; + return Str.str; +} + +BOOLEAN +LibMatchDevicePaths ( + IN EFI_DEVICE_PATH *Multi, + IN EFI_DEVICE_PATH *Single + ) +{ + EFI_DEVICE_PATH *DevicePath, *DevicePathInst; + UINTN Size; + + if (!Multi || !Single) { + return FALSE; + } + + DevicePath = Multi; + while ((DevicePathInst = DevicePathInstance (&DevicePath, &Size))) { + if (CompareMem (Single, DevicePathInst, Size) == 0) { + return TRUE; + } + } + return FALSE; +} + +EFI_DEVICE_PATH * +LibDuplicateDevicePathInstance ( + IN EFI_DEVICE_PATH *DevPath + ) +{ + EFI_DEVICE_PATH *NewDevPath,*DevicePathInst,*Temp; + UINTN Size; + + // + // get the size of an instance from the input + // + + Temp = DevPath; + DevicePathInst = DevicePathInstance (&Temp, &Size); + + // + // Make a copy and set proper end type + // + NewDevPath = NULL; + if (Size) { + NewDevPath = AllocatePool (Size + sizeof(EFI_DEVICE_PATH)); + } + + if (NewDevPath) { + CopyMem (NewDevPath, DevicePathInst, Size); + Temp = NextDevicePathNode(NewDevPath); + SetDevicePathEndNode(Temp); + } + + return NewDevPath; +} + diff --git a/gnu-efi-3.0/lib/error.c b/gnu-efi-3.0/lib/error.c new file mode 100644 index 0000000..e1d3249 --- /dev/null +++ b/gnu-efi-3.0/lib/error.c @@ -0,0 +1,76 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + error.c + +Abstract: + + + + +Revision History + +--*/ + +#include "lib.h" + + +struct { + EFI_STATUS Code; + WCHAR *Desc; +} ErrorCodeTable[] = { + { EFI_SUCCESS, L"Success"}, + { EFI_LOAD_ERROR, L"Load Error"}, + { EFI_INVALID_PARAMETER, L"Invalid Parameter"}, + { EFI_UNSUPPORTED, L"Unsupported"}, + { EFI_BAD_BUFFER_SIZE, L"Bad Buffer Size"}, + { EFI_BUFFER_TOO_SMALL, L"Buffer Too Small"}, + { EFI_NOT_READY, L"Not Ready"}, + { EFI_DEVICE_ERROR, L"Device Error"}, + { EFI_WRITE_PROTECTED, L"Write Protected"}, + { EFI_OUT_OF_RESOURCES, L"Out of Resources"}, + { EFI_VOLUME_CORRUPTED, L"Volume Corrupt"}, + { EFI_VOLUME_FULL, L"Volume Full"}, + { EFI_NO_MEDIA, L"No Media"}, + { EFI_MEDIA_CHANGED, L"Media changed"}, + { EFI_NOT_FOUND, L"Not Found"}, + { EFI_ACCESS_DENIED, L"Access Denied"}, + { EFI_NO_RESPONSE, L"No Response"}, + { EFI_NO_MAPPING, L"No mapping"}, + { EFI_TIMEOUT, L"Time out"}, + { EFI_NOT_STARTED, L"Not started"}, + { EFI_ALREADY_STARTED, L"Already started"}, + { EFI_ABORTED, L"Aborted"}, + { EFI_ICMP_ERROR, L"ICMP Error"}, + { EFI_TFTP_ERROR, L"TFTP Error"}, + { EFI_PROTOCOL_ERROR, L"Protocol Error"}, + + // warnings + { EFI_WARN_UNKOWN_GLYPH, L"Warning Unknown Glyph"}, + { EFI_WARN_DELETE_FAILURE, L"Warning Delete Failure"}, + { EFI_WARN_WRITE_FAILURE, L"Warning Write Failure"}, + { EFI_WARN_BUFFER_TOO_SMALL, L"Warning Buffer Too Small"}, + { 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; + } + } + + SPrint (Buffer, 0, L"%X", Status); +} diff --git a/gnu-efi-3.0/lib/event.c b/gnu-efi-3.0/lib/event.c new file mode 100644 index 0000000..6c16c62 --- /dev/null +++ b/gnu-efi-3.0/lib/event.c @@ -0,0 +1,153 @@ +/*++ + +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 + ); + ASSERT (!EFI_ERROR(Status)); + + // + // Register for protocol notifactions on this event + // + + Status = uefi_call_wrapper( + BS->RegisterProtocolNotify, + 3, + ProtocolGuid, + Event, + Registration + ); + + 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); + *Key = TimeoutKey; +} + diff --git a/gnu-efi-3.0/lib/guid.c b/gnu-efi-3.0/lib/guid.c new file mode 100644 index 0000000..92622b4 --- /dev/null +++ b/gnu-efi-3.0/lib/guid.c @@ -0,0 +1,175 @@ +/*++ + +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[] = { + { &NullGuid, L"G0"}, + { &EfiGlobalVariable, L"Efi"}, + + { &VariableStoreProtocol, L"varstore"}, + { &DevicePathProtocol, L"dpath"}, + { &LoadedImageProtocol, L"image"}, + { &TextInProtocol, L"txtin"}, + { &TextOutProtocol, L"txtout"}, + { &BlockIoProtocol, L"blkio"}, + { &DiskIoProtocol, L"diskio"}, + { &FileSystemProtocol, L"fs"}, + { &LoadFileProtocol, L"load"}, + { &DeviceIoProtocol, L"DevIo"}, + + { &GenericFileInfo, L"GenFileInfo"}, + { &FileSystemInfo, L"FileSysInfo"}, + + { &UnicodeCollationProtocol, L"unicode"}, + { &LegacyBootProtocol, L"LegacyBoot"}, + { &SerialIoProtocol, L"serialio"}, + { &VgaClassProtocol, L"vgaclass"}, + { &SimpleNetworkProtocol, L"net"}, + { &NetworkInterfaceIdentifierProtocol, L"nii"}, + { &PxeBaseCodeProtocol, L"pxebc"}, + { &PxeCallbackProtocol, L"pxecb"}, + + { &VariableStoreProtocol, L"varstore"}, + { &LegacyBootProtocol, L"LegacyBoot"}, + { &VgaClassProtocol, L"VgaClass"}, + { &TextOutSpliterProtocol, L"TxtOutSplit"}, + { &ErrorOutSpliterProtocol, L"ErrOutSplit"}, + { &TextInSpliterProtocol, L"TxtInSplit"}, + { &PcAnsiProtocol, L"PcAnsi"}, + { &Vt100Protocol, L"Vt100"}, + { &UnknownDevice, L"Unknown Device"}, + + { &EfiPartTypeSystemPartitionGuid, L"ESP"}, + { &EfiPartTypeLegacyMbrGuid, L"GPT MBR"}, + + { &ShellInterfaceProtocol, L"ShellInt"}, + { &SEnvId, L"SEnv"}, + { &SProtId, L"ShellProtId"}, + { &SMapId, L"ShellDevPathMap"}, + { &SAliasId, L"ShellAlias"}, + + { NULL } +}; + +// +// +// + +LIST_ENTRY GuidList; + + +VOID +InitializeGuid ( + VOID + ) +{ +} + +INTN +CompareGuid( + IN EFI_GUID *Guid1, + IN EFI_GUID *Guid2 + ) +/*++ + +Routine Description: + + Compares to GUIDs + +Arguments: + + Guid1 - guid to compare + Guid2 - guid to compare + +Returns: + = 0 if Guid1 == Guid2 + +--*/ +{ + return RtCompareGuid (Guid1, Guid2); +} + + +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) == 0) { + SPrint (Buffer, 0, KnownGuids[Index].GuidName); + return ; + } + } + + // + // Else dump it + // + + SPrint (Buffer, 0, L"%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] + ); +} diff --git a/gnu-efi-3.0/lib/hand.c b/gnu-efi-3.0/lib/hand.c new file mode 100644 index 0000000..c41c729 --- /dev/null +++ b/gnu-efi-3.0/lib/hand.c @@ -0,0 +1,633 @@ +/*++ + +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 *Start, *Next, *DevPath; + HARDDRIVE_DEVICE_PATH *HardDriveDevicePath; + BOOLEAN Match; + BOOLEAN PreviousNodeIsHardDriveDevicePath; + + // + // Initialize for GrowBuffer loop + // + + 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; + Start = DevPath; + + // + // 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]))) == 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 + // + + 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 + // + + 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 + // + + 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; + } + + // + // 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; + } + + // + // 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)); + } + } +} + + +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; + } + + // + // 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; + } + } + + // + // Done + // + + uefi_call_wrapper(BS->RestoreTPL, 1, OldTpl); + return Status; +} diff --git a/gnu-efi-3.0/lib/hw.c b/gnu-efi-3.0/lib/hw.c new file mode 100644 index 0000000..3d651ad --- /dev/null +++ b/gnu-efi-3.0/lib/hw.c @@ -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, + 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; + + 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; + + 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; + + 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; + + Status = uefi_call_wrapper(GlobalIoFncs->Pci.Write, 5, GlobalIoFncs, Width, (UINT64)Address, 1, &Data); + ASSERT(!EFI_ERROR(Status)); + return (UINT32)Data; +} + + + diff --git a/gnu-efi-3.0/lib/ia32/efi_stub.S b/gnu-efi-3.0/lib/ia32/efi_stub.S new file mode 100644 index 0000000..464eae5 --- /dev/null +++ b/gnu-efi-3.0/lib/ia32/efi_stub.S @@ -0,0 +1 @@ +/* This stub is a stub to make the build happy */ diff --git a/gnu-efi-3.0/lib/ia32/initplat.c b/gnu-efi-3.0/lib/ia32/initplat.c new file mode 100644 index 0000000..1e6ea82 --- /dev/null +++ b/gnu-efi-3.0/lib/ia32/initplat.c @@ -0,0 +1,28 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + initplat.c + +Abstract: + + + + +Revision History + +--*/ + +#include "lib.h" + +VOID +InitializeLibPlatform ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) + +{ +} + diff --git a/gnu-efi-3.0/lib/ia32/math.c b/gnu-efi-3.0/lib/ia32/math.c new file mode 100644 index 0000000..4f40388 --- /dev/null +++ b/gnu-efi-3.0/lib/ia32/math.c @@ -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 +{ +#ifdef __GNUC__ + 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 +{ +#ifdef __GNUC__ + 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 +{ +#ifdef __GNUC__ + 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!! +{ +#ifdef __GNUC__ + 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 +} diff --git a/gnu-efi-3.0/lib/ia64/initplat.c b/gnu-efi-3.0/lib/ia64/initplat.c new file mode 100644 index 0000000..36a30f9 --- /dev/null +++ b/gnu-efi-3.0/lib/ia64/initplat.c @@ -0,0 +1,31 @@ +/*++ + +Copyright (c) 1999 Intel Corporation + +Module Name: + + initplat.c + +Abstract: + + Functions to make SAL and PAL proc calls + +Revision History + +--*/ +#include "lib.h" + +//#include "palproc.h" + +VOID +InitializeLibPlatform ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) + +{ + PLABEL SalPlabel; + UINT64 PalEntry; + + LibInitSalAndPalProc (&SalPlabel, &PalEntry); +} diff --git a/gnu-efi-3.0/lib/ia64/math.c b/gnu-efi-3.0/lib/ia64/math.c new file mode 100644 index 0000000..a8c4e12 --- /dev/null +++ b/gnu-efi-3.0/lib/ia64/math.c @@ -0,0 +1,88 @@ +/*++ + +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 +{ + return Operand << Count; +} + +UINT64 +RShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +// Right shift 64bit by 32bit and get a 64bit result +{ + return Operand >> Count; +} + + +UINT64 +MultU64x32 ( + IN UINT64 Multiplicand, + IN UINTN Multiplier + ) +// Multiple 64bit by 32bit and get a 64bit result +{ + return Multiplicand * Multiplier; +} + +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!! +{ + ASSERT (Divisor != 0); + + if (Remainder) { + *Remainder = Dividend % Divisor; + } + + return Dividend / Divisor; +} diff --git a/gnu-efi-3.0/lib/ia64/palproc.S b/gnu-efi-3.0/lib/ia64/palproc.S new file mode 100644 index 0000000..c304a78 --- /dev/null +++ b/gnu-efi-3.0/lib/ia64/palproc.S @@ -0,0 +1,161 @@ +//++ +// Copyright (c) 1996-99 Intel Corp. +// +// +// Module Name: +// +// palproc.s +// +// Abstract: +// +// Contains an implementation for making PAL PROC calls on +// IA-64 architecture. +// +// +// +// Revision History: +// +//-- + + .file "palproc.s" + +#include "palproc.h" + + +//----------------------------------------------------------------------------- +//++ +// MakeStaticPALCall +// +// This routine is called whenever an architected static calling convention +// based PAL call is to be made. This call does use RSE actually, but our policy +// in making static PAL calls before memory is available is to make sure that +// we do not nest too deep and allocate beyond 96 banked registers. In other +// words we carefully code calls and control flow before memory is available. +// +// Arguments : All parameters set up to do static PAL call. +// +// On Entry : +// +// Return Value: +// +// As per static calling conventions. +// +//-- +//--------------------------------------------------------------------------- +PROCEDURE_ENTRY(MakeStaticPALCall) + + NESTED_SETUP (5,8,0,0) + mov loc3 = b5 + mov loc4 = r2 + mov loc7 = r1;; + + movl loc6 = PAL_MC_CLEAR_LOG + mov r2 = psr;; + mov loc5 = r2 + + cmp.eq p6,p7 = r28,loc6;; + (p7)movl loc6 = PAL_MC_DYNAMIC_STATE;; + (p7)cmp.eq p6,p7 = r28,loc6;; + + (p7)movl loc6 = PAL_MC_ERROR_INFO;; + (p7)cmp.eq p6,p7 = r28,loc6;; + + (p7)movl loc6 = PAL_MC_RESUME;; + (p7)cmp.eq p6,p7 = r28,loc6 + + mov loc6 = 0x1;; + (p7)dep r2 = loc6,r2,13,1;; // psr.ic = 1 + +// p6 will be true, if it is one of the MCHK calls. There has been lots of debate +// on psr.ic for these values. For now, do not do any thing to psr.ic + +// (p6)dep r2 = r0,r2,13,1;; // psr.ic = 0 + dep r2 = r0,r2,14,1;; // psr.i = 0 + + mov psr.l = r2 + srlz.d;; // Needs data serailization. + srlz.i;; // Needs instruction serailization. + +StaticGetPALLocalIP: + mov loc2 = ip;; + add loc2 = StaticComeBackFromPALCall - StaticGetPALLocalIP,loc2;; + mov b0 = loc2 // return address after Pal call + mov r28 = in1 // get the input parameters to PAL call + mov r29 = in2 + mov r30 = in3;; + mov r31 = in4 + mov b5 = in0;; // get the PalProcEntrypt from input + br.sptk b5 // Take the plunge. + +StaticComeBackFromPALCall: + + mov psr.l = loc5;; + srlz.d;; // Needs data serailization. + srlz.i;; // Needs instruction serailization. + + mov b5 = loc3 + mov r2 = loc4 + mov r1 = loc7 + + NESTED_RETURN + +PROCEDURE_EXIT(MakeStaticPALCall) + + +//----------------------------------------------------------------------------- +//++ +// MakeStackedPALCall +// +// This routine is called whenever an architected stacked calling convention +// based PAL call is to be made. This call is made after memory is available. +// Although stacked calls could be made directly from 'C', there is a PAL +// requirement which forces the index to be in GR28 and hence this stub is +// needed +// +// Arguments : All parameters set up to do stacted PAL call. +// +// On Entry : +// in0: PAL_PROC entrypoint +// in1-in4 : PAL_PROC arguments +// +// Return Value: +// +// As per stacked calling conventions. +// +//-- +//--------------------------------------------------------------------------- +PROCEDURE_ENTRY(MakeStackedPALCall) + + NESTED_SETUP (5,8,4,0) + mov loc3 = b5 + mov loc4 = r2 + mov loc7 = r1 + mov r2 = psr;; + mov loc5 = r2;; + dep r2 = r0,r2,14,1;; // psr.i = 0 + mov psr.l = r2 + srlz.d;; // Needs data serailization. + srlz.i;; // Needs instruction serailization. + +StackedGetPALLocalIP: + mov r28 = in1 // get the input parameters to PAL call + mov out0 = in1 + mov out1 = in2;; + mov out2 = in3 + mov out3 = in4 + mov b5 = in0;; // get the PalProcEntrypt from input + br.call.dpnt b0=b5;; // Take the plunge. + +StackedComeBackFromPALCall: + + mov psr.l = loc5;; + srlz.d;; // Needs data serailization. + srlz.i;; // Needs instruction serailization. + mov b5 = loc3 + mov r2 = loc4 + mov r1 = loc7 + + NESTED_RETURN + +PROCEDURE_EXIT(MakeStackedPALCall) + diff --git a/gnu-efi-3.0/lib/ia64/palproc.h b/gnu-efi-3.0/lib/ia64/palproc.h new file mode 100644 index 0000000..240946d --- /dev/null +++ b/gnu-efi-3.0/lib/ia64/palproc.h @@ -0,0 +1,51 @@ +// +// +// Copyright (c) 1996-99 Intel Corp. +// +// +//Module Name: +// +// palproc.h +// +//Abstract: +// +// This module contains generic macros for an IA64 assembly writer. +// +// +//Revision History +// + +#ifndef _PALPROC_H +#define _PALPROC_H + +#define PROCEDURE_ENTRY(name) .##text; \ + .##type name, @function; \ + .##global name; \ + .##proc name; \ +name: + +#define PROCEDURE_EXIT(name) .##endp name + +// Note: use of NESTED_SETUP requires number of locals (l) >= 3 + +#define NESTED_SETUP(i,l,o,r) \ + alloc loc1=ar##.##pfs,i,l,o,r ;\ + mov loc0=b0 + +#define NESTED_RETURN \ + mov b0=loc0 ;\ + mov ar##.##pfs=loc1 ;;\ + br##.##ret##.##dpnt b0;; + + +// defines needed in palproc.s + +#define PAL_MC_CLEAR_LOG 0x0015 +#define PAL_MC_DRAIN 0x0016 +#define PAL_MC_EXPECTED 0x0017 +#define PAL_MC_DYNAMIC_STATE 0x0018 +#define PAL_MC_ERROR_INFO 0x0019 +#define PAL_MC_RESUME 0x001a +#define PAL_MC_REGISTER_MEM 0x001b + +#endif // _PALPROC_H diff --git a/gnu-efi-3.0/lib/ia64/salpal.c b/gnu-efi-3.0/lib/ia64/salpal.c new file mode 100644 index 0000000..3d808f3 --- /dev/null +++ b/gnu-efi-3.0/lib/ia64/salpal.c @@ -0,0 +1,335 @@ +/*++ + +Copyright (c) 1999 Intel Corporation + +Module Name: + + salpal.c + +Abstract: + + Functions to make SAL and PAL proc calls + +Revision History + +--*/ +#include "lib.h" +#include "palproc.h" +#include "salproc.h" +/*++ + +Copyright (c) 1999 Intel Corporation + +Module Name: + + EfiRtLib.h + +Abstract: + + EFI Runtime library functions + + + +Revision History + +--*/ + +#include "efi.h" +#include "efilib.h" + +rArg +MakeStaticPALCall ( + IN UINT64 PALPROCPtr, + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4 + ); + +rArg +MakeStackedPALCall ( + IN UINT64 PALPROCPtr, + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4 + ); + + +PLABEL SalProcPlabel; +PLABEL PalProcPlabel; +CALL_SAL_PROC GlobalSalProc; +CALL_PAL_PROC GlobalPalProc; + +VOID +LibInitSalAndPalProc ( + OUT PLABEL *SalPlabel, + OUT UINT64 *PalEntry + ) +{ + SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable; + EFI_STATUS Status; + + GlobalSalProc = NULL; + GlobalPalProc = NULL; + + Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID **)&SalSystemTable); + if (EFI_ERROR(Status)) { + return; + } + + // + // BugBug: Add code to test checksum on the Sal System Table + // + if (SalSystemTable->Entry0.Type != 0) { + return; + } + + SalProcPlabel.ProcEntryPoint = SalSystemTable->Entry0.SalProcEntry; + SalProcPlabel.GP = SalSystemTable->Entry0.GlobalDataPointer; + GlobalSalProc = (CALL_SAL_PROC)&SalProcPlabel.ProcEntryPoint; + + // + // Need to check the PAL spec to make sure I'm not responsible for + // storing more state. + // We are passing in a Plabel that should be ignorred by the PAL. Call + // this way will cause use to retore our gp after the PAL returns. + // + PalProcPlabel.ProcEntryPoint = SalSystemTable->Entry0.PalProcEntry; + PalProcPlabel.GP = SalSystemTable->Entry0.GlobalDataPointer; + GlobalPalProc = (CALL_PAL_PROC)PalProcPlabel.ProcEntryPoint; + + *PalEntry = PalProcPlabel.ProcEntryPoint; + *SalPlabel = SalProcPlabel; +} + +EFI_STATUS +LibGetSalIoPortMapping ( + OUT UINT64 *IoPortMapping + ) +/*++ + + Get the IO Port Map from the SAL System Table. + DO NOT USE THIS TO DO YOU OWN IO's!!!!!!!!!!!! + Only use this for getting info, or initing the built in EFI IO abstraction. + Always use the EFI Device IO protoocl to access IO space. + +--*/ +{ + SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable; + SAL_ST_MEMORY_DESCRIPTOR_ENTRY *SalMemDesc; + EFI_STATUS Status; + + Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID **)&SalSystemTable); + if (EFI_ERROR(Status)) { + return EFI_UNSUPPORTED; + } + + // + // BugBug: Add code to test checksum on the Sal System Table + // + if (SalSystemTable->Entry0.Type != 0) { + return EFI_UNSUPPORTED; + } + + // + // The SalSystemTable pointer includes the Type 0 entry. + // The SalMemDesc is Type 1 so it comes next. + // + SalMemDesc = (SAL_ST_MEMORY_DESCRIPTOR_ENTRY *)(SalSystemTable + 1); + while (SalMemDesc->Type == SAL_ST_MEMORY_DESCRIPTOR) { + if (SalMemDesc->MemoryType == SAL_IO_PORT_MAPPING) { + *IoPortMapping = SalMemDesc->PhysicalMemoryAddress; + return EFI_SUCCESS; + } + SalMemDesc++; + } + return EFI_UNSUPPORTED; +} + +EFI_STATUS +LibGetSalIpiBlock ( + OUT UINT64 *IpiBlock + ) +/*++ + + Get the IPI block from the SAL system table + +--*/ +{ + SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable; + SAL_ST_MEMORY_DESCRIPTOR_ENTRY *SalMemDesc; + EFI_STATUS Status; + + Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID*)&SalSystemTable); + if (EFI_ERROR(Status)) { + return EFI_UNSUPPORTED; + } + + // + // BugBug: Add code to test checksum on the Sal System Table + // + if (SalSystemTable->Entry0.Type != 0) { + return EFI_UNSUPPORTED; + } + + // + // The SalSystemTable pointer includes the Type 0 entry. + // The SalMemDesc is Type 1 so it comes next. + // + SalMemDesc = (SAL_ST_MEMORY_DESCRIPTOR_ENTRY *)(SalSystemTable + 1); + while (SalMemDesc->Type == SAL_ST_MEMORY_DESCRIPTOR) { + if (SalMemDesc->MemoryType == SAL_SAPIC_IPI_BLOCK ) { + *IpiBlock = SalMemDesc->PhysicalMemoryAddress; + return EFI_SUCCESS; + } + SalMemDesc++; + } + return EFI_UNSUPPORTED; +} + +EFI_STATUS +LibGetSalWakeupVector ( + OUT UINT64 *WakeVector + ) +/*++ + +Get the wakeup vector from the SAL system table + +--*/ +{ + SAL_ST_AP_WAKEUP_DECRIPTOR *ApWakeUp; + + ApWakeUp = LibSearchSalSystemTable (SAL_ST_AP_WAKEUP); + if (!ApWakeUp) { + *WakeVector = -1; + return EFI_UNSUPPORTED; + } + *WakeVector = ApWakeUp->ExternalInterruptVector; + return EFI_SUCCESS; +} + +VOID * +LibSearchSalSystemTable ( + IN UINT8 EntryType + ) +{ + EFI_STATUS Status; + UINT8 *SalTableHack; + SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable; + UINT16 EntryCount; + UINT16 Count; + + Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID*)&SalSystemTable); + if (EFI_ERROR(Status)) { + return NULL; + } + + EntryCount = SalSystemTable->Header.EntryCount; + if (EntryCount == 0) { + return NULL; + } + // + // BugBug: Add code to test checksum on the Sal System Table + // + + SalTableHack = (UINT8 *)&SalSystemTable->Entry0; + for (Count = 0; Count < EntryCount ;Count++) { + if (*SalTableHack == EntryType) { + return (VOID *)SalTableHack; + } + switch (*SalTableHack) { + case SAL_ST_ENTRY_POINT: + SalTableHack += 48; + break; + case SAL_ST_MEMORY_DESCRIPTOR: + SalTableHack += 32; + break; + case SAL_ST_PLATFORM_FEATURES: + SalTableHack += 16; + break; + case SAL_ST_TR_USAGE: + SalTableHack += 32; + break; + case SAL_ST_PTC: + SalTableHack += 16; + break; + case SAL_ST_AP_WAKEUP: + SalTableHack += 16; + break; + default: + ASSERT(FALSE); + break; + } + } + return NULL; +} + +VOID +LibSalProc ( + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4, + IN UINT64 Arg5, + IN UINT64 Arg6, + IN UINT64 Arg7, + IN UINT64 Arg8, + OUT rArg *Results OPTIONAL + ) +{ + rArg ReturnValue; + + ReturnValue.p0 = -3; // SAL status return completed with error + if (GlobalSalProc) { + ReturnValue = GlobalSalProc(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); + } + + if (Results) { + CopyMem (Results, &ReturnValue, sizeof(rArg)); + } +} + +VOID +LibPalProc ( + IN UINT64 Arg1, // Pal Proc index + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4, + OUT rArg *Results OPTIONAL + ) +{ + + rArg ReturnValue; + + ReturnValue.p0 = -3; // PAL status return completed with error + + // + // check for valid PalProc entry point + // + + if (!GlobalPalProc) { + if (Results) + CopyMem (Results, &ReturnValue, sizeof(rArg)); + return; + } + + // + // check if index falls within stacked or static register calling conventions + // and call appropriate Pal stub call + // + + if (((Arg1 >=255) && (Arg1 <=511)) || + ((Arg1 >=768) && (Arg1 <=1023))) { + ReturnValue = MakeStackedPALCall((UINT64)GlobalPalProc,Arg1,Arg2,Arg3,Arg4); + } + else { + ReturnValue = MakeStaticPALCall((UINT64)GlobalPalProc,Arg1,Arg2,Arg3,Arg4); + } + + if (Results) + CopyMem (Results, &ReturnValue, sizeof(rArg)); + + return; +} + diff --git a/gnu-efi-3.0/lib/init.c b/gnu-efi-3.0/lib/init.c new file mode 100644 index 0000000..fa6f893 --- /dev/null +++ b/gnu-efi-3.0/lib/init.c @@ -0,0 +1,183 @@ +/*++ + +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) { + LibInitialized = TRUE; + LibFwInstance = FALSE; + + // + // 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, L"EFIDebug", &EfiGlobalVariable, &Attributes, &DataSize, &NewEFIDebug); + if (!EFI_ERROR(Status)) { + EFIDebug = NewEFIDebug; + } +} diff --git a/gnu-efi-3.0/lib/lib.h b/gnu-efi-3.0/lib/lib.h new file mode 100644 index 0000000..577bde2 --- /dev/null +++ b/gnu-efi-3.0/lib/lib.h @@ -0,0 +1,88 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + lib.h + +Abstract: + + EFI library header files + + + +Revision History + +--*/ + + +#include "efi.h" +#include "efilib.h" +#include "efirtlib.h" + +// +// Include non architectural protocols +// +#include "efivar.h" +#include "legacyboot.h" +#include "intload.h" +#include "vgaclass.h" +#include "eficonsplit.h" +#include "adapterdebug.h" +#include "intload.h" + +#include "efigpt.h" +#include "libsmbios.h" + +// +// Prototypes +// + +VOID +InitializeGuid ( + VOID + ); + +INTN +LibStubStriCmp ( + IN EFI_UNICODE_COLLATION_INTERFACE *This, + IN CHAR16 *S1, + IN CHAR16 *S2 + ); + +BOOLEAN +LibStubMetaiMatch ( + IN EFI_UNICODE_COLLATION_INTERFACE *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ); + +VOID +LibStubStrLwrUpr ( + IN EFI_UNICODE_COLLATION_INTERFACE *This, + IN CHAR16 *Str + ); + +BOOLEAN +LibMatchDevicePaths ( + IN EFI_DEVICE_PATH *Multi, + IN EFI_DEVICE_PATH *Single + ); + +EFI_DEVICE_PATH * +LibDuplicateDevicePathInstance ( + IN EFI_DEVICE_PATH *DevPath + ); + + +// +// Globals +// +extern BOOLEAN LibInitialized; +extern BOOLEAN LibFwInstance; +extern SIMPLE_TEXT_OUTPUT_INTERFACE *LibRuntimeDebugOut; +extern EFI_UNICODE_COLLATION_INTERFACE *UnicodeInterface; +extern EFI_UNICODE_COLLATION_INTERFACE LibStubUnicodeInterface; +extern EFI_RAISE_TPL LibRuntimeRaiseTPL; +extern EFI_RESTORE_TPL LibRuntimeRestoreTPL; diff --git a/gnu-efi-3.0/lib/lock.c b/gnu-efi-3.0/lib/lock.c new file mode 100644 index 0000000..a33bec3 --- /dev/null +++ b/gnu-efi-3.0/lib/lock.c @@ -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); +} diff --git a/gnu-efi-3.0/lib/misc.c b/gnu-efi-3.0/lib/misc.c new file mode 100644 index 0000000..1a68864 --- /dev/null +++ b/gnu-efi-3.0/lib/misc.c @@ -0,0 +1,520 @@ +/*++ + +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 * +ReallocatePool ( + IN VOID *OldPool, + IN UINTN OldSize, + IN UINTN NewSize + ) +{ + 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 +SetMem ( + IN VOID *Buffer, + IN UINTN Size, + IN UINT8 Value + ) +{ + RtSetMem (Buffer, Size, Value); +} + +VOID +CopyMem ( + IN VOID *Dest, + IN VOID *Src, + IN UINTN len + ) +{ + RtCopyMem (Dest, Src, len); +} + +INTN +CompareMem ( + IN VOID *Dest, + IN 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 + // + + 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; + 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 +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); + + 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 + ); + + if (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))==0) { + *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; +} diff --git a/gnu-efi-3.0/lib/print.c b/gnu-efi-3.0/lib/print.c new file mode 100644 index 0000000..b716299 --- /dev/null +++ b/gnu-efi-3.0/lib/print.c @@ -0,0 +1,1326 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + print.c + +Abstract: + + + + +Revision History + +--*/ + +#include "lib.h" +#include "efistdarg.h" // !!! + +// +// Declare runtime functions +// + +#ifdef RUNTIME_CODE +#ifndef __GNUC__ +#pragma RUNTIME_CODE(DbgPrint) + +// For debugging.. + +/* +#pragma RUNTIME_CODE(_Print) +#pragma RUNTIME_CODE(PFLUSH) +#pragma RUNTIME_CODE(PSETATTR) +#pragma RUNTIME_CODE(PPUTC) +#pragma RUNTIME_CODE(PGETC) +#pragma RUNTIME_CODE(PITEM) +#pragma RUNTIME_CODE(ValueToHex) +#pragma RUNTIME_CODE(ValueToString) +#pragma RUNTIME_CODE(TimeToString) +*/ + +#endif /* !defined(__GNUC__) */ +#endif + +// +// +// + + +#define PRINT_STRING_LEN 200 +#define PRINT_ITEM_BUFFER_LEN 100 + +typedef struct { + BOOLEAN Ascii; + UINTN Index; + union { + CHAR16 *pw; + CHAR8 *pc; + } un; +} POINTER; + +#define pw un.pw +#define pc un.pc + +typedef struct _pitem { + + POINTER Item; + CHAR16 Scratch[PRINT_ITEM_BUFFER_LEN]; + UINTN Width; + UINTN FieldWidth; + UINTN *WidthParse; + CHAR16 Pad; + BOOLEAN PadBefore; + BOOLEAN Comma; + BOOLEAN Long; +} PRINT_ITEM; + + +typedef struct _pstate { + // Input + POINTER fmt; + va_list args; + + // Output + CHAR16 *Buffer; + CHAR16 *End; + CHAR16 *Pos; + UINTN Len; + + UINTN Attr; + UINTN RestoreAttr; + + UINTN AttrNorm; + UINTN AttrHighlight; + UINTN AttrError; + + INTN (*Output)(VOID *context, CHAR16 *str); + INTN (*SetAttr)(VOID *context, UINTN attr); + VOID *Context; + + // Current item being formatted + struct _pitem *Item; +} PRINT_STATE; + +// +// Internal fucntions +// + +STATIC +UINTN +_Print ( + IN PRINT_STATE *ps + ); + +STATIC +UINTN +_IPrint ( + IN UINTN Column, + IN UINTN Row, + IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out, + IN CHAR16 *fmt, + IN CHAR8 *fmta, + IN va_list args + ); + +STATIC +INTN +_DbgOut ( + IN VOID *Context, + IN CHAR16 *Buffer + ); + +STATIC +VOID +PFLUSH ( + IN OUT PRINT_STATE *ps + ); + +STATIC +VOID +PPUTC ( + IN OUT PRINT_STATE *ps, + IN CHAR16 c + ); + +STATIC +VOID +PITEM ( + IN OUT PRINT_STATE *ps + ); + +STATIC +CHAR16 +PGETC ( + IN POINTER *p + ); + +STATIC +VOID +PSETATTR ( + IN OUT PRINT_STATE *ps, + IN UINTN Attr + ); + +// +// +// + +INTN +_SPrint ( + IN VOID *Context, + IN CHAR16 *Buffer + ); + +INTN +_PoolPrint ( + IN VOID *Context, + IN CHAR16 *Buffer + ); + +INTN +DbgPrint ( + IN INTN mask, + IN 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 (*)(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; + ps.SetAttr (ps.Context, attr); + } + + _Print (&ps); + + va_end (ps.args); + va_end (args); + + // + // Restore original attributes + // + + if (ps.SetAttr) { + ps.SetAttr (ps.Context, SavedAttribute); + } + + return 0; +} + +STATIC IsLocalPrint(void *func) +{ + if (func == _DbgOut || func == _SPrint || func == _PoolPrint) + return 1; + return 0; +} + +STATIC +INTN +_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 +_SPrint ( + IN VOID *Context, + IN CHAR16 *Buffer + ) +// Append string worker for SPrint, 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-1] = 0; + } + + return 0; +} + + +INTN +_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->str, + spc->len * sizeof(CHAR16), + spc->maxlen * sizeof(CHAR16) + ); + + if (!spc->str) { + spc->len = 0; + spc->maxlen = 0; + } + } + + // + // Append the new text + // + + return _SPrint (Context, Buffer); +} + + + +VOID +_PoolCatPrint ( + IN CHAR16 *fmt, + IN va_list args, + IN OUT POOL_PRINT *spc, + IN INTN (*Output)(VOID *context, CHAR16 *str) + ) +// Dispath function for SPrint, PoolPrint, and CatPrint +{ + PRINT_STATE ps; + + ZeroMem (&ps, sizeof(ps)); + ps.Output = Output; + ps.Context = spc; + ps.fmt.pw = fmt; + va_copy(ps.args, args); + _Print (&ps); + va_end(ps.args); +} + + + +UINTN +SPrint ( + OUT CHAR16 *Str, + IN UINTN StrSize, + IN 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 + +--*/ +{ + POOL_PRINT spc; + va_list args; + + + va_start (args, fmt); + spc.str = Str; + spc.maxlen = StrSize / sizeof(CHAR16) - 1; + spc.len = 0; + + _PoolCatPrint (fmt, args, &spc, _SPrint); + va_end (args); + return spc.len; +} + + +CHAR16 * +PoolPrint ( + IN 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. + +--*/ +{ + POOL_PRINT spc; + va_list args; + + ZeroMem (&spc, sizeof(spc)); + va_start (args, fmt); + _PoolCatPrint (fmt, args, &spc, _PoolPrint); + va_end (args); + return spc.str; +} + + + +CHAR16 * +CatPrint ( + IN OUT POOL_PRINT *Str, + IN 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 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 +VPrint ( + IN 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 _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args); +} + + +UINTN +PrintAt ( + IN UINTN Column, + IN UINTN Row, + IN 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 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 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 too + + 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 UINTN Column, + IN UINTN Row, + IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out, + IN CHAR16 *fmt, + IN CHAR8 *fmta, + IN va_list args + ) +// Display string worker for: Print, PrintAt, IPrint, IPrintAt +{ + PRINT_STATE ps; + UINTN back; + + ZeroMem (&ps, sizeof(ps)); + ps.Context = Out; + ps.Output = (INTN (*)(VOID *, CHAR16 *)) Out->OutputString; + ps.SetAttr = (INTN (*)(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 = _Print (&ps); + va_end(ps.args); + return back; +} + + +UINTN +APrint ( + IN 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 +VOID +PFLUSH ( + IN OUT PRINT_STATE *ps + ) +{ + *ps->Pos = 0; + if (IsLocalPrint(ps->Output)) + ps->Output(ps->Context, ps->Buffer); + else + uefi_call_wrapper(ps->Output, 2, ps->Context, ps->Buffer); + ps->Pos = ps->Buffer; +} + +STATIC +VOID +PSETATTR ( + IN OUT PRINT_STATE *ps, + IN UINTN Attr + ) +{ + PFLUSH (ps); + + ps->RestoreAttr = ps->Attr; + if (ps->SetAttr) { + uefi_call_wrapper(ps->SetAttr, 2, ps->Context, Attr); + } + + ps->Attr = Attr; +} + +STATIC +VOID +PPUTC ( + IN OUT PRINT_STATE *ps, + IN CHAR16 c + ) +{ + // if this is a newline, add a carraige return + if (c == '\n') { + PPUTC (ps, '\r'); + } + + *ps->Pos = c; + ps->Pos += 1; + ps->Len += 1; + + // if at the end of the buffer, flush it + if (ps->Pos >= ps->End) { + PFLUSH(ps); + } +} + + +STATIC +CHAR16 +PGETC ( + IN POINTER *p + ) +{ + CHAR16 c; + + c = p->Ascii ? p->pc[p->Index] : p->pw[p->Index]; + p->Index += 1; + + return c; +} + + +STATIC +VOID +PITEM ( + IN OUT PRINT_STATE *ps + ) +{ + UINTN Len, i; + PRINT_ITEM *Item; + CHAR16 c; + + // Get the length of the item + Item = ps->Item; + Item->Item.Index = 0; + while (Item->Item.Index < Item->FieldWidth) { + c = PGETC(&Item->Item); + if (!c) { + Item->Item.Index -= 1; + break; + } + } + Len = Item->Item.Index; + + // if there is no item field width, use the items width + if (Item->FieldWidth == (UINTN) -1) { + Item->FieldWidth = Len; + } + + // if item is larger then width, update width + if (Len > Item->Width) { + Item->Width = Len; + } + + + // if pad field before, add pad char + if (Item->PadBefore) { + for (i=Item->Width; i < Item->FieldWidth; i+=1) { + PPUTC (ps, ' '); + } + } + + // pad item + for (i=Len; i < Item->Width; i++) { + PPUTC (ps, Item->Pad); + } + + // add the item + Item->Item.Index=0; + while (Item->Item.Index < Len) { + PPUTC (ps, PGETC(&Item->Item)); + } + + // If pad at the end, add pad char + if (!Item->PadBefore) { + for (i=Item->Width; i < Item->FieldWidth; i+=1) { + PPUTC (ps, ' '); + } + } +} + + +STATIC +UINTN +_Print ( + IN PRINT_STATE *ps + ) +/*++ + +Routine Description: + + %w.lF - w = width + l = field width + F = format of arg + + Args F: + 0 - pad with zeros + - - justify on left (default is on right) + , - add comma's to field + * - width provided on stack + n - Set output attribute to normal (for this field only) + h - Set output attribute to highlight (for this field only) + e - Set output attribute to error (for this field only) + l - Value is 64 bits + + a - ascii string + s - unicode string + X - fixed 8 byte value in hex + x - hex value + d - value as decimal + c - Unicode char + t - EFI time structure + g - Pointer to GUID + r - EFI status code (result code) + + N - Set output attribute to normal + H - Set output attribute to highlight + E - Set output attribute to error + % - Print a % + +Arguments: + + SystemTable - The system table + +Returns: + + Number of charactors written + +--*/ +{ + CHAR16 c; + UINTN Attr; + PRINT_ITEM Item; + CHAR16 Buffer[PRINT_STRING_LEN]; + + ps->Len = 0; + ps->Buffer = Buffer; + ps->Pos = Buffer; + ps->End = Buffer + PRINT_STRING_LEN - 1; + ps->Item = &Item; + + ps->fmt.Index = 0; + while ((c = PGETC(&ps->fmt))) { + + if (c != '%') { + PPUTC ( ps, c ); + continue; + } + + // setup for new item + Item.FieldWidth = (UINTN) -1; + Item.Width = 0; + Item.WidthParse = &Item.Width; + Item.Pad = ' '; + Item.PadBefore = TRUE; + Item.Comma = FALSE; + Item.Long = FALSE; + Item.Item.Ascii = FALSE; + Item.Item.pw = NULL; + ps->RestoreAttr = 0; + Attr = 0; + + while ((c = PGETC(&ps->fmt))) { + + switch (c) { + + case '%': + // + // %% -> % + // + Item.Item.pw = Item.Scratch; + Item.Item.pw[0] = '%'; + Item.Item.pw[1] = 0; + break; + + case '0': + Item.Pad = '0'; + break; + + case '-': + Item.PadBefore = FALSE; + break; + + case ',': + Item.Comma = TRUE; + break; + + case '.': + Item.WidthParse = &Item.FieldWidth; + break; + + case '*': + *Item.WidthParse = va_arg(ps->args, UINTN); + break; + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + *Item.WidthParse = 0; + do { + *Item.WidthParse = *Item.WidthParse * 10 + c - '0'; + c = PGETC(&ps->fmt); + } while (c >= '0' && c <= '9') ; + ps->fmt.Index -= 1; + break; + + case 'a': + Item.Item.pc = va_arg(ps->args, CHAR8 *); + Item.Item.Ascii = TRUE; + if (!Item.Item.pc) { + Item.Item.pc = (CHAR8 *)"(null)"; + } + break; + + case 's': + Item.Item.pw = va_arg(ps->args, CHAR16 *); + if (!Item.Item.pw) { + Item.Item.pw = L"(null)"; + } + break; + + case 'c': + Item.Item.pw = Item.Scratch; + Item.Item.pw[0] = (CHAR16) va_arg(ps->args, UINTN); + Item.Item.pw[1] = 0; + break; + + case 'l': + Item.Long = TRUE; + break; + + case 'X': + Item.Width = Item.Long ? 16 : 8; + Item.Pad = '0'; + case 'x': + Item.Item.pw = Item.Scratch; + ValueToHex ( + Item.Item.pw, + Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32) + ); + + break; + + + case 'g': + Item.Item.pw = Item.Scratch; + GuidToString (Item.Item.pw, va_arg(ps->args, EFI_GUID *)); + break; + + case 'd': + Item.Item.pw = Item.Scratch; + ValueToString ( + Item.Item.pw, + Item.Comma, + Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32) + ); + break + ; + case 't': + Item.Item.pw = Item.Scratch; + TimeToString (Item.Item.pw, va_arg(ps->args, EFI_TIME *)); + break; + + case 'r': + Item.Item.pw = Item.Scratch; + StatusToString (Item.Item.pw, va_arg(ps->args, EFI_STATUS)); + break; + + case 'n': + PSETATTR(ps, ps->AttrNorm); + break; + + case 'h': + PSETATTR(ps, ps->AttrHighlight); + break; + + case 'e': + PSETATTR(ps, ps->AttrError); + break; + + case 'N': + Attr = ps->AttrNorm; + break; + + case 'H': + Attr = ps->AttrHighlight; + break; + + case 'E': + Attr = ps->AttrError; + break; + + default: + Item.Item.pw = Item.Scratch; + Item.Item.pw[0] = '?'; + Item.Item.pw[1] = 0; + break; + } + + // if we have an Item + if (Item.Item.pw) { + PITEM (ps); + break; + } + + // if we have an Attr set + if (Attr) { + PSETATTR(ps, Attr); + ps->RestoreAttr = 0; + break; + } + } + + if (ps->RestoreAttr) { + PSETATTR(ps, ps->RestoreAttr); + } + } + + // Flush buffer + PFLUSH (ps); + return ps->Len; +} + +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) { + *(p1++) = Hex[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 = (Comma ? ca[(p1 - str) % 3] : 999) + 1; + while (p1 != str) { + + c -= 1; + if (!c) { + *(p2++) = ','; + c = 3; + } + + *(p2++) = *(--p1); + } + *p2 = 0; +} + +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 + SPrint (Buffer, 0, L"%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 (L"%*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 (L"Press Enter to continue :"); + Input (L"", ReturnStr, sizeof(ReturnStr)/sizeof(CHAR16)); + Print (L"\n"); + } + + } +} diff --git a/gnu-efi-3.0/lib/runtime/efirtlib.c b/gnu-efi-3.0/lib/runtime/efirtlib.c new file mode 100644 index 0000000..bae75d7 --- /dev/null +++ b/gnu-efi-3.0/lib/runtime/efirtlib.c @@ -0,0 +1,149 @@ +/*++ + +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 + ) +{ + INT8 *pt; + + pt = Buffer; + while (Size--) { + *(pt++) = 0; + } +} + +#ifndef __GNUC__ +#pragma RUNTIME_CODE(RtSetMem) +#endif +VOID +RUNTIMEFUNCTION +RtSetMem ( + IN VOID *Buffer, + IN UINTN Size, + IN UINT8 Value + ) +{ + INT8 *pt; + + pt = Buffer; + while (Size--) { + *(pt++) = Value; + } +} + +#ifndef __GNUC__ +#pragma RUNTIME_CODE(RtCopyMem) +#endif +VOID +RUNTIMEFUNCTION +RtCopyMem ( + IN VOID *Dest, + IN VOID *Src, + IN UINTN len + ) +{ + CHAR8 *d, *s; + + d = Dest; + s = Src; + while (len--) { + *(d++) = *(s++); + } +} + +#ifndef __GNUC__ +#pragma RUNTIME_CODE(RtCompareMem) +#endif +INTN +RUNTIMEFUNCTION +RtCompareMem ( + IN VOID *Dest, + IN VOID *Src, + IN UINTN len + ) +{ + CHAR8 *d, *s; + + d = Dest; + s = Src; + while (len--) { + if (*d != *s) { + return *d - *s; + } + + d += 1; + s += 1; + } + + return 0; +} + +#ifndef __GNUC__ +#pragma RUNTIME_CODE(RtCompareGuid) +#endif +INTN +RUNTIMEFUNCTION +RtCompareGuid ( + IN EFI_GUID *Guid1, + IN EFI_GUID *Guid2 + ) +/*++ + +Routine Description: + + Compares to GUIDs + +Arguments: + + Guid1 - guid to compare + Guid2 - guid to compare + +Returns: + = 0 if Guid1 == Guid2 + +--*/ +{ + INT32 *g1, *g2, r; + + // + // Compare 32 bits at a time + // + + g1 = (INT32 *) Guid1; + g2 = (INT32 *) Guid2; + + r = g1[0] - g2[0]; + r |= g1[1] - g2[1]; + r |= g1[2] - g2[2]; + r |= g1[3] - g2[3]; + + return r; +} + + diff --git a/gnu-efi-3.0/lib/runtime/rtdata.c b/gnu-efi-3.0/lib/runtime/rtdata.c new file mode 100644 index 0000000..3efcbf3 --- /dev/null +++ b/gnu-efi-3.0/lib/runtime/rtdata.c @@ -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; + diff --git a/gnu-efi-3.0/lib/runtime/rtlock.c b/gnu-efi-3.0/lib/runtime/rtlock.c new file mode 100644 index 0000000..2eafdca --- /dev/null +++ b/gnu-efi-3.0/lib/runtime/rtlock.c @@ -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); + } + } +} diff --git a/gnu-efi-3.0/lib/runtime/rtstr.c b/gnu-efi-3.0/lib/runtime/rtstr.c new file mode 100644 index 0000000..332e50a --- /dev/null +++ b/gnu-efi-3.0/lib/runtime/rtstr.c @@ -0,0 +1,140 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + str.c + +Abstract: + + String runtime functions + + +Revision History + +--*/ + +#include "lib.h" + +#ifndef __GNUC__ +#pragma RUNTIME_CODE(RtAcquireLock) +#endif +INTN +RUNTIMEFUNCTION +RtStrCmp ( + IN CHAR16 *s1, + IN 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 CHAR16 *Src + ) +// copy strings +{ + while (*Src) { + *(Dest++) = *(Src++); + } + *Dest = 0; +} + +#ifndef __GNUC__ +#pragma RUNTIME_CODE(RtStrCat) +#endif +VOID +RUNTIMEFUNCTION +RtStrCat ( + IN CHAR16 *Dest, + IN CHAR16 *Src + ) +{ + RtStrCpy(Dest+StrLen(Dest), Src); +} + +#ifndef __GNUC__ +#pragma RUNTIME_CODE(RtStrLen) +#endif +UINTN +RUNTIMEFUNCTION +RtStrLen ( + IN CHAR16 *s1 + ) +// string length +{ + UINTN len; + + for (len=0; *s1; s1+=1, len+=1) ; + return len; +} + +#ifndef __GNUC__ +#pragma RUNTIME_CODE(RtStrSize) +#endif +UINTN +RUNTIMEFUNCTION +RtStrSize ( + IN 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))); +} + + diff --git a/gnu-efi-3.0/lib/runtime/vm.c b/gnu-efi-3.0/lib/runtime/vm.c new file mode 100644 index 0000000..26e0c8e --- /dev/null +++ b/gnu-efi-3.0/lib/runtime/vm.c @@ -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); +} diff --git a/gnu-efi-3.0/lib/smbios.c b/gnu-efi-3.0/lib/smbios.c new file mode 100644 index 0000000..5986f5a --- /dev/null +++ b/gnu-efi-3.0/lib/smbios.c @@ -0,0 +1,126 @@ +/*++ + +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" + + +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 *)(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; +} diff --git a/gnu-efi-3.0/lib/sread.c b/gnu-efi-3.0/lib/sread.c new file mode 100644 index 0000000..888f954 --- /dev/null +++ b/gnu-efi-3.0/lib/sread.c @@ -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); +} diff --git a/gnu-efi-3.0/lib/str.c b/gnu-efi-3.0/lib/str.c new file mode 100644 index 0000000..3b436dc --- /dev/null +++ b/gnu-efi-3.0/lib/str.c @@ -0,0 +1,379 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + str.c + +Abstract: + + + + +Revision History + +--*/ + +#include "lib.h" + + +INTN +StrCmp ( + IN CHAR16 *s1, + IN CHAR16 *s2 + ) +// compare strings +{ + return RtStrCmp(s1, s2); +} + +INTN +StrnCmp ( + IN CHAR16 *s1, + IN 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 +LibStubStriCmp ( + IN EFI_UNICODE_COLLATION_INTERFACE *This, + IN CHAR16 *s1, + IN CHAR16 *s2 + ) +{ + return StrCmp (s1, s2); +} + +VOID +LibStubStrLwrUpr ( + IN EFI_UNICODE_COLLATION_INTERFACE *This, + IN CHAR16 *Str + ) +{ +} + +INTN +StriCmp ( + IN CHAR16 *s1, + IN CHAR16 *s2 + ) +// compare strings +{ + if (UnicodeInterface == &LibStubUnicodeInterface) + return UnicodeInterface->StriColl(UnicodeInterface, s1, s2); + else + return uefi_call_wrapper(UnicodeInterface->StriColl, 3, UnicodeInterface, s1, 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 CHAR16 *Src + ) +// copy strings +{ + RtStrCpy (Dest, Src); +} + +VOID +StrCat ( + IN CHAR16 *Dest, + IN CHAR16 *Src + ) +{ + RtStrCat(Dest, Src); +} + +UINTN +StrLen ( + IN CHAR16 *s1 + ) +// string length +{ + return RtStrLen(s1); +} + +UINTN +StrSize ( + IN CHAR16 *s1 + ) +// string size +{ + return RtStrSize(s1); +} + +CHAR16 * +StrDuplicate ( + IN CHAR16 *Src + ) +// duplicate a string +{ + CHAR16 *Dest; + UINTN Size; + + Size = StrSize(Src); + Dest = AllocatePool (Size); + if (Dest) { + CopyMem (Dest, Src, Size); + } + return Dest; +} + +UINTN +strlena ( + IN CHAR8 *s1 + ) +// string length +{ + UINTN len; + + for (len=0; *s1; s1+=1, len+=1) ; + return len; +} + +UINTN +strcmpa ( + IN CHAR8 *s1, + IN CHAR8 *s2 + ) +// compare strings +{ + while (*s1) { + if (*s1 != *s2) { + break; + } + + s1 += 1; + s2 += 1; + } + + return *s1 - *s2; +} + +UINTN +strncmpa ( + IN CHAR8 *s1, + IN 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 ( + CHAR16 *str + ) +// convert hex string to uint +{ + UINTN u; + CHAR16 c; + + // skip preceeding white space + while (*str && *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) | (c - (c >= 'A' ? 'A'-10 : '0')); + } else { + break; + } + } + + return u; +} + +UINTN +Atoi ( + CHAR16 *str + ) +// convert hex string to uint +{ + UINTN u; + CHAR16 c; + + // skip preceeding white space + while (*str && *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 +LibStubMetaiMatch ( + IN EFI_UNICODE_COLLATION_INTERFACE *This, + 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); +} diff --git a/gnu-efi-3.0/lib/x86_64/callwrap.c b/gnu-efi-3.0/lib/x86_64/callwrap.c new file mode 100644 index 0000000..1c564a6 --- /dev/null +++ b/gnu-efi-3.0/lib/x86_64/callwrap.c @@ -0,0 +1,125 @@ +/* + * 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. + */ + +#include "efi.h" +#include "efistdarg.h" + +UINT64 efi_call0(void *func); +UINT64 efi_call1(void *func, UINT64 arg1); +UINT64 efi_call2(void *func, UINT64 arg1, UINT64 arg2); +UINT64 efi_call3(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3); +UINT64 efi_call4(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3, + UINT64 arg4); +UINT64 efi_call5(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3, + UINT64 arg4, UINT64 arg5); +UINT64 efi_call6(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3, + UINT64 arg4, UINT64 arg5, UINT64 arg6); +UINT64 efi_call7(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3, + UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7); +UINT64 efi_call8(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3, + UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7, + UINT64 arg8); +UINT64 efi_call9(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3, + UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7, + UINT64 arg8, UINT64 arg9); +UINT64 efi_call10(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3, + UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7, + UINT64 arg8, UINT64 arg9, UINT64 arg10); + +#define EFI_ARG_NUM_MAX 10 + +EFI_STATUS uefi_call_wrapper(void *fp, unsigned long va_num, ...) +{ + va_list ap; + int i; + unsigned long args[EFI_ARG_NUM_MAX]; + + if (va_num > EFI_ARG_NUM_MAX || va_num < 0) { + return EFI_LOAD_ERROR; + } + va_start(ap, va_num); + for (i = 0; i < va_num; i++) { + args[i] = va_arg(ap, UINT64); + } + va_end(ap); + /* As the number of args grows extend it appropriately */ + switch (va_num) { + case 0: + return efi_call0(fp); + case 1: + return efi_call1(fp, args[0]); + case 2: + return efi_call2(fp, + args[0], args[1]); + case 3: + return efi_call3(fp, + args[0], args[1], args[2]); + case 4: + return efi_call4(fp, + args[0], args[1], args[2], args[3]); + case 5: + return efi_call5(fp, + args[0], args[1], args[2], args[3], + args[4]); + case 6: + return efi_call6(fp, + args[0], args[1], args[2], args[3], + args[4], args[5]); + case 7: + return efi_call7(fp, + args[0], args[1], args[2], args[3], + args[4], args[5], args[6]); + case 8: + return efi_call8(fp, + args[0], args[1], args[2], args[3], + args[4], args[5], args[6], args[7]); + case 9: + return efi_call9(fp, + args[0], args[1], args[2], args[3], + args[4], args[5], args[6], args[7], + args[8]); + case 10: + return efi_call10(fp, + args[0], args[1], args[2], args[3], + args[4], args[5], args[6], args[7], + args[8], args[9]); + default: + return EFI_LOAD_ERROR; + } +} diff --git a/gnu-efi-3.0/lib/x86_64/efi_stub.S b/gnu-efi-3.0/lib/x86_64/efi_stub.S new file mode 100644 index 0000000..b402610 --- /dev/null +++ b/gnu-efi-3.0/lib/x86_64/efi_stub.S @@ -0,0 +1,274 @@ +/* + * 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> + */ + +/* + * 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) ELF gives us 8-byte aligned %rsp, so we need to pad out to 16-byte + * alignment. + * c) inside each call thunker, we can only adjust the stack by + * multiples of 16 bytes. "offset" below refers to however much + * we allocate inside a thunker. + * d) 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. + * e) 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) (48 saved) + * 6) r9 -> 40(%rsp) (48 saved) + * 7) pad+offset+0(%rsp) -> 48(%rsp) (64 saved) + * 8) pad+offset+8(%rsp) -> 56(%rsp) (64 saved) + * 9) pad+offset+16(%rsp) -> 64(%rsp) (80 saved) + * 10) pad+offset+24(%rsp) -> 72(%rsp) (80 saved) + * 11) pad+offset+32(%rsp) -> 80(%rsp) (96 saved) + * 12) pad+offset+40(%rsp) -> 88(%rsp) (96 saved) + * f) 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) (48 saved) + * 6) pad+offset+0(%rsp) -> 40(%rsp) (48 saved) + * 7) pad+offset+8(%rsp) -> 48(%rsp) (64 saved) + * 8) pad+offset+16(%rsp) -> 56(%rsp) (64 saved) + * 9) pad+offset+24(%rsp) -> 64(%rsp) (80 saved) + * 10) pad+offset+32(%rsp) -> 72(%rsp) (80 saved) + * 11) pad+offset+40(%rsp) -> 80(%rsp) (96 saved) + * 12) pad+offset+48(%rsp) -> 88(%rsp) (96 saved) + * e) arguments need to be moved in opposite order to avoid clobbering + * f) pad_stack leaves the amount of padding it added in %r11 for functions + * to use + * g) efi -> elf calls don't need to pad the stack, because the 16-byte + * alignment is also always 8-byte aligned. + */ + +#define ENTRY(name) \ + .globl name; \ + name: + +#define out(val) \ + push %rax ; \ + mov val, %rax ; \ + out %al, $128 ; \ + pop %rax + +#define pad_stack \ + subq $8, %rsp ; /* must be a multiple of 16 - sizeof(%rip) */ \ + /* stash some handy integers */ \ + mov $0x8, %rax ; \ + mov $0x10, %r10 ; \ + /* see if we need padding */ \ + and %rsp, %rax ; \ + /* store the pad amount in %r11 */ \ + cmovnz %rax, %r11 ; \ + cmovz %r10, %r11 ; \ + /* insert the padding */ \ + subq %r11, %rsp ; \ + /* add the $8 we saved above in %r11 */ \ + addq $8, %r11 ; \ + /* store the pad amount */ \ + mov %r11, (%rsp) ; \ + /* compensate for %rip being stored on the stack by call */ \ + addq $8, %r11 + +#define unpad_stack \ + /* fetch the pad amount we saved (%r11 has been clobbered) */ \ + mov (%rsp), %r11 ; \ + /* remove the padding */ \ + addq %r11, %rsp + +ENTRY(efi_call0) + pad_stack + subq $32, %rsp + call *%rdi + addq $32, %rsp + unpad_stack + ret + +ENTRY(efi_call1) + pad_stack + subq $32, %rsp + mov %rsi, %rcx + call *%rdi + addq $32, %rsp + unpad_stack + ret + +ENTRY(efi_call2) + pad_stack + subq $32, %rsp + /* mov %rdx, %rdx */ + mov %rsi, %rcx + call *%rdi + addq $32, %rsp + unpad_stack + ret + +ENTRY(efi_call3) + pad_stack + subq $32, %rsp + mov %rcx, %r8 + /* mov %rdx, %rdx */ + mov %rsi, %rcx + call *%rdi + addq $32, %rsp + unpad_stack + ret + +ENTRY(efi_call4) + pad_stack + subq $32, %rsp + mov %r8, %r9 + mov %rcx, %r8 + /* mov %rdx, %rdx */ + mov %rsi, %rcx + call *%rdi + addq $32, %rsp + unpad_stack + ret + +ENTRY(efi_call5) + pad_stack + subq $48, %rsp + mov %r9, 32(%rsp) + mov %r8, %r9 + mov %rcx, %r8 + /* mov %rdx, %rdx */ + mov %rsi, %rcx + call *%rdi + addq $48, %rsp + unpad_stack + ret + +ENTRY(efi_call6) + pad_stack + subq $48, %rsp + addq $48, %r11 + addq %rsp, %r11 + mov (%r11), %rax + mov %rax, 40(%rsp) + mov %r9, 32(%rsp) + mov %r8, %r9 + mov %rcx, %r8 + /* mov %rdx, %rdx */ + mov %rsi, %rcx + call *%rdi + addq $48, %rsp + unpad_stack + ret + +ENTRY(efi_call7) + pad_stack + subq $64, %rsp + addq $64, %r11 + addq $8, %r11 + addq %rsp, %r11 + mov (%r11), %rax + mov %rax, 48(%rsp) + subq $8, %r11 + mov (%r11), %rax + mov %rax, 40(%rsp) + mov %r9, 32(%rsp) + mov %r8, %r9 + mov %rcx, %r8 + /* mov %rdx, %rdx */ + mov %rsi, %rcx + call *%rdi + addq $64, %rsp + unpad_stack + ret + +ENTRY(efi_call8) + pad_stack + subq $64, %rsp + addq $64, %r11 + addq $16, %r11 + addq %rsp, %r11 + mov (%r11), %rax + mov %rax, 56(%rsp) + subq $8, %r11 + mov (%r11), %rax + mov %rax, 48(%rsp) + subq $8, %r11 + mov (%r11), %rax + mov %rax, 40(%rsp) + mov %r9, 32(%rsp) + mov %r8, %r9 + mov %rcx, %r8 + /* mov %rdx, %rdx */ + mov %rsi, %rcx + call *%rdi + addq $64, %rsp + unpad_stack + ret + +ENTRY(efi_call9) + pad_stack + subq $80, %rsp + addq $80, %r11 + addq $24, %r11 + addq %rsp, %r11 + mov (%r11), %rax + mov %rax, 64(%rsp) + subq $8, %r11 + mov (%r11), %rax + mov %rax, 56(%rsp) + subq $8, %r11 + mov (%r11), %rax + mov %rax, 48(%rsp) + subq $8, %r11 + mov (%r11), %rax + mov %rax, 40(%rsp) + mov %r9, 32(%rsp) + mov %r8, %r9 + mov %rcx, %r8 + /* mov %rdx, %rdx */ + mov %rsi, %rcx + call *%rdi + addq $80, %rsp + unpad_stack + ret + +ENTRY(efi_call10) + pad_stack + subq $80, %rsp + addq $80, %r11 + addq $32, %r11 + addq %rsp, %r11 + mov (%r11), %rax + mov %rax, 72(%rsp) + subq $8, %r11 + mov (%r11), %rax + mov %rax, 64(%rsp) + subq $8, %r11 + mov (%r11), %rax + mov %rax, 56(%rsp) + subq $8, %r11 + mov (%r11), %rax + mov %rax, 48(%rsp) + subq $8, %r11 + mov (%r11), %rax + mov %rax, 40(%rsp) + mov %r9, 32(%rsp) + mov %r8, %r9 + mov %rcx, %r8 + /* mov %rdx, %rdx */ + mov %rsi, %rcx + call *%rdi + addq $80, %rsp + unpad_stack + ret diff --git a/gnu-efi-3.0/lib/x86_64/initplat.c b/gnu-efi-3.0/lib/x86_64/initplat.c new file mode 100644 index 0000000..1e6ea82 --- /dev/null +++ b/gnu-efi-3.0/lib/x86_64/initplat.c @@ -0,0 +1,28 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + initplat.c + +Abstract: + + + + +Revision History + +--*/ + +#include "lib.h" + +VOID +InitializeLibPlatform ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) + +{ +} + diff --git a/gnu-efi-3.0/lib/x86_64/math.c b/gnu-efi-3.0/lib/x86_64/math.c new file mode 100644 index 0000000..4f40388 --- /dev/null +++ b/gnu-efi-3.0/lib/x86_64/math.c @@ -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 +{ +#ifdef __GNUC__ + 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 +{ +#ifdef __GNUC__ + 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 +{ +#ifdef __GNUC__ + 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!! +{ +#ifdef __GNUC__ + 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 +} |