1 //! Raw interface for working with UEFI.
2 //!
3 //! This crate is intended for implementing UEFI services. It is also used for
4 //! implementing the [`uefi`] crate, which provides a safe wrapper around UEFI.
5 //!
6 //! For creating UEFI applications and drivers, consider using the [`uefi`]
7 //! crate instead of `uefi-raw`.
8 //!
9 //! [`uefi`]: https://crates.io/crates/uefi
10 
11 #![no_std]
12 #![cfg_attr(docsrs, feature(doc_auto_cfg))]
13 #![deny(
14     clippy::all,
15     clippy::missing_const_for_fn,
16     clippy::must_use_candidate,
17     clippy::ptr_as_ptr,
18     clippy::use_self,
19     missing_debug_implementations,
20     unused
21 )]
22 
23 #[macro_use]
24 mod enums;
25 
26 pub mod capsule;
27 pub mod firmware_storage;
28 pub mod protocol;
29 pub mod table;
30 pub mod time;
31 
32 mod status;
33 
34 use core::ffi::c_void;
35 use core::fmt::{self, Debug, Formatter};
36 pub use status::Status;
37 pub use uguid::{guid, Guid};
38 
39 /// Handle to an event structure.
40 pub type Event = *mut c_void;
41 
42 /// Handle to a UEFI entity (protocol, image, etc).
43 pub type Handle = *mut c_void;
44 
45 /// One-byte character.
46 ///
47 /// Most strings in UEFI use [`Char16`], but a few places use one-byte
48 /// characters. Unless otherwise noted, these are encoded as 8-bit ASCII using
49 /// the ISO-Latin-1 character set.
50 pub type Char8 = u8;
51 
52 /// Two-byte character.
53 ///
54 /// Unless otherwise noted, the encoding is UCS-2. The UCS-2 encoding was
55 /// defined by Unicode 2.1 and ISO/IEC 10646 standards, but is no longer part of
56 /// the modern Unicode standards. It is essentially UTF-16 without support for
57 /// surrogate pairs.
58 pub type Char16 = u16;
59 
60 /// Physical memory address. This is always a 64-bit value, regardless
61 /// of target platform.
62 pub type PhysicalAddress = u64;
63 
64 /// Virtual memory address. This is always a 64-bit value, regardless
65 /// of target platform.
66 pub type VirtualAddress = u64;
67 
68 /// An IPv4 internet protocol address.
69 #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
70 #[repr(transparent)]
71 pub struct Ipv4Address(pub [u8; 4]);
72 
73 /// An IPv6 internet protocol address.
74 #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
75 #[repr(transparent)]
76 pub struct Ipv6Address(pub [u8; 16]);
77 
78 /// An IPv4 or IPv6 internet protocol address.
79 ///
80 /// Corresponds to the `EFI_IP_ADDRESS` type in the UEFI specification. This
81 /// type is defined in the same way as edk2 for compatibility with C code. Note
82 /// that this is an untagged union, so there's no way to tell which type of
83 /// address an `IpAddress` value contains without additional context.
84 #[derive(Clone, Copy)]
85 #[repr(C)]
86 pub union IpAddress {
87     /// This member serves to align the whole type to a 4 bytes as required by
88     /// the spec. Note that this is slightly different from `repr(align(4))`,
89     /// which would prevent placing this type in a packed structure.
90     pub addr: [u32; 4],
91 
92     /// An IPv4 internet protocol address.
93     pub v4: Ipv4Address,
94 
95     /// An IPv6 internet protocol address.
96     pub v6: Ipv6Address,
97 }
98 
99 impl IpAddress {
100     /// Construct a new IPv4 address.
101     #[must_use]
new_v4(ip_addr: [u8; 4]) -> Self102     pub const fn new_v4(ip_addr: [u8; 4]) -> Self {
103         Self {
104             v4: Ipv4Address(ip_addr),
105         }
106     }
107 
108     /// Construct a new IPv6 address.
109     #[must_use]
new_v6(ip_addr: [u8; 16]) -> Self110     pub const fn new_v6(ip_addr: [u8; 16]) -> Self {
111         Self {
112             v6: Ipv6Address(ip_addr),
113         }
114     }
115 }
116 
117 impl Debug for IpAddress {
fmt(&self, f: &mut Formatter<'_>) -> fmt::Result118     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
119         // The type is an untagged union, so we don't know whether it contains
120         // an IPv4 or IPv6 address. It's also not safe to just print the whole
121         // 16 bytes, since they might not all be initialized.
122         f.debug_struct("IpAddress").finish()
123     }
124 }
125 
126 impl Default for IpAddress {
default() -> Self127     fn default() -> Self {
128         Self { addr: [0u32; 4] }
129     }
130 }
131 
132 /// A Media Access Control (MAC) address.
133 #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
134 #[repr(transparent)]
135 pub struct MacAddress(pub [u8; 32]);
136