/* * Copyright (C) 2025 Danny Holman * * This file is part of BoxOS, a free and open-source Unix-like operating * system. * * BoxOS is free software; you can redistribute it and/or modify under the * terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * BoxOS is distributed in the hope it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * BoxOS; if not, see . */ #ifndef BOOTABI_EFI_H #define BOOTABI_EFI_H #include #include #include #define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 #define EFI_OPEN_PROTOCOL_BY_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_TRUE 1 #define EFI_FALSE 0 typedef struct efi_guid { uint32_t data1; uint16_t data2; uint16_t data3; uint8_t data4[8]; } efi_guid_t; static const efi_guid_t EFI_FILE_INFO_ID = {0x09576E92, 0x6D3F, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}}; static const efi_guid_t EFI_LOAD_FILE_PROTOCOL_ID = {0x5B1B31A1, 0x9562, 0x11D2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}}; static const efi_guid_t EFI_DEVICE_PATH_PROTOCOL_ID = {0x09576E91, 0x6D3F, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}}; static const efi_guid_t EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_ID = {0x0964E5B22, 0x6459, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}}; static const efi_guid_t EFI_LOADED_IMAGE_PROTOCOL_ID = {0x5B1B31A1, 0x9562, 0x11d2, {0x8E,0x3F,0x00,0xA0,0xC9,0x69,0x72,0x3B}}; static const efi_guid_t EFI_GRAPHICS_OUTPUT_PROTOCOL_ID = {0x9042A9DE, 0x23DC, 0x4A38, {0x96, 0xFB, 0x7A, 0xDE, 0xD0, 0x80, 0x51, 0x6A}}; typedef struct efi_time { uint16_t year; uint8_t month; uint8_t day; uint8_t hour; uint8_t minute; uint8_t second; uint8_t PAD0; uint32_t nsecond; uint16_t time_zone; uint8_t dst; uint8_t PAD1; } efi_time_t; typedef struct efi_time_cap { uint32_t resolution; uint32_t accuracy; uint8_t set_to_zero; } efi_time_cap_t; enum efi_alloc_type { AllocateAnyPages, AllocateMaxAddress, AllocateAddress, MaxAllocateType, }; enum efi_memory_type { ReservedMemory, LoaderCode, LoaderData, BootSrvCode, BootSrvData, RuntimeSrvCode, RuntimeSrvData, ConventionalMemory, UnusableMemory, ACPIReclaimMemory, ACPIMemoryNVS, MemoryMappedIO, MemoryMappedIOPortSpace, PalCode, PersistentMemory, UnacceptedMemory, MaxMemory, }; #define EFIERR(X) ((uint64_t)(0x8000000000000000 | (X))) enum efi_status { EFI_SUCCESS, EFI_LOAD_ERROR, EFI_INVALID_PARAMETER, EFI_UNSUPPORTED, EFI_BAD_BUFFER_SIZE, EFI_BUFFER_TOO_SMALL, EFI_NOT_READY, EFI_DEVICE_ERROR, EFI_WRITE_PROTECTED, EFI_OUT_OF_RESOURCES, EFI_VOLUME_CORRUPTED, EFI_VOLUME_FULL, EFI_NO_MEDIA, EFI_MEDIA_CHANGED, EFI_NOT_FOUND, EFI_ACCESS_DENIED, EFI_NO_RESPONSE, EFI_NO_MAPPING, EFI_TIMEOUT, EFI_NOT_STARTED, EFI_ALREADY_STARTED, EFI_ABORTED, EFI_ICMP_ERROR, EFI_TFTP_ERROR, EFI_PROTOCOL_ERROR, EFI_INCOMPATIBLE_VERSION, EFI_SECURITY_VIOLATION, EFI_CRC_ERROR, EFI_END_OF_MEDIA, EFI_END_OF_FILE, EFI_INVALID_LANGUAGE, EFI_COMPROMISED_DATA, EFI_IP_ADDRESS_CONFLICT, EFI_HTTP_ERROR, }; static char* efi_status_str[] = { "Success", "Load error", "Invalid parameter", "Unsupported operation", "Bad buffer size", "Buffer too small", "Not ready", "Device error", "Write protected", "Out of resources", "Volume corrupted", "Volume full", "No media", "Media changed", "Not found", "Access denied", "No response", "No mapping", "Operation timeout", "Operation not started", "Operation already started", "Operation aborted", "ICMP error", "TFTP error", "Protocol error", "Incompatible version", "Security violation", "Checksum error", "End of media", "End of file", "Invalid language", "Compressed data", "IP conflict", "HTTP error" }; enum efi_reset_type { EFI_RESET_COLD, EFI_RESET_WARM, EFI_RESET_SHUTDOWN, EFI_RESET_PFORM_SPECIFIC, }; typedef struct efi_memory_descriptor { uint32_t type; uintptr_t physical_start; uintptr_t virtual_start; uint64_t num_pages; uint64_t attribute; } efi_memory_descriptor_t; typedef struct efi_input_key { uint16_t scancode; uint16_t unicode; } efi_input_key_t; typedef struct efi_text_input { uint64_t (*read_key_stroke)(struct efi_text_input *this, efi_input_key_t *key); void *wait_for_key; } efi_text_input_t; typedef struct efi_text_output_mode { int32_t max_mode; int32_t mode; int32_t attribute; int32_t cursor_x; int32_t cursor_y; uint8_t cursor_enable; } efi_text_output_mode_t; typedef struct efi_text_output { uint64_t (*reset)(struct efi_text_output*, uint8_t); uint64_t (*output_str)(struct efi_text_output*, char16_t*); uint64_t (*test_string)(struct efi_text_output*, char16_t*); uint64_t (*query_mode)(struct efi_text_output*, uint64_t); uint64_t (*set_mode)(struct efi_text_output*, uint64_t); uint64_t (*set_attribute)(struct efi_text_output*, uint64_t); uint64_t (*clear_screen)(struct efi_text_output*); uint64_t (*set_cursor)(struct efi_text_output*, uint64_t, uint64_t); uint64_t (*enable_cursor)(struct efi_text_output*, uint8_t); efi_text_output_mode_t *mode; } efi_text_output_t; typedef struct efi_device_path { uint8_t type; uint8_t sub_type; uint8_t length[2]; } efi_device_path_t; typedef struct efi_protocol_entry { void *agent_handle; void *controller_handle; uint32_t attributes; uint32_t count; } efi_protocol_entry_t; typedef struct efi_cap_hdr { efi_guid_t cap_guid; uint32_t header_sz; uint32_t flags; uint32_t cap_sz; } efi_cap_hdr_t; #define EFI_FILE_MODE_READ (1 << 0) #define EFI_FILE_MODE_WRITE (2 << 0) #define EFI_FILE_MODE_CREATE (8 << 60) #define EFI_FILE_READ_ONLY (1 << 0) #define EFI_FILE_HIDDEN (2 << 0) #define EFI_FILE_SYSTEM (4 << 0) #define EFI_FILE_RESERVED (8 << 0) #define EFI_FILE_DIRECTORY (1 << 4) #define EFI_FILE_ARCHIVE (2 << 4) #define EFI_FILE_VALID_ATTR (55 << 0) #define FILENAME_MAX 255 typedef struct efi_file_io_token { void *event; uint64_t status; uint64_t bufsz; void *buffer; } efi_file_io_token_t; typedef struct efi_file_protocol { uint64_t revision; uint64_t (*open)(struct efi_file_protocol*, struct efi_file_protocol**, char16_t*, uint64_t, uint64_t); uint64_t (*close)(struct efi_file_protocol*); uint64_t (*deletef)(struct efi_file_protocol*); uint64_t (*read)(struct efi_file_protocol*, uint64_t*, void*); uint64_t (*write)(struct efi_file_protocol*, uint64_t*, void*); uint64_t (*get_position)(struct efi_file_protocol*, uint64_t*); uint64_t (*set_position)(struct efi_file_protocol*, uint64_t); uint64_t (*get_info)(struct efi_file_protocol*, efi_guid_t*, uint64_t*, void*); uint64_t (*set_info)(struct efi_file_protocol*, efi_guid_t*, uint64_t, void*); uint64_t (*flush)(struct efi_file_protocol*); uint64_t (*open_ex)(struct efi_file_protocol*, struct efi_file_protocol**, char16_t*, uint64_t, uint64_t, efi_file_io_token_t*); uint64_t (*read_ex)(struct efi_file_protocol*, efi_file_io_token_t*); uint64_t (*write_ex)(struct efi_file_protocol*, efi_file_io_token_t*); uint64_t (*flush_ex)(struct efi_file_protocol*, efi_file_io_token_t*); } efi_file_protocol_t; typedef struct efi_file_info { uint64_t size; uint64_t file_size; uint64_t phys_size; efi_time_t ctime; efi_time_t atime; efi_time_t mtime; uint64_t attribute; uint16_t filename[FILENAME_MAX]; } efi_file_info_t; typedef struct efi_simple_file_system_protocol { uint32_t revision; uint64_t (*open_volume)(void*, efi_file_protocol_t**); } efi_simple_file_system_protocol_t; typedef struct efi_table_hdr { uint64_t signature; uint32_t revision; uint32_t header_sz; uint32_t crc32; uint32_t RESERVED; } efi_table_hdr_t; typedef struct efi_runtime { efi_table_hdr_t header; uint64_t (*gettime)(efi_time_t*, efi_time_cap_t*); uint64_t (*settime)(efi_time_t*); uint64_t (*getwaketime)(uint8_t*, uint8_t*, efi_time_t*); uint64_t (*setwaketime)(uint8_t, efi_time_t*); uint64_t (*setvmap)(uint64_t, uint64_t, uint32_t, efi_memory_descriptor_t*); uint64_t (*convert_pointer)(uint64_t, void**); uint64_t (*getvar)(uint16_t*, efi_guid_t*, uint32_t*, uint64_t*, void*); uint64_t (*getnextvar)(uint64_t*, uint16_t*, efi_guid_t*); uint64_t (*setvar)(uint16_t*, efi_guid_t*, uint32_t, uint64_t, void*); uint64_t (*gethimon)(uint64_t*); uint64_t (*reset_system)(int, uint64_t, uint64_t, uint16_t*); uint64_t (*update_cap)(efi_cap_hdr_t**, uint64_t, uintptr_t); uint64_t (*query_cap)(efi_cap_hdr_t**, uint64_t, uint64_t*, int*); uint64_t (*query_var)(uint32_t, uint64_t*, uint64_t*, uint64_t*); } efi_runtime_t; typedef struct efi_boot { efi_table_hdr_t header; uint64_t (*raise_tpl)(uint64_t); uint64_t (*restore_tpl)(uint64_t); uint64_t (*allocate_pages)(int, int, uint64_t, uintptr_t*); uint64_t (*free_pages)(uintptr_t, uint64_t); uint64_t (*get_memory_map)(uint64_t*, efi_memory_descriptor_t*, uint64_t*, uint64_t*, uint32_t*); uint64_t (*allocate_pool)(int, uint64_t, void**); uint64_t (*free_pool)(void*); uint64_t (*create_event)(uint32_t, uint64_t, void*, void*, void*); uint64_t (*set_timer)(void*, int, uint64_t); uint64_t (*wait_event)(uint64_t, void*, uint64_t*); uint64_t (*signal_event)(void*); uint64_t (*close_event)(void*); uint64_t (*check_event)(void*); void *install_protocol_interface; void *reinstall_protocol_interface; void *uninstall_protocol_interface; uint64_t (*handle_protocol)(void**, const efi_guid_t*, void**); uint64_t (*pc_handle_protocol)(void**, const efi_guid_t*, void**); uint64_t (*register_protocol)(efi_guid_t*, void*, void**); uint64_t (*locate_handle)(int, efi_guid_t*, void*, uint64_t*, void**); uint64_t (*locate_device_path)(efi_guid_t*, efi_device_path_t**, void**); uint64_t (*install_cfg_table)(efi_guid_t*, void*); uint64_t (*load_image)(uint8_t, void*, efi_device_path_t*, void*, uint64_t, void**); uint64_t (*start_image)(void*, uint64_t*, uint16_t**); uint64_t (*exit)(void*, uint64_t, uint64_t, uint16_t*); uint64_t (*unload_image)(void); uint64_t (*exit_boot_services)(void*, uint64_t); uint64_t (*gethimon)(uint64_t*); uint64_t (*stall)(uint64_t); uint64_t (*setwatchdog)(uint64_t, uint64_t, uint64_t, uint16_t*); uint64_t (*connect_cont)(void*, void**, efi_device_path_t*, uint8_t); uint64_t (*disconnect_cont)(void*, void*, void*); uint64_t (*open_protocol)(void*, efi_guid_t*, void**, void*, void*, uint32_t); uint64_t (*close_protocol)(void*, efi_guid_t*, void*, void*); uint64_t (*open_protocol_info)(void*, efi_guid_t*, efi_protocol_entry_t**, uint64_t*); uint64_t (*protocols_per_handle)(void*, efi_guid_t***, uint64_t*); uint64_t (*locate_handle_buffer)(int, efi_guid_t*, void*, uint64_t*, void***); uint64_t (*locate_protocol)(efi_guid_t*, void*, void**); void *install_many_protocols; void *uninstall_many_protocols; uint64_t (*calc_crc32)(void*, uint64_t, uint32_t*); } efi_boot_t; typedef struct efi_system { efi_table_hdr_t header; uint16_t *firmware_vendor; uint32_t firmware_revision; void *console_in_handle; efi_text_input_t *console_in; void *console_out_handle; efi_text_output_t *console_out; void *console_err_handle; efi_text_output_t *console_err; efi_runtime_t *runtime; efi_boot_t *bootsrv; uint64_t num_entries; void *config_table; } efi_system_t; typedef struct efi_load_file_protocol { uint64_t (*load_file)(struct efi_load_file_protocol*, efi_device_path_t*, uint8_t, uint64_t, void*); } efi_load_file_protocol_t; typedef struct efi_loaded_image_protocol { uint64_t revision; void *parent_handle; efi_system_t *system_table; void *device_handle; uint16_t *file_path; void *RESERVED; uint32_t options_size; void *options; void *image_base; uint64_t image_size; uint64_t image_code_type; uint64_t image_data_type; } efi_loaded_image_protocol_t; typedef struct efi_pixel_bitmask { uint32_t red; uint32_t green; uint32_t blue; uint32_t alpha; } efi_pixel_bitmask_t; enum efi_gop_pixel_format { RGBA8, BGRA8, BIT_MASK, BIT_ONLY, FORMAT_MAX, }; typedef struct efi_gop_info { uint32_t version; uint32_t width; uint32_t height; enum efi_gop_pixel_format format; efi_pixel_bitmask_t pixel_info; uint32_t pixels_per_scaline; } efi_gop_info_t; typedef struct efi_gop_mode { uint32_t max_mode; uint32_t mode; efi_gop_info_t *info; uint64_t info_sz; uintptr_t fb_base; uint64_t fb_sz; } efi_gop_mode_t; typedef struct efi_gop { uint64_t (*query_mode)(); uint64_t (*set_mode)(); uint64_t (*blt)(); efi_gop_mode_t *mode; } efi_gop_t; typedef struct efi_bootparam { efi_system_t *st; efi_memory_descriptor_t *mmap; uint64_t mmap_size; uint64_t mmap_key; uint64_t mmap_dsize; efi_gop_mode_t* gop_mode; } efi_bootparam_t; uint64_t efi_abi_wrapper(void *efi_func, ...); uint64_t sysv_abi_wrapper(void *sysv_func, ...); #endif