summaryrefslogtreecommitdiff
path: root/lib/uefi.c3l/uefi
diff options
context:
space:
mode:
Diffstat (limited to 'lib/uefi.c3l/uefi')
-rw-r--r--lib/uefi.c3l/uefi/guid.c3i29
-rw-r--r--lib/uefi.c3l/uefi/protocol/console.c3i173
-rw-r--r--lib/uefi.c3l/uefi/protocol/file.c3i59
-rw-r--r--lib/uefi.c3l/uefi/protocol/image.c3i23
-rw-r--r--lib/uefi.c3l/uefi/protocol/services/boot.c3i86
-rw-r--r--lib/uefi.c3l/uefi/protocol/services/mem.c3i36
-rw-r--r--lib/uefi.c3l/uefi/protocol/services/runtime.c3i36
-rw-r--r--lib/uefi.c3l/uefi/protocol/services/time.c3i31
-rw-r--r--lib/uefi.c3l/uefi/status.c3i174
-rw-r--r--lib/uefi.c3l/uefi/uefi.c3i59
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;
+}