diff options
Diffstat (limited to 'src/uefi.rs')
| -rw-r--r-- | src/uefi.rs | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/src/uefi.rs b/src/uefi.rs new file mode 100644 index 0000000..2e3ed6b --- /dev/null +++ b/src/uefi.rs | |||
| @@ -0,0 +1,289 @@ | |||
| 1 | use core::ffi::c_void; | ||
| 2 | |||
| 3 | /// Opaque EFI handle | ||
| 4 | pub type Handle = *mut c_void; | ||
| 5 | |||
| 6 | /// EFI status (0 = success, bit 63 = error code) | ||
| 7 | pub type Status = u64; | ||
| 8 | |||
| 9 | /// Helper: UEFI error codes always have bit 63 set | ||
| 10 | const fn efi_err(n: u64) -> u64 { | ||
| 11 | n | (1u64 << 63) | ||
| 12 | } | ||
| 13 | |||
| 14 | pub const EFI_SUCCESS: Status = 0; | ||
| 15 | pub const EFI_LOAD_ERROR: Status = efi_err(1); | ||
| 16 | pub const EFI_INVALID_PARAMETER: Status = efi_err(2); | ||
| 17 | #[allow(dead_code)] | ||
| 18 | pub const EFI_UNSUPPORTED: Status = efi_err(3); | ||
| 19 | pub const EFI_BUFFER_TOO_SMALL: Status = efi_err(5); | ||
| 20 | #[allow(dead_code)] | ||
| 21 | pub const EFI_NOT_FOUND: Status = efi_err(14); | ||
| 22 | pub const EFI_OUT_OF_RESOURCES: Status = efi_err(9); | ||
| 23 | |||
| 24 | // --------------------------------------------------------------------------- | ||
| 25 | // GUID | ||
| 26 | // --------------------------------------------------------------------------- | ||
| 27 | #[repr(C)] | ||
| 28 | #[derive(Debug, Clone, Copy)] | ||
| 29 | pub struct Guid { | ||
| 30 | pub a: u32, | ||
| 31 | pub b: u16, | ||
| 32 | pub c: u16, | ||
| 33 | pub d: [u8; 8], | ||
| 34 | } | ||
| 35 | |||
| 36 | pub const EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID: Guid = Guid { | ||
| 37 | a: 0x9042a9de, | ||
| 38 | b: 0x23dc, | ||
| 39 | c: 0x4a38, | ||
| 40 | d: [0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a], | ||
| 41 | }; | ||
| 42 | |||
| 43 | // --------------------------------------------------------------------------- | ||
| 44 | // Table header | ||
| 45 | // --------------------------------------------------------------------------- | ||
| 46 | #[repr(C)] | ||
| 47 | pub struct TableHeader { | ||
| 48 | pub signature: u64, | ||
| 49 | pub revision: u32, | ||
| 50 | pub header_size: u32, | ||
| 51 | pub crc32: u32, | ||
| 52 | pub reserved: u32, | ||
| 53 | } | ||
| 54 | |||
| 55 | // --------------------------------------------------------------------------- | ||
| 56 | // Simple text output protocol (console output) | ||
| 57 | // --------------------------------------------------------------------------- | ||
| 58 | #[repr(C)] | ||
| 59 | pub struct SimpleTextOutput { | ||
| 60 | _reset: *mut c_void, | ||
| 61 | pub output_string: unsafe extern "efiapi" fn(*mut SimpleTextOutput, *const u16) -> Status, | ||
| 62 | _test_string: *mut c_void, | ||
| 63 | _query_mode: *mut c_void, | ||
| 64 | _set_mode: *mut c_void, | ||
| 65 | _set_attribute: *mut c_void, | ||
| 66 | _clear_screen: *mut c_void, | ||
| 67 | _set_cursor_position: *mut c_void, | ||
| 68 | _enable_cursor: *mut c_void, | ||
| 69 | _mode: *mut c_void, | ||
| 70 | } | ||
| 71 | |||
| 72 | // --------------------------------------------------------------------------- | ||
| 73 | // Simple text input protocol (keyboard input) | ||
| 74 | // --------------------------------------------------------------------------- | ||
| 75 | #[repr(C)] | ||
| 76 | pub struct InputKey { | ||
| 77 | pub scan_code: u16, | ||
| 78 | pub unicode_char: u16, | ||
| 79 | } | ||
| 80 | |||
| 81 | #[repr(C)] | ||
| 82 | pub struct SimpleTextInput { | ||
| 83 | _reset: *mut c_void, | ||
| 84 | pub read_key_stroke: unsafe extern "efiapi" fn(*mut SimpleTextInput, *mut InputKey) -> Status, | ||
| 85 | _wait_for_key: Handle, | ||
| 86 | } | ||
| 87 | |||
| 88 | // --------------------------------------------------------------------------- | ||
| 89 | // Runtime services (stub — we don't use them) | ||
| 90 | // --------------------------------------------------------------------------- | ||
| 91 | #[repr(C)] | ||
| 92 | pub struct RuntimeServices { | ||
| 93 | _hdr: TableHeader, | ||
| 94 | _reserved: [*mut c_void; 30], | ||
| 95 | } | ||
| 96 | |||
| 97 | // --------------------------------------------------------------------------- | ||
| 98 | // Configuration table entry | ||
| 99 | // --------------------------------------------------------------------------- | ||
| 100 | #[repr(C)] | ||
| 101 | pub struct ConfigurationTable { | ||
| 102 | pub vendor_guid: Guid, | ||
| 103 | pub vendor_table: *mut c_void, | ||
| 104 | } | ||
| 105 | |||
| 106 | // --------------------------------------------------------------------------- | ||
| 107 | /// UEFI memory descriptor (from GetMemoryMap) | ||
| 108 | // --------------------------------------------------------------------------- | ||
| 109 | #[repr(C)] | ||
| 110 | pub struct MemoryDescriptor { | ||
| 111 | pub kind: u32, | ||
| 112 | pub pad: u32, | ||
| 113 | pub physical_start: u64, | ||
| 114 | pub virtual_start: u64, | ||
| 115 | pub number_of_pages: u64, | ||
| 116 | pub attribute: u64, | ||
| 117 | } | ||
| 118 | |||
| 119 | pub const MEMORY_TYPE_CONVENTIONAL: u32 = 7; | ||
| 120 | #[allow(dead_code)] | ||
| 121 | pub const MEMORY_TYPE_LOADER_DATA: u32 = 6; | ||
| 122 | #[allow(dead_code)] | ||
| 123 | pub const MEMORY_TYPE_BOOT_SERVICES_CODE: u32 = 3; | ||
| 124 | #[allow(dead_code)] | ||
| 125 | pub const MEMORY_TYPE_BOOT_SERVICES_DATA: u32 = 4; | ||
| 126 | |||
| 127 | // --------------------------------------------------------------------------- | ||
| 128 | // Boot services table | ||
| 129 | // --------------------------------------------------------------------------- | ||
| 130 | pub type EfiGetMemoryMap = unsafe extern "efiapi" fn( | ||
| 131 | *mut usize, | ||
| 132 | *mut MemoryDescriptor, | ||
| 133 | *mut usize, | ||
| 134 | *mut usize, | ||
| 135 | *mut u32, | ||
| 136 | ) -> Status; | ||
| 137 | |||
| 138 | pub type EfiExitBootServices = unsafe extern "efiapi" fn(Handle, usize) -> Status; | ||
| 139 | |||
| 140 | pub type EfiHandleProtocol = | ||
| 141 | unsafe extern "efiapi" fn(Handle, *const Guid, *mut *mut c_void) -> Status; | ||
| 142 | |||
| 143 | pub type EfiLocateProtocol = | ||
| 144 | unsafe extern "efiapi" fn(*const Guid, *mut c_void, *mut *mut c_void) -> Status; | ||
| 145 | |||
| 146 | pub type EfiAllocatePool = unsafe extern "efiapi" fn(u8, usize, *mut *mut c_void) -> Status; | ||
| 147 | |||
| 148 | pub type EfiFreePool = unsafe extern "efiapi" fn(*mut c_void) -> Status; | ||
| 149 | |||
| 150 | pub type EfiStall = unsafe extern "efiapi" fn(usize) -> Status; | ||
| 151 | |||
| 152 | #[repr(C)] | ||
| 153 | pub struct BootServices { | ||
| 154 | pub hdr: TableHeader, | ||
| 155 | |||
| 156 | // 0-1: task priority | ||
| 157 | pub raise_tpl: *mut c_void, | ||
| 158 | pub restore_tpl: *mut c_void, | ||
| 159 | |||
| 160 | // 2-3: memory allocation | ||
| 161 | pub allocate_pages: *mut c_void, | ||
| 162 | pub free_pages: *mut c_void, | ||
| 163 | |||
| 164 | // 4: GetMemoryMap | ||
| 165 | pub get_memory_map: EfiGetMemoryMap, | ||
| 166 | |||
| 167 | // 5-6: pool | ||
| 168 | pub allocate_pool: EfiAllocatePool, | ||
| 169 | pub free_pool: EfiFreePool, | ||
| 170 | |||
| 171 | // 7-12: events | ||
| 172 | pub create_event: *mut c_void, | ||
| 173 | pub set_timer: *mut c_void, | ||
| 174 | pub wait_for_event: *mut c_void, | ||
| 175 | pub signal_event: *mut c_void, | ||
| 176 | pub close_event: *mut c_void, | ||
| 177 | pub check_event: *mut c_void, | ||
| 178 | |||
| 179 | // 13-14: protocol install | ||
| 180 | pub install_protocol_interface: *mut c_void, | ||
| 181 | pub reinstall_protocol_interface: *mut c_void, | ||
| 182 | pub uninstall_protocol_interface: *mut c_void, | ||
| 183 | |||
| 184 | // 16: HandleProtocol | ||
| 185 | pub handle_protocol: EfiHandleProtocol, | ||
| 186 | |||
| 187 | pub _reserved: *mut c_void, | ||
| 188 | |||
| 189 | // 18: register protocol notify | ||
| 190 | pub register_protocol_notify: *mut c_void, | ||
| 191 | |||
| 192 | // 19-21: locate | ||
| 193 | pub locate_handle: *mut c_void, | ||
| 194 | pub locate_device_path: *mut c_void, | ||
| 195 | pub install_configuration_table: *mut c_void, | ||
| 196 | |||
| 197 | // 22-23: image loading | ||
| 198 | pub load_image: *mut c_void, | ||
| 199 | pub start_image: *mut c_void, | ||
| 200 | |||
| 201 | // 24-25 | ||
| 202 | pub exit: *mut c_void, | ||
| 203 | pub unload_image: *mut c_void, | ||
| 204 | |||
| 205 | // 26: ExitBootServices | ||
| 206 | pub exit_boot_services: EfiExitBootServices, | ||
| 207 | |||
| 208 | // 27-29 | ||
| 209 | pub get_next_monotonic_count: *mut c_void, | ||
| 210 | pub stall: EfiStall, | ||
| 211 | pub set_watchdog_timer: *mut c_void, | ||
| 212 | |||
| 213 | // 30-36 | ||
| 214 | pub connect_controller: *mut c_void, | ||
| 215 | pub disconnect_controller: *mut c_void, | ||
| 216 | pub open_protocol: *mut c_void, | ||
| 217 | pub close_protocol: *mut c_void, | ||
| 218 | pub open_protocol_information: *mut c_void, | ||
| 219 | pub protocols_per_handle: *mut c_void, | ||
| 220 | pub locate_handle_buffer: *mut c_void, | ||
| 221 | |||
| 222 | // 37: LocateProtocol | ||
| 223 | pub locate_protocol: EfiLocateProtocol, | ||
| 224 | |||
| 225 | // 38-43 | ||
| 226 | pub install_multiple_protocol_interfaces: *mut c_void, | ||
| 227 | pub uninstall_multiple_protocol_interfaces: *mut c_void, | ||
| 228 | pub calculate_crc32: *mut c_void, | ||
| 229 | pub copy_mem: *mut c_void, | ||
| 230 | pub set_mem: *mut c_void, | ||
| 231 | pub create_event_ex: *mut c_void, | ||
| 232 | } | ||
| 233 | |||
| 234 | // --------------------------------------------------------------------------- | ||
| 235 | // Graphics Output Protocol (GOP) | ||
| 236 | // --------------------------------------------------------------------------- | ||
| 237 | #[repr(C)] | ||
| 238 | pub struct GopModeInfo { | ||
| 239 | pub version: u32, | ||
| 240 | pub horizontal_resolution: u32, | ||
| 241 | pub vertical_resolution: u32, | ||
| 242 | pub pixel_format: u32, // PixelFormat enum | ||
| 243 | pub red_mask: u32, | ||
| 244 | pub green_mask: u32, | ||
| 245 | pub blue_mask: u32, | ||
| 246 | pub reserved_mask: u32, | ||
| 247 | pub pixels_per_scan_line: u32, | ||
| 248 | } | ||
| 249 | |||
| 250 | pub const PIXEL_RGB: u32 = 0; | ||
| 251 | pub const PIXEL_BGR: u32 = 1; | ||
| 252 | |||
| 253 | #[repr(C)] | ||
| 254 | pub struct GopMode { | ||
| 255 | pub max_mode: u32, | ||
| 256 | pub mode: u32, | ||
| 257 | pub info: *mut GopModeInfo, | ||
| 258 | pub info_size: usize, | ||
| 259 | pub framebuffer_base: *mut c_void, | ||
| 260 | pub framebuffer_size: usize, | ||
| 261 | } | ||
| 262 | |||
| 263 | #[repr(C)] | ||
| 264 | pub struct GraphicsOutputProtocol { | ||
| 265 | pub query_mode: *mut c_void, | ||
| 266 | pub set_mode: *mut c_void, | ||
| 267 | pub get_current_mode: *mut c_void, | ||
| 268 | pub mode: *mut GopMode, | ||
| 269 | } | ||
| 270 | |||
| 271 | // --------------------------------------------------------------------------- | ||
| 272 | // System table | ||
| 273 | // --------------------------------------------------------------------------- | ||
| 274 | #[repr(C)] | ||
| 275 | pub struct SystemTable { | ||
| 276 | pub hdr: TableHeader, | ||
| 277 | pub firmware_vendor: *const u16, | ||
| 278 | pub firmware_revision: u32, | ||
| 279 | pub console_in_handle: Handle, | ||
| 280 | pub con_in: *mut SimpleTextInput, | ||
| 281 | pub console_out_handle: Handle, | ||
| 282 | pub con_out: *mut SimpleTextOutput, | ||
| 283 | pub stderr_handle: Handle, | ||
| 284 | pub std_err: *mut SimpleTextOutput, | ||
| 285 | pub runtime_services: *mut RuntimeServices, | ||
| 286 | pub boot_services: *mut BootServices, | ||
| 287 | pub number_of_table_entries: usize, | ||
| 288 | pub configuration_table: *const ConfigurationTable, | ||
| 289 | } | ||
