diff options
Diffstat (limited to 'lib/uefi.c3l/uefi')
| -rw-r--r-- | lib/uefi.c3l/uefi/guid.c3i | 29 | ||||
| -rw-r--r-- | lib/uefi.c3l/uefi/protocol/console.c3i | 173 | ||||
| -rw-r--r-- | lib/uefi.c3l/uefi/protocol/file.c3i | 59 | ||||
| -rw-r--r-- | lib/uefi.c3l/uefi/protocol/image.c3i | 23 | ||||
| -rw-r--r-- | lib/uefi.c3l/uefi/protocol/services/boot.c3i | 86 | ||||
| -rw-r--r-- | lib/uefi.c3l/uefi/protocol/services/mem.c3i | 36 | ||||
| -rw-r--r-- | lib/uefi.c3l/uefi/protocol/services/runtime.c3i | 36 | ||||
| -rw-r--r-- | lib/uefi.c3l/uefi/protocol/services/time.c3i | 31 | ||||
| -rw-r--r-- | lib/uefi.c3l/uefi/status.c3i | 174 | ||||
| -rw-r--r-- | lib/uefi.c3l/uefi/uefi.c3i | 59 |
10 files changed, 706 insertions, 0 deletions
diff --git a/lib/uefi.c3l/uefi/guid.c3i b/lib/uefi.c3l/uefi/guid.c3i new file mode 100644 index 0000000..928d6e1 --- /dev/null +++ b/lib/uefi.c3l/uefi/guid.c3i @@ -0,0 +1,29 @@ +module uefi; + +struct EfiGuid @packed { + uint data1; + ushort data2; + ushort data3; + char[8] data4; +} + +module uefi::guid; + +const EfiGuid SIMPLE_TEXT_INPUT_PROTOCOL = { 0x387477c1, 0x69c7, 0x11d2, {0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b} }; +const EfiGuid SIMPLE_TEXT_INPUT_EX_PROTOCOL = { 0xdd9e7534, 0x7762, 0x4698, {0x8c,0x14,0xf5,0x85,0x17,0xa6,0x25,0xaa} }; +const EfiGuid SIMPLE_TEXT_OUTPUT_PROTOCOL = { 0x387477c2, 0x69c7, 0x11d2, {0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b} }; + +const EfiGuid LOADED_IMAGE_PROTOCOL = {0x5b1b31A1, 0x9562, 0x11d2, {0x8E,0x3F,0x00,0xA0,0xC9,0x69,0x72,0x3B} }; +const EfiGuid SIMPLE_FILE_SYSTEM_PROTOCOL = {0x0964e5b22, 0x6459, 0x11d2, {0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b} }; +const EfiGuid FILE_INFO = {0x09576e92, 0x6d3f, 0x11d2, {0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b} }; +const EfiGuid FILE_SYSTEM_INFO = {0x09576e93, 0x6d3f, 0x11d2, {0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b} }; + +// Configuration tables +const EfiGuid ACPI_20_TABLE = { 0x8868e871, 0xe4f1, 0x11d3, {0xbc,0x22,0x00,0x80,0xc7,0x3c,0x88,0x81} }; + +macro bool @compare(EfiGuid #a, EfiGuid #b) { + return #a.data1 == #b.data1 + && #a.data2 == #b.data2 + && #a.data3 == #b.data3 + && #a.data4 == #b.data4; +} diff --git a/lib/uefi.c3l/uefi/protocol/console.c3i b/lib/uefi.c3l/uefi/protocol/console.c3i new file mode 100644 index 0000000..19faf2d --- /dev/null +++ b/lib/uefi.c3l/uefi/protocol/console.c3i @@ -0,0 +1,173 @@ +module uefi::protocol::console; + +import uefi; + +alias InputResetFn = fn EfiStatus (SimpleTextInputProtocol*, bool); +alias InputReadKeyFn = fn EfiStatus (SimpleTextInputProtocol*, EfiInputKey*); +alias InputResetExFn = fn EfiStatus(SimpleTextInputExProtocol*, bool); +alias InputReadKeyExFn = fn EfiStatus (SimpleTextInputExProtocol*, EfiKeyData*); +alias InputSetStateFn = fn EfiStatus (SimpleTextInputExProtocol*, KeyToggleState*); +alias InputRegisterKeystrokeNotifyFn = fn EfiStatus (SimpleTextInputExProtocol*, EfiKeyData*, KeyNotificationFunctionFn, void**); +alias InputUnregisterKeystrokeNotifyFn = fn EfiStatus (EfiKeyData*); +alias KeyNotificationFunctionFn = fn EfiStatus (EfiKeyData*); +alias OutputResetFn = fn EfiStatus (SimpleTextOutputProtocol*, bool); +alias OutputStringFn = fn EfiStatus (SimpleTextOutputProtocol*, EfiString); +alias OutputTestStringFn = fn EfiStatus (SimpleTextOutputProtocol*, EfiString); +alias OutputQueryModeFn = fn EfiStatus (SimpleTextOutputProtocol*, usz, usz*, usz*); +alias OutputSetModeFn = fn EfiStatus (SimpleTextOutputProtocol*, usz); +alias OutputSetAttributeFn = fn EfiStatus (SimpleTextOutputProtocol*, usz); +alias OutputClearScreenFn = fn EfiStatus (SimpleTextOutputProtocol*); +alias OutputSetCursorPositionFn = fn EfiStatus (SimpleTextOutputProtocol*, usz, usz); +alias OutputEnableCursorFn = fn EfiStatus (SimpleTextOutputProtocol*, bool); + +bitstruct ConsoleColor : char @bigendian { + TextColor background: 0..3; + TextColor foreground: 4..6; + // bit 7 is technically not used per spec +} + +enum ScanCode : ushort (ushort raw) { + NULL { 0x0000 }, + UP_ARROW { 0x0001 }, + DOWN_ARROW { 0x0002 }, + RIGHT_ARROW { 0x0003 }, + LEFT_ARROW { 0x0004 }, + HOME { 0x0005 }, + END { 0x0006 }, + INSERT { 0x0007 }, + DELETE { 0x0008 }, + PAGE_UP { 0x0009 }, + PAGE_DOWN { 0x000A }, + F1 { 0x000B }, + F2 { 0x000C }, + F3 { 0x000D }, + F4 { 0x000E }, + F5 { 0x000F }, + F6 { 0x0010 }, + F7 { 0x0011 }, + F8 { 0x0012 }, + F9 { 0x0013 }, + F10 { 0x0014 }, + F11 { 0x0015 }, + F12 { 0x0016 }, + ESCAPE { 0x0017 }, + PAUSE { 0x0048 }, + F13 { 0x0068 }, + F14 { 0x0069 }, + F15 { 0x006A }, + F16 { 0x006B }, + F17 { 0x006C }, + F18 { 0x006D }, + F19 { 0x006E }, + F20 { 0x006F }, + F21 { 0x0070 }, + F22 { 0x0071 }, + F23 { 0x0072 }, + F24 { 0x0073 }, + MUTE { 0x007F }, + VOLUME_UP { 0x0080 }, + VOLUME_DOWN { 0x0081 }, + BRIGHTNESS_UP { 0x0100 }, + BRIGHTNESS_DOWN { 0x0101 }, + SUSPEND { 0x0102 }, + HIBERNATE { 0x0103 }, + TOGGLE_DISPLAY { 0x0104 }, + RECOVERY { 0x0105 }, + EJECT { 0x0106 }, +} + +struct SimpleTextInputProtocol { + InputResetFn _reset; + InputReadKeyFn _read_key; + EfiEvent _event_wait_for_key; +} + +struct EfiInputKey { + ushort scanCode; + ushort unicodeChar; +} + +struct SimpleTextInputExProtocol { + InputResetExFn reset; + InputReadKeyExFn read_key; + EfiEvent event_wait_for_key; + InputSetStateFn set_state; + InputRegisterKeystrokeNotifyFn register_keystroke_notify; + InputUnregisterKeystrokeNotifyFn unregister_keystroke_notify; +} + +enum KeyShiftState : uint (uint raw) { + SHIFT_STATE_VALID { 0x8000_0000 }, + RIGHT_SHIFT_PRESSED { 0x0000_0001 }, + LEFT_SHIFT_PRESSED { 0x0000_0002 }, + RIGHT_CONTROL_PRESSED { 0x0000_0004 }, + LEFT_CONTROL_PRESSED { 0x0000_0008 }, + RIGHT_ALT_PRESSED { 0x0000_0010 }, + LEFT_ALT_PRESSED { 0x0000_0020 }, + RIGHT_LOGO_PRESSED { 0x0000_0040 }, + LEFT_LOGO_PRESSED { 0x0000_0080 }, + MENU_KEY_PRESSED { 0x0000_0100 }, + SYS_REQ_PRESSED { 0x0000_0200 }, +} + +enum KeyToggleState : char (char raw) { + TOGGLE_STATE_VALID { 0x80 }, + KEY_STATE_EXPOSED { 0x40 }, + SCROLL_LOCK_ACTIVE { 0x01 }, + NUM_LOCK_ACTIVE { 0x02 }, + CAPS_LOCK_ACTIVE { 0x04 }, +} + +struct EfiKeyState { + KeyShiftState keyShiftState; + KeyToggleState keyToggleState; +} + +struct EfiKeyData { + EfiInputKey key; + EfiKeyState keyState; +} + +struct SimpleTextOutputProtocol { + OutputResetFn _reset; + OutputStringFn _output_string; + OutputTestStringFn _test_string; + OutputQueryModeFn _query_mode; + OutputSetModeFn _set_mode; + OutputSetAttributeFn _set_attribute; + OutputClearScreenFn _clear_screen; + OutputSetCursorPositionFn _set_cursor_position; + OutputEnableCursorFn _enable_cursor; + TextMode* mode; +} + +struct TextMode { + int maxMode; + int currentMode; + int currentAttribute; + int currentCursorColumn; + int currentCursorRow; + bool isCursorVisible; +} + +enum TextColor : char (char raw) { + BLACK { 0x00 }, + BLUE { 0x01 }, + GREEN { 0x02 }, + CYAN { 0x03 }, + RED { 0x04 }, + MAGENTA { 0x05 }, + BROWN { 0x06 }, + LIGHT_GRAY { 0x07 }, + DARK_GRAY { 0x08 }, + LIGHT_BLUE { 0x09 }, + LIGHT_GREEN { 0x0A }, + LIGHT_CYAN { 0x0B }, + LIGHT_RED { 0x0C }, + LIGHT_MAGENTA { 0x0D }, + YELLOW { 0x0E }, + WHITE { 0x0F }, + +} + +macro char @efi_color($fg, $bg) @builtin @public => ($fg | ((0x07 & $bg) << 4)); diff --git a/lib/uefi.c3l/uefi/protocol/file.c3i b/lib/uefi.c3l/uefi/protocol/file.c3i new file mode 100644 index 0000000..72c56d7 --- /dev/null +++ b/lib/uefi.c3l/uefi/protocol/file.c3i @@ -0,0 +1,59 @@ +module uefi::protocol::file; + +import uefi; + +alias FileOpenFn = fn EfiStatus (FileProtocol*, FileProtocol** newHandle, WChar* fileName, ulong openMode, ulong attributes); +alias FileCloseFn = fn EfiStatus (FileProtocol*); +alias FileDeleteFn = fn EfiStatus (FileProtocol*); +alias FileReadFn = fn EfiStatus (FileProtocol*, usz*, void*); +alias FileWriteFn = fn EfiStatus (FileProtocol*, usz*, void*); +alias FileGetPositionFn = fn EfiStatus (FileProtocol*, ulong*); +alias FileSetPositionFn = fn EfiStatus (FileProtocol*, ulong); +alias FileGetInfoFn = fn EfiStatus (FileProtocol*, EfiGuid*, usz*, void*); +alias FileSetInfoFn = fn EfiStatus (FileProtocol*, EfiGuid*, usz, void*); +alias FileFlushFn = fn EfiStatus (FileProtocol*); + +alias FileSystemOpenVolumeFn = fn EfiStatus (FileSystemProtocol*, FileProtocol**); + +struct FileProtocol { + ulong revision; + FileOpenFn _open; + FileCloseFn _close; + FileDeleteFn _delete; + FileReadFn _read; + FileWriteFn _write; + FileGetPositionFn _get_position; + FileSetPositionFn _set_position; + FileGetInfoFn _get_info; + FileSetInfoFn _set_info; + FileFlushFn _flush; + void* _open_ex; + void* _read_ex; + void* _write_ex; + void* _flush_ex; +} + +struct FileSystemProtocol { + ulong revision; + FileSystemOpenVolumeFn _open_volume; +} + +struct FileInfo { + ulong size; + ulong fileSize; + ulong physicalSize; + EfiTime createTime; + EfiTime lastAccessTime; + EfiTime editTime; + ulong attribute; + WChar[*] filename; +} + +struct FileSystemInfo { + ulong size; + bool readOnly; + ulong volumeSize; + ulong freeSpace; + uint blockSize; + WChar[*] volumeLabel; +} diff --git a/lib/uefi.c3l/uefi/protocol/image.c3i b/lib/uefi.c3l/uefi/protocol/image.c3i new file mode 100644 index 0000000..5d28f32 --- /dev/null +++ b/lib/uefi.c3l/uefi/protocol/image.c3i @@ -0,0 +1,23 @@ +module uefi::protocol::image; + +import uefi; +import uefi::protocol::mem; + +struct LoadedImageProtocol { + uint revision; + EfiHandle parentHandle; + SystemTable* systemTable; + + EfiHandle deviceHandle; + void* filePath; + void* reserved; + + uint loadOptionsSize; + void* loadOptions; + + void* imageBase; + ulong imageSize; + MemoryType imageCodeType; + MemoryType imageDataType; + void* unload; +} diff --git a/lib/uefi.c3l/uefi/protocol/services/boot.c3i b/lib/uefi.c3l/uefi/protocol/services/boot.c3i new file mode 100644 index 0000000..c5b8e06 --- /dev/null +++ b/lib/uefi.c3l/uefi/protocol/services/boot.c3i @@ -0,0 +1,86 @@ +module uefi::protocol::boot_services; + +import uefi::protocol::mem; + +alias AllocatePagesFn = fn EfiStatus (AllocateType, MemoryType, usz, void**); +alias AllocatePoolFn = fn EfiStatus (MemoryType, usz, void**); +alias FreePagesFn = fn EfiStatus (uptr, usz); +alias FreePoolFn = fn EfiStatus (void*); +alias GetMemoryMapFn = fn EfiStatus (usz*, MemoryDescriptor*, usz*, usz*, uint*); +alias HandleProtocolFn = fn EfiStatus (EfiHandle, EfiGuid*, void**); +alias ExitBootServicesFn = fn EfiStatus (EfiHandle, usz); +alias CopyMemFn = fn void (void* dst, void* src, usz); +alias SetMemFn = fn void (void* buf, usz, char); + +module uefi; +import uefi::protocol::boot_services; + +struct BootServices @packed { + inline TableHeader header; + + // Task priority services + void* raise_tpl; + void* restore_tpl; + + // Memory services (uefi::protocol::mem) + AllocatePagesFn allocate_pages; + FreePagesFn free_pages; + GetMemoryMapFn get_memory_map; + AllocatePoolFn allocate_pool; + FreePoolFn free_pool; + + // Event and Timer services + void* create_event; + void* set_timer; + void* wait_for_event; + void* signal_event; + void* close_event; + void* check_event; + + // Protocol Handler services + void* install_protocol_interface; + void* reinstall_protocol_interface; + void* uninstall_protocol_interface; + HandleProtocolFn handle_protocol; + void* _reserved; + void* register_protocol_notify; + void* locate_handle; + void* locate_device_path; + void* install_configuration_table; + + // Image services + void* load_image; + void* start_image; + void* exit_image; + void* unload_image; + ExitBootServicesFn exit_boot_services; + + // Misc services + void* get_next_monotonic_count; + void* stall; + void* set_watchdog_timer; + + // Driver Support services + void* connect_controller; + void* disconnect_controller; + + // Open/Close Protocol services + void* open_protocol; + void* close_protocol; + void* open_protocol_information; + + // Library services + void* protocols_per_handle; + void* locate_handle_buffer; + void* locate_protocol; + void* install_multiple_protocol_interfaces; + void* uninstall_multiple_protocol_interfaces; + + // 32-bit CRC services + void* calculate_crc32; + + // More misc services + CopyMemFn copy_mem; + SetMemFn set_mem; + void* create_event_ex; +} diff --git a/lib/uefi.c3l/uefi/protocol/services/mem.c3i b/lib/uefi.c3l/uefi/protocol/services/mem.c3i new file mode 100644 index 0000000..8b47264 --- /dev/null +++ b/lib/uefi.c3l/uefi/protocol/services/mem.c3i @@ -0,0 +1,36 @@ +module uefi::protocol::mem; + +enum MemoryType : uint { + RESERVED, + LOADER_CODE, + LOADER_DATA, + BOOT_SERVICES_CODE, + BOOT_SERVICES_DATA, + RUNTIME_SERVICES_CODE, + RUNTIME_SERVICES_DATA, + CONVENTIONAL, + UNUSABLE, + ACPI_RECLAIM, + ACPI_NVS, + MEMORY_MAPPED_IO, + MEMORY_MAPPED_IO_PORT_SPACE, + PAL_CODE, + PERSISTENT, + UNACCEPTED, +} + +enum AllocateType { + ANY_PAGES, + MAX_ADDRESS, + ADDRESS, +} + +struct MemoryDescriptor { + MemoryType type; + uptr physicalStart; + uptr virtualStart; + ulong numberOfPages; + ulong attribute; + // reserved padding + ulong _rsvd; +} diff --git a/lib/uefi.c3l/uefi/protocol/services/runtime.c3i b/lib/uefi.c3l/uefi/protocol/services/runtime.c3i new file mode 100644 index 0000000..cb690ed --- /dev/null +++ b/lib/uefi.c3l/uefi/protocol/services/runtime.c3i @@ -0,0 +1,36 @@ +module uefi::protocol::runtime_services; + +alias ResetSystemFn = fn void (ResetType, EfiStatus, usz, void*); + +enum ResetType : uint { + COLD, + WARM, + SHUTDOWN, + PLATFORM_SPECIFIC, +} + +module uefi; +import uefi::protocol::runtime_services; +import uefi::protocol::time; + +struct RuntimeServices @packed { + inline TableHeader header; + + GetTimeFn get_time; + void* set_time; + void* get_wakeup_time; + void* set_wakeup_time; + + void* set_virtual_address_map; + void* convert_pointer; + + void* get_variable; + void* get_next_variable_name; + void* set_variable; + + void* get_next_high_monotonic_count; + ResetSystemFn reset_system; + void* update_capsule; + void* query_capsule_capabilities; + void* query_variable_info; +} diff --git a/lib/uefi.c3l/uefi/protocol/services/time.c3i b/lib/uefi.c3l/uefi/protocol/services/time.c3i new file mode 100644 index 0000000..e7e20bc --- /dev/null +++ b/lib/uefi.c3l/uefi/protocol/services/time.c3i @@ -0,0 +1,31 @@ +module uefi::protocol::time; + +const short UNSPECIFIED_TIMEZONE = 0x07FF; + +struct Time @packed { + ushort year; + char month; + char day; + char hour; + char minute; + char second; + char _pad1; + uint nanosecond; + short timezone; + DaylightFlags daylight; + char _pad2; +} + +bitstruct DaylightFlags : char { + bool adjust : 0; + bool inDaylight : 1; + char reserved : 2..7; +} + +struct TimeCapabilities @packed { + uint resolution; + uint accuracy; + bool setsToZero; +} + +alias GetTimeFn = fn EfiStatus (Time*, TimeCapabilities*); diff --git a/lib/uefi.c3l/uefi/status.c3i b/lib/uefi.c3l/uefi/status.c3i new file mode 100644 index 0000000..e846cdb --- /dev/null +++ b/lib/uefi.c3l/uefi/status.c3i @@ -0,0 +1,174 @@ +module uefi::status::error; + +// Errors +faultdef + NO_FAULT, + LOAD_ERROR, + INVALID_PARAMETER, + UNSUPPORTED, + 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, + TIMEOUT, + NOT_STARTED, + ALREADY_STARTED, + ABORTED, + ICMP_ERROR, + TFTP_ERROR, + PROTOCOL_ERROR, + INCOMPATIBLE_VERSION, + SECURITY_VIOLATION, + CRC_ERROR, + END_OF_MEDIA, + UNKNOWN_29, /* UEFI spec is missing this definition. */ + UNKNOWN_30, /* UEFI spec is missing this definition. */ + END_OF_FILE, + INVALID_LANGUAGE, + COMPROMISED_DATA, + IP_ADDRESS_CONFLICT, + HTTP_ERROR, + EFILIB_UNINITIALIZED, /* Used for efilib calls when init() hasn't been called. */ + UNKNOWN_STATUS; /* Fallback for an unknown status code. */ + +module uefi::status::warning; + +// Warnings +faultdef + UNKNOWN_GLYPH, + DELETE_FAILURE, + WRITE_FAILURE, + BUFFER_TOO_SMALL, + STALE_DATA, + FILE_SYSTEM, + RESET_REQUIRED; + +module uefi; + +import uefi::status; + +macro @efi_err($x) @private => (usz)((1ul << ((usz::size * 8) - 1)) | $x); +macro @from_efi_err(#x) @private => (usz)((#x ^ (1ul << ((usz::size * 8) - 1)))+7); // add 7 warning to get the right ordinal +macro @efi_warn($x) @private => (usz)$x; + +constdef EfiStatus : ulong { + SUCCESS, + WARN_UNKNOWN_GLYPH = @efi_warn(1), + WARN_DELETE_FAILURE, + WARN_WRITE_FAILURE, + WARN_BUFFER_TOO_SMALL, + WARN_STALE_DATA, + WARN_FILE_SYSTEM, + WARN_RESET_REQUIRED, + LOAD_ERROR = @efi_err(1), + INVALID_PARAMETER, + UNSUPPORTED, + 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, + TIMEOUT, + NOT_STARTED, + ALREADY_STARTED, + ABORTED, + ICMP_ERROR, + TFTP_ERROR, + PROTOCOL_ERROR, + INCOMPATIBLE_VERSION, + SECURITY_VIOLATION, + CRC_ERROR, + END_OF_MEDIA, + UNKNOWN_29, + UNKNOWN_30, + END_OF_FILE, + INVALID_LANGUAGE, + COMPROMISED_DATA, + IP_ADDRESS_CONFLICT, + HTTP_ERROR, +} + +enum EfiStatusInternal : ulong (usz raw, fault faultType) { + SUCCESS { 0, error::NO_FAULT }, + + WARN_UNKNOWN_GLYPH { @efi_warn(1), warning::UNKNOWN_GLYPH }, + WARN_DELETE_FAILURE { @efi_warn(2), warning::DELETE_FAILURE }, + WARN_WRITE_FAILURE { @efi_warn(3), warning::WRITE_FAILURE }, + WARN_BUFFER_TOO_SMALL { @efi_warn(4), warning::BUFFER_TOO_SMALL }, + WARN_STALE_DATA { @efi_warn(5), warning::STALE_DATA }, + WARN_FILE_SYSTEM { @efi_warn(6), warning::FILE_SYSTEM }, + WARN_RESET_REQUIRED { @efi_warn(7), warning::RESET_REQUIRED }, + + LOAD_ERROR { @efi_err(1), error::LOAD_ERROR }, + INVALID_PARAMETER { @efi_err(2), error::INVALID_PARAMETER }, + UNSUPPORTED { @efi_err(3), error::UNSUPPORTED }, + BAD_BUFFER_SIZE { @efi_err(4), error::BAD_BUFFER_SIZE }, + BUFFER_TOO_SMALL { @efi_err(5), error::BUFFER_TOO_SMALL }, + NOT_READY { @efi_err(6), error::NOT_READY }, + DEVICE_ERROR { @efi_err(7), error::DEVICE_ERROR }, + WRITE_PROTECTED { @efi_err(8), error::WRITE_PROTECTED }, + OUT_OF_RESOURCES { @efi_err(9), error::OUT_OF_RESOURCES }, + VOLUME_CORRUPTED { @efi_err(10), error::VOLUME_CORRUPTED }, + VOLUME_FULL { @efi_err(11), error::VOLUME_FULL }, + NO_MEDIA { @efi_err(12), error::NO_MEDIA }, + MEDIA_CHANGED { @efi_err(13), error::MEDIA_CHANGED }, + NOT_FOUND { @efi_err(14), error::NOT_FOUND }, + ACCESS_DENIED { @efi_err(15), error::ACCESS_DENIED }, + NO_RESPONSE { @efi_err(16), error::NO_RESPONSE }, + NO_MAPPING { @efi_err(17), error::NO_MAPPING }, + TIMEOUT { @efi_err(18), error::TIMEOUT }, + NOT_STARTED { @efi_err(19), error::NOT_STARTED }, + ALREADY_STARTED { @efi_err(20), error::ALREADY_STARTED }, + ABORTED { @efi_err(21), error::ABORTED }, + ICMP_ERROR { @efi_err(22), error::ICMP_ERROR }, + TFTP_ERROR { @efi_err(23), error::TFTP_ERROR }, + PROTOCOL_ERROR { @efi_err(24), error::PROTOCOL_ERROR }, + INCOMPATIBLE_VERSION { @efi_err(25), error::INCOMPATIBLE_VERSION }, + SECURITY_VIOLATION { @efi_err(26), error::SECURITY_VIOLATION }, + CRC_ERROR { @efi_err(27), error::CRC_ERROR }, + END_OF_MEDIA { @efi_err(28), error::END_OF_MEDIA }, + UNKNOWN_29 { @efi_err(29), error::UNKNOWN_29 }, /* UEFI spec is missing this definition. */ + UNKNOWN_30 { @efi_err(30), error::UNKNOWN_30 }, /* UEFI spec is missing this definition. */ + END_OF_FILE { @efi_err(31), error::END_OF_FILE }, + INVALID_LANGUAGE { @efi_err(32), error::INVALID_LANGUAGE }, + COMPROMISED_DATA { @efi_err(33), error::COMPROMISED_DATA }, + IP_ADDRESS_CONFLICT { @efi_err(34), error::IP_ADDRESS_CONFLICT }, + HTTP_ERROR { @efi_err(35), error::HTTP_ERROR }, +} + +<* + Handle EFI errors when they occur. +*> +macro bool? efi_error(EfiStatus status, bool catchWarnings = true) @builtin { + switch { + case status == SUCCESS: return false; + + case status >= EfiStatus.WARN_UNKNOWN_GLYPH && status <= EfiStatus.WARN_RESET_REQUIRED: + EfiStatusInternal statusInternal = EfiStatusInternal::from_ordinal((ulong)status); + return catchWarnings ? statusInternal.faultType~ : true; + + case status >= EfiStatus.LOAD_ERROR && status <= EfiStatus.HTTP_ERROR: + return EfiStatusInternal::from_ordinal(@from_efi_err((ulong)status)).faultType~; + } + + return error::UNKNOWN_STATUS~; +}
\ No newline at end of file diff --git a/lib/uefi.c3l/uefi/uefi.c3i b/lib/uefi.c3l/uefi/uefi.c3i new file mode 100644 index 0000000..ab215c2 --- /dev/null +++ b/lib/uefi.c3l/uefi/uefi.c3i @@ -0,0 +1,59 @@ +module uefi; + +alias EfiHandle = void*; +typedef EfiEvent = void*; + +struct TableHeader { + ulong signature; + uint revision; + uint headerSize; + uint crc32; + uint reserved; +} + +struct ConfigurationTable { + EfiGuid vendorGuid; + void* vendorTable; +} + +struct SystemTable { + TableHeader header; + EfiString firmwareVendor; + uint firmwareRevision; + EfiHandle consoleInHandle; + SimpleTextInputProtocol* conIn; + EfiHandle consoleOutHandle; + SimpleTextOutputProtocol* conOut; + EfiHandle standardErrorHandle; + SimpleTextOutputProtocol* stdErr; + RuntimeServices* runtimeServices; + BootServices* bootServices; + ulong numberOfTableEntries; + ConfigurationTable* configurationTable; +} + +alias WChar = ushort; +typedef EfiString = inline WChar*; +typedef WString = inline WChar[]; +macro WString @w(String $string) @builtin @public => $$wstr16($string); + +// Time related definitions +struct EfiTime @packed { + ushort year; + char month; + char day; + char hour; + char minute; + char second; + char _pad1; + uint nanosecond; + short timezone; + EfiDaylightFlags daylight; + char _pad2; +} + +bitstruct EfiDaylightFlags : char { + bool adjust : 0; + bool in_daylight : 1; + char reserved : 2..7; +} |
