diff options
| author | andromeda <andromeda@bsd.my.domain> | 2026-10-19 01:41:59 -0400 |
|---|---|---|
| committer | andromeda <andromeda@bsd.my.domain> | 2026-10-19 01:41:59 -0400 |
| commit | 7ebe14b3275fba00662e0c0ceeabe96343d04c5a (patch) | |
| tree | a594923a4073c1eb1db766d41da297a715220479 /lib/uefi.c3l/src/err.c3 | |
init
Diffstat (limited to 'lib/uefi.c3l/src/err.c3')
| -rw-r--r-- | lib/uefi.c3l/src/err.c3 | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/lib/uefi.c3l/src/err.c3 b/lib/uefi.c3l/src/err.c3 new file mode 100644 index 0000000..d21729b --- /dev/null +++ b/lib/uefi.c3l/src/err.c3 @@ -0,0 +1,129 @@ +/* EFI errors can actually be faults: they should raise exceptions + in the handling of a program, if the user so chooses to. */ +module uefi::efi_error; +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, // NOTE: UEFI spec is missing this definition. + UNKNOWN_30, // NOTE: 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::efi_warning; +faultdef + UNKNOWN_GLYPH, DELETE_FAILURE, WRITE_FAILURE, BUFFER_TOO_SMALL, STALE_DATA, FILE_SYSTEM, RESET_REQUIRED; + + +module uefi; + +import uefi::efi_error; +import uefi::efi_warning; + +/** EFI_STATUS enum (apx D of the UEFI 2.11 specification). */ +macro @efi_err($x) @private => (usz)((1l << ((usz::size * 8) - 1)) | $x); +macro @efi_warn($x) @private => (usz)$x; + +enum EfiStatus : usz (usz raw, fault fault_type) +{ + SUCCESS { 0, efi_error::NO_FAULT }, + + LOAD_ERROR { @efi_err(1), efi_error::LOAD_ERROR }, + INVALID_PARAMETER { @efi_err(2), efi_error::INVALID_PARAMETER }, + UNSUPPORTED { @efi_err(3), efi_error::UNSUPPORTED }, + BAD_BUFFER_SIZE { @efi_err(4), efi_error::BAD_BUFFER_SIZE }, + BUFFER_TOO_SMALL { @efi_err(5), efi_error::BUFFER_TOO_SMALL }, + NOT_READY { @efi_err(6), efi_error::NOT_READY }, + DEVICE_ERROR { @efi_err(7), efi_error::DEVICE_ERROR }, + WRITE_PROTECTED { @efi_err(8), efi_error::WRITE_PROTECTED }, + OUT_OF_RESOURCES { @efi_err(9), efi_error::OUT_OF_RESOURCES }, + VOLUME_CORRUPTED { @efi_err(10), efi_error::VOLUME_CORRUPTED }, + VOLUME_FULL { @efi_err(11), efi_error::VOLUME_FULL }, + NO_MEDIA { @efi_err(12), efi_error::NO_MEDIA }, + MEDIA_CHANGED { @efi_err(13), efi_error::MEDIA_CHANGED }, + NOT_FOUND { @efi_err(14), efi_error::NOT_FOUND }, + ACCESS_DENIED { @efi_err(15), efi_error::ACCESS_DENIED }, + NO_RESPONSE { @efi_err(16), efi_error::NO_RESPONSE }, + NO_MAPPING { @efi_err(17), efi_error::NO_MAPPING }, + TIMEOUT { @efi_err(18), efi_error::TIMEOUT }, + NOT_STARTED { @efi_err(19), efi_error::NOT_STARTED }, + ALREADY_STARTED { @efi_err(20), efi_error::ALREADY_STARTED }, + ABORTED { @efi_err(21), efi_error::ABORTED }, + ICMP_ERROR { @efi_err(22), efi_error::ICMP_ERROR }, + TFTP_ERROR { @efi_err(23), efi_error::TFTP_ERROR }, + PROTOCOL_ERROR { @efi_err(24), efi_error::PROTOCOL_ERROR }, + INCOMPATIBLE_VERSION { @efi_err(25), efi_error::INCOMPATIBLE_VERSION }, + SECURITY_VIOLATION { @efi_err(26), efi_error::SECURITY_VIOLATION }, + CRC_ERROR { @efi_err(27), efi_error::CRC_ERROR }, + END_OF_MEDIA { @efi_err(28), efi_error::END_OF_MEDIA }, + UNKNOWN_29 { @efi_err(29), efi_error::UNKNOWN_29 }, /* NOTE: UEFI spec is missing this definition. */ + UNKNOWN_30 { @efi_err(30), efi_error::UNKNOWN_30 }, /* NOTE: UEFI spec is missing this definition. */ + END_OF_FILE { @efi_err(31), efi_error::END_OF_FILE }, + INVALID_LANGUAGE { @efi_err(32), efi_error::INVALID_LANGUAGE }, + COMPROMISED_DATA { @efi_err(33), efi_error::COMPROMISED_DATA }, + IP_ADDRESS_CONFLICT { @efi_err(34), efi_error::IP_ADDRESS_CONFLICT }, + HTTP_ERROR { @efi_err(35), efi_error::HTTP_ERROR }, + + WARN_UNKNOWN_GLYPH { @efi_warn(1), efi_warning::UNKNOWN_GLYPH }, + WARN_DELETE_FAILURE { @efi_warn(2), efi_warning::DELETE_FAILURE }, + WARN_WRITE_FAILURE { @efi_warn(3), efi_warning::WRITE_FAILURE }, + WARN_BUFFER_TOO_SMALL { @efi_warn(4), efi_warning::BUFFER_TOO_SMALL }, + WARN_STALE_DATA { @efi_warn(5), efi_warning::STALE_DATA }, + WARN_FILE_SYSTEM { @efi_warn(6), efi_warning::FILE_SYSTEM }, + WARN_RESET_REQUIRED { @efi_warn(7), efi_warning::RESET_REQUIRED }, +} + + +// ////////////////////////////////////////////////////////////////////// +<* + Handle EFI errors when they occur. + @param status : `The EfiStatus code to check` + @param throw_on_warnings : `Return a ``true`` value on EFI_WARN_... codes` + @return ```false`` on success. ``true`` when ``throw_on_warnings`` is false and ``status`` is a warning. Returns a fault otherwise.` +*> +fn bool? efi_error(EfiStatus status, bool throw_on_warnings = true) @export("efi_error") @builtin +{ + switch + { + case status == SUCCESS: return false; + + case status >= EfiStatus.WARN_UNKNOWN_GLYPH && status <= EfiStatus.WARN_RESET_REQUIRED: + return throw_on_warnings ? status.fault_type~ : true; + + case status >= EfiStatus.LOAD_ERROR && status <= EfiStatus.HTTP_ERROR: + return status.fault_type~; + } + + return efi_error::UNKNOWN_STATUS~; +}
\ No newline at end of file |
