Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
- `Image::get_image_file_system` now returns a `fs::FileSystem` instead of the
protocol.
- `CString16::default` now always contains a null character.
- Conversion from `Status` to `Result` has been reworked. The `into_with`,
`into_with_val`, and `into_with_err` methods have been removed from
`Status`. `impl From<Status> for Result` has also been removed. A new
`StatusExt` trait has been added that provides conversion methods to replace
the ones that have been removed. `StatusExt` has been added to the prelude.

## uefi-macros - [Unreleased]

Expand Down
4 changes: 4 additions & 0 deletions uefi-raw/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@

#[macro_use]
mod enums;

mod status;

pub use status::Status;
129 changes: 129 additions & 0 deletions uefi-raw/src/status.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
use core::fmt::Debug;

newtype_enum! {
/// UEFI uses status codes in order to report successes, errors, and warnings.
///
/// The spec allows implementation-specific status codes, so the `Status`
/// constants are not a comprehensive list of all possible values.
#[must_use]
pub enum Status: usize => {
/// The operation completed successfully.
SUCCESS = 0,

/// The string contained characters that could not be rendered and were skipped.
WARN_UNKNOWN_GLYPH = 1,
/// The handle was closed, but the file was not deleted.
WARN_DELETE_FAILURE = 2,
/// The handle was closed, but the data to the file was not flushed properly.
WARN_WRITE_FAILURE = 3,
/// The resulting buffer was too small, and the data was truncated.
WARN_BUFFER_TOO_SMALL = 4,
/// The data has not been updated within the timeframe set by local policy.
WARN_STALE_DATA = 5,
/// The resulting buffer contains UEFI-compliant file system.
WARN_FILE_SYSTEM = 6,
/// The operation will be processed across a system reset.
WARN_RESET_REQUIRED = 7,

/// The image failed to load.
LOAD_ERROR = Self::ERROR_BIT | 1,
/// A parameter was incorrect.
INVALID_PARAMETER = Self::ERROR_BIT | 2,
/// The operation is not supported.
UNSUPPORTED = Self::ERROR_BIT | 3,
/// The buffer was not the proper size for the request.
BAD_BUFFER_SIZE = Self::ERROR_BIT | 4,
/// The buffer is not large enough to hold the requested data.
/// The required buffer size is returned in the appropriate parameter.
BUFFER_TOO_SMALL = Self::ERROR_BIT | 5,
/// There is no data pending upon return.
NOT_READY = Self::ERROR_BIT | 6,
/// The physical device reported an error while attempting the operation.
DEVICE_ERROR = Self::ERROR_BIT | 7,
/// The device cannot be written to.
WRITE_PROTECTED = Self::ERROR_BIT | 8,
/// A resource has run out.
OUT_OF_RESOURCES = Self::ERROR_BIT | 9,
/// An inconstency was detected on the file system.
VOLUME_CORRUPTED = Self::ERROR_BIT | 10,
/// There is no more space on the file system.
VOLUME_FULL = Self::ERROR_BIT | 11,
/// The device does not contain any medium to perform the operation.
NO_MEDIA = Self::ERROR_BIT | 12,
/// The medium in the device has changed since the last access.
MEDIA_CHANGED = Self::ERROR_BIT | 13,
/// The item was not found.
NOT_FOUND = Self::ERROR_BIT | 14,
/// Access was denied.
ACCESS_DENIED = Self::ERROR_BIT | 15,
/// The server was not found or did not respond to the request.
NO_RESPONSE = Self::ERROR_BIT | 16,
/// A mapping to a device does not exist.
NO_MAPPING = Self::ERROR_BIT | 17,
/// The timeout time expired.
TIMEOUT = Self::ERROR_BIT | 18,
/// The protocol has not been started.
NOT_STARTED = Self::ERROR_BIT | 19,
/// The protocol has already been started.
ALREADY_STARTED = Self::ERROR_BIT | 20,
/// The operation was aborted.
ABORTED = Self::ERROR_BIT | 21,
/// An ICMP error occurred during the network operation.
ICMP_ERROR = Self::ERROR_BIT | 22,
/// A TFTP error occurred during the network operation.
TFTP_ERROR = Self::ERROR_BIT | 23,
/// A protocol error occurred during the network operation.
PROTOCOL_ERROR = Self::ERROR_BIT | 24,
/// The function encountered an internal version that was
/// incompatible with a version requested by the caller.
INCOMPATIBLE_VERSION = Self::ERROR_BIT | 25,
/// The function was not performed due to a security violation.
SECURITY_VIOLATION = Self::ERROR_BIT | 26,
/// A CRC error was detected.
CRC_ERROR = Self::ERROR_BIT | 27,
/// Beginning or end of media was reached
END_OF_MEDIA = Self::ERROR_BIT | 28,
/// The end of the file was reached.
END_OF_FILE = Self::ERROR_BIT | 31,
/// The language specified was invalid.
INVALID_LANGUAGE = Self::ERROR_BIT | 32,
/// The security status of the data is unknown or compromised and
/// the data must be updated or replaced to restore a valid security status.
COMPROMISED_DATA = Self::ERROR_BIT | 33,
/// There is an address conflict address allocation
IP_ADDRESS_CONFLICT = Self::ERROR_BIT | 34,
/// A HTTP error occurred during the network operation.
HTTP_ERROR = Self::ERROR_BIT | 35,
}}

impl Status {
/// Bit indicating that an UEFI status code is an error.
pub const ERROR_BIT: usize = 1 << (core::mem::size_of::<usize>() * 8 - 1);

/// Returns true if status code indicates success.
#[inline]
#[must_use]
pub fn is_success(self) -> bool {
self == Status::SUCCESS
}

/// Returns true if status code indicates a warning.
#[inline]
#[must_use]
pub fn is_warning(self) -> bool {
(self != Status::SUCCESS) && (self.0 & Self::ERROR_BIT == 0)
}

/// Returns true if the status code indicates an error.
#[inline]
#[must_use]
pub const fn is_error(self) -> bool {
self.0 & Self::ERROR_BIT != 0
}
}

impl core::fmt::Display for Status {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Debug::fmt(self, f)
}
}
2 changes: 1 addition & 1 deletion uefi-services/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub fn init(st: &mut SystemTable<Boot>) -> Result {
unsafe {
// Avoid double initialization.
if SYSTEM_TABLE.is_some() {
return Status::SUCCESS.into();
return Status::SUCCESS.to_result();
}

// Setup the system table singleton
Expand Down
2 changes: 1 addition & 1 deletion uefi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ pub use self::data_types::{CStr16, CStr8, Char16, Char8, Event, Guid, Handle, Id
pub use uefi_macros::{cstr16, cstr8, entry, guid};

mod result;
pub use self::result::{Error, Result, ResultExt, Status};
pub use self::result::{Error, Result, ResultExt, Status, StatusExt};

pub mod table;

Expand Down
4 changes: 2 additions & 2 deletions uefi/src/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ pub(crate) fn make_boxed<
#[cfg(test)]
mod tests {
use super::*;
use crate::ResultExt;
use crate::{ResultExt, StatusExt};
#[cfg(feature = "unstable")]
use alloc::alloc::Global;
use core::mem::{align_of, size_of};
Expand Down Expand Up @@ -146,7 +146,7 @@ mod tests {

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

// assert alignment
Expand Down
2 changes: 1 addition & 1 deletion uefi/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! This includes the system table types, `Status` codes, etc.

pub use crate::{Handle, ResultExt, Status};
pub use crate::{Handle, ResultExt, Status, StatusExt};

// Import the basic table types.
pub use crate::table::boot::BootServices;
Expand Down
18 changes: 9 additions & 9 deletions uefi/src/proto/console/gop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@

use crate::proto::unsafe_protocol;
use crate::util::usize_from_u32;
use crate::{Result, Status};
use crate::{Result, Status, StatusExt};
use core::fmt::{Debug, Formatter};
use core::marker::PhantomData;
use core::{mem, ptr};
Expand Down Expand Up @@ -94,7 +94,7 @@ impl GraphicsOutput {
let mut info_sz = 0;
let mut info = ptr::null();

(self.query_mode)(self, index, &mut info_sz, &mut info).into_with_val(|| {
(self.query_mode)(self, index, &mut info_sz, &mut info).to_result_with_val(|| {
let info = unsafe { *info };
Mode {
index,
Expand All @@ -119,7 +119,7 @@ impl GraphicsOutput {
///
/// This function will invalidate the current framebuffer.
pub fn set_mode(&mut self, mode: &Mode) -> Result {
(self.set_mode)(self, mode.index).into()
(self.set_mode)(self, mode.index).to_result()
}

/// Performs a blt (block transfer) operation on the frame buffer.
Expand Down Expand Up @@ -147,7 +147,7 @@ impl GraphicsOutput {
height,
0,
)
.into()
.to_result()
}
BltOp::VideoToBltBuffer {
buffer,
Expand All @@ -170,7 +170,7 @@ impl GraphicsOutput {
height,
0,
)
.into(),
.to_result(),
BltRegion::SubRectangle {
coords: (dest_x, dest_y),
px_stride,
Expand All @@ -186,7 +186,7 @@ impl GraphicsOutput {
height,
px_stride * core::mem::size_of::<BltPixel>(),
)
.into(),
.to_result(),
}
}
BltOp::BufferToVideo {
Expand All @@ -210,7 +210,7 @@ impl GraphicsOutput {
height,
0,
)
.into(),
.to_result(),
BltRegion::SubRectangle {
coords: (src_x, src_y),
px_stride,
Expand All @@ -226,7 +226,7 @@ impl GraphicsOutput {
height,
px_stride * core::mem::size_of::<BltPixel>(),
)
.into(),
.to_result(),
}
}
BltOp::VideoToVideo {
Expand All @@ -248,7 +248,7 @@ impl GraphicsOutput {
height,
0,
)
.into()
.to_result()
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions uefi/src/proto/console/pointer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Pointer device access.

use crate::proto::unsafe_protocol;
use crate::{Event, Result, Status};
use crate::{Event, Result, Status, StatusExt};
use core::mem::MaybeUninit;

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

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

match (self.get_state)(self, pointer_state.as_mut_ptr()) {
Status::NOT_READY => Ok(None),
other => other.into_with_val(|| unsafe { Some(pointer_state.assume_init()) }),
other => other.to_result_with_val(|| unsafe { Some(pointer_state.assume_init()) }),
}
}

Expand Down
14 changes: 7 additions & 7 deletions uefi/src/proto/console/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use core::fmt::Write;

use crate::proto::unsafe_protocol;
use crate::{Result, Status};
use crate::{Result, Status, StatusExt};
use bitflags::bitflags;

/// Provides access to a serial I/O device.
Expand Down Expand Up @@ -39,7 +39,7 @@ pub struct Serial {
impl Serial {
/// Reset the device.
pub fn reset(&mut self) -> Result {
(self.reset)(self).into()
(self.reset)(self).to_result()
}

/// Returns the current I/O mode.
Expand Down Expand Up @@ -71,21 +71,21 @@ impl Serial {
mode.data_bits as u8,
mode.stop_bits,
)
.into()
.to_result()
}

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

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

/// Reads data from this device.
Expand All @@ -95,7 +95,7 @@ impl Serial {
/// bytes were actually read from the device.
pub fn read(&mut self, data: &mut [u8]) -> Result<(), usize> {
let mut buffer_size = data.len();
unsafe { (self.read)(self, &mut buffer_size, data.as_mut_ptr()) }.into_with(
unsafe { (self.read)(self, &mut buffer_size, data.as_mut_ptr()) }.to_result_with(
|| debug_assert_eq!(buffer_size, data.len()),
|_| buffer_size,
)
Expand All @@ -108,7 +108,7 @@ impl Serial {
/// were actually written to the device.
pub fn write(&mut self, data: &[u8]) -> Result<(), usize> {
let mut buffer_size = data.len();
unsafe { (self.write)(self, &mut buffer_size, data.as_ptr()) }.into_with(
unsafe { (self.write)(self, &mut buffer_size, data.as_ptr()) }.to_result_with(
|| debug_assert_eq!(buffer_size, data.len()),
|_| buffer_size,
)
Expand Down
6 changes: 3 additions & 3 deletions uefi/src/proto/console/text/input.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::proto::unsafe_protocol;
use crate::{Char16, Event, Result, Status};
use crate::{Char16, Event, Result, Status, StatusExt};
use core::mem::MaybeUninit;

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

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

match (self.read_key_stroke)(self, key.as_mut_ptr()) {
Status::NOT_READY => Ok(None),
other => other.into_with_val(|| Some(unsafe { key.assume_init() }.into())),
other => other.to_result_with_val(|| Some(unsafe { key.assume_init() }.into())),
}
}

Expand Down
Loading