diff --git a/Cargo.lock b/Cargo.lock index 0f0b1984..2f9f5c9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -408,14 +408,14 @@ dependencies = [ [[package]] name = "framework_lib" -version = "0.4.1" +version = "0.4.2" dependencies = [ "built", "clap", "clap-num", "clap-verbosity-flag", "env_logger", - "guid_macros", + "guid-create", "hidapi", "lazy_static", "libc", @@ -440,7 +440,7 @@ dependencies = [ [[package]] name = "framework_tool" -version = "0.4.1" +version = "0.4.2" dependencies = [ "embed-resource", "framework_lib", @@ -451,7 +451,7 @@ dependencies = [ [[package]] name = "framework_uefi" -version = "0.4.1" +version = "0.4.2" dependencies = [ "framework_lib", "log", @@ -581,12 +581,11 @@ dependencies = [ ] [[package]] -name = "guid_macros" -version = "0.11.0" +name = "guid-create" +version = "0.4.1" +source = "git+https://github.com/FrameworkComputer/guid-create?branch=no-rand#84c3ad2e8b64a12beebb460804a65da55434cfd9" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.98", + "winapi", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 41f48e81..d8108e1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,9 +11,6 @@ members = [ "framework_uefi", # Catchall library that we'll probably want to split up further "framework_lib", - # Fork of https://github.com/rust-osdev/uefi-rs/blob/main/uefi-macros - # To avoid pulling in UEFI dependencies when building for an OS - "guid_macros", ] # Don't build UEFI by default. Needs special cargo invocation diff --git a/README.md b/README.md index 2841b579..7fbcea32 100644 --- a/README.md +++ b/README.md @@ -126,14 +126,12 @@ make -C framework_uefi ls -l framework_uefi/build/x86_64-unknown-uefi/boot.efi ``` -Building on Windows or in general with fewer features: +## Install local package -```ps1 -# Build the library and tool -cargo build - -# Running the tool -cargo run +``` +> cargo install --path framework_tool +> which framework_tool +/home/zoid/.cargo/bin/framework_tool ``` ## Running diff --git a/framework_lib/Cargo.toml b/framework_lib/Cargo.toml index f0477678..8d362370 100644 --- a/framework_lib/Cargo.toml +++ b/framework_lib/Cargo.toml @@ -1,6 +1,11 @@ [package] name = "framework_lib" -version = "0.4.1" +version = "0.4.2" +description = "Library to control Framework Computer systems" +homepage = "https://github.com/FrameworkComputer/framework-system" +repository = "https://github.com/FrameworkComputer/framework-system" +readme = "README.md" +license = "BSD-3-Clause" edition = "2021" # Minimum Supported Rust Version # Ubuntu 24.04 LTS ships 1.75 @@ -26,9 +31,9 @@ num-traits = { version = "0.2", default-features = false } log = { version = "0.4", default-features = true } spin = { version = "0.9.8" } no-std-compat = { version = "0.4.1", features = [ "alloc" ] } -guid_macros = { path = "../guid_macros" } hidapi = { version = "2.6.3", features = [ "windows-native" ], optional = true } rusb = { version = "0.9.4", optional = true } +guid-create = { git = "https://github.com/FrameworkComputer/guid-create", branch = "no-rand", default-features = false } [target.'cfg(target_os = "uefi")'.dependencies] uefi = { version = "0.20", features = ["alloc"] } diff --git a/framework_lib/src/capsule.rs b/framework_lib/src/capsule.rs index 971db631..e2dff320 100644 --- a/framework_lib/src/capsule.rs +++ b/framework_lib/src/capsule.rs @@ -11,16 +11,12 @@ use std::prelude::v1::*; use core::prelude::rust_2021::derive; +use guid_create::Guid; #[cfg(not(feature = "uefi"))] use std::fs::File; #[cfg(not(feature = "uefi"))] use std::io::prelude::*; -#[cfg(not(feature = "uefi"))] -use crate::guid::Guid; -#[cfg(feature = "uefi")] -use uefi::Guid; - #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[repr(C)] pub struct EfiCapsuleHeader { @@ -209,14 +205,14 @@ mod tests { let data = fs::read(capsule_path).unwrap(); let cap = parse_capsule_header(&data).unwrap(); let expected_header = EfiCapsuleHeader { - capsule_guid: esrt::WINUX_GUID, + capsule_guid: Guid::from(esrt::WINUX_GUID), header_size: 28, flags: 65536, capsule_image_size: 676898, }; assert_eq!(cap, expected_header); - assert_eq!(cap.capsule_guid, esrt::WINUX_GUID); + assert_eq!(cap.capsule_guid, Guid::from(esrt::WINUX_GUID)); let ux_header = parse_ux_header(&data); assert_eq!( ux_header, diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index b137f511..0477cbbe 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -7,6 +7,7 @@ use alloc::format; use alloc::string::String; use alloc::string::ToString; use alloc::vec::Vec; +use guid_create::{Guid, GUID}; use log::Level; use num_traits::FromPrimitive; @@ -494,7 +495,7 @@ fn print_versions(ec: &CrosEc) { let mut right_retimer: Option = None; if let Some(esrt) = esrt::get_esrt() { for entry in &esrt.entries { - match entry.fw_class { + match GUID::from(entry.fw_class) { esrt::TGL_RETIMER01_GUID | esrt::ADL_RETIMER01_GUID | esrt::RPL_RETIMER01_GUID @@ -700,7 +701,7 @@ fn compare_version(device: Option, version: String, ec: &Cro if let Some(esrt) = esrt::get_esrt() { for entry in &esrt.entries { - match entry.fw_class { + match GUID::from(entry.fw_class) { esrt::TGL_RETIMER01_GUID | esrt::ADL_RETIMER01_GUID | esrt::RPL_RETIMER01_GUID => { if device == Some(HardwareDeviceType::RTM01) { println!("Comparing RTM01 version {:?}", entry.fw_version.to_string()); @@ -1032,7 +1033,7 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { println!(" Size: {:>20} B", data.len()); println!(" Size: {:>20} KB", data.len() / 1024); if let Some(header) = analyze_capsule(&data) { - if header.capsule_guid == esrt::WINUX_GUID { + if header.capsule_guid == Guid::from(esrt::WINUX_GUID) { let ux_header = capsule::parse_ux_header(&data); if let Some(dump_path) = &args.dump { // TODO: Better error handling, rather than just panicking @@ -1434,7 +1435,7 @@ pub fn analyze_capsule(data: &[u8]) -> Option { let header = capsule::parse_capsule_header(data)?; capsule::print_capsule_header(&header); - match header.capsule_guid { + match GUID::from(header.capsule_guid) { esrt::TGL_BIOS_GUID => { println!(" Type: Framework TGL Insyde BIOS"); } diff --git a/framework_lib/src/esrt/mod.rs b/framework_lib/src/esrt/mod.rs index 16770df5..15daea4c 100644 --- a/framework_lib/src/esrt/mod.rs +++ b/framework_lib/src/esrt/mod.rs @@ -14,13 +14,8 @@ use log::{debug, error, info, trace}; use std::prelude::v1::*; -#[cfg(not(feature = "uefi"))] -use crate::guid::Guid; use core::prelude::v1::derive; -#[cfg(not(feature = "uefi"))] -use guid_macros::guid; -#[cfg(feature = "uefi")] -use uefi::{guid, Guid}; +use guid_create::{Guid, GUID}; #[cfg(target_os = "linux")] use std::fs; @@ -38,66 +33,133 @@ use std::os::fd::AsRawFd; #[cfg(target_os = "freebsd")] use std::os::unix::fs::OpenOptionsExt; -/// Decode from GUID string version -/// -/// # Examples -/// ``` -/// use framework_lib::esrt::*; -/// use framework_lib::guid::*; -/// -/// let valid_guid = Guid::from_values(0xA9C91B0C, 0xC0B8, 0x463D, 0xA7DA, 0xA5D6EC646333); -/// // Works with lower-case -/// let guid = guid_from_str("a9c91b0c-c0b8-463d-a7da-a5d6ec646333"); -/// assert_eq!(guid, Some(valid_guid)); -/// // And upper-case -/// let guid = guid_from_str("A9C91B0C-C0B8-463D-A7DA-A5D6EC646333"); -/// assert_eq!(guid, Some(valid_guid)); -/// -/// let guid = guid_from_str("invalid-guid"); -/// assert_eq!(guid, None); -/// ``` -pub fn guid_from_str(string: &str) -> Option { - let string = string.strip_suffix('\n').unwrap_or(string); - let sections: Vec<&str> = string.split('-').collect(); - let time_low = u32::from_str_radix(sections[0], 16).ok()?; - let time_mid = u16::from_str_radix(sections[1], 16).ok()?; - let time_high_and_version = u16::from_str_radix(sections[2], 16).ok()?; - let clock_seq_and_variant = u16::from_str_radix(sections[3], 16).ok()?; - let node = u64::from_str_radix(sections[4], 16).ok()?; - - Some(Guid::from_values( - time_low, - time_mid, - time_high_and_version, - clock_seq_and_variant, - node, - )) -} - -pub const TGL_BIOS_GUID: Guid = guid!("b3bdb2e4-c5cb-5c1b-bdc3-e6fc132462ff"); -pub const ADL_BIOS_GUID: Guid = guid!("a30a8cf3-847f-5e59-bd59-f9ec145c1a8c"); -pub const RPL_BIOS_GUID: Guid = guid!("13fd4ed2-cba9-50ba-bb91-aece0acb4cc3"); -pub const MTL_BIOS_GUID: Guid = guid!("72cecb9b-2b37-5ec2-a9ff-c739aabaadf3"); - -pub const TGL_RETIMER01_GUID: Guid = guid!("832af090-2ef9-7c47-8f6d-b405c8c7f156"); -pub const TGL_RETIMER23_GUID: Guid = guid!("20ef4108-6c64-d049-b6de-11ee35980b8f"); -pub const ADL_RETIMER01_GUID: Guid = guid!("a9c91b0c-c0b8-463d-a7da-a5d6ec646333"); -pub const ADL_RETIMER23_GUID: Guid = guid!("ba2e4e6e-3b0c-4f25-8a59-4c553fc86ea2"); -pub const RPL_RETIMER01_GUID: Guid = guid!("0c42b824-818f-428f-8687-5efcaf059bea"); -pub const RPL_RETIMER23_GUID: Guid = guid!("268ccbde-e087-420b-bf82-2212bd3f9bfc"); -pub const MTL_RETIMER01_GUID: Guid = guid!("c57fd615-2ac9-4154-bf34-4dc715344408"); -pub const MTL_RETIMER23_GUID: Guid = guid!("bdffce36-809c-4fa6-aecc-54536922f0e0"); - -pub const FL16_BIOS_GUID: Guid = guid!("6ae76af1-c002-5d64-8e18-658d205acf34"); -pub const AMD13_BIOS_GUID: Guid = guid!("b5f7dcc1-568c-50f8-a4dd-e39d1f93fda1"); -pub const RPL_CSME_GUID: Guid = guid!("865d322c-6ac7-4734-b43e-55db5a557d63"); -pub const MTL_CSME_GUID: Guid = guid!("32d8d677-eebc-4947-8f8a-0693a45240e5"); +pub const TGL_BIOS_GUID: GUID = GUID::build_from_components( + 0xb3bdb2e4, + 0xc5cb, + 0x5c1b, + &[0xbd, 0xc3, 0xe6, 0xfc, 0x13, 0x24, 0x62, 0xff], +); +pub const ADL_BIOS_GUID: GUID = GUID::build_from_components( + 0xa30a8cf3, + 0x847f, + 0x5e59, + &[0xbd, 0x59, 0xf9, 0xec, 0x14, 0x5c, 0x1a, 0x8c], +); +pub const RPL_BIOS_GUID: GUID = GUID::build_from_components( + 0x13fd4ed2, + 0xcba9, + 0x50ba, + &[0xbb, 0x91, 0xae, 0xce, 0x0a, 0xcb, 0x4c, 0xc3], +); +pub const MTL_BIOS_GUID: GUID = GUID::build_from_components( + 0x72cecb9b, + 0x2b37, + 0x5ec2, + &[0xa9, 0xff, 0xc7, 0x39, 0xaa, 0xba, 0xad, 0xf3], +); +pub const FW12_RPL_BIOS_GUID: GUID = GUID::build_from_components( + 0x6bc0986c, + 0xd281, + 0x5ba3, + &[0x96, 0x5c, 0x2f, 0x8d, 0x13, 0xe1, 0xee, 0xe8], +); + +pub const TGL_RETIMER01_GUID: GUID = GUID::build_from_components( + 0x832af090, + 0x2ef9, + 0x7c47, + &[0x8f, 0x6d, 0xb4, 0x05, 0xc8, 0xc7, 0xf1, 0x56], +); +pub const TGL_RETIMER23_GUID: GUID = GUID::build_from_components( + 0x20ef4108, + 0x6c64, + 0xd049, + &[0xb6, 0xde, 0x11, 0xee, 0x35, 0x98, 0x0b, 0x8f], +); +pub const ADL_RETIMER01_GUID: GUID = GUID::build_from_components( + 0xa9c91b0c, + 0xc0b8, + 0x463d, + &[0xa7, 0xda, 0xa5, 0xd6, 0xec, 0x64, 0x63, 0x33], +); +pub const ADL_RETIMER23_GUID: GUID = GUID::build_from_components( + 0xba2e4e6e, + 0x3b0c, + 0x4f25, + &[0x8a, 0x59, 0x4c, 0x55, 0x3f, 0xc8, 0x6e, 0xa2], +); +pub const RPL_RETIMER01_GUID: GUID = GUID::build_from_components( + 0x0c42b824, + 0x818f, + 0x428f, + &[0x86, 0x87, 0x5e, 0xfc, 0xaf, 0x05, 0x9b, 0xea], +); +pub const RPL_RETIMER23_GUID: GUID = GUID::build_from_components( + 0x268ccbde, + 0xe087, + 0x420b, + &[0xbf, 0x82, 0x22, 0x12, 0xbd, 0x3f, 0x9b, 0xfc], +); +pub const MTL_RETIMER01_GUID: GUID = GUID::build_from_components( + 0xc57fd615, + 0x2ac9, + 0x4154, + &[0xbf, 0x34, 0x4d, 0xc7, 0x15, 0x34, 0x44, 0x08], +); +pub const MTL_RETIMER23_GUID: GUID = GUID::build_from_components( + 0xbdffce36, + 0x809c, + 0x4fa6, + &[0xae, 0xcc, 0x54, 0x53, 0x69, 0x22, 0xf0, 0xe0], +); + +pub const FL16_BIOS_GUID: GUID = GUID::build_from_components( + 0x6ae76af1, + 0xc002, + 0x5d64, + &[0x8e, 0x18, 0x65, 0x8d, 0x20, 0x5a, 0xcf, 0x34], +); +pub const AMD13_RYZEN7040_BIOS_GUID: GUID = GUID::build_from_components( + 0xb5f7dcc1, + 0x568c, + 0x50f8, + &[0xa4, 0xdd, 0xe3, 0x9d, 0x1f, 0x93, 0xfd, 0xa1], +); +pub const AMD13_AI300_BIOS_GUID: GUID = GUID::build_from_components( + 0x9c13b7f1, + 0xd618, + 0x5d68, + &[0xbe, 0x61, 0x6b, 0x17, 0x88, 0x10, 0x14, 0xa7], +); +pub const RPL_CSME_GUID: GUID = GUID::build_from_components( + 0x865d322c, + 0x6ac7, + 0x4734, + &[0xb4, 0x3e, 0x55, 0xdb, 0x5a, 0x55, 0x7d, 0x63], +); +pub const RPL_U_CSME_GUID: GUID = GUID::build_from_components( + 0x0f74c56d, + 0xd5ba, + 0x4942, + &[0x96, 0xfa, 0xd3, 0x75, 0x60, 0xf4, 0x05, 0x54], +); +pub const MTL_CSME_GUID: GUID = GUID::build_from_components( + 0x32d8d677, + 0xeebc, + 0x4947, + &[0x8f, 0x8a, 0x06, 0x93, 0xa4, 0x52, 0x40, 0xe5], +); // In EDK2 // Handled by MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c // Defined by MdePkg/Include/IndustryStandard/WindowsUxCapsule.h /// gWindowsUxCapsuleGuid from MdePkg/MdePkg.dec -pub const WINUX_GUID: Guid = guid!("3b8c8162-188c-46a4-aec9-be43f1d65697"); +pub const WINUX_GUID: GUID = GUID::build_from_components( + 0x3b8c8162, + 0x188c, + 0x46a4, + &[0xae, 0xc9, 0xbe, 0x43, 0xf1, 0xd6, 0x56, 0x97], +); #[derive(Debug)] pub enum FrameworkGuidKind { @@ -105,6 +167,7 @@ pub enum FrameworkGuidKind { AdlBios, RplBios, MtlBios, + Fw12RplBios, TglRetimer01, TglRetimer23, AdlRetimer01, @@ -114,21 +177,25 @@ pub enum FrameworkGuidKind { MtlRetimer01, MtlRetimer23, RplCsme, + RplUCsme, MtlCsme, Fl16Bios, - Amd13Bios, + Amd13Ryzen7040Bios, + Amd13Ai300Bios, WinUx, Unknown, } pub fn match_guid_kind(guid: &Guid) -> FrameworkGuidKind { - match *guid { + match GUID::from(*guid) { TGL_BIOS_GUID => FrameworkGuidKind::TglBios, ADL_BIOS_GUID => FrameworkGuidKind::AdlBios, RPL_BIOS_GUID => FrameworkGuidKind::RplBios, MTL_BIOS_GUID => FrameworkGuidKind::MtlBios, + FW12_RPL_BIOS_GUID => FrameworkGuidKind::Fw12RplBios, FL16_BIOS_GUID => FrameworkGuidKind::Fl16Bios, - AMD13_BIOS_GUID => FrameworkGuidKind::Amd13Bios, + AMD13_RYZEN7040_BIOS_GUID => FrameworkGuidKind::Amd13Ryzen7040Bios, + AMD13_AI300_BIOS_GUID => FrameworkGuidKind::Amd13Ai300Bios, TGL_RETIMER01_GUID => FrameworkGuidKind::TglRetimer01, TGL_RETIMER23_GUID => FrameworkGuidKind::TglRetimer23, ADL_RETIMER01_GUID => FrameworkGuidKind::AdlRetimer01, @@ -138,6 +205,7 @@ pub fn match_guid_kind(guid: &Guid) -> FrameworkGuidKind { MTL_RETIMER01_GUID => FrameworkGuidKind::MtlRetimer01, MTL_RETIMER23_GUID => FrameworkGuidKind::MtlRetimer23, RPL_CSME_GUID => FrameworkGuidKind::RplCsme, + RPL_U_CSME_GUID => FrameworkGuidKind::RplUCsme, MTL_CSME_GUID => FrameworkGuidKind::MtlCsme, WINUX_GUID => FrameworkGuidKind::WinUx, _ => FrameworkGuidKind::Unknown, @@ -288,8 +356,9 @@ fn esrt_from_sysfs(dir: &Path) -> io::Result { let last_attempt_version = fs::read_to_string(path.join("last_attempt_version"))?; let last_attempt_status = fs::read_to_string(path.join("last_attempt_status"))?; let esrt = EsrtResourceEntry { - // TODO: Parse GUID - fw_class: guid_from_str(&fw_class).expect("Kernel provided wrong value"), + fw_class: Guid::from( + GUID::parse(fw_class.trim()).expect("Kernel provided wrong value"), + ), fw_type: fw_type .trim() .parse::() @@ -358,8 +427,8 @@ pub fn get_esrt() -> Option { let guid_str = caps.get(1).unwrap().as_str().to_string(); let ver_str = caps.get(2).unwrap().as_str().to_string(); - let guid = guid_from_str(&guid_str).unwrap(); - let guid_kind = match_guid_kind(&guid); + let guid = GUID::parse(guid_str.trim()).expect("Kernel provided wrong value"); + let guid_kind = match_guid_kind(&Guid::from(guid)); let ver = u32::from_str_radix(&ver_str, 16).unwrap(); debug!("ESRT Entry {}", i); debug!(" Name: {:?}", guid_kind); @@ -379,7 +448,7 @@ pub fn get_esrt() -> Option { // TODO: The missing fields are present in Device Manager // So there must be a way to get at them let esrt = EsrtResourceEntry { - fw_class: guid, + fw_class: Guid::from(guid), fw_type, fw_version: ver, // TODO: Not exposed by windows @@ -428,7 +497,7 @@ pub fn get_esrt() -> Option { let mut buf: Vec = Vec::new(); let mut table = EfiGetTableIoc { buf: std::ptr::null_mut(), - uuid: SYSTEM_RESOURCE_TABLE_GUID.to_bytes(), + uuid: SYSTEM_RESOURCE_TABLE_GUID_BYTES, buf_len: 0, table_len: 0, }; @@ -448,7 +517,15 @@ pub fn get_esrt() -> Option { } /// gEfiSystemResourceTableGuid from MdePkg/MdePkg.dec -pub const SYSTEM_RESOURCE_TABLE_GUID: Guid = guid!("b122a263-3661-4f68-9929-78f8b0d62180"); +pub const SYSTEM_RESOURCE_TABLE_GUID: GUID = GUID::build_from_components( + 0xb122a263, + 0x3661, + 0x4f68, + &[0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80], +); +pub const SYSTEM_RESOURCE_TABLE_GUID_BYTES: [u8; 16] = [ + 0xb1, 0x22, 0xa2, 0x63, 0x36, 0x61, 0x4f, 0x68, 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80, +]; #[cfg(feature = "uefi")] pub fn get_esrt() -> Option { @@ -459,6 +536,7 @@ pub fn get_esrt() -> Option { // TODO: Why aren't they the same type? //debug!("Table: {:?}", table); let table_guid: Guid = unsafe { std::mem::transmute(table.guid) }; + let table_guid = GUID::from(table_guid); match table_guid { SYSTEM_RESOURCE_TABLE_GUID => unsafe { return esrt_from_buf(table.address as *const u8); diff --git a/framework_lib/src/guid.rs b/framework_lib/src/guid.rs deleted file mode 100644 index 2de63088..00000000 --- a/framework_lib/src/guid.rs +++ /dev/null @@ -1,173 +0,0 @@ -// Taken from https://github.com/rust-osdev/uefi-rs/blob/main/uefi/src/data_types/guid.rs -use core::fmt; - -/// A globally unique identifier -/// -/// GUIDs are used by UEFI to identify protocols and other objects. They are -/// mostly like variant 2 UUIDs as specified by RFC 4122, but differ from them -/// in that the first 3 fields are little endian instead of big endian. -/// -/// The `Display` formatter prints GUIDs in the canonical format defined by -/// RFC 4122, which is also used by UEFI. -#[derive(Debug, Default, Copy, Clone, Eq, Ord, PartialEq, PartialOrd)] -#[repr(C)] -pub struct Guid { - /// The low field of the timestamp. - a: u32, - /// The middle field of the timestamp. - b: u16, - /// The high field of the timestamp multiplexed with the version number. - c: u16, - /// Contains, in this order: - /// - The high field of the clock sequence multiplexed with the variant. - /// - The low field of the clock sequence. - /// - The spatially unique node identifier. - d: [u8; 8], -} - -impl Guid { - /// Creates a new GUID from its canonical representation - #[must_use] - pub const fn from_values( - time_low: u32, - time_mid: u16, - time_high_and_version: u16, - clock_seq_and_variant: u16, - 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, - c: time_high_and_version, - d: [ - (clock_seq_and_variant / 0x100) as u8, - (clock_seq_and_variant % 0x100) as u8, - // 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], - ], - } - } - - /// Create a GUID from a 16-byte array. No changes to byte order are made. - #[must_use] - pub const fn from_bytes(bytes: [u8; 16]) -> Self { - let a = u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]); - let b = u16::from_le_bytes([bytes[4], bytes[5]]); - let c = u16::from_le_bytes([bytes[6], bytes[7]]); - let d = [ - bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15], - ]; - - Self { a, b, c, d } - } - - /// Convert to a 16-byte array. - #[must_use] - #[rustfmt::skip] - pub const fn to_bytes(self) -> [u8; 16] { - let a = self.a.to_le_bytes(); - let b = self.b.to_le_bytes(); - let c = self.c.to_le_bytes(); - let d = self.d; - - [ - a[0], a[1], a[2], a[3], - b[0], b[1], c[0], c[1], - d[0], d[1], d[2], d[3], - d[4], d[5], d[6], d[7], - ] - } -} - -impl fmt::Display for Guid { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let a = self.a; - let b = self.b; - let c = self.c; - - let d = { - let mut buf = [0u8; 2]; - buf[..].copy_from_slice(&self.d[0..2]); - u16::from_be_bytes(buf) - }; - - 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, "{a:08x}-{b:04x}-{c:04x}-{d:04x}-{e:012x}",) - } -} - -/// Several entities in the UEFI specification can be referred to by their GUID, -/// this trait is a building block to interface them in uefi-rs. -/// -/// You should never need to use the `Identify` trait directly, but instead go -/// for more specific traits such as `Protocol` or `FileProtocolInfo`, which -/// indicate in which circumstances an `Identify`-tagged type should be used. -/// -/// For the common case of implementing this trait for a protocol, use -/// the `unsafe_protocol` macro. -/// -/// # Safety -/// -/// Implementing `Identify` is unsafe because attaching an incorrect GUID to a -/// type can lead to type unsafety on both the Rust and UEFI side. -pub unsafe trait Identify { - /// Unique protocol identifier. - const GUID: Guid; -} - -#[cfg(test)] -mod tests { - use super::*; - use guid_macros::guid; - - #[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_guid_macro() { - assert_eq!( - guid!("12345678-9abc-def0-1234-56789abcdef0"), - Guid::from_values(0x12345678, 0x9abc, 0xdef0, 0x1234, 0x56789abcdef0) - ); - } - - #[test] - fn test_to_from_bytes() { - #[rustfmt::skip] - let bytes = [ - 0x78, 0x56, 0x34, 0x12, - 0xbc, 0x9a, - 0xf0, 0xde, - 0x12, 0x34, - 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, - ]; - assert_eq!( - Guid::from_bytes(bytes), - Guid::from_values(0x12345678, 0x9abc, 0xdef0, 0x1234, 0x56789abcdef0) - ); - assert_eq!(Guid::from_bytes(bytes).to_bytes(), bytes); - } -} diff --git a/framework_lib/src/lib.rs b/framework_lib/src/lib.rs index 661f9e14..93d91e2b 100644 --- a/framework_lib/src/lib.rs +++ b/framework_lib/src/lib.rs @@ -37,8 +37,6 @@ pub mod commandline; pub mod csme; pub mod ec_binary; pub mod esrt; -#[cfg(not(feature = "uefi"))] -pub mod guid; mod os_specific; pub mod power; pub mod smbios; diff --git a/framework_tool/Cargo.toml b/framework_tool/Cargo.toml index 7cdfd1f6..8da6a35c 100644 --- a/framework_tool/Cargo.toml +++ b/framework_tool/Cargo.toml @@ -1,8 +1,17 @@ [package] name = "framework_tool" -version = "0.4.1" +version = "0.4.2" +description = "Tool to control Framework Computer systems" +homepage = "https://github.com/FrameworkComputer/framework-system" +repository = "https://github.com/FrameworkComputer/framework-system" +readme = "README.md" +license = "BSD-3-Clause" edition = "2021" +[[bin]] +name = "framework_tool" +path = "src/main.rs" + [dependencies.framework_lib] path = "../framework_lib" diff --git a/framework_uefi/Cargo.toml b/framework_uefi/Cargo.toml index d0ad0cc4..852fa7ec 100644 --- a/framework_uefi/Cargo.toml +++ b/framework_uefi/Cargo.toml @@ -1,6 +1,11 @@ [package] name = "framework_uefi" -version = "0.4.1" +version = "0.4.2" +description = "UEFI Tool to control Framework Computer systems" +homepage = "https://github.com/FrameworkComputer/framework-system" +repository = "https://github.com/FrameworkComputer/framework-system" +readme = "README.md" +license = "BSD-3-Clause" edition = "2021" # Minimum Supported Rust Version rust-version = "1.74" diff --git a/guid_macros/Cargo.toml b/guid_macros/Cargo.toml deleted file mode 100644 index d1680814..00000000 --- a/guid_macros/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "guid_macros" -version = "0.11.0" -authors = ["The Rust OSDev team"] -readme = "README.md" -edition = "2021" -description = "Procedural macros for the `uefi` crate." -repository = "https://github.com/rust-osdev/uefi-rs" -keywords = ["uefi", "efi"] -categories = ["embedded", "no-std", "api-bindings"] -license = "MPL-2.0" - -[lib] -proc-macro = true - -[dependencies] -proc-macro2 = "1.0.28" -quote = "1.0.9" -syn = { version = "2.0.4", features = ["full"] } - -#[dev-dependencies] -#trybuild = "1.0.61" -#uefi = { version = "0.20.0", default-features = false } diff --git a/guid_macros/src/lib.rs b/guid_macros/src/lib.rs deleted file mode 100644 index 7556a5d5..00000000 --- a/guid_macros/src/lib.rs +++ /dev/null @@ -1,101 +0,0 @@ -// Taken from - -use proc_macro::TokenStream; - -use proc_macro2::{TokenStream as TokenStream2, TokenTree}; -use quote::{quote, ToTokens}; -use syn::spanned::Spanned; -use syn::{parse_macro_input, Error, LitStr}; - -macro_rules! err { - ($span:expr, $message:expr $(,)?) => { - Error::new($span.span(), $message).to_compile_error() - }; - ($span:expr, $message:expr, $($args:expr),*) => { - Error::new($span.span(), format!($message, $($args),*)).to_compile_error() - }; -} - -/// Create a `Guid` at compile time. -/// -/// # Example -/// -/// ``` -/// use uefi::{guid, Guid}; -/// const EXAMPLE_GUID: Guid = guid!("12345678-9abc-def0-1234-56789abcdef0"); -/// ``` -#[proc_macro] -pub fn guid(args: TokenStream) -> TokenStream { - let (time_low, time_mid, time_high_and_version, clock_seq_and_variant, node) = - match parse_guid(parse_macro_input!(args as LitStr)) { - Ok(data) => data, - Err(tokens) => return tokens.into(), - }; - - quote!({ - const g: crate::guid::Guid = crate::guid::Guid::from_values( - #time_low, - #time_mid, - #time_high_and_version, - #clock_seq_and_variant, - #node, - ); - g - }) - .into() -} - -fn parse_guid(guid_lit: LitStr) -> Result<(u32, u16, u16, u16, u64), TokenStream2> { - let guid_str = guid_lit.value(); - - // We expect a canonical GUID string, such as "12345678-9abc-def0-fedc-ba9876543210" - if guid_str.len() != 36 { - return Err(err!( - guid_lit, - "\"{}\" is not a canonical GUID string (expected 36 bytes, found {})", - guid_str, - guid_str.len() - )); - } - let mut offset = 1; // 1 is for the starting quote - let mut guid_hex_iter = guid_str.split('-'); - let mut next_guid_int = |len: usize| -> Result { - let guid_hex_component = guid_hex_iter.next().unwrap(); - - // convert syn::LitStr to proc_macro2::Literal.. - let lit = match guid_lit.to_token_stream().into_iter().next().unwrap() { - TokenTree::Literal(lit) => lit, - _ => unreachable!(), - }; - // ..so that we can call subspan and nightly users (us) will get the fancy span - let span = lit - .subspan(offset..offset + guid_hex_component.len()) - .unwrap_or_else(|| lit.span()); - - if guid_hex_component.len() != len * 2 { - return Err(err!( - span, - "GUID component \"{}\" is not a {}-bit hexadecimal string", - guid_hex_component, - len * 8 - )); - } - offset += guid_hex_component.len() + 1; // + 1 for the dash - u64::from_str_radix(guid_hex_component, 16).map_err(|_| { - err!( - span, - "GUID component \"{}\" is not a hexadecimal number", - guid_hex_component - ) - }) - }; - - // The GUID string is composed of a 32-bit integer, three 16-bit ones, and a 48-bit one - Ok(( - next_guid_int(4)? as u32, - next_guid_int(2)? as u16, - next_guid_int(2)? as u16, - next_guid_int(2)? as u16, - next_guid_int(6)?, - )) -}