use core::ffi::c_void; /// Opaque EFI handle pub type Handle = *mut c_void; /// EFI status (0 = success, bit 63 = error code) pub type Status = u64; /// Helper: UEFI error codes always have bit 63 set const fn efi_err(n: u64) -> u64 { n | (1u64 << 63) } pub const EFI_SUCCESS: Status = 0; pub const EFI_LOAD_ERROR: Status = efi_err(1); pub const EFI_INVALID_PARAMETER: Status = efi_err(2); #[allow(dead_code)] pub const EFI_UNSUPPORTED: Status = efi_err(3); pub const EFI_BUFFER_TOO_SMALL: Status = efi_err(5); #[allow(dead_code)] pub const EFI_NOT_FOUND: Status = efi_err(14); pub const EFI_OUT_OF_RESOURCES: Status = efi_err(9); // --------------------------------------------------------------------------- // GUID // --------------------------------------------------------------------------- #[repr(C)] #[derive(Debug, Clone, Copy)] pub struct Guid { pub a: u32, pub b: u16, pub c: u16, pub d: [u8; 8], } pub const EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID: Guid = Guid { a: 0x9042a9de, b: 0x23dc, c: 0x4a38, d: [0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a], }; pub const EFI_LOADED_IMAGE_PROTOCOL_GUID: Guid = Guid { a: 0x5b1b31a1, b: 0x9562, c: 0x11d2, d: [0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b], }; /// Minimal EFI_LOADED_IMAGE_PROTOCOL — we only need the image base/size /// to reserve the kernel's own code/data/bss pages so the heap and page /// allocators can never overwrite the running kernel. #[repr(C)] pub struct LoadedImageProtocol { pub revision: u32, _pad0: u32, pub parent_handle: Handle, pub system_table: *mut core::ffi::c_void, pub device_handle: Handle, pub file_path: *mut core::ffi::c_void, _reserved: *mut core::ffi::c_void, pub load_options_size: u32, _pad1: u32, pub load_options: *mut core::ffi::c_void, pub image_base: *mut core::ffi::c_void, pub image_size: u64, } // --------------------------------------------------------------------------- // Table header // --------------------------------------------------------------------------- #[repr(C)] pub struct TableHeader { pub signature: u64, pub revision: u32, pub header_size: u32, pub crc32: u32, pub reserved: u32, } // --------------------------------------------------------------------------- // Simple text output protocol (console output) // --------------------------------------------------------------------------- #[repr(C)] pub struct SimpleTextOutput { _reset: *mut c_void, pub output_string: unsafe extern "efiapi" fn(*mut SimpleTextOutput, *const u16) -> Status, _test_string: *mut c_void, _query_mode: *mut c_void, _set_mode: *mut c_void, _set_attribute: *mut c_void, _clear_screen: *mut c_void, _set_cursor_position: *mut c_void, _enable_cursor: *mut c_void, _mode: *mut c_void, } // --------------------------------------------------------------------------- // Simple text input protocol (keyboard input) // --------------------------------------------------------------------------- #[repr(C)] pub struct InputKey { pub scan_code: u16, pub unicode_char: u16, } #[repr(C)] pub struct SimpleTextInput { _reset: *mut c_void, pub read_key_stroke: unsafe extern "efiapi" fn(*mut SimpleTextInput, *mut InputKey) -> Status, _wait_for_key: Handle, } // --------------------------------------------------------------------------- // Runtime services // --------------------------------------------------------------------------- /// `EFI_RESET_SYSTEM` — ResetType, ResetStatus, DataSize, ResetData. /// ResetType: 0 cold, 1 warm, 2 shutdown, 3 platform-specific. pub type EfiResetSystem = unsafe extern "efiapi" fn(u32, u64, usize, *const u16) -> Status; pub const RESET_COLD: u32 = 0; #[allow(dead_code)] pub const RESET_WARM: u32 = 1; pub const RESET_SHUTDOWN: u32 = 2; #[allow(dead_code)] pub const RESET_PLATFORM_SPECIFIC: u32 = 3; /// EFI_RUNTIME_SERVICES — function pointers in spec order after the header. /// We only use ResetSystem; the rest stay opaque. The table remains /// callable after ExitBootServices because we never call SetVirtualAddressMap, /// so the pointers keep working with physical (identity) addresses. #[repr(C)] pub struct RuntimeServices { _hdr: TableHeader, _get_time: *mut c_void, // 0 _set_time: *mut c_void, // 1 _get_wakeup_time: *mut c_void, // 2 _set_wakeup_time: *mut c_void, // 3 _set_virtual_address_map: *mut c_void, // 4 _convert_pointer: *mut c_void, // 5 _get_variable: *mut c_void, // 6 _get_next_variable_name: *mut c_void, // 7 _set_variable: *mut c_void, // 8 _get_next_high_monotonic_count: *mut c_void, // 9 pub reset_system: EfiResetSystem, // 10 _update_capsule: *mut c_void, // 11 _query_capsule_capabilities: *mut c_void, // 12 _query_variable_info: *mut c_void, // 13 } // --------------------------------------------------------------------------- // Configuration table entry // --------------------------------------------------------------------------- #[repr(C)] pub struct ConfigurationTable { pub vendor_guid: Guid, pub vendor_table: *mut c_void, } // --------------------------------------------------------------------------- /// UEFI memory descriptor (from GetMemoryMap) // --------------------------------------------------------------------------- #[repr(C)] pub struct MemoryDescriptor { pub kind: u32, pub pad: u32, pub physical_start: u64, pub virtual_start: u64, pub number_of_pages: u64, pub attribute: u64, } pub const MEMORY_TYPE_RESERVED: u32 = 0; pub const MEMORY_TYPE_LOADER_CODE: u32 = 1; pub const MEMORY_TYPE_LOADER_DATA: u32 = 2; pub const MEMORY_TYPE_BOOT_SERVICES_CODE: u32 = 3; pub const MEMORY_TYPE_BOOT_SERVICES_DATA: u32 = 4; pub const MEMORY_TYPE_RUNTIME_CODE: u32 = 5; pub const MEMORY_TYPE_RUNTIME_DATA: u32 = 6; pub const MEMORY_TYPE_CONVENTIONAL: u32 = 7; pub const MEMORY_TYPE_UNUSABLE: u32 = 8; pub const MEMORY_TYPE_ACPI_RECLAIM: u32 = 9; pub const MEMORY_TYPE_ACPI_NVS: u32 = 10; pub const MEMORY_TYPE_MMIO: u32 = 11; pub const MEMORY_TYPE_MMIO_PORT: u32 = 12; pub const MEMORY_TYPE_PAL_CODE: u32 = 13; pub const MEMORY_TYPE_PERSISTENT: u32 = 14; /// Human-readable name for a UEFI memory type. pub fn memory_type_name(kind: u32) -> &'static str { match kind { 0 => "Reserved", 1 => "LoaderCode", 2 => "LoaderData", 3 => "BootServicesCode", 4 => "BootServicesData", 5 => "RuntimeCode", 6 => "RuntimeData", 7 => "Conventional", 8 => "Unusable", 9 => "ACPIReclaim", 10 => "ACPINVS", 11 => "MMIO", 12 => "MMIOPort", 13 => "PalCode", 14 => "Persistent", _ => "Unknown", } } // --------------------------------------------------------------------------- // Boot services table // --------------------------------------------------------------------------- pub type EfiGetMemoryMap = unsafe extern "efiapi" fn( *mut usize, *mut MemoryDescriptor, *mut usize, *mut usize, *mut u32, ) -> Status; pub type EfiExitBootServices = unsafe extern "efiapi" fn(Handle, usize) -> Status; pub type EfiHandleProtocol = unsafe extern "efiapi" fn(Handle, *const Guid, *mut *mut c_void) -> Status; pub type EfiLocateProtocol = unsafe extern "efiapi" fn(*const Guid, *mut c_void, *mut *mut c_void) -> Status; pub type EfiAllocatePool = unsafe extern "efiapi" fn(u8, usize, *mut *mut c_void) -> Status; pub type EfiFreePool = unsafe extern "efiapi" fn(*mut c_void) -> Status; pub type EfiStall = unsafe extern "efiapi" fn(usize) -> Status; #[repr(C)] pub struct BootServices { pub hdr: TableHeader, // 0-1: task priority pub raise_tpl: *mut c_void, pub restore_tpl: *mut c_void, // 2-3: memory allocation pub allocate_pages: *mut c_void, pub free_pages: *mut c_void, // 4: GetMemoryMap pub get_memory_map: EfiGetMemoryMap, // 5-6: pool pub allocate_pool: EfiAllocatePool, pub free_pool: EfiFreePool, // 7-12: events pub create_event: *mut c_void, pub set_timer: *mut c_void, pub wait_for_event: *mut c_void, pub signal_event: *mut c_void, pub close_event: *mut c_void, pub check_event: *mut c_void, // 13-14: protocol install pub install_protocol_interface: *mut c_void, pub reinstall_protocol_interface: *mut c_void, pub uninstall_protocol_interface: *mut c_void, // 16: HandleProtocol pub handle_protocol: EfiHandleProtocol, pub _reserved: *mut c_void, // 18: register protocol notify pub register_protocol_notify: *mut c_void, // 19-21: locate pub locate_handle: *mut c_void, pub locate_device_path: *mut c_void, pub install_configuration_table: *mut c_void, // 22-23: image loading pub load_image: *mut c_void, pub start_image: *mut c_void, // 24-25 pub exit: *mut c_void, pub unload_image: *mut c_void, // 26: ExitBootServices pub exit_boot_services: EfiExitBootServices, // 27-29 pub get_next_monotonic_count: *mut c_void, pub stall: EfiStall, pub set_watchdog_timer: *mut c_void, // 30-36 pub connect_controller: *mut c_void, pub disconnect_controller: *mut c_void, pub open_protocol: *mut c_void, pub close_protocol: *mut c_void, pub open_protocol_information: *mut c_void, pub protocols_per_handle: *mut c_void, pub locate_handle_buffer: *mut c_void, // 37: LocateProtocol pub locate_protocol: EfiLocateProtocol, // 38-43 pub install_multiple_protocol_interfaces: *mut c_void, pub uninstall_multiple_protocol_interfaces: *mut c_void, pub calculate_crc32: *mut c_void, pub copy_mem: *mut c_void, pub set_mem: *mut c_void, pub create_event_ex: *mut c_void, } // --------------------------------------------------------------------------- // Graphics Output Protocol (GOP) // --------------------------------------------------------------------------- #[repr(C)] pub struct GopModeInfo { pub version: u32, pub horizontal_resolution: u32, pub vertical_resolution: u32, pub pixel_format: u32, // PixelFormat enum pub red_mask: u32, pub green_mask: u32, pub blue_mask: u32, pub reserved_mask: u32, pub pixels_per_scan_line: u32, } pub const PIXEL_RGB: u32 = 0; pub const PIXEL_BGR: u32 = 1; #[repr(C)] pub struct GopMode { pub max_mode: u32, pub mode: u32, pub info: *mut GopModeInfo, pub info_size: usize, pub framebuffer_base: *mut c_void, pub framebuffer_size: usize, } #[repr(C)] pub struct GraphicsOutputProtocol { pub query_mode: EfiGopQueryMode, pub set_mode: EfiGopSetMode, pub get_current_mode: EfiGopGetMode, pub mode: *mut GopMode, } pub type EfiGopQueryMode = unsafe extern "efiapi" fn( *mut GraphicsOutputProtocol, u32, // mode number *mut usize, // out: size of info *mut *mut GopModeInfo, // out: info pointer (firmware-owned) ) -> Status; pub type EfiGopSetMode = unsafe extern "efiapi" fn(*mut GraphicsOutputProtocol, u32) -> Status; pub type EfiGopGetMode = unsafe extern "efiapi" fn( *mut GraphicsOutputProtocol, *mut u32, // out: current mode *mut u32, // out: size of info *mut *mut GopModeInfo, // out: info pointer ) -> Status; // --------------------------------------------------------------------------- // System table // --------------------------------------------------------------------------- #[repr(C)] pub struct SystemTable { pub hdr: TableHeader, pub firmware_vendor: *const u16, pub firmware_revision: u32, pub console_in_handle: Handle, pub con_in: *mut SimpleTextInput, pub console_out_handle: Handle, pub con_out: *mut SimpleTextOutput, pub stderr_handle: Handle, pub std_err: *mut SimpleTextOutput, pub runtime_services: *mut RuntimeServices, pub boot_services: *mut BootServices, pub number_of_table_entries: usize, pub configuration_table: *const ConfigurationTable, }