From 2d85ea49261000ee1cd8df71ce948c54d867d546 Mon Sep 17 00:00:00 2001 From: Tim Roberts <39689890+timrobertsdev@users.noreply.github.com> Date: Fri, 3 Sep 2021 15:40:46 -0400 Subject: [PATCH 1/5] Change Guid::from_values() to accept u64 for node. --- src/data_types/guid.rs | 17 ++++++++--------- src/proto/media/partition.rs | 6 +++--- src/table/cfg.rs | 27 +++++++++++++-------------- src/table/runtime.rs | 7 +++---- uefi-macros/src/lib.rs | 24 ++++++++++++------------ uefi-test-runner/src/runtime/vars.rs | 2 +- 6 files changed, 40 insertions(+), 43 deletions(-) diff --git a/src/data_types/guid.rs b/src/data_types/guid.rs index d1d40b1ab..d8ed6b8d6 100644 --- a/src/data_types/guid.rs +++ b/src/data_types/guid.rs @@ -26,19 +26,17 @@ pub struct Guid { impl Guid { /// Creates a new GUID from its canonical representation - // - // FIXME: An unwieldy array of bytes must be used for the node ID until one - // can assert that an u64 has its high 16-bits cleared in a const fn. - // Once that is done, we can take an u64 to be even closer to the - // canonical UUID/GUID format. - // pub const fn from_values( time_low: u32, time_mid: u16, time_high_and_version: u16, clock_seq_and_variant: u16, - node: [u8; 6], + node: u64, ) -> Self { + assert!(node.leading_zeros() >= 16, "node must be a 48-bit integer"); + // intentional shadowing + let node = node.to_be_bytes(); + Guid { a: time_low, b: time_mid, @@ -46,12 +44,13 @@ impl Guid { d: [ (clock_seq_and_variant / 0x100) as u8, (clock_seq_and_variant % 0x100) as u8, - node[0], - node[1], + // first two elements of node are ignored, we only want the low 48 bits node[2], node[3], node[4], node[5], + node[6], + node[7], ], } } diff --git a/src/proto/media/partition.rs b/src/proto/media/partition.rs index 77ed58e23..2311fbe1b 100644 --- a/src/proto/media/partition.rs +++ b/src/proto/media/partition.rs @@ -59,7 +59,7 @@ newtype_enum! { 0x0000, 0x0000, 0x0000, - [0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + 0x000000000000, ), /// EFI System Partition. @@ -68,7 +68,7 @@ newtype_enum! { 0xf81f, 0x11d2, 0xba4b, - [0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b], + 0x00a0c93ec93b, ), /// Partition containing a legacy MBR. @@ -77,7 +77,7 @@ newtype_enum! { 0x33e7, 0x11d3, 0x9d69, - [0x00, 0x08, 0xc7, 0x81, 0xf3, 0x9f], + 0x0008c781f39f, ), } } diff --git a/src/table/cfg.rs b/src/table/cfg.rs index 1108ecef1..82cc6628a 100644 --- a/src/table/cfg.rs +++ b/src/table/cfg.rs @@ -26,14 +26,13 @@ pub struct ConfigTableEntry { /// Whether this is a physical or virtual address depends on the table. pub address: *const c_void, } - -/// Entry pointing to the old ACPI 1 RSDP. +///ryntto oCP0000 1 RSDP. pub const ACPI_GUID: Guid = Guid::from_values( 0xeb9d2d30, 0x2d88, 0x11d3, 0x9a16, - [0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d], + 0x0090273fc14d, ); ///Entry pointing to the ACPI 2 RSDP. @@ -42,7 +41,7 @@ pub const ACPI2_GUID: Guid = Guid::from_values( 0xe4f1, 0x11d3, 0xbc22, - [0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81], + 0x0080c73c8881, ); /// Entry pointing to the SMBIOS 1.0 table. @@ -51,7 +50,7 @@ pub const SMBIOS_GUID: Guid = Guid::from_values( 0x2d88, 0x11d3, 0x9a16, - [0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d], + 0x0090273fc14d, ); /// Entry pointing to the SMBIOS 3.0 table. @@ -60,7 +59,7 @@ pub const SMBIOS3_GUID: Guid = Guid::from_values( 0x9794, 0x4a2c, 0x992e, - [0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94], + 0xe5bbcf20e394, ); /// GUID of the UEFI properties table. @@ -72,7 +71,7 @@ pub const PROPERTIES_TABLE_GUID: Guid = Guid::from_values( 0x4adc, 0x4a04, 0x9079, - [0xb7, 0x47, 0x34, 0x08, 0x25, 0xe5], + 0xb747340825e5, ); /// This table contains additional information about the UEFI implementation. @@ -107,7 +106,7 @@ pub const HAND_OFF_BLOCK_LIST_GUID: Guid = Guid::from_values( 0x93d7, 0x11d4, 0x9a3a, - [0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d], + 0x0090273fc14d, ); /// Table used in the early boot environment to record memory ranges. @@ -116,7 +115,7 @@ pub const MEMORY_TYPE_INFORMATION_GUID: Guid = Guid::from_values( 0x4137, 0x4dd3, 0x9c10, - [0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa], + 0x8b97a83ffdfa, ); /// Used to identify Hand-off Blocks which store @@ -126,7 +125,7 @@ pub const MEMORY_STATUS_CODE_RECORD_GUID: Guid = Guid::from_values( 0x4c0d, 0x4dda, 0x8f41, - [0x59, 0x5f, 0xef, 0x00, 0xa5, 0x02], + 0x595fef00a502, ); /// Table which provides Driver eXecution Environment services. @@ -135,7 +134,7 @@ pub const DXE_SERVICES_GUID: Guid = Guid::from_values( 0x6f02, 0x4214, 0x952e, - [0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9], + 0x4da0398e2bb9, ); /// LZMA-compressed filesystem. @@ -144,7 +143,7 @@ pub const LZMA_COMPRESS_GUID: Guid = Guid::from_values( 0x3914, 0x4259, 0x9d6e, - [0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf], + 0xdc7bd79403cf, ); /// A custom compressed filesystem used by the Tiano UEFI implementation. @@ -153,7 +152,7 @@ pub const TIANO_COMPRESS_GUID: Guid = Guid::from_values( 0x481e, 0x41b6, 0x95e8, - [0x12, 0x7f, 0x4c, 0x98, 0x47, 0x79], + 0x127f4c984779, ); /// Pointer to the debug image info table. @@ -162,5 +161,5 @@ pub const DEBUG_IMAGE_INFO_GUID: Guid = Guid::from_values( 0x1ada, 0x4764, 0xb7a2, - [0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b], + 0x7afefed95e8b, ); diff --git a/src/table/runtime.rs b/src/table/runtime.rs index ceb2c0bce..180af9afa 100644 --- a/src/table/runtime.rs +++ b/src/table/runtime.rs @@ -14,8 +14,7 @@ use core::fmt::{Debug, Formatter}; use core::mem; use core::mem::MaybeUninit; use core::{fmt, ptr}; - -/// Contains pointers to all of the runtime services. +///taporsal t0000e runtime services. /// /// This table, and the function pointers it contains are valid /// even after the UEFI OS loader and OS have taken control of the platform. @@ -503,7 +502,7 @@ newtype_enum! { 0x93ca, 0x11d2, 0xaa0d, - [0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c], + 0x00e098032b8c, ), /// Used to access EFI signature database variables. @@ -512,7 +511,7 @@ newtype_enum! { 0x3d3a, 0x4596, 0xa3bc, - [0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f], + 0xdad00e67656f, ), } } diff --git a/uefi-macros/src/lib.rs b/uefi-macros/src/lib.rs index 92cc2dcfd..8bc1bb9a9 100644 --- a/uefi-macros/src/lib.rs +++ b/uefi-macros/src/lib.rs @@ -73,17 +73,17 @@ pub fn unsafe_guid(args: TokenStream, input: TokenStream) -> TokenStream { let time_mid = next_guid_int(16) as u16; let time_high_and_version = next_guid_int(16) as u16; let clock_seq_and_variant = next_guid_int(16) as u16; - let node_64 = next_guid_int(48); - - // Convert the node ID to an array of bytes to comply with Guid::from_values expectations - let node = [ - (node_64 >> 40) as u8, - ((node_64 >> 32) % 0x100) as u8, - ((node_64 >> 24) % 0x100) as u8, - ((node_64 >> 16) % 0x100) as u8, - ((node_64 >> 8) % 0x100) as u8, - (node_64 % 0x100) as u8, - ]; + let node = next_guid_int(48); + + // // Convert the node ID to an array of bytes to comply with Guid::from_values expectations + // let node = [ + // (node_64 >> 40) as u8, + // ((node_64 >> 32) % 0x100) as u8, + // ((node_64 >> 24) % 0x100) as u8, + // ((node_64 >> 16) % 0x100) as u8, + // ((node_64 >> 8) % 0x100) as u8, + // (node_64 % 0x100) as u8, + // ]; // At this point, we know everything we need to implement Identify let ident = type_definition.ident.clone(); @@ -97,7 +97,7 @@ pub fn unsafe_guid(args: TokenStream, input: TokenStream) -> TokenStream { #time_mid, #time_high_and_version, #clock_seq_and_variant, - [#(#node),*], + #node, ); } }); diff --git a/uefi-test-runner/src/runtime/vars.rs b/uefi-test-runner/src/runtime/vars.rs index 14c847713..4f5c4ee18 100644 --- a/uefi-test-runner/src/runtime/vars.rs +++ b/uefi-test-runner/src/runtime/vars.rs @@ -15,7 +15,7 @@ fn test_variables(rt: &RuntimeServices) { 0xe187, 0x497e, 0xae77, - [0x5b, 0xd8, 0xb0, 0xe0, 0x97, 0x03], + 0x5bd8b0e09703, )); info!("Testing set_variable"); From 691bc9222dbefa2556b4a9094db2031f84ebb352 Mon Sep 17 00:00:00 2001 From: Tim Roberts <39689890+timrobertsdev@users.noreply.github.com> Date: Mon, 6 Sep 2021 07:11:44 -0400 Subject: [PATCH 2/5] Change Guid::fmt to use stdlib methods for obtaining u16/u64 from bytes --- src/data_types/guid.rs | 19 +++++++++---------- uefi-macros/src/lib.rs | 10 ---------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/data_types/guid.rs b/src/data_types/guid.rs index d8ed6b8d6..3715e9d8e 100644 --- a/src/data_types/guid.rs +++ b/src/data_types/guid.rs @@ -59,18 +59,17 @@ impl Guid { impl fmt::Display for Guid { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let d = { - let (low, high) = (u16::from(self.d[0]), u16::from(self.d[1])); - - (low << 8) | high + let mut buf = [0u8; 2]; + buf[..].copy_from_slice(&self.d[0..2]); + u16::from_be_bytes(buf) }; - // Extract and reverse byte order. - let e = self.d[2..8].iter().enumerate().fold(0, |acc, (i, &elem)| { - acc | { - let shift = (5 - i) * 8; - u64::from(elem) << shift - } - }); + let e = { + let mut buf = [0u8; 8]; + // first two elements of node are ignored, we only want the low 48 bits + buf[2..].copy_from_slice(&self.d[2..8]); + u64::from_be_bytes(buf) + }; write!( fmt, diff --git a/uefi-macros/src/lib.rs b/uefi-macros/src/lib.rs index 8bc1bb9a9..371246f20 100644 --- a/uefi-macros/src/lib.rs +++ b/uefi-macros/src/lib.rs @@ -75,16 +75,6 @@ pub fn unsafe_guid(args: TokenStream, input: TokenStream) -> TokenStream { let clock_seq_and_variant = next_guid_int(16) as u16; let node = next_guid_int(48); - // // Convert the node ID to an array of bytes to comply with Guid::from_values expectations - // let node = [ - // (node_64 >> 40) as u8, - // ((node_64 >> 32) % 0x100) as u8, - // ((node_64 >> 24) % 0x100) as u8, - // ((node_64 >> 16) % 0x100) as u8, - // ((node_64 >> 8) % 0x100) as u8, - // (node_64 % 0x100) as u8, - // ]; - // At this point, we know everything we need to implement Identify let ident = type_definition.ident.clone(); let (impl_generics, ty_generics, where_clause) = type_definition.generics.split_for_impl(); From 0dddb3d0b1d0cc652cb6d66058c55f20dd93d67b Mon Sep 17 00:00:00 2001 From: Tim Roberts <39689890+timrobertsdev@users.noreply.github.com> Date: Mon, 6 Sep 2021 16:47:06 -0400 Subject: [PATCH 3/5] Cargo fmt changes --- src/table/cfg.rs | 105 ++++++++++------------------------------------- 1 file changed, 21 insertions(+), 84 deletions(-) diff --git a/src/table/cfg.rs b/src/table/cfg.rs index 82cc6628a..8db47133d 100644 --- a/src/table/cfg.rs +++ b/src/table/cfg.rs @@ -27,52 +27,24 @@ pub struct ConfigTableEntry { pub address: *const c_void, } ///ryntto oCP0000 1 RSDP. -pub const ACPI_GUID: Guid = Guid::from_values( - 0xeb9d2d30, - 0x2d88, - 0x11d3, - 0x9a16, - 0x0090273fc14d, -); +pub const ACPI_GUID: Guid = Guid::from_values(0xeb9d2d30, 0x2d88, 0x11d3, 0x9a16, 0x0090273fc14d); ///Entry pointing to the ACPI 2 RSDP. -pub const ACPI2_GUID: Guid = Guid::from_values( - 0x8868e871, - 0xe4f1, - 0x11d3, - 0xbc22, - 0x0080c73c8881, -); +pub const ACPI2_GUID: Guid = Guid::from_values(0x8868e871, 0xe4f1, 0x11d3, 0xbc22, 0x0080c73c8881); /// Entry pointing to the SMBIOS 1.0 table. -pub const SMBIOS_GUID: Guid = Guid::from_values( - 0xeb9d2d31, - 0x2d88, - 0x11d3, - 0x9a16, - 0x0090273fc14d, -); +pub const SMBIOS_GUID: Guid = Guid::from_values(0xeb9d2d31, 0x2d88, 0x11d3, 0x9a16, 0x0090273fc14d); /// Entry pointing to the SMBIOS 3.0 table. -pub const SMBIOS3_GUID: Guid = Guid::from_values( - 0xf2fd1544, - 0x9794, - 0x4a2c, - 0x992e, - 0xe5bbcf20e394, -); +pub const SMBIOS3_GUID: Guid = + Guid::from_values(0xf2fd1544, 0x9794, 0x4a2c, 0x992e, 0xe5bbcf20e394); /// GUID of the UEFI properties table. /// /// The properties table is used to provide additional info /// about the UEFI implementation. -pub const PROPERTIES_TABLE_GUID: Guid = Guid::from_values( - 0x880aaca3, - 0x4adc, - 0x4a04, - 0x9079, - 0xb747340825e5, -); +pub const PROPERTIES_TABLE_GUID: Guid = + Guid::from_values(0x880aaca3, 0x4adc, 0x4a04, 0x9079, 0xb747340825e5); /// This table contains additional information about the UEFI implementation. #[repr(C)] @@ -101,65 +73,30 @@ bitflags! { /// Hand-off Blocks are used to pass data from the early pre-UEFI environment to the UEFI drivers. /// /// Most OS loaders or applications should not mess with this. -pub const HAND_OFF_BLOCK_LIST_GUID: Guid = Guid::from_values( - 0x7739f24c, - 0x93d7, - 0x11d4, - 0x9a3a, - 0x0090273fc14d, -); +pub const HAND_OFF_BLOCK_LIST_GUID: Guid = + Guid::from_values(0x7739f24c, 0x93d7, 0x11d4, 0x9a3a, 0x0090273fc14d); /// Table used in the early boot environment to record memory ranges. -pub const MEMORY_TYPE_INFORMATION_GUID: Guid = Guid::from_values( - 0x4c19049f, - 0x4137, - 0x4dd3, - 0x9c10, - 0x8b97a83ffdfa, -); +pub const MEMORY_TYPE_INFORMATION_GUID: Guid = + Guid::from_values(0x4c19049f, 0x4137, 0x4dd3, 0x9c10, 0x8b97a83ffdfa); /// Used to identify Hand-off Blocks which store /// status codes reported during the pre-UEFI environment. -pub const MEMORY_STATUS_CODE_RECORD_GUID: Guid = Guid::from_values( - 0x60cc026, - 0x4c0d, - 0x4dda, - 0x8f41, - 0x595fef00a502, -); +pub const MEMORY_STATUS_CODE_RECORD_GUID: Guid = + Guid::from_values(0x60cc026, 0x4c0d, 0x4dda, 0x8f41, 0x595fef00a502); /// Table which provides Driver eXecution Environment services. -pub const DXE_SERVICES_GUID: Guid = Guid::from_values( - 0x5ad34ba, - 0x6f02, - 0x4214, - 0x952e, - 0x4da0398e2bb9, -); +pub const DXE_SERVICES_GUID: Guid = + Guid::from_values(0x5ad34ba, 0x6f02, 0x4214, 0x952e, 0x4da0398e2bb9); /// LZMA-compressed filesystem. -pub const LZMA_COMPRESS_GUID: Guid = Guid::from_values( - 0xee4e5898, - 0x3914, - 0x4259, - 0x9d6e, - 0xdc7bd79403cf, -); +pub const LZMA_COMPRESS_GUID: Guid = + Guid::from_values(0xee4e5898, 0x3914, 0x4259, 0x9d6e, 0xdc7bd79403cf); /// A custom compressed filesystem used by the Tiano UEFI implementation. -pub const TIANO_COMPRESS_GUID: Guid = Guid::from_values( - 0xa31280ad, - 0x481e, - 0x41b6, - 0x95e8, - 0x127f4c984779, -); +pub const TIANO_COMPRESS_GUID: Guid = + Guid::from_values(0xa31280ad, 0x481e, 0x41b6, 0x95e8, 0x127f4c984779); /// Pointer to the debug image info table. -pub const DEBUG_IMAGE_INFO_GUID: Guid = Guid::from_values( - 0x49152e77, - 0x1ada, - 0x4764, - 0xb7a2, - 0x7afefed95e8b, -); +pub const DEBUG_IMAGE_INFO_GUID: Guid = + Guid::from_values(0x49152e77, 0x1ada, 0x4764, 0xb7a2, 0x7afefed95e8b); From d7c76ba02eea523ba8abf458993872c62ff780e9 Mon Sep 17 00:00:00 2001 From: Tim Roberts <39689890+timrobertsdev@users.noreply.github.com> Date: Tue, 7 Sep 2021 02:14:45 -0400 Subject: [PATCH 4/5] Fix accidental comment changes. --- src/table/cfg.rs | 2 +- src/table/runtime.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/table/cfg.rs b/src/table/cfg.rs index 8db47133d..3351699dc 100644 --- a/src/table/cfg.rs +++ b/src/table/cfg.rs @@ -26,7 +26,7 @@ pub struct ConfigTableEntry { /// Whether this is a physical or virtual address depends on the table. pub address: *const c_void, } -///ryntto oCP0000 1 RSDP. +/// Entry pointing to the old ACPI 1 RSDP. pub const ACPI_GUID: Guid = Guid::from_values(0xeb9d2d30, 0x2d88, 0x11d3, 0x9a16, 0x0090273fc14d); ///Entry pointing to the ACPI 2 RSDP. diff --git a/src/table/runtime.rs b/src/table/runtime.rs index 180af9afa..9828faec9 100644 --- a/src/table/runtime.rs +++ b/src/table/runtime.rs @@ -14,7 +14,7 @@ use core::fmt::{Debug, Formatter}; use core::mem; use core::mem::MaybeUninit; use core::{fmt, ptr}; -///taporsal t0000e runtime services. +/// Contains pointers to all of the runtime services. /// /// This table, and the function pointers it contains are valid /// even after the UEFI OS loader and OS have taken control of the platform. From 74bde291edf2a5173ba930e963f8163c8abd1188 Mon Sep 17 00:00:00 2001 From: Tim Roberts <39689890+timrobertsdev@users.noreply.github.com> Date: Tue, 7 Sep 2021 03:27:41 -0400 Subject: [PATCH 5/5] Add unit tests for Guid --- src/data_types/guid.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/data_types/guid.rs b/src/data_types/guid.rs index 3715e9d8e..9cc5e3701 100644 --- a/src/data_types/guid.rs +++ b/src/data_types/guid.rs @@ -105,3 +105,32 @@ pub unsafe trait Identify { } pub use uefi_macros::unsafe_guid; + +#[cfg(test)] +mod tests { + use uefi::unsafe_guid; + extern crate alloc; + use super::*; + + #[test] + fn test_guid_display() { + assert_eq!( + alloc::format!( + "{}", + Guid::from_values(0x12345678, 0x9abc, 0xdef0, 0x1234, 0x56789abcdef0) + ), + "12345678-9abc-def0-1234-56789abcdef0" + ); + } + + #[test] + fn test_unsafe_guid() { + #[unsafe_guid("12345678-9abc-def0-1234-56789abcdef0")] + struct X; + + assert_eq!( + X::GUID, + Guid::from_values(0x12345678, 0x9abc, 0xdef0, 0x1234, 0x56789abcdef0) + ); + } +}