1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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~;
}
|