diff --git a/Bootloader/CMakeLists.txt b/Bootloader/CMakeLists.txt index 930f51c..d8ee154 100644 --- a/Bootloader/CMakeLists.txt +++ b/Bootloader/CMakeLists.txt @@ -1,45 +1,32 @@ cmake_minimum_required(VERSION 3.20) project(ksOS_bootloader LANGUAGES C ASM) -set(UEFI_COMPILE_OPTIONS +set(UEFI_COMPILE_OPTIONS -std=c23 -target aarch64-unknown-windows-msvc -Wall -Wextra -fno-builtin ) -set(POSIX_UEFI_SOURCES - Source/uefi/crt_aarch64.c - Source/uefi/dirent.c - Source/uefi/qsort.c - Source/uefi/stat.c - Source/uefi/stdio.c - Source/uefi/stdlib.c - Source/uefi/string.c - Source/uefi/time.c - Source/uefi/unistd.c +add_executable(BOOTAA64 + Source/uefi/efi_entry.c + Source/main.c ) - -add_library(posix_uefi_lib OBJECT ${POSIX_UEFI_SOURCES}) -target_compile_options(posix_uefi_lib PRIVATE ${UEFI_COMPILE_OPTIONS}) -target_include_directories(posix_uefi_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Source/uefi) - - -add_executable(BOOTAA64 Source/main.c) target_compile_options(BOOTAA64 PRIVATE ${UEFI_COMPILE_OPTIONS}) - -target_link_libraries(BOOTAA64 PRIVATE posix_uefi_lib) +target_include_directories(BOOTAA64 PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/Source + ${CMAKE_CURRENT_SOURCE_DIR}/Source/uefi +) target_link_options(BOOTAA64 PRIVATE -fuse-ld=lld -target aarch64-unknown-windows-msvc -nostdlib -Wl,-subsystem:efi_application - -Wl,-include:uefi_init - -Wl,-entry:uefi_init + -Wl,-entry:efi_main ) -set_target_properties(BOOTAA64 PROPERTIES +set_target_properties(BOOTAA64 PROPERTIES SUFFIX ".EFI" OUTPUT_NAME "BOOTAA64" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/efi_bin" diff --git a/Bootloader/Source/main.c b/Bootloader/Source/main.c index 2f5d06c..05a954f 100644 --- a/Bootloader/Source/main.c +++ b/Bootloader/Source/main.c @@ -1,144 +1,210 @@ -#include "uefi/uefi.h" // IWYU pragma: keep +#include "uefi/uefi.h" #include "../../Common/bootinfo.h" -void print(wchar_t* msg) { - ST->ConOut->OutputString(ST->ConOut, msg); +#define PAGE_SIZE 0x1000 +#define WSTR(str) ((wchar_t*)L##str) + +static wchar_t* kernel_path = WSTR("ksOSKernel.bin"); +static efi_guid_t dtb_guid = { + 0xb1b621d5, 0xf19c, 0x41a5, {0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0} +}; + +static void print(const wchar_t* msg) { + ST->ConOut->OutputString(ST->ConOut, (wchar_t*)msg); } -efi_status_t die() { - while(1) __asm__ volatile("wfi"); +static efi_status_t die(void) { + while (1) { + __asm__ volatile("wfi"); + } + return EFI_ABORTED; } -int compare_guid(efi_guid_t* a, efi_guid_t* b) { - uint8_t* p1 = (uint8_t*)a; - uint8_t* p2 = (uint8_t*)b; - for (int i = 0; i < 16; i++) { - if (p1[i] != p2[i]) return 0; +static efi_status_t fail(const wchar_t* msg) { + print(msg); + return die(); +} + +static int guid_equal(const efi_guid_t* lhs, const efi_guid_t* rhs) { + const uint8_t* lhs_bytes = (const uint8_t*)lhs; + const uint8_t* rhs_bytes = (const uint8_t*)rhs; + + for (int i = 0; i < 16; ++i) { + if (lhs_bytes[i] != rhs_bytes[i]) { + return 0; + } } + return 1; } -int main() -{ - efi_gop_t* gop = NULL; - efi_guid_t gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; - ST->BootServices->LocateProtocol(&gop_guid, 0, (void**)&gop); - - efi_guid_t dtb_guid = {0xb1b621d5, 0xf19c, 0x41a5, {0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0}}; - void* dtbAddress = NULL; - - for (uintn_t i = 0; i < ST->NumberOfTableEntries; i++) { - if (compare_guid(&ST->ConfigurationTable[i].VendorGuid, &dtb_guid)) { - dtbAddress = ST->ConfigurationTable[i].VendorTable; - break; +static void* find_configuration_table(const efi_guid_t* guid) { + for (uintn_t i = 0; i < ST->NumberOfTableEntries; ++i) { + if (guid_equal(&ST->ConfigurationTable[i].VendorGuid, guid)) { + return ST->ConfigurationTable[i].VendorTable; } } - if (!dtbAddress) { - print(L"Failed to find DTB!\r\n"); - return die(); - } + return NULL; +} - efi_loaded_image_protocol_t* loaded_image; - efi_guid_t lip_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - gBS->HandleProtocol(IM, &lip_guid, (void**)&loaded_image); - - efi_simple_file_system_protocol_t* fs; - efi_guid_t sfsp_guid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; - gBS->HandleProtocol(loaded_image->DeviceHandle, &sfsp_guid, (void**)&fs); - - efi_file_handle_t* root; - fs->OpenVolume(fs, &root); - - efi_file_handle_t* kernel_file; - uintn_t kinfo_size = 0; - efi_file_info_t* kfile_info = NULL; - efi_guid_t fi_guid = EFI_FILE_INFO_GUID; - - efi_status_t status = root->Open(root, &kernel_file, L"ksOSKernel.bin", EFI_FILE_MODE_READ, 0); +static efi_status_t open_root_volume(efi_file_handle_t** root) { + efi_loaded_image_protocol_t* loaded_image = NULL; + efi_guid_t loaded_image_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + efi_status_t status = gBS->HandleProtocol(IM, &loaded_image_guid, (void**)&loaded_image); if (EFI_ERROR(status)) { - print(L"Cant find ksOSKernel.bin\r\n"); - return die(); + return status; } - status = kernel_file->GetInfo(kernel_file, &fi_guid, &kinfo_size, NULL); - if (status == EFI_BUFFER_TOO_SMALL) { - gBS->AllocatePool(EfiLoaderData, kinfo_size, (void**)&kfile_info); - status = kernel_file->GetInfo(kernel_file, &fi_guid, &kinfo_size, kfile_info); - } - - uint64_t kernel_size = kfile_info->FileSize; - uintn_t kernel_size_read = (uintn_t)kernel_size; - - uintn_t kernel_pages = (kernel_size + 0xFFF) / 0x1000; - efi_physical_address_t kernel_addr = 0; - - status = gBS->AllocatePages(AllocateAnyPages, EfiLoaderData, kernel_pages, &kernel_addr); + efi_simple_file_system_protocol_t* fs = NULL; + efi_guid_t filesystem_guid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; + status = gBS->HandleProtocol(loaded_image->DeviceHandle, &filesystem_guid, (void**)&fs); if (EFI_ERROR(status)) { - print(L"Failed to allocate ANY memory for kernel!\r\n"); - return die(); + return status; } - kernel_file->Read(kernel_file, &kernel_size_read, (void*)kernel_addr); \ - printf("Kernel loaded at %p\r\n", (void*)kernel_addr); + return fs->OpenVolume(fs, root); +} - Bootinfo* bootInfo = (Bootinfo*)malloc(sizeof(Bootinfo)); - bootInfo->magic = BOOTINFO_MAGIC; +static efi_status_t read_file_info(efi_file_handle_t* file, efi_file_info_t** file_info) { + efi_guid_t file_info_guid = EFI_FILE_INFO_GUID; + uintn_t file_info_size = 0; + efi_status_t status = file->GetInfo(file, &file_info_guid, &file_info_size, NULL); + if (status != EFI_BUFFER_TOO_SMALL) { + return status; + } - bootInfo->kernelInfo.kernelAddress = (void*)kernel_addr; - bootInfo->kernelInfo.kernelSize = kernel_size; + status = gBS->AllocatePool(EfiLoaderData, file_info_size, (void**)file_info); + if (EFI_ERROR(status)) { + return status; + } - bootInfo->framebuffer.base = (BIUInt32*)gop->Mode->FrameBufferBase; - bootInfo->framebuffer.baseSize = gop->Mode->FrameBufferSize; - bootInfo->framebuffer.height = gop->Mode->Information->VerticalResolution; - bootInfo->framebuffer.width = gop->Mode->Information->HorizontalResolution; - bootInfo->framebuffer.pitch = gop->Mode->Information->PixelsPerScanLine; + return file->GetInfo(file, &file_info_guid, &file_info_size, *file_info); +} - bootInfo->dtb = dtbAddress; - printf("DTB located at: %p\r\n", (void*)dtbAddress); - +static efi_status_t load_kernel(efi_file_handle_t* root, efi_physical_address_t* kernel_addr, uint64_t* kernel_size) { + efi_file_handle_t* kernel_file = NULL; + efi_file_info_t* kernel_info = NULL; + efi_status_t status = root->Open(root, &kernel_file, kernel_path, EFI_FILE_MODE_READ, 0); + if (EFI_ERROR(status)) { + return status; + } + + status = read_file_info(kernel_file, &kernel_info); + if (EFI_ERROR(status)) { + return status; + } + + *kernel_size = kernel_info->FileSize; + + uintn_t bytes_to_read = (uintn_t)*kernel_size; + uintn_t kernel_pages = (*kernel_size + PAGE_SIZE - 1) / PAGE_SIZE; + *kernel_addr = 0; + + status = gBS->AllocatePages(AllocateAnyPages, EfiLoaderData, kernel_pages, kernel_addr); + if (EFI_ERROR(status)) { + return status; + } + + status = kernel_file->Read(kernel_file, &bytes_to_read, (void*)*kernel_addr); + if (EFI_ERROR(status) || bytes_to_read != (uintn_t)*kernel_size) { + return EFI_LOAD_ERROR; + } + + return EFI_SUCCESS; +} + +static efi_status_t populate_memory_map(Bootinfo* boot_info) { uintn_t map_size = 0; - efi_memory_descriptor_t *map = NULL; - uintn_t map_key; - uintn_t desc_size; - uint32_t desc_version; + efi_memory_descriptor_t* map = NULL; + uintn_t map_key = 0; + uintn_t descriptor_size = 0; + uint32_t descriptor_version = 0; + efi_status_t status = gBS->GetMemoryMap(&map_size, NULL, &map_key, &descriptor_size, &descriptor_version); + if (status != EFI_BUFFER_TOO_SMALL) { + return status; + } - print(L"Almost ready to jump :D. Working with memory map\r\n"); - - gBS->GetMemoryMap(&map_size, NULL, &map_key, &desc_size, &desc_version); - map_size += 4096; - // woah letsgoo + map_size += PAGE_SIZE; status = gBS->AllocatePool(EfiLoaderData, map_size, (void**)&map); if (EFI_ERROR(status)) { - print(L"Failed to allocate pool\r\n"); + return status; } - do { - status = gBS->GetMemoryMap(&map_size, map, &map_key, &desc_size, &desc_version); + while (1) { + status = gBS->GetMemoryMap(&map_size, map, &map_key, &descriptor_size, &descriptor_version); if (EFI_ERROR(status)) { - break; + return status; } - - bootInfo->memoryMap.descriptorSize = desc_size; - bootInfo->memoryMap.descriptorVersion = desc_version; - bootInfo->memoryMap.mapSize = map_size; - bootInfo->memoryMap.mapKey = map_key; - bootInfo->memoryMap.map = map; + + boot_info->memoryMap.descriptorSize = descriptor_size; + boot_info->memoryMap.descriptorVersion = descriptor_version; + boot_info->memoryMap.mapSize = map_size; + boot_info->memoryMap.mapKey = map_key; + boot_info->memoryMap.map = map; status = gBS->ExitBootServices(IM, map_key); if (status == EFI_SUCCESS) { - break; // FUCK OFF; + return EFI_SUCCESS; } - map_size += 2 * desc_size; - } while (EFI_ERROR(status)); - typedef void (__attribute__((sysv_abi)) *kentry)(Bootinfo*); - kentry kmain = (kentry)kernel_addr; + map_size += 2 * descriptor_size; + } +} - kmain(bootInfo); // yay! :D +efi_status_t bootloader_main(void) { + efi_gop_t* gop = NULL; + efi_guid_t gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; + efi_status_t status = ST->BootServices->LocateProtocol(&gop_guid, 0, (void**)&gop); + if (EFI_ERROR(status) || gop == NULL) { + return fail(WSTR("Failed to locate GOP\r\n")); + } + void* dtb_address = find_configuration_table(&dtb_guid); + if (dtb_address == NULL) { + return fail(WSTR("Failed to find DTB\r\n")); + } + + efi_file_handle_t* root = NULL; + status = open_root_volume(&root); + if (EFI_ERROR(status)) { + return fail(WSTR("Failed to open boot volume\r\n")); + } + + efi_physical_address_t kernel_addr = 0; + uint64_t kernel_size = 0; + status = load_kernel(root, &kernel_addr, &kernel_size); + if (EFI_ERROR(status)) { + return fail(WSTR("Failed to load ksOSKernel.bin\r\n")); + } + + Bootinfo* boot_info = NULL; + status = gBS->AllocatePool(EfiLoaderData, sizeof(Bootinfo), (void**)&boot_info); + if (EFI_ERROR(status) || boot_info == NULL) { + return fail(WSTR("Failed to allocate boot info\r\n")); + } + + boot_info->magic = BOOTINFO_MAGIC; + boot_info->kernelInfo.kernelAddress = (void*)kernel_addr; + boot_info->kernelInfo.kernelSize = kernel_size; + boot_info->framebuffer.base = (BIUInt32*)gop->Mode->FrameBufferBase; + boot_info->framebuffer.baseSize = gop->Mode->FrameBufferSize; + boot_info->framebuffer.height = gop->Mode->Information->VerticalResolution; + boot_info->framebuffer.width = gop->Mode->Information->HorizontalResolution; + boot_info->framebuffer.pitch = gop->Mode->Information->PixelsPerScanLine; + boot_info->dtb = dtb_address; + + print(WSTR("Almost ready to jump. Reading memory map\r\n")); + status = populate_memory_map(boot_info); + if (EFI_ERROR(status)) { + return fail(WSTR("Failed to exit boot services\r\n")); + } + + typedef void (*kernel_entry_t)(Bootinfo*); + kernel_entry_t kernel_main = (kernel_entry_t)kernel_addr; + kernel_main(boot_info); return EFI_SUCCESS; } \ No newline at end of file diff --git a/Bootloader/Source/uefi/Makefile b/Bootloader/Source/uefi/Makefile deleted file mode 100644 index 64952c1..0000000 --- a/Bootloader/Source/uefi/Makefile +++ /dev/null @@ -1,135 +0,0 @@ -# detect architecture -MYARCH = $(shell uname -m | sed s,i[3456789]86,ia32, | sed s,amd,x86_,) -ifeq ($(ARCH),) -ARCH = $(MYARCH) -endif - -# get source files, generate object names -ifeq ($(SRCS),) -SRCS = $(wildcard *.c) $(wildcard *.S) -endif -ifeq ($(OBJS),) -TMP = $(SRCS:.c=.o) -OBJS = $(TMP:.S=.o) -endif -ifneq ($(OUTDIR),) -# OUTDIR is not used with uefi/*.o deliberately -OUTDIR:=$(addsuffix /,$(OUTDIR)) -endif -CFLAGS += -fshort-wchar -fno-strict-aliasing -ffreestanding -fno-stack-protector -fno-stack-check -I. -I./uefi \ - -I/usr/include -I/usr/include/efi -I/usr/include/efi/protocol -I/usr/include/efi/$(ARCH) -D__$(ARCH)__ -ifeq ($(ARCH),x86_64) -CFLAGS += -DHAVE_USE_MS_ABI -mno-red-zone -endif - -# for libuefi.a -LIBSRCS = $(filter-out $(wildcard crt_*.c),$(wildcard *.c)) $(wildcard *.S) -TMP2 = $(LIBSRCS:.c=.o) -LIBOBJS = $(TMP2:.S=.o) -MAKE ?= make - -# detect toolchain -ifeq ($(wildcard /usr/bin/clang)$(wildcard /usr/local/bin/clang)$(wildcard /usr/lib/llvm/*/bin/clang)$(wildcard /gnu/store/*/bin/clang),) -USE_GCC = 1 -endif -ifneq ($(USE_GCC),) -ifeq ($(ARCH),x86_64) -CFLAGS += -maccumulate-outgoing-args -endif -CFLAGS += -Wno-builtin-declaration-mismatch -fpic -fPIC -LDFLAGS += -nostdlib -shared -Bsymbolic -Luefi uefi/crt_$(ARCH).o -LIBS += -o $(addprefix $(OUTDIR),$(TARGET).so) -luefi -T uefi/elf_$(ARCH)_efi.lds -# see if we're cross-compiling -ifneq ($(ARCH),$(MYARCH)) -CC = $(ARCH)-elf-gcc -LD = $(ARCH)-elf-ld -OBJCOPY ?= $(ARCH)-elf-objcopy -else -CC = gcc -LD = ld -OBJCOPY ?= objcopy -endif -ifeq ($(ARCH),aarch64) -EFIARCH = pei-aarch64-little -else -ifeq ($(ARCH),riscv64) -EFIARCH = pei-riscv64-little -else -EFIARCH = efi-app-$(ARCH) -endif -endif -AR ?= ar -else -CFLAGS += --target=$(ARCH)-pc-win32-coff -Wno-builtin-requires-header -Wno-incompatible-library-redeclaration -Wno-long-long -LDFLAGS += -subsystem:efi_application -nodefaultlib -dll -entry:uefi_init uefi/*.o -LIBS = -out:$(addprefix $(OUTDIR),$(TARGET)) -CC = clang -LD = lld -flavor link -OBJCOPY = true -endif - -# recipies -ifeq ($(wildcard uefi/Makefile),) -ALLTARGETS = crt_$(ARCH).o libuefi.a buildlib -else -ALLTARGETS = uefi/crt_$(ARCH).o uefi/libuefi.a $(OBJS) $(TARGET) -endif - -all: $(OUTDIR) $(EXTRA) $(ALLTARGETS) $(ALSO) - -ifneq ($(OUTDIR),) -$(OUTDIR): - @mkdir -p $(OUTDIR) -endif - -uefi/libuefi.a: - @$(MAKE) --no-print-directory -C uefi libuefi.a USE_GCC=$(USE_GCC) ARCH=$(ARCH) - -libuefi.lib: $(LIBOBJS) - -libuefi.a: $(LIBOBJS) - @rm $@ 2>/dev/null || true - $(AR) -rsv $@ $(LIBOBJS) >/dev/null - -$(TARGET): $(addprefix $(OUTDIR),$(TARGET).so) -ifneq ($(USE_GCC),) - $(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .rel.* -j .rela.* -j .reloc --target $(EFIARCH) --subsystem=10 $^ $(addprefix $(OUTDIR),$@) || echo target: $(EFIARCH) - @rm $(addprefix $(OUTDIR),$(TARGET).so) -endif - -$(addprefix $(OUTDIR),$(TARGET).so): $(addprefix $(OUTDIR),$(OBJS)) $(EXTRA) - $(LD) $(LDFLAGS) $^ $(LIBS) - @rm $(addprefix $(OUTDIR),*.lib) 2>/dev/null || true - -uefi/%.o: uefi/%.c - $(CC) $(CFLAGS) -c $< -o $@ - -%.o: %.c - $(CC) $(CFLAGS) -c $< -o $(addprefix $(OUTDIR),$@) - -%.o: %.S - $(CC) $(CFLAGS) -c $< -o $(addprefix $(OUTDIR),$@) - -buildlib: - @mkdir ../build ../build/uefi 2>/dev/null || true - @cp crt_$(ARCH).o ../build/uefi/crt0.o - @cp elf_$(ARCH)_efi.lds ../build/uefi/link.ld -ifneq ($(USE_GCC),) - @cp libuefi.a uefi.h ../build/uefi -else - @cp uefi.h ../build/uefi - @cp libuefi.a ../build/uefi/libuefi.dll.a -endif - -clean: - @rm $(addprefix $(OUTDIR),$(TARGET)) *.o *.a *.lib *.elf $(LIBOBJS) 2>/dev/null || true -ifneq ($(OUTDIR),) - @rm -rf $(OUTDIR) -endif - -distclean: clean -ifeq ($(wildcard uefi/Makefile),) - @rm -rf ../build 2>/dev/null || true -else - @rm uefi/*.o uefi/libuefi.a 2>/dev/null || true -endif diff --git a/Bootloader/Source/uefi/crt_aarch64.c b/Bootloader/Source/uefi/crt_aarch64.c deleted file mode 100644 index 82324a5..0000000 --- a/Bootloader/Source/uefi/crt_aarch64.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * crt_aarch64.c - * - * Copyright (C) 2021 bzt (bztsrc@gitlab) - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * This file is part of the POSIX-UEFI package. - * @brief C runtime, bootstraps an EFI application to call standard main() - * - */ - -#include - -/* this is implemented by the application */ -extern int main(int argc, char_t **argv); - -/* definitions for elf relocations */ -#ifndef __clang__ -typedef uint64_t Elf64_Xword; -typedef int64_t Elf64_Sxword; -typedef uint64_t Elf64_Addr; -typedef struct -{ - Elf64_Sxword d_tag; /* Dynamic entry type */ - union - { - Elf64_Xword d_val; /* Integer value */ - Elf64_Addr d_ptr; /* Address value */ - } d_un; -} Elf64_Dyn; -#define DT_NULL 0 /* Marks end of dynamic section */ -#define DT_RELA 7 /* Address of Rela relocs */ -#define DT_RELASZ 8 /* Total size of Rela relocs */ -#define DT_RELAENT 9 /* Size of one Rela reloc */ -typedef struct -{ - Elf64_Addr r_offset; /* Address */ - Elf64_Xword r_info; /* Relocation type and symbol index */ -} Elf64_Rel; -#define ELF64_R_TYPE(i) ((i) & 0xffffffff) -#define R_AARCH64_RELATIVE 1027 /* Adjust by program base */ -#endif - -/* globals to store system table pointers */ -efi_handle_t IM = NULL; -efi_system_table_t *ST = NULL; -efi_boot_services_t *BS = NULL; -efi_runtime_services_t *RT = NULL; -efi_loaded_image_protocol_t *LIP = NULL; -#ifndef UEFI_NO_UTF8 -char *__argvutf8 = NULL; -#endif - -/* we only need one .o file, so use inline Assembly here */ -void bootstrap(void) -{ - __asm__ __volatile__ ( - /* call init in C */ - " .align 4\n" -#ifndef __clang__ - " .globl _start\n" - "_start:\n" - " ldr x2, =ImageBase\n" - " adrp x3, _DYNAMIC\n" - " add x3, x3, #:lo12:_DYNAMIC\n" - " bl uefi_init\n" - " ret\n" - - /* fake a relocation record, so that EFI won't complain */ - " .data\n" - "dummy: .long 0\n" - " .section .reloc, \"a\"\n" - "label1:\n" - " .long dummy-label1\n" - " .long 10\n" - " .word 0\n" - ".text\n" -#else - " .globl __chkstk\n" - "__chkstk:\n" - " ret\n" -#endif - ); - - /* setjmp and longjmp */ - __asm__ __volatile__ ( - " .p2align 3\n" - " .globl setjmp\n" - "setjmp:\n" - " mov x16, sp\n" - " stp x19, x20, [x0, #0]\n" - " stp x21, x22, [x0, #16]\n" - " stp x23, x24, [x0, #32]\n" - " stp x25, x26, [x0, #48]\n" - " stp x27, x28, [x0, #64]\n" - " stp x29, x30, [x0, #80]\n" - " str x16, [x0, #96]\n" - " stp d8, d9, [x0, #112]\n" - " stp d10, d11, [x0, #128]\n" - " stp d12, d13, [x0, #144]\n" - " stp d14, d15, [x0, #160]\n" - " mov w0, #0\n" - " ret\n" - ); - __asm__ __volatile__ ( - " .globl longjmp\n" - "longjmp:\n" - " ldp x19, x20, [x0, #0]\n" - " ldp x21, x22, [x0, #16]\n" - " ldp x23, x24, [x0, #32]\n" - " ldp x25, x26, [x0, #48]\n" - " ldp x27, x28, [x0, #64]\n" - " ldp x29, x30, [x0, #80]\n" - " ldr x16, [x0, #96]\n" - " ldp d8, d9, [x0, #112]\n" - " ldp d10, d11, [x0, #128]\n" - " ldp d12, d13, [x0, #144]\n" - " ldp d14, d15, [x0, #160]\n" - " mov sp, x16\n" - " cmp w1, #0\n" - " mov w0, #1\n" - " csel w0, w1, w0, ne\n" - " br x30\n" - ); -} - -/** - * Initialize POSIX-UEFI and call the application's main() function - */ -efi_status_t uefi_init ( - efi_handle_t image, efi_system_table_t *systab -#ifndef __clang__ - , uintptr_t ldbase, Elf64_Dyn *dyn -#endif -) { - efi_guid_t shpGuid = EFI_SHELL_PARAMETERS_PROTOCOL_GUID; - efi_shell_parameters_protocol_t *shp = NULL; - efi_guid_t shiGuid = SHELL_INTERFACE_PROTOCOL_GUID; - efi_shell_interface_protocol_t *shi = NULL; - efi_guid_t lipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - efi_status_t status; - int argc = 0, i, ret; - wchar_t **argv = NULL; -#ifndef UEFI_NO_UTF8 - int j; - char *s; -#endif -#ifndef __clang__ - long relsz = 0, relent = 0; - Elf64_Rel *rel = 0; - uintptr_t *addr; - /* handle relocations */ - for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { - switch (dyn[i].d_tag) { - case DT_RELA: rel = (Elf64_Rel*)((unsigned long)dyn[i].d_un.d_ptr + ldbase); break; - case DT_RELASZ: relsz = dyn[i].d_un.d_val; break; - case DT_RELAENT: relent = dyn[i].d_un.d_val; break; - default: break; - } - } - if (rel && relent) { - while (relsz > 0) { - if(ELF64_R_TYPE (rel->r_info) == R_AARCH64_RELATIVE) - { addr = (unsigned long *)(ldbase + rel->r_offset); *addr += ldbase; } - rel = (Elf64_Rel*) ((char *) rel + relent); - relsz -= relent; - } - } -#else - (void)i; -#endif - /* failsafes, should never happen */ - if(!image || !systab || !systab->BootServices || !systab->BootServices->HandleProtocol || - !systab->BootServices->OpenProtocol || !systab->BootServices->AllocatePool || !systab->BootServices->FreePool) - return EFI_UNSUPPORTED; - /* save EFI pointers and loaded image into globals */ - IM = image; - ST = systab; - BS = systab->BootServices; - RT = systab->RuntimeServices; - BS->HandleProtocol(image, &lipGuid, (void **)&LIP); - /* get command line arguments */ - status = BS->OpenProtocol(image, &shpGuid, (void **)&shp, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if(!EFI_ERROR(status) && shp) { argc = (int)shp->Argc; argv = shp->Argv; } - else { - /* if shell 2.0 failed, fallback to shell 1.0 interface */ - status = BS->OpenProtocol(image, &shiGuid, (void **)&shi, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if(!EFI_ERROR(status) && shi) { argc = (int)shi->Argc; argv = shi->Argv; } - } - /* call main */ -#ifndef UEFI_NO_UTF8 - if(argc && argv) { - ret = (argc + 1) * ((int)sizeof(uintptr_t) + 1); - for(i = 0; i < argc; i++) - for(j = 0; argv[i] && argv[i][j]; j++) - ret += argv[i][j] < 0x80 ? 1 : (argv[i][j] < 0x800 ? 2 : 3); - status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, (uintn_t)ret, (void **)&__argvutf8); - if(EFI_ERROR(status) || !__argvutf8) { argc = 0; __argvutf8 = NULL; } - else { - s = __argvutf8 + argc * (int)sizeof(uintptr_t); - *((uintptr_t*)s) = (uintptr_t)0; s += sizeof(uintptr_t); - for(i = 0; i < argc; i++) { - *((uintptr_t*)(__argvutf8 + i * (int)sizeof(uintptr_t))) = (uintptr_t)s; - for(j = 0; argv[i] && argv[i][j]; j++) { - if(argv[i][j]<0x80) { *s++ = argv[i][j]; } else - if(argv[i][j]<0x800) { *s++ = ((argv[i][j]>>6)&0x1F)|0xC0; *s++ = (argv[i][j]&0x3F)|0x80; } else - { *s++ = ((argv[i][j]>>12)&0x0F)|0xE0; *s++ = ((argv[i][j]>>6)&0x3F)|0x80; *s++ = (argv[i][j]&0x3F)|0x80; } - } - *s++ = 0; - } - } - } - ret = main(argc, (char**)__argvutf8); - if(__argvutf8) BS->FreePool(__argvutf8); - return ret; -#else - ret = main(argc, argv); -#endif - return ret ? EFIERR(ret) : EFI_SUCCESS; -} diff --git a/Bootloader/Source/uefi/crt_riscv64.c b/Bootloader/Source/uefi/crt_riscv64.c deleted file mode 100644 index 77b52ae..0000000 --- a/Bootloader/Source/uefi/crt_riscv64.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * crt_riscv64.c - * - * Copyright (C) 2023 bzt (bztsrc@gitlab) - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * This file is part of the POSIX-UEFI package. - * @brief C runtime, bootstraps an EFI application to call standard main() - * - */ - -#include - -/* this is implemented by the application */ -extern int main(int argc, char_t **argv); - -/* definitions for elf relocations */ -#ifndef __clang__ -typedef uint64_t Elf64_Xword; -typedef int64_t Elf64_Sxword; -typedef uint64_t Elf64_Addr; -typedef struct -{ - Elf64_Sxword d_tag; /* Dynamic entry type */ - union - { - Elf64_Xword d_val; /* Integer value */ - Elf64_Addr d_ptr; /* Address value */ - } d_un; -} Elf64_Dyn; -#define DT_NULL 0 /* Marks end of dynamic section */ -#define DT_RELA 7 /* Address of Rela relocs */ -#define DT_RELASZ 8 /* Total size of Rela relocs */ -#define DT_RELAENT 9 /* Size of one Rela reloc */ -typedef struct -{ - Elf64_Addr r_offset; /* Address */ - Elf64_Xword r_info; /* Relocation type and symbol index */ -} Elf64_Rel; -#define ELF64_R_TYPE(i) ((i) & 0xffffffff) -#define R_RISCV_RELATIVE 3 /* Adjust by program base */ -#endif - -/* globals to store system table pointers */ -efi_handle_t IM = NULL; -efi_system_table_t *ST = NULL; -efi_boot_services_t *BS = NULL; -efi_runtime_services_t *RT = NULL; -efi_loaded_image_protocol_t *LIP = NULL; -#ifndef UEFI_NO_UTF8 -char *__argvutf8 = NULL; -#endif - -/* we only need one .o file, so use inline Assembly here */ -void bootstrap(void) -{ - __asm__ __volatile__ ( - /* call init in C */ - " .align 4\n" -#ifndef __clang__ - " .globl _start\n" - "_start:\n" - " lla a2, ImageBase\n" - " lui a3, %hi(_DYNAMIC)\n" - " addi a3, a3, %lo(_DYNAMIC)\n" - " call uefi_init\n" - " ret\n" - - /* fake a relocation record, so that EFI won't complain */ - " .data\n" - "dummy: .long 0\n" - " .section .reloc, \"a\"\n" - "label1:\n" - " .long dummy-label1\n" - " .long 10\n" - " .word 0\n" - ".text\n" -#else - " .globl __chkstk\n" - "__chkstk:\n" - " ret\n" -#endif - ); - - /* setjmp and longjmp */ - __asm__ __volatile__ ( - " .p2align 3\n" - " .globl setjmp\n" - "setjmp:\n" - " sd ra, 0(a0)\n" - " sd sp, 8(a0)\n" - " sd s0, 16(a0)\n" - " sd s1, 24(a0)\n" - " sd s2, 32(a0)\n" - " sd s3, 40(a0)\n" - " sd s4, 48(a0)\n" - " sd s5, 56(a0)\n" - " sd s6, 64(a0)\n" - " sd s7, 72(a0)\n" - " sd s8, 80(a0)\n" - " sd s9, 88(a0)\n" - " sd s10, 96(a0)\n" - " sd s11, 104(a0)\n" -#ifndef __riscv_float_abi_soft - " fsd fs0, 112(a0)\n" - " fsd fs1, 120(a0)\n" - " fsd fs2, 128(a0)\n" - " fsd fs3, 136(a0)\n" - " fsd fs4, 144(a0)\n" - " fsd fs5, 152(a0)\n" - " fsd fs6, 160(a0)\n" - " fsd fs7, 168(a0)\n" - " fsd fs8, 176(a0)\n" - " fsd fs9, 184(a0)\n" - " fsd fs10,192(a0)\n" - " fsd fs11,200(a0)\n" -#endif - " li a0, 0\n" - " ret\n" - ); - __asm__ __volatile__ ( - " .globl longjmp\n" - "longjmp:\n" - " ld ra, 0(a0)\n" - " ld sp, 8(a0)\n" - " ld s0, 16(a0)\n" - " ld s1, 24(a0)\n" - " ld s2, 32(a0)\n" - " ld s3, 40(a0)\n" - " ld s4, 48(a0)\n" - " ld s5, 56(a0)\n" - " ld s6, 64(a0)\n" - " ld s7, 72(a0)\n" - " ld s8, 80(a0)\n" - " ld s9, 88(a0)\n" - " ld s10, 96(a0)\n" - " ld s11, 104(a0)\n" -#ifndef __riscv_float_abi_soft - " fld fs0, 112(a0)\n" - " fld fs1, 120(a0)\n" - " fld fs2, 128(a0)\n" - " fld fs3, 136(a0)\n" - " fld fs4, 144(a0)\n" - " fld fs5, 152(a0)\n" - " fld fs6, 160(a0)\n" - " fld fs7, 168(a0)\n" - " fld fs8, 176(a0)\n" - " fld fs9, 184(a0)\n" - " fld fs10,192(a0)\n" - " fld fs11,200(a0)\n" -#endif - " seqz a0, a1\n" - " add a0, a0, a1\n" - " ret\n" - ); -} - -/** - * Initialize POSIX-UEFI and call the application's main() function - */ -efi_status_t uefi_init ( - efi_handle_t image, efi_system_table_t *systab -#ifndef __clang__ - , uintptr_t ldbase, Elf64_Dyn *dyn -#endif -) { - efi_guid_t shpGuid = EFI_SHELL_PARAMETERS_PROTOCOL_GUID; - efi_shell_parameters_protocol_t *shp = NULL; - efi_guid_t shiGuid = SHELL_INTERFACE_PROTOCOL_GUID; - efi_shell_interface_protocol_t *shi = NULL; - efi_guid_t lipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - efi_status_t status; - int argc = 0, i, ret; - wchar_t **argv = NULL; -#ifndef UEFI_NO_UTF8 - int j; - char *s; -#endif -#ifndef __clang__ - long relsz = 0, relent = 0; - Elf64_Rel *rel = 0; - uintptr_t *addr; - /* handle relocations */ - for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { - switch (dyn[i].d_tag) { - case DT_RELA: rel = (Elf64_Rel*)((unsigned long)dyn[i].d_un.d_ptr + ldbase); break; - case DT_RELASZ: relsz = dyn[i].d_un.d_val; break; - case DT_RELAENT: relent = dyn[i].d_un.d_val; break; - default: break; - } - } - if (rel && relent) { - while (relsz > 0) { - if(ELF64_R_TYPE (rel->r_info) == R_RISCV_RELATIVE) - { addr = (unsigned long *)(ldbase + rel->r_offset); *addr += ldbase; } - rel = (Elf64_Rel*) ((char *) rel + relent); - relsz -= relent; - } - } -#else - (void)i; -#endif - /* failsafes, should never happen */ - if(!image || !systab || !systab->BootServices || !systab->BootServices->HandleProtocol || - !systab->BootServices->OpenProtocol || !systab->BootServices->AllocatePool || !systab->BootServices->FreePool) - return EFI_UNSUPPORTED; - /* save EFI pointers and loaded image into globals */ - IM = image; - ST = systab; - BS = systab->BootServices; - RT = systab->RuntimeServices; - BS->HandleProtocol(image, &lipGuid, (void **)&LIP); - /* get command line arguments */ - status = BS->OpenProtocol(image, &shpGuid, (void **)&shp, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if(!EFI_ERROR(status) && shp) { argc = (int)shp->Argc; argv = shp->Argv; } - else { - /* if shell 2.0 failed, fallback to shell 1.0 interface */ - status = BS->OpenProtocol(image, &shiGuid, (void **)&shi, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if(!EFI_ERROR(status) && shi) { argc = (int)shi->Argc; argv = shi->Argv; } - } - /* call main */ -#ifndef UEFI_NO_UTF8 - if(argc && argv) { - ret = (argc + 1) * ((int)sizeof(uintptr_t) + 1); - for(i = 0; i < argc; i++) - for(j = 0; argv[i] && argv[i][j]; j++) - ret += argv[i][j] < 0x80 ? 1 : (argv[i][j] < 0x800 ? 2 : 3); - status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, (uintn_t)ret, (void **)&__argvutf8); - if(EFI_ERROR(status) || !__argvutf8) { argc = 0; __argvutf8 = NULL; } - else { - s = __argvutf8 + argc * (int)sizeof(uintptr_t); - *((uintptr_t*)s) = (uintptr_t)0; s += sizeof(uintptr_t); - for(i = 0; i < argc; i++) { - *((uintptr_t*)(__argvutf8 + i * (int)sizeof(uintptr_t))) = (uintptr_t)s; - for(j = 0; argv[i] && argv[i][j]; j++) { - if(argv[i][j]<0x80) { *s++ = argv[i][j]; } else - if(argv[i][j]<0x800) { *s++ = ((argv[i][j]>>6)&0x1F)|0xC0; *s++ = (argv[i][j]&0x3F)|0x80; } else - { *s++ = ((argv[i][j]>>12)&0x0F)|0xE0; *s++ = ((argv[i][j]>>6)&0x3F)|0x80; *s++ = (argv[i][j]&0x3F)|0x80; } - } - *s++ = 0; - } - } - } - ret = main(argc, (char**)__argvutf8); - if(__argvutf8) BS->FreePool(__argvutf8); - return ret; -#else - ret = main(argc, argv); -#endif - return ret ? EFIERR(ret) : EFI_SUCCESS; -} diff --git a/Bootloader/Source/uefi/crt_x86_64.c b/Bootloader/Source/uefi/crt_x86_64.c deleted file mode 100644 index b146bb3..0000000 --- a/Bootloader/Source/uefi/crt_x86_64.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * crt_x86_64.c - * - * Copyright (C) 2021 bzt (bztsrc@gitlab) - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * This file is part of the POSIX-UEFI package. - * @brief C runtime, bootstraps an EFI application to call standard main() - * - */ - -#include - -/* this is implemented by the application */ -extern int main(int argc, char_t **argv); - -/* definitions for elf relocations */ -#ifndef __clang__ -typedef uint64_t Elf64_Xword; -typedef int64_t Elf64_Sxword; -typedef uint64_t Elf64_Addr; -typedef struct -{ - Elf64_Sxword d_tag; /* Dynamic entry type */ - union - { - Elf64_Xword d_val; /* Integer value */ - Elf64_Addr d_ptr; /* Address value */ - } d_un; -} Elf64_Dyn; -#define DT_NULL 0 /* Marks end of dynamic section */ -#define DT_RELA 7 /* Address of Rela relocs */ -#define DT_RELASZ 8 /* Total size of Rela relocs */ -#define DT_RELAENT 9 /* Size of one Rela reloc */ -typedef struct -{ - Elf64_Addr r_offset; /* Address */ - Elf64_Xword r_info; /* Relocation type and symbol index */ -} Elf64_Rel; -#define ELF64_R_TYPE(i) ((i) & 0xffffffff) -#define R_X86_64_RELATIVE 8 /* Adjust by program base */ -#endif - -/* globals to store system table pointers */ -efi_handle_t IM = NULL; -efi_system_table_t *ST = NULL; -efi_boot_services_t *BS = NULL; -efi_runtime_services_t *RT = NULL; -efi_loaded_image_protocol_t *LIP = NULL; -#ifndef UEFI_NO_UTF8 -char *__argvutf8 = NULL; -#endif - -/* we only need one .o file, so use inline Assembly here */ -void bootstrap(void) -{ - __asm__ __volatile__ ( - /* call init in C */ - " .align 4\n" -#ifndef __clang__ - " .globl _start\n" - "_start:\n" - " lea ImageBase(%rip), %rdi\n" - " lea _DYNAMIC(%rip), %rsi\n" - " call uefi_init\n" - " ret\n" - - /* fake a relocation record, so that EFI won't complain */ - " .data\n" - "dummy: .long 0\n" - " .section .reloc, \"a\"\n" - "label1:\n" - " .long dummy-label1\n" - " .long 10\n" - " .word 0\n" - ".text\n" -#else - " .globl __chkstk\n" - "__chkstk:\n" - " ret\n" -#endif - ); - - /* setjmp and longjmp */ - __asm__ __volatile__ ( - " .globl setjmp\n" - "setjmp:\n" - " pop %rsi\n" - " movq %rbx,0x00(%rdi)\n" - " movq %rsp,0x08(%rdi)\n" - " push %rsi\n" - " movq %rbp,0x10(%rdi)\n" - " movq %r12,0x18(%rdi)\n" - " movq %r13,0x20(%rdi)\n" - " movq %r14,0x28(%rdi)\n" - " movq %r15,0x30(%rdi)\n" - " movq %rsi,0x38(%rdi)\n" - " xor %rax,%rax\n" - " ret\n" - ); - __asm__ __volatile__ ( - " .globl longjmp\n" - "longjmp:\n" - " movl %esi, %eax\n" - " movq 0x00(%rdi), %rbx\n" - " movq 0x08(%rdi), %rsp\n" - " movq 0x10(%rdi), %rbp\n" - " movq 0x18(%rdi), %r12\n" - " movq 0x20(%rdi), %r13\n" - " movq 0x28(%rdi), %r14\n" - " movq 0x30(%rdi), %r15\n" - " xor %rdx,%rdx\n" - " mov $1,%rcx\n" - " cmp %rax,%rdx\n" - " cmove %rcx,%rax\n" - " jmp *0x38(%rdi)\n" - ); -} - -/** - * Initialize POSIX-UEFI and call the application's main() function - */ -efi_status_t uefi_init ( -#ifndef __clang__ - uintptr_t ldbase, Elf64_Dyn *dyn, efi_system_table_t *systab, efi_handle_t image -#else - efi_handle_t image, efi_system_table_t *systab -#endif -) { - efi_guid_t shpGuid = EFI_SHELL_PARAMETERS_PROTOCOL_GUID; - efi_shell_parameters_protocol_t *shp = NULL; - efi_guid_t shiGuid = SHELL_INTERFACE_PROTOCOL_GUID; - efi_shell_interface_protocol_t *shi = NULL; - efi_guid_t lipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - efi_status_t status; - int argc = 0, i, ret; - wchar_t **argv = NULL; -#ifndef UEFI_NO_UTF8 - int j; - char *s; -#endif -#ifndef __clang__ - long relsz = 0, relent = 0; - Elf64_Rel *rel = 0; - uintptr_t *addr; - /* handle relocations */ - for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { - switch (dyn[i].d_tag) { - case DT_RELA: rel = (Elf64_Rel*)((unsigned long)dyn[i].d_un.d_ptr + ldbase); break; - case DT_RELASZ: relsz = dyn[i].d_un.d_val; break; - case DT_RELAENT: relent = dyn[i].d_un.d_val; break; - default: break; - } - } - if (rel && relent) { - while (relsz > 0) { - if(ELF64_R_TYPE (rel->r_info) == R_X86_64_RELATIVE) - { addr = (unsigned long *)(ldbase + rel->r_offset); *addr += ldbase; } - rel = (Elf64_Rel*) ((char *) rel + relent); - relsz -= relent; - } - } -#else - (void)i; -#endif - /* make sure SSE is enabled, because some say there are buggy firmware in the wild not doing that */ - __asm__ __volatile__ ( - " movq %cr0, %rax\n" - " andb $0xF1, %al\n" - " movq %rax, %cr0\n" - " movq %cr4, %rax\n" - " orw $3 << 9, %ax\n" - " mov %rax, %cr4\n" - ); - /* failsafes, should never happen */ - if(!image || !systab || !systab->BootServices || !systab->BootServices->HandleProtocol || - !systab->BootServices->OpenProtocol || !systab->BootServices->AllocatePool || !systab->BootServices->FreePool) - return EFI_UNSUPPORTED; - /* save EFI pointers and loaded image into globals */ - IM = image; - ST = systab; - BS = systab->BootServices; - RT = systab->RuntimeServices; - BS->HandleProtocol(image, &lipGuid, (void **)&LIP); - /* get command line arguments */ - status = BS->OpenProtocol(image, &shpGuid, (void **)&shp, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if(!EFI_ERROR(status) && shp) { argc = (int)shp->Argc; argv = shp->Argv; } - else { - /* if shell 2.0 failed, fallback to shell 1.0 interface */ - status = BS->OpenProtocol(image, &shiGuid, (void **)&shi, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if(!EFI_ERROR(status) && shi) { argc = (int)shi->Argc; argv = shi->Argv; } - } - /* call main */ -#ifndef UEFI_NO_UTF8 - if(argc && argv) { - ret = (argc + 1) * ((int)sizeof(uintptr_t) + 1); - for(i = 0; i < argc; i++) - for(j = 0; argv[i] && argv[i][j]; j++) - ret += argv[i][j] < 0x80 ? 1 : (argv[i][j] < 0x800 ? 2 : 3); - status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, (uintn_t)ret, (void **)&__argvutf8); - if(EFI_ERROR(status) || !__argvutf8) { argc = 0; __argvutf8 = NULL; } - else { - s = __argvutf8 + argc * (int)sizeof(uintptr_t); - *((uintptr_t*)s) = (uintptr_t)0; s += sizeof(uintptr_t); - for(i = 0; i < argc; i++) { - *((uintptr_t*)(__argvutf8 + i * (int)sizeof(uintptr_t))) = (uintptr_t)s; - for(j = 0; argv[i] && argv[i][j]; j++) { - if(argv[i][j]<0x80) { *s++ = argv[i][j]; } else - if(argv[i][j]<0x800) { *s++ = ((argv[i][j]>>6)&0x1F)|0xC0; *s++ = (argv[i][j]&0x3F)|0x80; } else - { *s++ = ((argv[i][j]>>12)&0x0F)|0xE0; *s++ = ((argv[i][j]>>6)&0x3F)|0x80; *s++ = (argv[i][j]&0x3F)|0x80; } - } - *s++ = 0; - } - } - } - ret = main(argc, (char**)__argvutf8); - if(__argvutf8) BS->FreePool(__argvutf8); -#else - ret = main(argc, argv); -#endif - return ret ? EFIERR(ret) : EFI_SUCCESS; -} diff --git a/Bootloader/Source/uefi/dirent.c b/Bootloader/Source/uefi/dirent.c deleted file mode 100644 index 402011c..0000000 --- a/Bootloader/Source/uefi/dirent.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * dirent.c - * - * Copyright (C) 2021 bzt (bztsrc@gitlab) - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * This file is part of the POSIX-UEFI package. - * @brief Implementing functions which are defined in dirent.h - * - */ - -#include - -extern void __stdio_seterrno(efi_status_t status); -static struct dirent __dirent; - -DIR *opendir (const char_t *__name) -{ - DIR *dp = (DIR*)fopen(__name, CL("rd")); - if(dp) rewinddir(dp); - return dp; -} - -struct dirent *readdir (DIR *__dirp) -{ - efi_status_t status; - efi_file_info_t info; - uintn_t bs = sizeof(efi_file_info_t); - memset(&__dirent, 0, sizeof(struct dirent)); - status = __dirp->Read(__dirp, &bs, &info); - if(EFI_ERROR(status) || !bs) { - if(EFI_ERROR(status)) __stdio_seterrno(status); - else errno = 0; - return NULL; - } - __dirent.d_type = info.Attribute & EFI_FILE_DIRECTORY ? DT_DIR : DT_REG; -#ifndef UEFI_NO_UTF8 - __dirent.d_reclen = (unsigned short int)wcstombs(__dirent.d_name, info.FileName, FILENAME_MAX - 1); -#else - __dirent.d_reclen = strlen(info.FileName); - strncpy(__dirent.d_name, info.FileName, FILENAME_MAX - 1); -#endif - return &__dirent; -} - -void rewinddir (DIR *__dirp) -{ - if(__dirp) - __dirp->SetPosition(__dirp, 0); -} - -int closedir (DIR *__dirp) -{ - return fclose((FILE*)__dirp); -} - - diff --git a/Bootloader/Source/uefi/efi_entry.c b/Bootloader/Source/uefi/efi_entry.c new file mode 100644 index 0000000..d6e1ec9 --- /dev/null +++ b/Bootloader/Source/uefi/efi_entry.c @@ -0,0 +1,23 @@ +#include "uefi.h" + +efi_handle_t IM = NULL; +efi_system_table_t* ST = NULL; +efi_boot_services_t* BS = NULL; +efi_runtime_services_t* RT = NULL; + +efi_status_t bootloader_main(void); + +void __chkstk(void) {} + +efi_status_t EFIAPI efi_main(efi_handle_t image, efi_system_table_t* system_table) { + if (image == NULL || system_table == NULL || system_table->BootServices == NULL) { + return EFI_UNSUPPORTED; + } + + IM = image; + ST = system_table; + BS = system_table->BootServices; + RT = system_table->RuntimeServices; + + return bootloader_main(); +} diff --git a/Bootloader/Source/uefi/elf_aarch64_efi.lds b/Bootloader/Source/uefi/elf_aarch64_efi.lds deleted file mode 100644 index 836d982..0000000 --- a/Bootloader/Source/uefi/elf_aarch64_efi.lds +++ /dev/null @@ -1,63 +0,0 @@ -OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") -OUTPUT_ARCH(aarch64) -ENTRY(_start) -SECTIONS -{ - .text 0x0 : { - _text = .; - *(.text.head) - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - *(.srodata) - *(.rodata*) - . = ALIGN(16); - } - _etext = .; - _text_size = . - _text; - .dynamic : { *(.dynamic) } - .data : ALIGN(4096) - { - _data = .; - *(.sdata) - *(.data) - *(.data1) - *(.data.*) - *(.got.plt) - *(.got) - - /* the EFI loader doesn't seem to like a .bss section, so we stick - it all into .data: */ - . = ALIGN(16); - _bss = .; - *(.sbss) - *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - . = ALIGN(16); - _bss_end = .; - } - - .rela.dyn : { *(.rela.dyn) } - .rela.plt : { *(.rela.plt) } - .rela.got : { *(.rela.got) } - .rela.data : { *(.rela.data) *(.rela.data*) } - . = ALIGN(512); - _edata = .; - _data_size = . - _data; - - . = ALIGN(4096); - .dynsym : { *(.dynsym) } - . = ALIGN(4096); - .dynstr : { *(.dynstr) } - . = ALIGN(4096); - .note.gnu.build-id : { *(.note.gnu.build-id) } - /DISCARD/ : - { - *(.rel.reloc) - *(.eh_frame) - *(.note.GNU-stack) - } - .comment 0 : { *(.comment) } -} diff --git a/Bootloader/Source/uefi/elf_riscv64_efi.lds b/Bootloader/Source/uefi/elf_riscv64_efi.lds deleted file mode 100644 index 6f1936b..0000000 --- a/Bootloader/Source/uefi/elf_riscv64_efi.lds +++ /dev/null @@ -1,64 +0,0 @@ -OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv") -OUTPUT_ARCH(riscv) -ENTRY(_start) -SECTIONS -{ - .text 0x0 : { - _text = .; - *(.text.head) - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - *(.srodata) - *(.rodata*) - . = ALIGN(16); - } - _etext = .; - _text_size = . - _text; - .dynamic : { *(.dynamic) } - .data : ALIGN(4096) - { - _data = .; - *(.sdata) - *(.data) - *(.data1) - *(.data.*) - *(.got.plt) - *(.got) - - /* the EFI loader doesn't seem to like a .bss section, so we stick - it all into .data: */ - . = ALIGN(16); - _bss = .; - *(.sbss) - *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - . = ALIGN(16); - _bss_end = .; - } - - .rela.text : { *(.rela.text) *(.rela.text*) } - .rela.dyn : { *(.rela.dyn) } - .rela.plt : { *(.rela.plt) } - .rela.got : { *(.rela.got) } - .rela.data : { *(.rela.data) *(.rela.data*) } - . = ALIGN(512); - _edata = .; - _data_size = . - _data; - - . = ALIGN(4096); - .dynsym : { *(.dynsym) } - . = ALIGN(4096); - .dynstr : { *(.dynstr) } - . = ALIGN(4096); - .note.gnu.build-id : { *(.note.gnu.build-id) } - /DISCARD/ : - { - *(.rel.reloc) - *(.eh_frame) - *(.note.GNU-stack) - } - .comment 0 : { *(.comment) } -} diff --git a/Bootloader/Source/uefi/elf_x86_64_efi.lds b/Bootloader/Source/uefi/elf_x86_64_efi.lds deleted file mode 100644 index 7be5902..0000000 --- a/Bootloader/Source/uefi/elf_x86_64_efi.lds +++ /dev/null @@ -1,76 +0,0 @@ -/* Same as elf_x86_64_fbsd_efi.lds, except for OUTPUT_FORMAT below - KEEP IN SYNC */ -OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") -OUTPUT_ARCH(i386:x86-64) -ENTRY(_start) -SECTIONS -{ - . = 0; - ImageBase = .; - /* .hash and/or .gnu.hash MUST come first! */ - .hash : { *(.hash) } - .gnu.hash : { *(.gnu.hash) } - . = ALIGN(4096); - .eh_frame : - { - *(.eh_frame) - } - . = ALIGN(4096); - .text : - { - _text = .; - *(.text) - *(.text.*) - *(.gnu.linkonce.t.*) - . = ALIGN(16); - } - _etext = .; - _text_size = . - _text; - . = ALIGN(4096); - .reloc : - { - *(.reloc) - } - . = ALIGN(4096); - .data : - { - _data = .; - *(.rodata*) - *(.got.plt) - *(.got) - *(.data*) - *(.sdata) - /* the EFI loader doesn't seem to like a .bss section, so we stick - it all into .data: */ - *(.sbss) - *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - *(.rel.local) - } - .note.gnu.build-id : { *(.note.gnu.build-id) } - - _edata = .; - _data_size = . - _etext; - . = ALIGN(4096); - .dynamic : { *(.dynamic) } - . = ALIGN(4096); - .rela : - { - *(.rela.data*) - *(.rela.got) - *(.rela.stab) - } - . = ALIGN(4096); - .dynsym : { *(.dynsym) } - . = ALIGN(4096); - .dynstr : { *(.dynstr) } - . = ALIGN(4096); - .ignored.reloc : - { - *(.rela.reloc) - *(.eh_frame) - *(.note.GNU-stack) - } - .comment 0 : { *(.comment) } -} diff --git a/Bootloader/Source/uefi/qsort.c b/Bootloader/Source/uefi/qsort.c deleted file mode 100644 index d6563c9..0000000 --- a/Bootloader/Source/uefi/qsort.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * qsort.c - * - * @brief from OpenBSD - */ - -/* $OpenBSD: qsort.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */ -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, 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 - -static __inline char *med3(char *, char *, char *, __compar_fn_t cmp); -static __inline void swapfunc(char *, char *, int, int); -/* - * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". - */ -#define swapcode(TYPE, parmi, parmj, n) { \ - long i = (n) / sizeof (TYPE); \ - TYPE *pi = (TYPE *) (parmi); \ - TYPE *pj = (TYPE *) (parmj); \ - do { \ - TYPE t = *pi; \ - *pi++ = *pj; \ - *pj++ = t; \ - } while (--i > 0); \ -} -#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ - es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; -static __inline void -swapfunc(char *a, char *b, int n, int swaptype) -{ - if (swaptype <= 1) - swapcode(long, a, b, n) - else - swapcode(char, a, b, n) -} -#define swap(a, b) \ - if (swaptype == 0) { \ - long t = *(long *)(a); \ - *(long *)(a) = *(long *)(b); \ - *(long *)(b) = t; \ - } else \ - swapfunc(a, b, es, swaptype) -#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) -static __inline char * -med3(char *a, char *b, char *c, __compar_fn_t cmp) -{ - return cmp(a, b) < 0 ? - (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a )) - :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c )); -} - -void qsort(void *aa, size_t n, size_t es, __compar_fn_t cmp) -{ - char *pa, *pb, *pc, *pd, *pl, *pm, *pn; - int d, r, swaptype, swap_cnt; - char *a = aa; -loop: SWAPINIT(a, es); - swap_cnt = 0; - if (n < 7) { - for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es) - for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; - pl -= es) - swap(pl, pl - es); - return; - } - pm = (char *)a + (n / 2) * es; - if (n > 7) { - pl = (char *)a; - pn = (char *)a + (n - 1) * es; - if (n > 40) { - d = (n / 8) * es; - pl = med3(pl, pl + d, pl + 2 * d, cmp); - pm = med3(pm - d, pm, pm + d, cmp); - pn = med3(pn - 2 * d, pn - d, pn, cmp); - } - pm = med3(pl, pm, pn, cmp); - } - swap(a, pm); - pa = pb = (char *)a + es; - - pc = pd = (char *)a + (n - 1) * es; - for (;;) { - while (pb <= pc && (r = cmp(pb, a)) <= 0) { - if (r == 0) { - swap_cnt = 1; - swap(pa, pb); - pa += es; - } - pb += es; - } - while (pb <= pc && (r = cmp(pc, a)) >= 0) { - if (r == 0) { - swap_cnt = 1; - swap(pc, pd); - pd -= es; - } - pc -= es; - } - if (pb > pc) - break; - swap(pb, pc); - swap_cnt = 1; - pb += es; - pc -= es; - } - if (swap_cnt == 0) { /* Switch to insertion sort */ - for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es) - for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; - pl -= es) - swap(pl, pl - es); - return; - } - pn = (char *)a + n * es; - r = min(pa - (char *)a, pb - pa); - vecswap(a, pb - r, r); - r = min(pd - pc, pn - pd - (int)es); - vecswap(pb, pn - r, r); - if ((r = pb - pa) > (int)es) - qsort(a, r / es, es, cmp); - if ((r = pd - pc) > (int)es) { - /* Iterate rather than recurse to save stack space */ - a = pn - r; - n = r / es; - goto loop; - } -/* qsort(pn - r, r / es, es, cmp);*/ -} diff --git a/Bootloader/Source/uefi/stat.c b/Bootloader/Source/uefi/stat.c deleted file mode 100644 index 017a4f8..0000000 --- a/Bootloader/Source/uefi/stat.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * stat.c - * - * Copyright (C) 2021 bzt (bztsrc@gitlab) - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * This file is part of the POSIX-UEFI package. - * @brief Implementing functions which are defined in sys/stat.h - * - */ - -#include - -/* fstat is in stdio.c because we can't access static variables otherwise... */ - -int stat (const char_t *__file, struct stat *__buf) -{ - int ret; - FILE *f; - - if(!__file || !*__file || !__buf) { - errno = EINVAL; - return -1; - } - f = fopen(__file, CL("*")); - if(!f) { - memset(__buf, 0, sizeof(struct stat)); - return -1; - } - ret = fstat(f, __buf); - fclose(f); - return ret; -} - -extern int mkdir (const char_t *__path, mode_t __mode) -{ - FILE *f; - (void)__mode; - if(!__path || !*__path) { - errno = EINVAL; - return -1; - } - f = fopen(__path, CL("wd")); - if(!f) { - return -1; - } - fclose(f); - return 0; -} diff --git a/Bootloader/Source/uefi/stdio.c b/Bootloader/Source/uefi/stdio.c deleted file mode 100644 index c536d44..0000000 --- a/Bootloader/Source/uefi/stdio.c +++ /dev/null @@ -1,817 +0,0 @@ -/* - * stdio.c - * - * Copyright (C) 2021 bzt (bztsrc@gitlab) - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * This file is part of the POSIX-UEFI package. - * @brief Implementing functions which are defined in stdio.h - * - */ - -#include - -static efi_file_handle_t *__root_dir = NULL; -static efi_serial_io_protocol_t *__ser = NULL; -static block_file_t *__blk_devs = NULL; -static uintn_t __blk_ndevs = 0; -extern time_t __mktime_efi(efi_time_t *t); -void __stdio_cleanup(void); -void __stdio_seterrno(efi_status_t status); -int __remove (const char_t *__filename, int isdir); - -void __stdio_cleanup(void) -{ -#ifndef UEFI_NO_UTF8 - if(__argvutf8) - BS->FreePool(__argvutf8); -#endif - if(__blk_devs) { - free(__blk_devs); - __blk_devs = NULL; - __blk_ndevs = 0; - } -} - -void __stdio_seterrno(efi_status_t status) -{ - switch((int)(status & 0xffff)) { - case EFI_WRITE_PROTECTED & 0xffff: errno = EROFS; break; - case EFI_ACCESS_DENIED & 0xffff: errno = EACCES; break; - case EFI_VOLUME_FULL & 0xffff: errno = ENOSPC; break; - case EFI_NOT_FOUND & 0xffff: errno = ENOENT; break; - case EFI_INVALID_PARAMETER & 0xffff: errno = EINVAL; break; - default: errno = EIO; break; - } -} - -int fstat (FILE *__f, struct stat *__buf) -{ - efi_guid_t infGuid = EFI_FILE_INFO_GUID; - efi_file_info_t info; - uintn_t fsiz = (uintn_t)sizeof(efi_file_info_t); - efi_status_t status; - uintn_t i; - - if(!__f || !__buf) { - errno = EINVAL; - return -1; - } - memset(__buf, 0, sizeof(struct stat)); - if(__f == stdin) { - __buf->st_mode = S_IREAD | S_IFIFO; - return 0; - } - if(__f == stdout || __f == stderr) { - __buf->st_mode = S_IWRITE | S_IFIFO; - return 0; - } - if(__ser && __f == (FILE*)__ser) { - __buf->st_mode = S_IREAD | S_IWRITE | S_IFCHR; - return 0; - } - for(i = 0; i < __blk_ndevs; i++) - if(__f == (FILE*)__blk_devs[i].bio) { - __buf->st_mode = S_IREAD | S_IWRITE | S_IFBLK; - __buf->st_size = (off_t)__blk_devs[i].bio->Media->BlockSize * ((off_t)__blk_devs[i].bio->Media->LastBlock + 1); - __buf->st_blocks = __blk_devs[i].bio->Media->LastBlock + 1; - return 0; - } - status = __f->GetInfo(__f, &infGuid, &fsiz, &info); - if(EFI_ERROR(status)) { - __stdio_seterrno(status); - return -1; - } - __buf->st_mode = S_IREAD | - (info.Attribute & EFI_FILE_READ_ONLY ? 0 : S_IWRITE) | - (info.Attribute & EFI_FILE_DIRECTORY ? S_IFDIR : S_IFREG); - __buf->st_size = (off_t)info.FileSize; - __buf->st_blocks = (blkcnt_t)info.PhysicalSize; - __buf->st_atime = __mktime_efi(&info.LastAccessTime); - __buf->st_mtime = __mktime_efi(&info.ModificationTime); - __buf->st_ctime = __mktime_efi(&info.CreateTime); - return 0; -} - -int fclose (FILE *__stream) -{ - efi_status_t status = EFI_SUCCESS; - uintn_t i; - if(!__stream) { - errno = EINVAL; - return 0; - } - if(__stream == stdin || __stream == stdout || __stream == stderr || (__ser && __stream == (FILE*)__ser)) { - return 1; - } - for(i = 0; i < __blk_ndevs; i++) - if(__stream == (FILE*)__blk_devs[i].bio) - return 1; - status = __stream->Close(__stream); - free(__stream); - return !EFI_ERROR(status); -} - -int fflush (FILE *__stream) -{ - efi_status_t status = EFI_SUCCESS; - uintn_t i; - if(!__stream) { - errno = EINVAL; - return 0; - } - if(__stream == stdin || __stream == stdout || __stream == stderr || (__ser && __stream == (FILE*)__ser)) { - return 1; - } - for(i = 0; i < __blk_ndevs; i++) - if(__stream == (FILE*)__blk_devs[i].bio) { - return 1; - } - status = __stream->Flush(__stream); - return !EFI_ERROR(status); -} - -int __remove (const char_t *__filename, int isdir) -{ - efi_status_t status; - efi_guid_t infGuid = EFI_FILE_INFO_GUID; - efi_file_info_t info; - uintn_t fsiz = (uintn_t)sizeof(efi_file_info_t), i; - /* little hack to support read and write mode for Delete() and stat() without create mode or checks */ - FILE *f = fopen(__filename, CL("*")); - if(errno) - return 1; - if(!f || f == stdin || f == stdout || f == stderr || (__ser && f == (FILE*)__ser)) { - errno = EBADF; - return 1; - } - for(i = 0; i < __blk_ndevs; i++) - if(f == (FILE*)__blk_devs[i].bio) { - errno = EBADF; - return 1; - } - if(isdir != -1) { - status = f->GetInfo(f, &infGuid, &fsiz, &info); - if(EFI_ERROR(status)) goto err; - if(isdir == 0 && (info.Attribute & EFI_FILE_DIRECTORY)) { - fclose(f); errno = EISDIR; - return -1; - } - if(isdir == 1 && !(info.Attribute & EFI_FILE_DIRECTORY)) { - fclose(f); errno = ENOTDIR; - return -1; - } - } - status = f->Delete(f); - if(EFI_ERROR(status)) { -err: __stdio_seterrno(status); - fclose(f); - return -1; - } - /* no need for fclose(f); */ - free(f); - return 0; -} - -int remove (const char_t *__filename) -{ - return __remove(__filename, -1); -} - -FILE *fopen (const char_t *__filename, const char_t *__modes) -{ - FILE *ret; - efi_status_t status; - efi_guid_t sfsGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; - efi_simple_file_system_protocol_t *sfs = NULL; - efi_guid_t infGuid = EFI_FILE_INFO_GUID; - efi_file_info_t info; - uintn_t fsiz = (uintn_t)sizeof(efi_file_info_t), par, i; -#ifndef UEFI_NO_UTF8 - wchar_t wcname[BUFSIZ]; -#endif - errno = 0; - if(!__filename || !*__filename || !__modes || (__modes[0] != CL('r') && __modes[0] != CL('w') && __modes[0] != CL('a') && - __modes[0] != CL('*')) || (__modes[1] != 0 && __modes[1] != CL('d') && __modes[1] != CL('+'))) { - errno = EINVAL; - return NULL; - } - /* fake some device names. UEFI has no concept of device files */ - if(!strcmp(__filename, CL("/dev/stdin"))) { - if(__modes[0] == CL('w') || __modes[0] == CL('a')) { errno = EPERM; return NULL; } - return stdin; - } - if(!strcmp(__filename, CL("/dev/stdout"))) { - if(__modes[0] == CL('r')) { errno = EPERM; return NULL; } - return stdout; - } - if(!strcmp(__filename, CL("/dev/stderr"))) { - if(__modes[0] == CL('r')) { errno = EPERM; return NULL; } - return stderr; - } - if(!memcmp(__filename, CL("/dev/serial"), 11 * sizeof(char_t))) { - par = (uintn_t)atol(__filename + 11); - if(!__ser) { - efi_guid_t serGuid = EFI_SERIAL_IO_PROTOCOL_GUID; - status = BS->LocateProtocol(&serGuid, NULL, (void**)&__ser); - if(EFI_ERROR(status) || !__ser) { errno = ENOENT; return NULL; } - } - __ser->SetAttributes(__ser, par > 9600 ? par : 115200, 0, 1000, NoParity, 8, OneStopBit); - return (FILE*)__ser; - } - if(!memcmp(__filename, CL("/dev/disk"), 9 * sizeof(char_t))) { - par = (uintn_t)atol(__filename + 9); - if(!__blk_ndevs) { - efi_guid_t bioGuid = EFI_BLOCK_IO_PROTOCOL_GUID; - efi_handle_t handles[128]; - uintn_t handle_size = sizeof(handles); - status = BS->LocateHandle(ByProtocol, &bioGuid, NULL, &handle_size, (efi_handle_t*)&handles); - if(!EFI_ERROR(status)) { - handle_size /= (uintn_t)sizeof(efi_handle_t); - /* workaround a bug in TianoCore, it reports zero size even though the data is in the buffer */ - if(handle_size < 1) - handle_size = (uintn_t)sizeof(handles) / sizeof(efi_handle_t); - __blk_devs = (block_file_t*)malloc(handle_size * sizeof(block_file_t)); - if(__blk_devs) { - memset(__blk_devs, 0, handle_size * sizeof(block_file_t)); - for(i = __blk_ndevs = 0; i < handle_size; i++) - if(handles[i] && !EFI_ERROR(BS->HandleProtocol(handles[i], &bioGuid, (void **) &__blk_devs[__blk_ndevs].bio)) && - __blk_devs[__blk_ndevs].bio && __blk_devs[__blk_ndevs].bio->Media && - __blk_devs[__blk_ndevs].bio->Media->BlockSize > 0) - __blk_ndevs++; - } else - __blk_ndevs = 0; - } - } - if(__blk_ndevs && par < __blk_ndevs) - return (FILE*)__blk_devs[par].bio; - errno = ENOENT; - return NULL; - } - if(!__root_dir && LIP) { - status = BS->HandleProtocol(LIP->DeviceHandle, &sfsGuid, (void **)&sfs); - if(!EFI_ERROR(status)) - status = sfs->OpenVolume(sfs, &__root_dir); - } - if(!__root_dir) { - errno = ENODEV; - return NULL; - } - ret = (FILE*)malloc(sizeof(FILE)); - if(!ret) return NULL; - /* normally write means read,write,create. But for remove (internal '*' mode), we need read,write without create - * also mode 'w' in POSIX means write-only (without read), but that's not working on certain firmware, we must - * pass read too. This poses a problem of truncating a write-only file, see issue #26, we have to do that manually */ -#ifndef UEFI_NO_UTF8 - mbstowcs((wchar_t*)&wcname, __filename, BUFSIZ - 1); - status = __root_dir->Open(__root_dir, &ret, (wchar_t*)&wcname, -#else - status = __root_dir->Open(__root_dir, &ret, (wchar_t*)__filename, -#endif - __modes[0] == CL('w') || __modes[0] == CL('a') ? (EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ | EFI_FILE_MODE_CREATE) : - EFI_FILE_MODE_READ | (__modes[0] == CL('*') || __modes[1] == CL('+') ? EFI_FILE_MODE_WRITE : 0), - __modes[1] == CL('d') ? EFI_FILE_DIRECTORY : 0); - if(EFI_ERROR(status)) { -err: __stdio_seterrno(status); - free(ret); return NULL; - } - if(__modes[0] == CL('*')) return ret; - status = ret->GetInfo(ret, &infGuid, &fsiz, &info); - if(EFI_ERROR(status)) goto err; - if(__modes[1] == CL('d') && !(info.Attribute & EFI_FILE_DIRECTORY)) { - ret->Close(ret); free(ret); errno = ENOTDIR; return NULL; - } - if(__modes[1] != CL('d') && (info.Attribute & EFI_FILE_DIRECTORY)) { - ret->Close(ret); free(ret); errno = EISDIR; return NULL; - } - if(__modes[0] == CL('a')) fseek(ret, 0, SEEK_END); - if(__modes[0] == CL('w')) { - /* manually truncate file size - * See https://github.com/tianocore/edk2/blob/master/MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.c - * function FileHandleSetSize */ - info.FileSize = 0; - ret->SetInfo(ret, &infGuid, fsiz, &info); - } - return ret; -} - -size_t fread (void *__ptr, size_t __size, size_t __n, FILE *__stream) -{ - uintn_t bs = __size * __n, i, n; - efi_status_t status; - if(!__ptr || __size < 1 || __n < 1 || !__stream) { - errno = EINVAL; - return 0; - } - if(__stream == stdin || __stream == stdout || __stream == stderr) { - errno = ESPIPE; - return 0; - } - if(__ser && __stream == (FILE*)__ser) { - status = __ser->Read(__ser, &bs, __ptr); - } else { - for(i = 0; i < __blk_ndevs; i++) - if(__stream == (FILE*)__blk_devs[i].bio) { - n = __blk_devs[i].offset / __blk_devs[i].bio->Media->BlockSize; - bs = (bs / __blk_devs[i].bio->Media->BlockSize) * __blk_devs[i].bio->Media->BlockSize; - status = __blk_devs[i].bio->ReadBlocks(__blk_devs[i].bio, __blk_devs[i].bio->Media->MediaId, n, bs, __ptr); - if(EFI_ERROR(status)) { - __stdio_seterrno(status); - return 0; - } - __blk_devs[i].offset += bs; - return bs / __size; - } - status = __stream->Read(__stream, &bs, __ptr); - } - if(EFI_ERROR(status)) { - __stdio_seterrno(status); - return 0; - } - return bs / __size; -} - -size_t fwrite (const void *__ptr, size_t __size, size_t __n, FILE *__stream) -{ - uintn_t bs = __size * __n, n, i; - efi_status_t status; - if(!__ptr || __size < 1 || __n < 1 || !__stream) { - errno = EINVAL; - return 0; - } - if(__stream == stdin || __stream == stdout || __stream == stderr) { - errno = ESPIPE; - return 0; - } - if(__ser && __stream == (FILE*)__ser) { - status = __ser->Write(__ser, &bs, (void*)__ptr); - } else { - for(i = 0; i < __blk_ndevs; i++) - if(__stream == (FILE*)__blk_devs[i].bio) { - n = __blk_devs[i].offset / __blk_devs[i].bio->Media->BlockSize; - bs = (bs / __blk_devs[i].bio->Media->BlockSize) * __blk_devs[i].bio->Media->BlockSize; - status = __blk_devs[i].bio->WriteBlocks(__blk_devs[i].bio, __blk_devs[i].bio->Media->MediaId, n, bs, (void*)__ptr); - if(EFI_ERROR(status)) { - __stdio_seterrno(status); - return 0; - } - __blk_devs[i].offset += bs; - return bs / __size; - } - status = __stream->Write(__stream, &bs, (void *)__ptr); - } - if(EFI_ERROR(status)) { - __stdio_seterrno(status); - return 0; - } - return bs / __size; -} - -int fseek (FILE *__stream, long int __off, int __whence) -{ - off_t off = 0; - efi_status_t status; - efi_guid_t infoGuid = EFI_FILE_INFO_GUID; - efi_file_info_t info; - uintn_t fsiz = sizeof(efi_file_info_t), i; - if(!__stream || (__whence != SEEK_SET && __whence != SEEK_CUR && __whence != SEEK_END)) { - errno = EINVAL; - return -1; - } - if(__stream == stdin || __stream == stdout || __stream == stderr) { - errno = ESPIPE; - return -1; - } - if(__ser && __stream == (FILE*)__ser) { - errno = EBADF; - return -1; - } - for(i = 0; i < __blk_ndevs; i++) - if(__stream == (FILE*)__blk_devs[i].bio) { - off = (uint64_t)__blk_devs[i].bio->Media->BlockSize * (uint64_t)__blk_devs[i].bio->Media->LastBlock; - switch(__whence) { - case SEEK_END: - __blk_devs[i].offset = off + __off; - break; - case SEEK_CUR: - __blk_devs[i].offset += __off; - break; - case SEEK_SET: - __blk_devs[i].offset = __off; - break; - } - if(__blk_devs[i].offset < 0) __blk_devs[i].offset = 0; - if(__blk_devs[i].offset > off) __blk_devs[i].offset = off; - __blk_devs[i].offset = (__blk_devs[i].offset / __blk_devs[i].bio->Media->BlockSize) * - __blk_devs[i].bio->Media->BlockSize; - return 0; - } - switch(__whence) { - case SEEK_END: - status = __stream->GetInfo(__stream, &infoGuid, &fsiz, &info); - if(!EFI_ERROR(status)) { - off = info.FileSize + __off; - status = __stream->SetPosition(__stream, off); - } - break; - case SEEK_CUR: - status = __stream->GetPosition(__stream, &off); - if(!EFI_ERROR(status)) { - off += __off; - status = __stream->SetPosition(__stream, off); - } - break; - default: - status = __stream->SetPosition(__stream, __off); - break; - } - return EFI_ERROR(status) ? -1 : 0; -} - -long int ftell (FILE *__stream) -{ - uint64_t off = 0; - uintn_t i; - efi_status_t status; - if(!__stream) { - errno = EINVAL; - return -1; - } - if(__stream == stdin || __stream == stdout || __stream == stderr) { - errno = ESPIPE; - return -1; - } - if(__ser && __stream == (FILE*)__ser) { - errno = EBADF; - return -1; - } - for(i = 0; i < __blk_ndevs; i++) - if(__stream == (FILE*)__blk_devs[i].bio) { - return (long int)__blk_devs[i].offset; - } - status = __stream->GetPosition(__stream, &off); - return EFI_ERROR(status) ? -1 : (long int)off; -} - -int feof (FILE *__stream) -{ - uint64_t off = 0; - efi_guid_t infGuid = EFI_FILE_INFO_GUID; - efi_file_info_t info; - uintn_t fsiz = (uintn_t)sizeof(efi_file_info_t), i; - efi_status_t status; - if(!__stream) { - errno = EINVAL; - return 0; - } - if(__stream == stdin || __stream == stdout || __stream == stderr) { - errno = ESPIPE; - return 0; - } - if(__ser && __stream == (FILE*)__ser) { - errno = EBADF; - return 0; - } - for(i = 0; i < __blk_ndevs; i++) - if(__stream == (FILE*)__blk_devs[i].bio) { - errno = EBADF; - return __blk_devs[i].offset == (off_t)__blk_devs[i].bio->Media->BlockSize * (off_t)__blk_devs[i].bio->Media->LastBlock; - } - status = __stream->GetPosition(__stream, &off); - if(EFI_ERROR(status)) { -err: __stdio_seterrno(status); - return 1; - } - status = __stream->GetInfo(__stream, &infGuid, &fsiz, &info); - if(EFI_ERROR(status)) goto err; - __stream->SetPosition(__stream, off); - return info.FileSize == off; -} - -int vsnprintf(char_t *dst, size_t maxlen, const char_t *fmt, __builtin_va_list args) -{ -#define needsescape(a) (a==CL('\"') || a==CL('\\') || a==CL('\a') || a==CL('\b') || a==CL('\033') || a==CL('\f') || \ - a==CL('\r') || a==CL('\n') || a==CL('\t') || a==CL('\v')) - efi_physical_address_t m; - uint8_t *mem; - uint64_t arg; - int64_t iarg; - int len, sign, i, j; - char_t *p, *orig=dst, *end = dst + maxlen - 1, tmpstr[24], pad, n; -#ifdef UEFI_NO_UTF8 - char *c; -#endif - if(dst==NULL || fmt==NULL) - return 0; - - arg = 0; - while(*fmt && dst < end) { - if(*fmt==CL('%')) { - fmt++; - if(*fmt==CL('%')) goto put; - len=0; pad=CL(' '); - if(*fmt==CL('0')) pad=CL('0'); - while(*fmt>=CL('0') && *fmt<=CL('9')) { - len *= 10; - len += *fmt-CL('0'); - fmt++; - } - if(*fmt==CL('l')) fmt++; - if(*fmt==CL('c')) { - arg = __builtin_va_arg(args, uint32_t); -#ifndef UEFI_NO_UTF8 - if(arg<0x80) { *dst++ = arg; } else - if(arg<0x800) { *dst++ = ((arg>>6)&0x1F)|0xC0; *dst++ = (arg&0x3F)|0x80; } else - { *dst++ = ((arg>>12)&0x0F)|0xE0; *dst++ = ((arg>>6)&0x3F)|0x80; *dst++ = (arg&0x3F)|0x80; } -#else - *dst++ = (wchar_t)(arg & 0xffff); -#endif - fmt++; - continue; - } else - if(*fmt==CL('d') || *fmt==CL('i') || *fmt==CL('u')) { - iarg = __builtin_va_arg(args, int64_t); - sign=0; - if(*fmt!=CL('u') && iarg<0) { - arg=-iarg; - sign++; - } else arg=(uint64_t)iarg; - i=23; - tmpstr[i]=0; - do { - tmpstr[--i]=CL('0')+(arg%10); - arg/=10; - } while(arg!=0 && i>0); - if(sign) { - tmpstr[--i]=CL('-'); - } - if(len>0 && len<23) { - while(i && i>23-len) { - tmpstr[--i]=pad; - } - } - p=&tmpstr[i]; - goto copystring; - } else - if(*fmt==CL('p')) { - arg = __builtin_va_arg(args, uint64_t); - len = 16; pad = CL('0'); goto hex; - } else - if(*fmt==CL('x') || *fmt==CL('X')) { - arg = __builtin_va_arg(args, uint64_t); -hex: i=16; - tmpstr[i]=0; - do { - n=arg & 0xf; - /* 0-9 => '0'-'9', 10-15 => 'A'-'F' */ - tmpstr[--i]=n+(n>9?(*fmt==CL('X')?0x37:0x57):0x30); - arg>>=4; - } while(arg!=0 && i>0); - /* padding, only leading zeros */ - if(len>0 && len<=16) { - while(i>16-len) { - tmpstr[--i]=CL('0'); - } - } - p=&tmpstr[i]; - goto copystring; - } else - if(*fmt==CL('s') || *fmt==CL('q')) { - p = __builtin_va_arg(args, char_t*); -copystring: if(p==NULL) { - p=CL("(null)"); - } - while(*p && dst + 2 < end) { - if(*fmt==CL('q') && needsescape(*p)) { - *dst++ = CL('\\'); - switch(*p) { - case CL('\a'): *dst++ = CL('a'); break; - case CL('\b'): *dst++ = CL('b'); break; - case 27: *dst++ = CL('e'); break; /* gcc 10.2 doesn't like CL('\e') in ansi mode */ - case CL('\f'): *dst++ = CL('f'); break; - case CL('\n'): *dst++ = CL('n'); break; - case CL('\r'): *dst++ = CL('r'); break; - case CL('\t'): *dst++ = CL('t'); break; - case CL('\v'): *dst++ = CL('v'); break; - default: *dst++ = *p++; break; - } - } else { - if(*p == CL('\n') && (orig == dst || *(dst - 1) != CL('\r'))) *dst++ = CL('\r'); - *dst++ = *p++; - } - } - } else -#ifdef UEFI_NO_UTF8 - if(*fmt==L'S' || *fmt==L'Q') { - c = __builtin_va_arg(args, char*); - if(c==NULL) goto copystring; - while(*p && dst + 2 < end) { - arg = *c; - if((*c & 128) != 0) { - if((*c & 32) == 0 ) { - arg = ((*c & 0x1F)<<6)|(*(c+1) & 0x3F); - c += 1; - } else - if((*c & 16) == 0 ) { - arg = ((*c & 0xF)<<12)|((*(c+1) & 0x3F)<<6)|(*(c+2) & 0x3F); - c += 2; - } else - if((*c & 8) == 0 ) { - arg = ((*c & 0x7)<<18)|((*(c+1) & 0x3F)<<12)|((*(c+2) & 0x3F)<<6)|(*(c+3) & 0x3F); - c += 3; - } else - arg = L'?'; - } - if(!arg) break; - if(*fmt==L'Q' && needsescape(arg)) { - *dst++ = L'\\'; - switch(arg) { - case L'\a': *dst++ = L'a'; break; - case L'\b': *dst++ = L'b'; break; - case 27: *dst++ = L'e'; break; /* gcc 10.2 doesn't like L'\e' in ansi mode */ - case L'\f': *dst++ = L'f'; break; - case L'\n': *dst++ = L'n'; break; - case L'\r': *dst++ = L'r'; break; - case L'\t': *dst++ = L't'; break; - case L'\v': *dst++ = L'v'; break; - default: *dst++ = arg; break; - } - } else { - if(arg == L'\n') *dst++ = L'\r'; - *dst++ = (wchar_t)(arg & 0xffff); - } - } - } else -#endif - if(*fmt==CL('D')) { - m = __builtin_va_arg(args, efi_physical_address_t); - for(j = 0; j < (len < 1 ? 1 : (len > 16 ? 16 : len)); j++) { - for(i = 44; i >= 0; i -= 4) { - n = (m >> i) & 15; *dst++ = n + (n>9?0x37:0x30); - if(dst >= end) goto zro; - } - *dst++ = CL(':'); if(dst >= end) goto zro; - *dst++ = CL(' '); if(dst >= end) goto zro; - mem = (uint8_t*)m; - for(i = 0; i < 16; i++) { - n = (mem[i] >> 4) & 15; *dst++ = n + (n>9?0x37:0x30); if(dst >= end) goto zro; - n = mem[i] & 15; *dst++ = n + (n>9?0x37:0x30); if(dst >= end) goto zro; - *dst++ = CL(' ');if(dst >= end) goto zro; - } - *dst++ = CL(' '); if(dst >= end) goto zro; - for(i = 0; i < 16; i++) { - *dst++ = (mem[i] < 32 || mem[i] >= 127 ? CL('.') : (char_t)mem[i]); - if(dst >= end) goto zro; - } - *dst++ = CL('\r'); if(dst >= end) goto zro; - *dst++ = CL('\n'); if(dst >= end) goto zro; - m += 16; - } - } - } else { -put: if(*fmt == CL('\n') && (orig == dst || *(dst - 1) != CL('\r'))) *dst++ = CL('\r'); - *dst++ = *fmt; - } - fmt++; - } -zro:*dst=0; - return (int)(dst-orig); -#undef needsescape -} - -int vsprintf(char_t *dst, const char_t *fmt, __builtin_va_list args) -{ - return vsnprintf(dst, BUFSIZ, fmt, args); -} - -int sprintf(char_t *dst, const char_t* fmt, ...) -{ - int ret; - __builtin_va_list args; - __builtin_va_start(args, fmt); - ret = vsnprintf(dst, BUFSIZ, fmt, args); - __builtin_va_end(args); - return ret; -} - -int snprintf(char_t *dst, size_t maxlen, const char_t* fmt, ...) -{ - int ret; - __builtin_va_list args; - __builtin_va_start(args, fmt); - ret = vsnprintf(dst, maxlen, fmt, args); - __builtin_va_end(args); - return ret; -} - -int vprintf(const char_t* fmt, __builtin_va_list args) -{ - int ret; - wchar_t dst[BUFSIZ]; -#ifndef UEFI_NO_UTF8 - char_t tmp[BUFSIZ]; - ret = vsnprintf(tmp, BUFSIZ, fmt, args); - mbstowcs(dst, tmp, BUFSIZ - 1); -#else - ret = vsnprintf(dst, BUFSIZ, fmt, args); -#endif - ST->ConOut->OutputString(ST->ConOut, (wchar_t *)&dst); - return ret; -} - -int printf(const char_t* fmt, ...) -{ - int ret; - __builtin_va_list args; - __builtin_va_start(args, fmt); - ret = vprintf(fmt, args); - __builtin_va_end(args); - return ret; -} - -int vfprintf (FILE *__stream, const char_t *__format, __builtin_va_list args) -{ - wchar_t dst[BUFSIZ]; - char_t tmp[BUFSIZ]; - uintn_t ret, i; -#ifndef UEFI_NO_UTF8 - ret = (uintn_t)vsnprintf(tmp, BUFSIZ, __format, args); - ret = mbstowcs(dst, tmp, BUFSIZ - 1); -#else - ret = vsnprintf(dst, BUFSIZ, __format, args); -#endif - if(ret < 1 || !__stream || __stream == stdin) return 0; - for(i = 0; i < __blk_ndevs; i++) - if(__stream == (FILE*)__blk_devs[i].bio) { - errno = EBADF; - return -1; - } - if(__stream == stdout) - ST->ConOut->OutputString(ST->ConOut, (wchar_t*)&dst); - else if(__stream == stderr) - ST->StdErr->OutputString(ST->StdErr, (wchar_t*)&dst); - else if(__ser && __stream == (FILE*)__ser) { -#ifdef UEFI_NO_UTF8 - wcstombs((char*)&tmp, dst, BUFSIZ - 1); -#endif - __ser->Write(__ser, &ret, (void*)&tmp); - } else -#ifndef UEFI_NO_UTF8 - __stream->Write(__stream, &ret, (void*)&tmp); -#else - __stream->Write(__stream, &ret, (void*)&dst); -#endif - return (int)ret; -} - -int fprintf (FILE *__stream, const char_t *__format, ...) -{ - int ret; - __builtin_va_list args; - __builtin_va_start(args, __format); - ret = vfprintf(__stream, __format, args); - __builtin_va_end(args); - return ret; -} - -int getchar_ifany (void) -{ - efi_input_key_t key = { 0 }; - efi_status_t status = ST->ConIn->ReadKeyStroke(ST->ConIn, &key); - return EFI_ERROR(status) ? 0 : key.UnicodeChar; -} - -int getchar (void) -{ - uintn_t idx; - BS->WaitForEvent(1, &ST->ConIn->WaitForKey, &idx); - return getchar_ifany(); -} - -int putchar (int __c) -{ - wchar_t tmp[2]; - tmp[0] = (wchar_t)__c; - tmp[1] = 0; - ST->ConOut->OutputString(ST->ConOut, (__c == L'\n' ? (wchar_t*)L"\r\n" : (wchar_t*)&tmp)); - return (int)tmp[0]; -} diff --git a/Bootloader/Source/uefi/stdlib.c b/Bootloader/Source/uefi/stdlib.c deleted file mode 100644 index 81b33df..0000000 --- a/Bootloader/Source/uefi/stdlib.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * stdlib.c - * - * Copyright (C) 2021 bzt (bztsrc@gitlab) - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * This file is part of the POSIX-UEFI package. - * @brief Implementing functions which are defined in stdlib.h - * - */ - -#include - -int errno = 0; -static uint64_t __srand_seed = 6364136223846793005ULL; -extern void __stdio_cleanup(void); -#ifndef UEFI_NO_TRACK_ALLOC -static uintptr_t *__stdlib_allocs = NULL; -static uintn_t __stdlib_numallocs = 0; -#endif - -int atoi(const char_t *s) -{ - return (int)atol(s); -} - -int64_t atol(const char_t *s) -{ - int64_t sign = 1; - if(!s || !*s) return 0; - if(*s == CL('-')) { sign = -1; s++; } - if(s[0] == CL('0')) { - if(s[1] == CL('x')) - return strtol(s + 2, NULL, 16) * sign; - if(s[1] >= CL('0') && s[1] <= CL('7')) - return strtol(s, NULL, 8) * sign; - } - return strtol(s, NULL, 10) * sign; -} - -int64_t strtol (const char_t *s, char_t **__endptr, int __base) -{ - int64_t v=0, sign = 1; - if(!s || !*s) return 0; - if(*s == CL('-')) { sign = -1; s++; } - while(!(*s < CL('0') || (__base < 10 && *s >= __base + CL('0')) || (__base >= 10 && ((*s > CL('9') && *s < CL('A')) || - (*s > CL('F') && *s < CL('a')) || *s > CL('f'))))) { - v *= __base; - if(*s >= CL('0') && *s <= (__base < 10 ? __base + CL('0') : CL('9'))) - v += (*s)-CL('0'); - else if(__base == 16 && *s >= CL('a') && *s <= CL('f')) - v += (*s)-CL('a')+10; - else if(__base == 16 && *s >= CL('A') && *s <= CL('F')) - v += (*s)-CL('A')+10; - s++; - } - if(__endptr) *__endptr = (char_t*)s; - return v * sign; -} - -void *malloc (size_t __size) -{ - void *ret = NULL; - efi_status_t status; -#ifndef UEFI_NO_TRACK_ALLOC - uintn_t i; - for(i = 0; i < __stdlib_numallocs && __stdlib_allocs[i] != 0; i += 2); - if(i == __stdlib_numallocs) { - /* no free slots found, (re)allocate the housekeeping array */ - status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, (__stdlib_numallocs + 2) * sizeof(uintptr_t), &ret); - if(EFI_ERROR(status) || !ret) { errno = ENOMEM; return NULL; } - if(__stdlib_allocs) memcpy(ret, __stdlib_allocs, __stdlib_numallocs * sizeof(uintptr_t)); - __stdlib_allocs = (uintptr_t*)ret; - __stdlib_allocs[i] = __stdlib_allocs[i + 1] = 0; - __stdlib_numallocs += 2; - ret = NULL; - } -#endif - status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __size, &ret); - if(EFI_ERROR(status) || !ret) { errno = ENOMEM; ret = NULL; } -#ifndef UEFI_NO_TRACK_ALLOC - __stdlib_allocs[i] = (uintptr_t)ret; - __stdlib_allocs[i + 1] = (uintptr_t)__size; -#endif - return ret; -} - -void *calloc (size_t __nmemb, size_t __size) -{ - void *ret = malloc(__nmemb * __size); - if(ret) memset(ret, 0, __nmemb * __size); - return ret; -} - -void *realloc (void *__ptr, size_t __size) -{ - void *ret = NULL; - efi_status_t status; -#ifndef UEFI_NO_TRACK_ALLOC - uintn_t i; -#endif - if(!__ptr) return malloc(__size); - if(!__size) { free(__ptr); return NULL; } -#ifndef UEFI_NO_TRACK_ALLOC - /* get the slot which stores the old size for this buffer */ - for(i = 0; i < __stdlib_numallocs && __stdlib_allocs[i] != (uintptr_t)__ptr; i += 2); - if(i == __stdlib_numallocs) { errno = ENOMEM; return NULL; } - /* allocate a new buffer and copy data from old buffer */ - status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __size, &ret); - if(EFI_ERROR(status) || !ret) { errno = ENOMEM; ret = NULL; } - else { - memcpy(ret, (void*)__stdlib_allocs[i], __stdlib_allocs[i + 1] < __size ? __stdlib_allocs[i + 1] : __size); - if(__size > __stdlib_allocs[i + 1]) memset((uint8_t*)ret + __stdlib_allocs[i + 1], 0, __size - __stdlib_allocs[i + 1]); - /* free old buffer and store new buffer in slot */ - BS->FreePool((void*)__stdlib_allocs[i]); - __stdlib_allocs[i] = (uintptr_t)ret; - __stdlib_allocs[i + 1] = (uintptr_t)__size; - } -#else - status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __size, &ret); - if(EFI_ERROR(status) || !ret) { errno = ENOMEM; return NULL; } - /* this means out of bounds read, but fine with POSIX as the end of new buffer supposed to be left uninitialized) */ - memcpy(ret, (void*)__ptr, __size); - BS->FreePool((void*)__ptr); -#endif - return ret; -} - -void free (void *__ptr) -{ - efi_status_t status; -#ifndef UEFI_NO_TRACK_ALLOC - uintn_t i; -#endif - if(!__ptr) { errno = ENOMEM; return; } -#ifndef UEFI_NO_TRACK_ALLOC - /* find and clear the slot */ - for(i = 0; i < __stdlib_numallocs && __stdlib_allocs[i] != (uintptr_t)__ptr; i += 2); - if(i == __stdlib_numallocs) { errno = ENOMEM; return; } - __stdlib_allocs[i] = 0; - __stdlib_allocs[i + 1] = 0; - /* if there are only empty slots, free the housekeeping array too */ - for(i = 0; i < __stdlib_numallocs && __stdlib_allocs[i] == 0; i += 2); - if(i == __stdlib_numallocs) { BS->FreePool(__stdlib_allocs); __stdlib_allocs = NULL; __stdlib_numallocs = 0; } -#endif - status = BS->FreePool(__ptr); - if(EFI_ERROR(status)) errno = ENOMEM; -} - -void abort () -{ -#ifndef UEFI_NO_TRACK_ALLOC - if(__stdlib_allocs) - BS->FreePool(__stdlib_allocs); - __stdlib_allocs = NULL; - __stdlib_numallocs = 0; -#endif - __stdio_cleanup(); - BS->Exit(IM, EFI_ABORTED, 0, NULL); -} - -void exit (int __status) -{ -#ifndef UEFI_NO_TRACK_ALLOC - if(__stdlib_allocs) - BS->FreePool(__stdlib_allocs); - __stdlib_allocs = NULL; - __stdlib_numallocs = 0; -#endif - __stdio_cleanup(); - BS->Exit(IM, !__status ? 0 : (__status < 0 ? EFIERR(-__status) : EFIERR(__status)), 0, NULL); -} - -int exit_bs() -{ - efi_status_t status = 0; - efi_memory_descriptor_t *memory_map = NULL; - uintn_t cnt = 3, memory_map_size=0, map_key=0, desc_size=0; -#ifndef UEFI_NO_TRACK_ALLOC - if(__stdlib_allocs) - BS->FreePool(__stdlib_allocs); - __stdlib_allocs = NULL; - __stdlib_numallocs = 0; -#endif - __stdio_cleanup(); - while(cnt--) { - status = BS->GetMemoryMap(&memory_map_size, memory_map, &map_key, &desc_size, NULL); - if (status!=EFI_BUFFER_TOO_SMALL) break; - status = BS->ExitBootServices(IM, map_key); - if(!EFI_ERROR(status)) return 0; - } - return (int)(status & 0xffff); -} - -void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, __compar_fn_t cmp) -{ - uint64_t s=0, e=nmemb, m; - int ret; - while (s < e) { - m = s + (e-s)/2; - ret = cmp(key, (uint8_t*)base + m*size); - if (ret < 0) e = m; else - if (ret > 0) s = m+1; else - return (void *)((uint8_t*)base + m*size); - } - return NULL; -} - -int mblen(const char *s, size_t n) -{ - const char *e = s+n; - int c = 0; - if(s) { - while(s < e && *s) { - if((*s & 128) != 0) { - if((*s & 32) == 0 ) s++; else - if((*s & 16) == 0 ) s+=2; else - if((*s & 8) == 0 ) s+=3; - } - c++; - s++; - } - } - return c; -} - -int mbtowc (wchar_t * __pwc, const char *s, size_t n) -{ - wchar_t arg; - int ret = 1; - if(!s || !*s) return 0; - arg = (wchar_t)*s; - if((*s & 128) != 0) { - if((*s & 32) == 0 && n > 0) { arg = ((*s & 0x1F)<<6)|(*(s+1) & 0x3F); ret = 2; } else - if((*s & 16) == 0 && n > 1) { arg = ((*s & 0xF)<<12)|((*(s+1) & 0x3F)<<6)|(*(s+2) & 0x3F); ret = 3; } else - if((*s & 8) == 0 && n > 2) { arg = ((*s & 0x7)<<18)|((*(s+1) & 0x3F)<<12)|((*(s+2) & 0x3F)<<6)|(*(s+3) & 0x3F); ret = 4; } - else return -1; - } - if(__pwc) *__pwc = arg; - return ret; -} - -int wctomb (char *s, wchar_t u) -{ - int ret = 0; - if(u<0x80) { - *s = u; - ret = 1; - } else if(u<0x800) { - *(s+0)=((u>>6)&0x1F)|0xC0; - *(s+1)=(u&0x3F)|0x80; - ret = 2; - } else { - *(s+0)=((u>>12)&0x0F)|0xE0; - *(s+1)=((u>>6)&0x3F)|0x80; - *(s+2)=(u&0x3F)|0x80; - ret = 3; - } - return ret; -} - -size_t mbstowcs (wchar_t *__pwcs, const char *__s, size_t __n) -{ - int r; - wchar_t *orig = __pwcs; - if(!__s || !*__s) return 0; - while(*__s) { - r = mbtowc(__pwcs, __s, __n - (size_t)(__pwcs - orig)); - if(r < 0) return (size_t)-1; - __pwcs++; - __s += r; - } - *__pwcs = 0; - return (size_t)(__pwcs - orig); -} - -size_t wcstombs (char *__s, const wchar_t *__pwcs, size_t __n) -{ - int r; - char *orig = __s; - if(!__s || !__pwcs || !*__pwcs) return 0; - while(*__pwcs && ((size_t)(__s - orig + 4) < __n)) { - r = wctomb(__s, *__pwcs); - if(r < 0) return (size_t)-1; - __pwcs++; - __s += r; - } - *__s = 0; - return (size_t)(__s - orig); -} - -void srand(unsigned int __seed) -{ - __srand_seed = __seed - 1; -} - -int rand() -{ - efi_guid_t rngGuid = EFI_RNG_PROTOCOL_GUID; - efi_rng_protocol_t *rng = NULL; - efi_status_t status; - int ret = 0; - - __srand_seed = 6364136223846793005ULL*__srand_seed + 1; - status = BS->LocateProtocol(&rngGuid, NULL, (void**)&rng); - if(!EFI_ERROR(status) && rng) - rng->GetRNG(rng, NULL, (uintn_t)sizeof(int), (uint8_t*)&ret); - ret ^= (int)(__srand_seed>>33); - return ret; -} - -uint8_t *getenv(char_t *name, uintn_t *len) -{ - efi_guid_t globGuid = EFI_GLOBAL_VARIABLE; - uint8_t tmp[EFI_MAXIMUM_VARIABLE_SIZE], *ret; - uint32_t attr; - efi_status_t status; -#ifndef UEFI_NO_UTF8 - wchar_t wcname[256]; - mbstowcs((wchar_t*)&wcname, name, 256); - status = RT->GetVariable((wchar_t*)&wcname, &globGuid, &attr, len, &tmp); -#else - status = RT->GetVariable(name, &globGuid, &attr, len, &tmp); -#endif - if(EFI_ERROR(status) || *len < 1 || !(ret = malloc((*len) + 1))) { - *len = 0; - return NULL; - } - memcpy(ret, tmp, *len); - ret[*len] = 0; - return ret; -} - -int setenv(char_t *name, uintn_t len, uint8_t *data) -{ - efi_guid_t globGuid = EFI_GLOBAL_VARIABLE; - efi_status_t status; -#ifndef UEFI_NO_UTF8 - wchar_t wcname[256]; - mbstowcs((wchar_t*)&wcname, name, 256); - status = RT->SetVariable(wcname, &globGuid, 0, len, data); -#else - status = RT->SetVariable(name, &globGuid, 0, len, data); -#endif - return !EFI_ERROR(status); -} diff --git a/Bootloader/Source/uefi/string.c b/Bootloader/Source/uefi/string.c deleted file mode 100644 index a6d0348..0000000 --- a/Bootloader/Source/uefi/string.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * string.c - * - * Copyright (C) 2021 bzt (bztsrc@gitlab) - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * This file is part of the POSIX-UEFI package. - * @brief Implementing functions which are defined in string.h - * - */ - -#include - -void *memcpy(void *dst, const void *src, size_t n) -{ - uint8_t *a=(uint8_t*)dst,*b=(uint8_t*)src; - if(src && dst && src != dst && n>0) { - while(n--) *a++ = *b++; - } - return dst; -} - -void *memmove(void *dst, const void *src, size_t n) -{ - uint8_t *a=(uint8_t*)dst,*b=(uint8_t*)src; - if(src && dst && src != dst && n>0) { - if(a>b && a0) *a--=*b--; - } else { - while(n--) *a++ = *b++; - } - } - return dst; -} - -void *memset(void *s, int c, size_t n) -{ - uint8_t *p=(uint8_t*)s; - if(s && n>0) { - while(n--) *p++ = (uint8_t)c; - } - return s; -} - -int memcmp(const void *s1, const void *s2, size_t n) -{ - uint8_t *a=(uint8_t*)s1,*b=(uint8_t*)s2; - if(s1 && s2 && s1 != s2 && n>0) { - while(n--) { - if(*a != *b) return *a - *b; - a++; b++; - } - } - return 0; -} - -void *memchr(const void *s, int c, size_t n) -{ - uint8_t *e, *p=(uint8_t*)s; - if(s && n>0) { - for(e=p+n; p0) { - for(e=p+n; p hl) return NULL; - hl -= nl - 1; - while(hl) { - if(!memcmp(c, needle, nl)) return c; - c++; hl--; - } - return NULL; -} - -void *memrmem(const void *haystack, size_t hl, const void *needle, size_t nl) -{ - uint8_t *c = (uint8_t*)haystack; - if(!haystack || !needle || !hl || !nl || nl > hl) return NULL; - hl -= nl; - c += hl; - while(hl) { - if(!memcmp(c, needle, nl)) return c; - c--; hl--; - } - return NULL; -} - -char_t *strcpy(char_t *dst, const char_t *src) -{ - char_t *s = dst; - if(src && dst && src != dst) { - while(*src) {*dst++=*src++;} *dst=0; - } - return s; -} - -char_t *strncpy(char_t *dst, const char_t *src, size_t n) -{ - char_t *s = dst; - const char_t *e = src+n; - if(src && dst && src != dst && n>0) { - while(*src && src0) { - dst += strlen(dst); - while(*src && src0) { - while(s1 - -static struct tm __tm; -time_t __mktime_efi(efi_time_t *t); - -/* from musl */ -static uint64_t __year_to_secs(uint64_t year, int *is_leap) -{ - int y, cycles, centuries, leaps, rem; - - if (year-2ULL <= 136) { - y = (int)year; - leaps = (y-68)>>2; - if (!((y-68)&3)) { - leaps--; - if (is_leap) *is_leap = 1; - } else if (is_leap) *is_leap = 0; - return 31536000ULL*(uint64_t)(y-70) + 86400ULL*(uint64_t)leaps; - } - - if (!is_leap) is_leap = &(int){0}; - cycles = (int)((year-100) / 400); - rem = (year-100) % 400; - if (rem < 0) { - cycles--; - rem += 400; - } - if (!rem) { - *is_leap = 1; - centuries = 0; - leaps = 0; - } else { - if (rem >= 200) { - if (rem >= 300) { centuries = 3; rem -= 300; } - else { centuries = 2; rem -= 200; } - } else { - if (rem >= 100) { centuries = 1; rem -= 100; } - else centuries = 0; - } - if (!rem) { - *is_leap = 0; - leaps = 0; - } else { - leaps = rem / 4; - rem %= 4; - *is_leap = !rem; - } - } - - leaps += 97*cycles + 24*centuries - *is_leap; - - return (uint64_t)(year-100) * 31536000ULL + (uint64_t)leaps * 86400ULL + 946684800ULL + 86400ULL; -} - -time_t __mktime_efi(efi_time_t *t) -{ - __tm.tm_year = t->Year + (/* workaround some buggy firmware*/ t->Year > 2000 ? -1900 : 98); - __tm.tm_mon = t->Month - 1; - __tm.tm_mday = t->Day; - __tm.tm_hour = t->Hour; - __tm.tm_min = t->Minute; - __tm.tm_sec = t->Second; - __tm.tm_isdst = t->Daylight; - return mktime(&__tm); -} - -/** - * This isn't POSIX, no arguments. Just returns the current time in struct tm - */ -struct tm *localtime (const time_t *__timer) -{ - efi_time_t t = {0}; - (void)__timer; - ST->RuntimeServices->GetTime(&t, NULL); - __mktime_efi(&t); - return &__tm; -} - -time_t mktime(const struct tm *tm) -{ - static const uint64_t secs_through_month[] = { - 0, 31*86400, 59*86400, 90*86400, - 120*86400, 151*86400, 181*86400, 212*86400, - 243*86400, 273*86400, 304*86400, 334*86400 }; - int is_leap; - uint64_t year = (uint64_t)tm->tm_year, t, adj; - int month = tm->tm_mon; - if (month >= 12 || month < 0) { - adj = (uint64_t)month / 12; - month %= 12; - if (month < 0) { - adj--; - month += 12; - } - year += adj; - } - t = __year_to_secs(year, &is_leap); - t += secs_through_month[month]; - if (is_leap && month >= 2) t += 86400; - t += 86400ULL * (uint64_t)(tm->tm_mday-1); - t += 3600ULL * (uint64_t)tm->tm_hour; - t += 60ULL * (uint64_t)tm->tm_min; - t += (uint64_t)tm->tm_sec; - return (time_t)t; -} - -time_t time(time_t *__timer) -{ - time_t ret; - efi_time_t t = {0}; - ST->RuntimeServices->GetTime(&t, NULL); - ret = __mktime_efi(&t); - if(__timer) *__timer = ret; - return ret; -} - diff --git a/Bootloader/Source/uefi/uefi.h b/Bootloader/Source/uefi/uefi.h index d46ed95..f229ba1 100644 --- a/Bootloader/Source/uefi/uefi.h +++ b/Bootloader/Source/uefi/uefi.h @@ -1,514 +1,56 @@ -/* - * uefi.h - * https://gitlab.com/bztsrc/posix-uefi - * - * Copyright (C) 2021 bzt (bztsrc@gitlab) - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * This file is part of the POSIX-UEFI package. - * @brief Main (and only) header file - * - */ +#pragma once -#ifndef _UEFI_H_ -#define _UEFI_H_ - -/*** configuration ***/ -/* #define UEFI_NO_UTF8 */ /* use wchar_t in your application */ -/* #define UEFI_NO_TRACK_ALLOC */ /* do not track allocated buffers' size */ -/*** configuration ends ***/ - -#ifdef __cplusplus -extern "C" { -#endif - -/* get these from the compiler or the efi headers, only define if we have neither */ -#if !defined(_STDINT_H) && !defined(_GCC_STDINT_H) && !defined(_EFI_INCLUDE_) -#define _STDINT_H -typedef char int8_t; -typedef unsigned char uint8_t; -typedef short int16_t; -typedef unsigned short uint16_t; -typedef int int32_t; -typedef unsigned int uint32_t; -#ifndef __clang__ -typedef long int int64_t; -typedef unsigned long int uint64_t; -typedef unsigned long int uintptr_t; -#else -typedef long long int64_t; -typedef unsigned long long uint64_t; -typedef unsigned long long uintptr_t; -#endif -#endif -extern char c_assert1[sizeof(uint32_t) == 4 ? 1 : -1]; -extern char c_assert2[sizeof(uint64_t) == 8 ? 1 : -1]; -extern char c_assert3[sizeof(uintptr_t) == 8 ? 1 : -1]; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; +typedef int int32_t; +typedef long long int64_t; +typedef uint64_t uintptr_t; +typedef int64_t intn_t; +typedef uint64_t uintn_t; +typedef uint8_t boolean_t; +typedef uint64_t efi_status_t; +typedef uint64_t efi_tpl_t; +typedef uint64_t efi_physical_address_t; +typedef uint64_t efi_virtual_address_t; +typedef void* efi_handle_t; +typedef void* efi_event_t; #ifndef NULL #define NULL ((void*)0) #endif -/*** common defines and typedefs ***/ -typedef int64_t intn_t; -typedef uint8_t boolean_t; + #ifndef __cplusplus typedef uint16_t wchar_t; #endif -typedef uint64_t uintn_t; -typedef uint64_t size_t; -typedef uint64_t time_t; -typedef uint64_t mode_t; -typedef uint64_t off_t; -typedef uint64_t blkcnt_t; -typedef uint64_t efi_status_t; -typedef uint64_t efi_tpl_t; -typedef uint64_t efi_lba_t; -typedef uint64_t efi_physical_address_t; -typedef uint64_t efi_virtual_address_t; -typedef void *efi_handle_t; -typedef void *efi_event_t; -#ifndef UEFI_NO_UTF8 -typedef char char_t; -#define CL(a) a -extern char *__argvutf8; -#else -typedef wchar_t char_t; -#define CL(a) L ## a -#endif - -typedef struct { - uint32_t Data1; - uint16_t Data2; - uint16_t Data3; - uint8_t Data4[8]; -} efi_guid_t; - -typedef struct { - uint8_t Type; - uint8_t SubType; - uint8_t Length[2]; -} efi_device_path_t; - -typedef struct { - uint32_t Type; - uint32_t Pad; - efi_physical_address_t PhysicalStart; - efi_virtual_address_t VirtualStart; - uint64_t NumberOfPages; - uint64_t Attribute; -} efi_memory_descriptor_t; - -typedef struct { - uint64_t Signature; - uint32_t Revision; - uint32_t HeaderSize; - uint32_t CRC32; - uint32_t Reserved; -} efi_table_header_t; - -/*** definitions only needed when efi.h (either from EDK II or gnu-efi) is NOT included ***/ - -#ifndef EFI_SPECIFICATION_MAJOR_REVISION - -/* efibind.h */ -#ifndef __WCHAR_TYPE__ -# define __WCHAR_TYPE__ short -#endif -#define EFIERR(a) (0x8000000000000000 | (unsigned int)(a)) -#define EFI_ERROR_MASK 0x8000000000000000 -#define EFIERR_OEM(a) (0xc000000000000000 | (unsigned int)(a)) - -#define BAD_POINTER 0xFBFBFBFBFBFBFBFB -#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF - -#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) -#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) -#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((uint64_t)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) #ifndef EFIAPI -# ifdef _MSC_EXTENSIONS -# define EFIAPI __cdecl -# elif defined(HAVE_USE_MS_ABI) -# define EFIAPI __attribute__((ms_abi)) -# else -# define EFIAPI -# endif +#define EFIAPI #endif -/* efistdarg.h */ -typedef __builtin_va_list va_list; -#define va_start(v,l) __builtin_va_start(v,l) -#define va_end(v) __builtin_va_end(v) -#define va_arg(v,l) __builtin_va_arg(v,l) -#define va_copy(d,s) __builtin_va_copy(d,s) +#define EFIERR(value) (0x8000000000000000ULL | (uint32_t)(value)) +#define EFI_ERROR(status) (((intn_t)(status)) < 0) -/* efierr.h */ -#define EFIWARN(a) (a) -#define EFI_ERROR(a) (((intn_t) a) < 0) -#define EFI_SUCCESS 0 -#define EFI_LOAD_ERROR EFIERR(1) -#define EFI_INVALID_PARAMETER EFIERR(2) -#define EFI_UNSUPPORTED EFIERR(3) -#define EFI_BAD_BUFFER_SIZE EFIERR(4) -#define EFI_BUFFER_TOO_SMALL EFIERR(5) -#define EFI_NOT_READY EFIERR(6) -#define EFI_DEVICE_ERROR EFIERR(7) -#define EFI_WRITE_PROTECTED EFIERR(8) -#define EFI_OUT_OF_RESOURCES EFIERR(9) -#define EFI_VOLUME_CORRUPTED EFIERR(10) -#define EFI_VOLUME_FULL EFIERR(11) -#define EFI_NO_MEDIA EFIERR(12) -#define EFI_MEDIA_CHANGED EFIERR(13) -#define EFI_NOT_FOUND EFIERR(14) -#define EFI_ACCESS_DENIED EFIERR(15) -#define EFI_NO_RESPONSE EFIERR(16) -#define EFI_NO_MAPPING EFIERR(17) -#define EFI_TIMEOUT EFIERR(18) -#define EFI_NOT_STARTED EFIERR(19) -#define EFI_ALREADY_STARTED EFIERR(20) -#define EFI_ABORTED EFIERR(21) -#define EFI_ICMP_ERROR EFIERR(22) -#define EFI_TFTP_ERROR EFIERR(23) -#define EFI_PROTOCOL_ERROR EFIERR(24) -#define EFI_INCOMPATIBLE_VERSION EFIERR(25) -#define EFI_SECURITY_VIOLATION EFIERR(26) -#define EFI_CRC_ERROR EFIERR(27) -#define EFI_END_OF_MEDIA EFIERR(28) -#define EFI_END_OF_FILE EFIERR(31) -#define EFI_INVALID_LANGUAGE EFIERR(32) -#define EFI_COMPROMISED_DATA EFIERR(33) +#define EFI_SUCCESS 0 +#define EFI_LOAD_ERROR EFIERR(1) +#define EFI_UNSUPPORTED EFIERR(3) +#define EFI_BUFFER_TOO_SMALL EFIERR(5) +#define EFI_ABORTED EFIERR(21) -#define EFI_WARN_UNKOWN_GLYPH EFIWARN(1) -#define EFI_WARN_UNKNOWN_GLYPH EFIWARN(1) -#define EFI_WARN_DELETE_FAILURE EFIWARN(2) -#define EFI_WARN_WRITE_FAILURE EFIWARN(3) -#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN(4) +#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002 +#define EFI_FILE_MODE_READ 0x0000000000000001ULL -/* efisetjmp.h */ -#ifdef __x86_64__ -typedef struct { - uint64_t Rbx; - uint64_t Rsp; - uint64_t Rbp; - uint64_t Rdi; - uint64_t Rsi; - uint64_t R12; - uint64_t R13; - uint64_t R14; - uint64_t R15; - uint64_t Rip; - uint64_t MxCsr; - uint8_t XmmBuffer[160]; -} __attribute__((aligned(8))) jmp_buf[1]; -#endif -#ifdef __aarch64__ -typedef struct { - uint64_t X19; - uint64_t X20; - uint64_t X21; - uint64_t X22; - uint64_t X23; - uint64_t X24; - uint64_t X25; - uint64_t X26; - uint64_t X27; - uint64_t X28; - uint64_t FP; - uint64_t LR; - uint64_t IP0; - uint64_t reserved; - uint64_t D8; - uint64_t D9; - uint64_t D10; - uint64_t D11; - uint64_t D12; - uint64_t D13; - uint64_t D14; - uint64_t D15; -} __attribute__((aligned(8))) jmp_buf[1]; -#endif -#if defined(__riscv) && __riscv_xlen == 64 -typedef struct { - uint64_t pc; - uint64_t sp; - uint64_t regs[12]; - double fp[12]; -} __attribute__((aligned(8))) jmp_buf[1]; -#endif -extern uintn_t setjmp(jmp_buf env) __attribute__((returns_twice)); -extern void longjmp(jmp_buf env, uintn_t value) __attribute__((noreturn)); +#define EFI_LOADED_IMAGE_PROTOCOL_GUID \ + {0x5B1B31A1, 0x9562, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}} +#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ + {0x964e5b22, 0x6459, 0x11d2, {0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} +#define EFI_FILE_INFO_GUID \ + {0x09576e92, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} +#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \ + {0x9042a9de, 0x23dc, 0x4a38, {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a}} -/* efidevp.h */ -#define EFI_DEVICE_PATH_PROTOCOL_GUID { 0x9576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } -#define EFI_DP_TYPE_MASK 0x7F -#define EFI_DP_TYPE_UNPACKED 0x80 -#define END_DEVICE_PATH_TYPE 0x7f -#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff -#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01 -#define END_DEVICE_PATH_LENGTH (sizeof(efi_device_path_t)) -#define DP_IS_END_TYPE(a) -#define DP_IS_END_SUBTYPE(a) ( ((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE ) -#define DevicePathType(a) ( ((a)->Type) & EFI_DP_TYPE_MASK ) -#define DevicePathSubType(a) ( (a)->SubType ) -#define DevicePathNodeLength(a) ( ((a)->Length[0]) | ((a)->Length[1] << 8) ) -#define NextDevicePathNode(a) ( (efi_device_path_t *) ( ((uint8_t *) (a)) + DevicePathNodeLength(a))) -#define IsDevicePathEndType(a) ( DevicePathType(a) == END_DEVICE_PATH_TYPE ) -#define IsDevicePathEndSubType(a) ( (a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE ) -#define IsDevicePathEnd(a) ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) ) -#define IsDevicePathUnpacked(a) ( (a)->Type & EFI_DP_TYPE_UNPACKED ) -#define SetDevicePathNodeLength(a,l) { \ - (a)->Length[0] = (uint8_t) (l); \ - (a)->Length[1] = (uint8_t) ((l) >> 8); \ - } -#define SetDevicePathEndNode(a) { \ - (a)->Type = END_DEVICE_PATH_TYPE; \ - (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; \ - (a)->Length[0] = sizeof(efi_device_path_t); \ - (a)->Length[1] = 0; \ - } - -/* efiapi.h */ -#define EFI_SPECIFICATION_MAJOR_REVISION 1 -#define EFI_SPECIFICATION_MINOR_REVISION 02 - -#define TPL_APPLICATION 4 -#define TPL_CALLBACK 8 -#define TPL_NOTIFY 16 -#define TPL_HIGH_LEVEL 31 -#define EFI_TPL_APPLICATION TPL_APPLICATION -#define EFI_TPL_CALLBACK TPL_CALLBACK -#define EFI_TPL_NOTIFY TPL_NOTIFY -#define EFI_TPL_HIGH_LEVEL TPL_HIGH_LEVEL - -#define NextMemoryDescriptor(Ptr,Size) ((efi_memory_descriptor_t *) (((uint8_t *) Ptr) + Size)) - -#define EFI_PAGE_SIZE 4096 -#define EFI_PAGE_MASK 0xFFF -#define EFI_PAGE_SHIFT 12 - -#define EFI_SIZE_TO_PAGES(a) ( ((a) >> EFI_PAGE_SHIFT) + ((a) & EFI_PAGE_MASK ? 1 : 0) ) - -#define EFI_MEMORY_UC 0x0000000000000001 -#define EFI_MEMORY_WC 0x0000000000000002 -#define EFI_MEMORY_WT 0x0000000000000004 -#define EFI_MEMORY_WB 0x0000000000000008 -#define EFI_MEMORY_UCE 0x0000000000000010 -#define EFI_MEMORY_WP 0x0000000000001000 -#define EFI_MEMORY_RP 0x0000000000002000 -#define EFI_MEMORY_XP 0x0000000000004000 -#define EFI_MEMORY_RUNTIME 0x8000000000000000 -#define EFI_MEMORY_DESCRIPTOR_VERSION 1 - -#define EVT_TIMER 0x80000000 -#define EVT_RUNTIME 0x40000000 -#define EVT_RUNTIME_CONTEXT 0x20000000 - -#define EVT_NOTIFY_WAIT 0x00000100 -#define EVT_NOTIFY_SIGNAL 0x00000200 - -#define EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201 -#define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202 - -#define EVT_EFI_SIGNAL_MASK 0x000000FF -#define EVT_EFI_SIGNAL_MAX 4 - -#define EFI_EVENT_TIMER EVT_TIMER -#define EFI_EVENT_RUNTIME EVT_RUNTIME -#define EFI_EVENT_RUNTIME_CONTEXT EVT_RUNTIME_CONTEXT -#define EFI_EVENT_NOTIFY_WAIT EVT_NOTIFY_WAIT -#define EFI_EVENT_NOTIFY_SIGNAL EVT_NOTIFY_SIGNAL -#define EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES EVT_SIGNAL_EXIT_BOOT_SERVICES -#define EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE -#define EFI_EVENT_EFI_SIGNAL_MASK EVT_EFI_SIGNAL_MASK -#define EFI_EVENT_EFI_SIGNAL_MAX EVT_EFI_SIGNAL_MAX - -#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 -#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002 -#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004 -#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008 -#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 -#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020 - -#define EFI_OPTIONAL_PTR 0x00000001 -#define EFI_INTERNAL_FNC 0x00000002 -#define EFI_INTERNAL_PTR 0x00000004 - -#define EFI_GLOBAL_VARIABLE { 0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C} } -#define EFI_VARIABLE_NON_VOLATILE 0x00000001 -#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 -#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 -#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008 -#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010 -#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020 -#define EFI_VARIABLE_APPEND_WRITE 0x00000040 -#define EFI_MAXIMUM_VARIABLE_SIZE 1024 - -#define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000 -#define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000 -#define CAPSULE_FLAGS_INITIATE_RESET 0x00040000 - -#define MPS_TABLE_GUID { 0xeb9d2d2f, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } -#define ACPI_TABLE_GUID { 0xeb9d2d30, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } -#define ACPI_20_TABLE_GUID { 0x8868e871, 0xe4f1, 0x11d3, {0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81} } -#define SMBIOS_TABLE_GUID { 0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } -#define SMBIOS3_TABLE_GUID { 0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e,0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94} } -#define SAL_SYSTEM_TABLE_GUID { 0xeb9d2d32, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } - -#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552 -#define EFI_RUNTIME_SERVICES_REVISION (EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION) - -#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42 -#define EFI_BOOT_SERVICES_REVISION (EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION) - -#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249 -#define EFI_SYSTEM_TABLE_REVISION (EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION) - -/* eficon.h */ -#define EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID { 0x387477c2, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } -#define EFI_BLACK 0x00 -#define EFI_BLUE 0x01 -#define EFI_GREEN 0x02 -#define EFI_CYAN (EFI_BLUE | EFI_GREEN) -#define EFI_RED 0x04 -#define EFI_MAGENTA (EFI_BLUE | EFI_RED) -#define EFI_BROWN (EFI_GREEN | EFI_RED) -#define EFI_LIGHTGRAY (EFI_BLUE | EFI_GREEN | EFI_RED) -#define EFI_BRIGHT 0x08 -#define EFI_DARKGRAY (EFI_BRIGHT) -#define EFI_LIGHTBLUE (EFI_BLUE | EFI_BRIGHT) -#define EFI_LIGHTGREEN (EFI_GREEN | EFI_BRIGHT) -#define EFI_LIGHTCYAN (EFI_CYAN | EFI_BRIGHT) -#define EFI_LIGHTRED (EFI_RED | EFI_BRIGHT) -#define EFI_LIGHTMAGENTA (EFI_MAGENTA | EFI_BRIGHT) -#define EFI_YELLOW (EFI_BROWN | EFI_BRIGHT) -#define EFI_WHITE (EFI_BLUE | EFI_GREEN | EFI_RED | EFI_BRIGHT) -#define EFI_TEXT_ATTR(f,b) ((f) | ((b) << 4)) -#define EFI_BACKGROUND_BLACK 0x00 -#define EFI_BACKGROUND_BLUE 0x10 -#define EFI_BACKGROUND_GREEN 0x20 -#define EFI_BACKGROUND_CYAN (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN) -#define EFI_BACKGROUND_RED 0x40 -#define EFI_BACKGROUND_MAGENTA (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_RED) -#define EFI_BACKGROUND_BROWN (EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED) -#define EFI_BACKGROUND_LIGHTGRAY (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED) -#define BOXDRAW_HORIZONTAL 0x2500 -#define BOXDRAW_VERTICAL 0x2502 -#define BOXDRAW_DOWN_RIGHT 0x250c -#define BOXDRAW_DOWN_LEFT 0x2510 -#define BOXDRAW_UP_RIGHT 0x2514 -#define BOXDRAW_UP_LEFT 0x2518 -#define BOXDRAW_VERTICAL_RIGHT 0x251c -#define BOXDRAW_VERTICAL_LEFT 0x2524 -#define BOXDRAW_DOWN_HORIZONTAL 0x252c -#define BOXDRAW_UP_HORIZONTAL 0x2534 -#define BOXDRAW_VERTICAL_HORIZONTAL 0x253c -#define BOXDRAW_DOUBLE_HORIZONTAL 0x2550 -#define BOXDRAW_DOUBLE_VERTICAL 0x2551 -#define BOXDRAW_DOWN_RIGHT_DOUBLE 0x2552 -#define BOXDRAW_DOWN_DOUBLE_RIGHT 0x2553 -#define BOXDRAW_DOUBLE_DOWN_RIGHT 0x2554 -#define BOXDRAW_DOWN_LEFT_DOUBLE 0x2555 -#define BOXDRAW_DOWN_DOUBLE_LEFT 0x2556 -#define BOXDRAW_DOUBLE_DOWN_LEFT 0x2557 -#define BOXDRAW_UP_RIGHT_DOUBLE 0x2558 -#define BOXDRAW_UP_DOUBLE_RIGHT 0x2559 -#define BOXDRAW_DOUBLE_UP_RIGHT 0x255a -#define BOXDRAW_UP_LEFT_DOUBLE 0x255b -#define BOXDRAW_UP_DOUBLE_LEFT 0x255c -#define BOXDRAW_DOUBLE_UP_LEFT 0x255d -#define BOXDRAW_VERTICAL_RIGHT_DOUBLE 0x255e -#define BOXDRAW_VERTICAL_DOUBLE_RIGHT 0x255f -#define BOXDRAW_DOUBLE_VERTICAL_RIGHT 0x2560 -#define BOXDRAW_VERTICAL_LEFT_DOUBLE 0x2561 -#define BOXDRAW_VERTICAL_DOUBLE_LEFT 0x2562 -#define BOXDRAW_DOUBLE_VERTICAL_LEFT 0x2563 -#define BOXDRAW_DOWN_HORIZONTAL_DOUBLE 0x2564 -#define BOXDRAW_DOWN_DOUBLE_HORIZONTAL 0x2565 -#define BOXDRAW_DOUBLE_DOWN_HORIZONTAL 0x2566 -#define BOXDRAW_UP_HORIZONTAL_DOUBLE 0x2567 -#define BOXDRAW_UP_DOUBLE_HORIZONTAL 0x2568 -#define BOXDRAW_DOUBLE_UP_HORIZONTAL 0x2569 -#define BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE 0x256a -#define BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL 0x256b -#define BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL 0x256c -#define BLOCKELEMENT_FULL_BLOCK 0x2588 -#define BLOCKELEMENT_LIGHT_SHADE 0x2591 -#define GEOMETRICSHAPE_UP_TRIANGLE 0x25b2 -#define GEOMETRICSHAPE_RIGHT_TRIANGLE 0x25ba -#define GEOMETRICSHAPE_DOWN_TRIANGLE 0x25bc -#define GEOMETRICSHAPE_LEFT_TRIANGLE 0x25c4 -#define ARROW_UP 0x2191 -#define ARROW_DOWN 0x2193 - -#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID { 0x387477c1, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } -#define CHAR_NULL 0x0000 -#define CHAR_BACKSPACE 0x0008 -#define CHAR_TAB 0x0009 -#define CHAR_LINEFEED 0x000A -#define CHAR_CARRIAGE_RETURN 0x000D -#define SCAN_NULL 0x0000 -#define SCAN_UP 0x0001 -#define SCAN_DOWN 0x0002 -#define SCAN_RIGHT 0x0003 -#define SCAN_LEFT 0x0004 -#define SCAN_HOME 0x0005 -#define SCAN_END 0x0006 -#define SCAN_INSERT 0x0007 -#define SCAN_DELETE 0x0008 -#define SCAN_PAGE_UP 0x0009 -#define SCAN_PAGE_DOWN 0x000A -#define SCAN_F1 0x000B -#define SCAN_F2 0x000C -#define SCAN_F3 0x000D -#define SCAN_F4 0x000E -#define SCAN_F5 0x000F -#define SCAN_F6 0x0010 -#define SCAN_F7 0x0011 -#define SCAN_F8 0x0012 -#define SCAN_F9 0x0013 -#define SCAN_F10 0x0014 -#define SCAN_F11 0x0015 -#define SCAN_F12 0x0016 -#define SCAN_ESC 0x0017 - -/* efigpt.h */ -#define PRIMARY_PART_HEADER_LBA 1 -#define EFI_PTAB_HEADER_ID "EFI PART" -#define EFI_PART_USED_BY_EFI 0x0000000000000001 -#define EFI_PART_REQUIRED_TO_FUNCTION 0x0000000000000002 -#define EFI_PART_USED_BY_OS 0x0000000000000004 -#define EFI_PART_REQUIRED_BY_OS 0x0000000000000008 -#define EFI_PART_BACKUP_REQUIRED 0x0000000000000010 -#define EFI_PART_USER_DATA 0x0000000000000020 -#define EFI_PART_CRITICAL_USER_DATA 0x0000000000000040 -#define EFI_PART_REDUNDANT_PARTITION 0x0000000000000080 -#define EFI_PART_TYPE_UNUSED_GUID { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} } -#define EFI_PART_TYPE_EFI_SYSTEM_PART_GUID { 0xc12a7328, 0xf81f, 0x11d2, {0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b} } -#define EFI_PART_TYPE_LEGACY_MBR_GUID { 0x024dee41, 0x33e7, 0x11d3, {0x9d, 0x69, 0x00, 0x08, 0xc7, 0x81, 0xf3, 0x9f} } - -/* Protocol GUIDs */ -#ifndef INTERNAL_SHELL_GUID -#define INTERNAL_SHELL_GUID { 0xd65a6b8c, 0x71e5, 0x4df0, {0xa9, 0x09, 0xf0, 0xd2, 0x99, 0x2b, 0x5a, 0xa9} } -#endif +#define FILENAME_MAX 262 typedef enum { AllocateAnyPages, @@ -537,13 +79,6 @@ typedef enum { EfiMaxMemoryType } efi_memory_type_t; -typedef enum { - TimerCancel, - TimerPeriodic, - TimerRelative, - TimerTypeMax -} efi_timer_delay_t; - typedef enum { AllHandles, ByRegisterNotify, @@ -551,896 +86,313 @@ typedef enum { } efi_locate_search_type_t; typedef enum { - EfiResetCold, - EfiResetWarm, - EfiResetShutdown -} efi_reset_type_t; - -#else - -#define efi_allocate_type_t EFI_ALLOCATE_TYPE -#define efi_memory_type_t EFI_MEMORY_TYPE -#define efi_timer_delay_t EFI_TIMER_DELAY -#define efi_locate_search_type_t EFI_LOCATE_SEARCH_TYPE -#define efi_reset_type_t EFI_RESET_TYPE - -#endif - -/*** standard input, output and error streams via ConIn, ConOut and StdErr ***/ -typedef struct { - uint16_t ScanCode; - wchar_t UnicodeChar; -} efi_input_key_t; - -typedef efi_status_t (EFIAPI *efi_input_reset_t)(void *This, boolean_t ExtendedVerification); -typedef efi_status_t (EFIAPI *efi_input_read_key_t)(void *This, efi_input_key_t *Key); + PixelRedGreenBlueReserved8BitPerColor, + PixelBlueGreenRedReserved8BitPerColor, + PixelBitMask, + PixelBltOnly, + PixelFormatMax +} efi_gop_pixel_format_t; typedef struct { - efi_input_reset_t Reset; - efi_input_read_key_t ReadKeyStroke; - efi_event_t WaitForKey; -} simple_input_interface_t; - -typedef efi_status_t (EFIAPI *efi_text_reset_t)(void *This, boolean_t ExtendedVerification); -typedef efi_status_t (EFIAPI *efi_text_output_string_t)(void *This, wchar_t *String); -typedef efi_status_t (EFIAPI *efi_text_test_string_t)(void *This, wchar_t *String); -typedef efi_status_t (EFIAPI *efi_text_query_mode_t)(void *This, uintn_t ModeNumber, uintn_t *Column, uintn_t *Row); -typedef efi_status_t (EFIAPI *efi_text_set_mode_t)(void *This, uintn_t ModeNumber); -typedef efi_status_t (EFIAPI *efi_text_set_attribute_t)(void *This, uintn_t Attribute); -typedef efi_status_t (EFIAPI *efi_text_clear_screen_t)(void *This); -typedef efi_status_t (EFIAPI *efi_text_set_cursor_t)(void *This, uintn_t Column, uintn_t Row); -typedef efi_status_t (EFIAPI *efi_text_enable_cursor_t)(void *This, boolean_t Enable); + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + uint8_t Data4[8]; +} efi_guid_t; typedef struct { - int32_t MaxMode; - int32_t Mode; - int32_t Attribute; - int32_t CursorColumn; - int32_t CursorRow; - boolean_t CursorVisible; -} simple_text_output_mode_t; + uint8_t Type; + uint8_t SubType; + uint8_t Length[2]; +} efi_device_path_t; typedef struct { - efi_text_reset_t Reset; - efi_text_output_string_t OutputString; - efi_text_test_string_t TestString; - efi_text_query_mode_t QueryMode; - efi_text_set_mode_t SetMode; - efi_text_set_attribute_t SetAttribute; - efi_text_clear_screen_t ClearScreen; - efi_text_set_cursor_t SetCursorPosition; - efi_text_enable_cursor_t EnableCursor; - simple_text_output_mode_t *Mode; -} simple_text_output_interface_t; + uint32_t Type; + uint32_t Pad; + efi_physical_address_t PhysicalStart; + efi_virtual_address_t VirtualStart; + uint64_t NumberOfPages; + uint64_t Attribute; +} efi_memory_descriptor_t; -/*** Runtime Services ***/ typedef struct { - uint16_t Year; /* 1998 - 2XXX */ - uint8_t Month; /* 1 - 12 */ - uint8_t Day; /* 1 - 31 */ - uint8_t Hour; /* 0 - 23 */ - uint8_t Minute; /* 0 - 59 */ - uint8_t Second; /* 0 - 59 */ - uint8_t Pad1; - uint32_t Nanosecond; /* 0 - 999,999,999 */ - int16_t TimeZone; /* -1440 to 1440 or 2047 */ - uint8_t Daylight; - uint8_t Pad2; + uint64_t Signature; + uint32_t Revision; + uint32_t HeaderSize; + uint32_t CRC32; + uint32_t Reserved; +} efi_table_header_t; + +typedef struct { + uint16_t Year; + uint8_t Month; + uint8_t Day; + uint8_t Hour; + uint8_t Minute; + uint8_t Second; + uint8_t Pad1; + uint32_t Nanosecond; + short TimeZone; + uint8_t Daylight; + uint8_t Pad2; } efi_time_t; typedef struct { - uint32_t Resolution; - uint32_t Accuracy; - boolean_t SetsToZero; -} efi_time_capabilities_t; + uint16_t ScanCode; + wchar_t UnicodeChar; +} efi_input_key_t; typedef struct { - efi_guid_t CapsuleGuid; - uint32_t HeaderSize; - uint32_t Flags; - uint32_t CapsuleImageSize; -} efi_capsule_header_t; + int32_t MaxMode; + int32_t Mode; + int32_t Attribute; + int32_t CursorColumn; + int32_t CursorRow; + boolean_t CursorVisible; +} simple_text_output_mode_t; -#ifndef DataBlock -#define DataBlock ContinuationPointer -#endif -typedef struct { - uint64_t Length; - efi_physical_address_t ContinuationPointer; -} efi_capsule_block_descriptor_t; - -typedef efi_status_t (EFIAPI *efi_get_time_t)(efi_time_t *Time, efi_time_capabilities_t *Capabilities); -typedef efi_status_t (EFIAPI *efi_set_time_t)(efi_time_t *Time); -typedef efi_status_t (EFIAPI *efi_get_wakeup_time_t)(boolean_t *Enable, boolean_t *Pending, efi_time_t *Time); -typedef efi_status_t (EFIAPI *efi_set_wakeup_time_t)(boolean_t Enable, efi_time_t *Time); -typedef efi_status_t (EFIAPI *efi_set_virtual_address_map_t)(uintn_t MemoryMapSize, uintn_t DescriptorSize, - uint32_t DescriptorVersion, efi_memory_descriptor_t *VirtualMap); -typedef efi_status_t (EFIAPI *efi_convert_pointer_t)(uintn_t DebugDisposition, void **Address); -typedef efi_status_t (EFIAPI *efi_get_variable_t)(wchar_t *VariableName, efi_guid_t *VendorGuid, uint32_t *Attributes, - uintn_t *DataSize, void *Data); -typedef efi_status_t (EFIAPI *efi_get_next_variable_name_t)(uintn_t *VariableNameSize, wchar_t *VariableName, - efi_guid_t *VendorGuid); -typedef efi_status_t (EFIAPI *efi_set_variable_t)(wchar_t *VariableName, efi_guid_t *VendorGuid, uint32_t Attributes, - uintn_t DataSize, void *Data); -typedef efi_status_t (EFIAPI *efi_get_next_high_mono_t)(uint64_t *Count); -typedef efi_status_t (EFIAPI *efi_reset_system_t)(efi_reset_type_t ResetType, efi_status_t ResetStatus, uintn_t DataSize, - wchar_t *ResetData); -typedef efi_status_t (EFIAPI *efi_update_capsule_t)(efi_capsule_header_t **CapsuleHeaderArray, uintn_t CapsuleCount, - efi_physical_address_t ScatterGatherList); -typedef efi_status_t (EFIAPI *efi_query_capsule_capabilities_t)(efi_capsule_header_t **CapsuleHeaderArray, uintn_t CapsuleCount, - uint64_t *MaximumCapsuleSize, efi_reset_type_t *ResetType); -typedef efi_status_t (EFIAPI *efi_query_variable_info_t)(uint32_t Attributes, uint64_t *MaximumVariableStorageSize, - uint64_t *RemainingVariableStorageSize, uint64_t *MaximumVariableSize); +typedef efi_status_t (EFIAPI *efi_input_reset_t)(void* this_ptr, boolean_t extended_verification); +typedef efi_status_t (EFIAPI *efi_input_read_key_t)(void* this_ptr, efi_input_key_t* key); +typedef efi_status_t (EFIAPI *efi_text_reset_t)(void* this_ptr, boolean_t extended_verification); +typedef efi_status_t (EFIAPI *efi_text_output_string_t)(void* this_ptr, wchar_t* string); +typedef efi_status_t (EFIAPI *efi_text_test_string_t)(void* this_ptr, wchar_t* string); +typedef efi_status_t (EFIAPI *efi_text_query_mode_t)(void* this_ptr, uintn_t mode_number, uintn_t* column, uintn_t* row); +typedef efi_status_t (EFIAPI *efi_text_set_mode_t)(void* this_ptr, uintn_t mode_number); +typedef efi_status_t (EFIAPI *efi_text_set_attribute_t)(void* this_ptr, uintn_t attribute); +typedef efi_status_t (EFIAPI *efi_text_clear_screen_t)(void* this_ptr); +typedef efi_status_t (EFIAPI *efi_text_set_cursor_t)(void* this_ptr, uintn_t column, uintn_t row); +typedef efi_status_t (EFIAPI *efi_text_enable_cursor_t)(void* this_ptr, boolean_t enable); typedef struct { - efi_table_header_t Hdr; + efi_input_reset_t Reset; + efi_input_read_key_t ReadKeyStroke; + efi_event_t WaitForKey; +} simple_input_interface_t; - efi_get_time_t GetTime; - efi_set_time_t SetTime; - efi_get_wakeup_time_t GetWakeupTime; - efi_set_wakeup_time_t SetWakeupTime; +typedef struct { + efi_text_reset_t Reset; + efi_text_output_string_t OutputString; + efi_text_test_string_t TestString; + efi_text_query_mode_t QueryMode; + efi_text_set_mode_t SetMode; + efi_text_set_attribute_t SetAttribute; + efi_text_clear_screen_t ClearScreen; + efi_text_set_cursor_t SetCursorPosition; + efi_text_enable_cursor_t EnableCursor; + simple_text_output_mode_t* Mode; +} simple_text_output_interface_t; - efi_set_virtual_address_map_t SetVirtualAddressMap; - efi_convert_pointer_t ConvertPointer; - - efi_get_variable_t GetVariable; - efi_get_next_variable_name_t GetNextVariableName; - efi_set_variable_t SetVariable; - - efi_get_next_high_mono_t GetNextHighMonotonicCount; - efi_reset_system_t ResetSystem; - - efi_update_capsule_t UpdateCapsule; - efi_query_capsule_capabilities_t QueryCapsuleCapabilities; - efi_query_variable_info_t QueryVariableInfo; +typedef struct efi_runtime_services_t { + efi_table_header_t Hdr; } efi_runtime_services_t; -extern efi_runtime_services_t *RT; -#define gRT RT -/** Boot Services ***/ typedef struct { - efi_handle_t AgentHandle; - efi_handle_t ControllerHandle; - uint32_t Attributes; - uint32_t OpenCount; + efi_handle_t AgentHandle; + efi_handle_t ControllerHandle; + uint32_t Attributes; + uint32_t OpenCount; } efi_open_protocol_information_entry_t; -typedef efi_tpl_t (EFIAPI *efi_raise_tpl_t)(efi_tpl_t NewTpl); -typedef efi_tpl_t (EFIAPI *efi_restore_tpl_t)(efi_tpl_t OldTpl); -typedef efi_status_t (EFIAPI *efi_allocate_pages_t)(efi_allocate_type_t Type, efi_memory_type_t MemoryType, - uintn_t NoPages, efi_physical_address_t *Memory); -typedef efi_status_t (EFIAPI *efi_free_pages_t)(efi_physical_address_t Memory, uintn_t NoPages); -typedef efi_status_t (EFIAPI *efi_get_memory_map_t)(uintn_t *MemoryMapSize, efi_memory_descriptor_t *MemoryMap, - uintn_t *MapKey, uintn_t *DescriptorSize, uint32_t *DescriptorVersion); -typedef efi_status_t (EFIAPI *efi_allocate_pool_t)(efi_memory_type_t PoolType, uintn_t Size, void **Buffer); -typedef efi_status_t (EFIAPI *efi_free_pool_t)(void *Buffer); -typedef void (EFIAPI *efi_event_notify_t)(efi_event_t Event, void *Context); -typedef efi_status_t (EFIAPI *efi_create_event_t)(uint32_t Type, efi_tpl_t NotifyTpl, efi_event_notify_t NotifyFunction, - void *NextContext, efi_event_t *Event); -typedef efi_status_t (EFIAPI *efi_set_timer_t)(efi_event_t Event, efi_timer_delay_t Type, uint64_t TriggerTime); -typedef efi_status_t (EFIAPI *efi_wait_for_event_t)(uintn_t NumberOfEvents, efi_event_t *Event, uintn_t *Index); -typedef efi_status_t (EFIAPI *efi_signal_event_t)(efi_event_t Event); -typedef efi_status_t (EFIAPI *efi_close_event_t)(efi_event_t Event); -typedef efi_status_t (EFIAPI *efi_check_event_t)(efi_event_t Event); -typedef efi_status_t (EFIAPI *efi_handle_protocol_t)(efi_handle_t Handle, efi_guid_t *Protocol, void **Interface); -typedef efi_status_t (EFIAPI *efi_register_protocol_notify_t)(efi_guid_t *Protocol, efi_event_t Event, void **Registration); -typedef efi_status_t (EFIAPI *efi_locate_handle_t)(efi_locate_search_type_t SearchType, efi_guid_t *Protocol, - void *SearchKey, uintn_t *BufferSize, efi_handle_t *Buffer); -typedef efi_status_t (EFIAPI *efi_locate_device_path_t)(efi_guid_t *Protocol, efi_device_path_t **DevicePath, - efi_handle_t *Device); -typedef efi_status_t (EFIAPI *efi_install_configuration_table_t)(efi_guid_t *Guid, void *Table); -typedef efi_status_t (EFIAPI *efi_image_load_t)(boolean_t BootPolicy, efi_handle_t ParentImageHandle, efi_device_path_t *FilePath, - void *SourceBuffer, uintn_t SourceSize, efi_handle_t *ImageHandle); -typedef efi_status_t (EFIAPI *efi_image_start_t)(efi_handle_t ImageHandle, uintn_t *ExitDataSize, wchar_t **ExitData); -typedef efi_status_t (EFIAPI *efi_exit_t)(efi_handle_t ImageHandle, efi_status_t ExitStatus, uintn_t ExitDataSize, - wchar_t *ExitData); -typedef efi_status_t (EFIAPI *efi_exit_boot_services_t)(efi_handle_t ImageHandle, uintn_t MapKey); -typedef efi_status_t (EFIAPI *efi_get_next_monotonic_t)(uint64_t *Count); -typedef efi_status_t (EFIAPI *efi_stall_t)(uintn_t Microseconds); -typedef efi_status_t (EFIAPI *efi_set_watchdog_timer_t)(uintn_t Timeout, uint64_t WatchdogCode, uintn_t DataSize, - wchar_t *WatchdogData); -typedef efi_status_t (EFIAPI *efi_connect_controller_t)(efi_handle_t ControllerHandle, efi_handle_t *DriverImageHandle, - efi_device_path_t *RemainingDevicePath, boolean_t Recursive); -typedef efi_status_t (EFIAPI *efi_disconnect_controller_t)(efi_handle_t ControllerHandle, efi_handle_t DriverImageHandle, - efi_handle_t ChildHandle); -typedef efi_status_t (EFIAPI *efi_open_protocol_t)(efi_handle_t Handle, efi_guid_t *Protocol, void **Interface, - efi_handle_t AgentHandle, efi_handle_t ControllerHandle, uint32_t Attributes); -typedef efi_status_t (EFIAPI *efi_close_protocol_t)(efi_handle_t Handle, efi_guid_t *Protocol, efi_handle_t AgentHandle, - efi_handle_t ControllerHandle); -typedef efi_status_t (EFIAPI *efi_open_protocol_information_t)(efi_handle_t Handle, efi_guid_t *Protocol, - efi_open_protocol_information_entry_t**EntryBuffer, uintn_t *EntryCount); -typedef efi_status_t (EFIAPI *efi_protocols_per_handle_t)(efi_handle_t Handle, efi_guid_t ***ProtocolBuffer, - uintn_t *ProtocolBufferCount); -typedef efi_status_t (EFIAPI *efi_locate_handle_buffer_t)(efi_locate_search_type_t SearchType, efi_guid_t *Protocol, - void *SearchKey, uintn_t *NoHandles, efi_handle_t **Handles); -typedef efi_status_t (EFIAPI *efi_locate_protocol_t)(efi_guid_t *Protocol, void *Registration, void **Interface); -typedef efi_status_t (EFIAPI *efi_calculate_crc32_t)(void *Data, uintn_t DataSize, uint32_t *Crc32); +typedef efi_tpl_t (EFIAPI *efi_raise_tpl_t)(efi_tpl_t new_tpl); +typedef efi_tpl_t (EFIAPI *efi_restore_tpl_t)(efi_tpl_t old_tpl); +typedef efi_status_t (EFIAPI *efi_allocate_pages_t)(efi_allocate_type_t type, efi_memory_type_t memory_type, uintn_t pages, efi_physical_address_t* memory); +typedef efi_status_t (EFIAPI *efi_free_pages_t)(efi_physical_address_t memory, uintn_t pages); +typedef efi_status_t (EFIAPI *efi_get_memory_map_t)(uintn_t* memory_map_size, efi_memory_descriptor_t* memory_map, uintn_t* map_key, uintn_t* descriptor_size, uint32_t* descriptor_version); +typedef efi_status_t (EFIAPI *efi_allocate_pool_t)(efi_memory_type_t pool_type, uintn_t size, void** buffer); +typedef efi_status_t (EFIAPI *efi_free_pool_t)(void* buffer); +typedef void (EFIAPI *efi_event_notify_t)(efi_event_t event, void* context); +typedef efi_status_t (EFIAPI *efi_create_event_t)(uint32_t type, efi_tpl_t notify_tpl, efi_event_notify_t notify_function, void* context, efi_event_t* event); +typedef efi_status_t (EFIAPI *efi_set_timer_t)(efi_event_t event, uint32_t type, uint64_t trigger_time); +typedef efi_status_t (EFIAPI *efi_wait_for_event_t)(uintn_t number_of_events, efi_event_t* event, uintn_t* index); +typedef efi_status_t (EFIAPI *efi_signal_event_t)(efi_event_t event); +typedef efi_status_t (EFIAPI *efi_close_event_t)(efi_event_t event); +typedef efi_status_t (EFIAPI *efi_check_event_t)(efi_event_t event); +typedef efi_status_t (EFIAPI *efi_handle_protocol_t)(efi_handle_t handle, efi_guid_t* protocol, void** interface); +typedef efi_status_t (EFIAPI *efi_register_protocol_notify_t)(efi_guid_t* protocol, efi_event_t event, void** registration); +typedef efi_status_t (EFIAPI *efi_locate_handle_t)(efi_locate_search_type_t search_type, efi_guid_t* protocol, void* search_key, uintn_t* buffer_size, efi_handle_t* buffer); +typedef efi_status_t (EFIAPI *efi_locate_device_path_t)(efi_guid_t* protocol, efi_device_path_t** device_path, efi_handle_t* device); +typedef efi_status_t (EFIAPI *efi_install_configuration_table_t)(efi_guid_t* guid, void* table); +typedef efi_status_t (EFIAPI *efi_image_load_t)(boolean_t boot_policy, efi_handle_t parent_image_handle, efi_device_path_t* file_path, void* source_buffer, uintn_t source_size, efi_handle_t* image_handle); +typedef efi_status_t (EFIAPI *efi_image_start_t)(efi_handle_t image_handle, uintn_t* exit_data_size, wchar_t** exit_data); +typedef efi_status_t (EFIAPI *efi_exit_t)(efi_handle_t image_handle, efi_status_t exit_status, uintn_t exit_data_size, wchar_t* exit_data); +typedef efi_status_t (EFIAPI *efi_exit_boot_services_t)(efi_handle_t image_handle, uintn_t map_key); +typedef efi_status_t (EFIAPI *efi_get_next_monotonic_t)(uint64_t* count); +typedef efi_status_t (EFIAPI *efi_stall_t)(uintn_t microseconds); +typedef efi_status_t (EFIAPI *efi_set_watchdog_timer_t)(uintn_t timeout, uint64_t watchdog_code, uintn_t data_size, wchar_t* watchdog_data); +typedef efi_status_t (EFIAPI *efi_connect_controller_t)(efi_handle_t controller_handle, efi_handle_t* driver_image_handle, efi_device_path_t* remaining_device_path, boolean_t recursive); +typedef efi_status_t (EFIAPI *efi_disconnect_controller_t)(efi_handle_t controller_handle, efi_handle_t driver_image_handle, efi_handle_t child_handle); +typedef efi_status_t (EFIAPI *efi_open_protocol_t)(efi_handle_t handle, efi_guid_t* protocol, void** interface, efi_handle_t agent_handle, efi_handle_t controller_handle, uint32_t attributes); +typedef efi_status_t (EFIAPI *efi_close_protocol_t)(efi_handle_t handle, efi_guid_t* protocol, efi_handle_t agent_handle, efi_handle_t controller_handle); +typedef efi_status_t (EFIAPI *efi_open_protocol_information_t)(efi_handle_t handle, efi_guid_t* protocol, efi_open_protocol_information_entry_t** entry_buffer, uintn_t* entry_count); +typedef efi_status_t (EFIAPI *efi_protocols_per_handle_t)(efi_handle_t handle, efi_guid_t*** protocol_buffer, uintn_t* protocol_buffer_count); +typedef efi_status_t (EFIAPI *efi_locate_handle_buffer_t)(efi_locate_search_type_t search_type, efi_guid_t* protocol, void* search_key, uintn_t* handle_count, efi_handle_t** handles); +typedef efi_status_t (EFIAPI *efi_locate_protocol_t)(efi_guid_t* protocol, void* registration, void** interface); +typedef efi_status_t (EFIAPI *efi_calculate_crc32_t)(void* data, uintn_t data_size, uint32_t* crc32); typedef struct { - efi_table_header_t Hdr; - - efi_raise_tpl_t RaiseTPL; - efi_restore_tpl_t RestoreTPL; - - efi_allocate_pages_t AllocatePages; - efi_free_pages_t FreePages; - efi_get_memory_map_t GetMemoryMap; - efi_allocate_pool_t AllocatePool; - efi_free_pool_t FreePool; - - efi_create_event_t CreateEvent; - efi_set_timer_t SetTimer; - efi_wait_for_event_t WaitForEvent; - efi_signal_event_t SignalEvent; - efi_close_event_t CloseEvent; - efi_check_event_t CheckEvent; - - void* InstallProtocolInterface; /* not defined yet */ - void* ReinstallProtocolInterface; - void* UninstallProtocolInterface; - efi_handle_protocol_t HandleProtocol; - efi_handle_protocol_t PCHandleProtocol; + efi_table_header_t Hdr; + efi_raise_tpl_t RaiseTPL; + efi_restore_tpl_t RestoreTPL; + efi_allocate_pages_t AllocatePages; + efi_free_pages_t FreePages; + efi_get_memory_map_t GetMemoryMap; + efi_allocate_pool_t AllocatePool; + efi_free_pool_t FreePool; + efi_create_event_t CreateEvent; + efi_set_timer_t SetTimer; + efi_wait_for_event_t WaitForEvent; + efi_signal_event_t SignalEvent; + efi_close_event_t CloseEvent; + efi_check_event_t CheckEvent; + void* InstallProtocolInterface; + void* ReinstallProtocolInterface; + void* UninstallProtocolInterface; + efi_handle_protocol_t HandleProtocol; + efi_handle_protocol_t PCHandleProtocol; efi_register_protocol_notify_t RegisterProtocolNotify; - efi_locate_handle_t LocateHandle; - efi_locate_device_path_t LocateDevicePath; + efi_locate_handle_t LocateHandle; + efi_locate_device_path_t LocateDevicePath; efi_install_configuration_table_t InstallConfigurationTable; - - efi_image_load_t LoadImage; - efi_image_start_t StartImage; - efi_exit_t Exit; - void* UnloadImage; /* not defined in gnu-efi either */ - efi_exit_boot_services_t ExitBootServices; - - efi_get_next_monotonic_t GetNextHighMonotonicCount; - efi_stall_t Stall; - efi_set_watchdog_timer_t SetWatchdogTimer; - - efi_connect_controller_t ConnectController; + efi_image_load_t LoadImage; + efi_image_start_t StartImage; + efi_exit_t Exit; + void* UnloadImage; + efi_exit_boot_services_t ExitBootServices; + efi_get_next_monotonic_t GetNextHighMonotonicCount; + efi_stall_t Stall; + efi_set_watchdog_timer_t SetWatchdogTimer; + efi_connect_controller_t ConnectController; efi_disconnect_controller_t DisconnectController; - - efi_open_protocol_t OpenProtocol; - efi_close_protocol_t CloseProtocol; + efi_open_protocol_t OpenProtocol; + efi_close_protocol_t CloseProtocol; efi_open_protocol_information_t OpenProtocolInformation; - - efi_protocols_per_handle_t ProtocolsPerHandle; - efi_locate_handle_buffer_t LocateHandleBuffer; - efi_locate_protocol_t LocateProtocol; - void* InstallMultipleProtocolInterfaces; - void* UninstallMultipleProtocolInterfaces; - - efi_calculate_crc32_t CalculateCrc32; + efi_protocols_per_handle_t ProtocolsPerHandle; + efi_locate_handle_buffer_t LocateHandleBuffer; + efi_locate_protocol_t LocateProtocol; + void* InstallMultipleProtocolInterfaces; + void* UninstallMultipleProtocolInterfaces; + efi_calculate_crc32_t CalculateCrc32; } efi_boot_services_t; -extern efi_boot_services_t *BS; -#define gBS BS - -/*** Loaded Image Protocol ***/ -#ifndef EFI_LOADED_IMAGE_PROTOCOL_GUID -#define EFI_LOADED_IMAGE_PROTOCOL_GUID { 0x5B1B31A1, 0x9562, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B} } -#define LOADED_IMAGE_PROTOCOL EFI_LOADED_IMAGE_PROTOCOL_GUID - -#define EFI_LOADED_IMAGE_PROTOCOL_REVISION 0x1000 -#define EFI_IMAGE_INFORMATION_REVISION EFI_LOADED_IMAGE_PROTOCOL_REVISION -#endif typedef struct { - uint32_t Revision; - efi_handle_t ParentHandle; - void *SystemTable; - efi_handle_t DeviceHandle; - efi_device_path_t *FilePath; - void *Reserved; - uint32_t LoadOptionsSize; - void *LoadOptions; - void *ImageBase; - uint64_t ImageSize; - efi_memory_type_t ImageCodeType; - efi_memory_type_t ImageDataType; + uint32_t Revision; + efi_handle_t ParentHandle; + void* SystemTable; + efi_handle_t DeviceHandle; + efi_device_path_t* FilePath; + void* Reserved; + uint32_t LoadOptionsSize; + void* LoadOptions; + void* ImageBase; + uint64_t ImageSize; + efi_memory_type_t ImageCodeType; + efi_memory_type_t ImageDataType; } efi_loaded_image_protocol_t; -extern efi_loaded_image_protocol_t *LIP; -extern efi_handle_t IM; -/*** System Table ***/ typedef struct { - efi_guid_t VendorGuid; - void *VendorTable; + efi_guid_t VendorGuid; + void* VendorTable; } efi_configuration_table_t; typedef struct { - efi_table_header_t Hdr; - - wchar_t *FirmwareVendor; - uint32_t FirmwareRevision; - - efi_handle_t ConsoleInHandle; - simple_input_interface_t *ConIn; - - efi_handle_t ConsoleOutHandle; - simple_text_output_interface_t *ConOut; - - efi_handle_t ConsoleErrorHandle; - simple_text_output_interface_t *StdErr; - - efi_runtime_services_t *RuntimeServices; - efi_boot_services_t *BootServices; - - uintn_t NumberOfTableEntries; - efi_configuration_table_t *ConfigurationTable; + efi_table_header_t Hdr; + wchar_t* FirmwareVendor; + uint32_t FirmwareRevision; + efi_handle_t ConsoleInHandle; + simple_input_interface_t* ConIn; + efi_handle_t ConsoleOutHandle; + simple_text_output_interface_t* ConOut; + efi_handle_t ConsoleErrorHandle; + simple_text_output_interface_t* StdErr; + efi_runtime_services_t* RuntimeServices; + efi_boot_services_t* BootServices; + uintn_t NumberOfTableEntries; + efi_configuration_table_t* ConfigurationTable; } efi_system_table_t; -extern efi_system_table_t *ST; -#define gST ST - -/*** Simple File System Protocol ***/ -#ifndef EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID -#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID { 0x964e5b22, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } - -#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION 0x00010000 -#define EFI_FILE_IO_INTERFACE_REVISION EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION - -#define EFI_FILE_MODE_READ 0x0000000000000001 -#define EFI_FILE_MODE_WRITE 0x0000000000000002 -#define EFI_FILE_MODE_CREATE 0x8000000000000000 - -#define EFI_FILE_READ_ONLY 0x0000000000000001 -#define EFI_FILE_HIDDEN 0x0000000000000002 -#define EFI_FILE_SYSTEM 0x0000000000000004 -#define EFI_FILE_RESERVED 0x0000000000000008 -#define EFI_FILE_DIRECTORY 0x0000000000000010 -#define EFI_FILE_ARCHIVE 0x0000000000000020 -#define EFI_FILE_VALID_ATTR 0x0000000000000037 - -#define EFI_FILE_PROTOCOL_REVISION 0x00010000 -#define EFI_FILE_HANDLE_REVISION EFI_FILE_PROTOCOL_REVISION -#endif - -#ifndef EFI_FILE_INFO_GUID -#define EFI_FILE_INFO_GUID { 0x9576e92, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } -#endif - -#ifndef FILENAME_MAX -#define FILENAME_MAX 262 /* from FAT spec */ -#endif - -typedef struct { - uint64_t Size; - uint64_t FileSize; - uint64_t PhysicalSize; - efi_time_t CreateTime; - efi_time_t LastAccessTime; - efi_time_t ModificationTime; - uint64_t Attribute; - wchar_t FileName[FILENAME_MAX]; -} efi_file_info_t; typedef struct efi_file_handle_s efi_file_handle_t; -typedef efi_status_t (EFIAPI *efi_volume_open_t)(void *This, efi_file_handle_t **Root); +typedef efi_status_t (EFIAPI *efi_volume_open_t)(void* this_ptr, efi_file_handle_t** root); typedef struct { - uint64_t Revision; - efi_volume_open_t OpenVolume; + uint64_t Revision; + efi_volume_open_t OpenVolume; } efi_simple_file_system_protocol_t; -typedef efi_status_t (EFIAPI *efi_file_open_t)(efi_file_handle_t *File, efi_file_handle_t **NewHandle, wchar_t *FileName, - uint64_t OpenMode, uint64_t Attributes); -typedef efi_status_t (EFIAPI *efi_file_close_t)(efi_file_handle_t *File); -typedef efi_status_t (EFIAPI *efi_file_delete_t)(efi_file_handle_t *File); -typedef efi_status_t (EFIAPI *efi_file_read_t)(efi_file_handle_t *File, uintn_t *BufferSize, void *Buffer); -typedef efi_status_t (EFIAPI *efi_file_write_t)(efi_file_handle_t *File, uintn_t *BufferSize, void *Buffer); -typedef efi_status_t (EFIAPI *efi_file_get_pos_t)(efi_file_handle_t *File, uint64_t *Position); -typedef efi_status_t (EFIAPI *efi_file_set_pos_t)(efi_file_handle_t *File, uint64_t Position); -typedef efi_status_t (EFIAPI *efi_file_get_info_t)(efi_file_handle_t *File, efi_guid_t *InformationType, uintn_t *BufferSize, - void *Buffer); -typedef efi_status_t (EFIAPI *efi_file_set_info_t)(efi_file_handle_t *File, efi_guid_t *InformationType, uintn_t BufferSize, - void *Buffer); -typedef efi_status_t (EFIAPI *efi_file_flush_t)(efi_file_handle_t *File); +typedef struct { + uint64_t Size; + uint64_t FileSize; + uint64_t PhysicalSize; + efi_time_t CreateTime; + efi_time_t LastAccessTime; + efi_time_t ModificationTime; + uint64_t Attribute; + wchar_t FileName[FILENAME_MAX]; +} efi_file_info_t; + +typedef efi_status_t (EFIAPI *efi_file_open_t)(efi_file_handle_t* file, efi_file_handle_t** new_handle, wchar_t* file_name, uint64_t open_mode, uint64_t attributes); +typedef efi_status_t (EFIAPI *efi_file_close_t)(efi_file_handle_t* file); +typedef efi_status_t (EFIAPI *efi_file_delete_t)(efi_file_handle_t* file); +typedef efi_status_t (EFIAPI *efi_file_read_t)(efi_file_handle_t* file, uintn_t* buffer_size, void* buffer); +typedef efi_status_t (EFIAPI *efi_file_write_t)(efi_file_handle_t* file, uintn_t* buffer_size, void* buffer); +typedef efi_status_t (EFIAPI *efi_file_get_pos_t)(efi_file_handle_t* file, uint64_t* position); +typedef efi_status_t (EFIAPI *efi_file_set_pos_t)(efi_file_handle_t* file, uint64_t position); +typedef efi_status_t (EFIAPI *efi_file_get_info_t)(efi_file_handle_t* file, efi_guid_t* information_type, uintn_t* buffer_size, void* buffer); +typedef efi_status_t (EFIAPI *efi_file_set_info_t)(efi_file_handle_t* file, efi_guid_t* information_type, uintn_t buffer_size, void* buffer); +typedef efi_status_t (EFIAPI *efi_file_flush_t)(efi_file_handle_t* file); struct efi_file_handle_s { - uint64_t Revision; - efi_file_open_t Open; - efi_file_close_t Close; - efi_file_delete_t Delete; - efi_file_read_t Read; - efi_file_write_t Write; - efi_file_get_pos_t GetPosition; - efi_file_set_pos_t SetPosition; - efi_file_get_info_t GetInfo; - efi_file_set_info_t SetInfo; - efi_file_flush_t Flush; + uint64_t Revision; + efi_file_open_t Open; + efi_file_close_t Close; + efi_file_delete_t Delete; + efi_file_read_t Read; + efi_file_write_t Write; + efi_file_get_pos_t GetPosition; + efi_file_set_pos_t SetPosition; + efi_file_get_info_t GetInfo; + efi_file_set_info_t SetInfo; + efi_file_flush_t Flush; }; -/*** Shell Parameter Protocols ***/ -#ifndef EFI_SHELL_PARAMETERS_PROTOCOL_GUID -#define EFI_SHELL_PARAMETERS_PROTOCOL_GUID { 0x752f3136, 0x4e16, 0x4fdc, {0xa2, 0x2a, 0xe5, 0xf4, 0x68, 0x12, 0xf4, 0xca} } -#endif - typedef struct { - wchar_t **Argv; - uintn_t Argc; - efi_handle_t StdIn; - efi_handle_t StdOut; - efi_handle_t StdErr; -} efi_shell_parameters_protocol_t; - -#ifndef SHELL_INTERFACE_PROTOCOL_GUID -#define SHELL_INTERFACE_PROTOCOL_GUID { 0x47c7b223, 0xc42a, 0x11d2, {0x8e, 0x57, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } -#endif - -typedef struct { - efi_handle_t ImageHandle; - void* *Info; - wchar_t **Argv; - uintn_t Argc; - wchar_t **RedirArgv; - uintn_t RedirArgc; - efi_handle_t StdIn; - efi_handle_t StdOut; - efi_handle_t StdErr; -} efi_shell_interface_protocol_t; - -/*** Random Number Generator ***/ -#ifndef EFI_RNG_PROTOCOL_GUID -#define EFI_RNG_PROTOCOL_GUID { 0x3152bca5, 0xeade, 0x433d, {0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44} } -#endif - -typedef efi_status_t (EFIAPI *efi_rng_get_info_t)(void *This, uintn_t *RNGAlgorithmListSize, efi_guid_t *RNGAlgorithmList); -typedef efi_status_t (EFIAPI *efi_rng_get_rng_t)(void *This, efi_guid_t *RNGAlgorithm, uintn_t RNGValueLength, uint8_t *RNGValue); - -typedef struct { - efi_rng_get_info_t GetInfo; - efi_rng_get_rng_t GetRNG; -} efi_rng_protocol_t; - -/*** Serial IO Protocol ***/ -#ifndef EFI_SERIAL_IO_PROTOCOL_GUID -#define EFI_SERIAL_IO_PROTOCOL_GUID { 0xBB25CF6F, 0xF1D4, 0x11D2, {0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0xFD} } - -#define SERIAL_IO_INTERFACE_REVISION 0x00010000 -#define EFI_SERIAL_CLEAR_TO_SEND 0x0010 -#define EFI_SERIAL_DATA_SET_READY 0x0020 -#define EFI_SERIAL_RING_INDICATE 0x0040 -#define EFI_SERIAL_CARRIER_DETECT 0x0080 -#define EFI_SERIAL_REQUEST_TO_SEND 0x0002 -#define EFI_SERIAL_DATA_TERMINAL_READY 0x0001 -#define EFI_SERIAL_INPUT_BUFFER_EMPTY 0x0100 -#define EFI_SERIAL_OUTPUT_BUFFER_EMPTY 0x0200 -#define EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE 0x1000 -#define EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE 0x2000 -#define EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE 0x4000 - -typedef enum { - DefaultParity, - NoParity, - EvenParity, - OddParity, - MarkParity, - SpaceParity -} efi_parity_type_t; - -typedef enum { - DefaultStopBits, - OneStopBit, - OneFiveStopBits, - TwoStopBits -} efi_stop_bits_type_t; - -#else - -#define efi_parity_type_t EFI_PARITY_TYPE -#define efi_stop_bits_type_t EFI_STOP_BITS_TYPE - -#endif - -typedef struct { - uint32_t ControlMask; - uint32_t Timeout; - uint64_t BaudRate; - uint32_t ReceiveFifoDepth; - uint32_t DataBits; - uint32_t Parity; - uint32_t StopBits; -} efi_serial_io_mode_t; - -typedef efi_status_t (EFIAPI *efi_serial_reset_t)(void *This); -typedef efi_status_t (EFIAPI *efi_serial_set_attributes_t)(void *This, uint64_t BaudRate, uint32_t ReceiveFifoDepth, - uint32_t Timeout, efi_parity_type_t Parity, uint8_t DataBits, efi_stop_bits_type_t StopBits); -typedef efi_status_t (EFIAPI *efi_serial_set_control_bits_t)(void *This, uint32_t Control); -typedef efi_status_t (EFIAPI *efi_serial_get_control_bits_t)(void *This, uint32_t *Control); -typedef efi_status_t (EFIAPI *efi_serial_write_t)(void *This, uintn_t *BufferSize, void *Buffer); -typedef efi_status_t (EFIAPI *efi_serial_read_t)(void *This, uintn_t *BufferSize, void *Buffer); - -typedef struct { - uint32_t Revision; - efi_serial_reset_t Reset; - efi_serial_set_attributes_t SetAttributes; - efi_serial_set_control_bits_t SetControl; - efi_serial_get_control_bits_t GetControl; - efi_serial_write_t Write; - efi_serial_read_t Read; - efi_serial_io_mode_t *Mode; -} efi_serial_io_protocol_t; - -/*** Block IO Protocol ***/ -#ifndef EFI_BLOCK_IO_PROTOCOL_GUID -#define EFI_BLOCK_IO_PROTOCOL_GUID { 0x964e5b21, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } - -#define EFI_BLOCK_IO_PROTOCOL_REVISION 0x00010000 -#define EFI_BLOCK_IO_INTERFACE_REVISION EFI_BLOCK_IO_PROTOCOL_REVISION - -#endif - -typedef struct { - uint32_t MediaId; - boolean_t RemovableMedia; - boolean_t MediaPresent; - boolean_t LogicalPartition; - boolean_t ReadOnly; - boolean_t WriteCaching; - uint32_t BlockSize; - uint32_t IoAlign; - efi_lba_t LastBlock; -} efi_block_io_media_t; - -typedef efi_status_t (EFIAPI *efi_block_reset_t)(void *This, boolean_t ExtendedVerification); -typedef efi_status_t (EFIAPI *efi_block_read_t)(void *This, uint32_t MediaId, efi_lba_t LBA, uintn_t BufferSize, void *Buffer); -typedef efi_status_t (EFIAPI *efi_block_write_t)(void *This, uint32_t MediaId, efi_lba_t LBA, uintn_t BufferSize, void *Buffer); -typedef efi_status_t (EFIAPI *efi_block_flush_t)(void *This); - -typedef struct { - uint64_t Revision; - efi_block_io_media_t *Media; - efi_block_reset_t Reset; - efi_block_read_t ReadBlocks; - efi_block_write_t WriteBlocks; - efi_block_flush_t FlushBlocks; -} efi_block_io_t; - -typedef struct { - off_t offset; - efi_block_io_t *bio; -} block_file_t; - -/*** Graphics Output Protocol (not used, but could be useful to have) ***/ -#ifndef EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID -#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID { 0x9042a9de, 0x23dc, 0x4a38, {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } } - -typedef enum { - PixelRedGreenBlueReserved8BitPerColor, - PixelBlueGreenRedReserved8BitPerColor, - PixelBitMask, - PixelBltOnly, - PixelFormatMax -} efi_gop_pixel_format_t; - -typedef enum { - EfiBltVideoFill, - EfiBltVideoToBltBuffer, - EfiBltBufferToVideo, - EfiBltVideoToVideo, - EfiGraphicsOutputBltOperationMax -} efi_gop_blt_operation_t; - -#else - -#define efi_gop_pixel_format_t EFI_GRAPHICS_PIXEL_FORMAT -#define efi_gop_blt_operation_t EFI_GRAPHICS_OUTPUT_BLT_OPERATION - -#endif - -typedef struct { - uint32_t RedMask; - uint32_t GreenMask; - uint32_t BlueMask; - uint32_t ReservedMask; + uint32_t RedMask; + uint32_t GreenMask; + uint32_t BlueMask; + uint32_t ReservedMask; } efi_gop_pixel_bitmask_t; typedef struct { - uint32_t Version; - uint32_t HorizontalResolution; - uint32_t VerticalResolution; - efi_gop_pixel_format_t PixelFormat; + uint32_t Version; + uint32_t HorizontalResolution; + uint32_t VerticalResolution; + efi_gop_pixel_format_t PixelFormat; efi_gop_pixel_bitmask_t PixelInformation; - uint32_t PixelsPerScanLine; + uint32_t PixelsPerScanLine; } efi_gop_mode_info_t; typedef struct { - uint32_t MaxMode; - uint32_t Mode; - efi_gop_mode_info_t *Information; - uintn_t SizeOfInfo; - efi_physical_address_t FrameBufferBase; - uintn_t FrameBufferSize; + uint32_t MaxMode; + uint32_t Mode; + efi_gop_mode_info_t* Information; + uintn_t SizeOfInfo; + efi_physical_address_t FrameBufferBase; + uintn_t FrameBufferSize; } efi_gop_mode_t; -typedef efi_status_t (EFIAPI *efi_gop_query_mode_t)(void *This, uint32_t ModeNumber, uintn_t *SizeOfInfo, - efi_gop_mode_info_t **Info); -typedef efi_status_t (EFIAPI *efi_gop_set_mode_t)(void *This, uint32_t ModeNumber); -typedef efi_status_t (EFIAPI *efi_gop_blt_t)(void *This, uint32_t *BltBuffer, efi_gop_blt_operation_t BltOperation, - uintn_t SourceX, uintn_t SourceY, uintn_t DestinationX, uintn_t DestionationY, uintn_t Width, uintn_t Height, uintn_t Delta); +typedef efi_status_t (EFIAPI *efi_gop_query_mode_t)(void* this_ptr, uint32_t mode_number, uintn_t* size_of_info, efi_gop_mode_info_t** info); +typedef efi_status_t (EFIAPI *efi_gop_set_mode_t)(void* this_ptr, uint32_t mode_number); +typedef efi_status_t (EFIAPI *efi_gop_blt_t)(void* this_ptr, uint32_t* blt_buffer, uint32_t blt_operation, uintn_t source_x, uintn_t source_y, uintn_t destination_x, uintn_t destination_y, uintn_t width, uintn_t height, uintn_t delta); typedef struct { - efi_gop_query_mode_t QueryMode; - efi_gop_set_mode_t SetMode; - efi_gop_blt_t Blt; - efi_gop_mode_t *Mode; + efi_gop_query_mode_t QueryMode; + efi_gop_set_mode_t SetMode; + efi_gop_blt_t Blt; + efi_gop_mode_t* Mode; } efi_gop_t; -/*** EDID Protocol (not used, but could be useful to have) ***/ -#ifndef EFI_EDID_ACTIVE_GUID -#define EFI_EDID_ACTIVE_GUID { 0xbd8c1056, 0x9f36, 0x44ec, { 0x92, 0xa8, 0xa6, 0x33, 0x7f, 0x81, 0x79, 0x86 } } -#define EFI_EDID_DISCOVERED_GUID { 0x1c0c34f6, 0xd380, 0x41fa, { 0xa0, 0x49, 0x8a, 0xd0, 0x6c, 0x1a, 0x66, 0xaa } } -#endif +extern efi_handle_t IM; +extern efi_system_table_t* ST; +extern efi_boot_services_t* BS; +extern efi_runtime_services_t* RT; -typedef struct { - uint32_t SizeOfEdid; - uint8_t *Edid; -} efi_edid_t; - -/*** Simple Pointer Protocol (not used, but could be useful to have) ***/ -#ifndef EFI_SIMPLE_POINTER_PROTOCOL_GUID -#define EFI_SIMPLE_POINTER_PROTOCOL_GUID { 0x31878c87, 0xb75, 0x11d5, { 0x9a, 0x4f, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } -#endif - -typedef struct { - int32_t RelativeMovementX; - int32_t RelativeMovementY; - int32_t RelativeMovementZ; - boolean_t LeftButton; - boolean_t RightButton; -} efi_simple_pointer_state_t; - -typedef struct { - uint64_t ResolutionX; - uint64_t ResolutionY; - uint64_t ResolutionZ; - boolean_t LeftButton; - boolean_t RightButton; -} efi_simple_pointer_mode_t; - -typedef efi_status_t (EFIAPI *efi_simple_pointer_reset_t) (void *This, boolean_t ExtendedVerification); -typedef efi_status_t (EFIAPI *efi_simple_pointer_get_state_t) (void *This, efi_simple_pointer_state_t *State); - -typedef struct { - efi_simple_pointer_reset_t Reset; - efi_simple_pointer_get_state_t GetState; - efi_event_t WaitForInput; - efi_simple_pointer_mode_t *Mode; -} efi_simple_pointer_protocol_t; - -/*** Option ROM Protocol (not used, but could be useful to have) ***/ -#ifndef EFI_PCI_OPTION_ROM_TABLE_GUID -#define EFI_PCI_OPTION_ROM_TABLE_GUID { 0x7462660f, 0x1cbd, 0x48da, {0xad, 0x11, 0x91, 0x71, 0x79, 0x13, 0x83, 0x1c} } -#endif - -typedef struct { - efi_physical_address_t RomAddress; - efi_memory_type_t MemoryType; - uint32_t RomLength; - uint32_t Seg; - uint8_t Bus; - uint8_t Dev; - uint8_t Func; - boolean_t ExecutedLegacyBiosImage; - boolean_t DontLoadEfiRom; -} efi_pci_option_rom_descriptor_t; - -typedef struct { - uint64_t PciOptionRomCount; - efi_pci_option_rom_descriptor_t *PciOptionRomDescriptors; -} efi_pci_option_rom_table_t; - -/*** GPT partitioning table (not used, but could be useful to have) ***/ -typedef struct { - efi_table_header_t Header; - efi_lba_t MyLBA; - efi_lba_t AlternateLBA; - efi_lba_t FirstUsableLBA; - efi_lba_t LastUsableLBA; - efi_guid_t DiskGUID; - efi_lba_t PartitionEntryLBA; - uint32_t NumberOfPartitionEntries; - uint32_t SizeOfPartitionEntry; - uint32_t PartitionEntryArrayCRC32; -} efi_partition_table_header_t; - -typedef struct { - efi_guid_t PartitionTypeGUID; - efi_guid_t UniquePartitionGUID; - efi_lba_t StartingLBA; - efi_lba_t EndingLBA; - uint64_t Attributes; - wchar_t PartitionName[36]; -} efi_partition_entry_t; - -/*** POSIX definitions ***/ -#define abs(x) ((x)<0?-(x):(x)) -#define min(x,y) ((x)<(y)?(x):(y)) -#define max(x,y) ((x)>(y)?(x):(y)) - -/* dirent.h */ -#define IFTODT(mode) (((mode) & 0170000) >> 12) -#define DTTOIF(dirtype) ((dirtype) << 12) -#define DT_DIR 4 -#define DT_REG 8 -struct dirent { - unsigned short int d_reclen; - unsigned char d_type; - char_t d_name[FILENAME_MAX]; -}; -typedef struct efi_file_handle_s DIR; -extern DIR *opendir (const char_t *__name); -extern struct dirent *readdir (DIR *__dirp); -extern void rewinddir (DIR *__dirp); -extern int closedir (DIR *__dirp); - -/* errno.h */ -extern int errno; -#define EPERM 1 /* Operation not permitted */ -#define ENOENT 2 /* No such file or directory */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted system call */ -#define EIO 5 /* I/O error */ -#define ENXIO 6 /* No such device or address */ -#define E2BIG 7 /* Argument list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file number */ -#define ECHILD 10 /* No child processes */ -#define EAGAIN 11 /* Try again */ -#define ENOMEM 12 /* Out of memory */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -#define ENOTBLK 15 /* Block device required */ -#define EBUSY 16 /* Device or resource busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* File table overflow */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Not a typewriter */ -#define ETXTBSY 26 /* Text file busy */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Illegal seek */ -#define EROFS 30 /* Read-only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ -#define EDOM 33 /* Math argument out of domain of func */ -#define ERANGE 34 /* Math result not representable */ - -/* stdlib.h */ -#define RAND_MAX 2147483647 -typedef int (*__compar_fn_t) (const void *, const void *); -extern int atoi (const char_t *__nptr); -extern int64_t atol (const char_t *__nptr); -extern int64_t strtol (const char_t *__nptr, char_t **__endptr, int __base); -extern void *malloc (size_t __size); -extern void *calloc (size_t __nmemb, size_t __size); -extern void *realloc (void *__ptr, size_t __size); -extern void free (void *__ptr); -extern void abort (void); -extern void exit (int __status); -/* exit Boot Services function. Returns 0 on success. */ -extern int exit_bs(void); -extern void *bsearch (const void *__key, const void *__base, size_t __nmemb, size_t __size, __compar_fn_t __compar); -extern void qsort (void *__base, size_t __nmemb, size_t __size, __compar_fn_t __compar); -extern int mblen (const char *__s, size_t __n); -extern int mbtowc (wchar_t * __pwc, const char * __s, size_t __n); -extern int wctomb (char *__s, wchar_t __wchar); -extern size_t mbstowcs (wchar_t *__pwcs, const char *__s, size_t __n); -extern size_t wcstombs (char *__s, const wchar_t *__pwcs, size_t __n); -extern void srand(unsigned int __seed); -extern int rand(void); -extern uint8_t *getenv(char_t *name, uintn_t *len); -extern int setenv(char_t *name, uintn_t len, uint8_t *data); - -/* stdio.h */ -#ifndef BUFSIZ -#define BUFSIZ 8192 -#endif -#define SEEK_SET 0 /* Seek from beginning of file. */ -#define SEEK_CUR 1 /* Seek from current position. */ -#define SEEK_END 2 /* Seek from end of file. */ -#define stdin (FILE*)ST->ConsoleInHandle -#define stdout (FILE*)ST->ConsoleOutHandle -#define stderr (FILE*)ST->ConsoleErrorHandle -typedef struct efi_file_handle_s FILE; -extern int fclose (FILE *__stream); -extern int fflush (FILE *__stream); -extern int remove (const char_t *__filename); -extern FILE *fopen (const char_t *__filename, const char_t *__modes); -extern size_t fread (void *__ptr, size_t __size, size_t __n, FILE *__stream); -extern size_t fwrite (const void *__ptr, size_t __size, size_t __n, FILE *__s); -extern int fseek (FILE *__stream, long int __off, int __whence); -extern long int ftell (FILE *__stream); -extern int feof (FILE *__stream); -extern int fprintf (FILE *__stream, const char_t *__format, ...); -extern int printf (const char_t *__format, ...); -extern int sprintf (char_t *__s, const char_t *__format, ...); -extern int vfprintf (FILE *__s, const char_t *__format, __builtin_va_list __arg); -extern int vprintf (const char_t *__format, __builtin_va_list __arg); -extern int vsprintf (char_t *__s, const char_t *__format, __builtin_va_list __arg); -extern int snprintf (char_t *__s, size_t __maxlen, const char_t *__format, ...); -extern int vsnprintf (char_t *__s, size_t __maxlen, const char_t *__format, __builtin_va_list __arg); -extern int getchar (void); -/* non-blocking, only returns UNICODE if there's any key pressed, 0 otherwise */ -extern int getchar_ifany (void); -extern int putchar (int __c); - -/* string.h */ -extern void *memcpy(void *__dest, const void *__src, size_t __n); -extern void *memmove(void *__dest, const void *__src, size_t __n); -extern void *memset(void *__s, int __c, size_t __n); -extern int memcmp(const void *__s1, const void *__s2, size_t __n); -extern void *memchr(const void *__s, int __c, size_t __n); -extern void *memrchr(const void *__s, int __c, size_t __n); -void *memmem(const void *haystack, size_t hl, const void *needle, size_t nl); -void *memrmem(const void *haystack, size_t hl, const void *needle, size_t nl); -extern char_t *strcpy (char_t *__dest, const char_t *__src); -extern char_t *strncpy (char_t *__dest, const char_t *__src, size_t __n); -extern char_t *strcat (char_t *__dest, const char_t *__src); -extern char_t *strncat (char_t *__dest, const char_t *__src, size_t __n); -extern int strcmp (const char_t *__s1, const char_t *__s2); -extern int strncmp (const char_t *__s1, const char_t *__s2, size_t __n); -extern char_t *strdup (const char_t *__s); -extern char_t *strchr (const char_t *__s, int __c); -extern char_t *strrchr (const char_t *__s, int __c); -extern char_t *strstr (const char_t *__haystack, const char_t *__needle); -extern char_t *strtok (char_t *__s, const char_t *__delim); -extern char_t *strtok_r (char_t *__s, const char_t *__delim, char_t **__save_ptr); -extern size_t strlen (const char_t *__s); - -/* sys/stat.h */ -#define S_IREAD 0400 /* Read by owner. */ -#define S_IWRITE 0200 /* Write by owner. */ -#define S_IFMT 0170000 /* These bits determine file type. */ -#define S_IFIFO 0010000 /* FIFO. */ -#define S_IFCHR 0020000 /* Character device. */ -#define S_IFDIR 0040000 /* Directory. */ -#define S_IFBLK 0060000 /* Block device. */ -#define S_IFREG 0100000 /* Regular file. */ -#define S_ISTYPE(mode, mask) (((mode) & S_IFMT) == (mask)) -#define S_ISCHR(mode) S_ISTYPE((mode), S_IFCHR) -#define S_ISDIR(mode) S_ISTYPE((mode), S_IFDIR) -#define S_ISBLK(mode) S_ISTYPE((mode), S_IFBLK) -#define S_ISREG(mode) S_ISTYPE((mode), S_IFREG) -#define S_ISFIFO(mode) S_ISTYPE((mode), S_IFIFO) -struct stat { - mode_t st_mode; - off_t st_size; - blkcnt_t st_blocks; - time_t st_atime; - time_t st_mtime; - time_t st_ctime; -}; -extern int stat (const char_t *__file, struct stat *__buf); -extern int fstat (FILE *__f, struct stat *__buf); -extern int mkdir (const char_t *__path, mode_t __mode); - -/* time.h */ -struct tm { - int tm_sec; /* Seconds. [0-60] (1 leap second) */ - int tm_min; /* Minutes. [0-59] */ - int tm_hour; /* Hours. [0-23] */ - int tm_mday; /* Day. [1-31] */ - int tm_mon; /* Month. [0-11] */ - int tm_year; /* Year - 1900. */ - int tm_wday; /* Day of week. [0-6] (not set) */ - int tm_yday; /* Days in year.[0-365] (not set) */ - int tm_isdst; /* DST. [-1/0/1]*/ -}; -extern struct tm *localtime (const time_t *__timer); -extern time_t mktime(const struct tm *__tm); -extern time_t time(time_t *__timer); - -/* unistd.h */ -extern unsigned int sleep (unsigned int __seconds); -extern int usleep (unsigned long int __useconds); -extern int unlink (const wchar_t *__filename); -extern int rmdir (const wchar_t *__filename); - -#ifdef __cplusplus -} -#endif - -#endif /* _UEFI_H_ */ +#define gBS BS diff --git a/Bootloader/Source/uefi/unistd.c b/Bootloader/Source/uefi/unistd.c deleted file mode 100644 index b8dccdd..0000000 --- a/Bootloader/Source/uefi/unistd.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * unistd.c - * - * Copyright (C) 2021 bzt (bztsrc@gitlab) - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * This file is part of the POSIX-UEFI package. - * @brief Implementing functions which are defined in unistd.h - * - */ - -#include - -int __remove(const wchar_t *__filename, int isdir); - -int usleep (unsigned long int __useconds) -{ - BS->Stall(__useconds); - return 0; -} - -unsigned int sleep (unsigned int __seconds) -{ - /* Issue 56: some real firmware is buggy and Stall doesn't work for large delays, so use a timer instead */ - uint64_t usec = (uint64_t)__seconds * 1000000UL; - uintn_t index = 0; - efi_event_t timer_event; - efi_status_t status = status = BS->CreateEvent(EVT_TIMER, 0, NULL, NULL, &timer_event); - if(!EFI_ERROR(status)) { - BS->SetTimer(timer_event, TimerRelative, usec * 10UL); - BS->WaitForEvent(1, &timer_event, &index); - BS->CloseEvent(timer_event); - } else - BS->Stall(usec); - return 0; -} - -int unlink (const wchar_t *__filename) -{ - return __remove(__filename, 0); -} - -int rmdir (const wchar_t *__filename) -{ - return __remove(__filename, 1); -}