Skip to content

Commit 3ce9ed4

Browse files
authored
Merge pull request #768 from nicholasbishop/bishop-move-status-raw
Move `Status` to `uefi-raw`, along with related API changes
2 parents d38ef92 + 3cb29d6 commit 3ce9ed4

File tree

32 files changed

+413
-370
lines changed

32 files changed

+413
-370
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
- `Image::get_image_file_system` now returns a `fs::FileSystem` instead of the
3131
protocol.
3232
- `CString16::default` now always contains a null character.
33+
- Conversion from `Status` to `Result` has been reworked. The `into_with`,
34+
`into_with_val`, and `into_with_err` methods have been removed from
35+
`Status`. `impl From<Status> for Result` has also been removed. A new
36+
`StatusExt` trait has been added that provides conversion methods to replace
37+
the ones that have been removed. `StatusExt` has been added to the prelude.
3338

3439
## uefi-macros - [Unreleased]
3540

uefi-raw/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,7 @@
1616

1717
#[macro_use]
1818
mod enums;
19+
20+
mod status;
21+
22+
pub use status::Status;

uefi-raw/src/status.rs

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
use core::fmt::Debug;
2+
3+
newtype_enum! {
4+
/// UEFI uses status codes in order to report successes, errors, and warnings.
5+
///
6+
/// The spec allows implementation-specific status codes, so the `Status`
7+
/// constants are not a comprehensive list of all possible values.
8+
#[must_use]
9+
pub enum Status: usize => {
10+
/// The operation completed successfully.
11+
SUCCESS = 0,
12+
13+
/// The string contained characters that could not be rendered and were skipped.
14+
WARN_UNKNOWN_GLYPH = 1,
15+
/// The handle was closed, but the file was not deleted.
16+
WARN_DELETE_FAILURE = 2,
17+
/// The handle was closed, but the data to the file was not flushed properly.
18+
WARN_WRITE_FAILURE = 3,
19+
/// The resulting buffer was too small, and the data was truncated.
20+
WARN_BUFFER_TOO_SMALL = 4,
21+
/// The data has not been updated within the timeframe set by local policy.
22+
WARN_STALE_DATA = 5,
23+
/// The resulting buffer contains UEFI-compliant file system.
24+
WARN_FILE_SYSTEM = 6,
25+
/// The operation will be processed across a system reset.
26+
WARN_RESET_REQUIRED = 7,
27+
28+
/// The image failed to load.
29+
LOAD_ERROR = Self::ERROR_BIT | 1,
30+
/// A parameter was incorrect.
31+
INVALID_PARAMETER = Self::ERROR_BIT | 2,
32+
/// The operation is not supported.
33+
UNSUPPORTED = Self::ERROR_BIT | 3,
34+
/// The buffer was not the proper size for the request.
35+
BAD_BUFFER_SIZE = Self::ERROR_BIT | 4,
36+
/// The buffer is not large enough to hold the requested data.
37+
/// The required buffer size is returned in the appropriate parameter.
38+
BUFFER_TOO_SMALL = Self::ERROR_BIT | 5,
39+
/// There is no data pending upon return.
40+
NOT_READY = Self::ERROR_BIT | 6,
41+
/// The physical device reported an error while attempting the operation.
42+
DEVICE_ERROR = Self::ERROR_BIT | 7,
43+
/// The device cannot be written to.
44+
WRITE_PROTECTED = Self::ERROR_BIT | 8,
45+
/// A resource has run out.
46+
OUT_OF_RESOURCES = Self::ERROR_BIT | 9,
47+
/// An inconstency was detected on the file system.
48+
VOLUME_CORRUPTED = Self::ERROR_BIT | 10,
49+
/// There is no more space on the file system.
50+
VOLUME_FULL = Self::ERROR_BIT | 11,
51+
/// The device does not contain any medium to perform the operation.
52+
NO_MEDIA = Self::ERROR_BIT | 12,
53+
/// The medium in the device has changed since the last access.
54+
MEDIA_CHANGED = Self::ERROR_BIT | 13,
55+
/// The item was not found.
56+
NOT_FOUND = Self::ERROR_BIT | 14,
57+
/// Access was denied.
58+
ACCESS_DENIED = Self::ERROR_BIT | 15,
59+
/// The server was not found or did not respond to the request.
60+
NO_RESPONSE = Self::ERROR_BIT | 16,
61+
/// A mapping to a device does not exist.
62+
NO_MAPPING = Self::ERROR_BIT | 17,
63+
/// The timeout time expired.
64+
TIMEOUT = Self::ERROR_BIT | 18,
65+
/// The protocol has not been started.
66+
NOT_STARTED = Self::ERROR_BIT | 19,
67+
/// The protocol has already been started.
68+
ALREADY_STARTED = Self::ERROR_BIT | 20,
69+
/// The operation was aborted.
70+
ABORTED = Self::ERROR_BIT | 21,
71+
/// An ICMP error occurred during the network operation.
72+
ICMP_ERROR = Self::ERROR_BIT | 22,
73+
/// A TFTP error occurred during the network operation.
74+
TFTP_ERROR = Self::ERROR_BIT | 23,
75+
/// A protocol error occurred during the network operation.
76+
PROTOCOL_ERROR = Self::ERROR_BIT | 24,
77+
/// The function encountered an internal version that was
78+
/// incompatible with a version requested by the caller.
79+
INCOMPATIBLE_VERSION = Self::ERROR_BIT | 25,
80+
/// The function was not performed due to a security violation.
81+
SECURITY_VIOLATION = Self::ERROR_BIT | 26,
82+
/// A CRC error was detected.
83+
CRC_ERROR = Self::ERROR_BIT | 27,
84+
/// Beginning or end of media was reached
85+
END_OF_MEDIA = Self::ERROR_BIT | 28,
86+
/// The end of the file was reached.
87+
END_OF_FILE = Self::ERROR_BIT | 31,
88+
/// The language specified was invalid.
89+
INVALID_LANGUAGE = Self::ERROR_BIT | 32,
90+
/// The security status of the data is unknown or compromised and
91+
/// the data must be updated or replaced to restore a valid security status.
92+
COMPROMISED_DATA = Self::ERROR_BIT | 33,
93+
/// There is an address conflict address allocation
94+
IP_ADDRESS_CONFLICT = Self::ERROR_BIT | 34,
95+
/// A HTTP error occurred during the network operation.
96+
HTTP_ERROR = Self::ERROR_BIT | 35,
97+
}}
98+
99+
impl Status {
100+
/// Bit indicating that an UEFI status code is an error.
101+
pub const ERROR_BIT: usize = 1 << (core::mem::size_of::<usize>() * 8 - 1);
102+
103+
/// Returns true if status code indicates success.
104+
#[inline]
105+
#[must_use]
106+
pub fn is_success(self) -> bool {
107+
self == Status::SUCCESS
108+
}
109+
110+
/// Returns true if status code indicates a warning.
111+
#[inline]
112+
#[must_use]
113+
pub fn is_warning(self) -> bool {
114+
(self != Status::SUCCESS) && (self.0 & Self::ERROR_BIT == 0)
115+
}
116+
117+
/// Returns true if the status code indicates an error.
118+
#[inline]
119+
#[must_use]
120+
pub const fn is_error(self) -> bool {
121+
self.0 & Self::ERROR_BIT != 0
122+
}
123+
}
124+
125+
impl core::fmt::Display for Status {
126+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
127+
Debug::fmt(self, f)
128+
}
129+
}

uefi-services/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ pub fn init(st: &mut SystemTable<Boot>) -> Result {
8282
unsafe {
8383
// Avoid double initialization.
8484
if SYSTEM_TABLE.is_some() {
85-
return Status::SUCCESS.into();
85+
return Status::SUCCESS.to_result();
8686
}
8787

8888
// Setup the system table singleton

uefi/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ pub use self::data_types::{CStr16, CStr8, Char16, Char8, Event, Guid, Handle, Id
103103
pub use uefi_macros::{cstr16, cstr8, entry, guid};
104104

105105
mod result;
106-
pub use self::result::{Error, Result, ResultExt, Status};
106+
pub use self::result::{Error, Result, ResultExt, Status, StatusExt};
107107

108108
pub mod table;
109109

uefi/src/mem.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ pub(crate) fn make_boxed<
108108
#[cfg(test)]
109109
mod tests {
110110
use super::*;
111-
use crate::ResultExt;
111+
use crate::{ResultExt, StatusExt};
112112
#[cfg(feature = "unstable")]
113113
use alloc::alloc::Global;
114114
use core::mem::{align_of, size_of};
@@ -146,7 +146,7 @@ mod tests {
146146

147147
if buf.len() < required_size {
148148
// We can use an zero-length buffer to find the required size.
149-
return Status::BUFFER_TOO_SMALL.into_with(|| panic!(), |_| Some(required_size));
149+
return Status::BUFFER_TOO_SMALL.to_result_with(|| panic!(), |_| Some(required_size));
150150
};
151151

152152
// assert alignment

uefi/src/prelude.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//!
33
//! This includes the system table types, `Status` codes, etc.
44
5-
pub use crate::{Handle, ResultExt, Status};
5+
pub use crate::{Handle, ResultExt, Status, StatusExt};
66

77
// Import the basic table types.
88
pub use crate::table::boot::BootServices;

uefi/src/proto/console/gop.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
5353
use crate::proto::unsafe_protocol;
5454
use crate::util::usize_from_u32;
55-
use crate::{Result, Status};
55+
use crate::{Result, Status, StatusExt};
5656
use core::fmt::{Debug, Formatter};
5757
use core::marker::PhantomData;
5858
use core::{mem, ptr};
@@ -94,7 +94,7 @@ impl GraphicsOutput {
9494
let mut info_sz = 0;
9595
let mut info = ptr::null();
9696

97-
(self.query_mode)(self, index, &mut info_sz, &mut info).into_with_val(|| {
97+
(self.query_mode)(self, index, &mut info_sz, &mut info).to_result_with_val(|| {
9898
let info = unsafe { *info };
9999
Mode {
100100
index,
@@ -119,7 +119,7 @@ impl GraphicsOutput {
119119
///
120120
/// This function will invalidate the current framebuffer.
121121
pub fn set_mode(&mut self, mode: &Mode) -> Result {
122-
(self.set_mode)(self, mode.index).into()
122+
(self.set_mode)(self, mode.index).to_result()
123123
}
124124

125125
/// Performs a blt (block transfer) operation on the frame buffer.
@@ -147,7 +147,7 @@ impl GraphicsOutput {
147147
height,
148148
0,
149149
)
150-
.into()
150+
.to_result()
151151
}
152152
BltOp::VideoToBltBuffer {
153153
buffer,
@@ -170,7 +170,7 @@ impl GraphicsOutput {
170170
height,
171171
0,
172172
)
173-
.into(),
173+
.to_result(),
174174
BltRegion::SubRectangle {
175175
coords: (dest_x, dest_y),
176176
px_stride,
@@ -186,7 +186,7 @@ impl GraphicsOutput {
186186
height,
187187
px_stride * core::mem::size_of::<BltPixel>(),
188188
)
189-
.into(),
189+
.to_result(),
190190
}
191191
}
192192
BltOp::BufferToVideo {
@@ -210,7 +210,7 @@ impl GraphicsOutput {
210210
height,
211211
0,
212212
)
213-
.into(),
213+
.to_result(),
214214
BltRegion::SubRectangle {
215215
coords: (src_x, src_y),
216216
px_stride,
@@ -226,7 +226,7 @@ impl GraphicsOutput {
226226
height,
227227
px_stride * core::mem::size_of::<BltPixel>(),
228228
)
229-
.into(),
229+
.to_result(),
230230
}
231231
}
232232
BltOp::VideoToVideo {
@@ -248,7 +248,7 @@ impl GraphicsOutput {
248248
height,
249249
0,
250250
)
251-
.into()
251+
.to_result()
252252
}
253253
}
254254
}

uefi/src/proto/console/pointer/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Pointer device access.
22
33
use crate::proto::unsafe_protocol;
4-
use crate::{Event, Result, Status};
4+
use crate::{Event, Result, Status, StatusExt};
55
use core::mem::MaybeUninit;
66

77
/// Provides information about a pointer device.
@@ -24,7 +24,7 @@ impl Pointer {
2424
///
2525
/// - `DeviceError` if the device is malfunctioning and cannot be reset.
2626
pub fn reset(&mut self, extended_verification: bool) -> Result {
27-
(self.reset)(self, extended_verification).into()
27+
(self.reset)(self, extended_verification).to_result()
2828
}
2929

3030
/// Retrieves the pointer device's current state, if a state change occurred
@@ -40,7 +40,7 @@ impl Pointer {
4040

4141
match (self.get_state)(self, pointer_state.as_mut_ptr()) {
4242
Status::NOT_READY => Ok(None),
43-
other => other.into_with_val(|| unsafe { Some(pointer_state.assume_init()) }),
43+
other => other.to_result_with_val(|| unsafe { Some(pointer_state.assume_init()) }),
4444
}
4545
}
4646

uefi/src/proto/console/serial.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use core::fmt::Write;
44

55
use crate::proto::unsafe_protocol;
6-
use crate::{Result, Status};
6+
use crate::{Result, Status, StatusExt};
77
use bitflags::bitflags;
88

99
/// Provides access to a serial I/O device.
@@ -39,7 +39,7 @@ pub struct Serial {
3939
impl Serial {
4040
/// Reset the device.
4141
pub fn reset(&mut self) -> Result {
42-
(self.reset)(self).into()
42+
(self.reset)(self).to_result()
4343
}
4444

4545
/// Returns the current I/O mode.
@@ -71,21 +71,21 @@ impl Serial {
7171
mode.data_bits as u8,
7272
mode.stop_bits,
7373
)
74-
.into()
74+
.to_result()
7575
}
7676

7777
/// Retrieve the device's current control bits.
7878
pub fn get_control_bits(&self) -> Result<ControlBits> {
7979
let mut bits = ControlBits::empty();
80-
(self.get_control_bits)(self, &mut bits).into_with_val(|| bits)
80+
(self.get_control_bits)(self, &mut bits).to_result_with_val(|| bits)
8181
}
8282

8383
/// Sets the device's new control bits.
8484
///
8585
/// Not all bits can be modified with this function. A mask of the allowed
8686
/// bits is stored in the [`ControlBits::SETTABLE`] constant.
8787
pub fn set_control_bits(&mut self, bits: ControlBits) -> Result {
88-
(self.set_control_bits)(self, bits).into()
88+
(self.set_control_bits)(self, bits).to_result()
8989
}
9090

9191
/// Reads data from this device.
@@ -95,7 +95,7 @@ impl Serial {
9595
/// bytes were actually read from the device.
9696
pub fn read(&mut self, data: &mut [u8]) -> Result<(), usize> {
9797
let mut buffer_size = data.len();
98-
unsafe { (self.read)(self, &mut buffer_size, data.as_mut_ptr()) }.into_with(
98+
unsafe { (self.read)(self, &mut buffer_size, data.as_mut_ptr()) }.to_result_with(
9999
|| debug_assert_eq!(buffer_size, data.len()),
100100
|_| buffer_size,
101101
)
@@ -108,7 +108,7 @@ impl Serial {
108108
/// were actually written to the device.
109109
pub fn write(&mut self, data: &[u8]) -> Result<(), usize> {
110110
let mut buffer_size = data.len();
111-
unsafe { (self.write)(self, &mut buffer_size, data.as_ptr()) }.into_with(
111+
unsafe { (self.write)(self, &mut buffer_size, data.as_ptr()) }.to_result_with(
112112
|| debug_assert_eq!(buffer_size, data.len()),
113113
|_| buffer_size,
114114
)

uefi/src/proto/console/text/input.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::proto::unsafe_protocol;
2-
use crate::{Char16, Event, Result, Status};
2+
use crate::{Char16, Event, Result, Status, StatusExt};
33
use core::mem::MaybeUninit;
44

55
/// Interface for text-based input devices.
@@ -21,7 +21,7 @@ impl Input {
2121
///
2222
/// - `DeviceError` if the device is malfunctioning and cannot be reset.
2323
pub fn reset(&mut self, extended_verification: bool) -> Result {
24-
(self.reset)(self, extended_verification).into()
24+
(self.reset)(self, extended_verification).to_result()
2525
}
2626

2727
/// Reads the next keystroke from the input device, if any.
@@ -77,7 +77,7 @@ impl Input {
7777

7878
match (self.read_key_stroke)(self, key.as_mut_ptr()) {
7979
Status::NOT_READY => Ok(None),
80-
other => other.into_with_val(|| Some(unsafe { key.assume_init() }.into())),
80+
other => other.to_result_with_val(|| Some(unsafe { key.assume_init() }.into())),
8181
}
8282
}
8383

0 commit comments

Comments
 (0)