ekern

ekern.git
git clone git://git.lenczewski.org/ekern.git
Log | Files | Refs | README | LICENSE

efi.h (26476B)


      1 /* UEFI definitions, generated from the uefi-2.10 docs
      2  * --
      3  *  see: https://uefi.org/specs/UEFI/2.10/index.html
      4  */
      5 
      6 #ifndef EFI_H
      7 #define EFI_H
      8 
      9 #define IN
     10 #define OUT
     11 #define OPTIONAL
     12 #define CONST const
     13 
     14 #define EFIAPI __attribute__((ms_abi))
     15 
     16 #include <stdalign.h>
     17 #include <stddef.h>
     18 #include <stdint.h>
     19 
     20 /* 2.3.1. Data Types
     21  * --
     22  *  see: https://uefi.org/specs/UEFI/2.10/02_Overview.html#data-types
     23  */
     24 
     25 typedef int8_t b8;
     26 
     27 #define true 1
     28 #define false 0
     29 
     30 typedef uint8_t u8;
     31 typedef uint16_t u16;
     32 typedef uint32_t u32;
     33 typedef uint64_t u64;
     34 // typedef uint128_t u128;
     35 typedef uintmax_t umm;
     36 
     37 typedef int8_t s8;
     38 typedef int16_t s16;
     39 typedef int32_t s32;
     40 typedef int64_t s64;
     41 // typedef int128_t s128;
     42 typedef intmax_t smm;
     43 
     44 typedef unsigned char c8;
     45 typedef uint16_t c16;
     46 
     47 typedef struct efi_guid {
     48 	alignas(u32) u8 vs[16];
     49 } efi_guid_t;
     50 
     51 #define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
     52 ((struct efi_guid) {.vs = { \
     53  ((a) >> 24) & 0xff, ((a) >> 16) & 0xff, ((a) >> 8) & 0xff, (a) & 0xff, \
     54  ((b) >> 8) & 0xff, (b) & 0xff, \
     55  ((c) >> 8) & 0xff, (c) & 0xff, \
     56  (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7), \
     57 }})
     58 
     59 typedef umm efi_status_t;
     60 
     61 typedef struct efi_handle {
     62 	void *v;
     63 } efi_handle_t;
     64 
     65 typedef struct efi_event {
     66 	void *v;
     67 } efi_event_t;
     68 
     69 typedef struct efi_lba {
     70 	u64 v;
     71 } efi_lba_t;
     72 
     73 typedef struct efi_tpl {
     74 	umm v;
     75 } efi_tpl_t;
     76 
     77 struct efi_mac_addr {
     78 	u8 vs[32];
     79 };
     80 
     81 struct efi_ipv4_addr {
     82 	u8 vs[4];
     83 };
     84 
     85 struct efi_ipv6_addr {
     86 	u8 vs[16];
     87 };
     88 
     89 union efi_ip_addr {
     90 	struct efi_ipv4_addr v4;
     91 	struct efi_ipv6_addr v6;
     92 };
     93 
     94 /* 4. EFI System Table
     95  * ---
     96  *  see: https://uefi.org/specs/UEFI/2.10/04_EFI_System_Table.html
     97  */
     98 
     99 #define EFI_IMAGE_ENTRY_POINT(name) \
    100 	efi_status_t (EFIAPI name) (IN efi_handle_t image_handle, \
    101 				    IN struct efi_system_table *system_table)
    102 
    103 struct efi_table_header {
    104 	u64 signature;
    105 	u32 revision;
    106 	u32 header_size;
    107 	u32 crc32;
    108 	u32 reserved0;
    109 };
    110 
    111 struct efi_system_table {
    112 	struct efi_table_header hdr;
    113 
    114 	c16 *firmware_vendor;
    115 	u32 firmware_revision;
    116 
    117 	efi_handle_t console_in_handle;
    118 	struct efi_simple_text_input_protocol *con_in;
    119 
    120 	efi_handle_t console_out_handle;
    121 	struct efi_simple_text_output_protocol *con_out;
    122 
    123 	efi_handle_t standard_error_handle;
    124 	struct efi_simple_text_output_protocol *std_err;
    125 
    126 	struct efi_runtime_services *runtime_services;
    127 	struct efi_boot_services *boot_services;
    128 
    129 	umm number_of_table_entries;
    130 	struct efi_configuration_table *configuration_table;
    131 };
    132 
    133 /* 4.6. EFI Configuration Table & Properties Table
    134  * ---
    135  *  see: https://uefi.org/specs/UEFI/2.10/04_EFI_System_Table.html#efi-configuration-table-properties-table
    136  */
    137 
    138 struct efi_configuration_table {
    139 	efi_guid_t vendor_guid;
    140 	void *vendor_table;
    141 };
    142 
    143 /* 7. Services - Boot Services
    144  * ---
    145  *  see: https://uefi.org/specs/UEFI/2.10/04_EFI_System_Table.html#efi-boot-services-table
    146  *  see: https://uefi.org/specs/UEFI/2.10/07_Services_Boot_Services.html
    147  */
    148 
    149 #define EVT_TIMER				0x80000000
    150 #define EVT_RUNTIME				0x40000000
    151 
    152 #define EVT_NOTIFY_WAIT				0x00000100
    153 #define EVT_NOTIFY_SIGNAL			0x00000200
    154 
    155 #define EVT_SIGNAL_EXIT_BOOT_SERVICES		0x00000201
    156 #define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE	0x60000202
    157 
    158 #define TPL_APPLICATION 4
    159 #define TPL_CALLBACK 8
    160 #define TPL_NOTIFY 16
    161 #define TPL_HIGH_LEVEL 31
    162 
    163 #define EFI_EVENT_NOTIFY(name) \
    164 	void (EFIAPI *name) (IN efi_event_t event, \
    165 			     IN void *context)
    166 
    167 typedef EFI_EVENT_NOTIFY(efi_event_notify_t);
    168 
    169 #define EFI_CREATE_EVENT(name) \
    170 	efi_status_t (EFIAPI *name) (IN u32 type, \
    171 				     IN efi_tpl_t notify_tpl, \
    172 				     IN efi_event_notify_t * OPTIONAL notify_function, \
    173 				     IN void * OPTIONAL notify_context, \
    174 				     OUT efi_event_t *event)
    175 
    176 #define EFI_EVENT_GROUP_EXIT_BOOT_SERVICES \
    177 	((efi_guid_t) {.vs = {0x27abf055, 0xb1b84c26, 0x8048748f, 0x37baa2df}})
    178 
    179 #define EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES \
    180 	((efi_guid_t) {.vs = {0x8be0e274, 0x39704b44, 0x80c51ab9, 0x502f3bfc}})
    181 
    182 #define EFI_EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE \
    183 	((efi_guid_t) {.vs = {0x13fa7698, 0xc83149c7, 0x87ea8f43, 0xfcc25196}})
    184 
    185 #define EFI_EVENT_GROUP_MEMORY_MAP_CHANGE \
    186 	((efi_guid_t) {.vs = {0x78bee926, 0x692f48fd, 0x9edb0142, 0x2ef0d7ab}})
    187 
    188 #define EFI_EVENT_GROUP_READY_TO_BOOT \
    189 	((efi_guid_t) {.vs = {0x7ce88fb3, 0x4bd74679, 0x87a8a8d8, 0xdee50d2b}})
    190 
    191 #define EFI_EVENT_GROUP_AFTER_READY_TO_BOOT \
    192 	((efi_guid_t) {.vs = {0x3a2a00ad, 0x98b94cdf, 0xa4787027, 0x77f1c10b}})
    193 
    194 #define EFI_EVENT_GROUP_RESET_SYSTEM \
    195 	((efi_guid_t) {.vs = {0x62ddaba56, 0x13fb485a, 0xa8daa3dd, 0x7912cb6b}})
    196 
    197 #define EFI_CREATE_EVENT_EX(name) \
    198 	efi_status_t (EFIAPI *name) (IN u32 type, \
    199 				     IN efi_tpl_t notify_tpl, \
    200 				     IN efi_event_notify_t * OPTIONAL notify_function, \
    201 				     IN void CONST * OPTIONAL notify_context, \
    202 				     IN efi_guid_t CONST * OPTIONAL event_group, \
    203 				     OUT efi_event_t *event)
    204 
    205 
    206 #define EFI_CLOSE_EVENT(name) \
    207 	efi_status_t (EFIAPI *name) (IN efi_event_t event)
    208 
    209 #define EFI_SIGNAL_EVENT(name) \
    210 	efi_status_t (EFIAPI *name) (IN efi_event_t event)
    211 
    212 #define EFI_WAIT_FOR_EVENT(name) \
    213 	efi_status_t (EFIAPI *name) (IN umm number_of_events, \
    214 				     IN efi_event_t *event, \
    215 				     OUT umm *index)
    216 
    217 #define EFI_CHECK_EVENT(name) \
    218 	efi_status_t (EFIAPI *name) (IN efi_event_t event)
    219 
    220 enum efi_timer_delay {
    221 	EFI_TIMER_CANCEL,
    222 	EFI_TIMER_PERIODIC,
    223 	EFI_TIMER_RELATIVE,
    224 };
    225 
    226 #define EFI_SET_TIMER(name) \
    227 	efi_status_t (EFIAPI *name) (IN efi_event_t event, \
    228 				     IN enum efi_timer_delay type, \
    229 				     IN u64 trigger_time)
    230 
    231 #define EFI_RAISE_TPL(name) \
    232 	efi_tpl_t (EFIAPI *name) (IN efi_tpl_t new_tpl)
    233 
    234 #define EFI_RESTORE_TPL(name) \
    235 	void (EFIAPI *name) (IN efi_tpl_t old_tpl)
    236 
    237 enum efi_allocate_type {
    238 	EFI_ALLOCATE_ANY_PAGES,
    239 	EFI_ALLOCATE_MAX_ADDRESS,
    240 	EFI_ALLOCATE_ADDRESS,
    241 	EFI_MAX_ALLOCATE_TYPE,
    242 };
    243 
    244 enum efi_memory_type {
    245 	EFI_RESERVED_MEMORY_TYPE,
    246 	EFI_LOADER_CODE,
    247 	EFI_LOADER_DATA,
    248 	EFI_BOOT_SERVICES_CODE,
    249 	EFI_BOOT_SERVICES_DATA,
    250 	EFI_RUNTIME_SERVICES_CODE,
    251 	EFI_RUNTIME_SERVICES_DATA,
    252 	EFI_CONVENTIONAL_MEMORY,
    253 	EFI_UNUSABLE_MEMORY,
    254 	EFI_ACPI_RECLAIM_MEMORY,
    255 	EFI_ACPI_MEMORY_NVS,
    256 	EFI_MEMORY_MAPPED_IO,
    257 	EFI_MEMORY_MAPPED_IO_PORT_SPACE,
    258 	EFI_PAL_CODE,
    259 	EFI_PERSISTENT_MEMORY,
    260 	EFI_UNACCEPTED_MEMORY_TYPE,
    261 	EFI_MAX_MEMORY_TYPE,
    262 };
    263 
    264 typedef struct efi_physical_address {
    265 	u64 v;
    266 } efi_physical_address_t;
    267 
    268 #define EFI_MEMORY_UC			0x0000000000000001
    269 #define EFI_MEMORY_WC			0x0000000000000002
    270 #define EFI_MEMORY_WT			0x0000000000000004
    271 #define EFI_MEMORY_WB			0x0000000000000008
    272 #define EFI_MEMORY_UCE			0x0000000000000010
    273 #define EFI_MEMORY_WP			0x0000000000001000
    274 #define EFI_MEMORY_RP			0x0000000000002000
    275 #define EFI_MEMORY_XP			0x0000000000004000
    276 #define EFI_MEMORY_NV			0x0000000000008000
    277 #define EFI_MEMORY_MORE_RELIABLE	0x0000000000010000
    278 #define EFI_MEMORY_RO			0x0000000000020000
    279 #define EFI_MEMORY_SP			0x0000000000040000
    280 #define EFI_MEMORY_CPU_CRYPTO		0x0000000000080000
    281 #define EFI_MEMORY_RUNTIME		0x8000000000000000
    282 #define EFI_MEMORY_ISA_VALID		0x4000000000000000
    283 #define EFI_MEMORY_ISA_MASK		0x0FFFF00000000000
    284 
    285 typedef struct efi_virtual_address {
    286 	u64 v;
    287 } efi_virtual_address_t;
    288 
    289 #define EFI_MEMORY_DESCRIPTOR_VERSION 1
    290 
    291 struct efi_memory_descriptor {
    292 	u32 type;
    293 	efi_physical_address_t physical_start;
    294 	efi_virtual_address_t virtual_start;
    295 	u64 number_of_pages;
    296 	u64 attribute;
    297 };
    298 
    299 #define EFI_ALLOCATE_PAGES(name) \
    300 	efi_status_t (EFIAPI *name) (IN enum efi_allocate_type type, \
    301 				     IN enum efi_memory_type memory_type, \
    302 				     IN umm pages, \
    303 				     IN OUT efi_physical_address_t *memory)
    304 
    305 #define EFI_FREE_PAGES(name) \
    306 	efi_status_t (EFIAPI *name) (IN efi_physical_address_t memory, \
    307 				     IN umm pages)
    308 
    309 #define EFI_GET_MEMORY_MAP(name) \
    310 	efi_status_t (EFIAPI *name) (IN OUT umm *memory_map_size, \
    311 				     OUT struct efi_memory_descriptor *memory_map, \
    312 				     OUT umm *map_key, \
    313 				     OUT umm *descriptor_size, \
    314 				     OUT u32 *descriptor_version)
    315 
    316 #define EFI_ALLOCATE_POOL(name) \
    317 	efi_status_t (EFIAPI *name) (IN enum efi_memory_type pool_type, \
    318 				     IN umm size, \
    319 				     OUT void **buffer)
    320 
    321 #define EFI_FREE_POOL(name) \
    322 	efi_status_t (EFIAPI *name) (IN void *buffer)
    323 
    324 enum efi_interface_type {
    325 	EFI_NATIVE_INTERFACE,
    326 };
    327 
    328 #define EFI_INSTALL_PROTOCOL_INTERFACE(name) \
    329 	efi_status_t (EFIAPI *name) (IN OUT efi_handle_t *handle, \
    330 				     IN efi_guid_t *protocol, \
    331 				     IN enum efi_interface_type interface_type, \
    332 				     IN void *interface)
    333 
    334 #define EFI_UNINSTALL_PROTOCOL_INTERFACE(name) \
    335 	efi_status_t (EFIAPI *name) (IN efi_handle_t handle, \
    336 				     IN efi_guid_t *protocol, \
    337 				     IN void *interface)
    338 
    339 #define EFI_REINSTALL_PROTOCOL_INTERFACE(name) \
    340 	efi_status_t (EFIAPI *name) (IN efi_handle_t handle, \
    341 				     IN efi_guid_t *protocol, \
    342 				     IN void *old_interface, \
    343 				     IN void *new_interface)
    344 
    345 #define EFI_REGISTER_PROTOCOL_NOTIFY(name) \
    346 	efi_status_t (EFIAPI *name) (IN efi_guid_t *protocol, \
    347 				     IN efi_event_t event, \
    348 				     OUT void **registration)
    349 
    350 enum efi_locate_search_type {
    351 	EFI_ALL_HANDLES,
    352 	EFI_BY_REGISTER_NOTIFY,
    353 	EFI_BY_PROTOCOL,
    354 };
    355 
    356 #define EFI_LOCATE_HANDLE(name) \
    357 	efi_status_t (EFIAPI *name) (IN enum efi_locate_search_type search_type, \
    358 				     IN efi_guid_t *OPTIONAL protocol, \
    359 				     IN void *OPTIONAL search_key, \
    360 				     IN OUT umm *buffer_size, \
    361 				     OUT efi_handle_t *buffer)
    362 
    363 #define EFI_HANDLE_PROTOCOL(name) \
    364 	efi_status_t (EFIAPI *name) (IN efi_handle_t handle, \
    365 				     IN efi_guid_t *protocol, \
    366 				     OUT void **interface)
    367 
    368 // TODO: implement definitions
    369 struct efi_device_path_protocol {
    370 	u8 type;
    371 	u8 subtype;
    372 	u8 length[2];
    373 };
    374 
    375 #define EFI_LOCATE_DEVICE_PATH(name) \
    376 	efi_status_t (EFIAPI *name) (IN efi_guid_t *protocol, \
    377 				     IN OUT struct efi_device_path_protocol **device_path, \
    378 				     OUT efi_handle_t *device)
    379 
    380 #define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL	0x00000001
    381 #define EFI_OPEN_PROTOCOL_GET_PROTOCOL		0x00000002
    382 #define EFI_OPEN_PROTOCOL_TEST_PROTOCOL		0x00000004
    383 #define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER	0x00000008
    384 #define EFI_OPEN_PROTOCOL_BY_DRIVER		0x00000010
    385 #define EFI_OPEN_PROTOCOL_EXCLUSIVE		0x00000020
    386 
    387 #define EFI_OPEN_PROTOCOL(name) \
    388 	efi_status_t (EFIAPI *name) (IN efi_handle_t handle, \
    389 				     IN efi_guid_t *protocol, \
    390 				     OUT void **OPTIONAL interface, \
    391 				     IN efi_handle_t agent_handle, \
    392 				     IN efi_handle_t controller_handle, \
    393 				     IN u32 attributes)
    394 
    395 #define EFI_CLOSE_PROTOCOL(name) \
    396 	efi_status_t (EFIAPI *name) (IN efi_handle_t handle, \
    397 				     IN efi_guid_t *protocol, \
    398 				     IN efi_handle_t agent_handle, \
    399 				     IN efi_handle_t controller_handle)
    400 
    401 struct efi_open_protocol_information_entry {
    402 	efi_handle_t agent_handle;
    403 	efi_handle_t controller_handle;
    404 	u32 attributes;
    405 	u32 open_count;
    406 };
    407 
    408 #define EFI_OPEN_PROTOCOL_INFORMATION(name) \
    409 	efi_status_t (EFIAPI *name) (IN efi_handle_t handle, \
    410 				     IN efi_guid_t *protocol, \
    411 				     OUT struct efi_open_protocol_information_entry **entry_buffer, \
    412 				     OUT umm *entry_count)
    413 
    414 #define EFI_CONNECT_CONTROLLER(name) \
    415 	efi_status_t (EFIAPI *name) (IN efi_handle_t controller_handle, \
    416 				     IN efi_handle_t *OPTIONAL driver_image_handle, \
    417 				     IN struct efi_device_path_protocol *OPTIONAL remaining_device_path, \
    418 				     IN b8 recursive)
    419 
    420 #define EFI_DISCONNECT_CONTROLLER(name) \
    421 	efi_status_t (EFIAPI *name) (IN efi_handle_t controller_handle, \
    422 				     IN efi_handle_t OPTIONAL driver_image_handle, \
    423 				     IN efi_handle_t OPTIONAL child_handle)
    424 
    425 #define EFI_PROTOCOLS_PER_HANDLE(name) \
    426 	efi_status_t (EFIAPI *name) (IN efi_handle_t handle, \
    427 				     OUT efi_guid_t ***protocol_buffer, \
    428 				     OUT umm *protocol_buffer_count)
    429 
    430 #define EFI_LOCATE_HANDLE_BUFFER(name) \
    431 	efi_status_t (EFIAPI *name) (IN enum efi_locate_search_type search_type, \
    432 				     IN efi_guid_t *OPTIONAL protocol, \
    433 				     IN void *OPTIONAL search_key, \
    434 				     OUT umm *no_handles, \
    435 				     OUT efi_handle_t **buffer)
    436 
    437 #define EFI_LOCATE_PROTOCOL(name) \
    438 	efi_status_t (EFIAPI *name) (IN efi_guid_t *protocol, \
    439 				     IN void *OPTIONAL registration, \
    440 				     OUT void **interface)
    441 
    442 #define EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES(name) \
    443 	efi_status_t (EFIAPI *name) (IN OUT efi_handle_t *handle, ...)
    444 
    445 #define EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES(name) \
    446 	efi_status_t (EFIAPI *name) (IN efi_handle_t handle, ...)
    447 
    448 #define EFI_IMAGE_LOAD(name) \
    449 	efi_status_t (EFIAPI *name) (IN b8 boot_policy, \
    450 				     IN efi_handle_t parent_image_handle, \
    451 				     IN struct efi_device_path_protocol *OPTIONAL device_path, \
    452 				     IN void *OPTIONAL source_buffer, \
    453 				     IN umm source_size, \
    454 				     OUT efi_handle_t *image_handle)
    455 
    456 #define EFI_IMAGE_START(name) \
    457 	efi_status_t (EFIAPI *name) (IN efi_handle_t image_handle, \
    458 				     OUT umm *exit_data_size, \
    459 				     OUT c16 **OPTIONAL exit_data)
    460 
    461 #define EFI_IMAGE_UNLOAD(name) \
    462 	efi_status_t (EFIAPI *name) (IN efi_handle_t image_handle)
    463 
    464 #define EFI_EXIT(name) \
    465 	efi_status_t (EFIAPI *name) (IN efi_handle_t image_handle, \
    466 				     IN efi_status_t exit_status, \
    467 				     IN umm exit_data_size, \
    468 				     IN c16 *OPTIONAL exit_data)
    469 
    470 #define EFI_EXIT_BOOT_SERVICES(name) \
    471 	efi_status_t (EFIAPI *name) (IN efi_handle_t image_handle, \
    472 				     IN umm map_key)
    473 
    474 #define EFI_SET_WATCHDOG_TIMER(name) \
    475 	efi_status_t (EFIAPI *name) (IN umm timeout, \
    476 				     IN u64 watchdog_code, \
    477 				     IN umm data_size, \
    478 				     IN c16 *OPTIONAL watchdog_data)
    479 
    480 #define EFI_STALL(name) \
    481 	efi_status_t (EFIAPI *name) (IN umm microseconds)
    482 
    483 #define EFI_COPY_MEM(name) \
    484 	efi_status_t (EFIAPI *name) (IN void *destination, \
    485 				     IN void *source, \
    486 				     IN umm length)
    487 
    488 #define EFI_SET_MEM(name) \
    489 	efi_status_t (EFIAPI *name) (IN void *buffer, \
    490 				     IN umm size, \
    491 				    IN u8 value)
    492 
    493 #define EFI_GET_NEXT_MONOTONIC_COUNT(name) \
    494 	efi_status_t (EFIAPI *name) (OUT u64 *count)
    495 
    496 #define EFI_INSTALL_CONFIGURATION_TABLE(name) \
    497 	efi_status_t (EFIAPI *name) (IN efi_guid_t *guid, \
    498 				     IN void *table)
    499 
    500 #define EFI_CALCULATE_CRC32(name) \
    501 	efi_status_t (EFIAPI *name) (IN void *data, \
    502 				     IN umm data_size, \
    503 				     OUT u32 *crc32)
    504 
    505 struct efi_boot_services {
    506 	struct efi_table_header hdr;
    507 
    508 	EFI_RAISE_TPL(raise_tpl);
    509 	EFI_RESTORE_TPL(restore_tpl);
    510 
    511 	EFI_ALLOCATE_PAGES(allocate_pages);
    512 	EFI_FREE_PAGES(free_pages);
    513 	EFI_GET_MEMORY_MAP(get_memory_map);
    514 	EFI_ALLOCATE_POOL(allocate_pool);
    515 	EFI_FREE_POOL(free_pool);
    516 
    517 	EFI_CREATE_EVENT(create_event);
    518 	EFI_SET_TIMER(set_timer);
    519 	EFI_WAIT_FOR_EVENT(wait_for_event);
    520 	EFI_SIGNAL_EVENT(signal_event);
    521 	EFI_CLOSE_EVENT(close_event);
    522 	EFI_CHECK_EVENT(check_event);
    523 
    524 	EFI_INSTALL_PROTOCOL_INTERFACE(install_protocol_interface);
    525 	EFI_REINSTALL_PROTOCOL_INTERFACE(reinstall_protocol_interface);
    526 	EFI_UNINSTALL_PROTOCOL_INTERFACE(uninstall_protocol_interface);
    527 	EFI_HANDLE_PROTOCOL(handle_protocol);
    528 	void *reserved0;
    529 	EFI_REGISTER_PROTOCOL_NOTIFY(register_protocol_notify);
    530 	EFI_LOCATE_HANDLE(locate_handle);
    531 	EFI_LOCATE_DEVICE_PATH(locate_device_path);
    532 	EFI_INSTALL_CONFIGURATION_TABLE(install_configuration_table);
    533 
    534 	EFI_IMAGE_LOAD(load_image);
    535 	EFI_IMAGE_START(start_image);
    536 	EFI_EXIT(exit);
    537 	EFI_IMAGE_UNLOAD(unload_image);
    538 	EFI_EXIT_BOOT_SERVICES(exit_boot_services);
    539 
    540 	EFI_GET_NEXT_MONOTONIC_COUNT(get_next_monotonic_count);
    541 	EFI_STALL(stall);
    542 	EFI_SET_WATCHDOG_TIMER(set_watchdog_timer);
    543 
    544 	//  EFI 1.1+
    545 	EFI_CONNECT_CONTROLLER(connect_controller);
    546 	EFI_DISCONNECT_CONTROLLER(disconnect_controller);
    547 
    548 	EFI_OPEN_PROTOCOL(open_protocol);
    549 	EFI_CLOSE_PROTOCOL(close_protocol);
    550 	EFI_OPEN_PROTOCOL_INFORMATION(open_protocol_information);
    551 	EFI_PROTOCOLS_PER_HANDLE(protocols_per_handle);
    552 	EFI_LOCATE_HANDLE_BUFFER(locate_handle_buffer);
    553 	EFI_LOCATE_PROTOCOL(locate_protocol);
    554 	EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES(install_multiple_protocol_interfaces);
    555 	EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES(uninstall_multiple_protocol_interfaces);
    556 
    557 	EFI_CALCULATE_CRC32(calculate_crc32);
    558 
    559 	EFI_COPY_MEM(copy_mem);
    560 	EFI_SET_MEM(set_mem);
    561 
    562 	// UEFI 2.0+
    563 	EFI_CREATE_EVENT_EX(create_event_ex);
    564 };
    565 
    566 /* 8. Services - Runtime Services
    567  * ---
    568  *  see: https://uefi.org/specs/UEFI/2.10/04_EFI_System_Table.html#efi-runtime-services-table
    569  *  see: https://uefi.org/specs/UEFI/2.10/08_Services_Runtime_Services.html
    570  */
    571 
    572 struct efi_time {
    573 	u16 year;		// 1999 - 9999
    574 	u8 month;		// 1 - 12
    575 	u8 day;			// 1 - 31
    576 	u8 hour;		// 0 - 23
    577 	u8 minute;		// 0 - 59
    578 	u8 second;		// 0 - 59
    579 	u8 pad1;
    580 	u32 nanosecond;		// 0 - 999,999,999
    581 	s16 timezone;		// -1440 - 1440 or 2047
    582 	u8 daylight;
    583 	u8 pad2;
    584 };
    585 
    586 #define EFI_TIME_ADJUST_DAYLIGHT 0x01
    587 #define EFI_TIME_IN_DAYLIGHT 0x02
    588 
    589 #define EFI_TIME_UNSPECIFIED_TIMEZONE 0x07ff
    590 
    591 #define EFI_VARIABLE_NON_VOLATILE				0x00000001
    592 #define EFI_VARIABLE_BOOTSERVICE_ACCESS				0x00000002
    593 #define EFI_VARIABLE_RUNTIME_ACCESS				0x00000004
    594 #define EFI_VARIABLE_HARDWARE_ERROR_RECORD			0x00000008
    595 
    596 // NOTE: deprecated
    597 //#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS		0x00000010
    598 
    599 #define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS	0x00000020
    600 #define EFI_VARIABLE_APPEND_WRITE				0x00000040
    601 #define EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS		0x00000080
    602 
    603 #define EFI_VARIABLE_AUTHENTICATION_3_CERT_ID_SHA256	1
    604 
    605 struct efi_variable_authentication_3_cert_id {
    606 	u8 type;
    607 	u32 id_size;
    608 	u8 id[];
    609 };
    610 
    611 #define EFI_GET_VARIABLE(name) \
    612 	efi_status_t (EFIAPI *name) (IN c16 *variable_name, \
    613 				     IN efi_guid_t *vendor_guid, \
    614 				     OUT u32 *OPTIONAL attributes, \
    615 				     IN OUT umm *data_size, \
    616 				     OUT void *OPTIONAL data)
    617 
    618 #define EFI_GET_NEXT_VARIABLE_NAME(name) \
    619 	efi_status_t (EFIAPI *name) (IN OUT umm *variable_name_size, \
    620 				     IN OUT c16 *variable_name, \
    621 				     IN OUT efi_guid_t *vendor_guid)
    622 
    623 struct win_certificate_uefi_guid {
    624 	u8 pad0; // TODO
    625 };
    626 
    627 struct efi_variable_authentication {
    628 	u64 monotonic_count;
    629 	struct win_certificate_uefi_guid auth_info;
    630 };
    631 
    632 struct efi_variable_authentication_2 {
    633 	struct efi_time time_stamp;
    634 	struct win_certificate_uefi_guid auth_info;
    635 };
    636 
    637 #define EFI_VARIABLE_AUTHENTICATION_3_TIMESTAMP_TYPE 1
    638 #define EFI_VARIABLE_AUTHENTICATION_3_NONCE_TYPE 2
    639 
    640 struct efi_variable_authentication_3 {
    641 	u8 version;
    642 	u8 type;
    643 	u32 metadata_size;
    644 	u32 flags;
    645 };
    646 
    647 struct efi_variable_authentication_3_nonce {
    648 	u32 nonce_size;
    649 	u8 nonce[];
    650 };
    651 
    652 #define EFI_SET_VARIABLE(name) \
    653 	efi_status_t (EFIAPI *name) (IN c16 *variable_name, \
    654 				     IN efi_guid_t *vendor_guid, \
    655 				     IN u32 attributes, \
    656 				     IN umm data_size, \
    657 				     IN void *data)
    658 
    659 #define EFI_QUERY_VARIABLE_INFO(name) \
    660 	efi_status_t (EFIAPI *name) (IN u32 attributes, \
    661 				     OUT u64 *maximum_variable_storage_size, \
    662 				     OUT u64 *remaining_variable_storage_size, \
    663 				     OUT u64 *maximum_variable_size)
    664 
    665 struct efi_time_capabilities {
    666 	u32 resolution;
    667 	u32 accuracy;
    668 	b8 sets_to_zero;
    669 };
    670 
    671 #define EFI_GET_TIME(name) \
    672 	efi_status_t (EFIAPI *name) (OUT struct efi_time *time, \
    673 				     OUT struct efi_time_capabilities * OPTIONAL capabilities)
    674 
    675 #define EFI_SET_TIME(name) \
    676 	efi_status_t (EFIAPI *name) (IN struct efi_time *time)
    677 
    678 #define EFI_GET_WAKEUP_TIME(name) \
    679 	efi_status_t (EFIAPI *name) (OUT b8 *enabled, \
    680 				     OUT b8 *pending, \
    681 				     OUT struct efi_time *time)
    682 
    683 #define EFI_SET_WAKEUP_TIME(name) \
    684 	efi_status_t (EFIAPI *name) (IN b8 enable, \
    685 				     IN struct efi_time * OPTIONAL time)
    686 
    687 #define EFI_SET_VIRTUAL_ADDRESS_MAP(name) \
    688 	efi_status_t (EFIAPI *name) (IN umm memory_map_size, \
    689 				     IN umm descriptor_size, \
    690 				     IN u32 descriptor_version, \
    691 				     IN struct efi_memory_descriptor *virtual_map)
    692 
    693 #define EFI_OPTIONAL_PTR	0x00000001
    694 
    695 #define EFI_CONVERT_POINTER(name) \
    696 	efi_status_t (EFIAPI *name) (IN umm debug_disposition, \
    697 				     IN void **address)
    698 
    699 enum efi_reset_type {
    700 	EFI_RESET_COLD,
    701 	EFI_RESET_WARM,
    702 	EFI_RESET_SHUTDOWN,
    703 	EFI_RESET_PLATFORM_SPECIFIC,
    704 };
    705 
    706 #define EFI_RESET_SYSTEM(name) \
    707 	void (EFIAPI *name) (IN enum efi_reset_type reset_type, \
    708 			     IN efi_status_t reset_status, \
    709 			     IN umm data_size, \
    710 			     IN void *OPTIONAL reset_data)
    711 
    712 #define EFI_GET_NEXT_HIGH_MONO_COUNT(name) \
    713 	efi_status_t (EFIAPI *name) (OUT u32 *high_count)
    714 
    715 struct efi_capsule_block_descriptor {
    716 	u64 length;
    717 	union {
    718 		efi_physical_address_t data_block;
    719 		efi_physical_address_t continuation_pointer;
    720 	};
    721 };
    722 
    723 struct efi_capsule_header {
    724 	efi_guid_t capsule_guid;
    725 	u32 header_size;
    726 	u32 flags;
    727 	u32 capsule_image_size;
    728 };
    729 
    730 #define CAPSULE_FLAGS_PERSIST_ACROSS_RESET	0x00010000
    731 #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE	0x00020000
    732 #define CAPSULE_FLAGS_INITIATE_RESET		0x00040000
    733 
    734 struct efi_capsule_table {
    735 	u32 capsule_array_number;
    736 	void *capsule_ptr[];
    737 };
    738 
    739 #define EFI_UPDATE_CAPSULE(name) \
    740 	efi_status_t (EFIAPI *name) (IN struct efi_capsule_header **capsule_header_array, \
    741 				     IN umm capsule_count, \
    742 				     IN efi_physical_address_t OPTIONAL scatter_gather_list)
    743 
    744 #define EFI_QUERY_CAPSULE_CAPABILITIES(name) \
    745 	efi_status_t (EFIAPI *name) (IN struct efi_capsule_header **capsule_header_array, \
    746 				     IN umm capsule_count, \
    747 				     OUT u64 *maxiumum_capsule_size, \
    748 				     OUT enum efi_reset_type *reset_type)
    749 
    750 struct efi_runtime_services {
    751 	struct efi_table_header hdr;
    752 
    753 	EFI_GET_TIME(get_time);
    754 	EFI_SET_TIME(set_time);
    755 	EFI_GET_WAKEUP_TIME(get_wakeup_time);
    756 	EFI_SET_WAKEUP_TIME(set_wakeup_time);
    757 
    758 	EFI_SET_VIRTUAL_ADDRESS_MAP(set_virtual_address_map);
    759 	EFI_CONVERT_POINTER(convert_pointer);
    760 
    761 	EFI_GET_VARIABLE(get_variable);
    762 	EFI_GET_NEXT_VARIABLE_NAME(get_next_variable_name);
    763 	EFI_SET_VARIABLE(set_variable);
    764 
    765 	EFI_GET_NEXT_HIGH_MONO_COUNT(get_next_high_monotonic_count);
    766 	EFI_RESET_SYSTEM(reset_system);
    767 
    768 	// UEFI 2.0+
    769 	EFI_UPDATE_CAPSULE(update_capsule);
    770 	EFI_QUERY_CAPSULE_CAPABILITIES(query_capsule_capabilities);
    771 
    772 	EFI_QUERY_VARIABLE_INFO(query_variable_info);
    773 };
    774 
    775 /* protocols
    776  * ===========================================================================
    777  */
    778 
    779 /* 12.3. Simple Text Input Protocol
    780  * ---
    781  *  see: https://uefi.org/specs/UEFI/2.10/12_Protocols_Console_Support.html#simple-text-input-protocol
    782  */
    783 
    784 #define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \
    785 	(efi_guid_t) {.vs = {0x387477c1, 0x69c711d2, 0x8e3900a0, 0xc969723b}}
    786 
    787 struct efi_input_key {
    788 	u16 scan_code;
    789 	c16 unicode_char;
    790 };
    791 
    792 #define EFI_INPUT_RESET(name) \
    793 	efi_status_t (EFIAPI *name) (IN struct efi_simple_text_input_protocol *this, \
    794 				     IN b8 extended_verification)
    795 
    796 #define EFI_INPUT_READ_KEY(name) \
    797 	efi_status_t (EFIAPI *name) (IN struct efi_simple_text_input_protocol *this, \
    798 				     OUT struct efi_input_key *key)
    799 
    800 struct efi_simple_text_input_protocol {
    801 	EFI_INPUT_RESET(reset);
    802 	EFI_INPUT_READ_KEY(read_key_stroke);
    803 	efi_event_t wait_for_key;
    804 };
    805 
    806 /* 12.4. Simple Text Output Protocol
    807  * ---
    808  *  see: https://uefi.org/specs/UEFI/2.10/12_Protocols_Console_Support.html#simple-text-output-protocol
    809  */
    810 
    811 #define EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID \
    812 	(efi_guid_t) {.vs = {0x387477c2, 0x69c711d2, 0x8e3900a0, 0xc969723b}}
    813 
    814 #define EFI_TEXT_RESET(name) \
    815 	efi_status_t (EFIAPI *name) (IN struct efi_simple_text_output_protocol *this, \
    816 				     IN b8 extended_verification)
    817 
    818 #define EFI_TEXT_STRING(name) \
    819 	efi_status_t (EFIAPI *name) (IN struct efi_simple_text_output_protocol *this, \
    820 				     IN c16 *string)
    821 
    822 #define EFI_TEXT_TEST_STRING(name) \
    823 	efi_status_t (EFIAPI *name) (IN struct efi_simple_text_output_protocol *this, \
    824 				     IN c16 *string)
    825 
    826 #define EFI_TEXT_QUERY_MODE(name) \
    827 	efi_status_t (EFIAPI *name) (IN struct efi_simple_text_output_protocol *this, \
    828 				     IN umm mode_number, \
    829 				     OUT umm *columns, \
    830 				     OUT umm *rows)
    831 
    832 #define EFI_TEXT_SET_MODE(name) \
    833 	efi_status_t (EFIAPI *name) (IN struct efi_simple_text_output_protocol *this, \
    834 				    IN umm mode)
    835 
    836 #define EFI_TEXT_SET_ATTRIBUTE(name) \
    837 	efi_status_t (EFIAPI *name) (IN struct efi_simple_text_output_protocol *this, \
    838 				     IN umm attribute)
    839 
    840 #define EFI_TEXT_CLEAR_SCREEN(name) \
    841 	efi_status_t (EFIAPI *name) (IN struct efi_simple_text_output_protocol *this)
    842 
    843 #define EFI_TEXT_SET_CURSOR_POSITION(name) \
    844 	efi_status_t (EFIAPI *name) (IN struct efi_simple_text_output_protocol *this, \
    845 				     IN umm column, \
    846 				     IN umm row)
    847 
    848 #define EFI_TEXT_ENABLE_CURSOR(name) \
    849 	efi_status_t (EFIAPI *name) (IN struct efi_simple_text_output_protocol *this, \
    850 				     IN b8 visible)
    851 
    852 struct efi_simple_text_output_mode {
    853 	s32 max_mode;
    854 	s32 mode;
    855 	s32 attribute;
    856 	s32 cursor_column;
    857 	s32 cursor_row;
    858 	b8 cursor_visible;
    859 };
    860 
    861 struct efi_simple_text_output_protocol {
    862 	EFI_TEXT_RESET(reset);
    863 	EFI_TEXT_STRING(output_string);
    864 	EFI_TEXT_TEST_STRING(test_string);
    865 	EFI_TEXT_QUERY_MODE(query_mode);
    866 	EFI_TEXT_SET_MODE(set_mode);
    867 	EFI_TEXT_SET_ATTRIBUTE(set_attribute);
    868 	EFI_TEXT_CLEAR_SCREEN(clear_screen);
    869 	EFI_TEXT_SET_CURSOR_POSITION(set_cursor_position);
    870 	EFI_TEXT_ENABLE_CURSOR(enable_cursor);
    871 	struct efi_simple_text_output_mode *mode;
    872 };
    873 
    874 /* Appendix D. Status Codes
    875  * --
    876  *  see: https://uefi.org/specs/UEFI/2.10/Apx_D_Status_Codes.html
    877  */
    878 
    879 #define EFI_ERROR		0x8000000000000000
    880 #define EFI_WARNING		0x0000000000000000
    881 
    882 #define EFIERR(err) (EFI_ERROR | (err))
    883 #define EFIWARN(err) (EFI_WARNING | (err))
    884 
    885 enum efi_status : u64 {
    886 	EFI_SUCCESS			= 0,
    887 
    888 	EFI_WARN_UNKNOWN_GLYPH		= EFIWARN(1),
    889 	EFI_WARN_DELETE_FAILURE		= EFIWARN(2),
    890 	EFI_WARN_WRITE_FAILURE		= EFIWARN(3),
    891 	EFI_WARN_BUFFER_TOO_SMALL	= EFIWARN(4),
    892 	EFI_WARN_STALE_DATA		= EFIWARN(5),
    893 	EFI_WARN_FILE_SYSTEM		= EFIWARN(6),
    894 	EFI_WARN_RESET_REQUIRED		= EFIWARN(7),
    895 
    896 	EFI_LOAD_ERROR			= EFIERR(1),
    897 	EFI_INVALID_PARAMETER		= EFIERR(2),
    898 	EFI_UNSUPPORTED			= EFIERR(3),
    899 	EFI_BAD_BUFFER_SIZE		= EFIERR(4),
    900 	EFI_BUFFER_TOO_SMALL		= EFIERR(5),
    901 	EFI_NOT_READY			= EFIERR(6),
    902 	EFI_DEVICE_ERROR		= EFIERR(7),
    903 	EFI_WRITE_PROTECTED		= EFIERR(8),
    904 	EFI_OUT_OF_RESOURCES		= EFIERR(9),
    905 	EFI_VOLUME_CORRUPTED		= EFIERR(10),
    906 	EFI_VOLUME_FULL			= EFIERR(11),
    907 	EFI_NO_MEDIA			= EFIERR(12),
    908 	EFI_MEDIA_CHANGED		= EFIERR(13),
    909 	EFI_NOT_FOUND			= EFIERR(14),
    910 	EFI_ACCESS_DENIED		= EFIERR(15),
    911 	EFI_NO_RESPONSE			= EFIERR(16),
    912 	EFI_NO_MAPPING			= EFIERR(17),
    913 	EFI_TIMEOUT			= EFIERR(18),
    914 	EFI_NOT_STARTED			= EFIERR(19),
    915 	EFI_ALREADY_STARTED		= EFIERR(20),
    916 	EFI_ABORTED			= EFIERR(21),
    917 	EFI_ICMP_ERROR			= EFIERR(22),
    918 	EFI_TFTP_ERROR			= EFIERR(23),
    919 	EFI_PROTOCOL_ERROR		= EFIERR(24),
    920 	EFI_INCOMPATIBLE_VERSION	= EFIERR(25),
    921 	EFI_SECURITY_VIOLATION		= EFIERR(26),
    922 	EFI_CRC_ERROR			= EFIERR(27),
    923 	EFI_END_OF_MEDIA		= EFIERR(28),
    924 	EFI_END_OF_FILE			= EFIERR(31),
    925 	EFI_INVALID_LANGUAGE		= EFIERR(32),
    926 	EFI_COMPROMISED_DATA		= EFIERR(33),
    927 	EFI_IP_ADDRESS_CONFLICT		= EFIERR(34),
    928 	EFI_HTTP_ERROR			= EFIERR(35),
    929 };
    930 
    931 #endif /* EFI_H */