summaryrefslogtreecommitdiff
path: root/include/bootabi/efi.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/bootabi/efi.h')
-rw-r--r--include/bootabi/efi.h454
1 files changed, 454 insertions, 0 deletions
diff --git a/include/bootabi/efi.h b/include/bootabi/efi.h
new file mode 100644
index 0000000..9db688d
--- /dev/null
+++ b/include/bootabi/efi.h
@@ -0,0 +1,454 @@
+/*
+ * Copyright (C) 2025 Danny Holman <dholman@gymli.org>
+ *
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef BOOTABI_EFI_H
+#define BOOTABI_EFI_H
+
+#include <stdint.h>
+#include <uchar.h>
+#include <limits.h>
+
+#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