From 0b2658b8c90e13fbd1b809f59d0d9a08b6076a89 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Thu, 8 May 2025 20:06:06 +0800 Subject: [PATCH 01/22] --expansion-bay: Print PCIe config Signed-off-by: Daniel Schaefer --- EXAMPLES.md | 2 ++ framework_lib/src/chromium_ec/command.rs | 1 + framework_lib/src/chromium_ec/commands.rs | 37 +++++++++++++++++++++++ framework_lib/src/chromium_ec/mod.rs | 14 +++++++++ 4 files changed, 54 insertions(+) diff --git a/EXAMPLES.md b/EXAMPLES.md index 7b915984..08c5cf8d 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -225,6 +225,8 @@ Expansion Bay Door closed: true Board: DualInterposer Serial Number: FRAXXXXXXXXXXXXXXX + Config: Pcie4x2 + Vendor: SsdHolder ``` ## Check charger and battery status (Framework 12/13/16) diff --git a/framework_lib/src/chromium_ec/command.rs b/framework_lib/src/chromium_ec/command.rs index 54b8db52..f1f47fec 100644 --- a/framework_lib/src/chromium_ec/command.rs +++ b/framework_lib/src/chromium_ec/command.rs @@ -96,6 +96,7 @@ pub enum EcCommands { GetHwDiag = 0x3E1C, /// Get gpu bay serial GetGpuSerial = 0x3E1D, + GetGpuPcie = 0x3E1E, /// Set gpu bay serial and program structure ProgramGpuEeprom = 0x3E1F, } diff --git a/framework_lib/src/chromium_ec/commands.rs b/framework_lib/src/chromium_ec/commands.rs index 38cafeb6..1eb588ed 100644 --- a/framework_lib/src/chromium_ec/commands.rs +++ b/framework_lib/src/chromium_ec/commands.rs @@ -1129,6 +1129,43 @@ impl EcRequest for EcRequestGetGpuSerial { } } +#[repr(C, packed)] +pub struct EcRequestGetGpuPcie {} + +#[repr(u8)] +#[derive(Debug, FromPrimitive)] +pub enum GpuPcieConfig { + /// PCIe 8x1 + Pcie8x1 = 0, + /// PCIe 4x1 + Pcie4x1 = 1, + /// PCIe 4x2 + Pcie4x2 = 2, +} + +#[repr(u8)] +#[derive(Debug, FromPrimitive)] +pub enum GpuVendor { + Initializing = 0x00, + FanOnly = 0x01, + GpuAmdR23M = 0x02, + SsdHolder = 0x03, + PcieAccessory = 0x4, +} + +#[repr(C, packed)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub struct EcResponseGetGpuPcie { + pub gpu_pcie_config: u8, + pub gpu_vendor: u8, +} + +impl EcRequest for EcRequestGetGpuPcie { + fn command_id() -> EcCommands { + EcCommands::GetGpuPcie + } +} + #[repr(u8)] pub enum SetGpuSerialMagic { /// 7700S config magic value diff --git a/framework_lib/src/chromium_ec/mod.rs b/framework_lib/src/chromium_ec/mod.rs index afdaef0c..d77994c5 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -1000,6 +1000,20 @@ impl CrosEc { println!(" Serial Number: Unknown"); } + let res = EcRequestGetGpuPcie {}.send_command(self)?; + let config: Option = FromPrimitive::from_u8(res.gpu_pcie_config); + let vendor: Option = FromPrimitive::from_u8(res.gpu_vendor); + if let Some(config) = config { + println!(" Config: {:?}", config); + } else { + println!(" Config: Unknown ({})", res.gpu_pcie_config); + } + if let Some(vendor) = vendor { + println!(" Vendor: {:?}", vendor); + } else { + println!(" Vendor: Unknown ({})", res.gpu_vendor); + } + Ok(()) } From 417ea9e1a29793c6e6c951a2f16aed1cd23cc841 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Thu, 8 May 2025 20:05:25 +0800 Subject: [PATCH 02/22] Add --ps2-enable to control ps2 emulation Signed-off-by: Daniel Schaefer --- framework_lib/src/chromium_ec/command.rs | 1 + framework_lib/src/chromium_ec/commands.rs | 11 +++++++++++ framework_lib/src/chromium_ec/mod.rs | 7 +++++++ framework_lib/src/commandline/clap_std.rs | 6 ++++++ framework_lib/src/commandline/mod.rs | 3 +++ framework_lib/src/commandline/uefi.rs | 21 +++++++++++++++++++++ 6 files changed, 49 insertions(+) diff --git a/framework_lib/src/chromium_ec/command.rs b/framework_lib/src/chromium_ec/command.rs index 54b8db52..86b50c92 100644 --- a/framework_lib/src/chromium_ec/command.rs +++ b/framework_lib/src/chromium_ec/command.rs @@ -60,6 +60,7 @@ pub enum EcCommands { FlashNotified = 0x3E01, /// Change charge limit ChargeLimitControl = 0x3E03, + DisablePs2Emulation = 0x3E08, /// Get/Set Fingerprint LED brightness FpLedLevelControl = 0x3E0E, /// Get information about the current chassis open/close status diff --git a/framework_lib/src/chromium_ec/commands.rs b/framework_lib/src/chromium_ec/commands.rs index 38cafeb6..d3bc4d8f 100644 --- a/framework_lib/src/chromium_ec/commands.rs +++ b/framework_lib/src/chromium_ec/commands.rs @@ -1048,6 +1048,17 @@ impl EcRequest for EcRequestChargeLimitControl { /// TODO: Use this pub const EC_CHARGE_LIMIT_RESTORE: u8 = 0x7F; +#[repr(C, packed)] +pub struct EcRequestDisablePs2Emulation { + pub disable: u8, +} + +impl EcRequest<()> for EcRequestDisablePs2Emulation { + fn command_id() -> EcCommands { + EcCommands::DisablePs2Emulation + } +} + #[repr(u8)] #[derive(Debug, FromPrimitive)] pub enum FpLedBrightnessLevel { diff --git a/framework_lib/src/chromium_ec/mod.rs b/framework_lib/src/chromium_ec/mod.rs index afdaef0c..2ea843f3 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -596,6 +596,13 @@ impl CrosEc { Ok((kblight.duty / (PWM_MAX_DUTY / 100)) as u8) } + pub fn ps2_emulation_enable(&self, enable: bool) -> EcResult<()> { + EcRequestDisablePs2Emulation { + disable: !enable as u8, + } + .send_command(self) + } + pub fn fan_set_rpm(&self, fan: Option, rpm: u32) -> EcResult<()> { if let Some(fan_idx) = fan { EcRequestPwmSetFanTargetRpmV1 { rpm, fan_idx }.send_command(self) diff --git a/framework_lib/src/commandline/clap_std.rs b/framework_lib/src/commandline/clap_std.rs index 76784a5f..9ace517f 100644 --- a/framework_lib/src/commandline/clap_std.rs +++ b/framework_lib/src/commandline/clap_std.rs @@ -188,6 +188,11 @@ struct ClapCli { #[arg(long, value_parser=maybe_hex::)] rgbkbd: Vec, + /// Enable/disable PS2 touchpad emulation + #[clap(value_enum)] + #[arg(long)] + ps2_enable: Option, + /// Set tablet mode override #[clap(value_enum)] #[arg(long)] @@ -393,6 +398,7 @@ pub fn parse(args: &[String]) -> Cli { fp_brightness: args.fp_brightness, kblight: args.kblight, rgbkbd: args.rgbkbd, + ps2_enable: args.ps2_enable, tablet_mode: args.tablet_mode, touchscreen_enable: args.touchscreen_enable, stylus_battery: args.stylus_battery, diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index b2a324f1..5df3e642 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -182,6 +182,7 @@ pub struct Cli { pub fp_brightness: Option>, pub kblight: Option>, pub rgbkbd: Vec, + pub ps2_enable: Option, pub tablet_mode: Option, pub touchscreen_enable: Option, pub stylus_battery: bool, @@ -819,6 +820,8 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { }); ec.rgbkbd_set_color(start_key, colors.collect()).unwrap(); } + } else if let Some(enable) = args.ps2_enable { + print_err(ec.ps2_emulation_enable(enable)); } else if let Some(None) = args.kblight { print!("Keyboard backlight: "); if let Some(percentage) = print_err(ec.get_keyboard_backlight()) { diff --git a/framework_lib/src/commandline/uefi.rs b/framework_lib/src/commandline/uefi.rs index 1fd9e5d8..b02667dd 100644 --- a/framework_lib/src/commandline/uefi.rs +++ b/framework_lib/src/commandline/uefi.rs @@ -95,6 +95,7 @@ pub fn parse(args: &[String]) -> Cli { fp_brightness: None, kblight: None, rgbkbd: vec![], + ps2_enable: None, tablet_mode: None, touchscreen_enable: None, stylus_battery: false, @@ -361,6 +362,26 @@ pub fn parse(args: &[String]) -> Cli { println!("--rgbkbd requires at least 2 arguments, the start key and an RGB value"); vec![] } + } else if arg == "--ps2-enable" { + cli.ps2_enable = if args.len() > i + 1 { + let enable_arg = &args[i + 1]; + if enable_arg == "true" { + Some(true) + } else if enable_arg == "false" { + Some(false) + } else { + println!( + "Need to provide a value for --ps2-enable: '{}'. {}", + args[i + 1], + "Must be `true` or `false`", + ); + None + } + } else { + println!("Need to provide a value for --tablet-mode. One of: `auto`, `tablet` or `laptop`"); + None + }; + found_an_option = true; } else if arg == "--tablet-mode" { cli.tablet_mode = if args.len() > i + 1 { let tablet_mode_arg = &args[i + 1]; From e4832fe054805b6869147c2b595b766e67bc3569 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Mon, 12 May 2025 14:10:00 +0800 Subject: [PATCH 03/22] --get-gpio: Return all GPIOs if no name was passed Another benefit is that you can find out the names of all GPIOs. ``` > sudo framework_tool --get-gpio ec_espi_rst_l 0 runpwrok 1 otg_en 0 ec_i2c0_clk0 0 ec_i2c0_sda0 0 ec_i2c1_clk0 0 ec_i2c1_sda0 0 ec_i2c2_clk0 0 [...] ``` Signed-off-by: Daniel Schaefer --- README.md | 4 +- framework_lib/src/chromium_ec/commands.rs | 55 +++++++++++++++++++++++ framework_lib/src/chromium_ec/mod.rs | 35 +++++++++++++++ framework_lib/src/commandline/clap_std.rs | 4 +- framework_lib/src/commandline/mod.rs | 16 ++++--- framework_lib/src/commandline/uefi.rs | 4 +- 6 files changed, 106 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 7c41c4ca..2841b579 100644 --- a/README.md +++ b/README.md @@ -171,8 +171,8 @@ Options: --expansion-bay Show status of the expansion bay (Framework 16 only) --charge-limit [] Get or set max charge limit - --get-gpio - Get GPIO value by name + --get-gpio [] + Get GPIO value by name or all, if no name provided --fp-led-level [] Get or set fingerprint LED brightness level [possible values: high, medium, low, ultra-low, auto] --fp-brightness [] diff --git a/framework_lib/src/chromium_ec/commands.rs b/framework_lib/src/chromium_ec/commands.rs index 38cafeb6..0c8a6ef2 100644 --- a/framework_lib/src/chromium_ec/commands.rs +++ b/framework_lib/src/chromium_ec/commands.rs @@ -343,6 +343,61 @@ impl EcRequest for EcRequestGpioGetV0 { } } +pub enum GpioGetSubCommand { + ByName = 0, + Count = 1, + Info = 2, +} + +#[repr(C, packed)] +pub struct EcRequestGpioGetV1Count { + pub subcmd: u8, +} + +#[repr(C, packed)] +pub struct EcRequestGpioGetV1ByName { + pub subcmd: u8, + pub name: [u8; 32], +} + +#[repr(C, packed)] +pub struct EcRequestGpioGetV1Info { + pub subcmd: u8, + pub index: u8, +} + +#[repr(C)] +pub struct EcResponseGpioGetV1Info { + pub val: u8, + pub name: [u8; 32], + pub flags: u32, +} + +impl EcRequest for EcRequestGpioGetV1Count { + fn command_id() -> EcCommands { + EcCommands::GpioGet + } + fn command_version() -> u8 { + 1 + } +} +impl EcRequest for EcRequestGpioGetV1ByName { + fn command_id() -> EcCommands { + EcCommands::GpioGet + } + fn command_version() -> u8 { + 1 + } +} +impl EcRequest for EcRequestGpioGetV1Info { + fn command_id() -> EcCommands { + EcCommands::GpioGet + } + fn command_version() -> u8 { + 1 + } +} + #[repr(C, packed)] pub struct EcRequestReboot {} diff --git a/framework_lib/src/chromium_ec/mod.rs b/framework_lib/src/chromium_ec/mod.rs index afdaef0c..460e7985 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -1228,6 +1228,41 @@ impl CrosEc { Ok(res.val == 1) } + pub fn get_all_gpios(&self) -> EcResult { + let res = EcRequestGpioGetV1Count { + subcmd: GpioGetSubCommand::Count as u8, + } + .send_command(self)?; + let gpio_count = res.val; + + debug!("Found {} GPIOs", gpio_count); + + for index in 0..res.val { + let res = EcRequestGpioGetV1Info { + subcmd: GpioGetSubCommand::Info as u8, + index, + } + .send_command(self)?; + + let name = std::str::from_utf8(&res.name) + .map_err(|utf8_err| { + EcError::DeviceError(format!("Failed to decode GPIO name: {:?}", utf8_err)) + })? + .trim_end_matches(char::from(0)) + .to_string(); + + if log_enabled!(Level::Info) { + // Same output as ectool + println!("{:>32}: {:>2} 0x{:04X}", res.val, name, { res.flags }); + } else { + // Simple output, just name and level high/low + println!("{:<32} {}", name, res.val); + } + } + + Ok(gpio_count) + } + pub fn adc_read(&self, adc_channel: u8) -> EcResult { let res = EcRequestAdcRead { adc_channel }.send_command(self)?; Ok(res.adc_value) diff --git a/framework_lib/src/commandline/clap_std.rs b/framework_lib/src/commandline/clap_std.rs index 76784a5f..14147f82 100644 --- a/framework_lib/src/commandline/clap_std.rs +++ b/framework_lib/src/commandline/clap_std.rs @@ -165,9 +165,9 @@ struct ClapCli { #[clap(num_args = ..=2)] charge_rate_limit: Vec, - /// Get GPIO value by name + /// Get GPIO value by name or all, if no name provided #[arg(long)] - get_gpio: Option, + get_gpio: Option>, /// Get or set fingerprint LED brightness level #[arg(long)] diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index b2a324f1..6676ca07 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -177,7 +177,7 @@ pub struct Cli { pub charge_limit: Option>, pub charge_current_limit: Option<(u32, Option)>, pub charge_rate_limit: Option<(f32, Option)>, - pub get_gpio: Option, + pub get_gpio: Option>, pub fp_led_level: Option>, pub fp_brightness: Option>, pub kblight: Option>, @@ -791,11 +791,15 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { } else if let Some((limit, soc)) = args.charge_rate_limit { print_err(ec.set_charge_rate_limit(limit, soc)); } else if let Some(gpio_name) = &args.get_gpio { - print!("Getting GPIO value {}: ", gpio_name); - if let Ok(value) = ec.get_gpio(gpio_name) { - println!("{:?}", value); + if let Some(gpio_name) = gpio_name { + print!("GPIO {}: ", gpio_name); + if let Ok(value) = ec.get_gpio(gpio_name) { + println!("{:?}", value); + } else { + println!("Not found"); + } } else { - println!("Not found"); + print_err(ec.get_all_gpios()); } } else if let Some(maybe_led_level) = &args.fp_led_level { print_err(handle_fp_led_level(&ec, *maybe_led_level)); @@ -1120,7 +1124,7 @@ Options: --expansion-bay Show status of the expansion bay (Framework 16 only) --charge-limit [] Get or set battery charge limit (Percentage number as arg, e.g. '100') --charge-current-limit [] Get or set battery current charge limit (Percentage number as arg, e.g. '100') - --get-gpio Get GPIO value by name + --get-gpio Get GPIO value by name or all, if no name provided --fp-led-level [] Get or set fingerprint LED brightness level [possible values: high, medium, low] --fp-brightness []Get or set fingerprint LED brightness percentage --kblight [] Set keyboard backlight percentage or get, if no value provided diff --git a/framework_lib/src/commandline/uefi.rs b/framework_lib/src/commandline/uefi.rs index 1fd9e5d8..1675c5be 100644 --- a/framework_lib/src/commandline/uefi.rs +++ b/framework_lib/src/commandline/uefi.rs @@ -329,9 +329,9 @@ pub fn parse(args: &[String]) -> Cli { found_an_option = true; } else if arg == "--get-gpio" { cli.get_gpio = if args.len() > i + 1 { - Some(args[i + 1].clone()) + Some(Some(args[i + 1].clone())) } else { - None + Some(None) }; found_an_option = true; } else if arg == "--kblight" { From 36cd61e1581c05f608f2714fe40a8b69f81c861b Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Mon, 12 May 2025 15:01:24 +0800 Subject: [PATCH 04/22] --sensors: Get information about sensors On Framework 12: ALS is not shown anymore and now shows which accel is which. ``` > framework_tool --sensors -vv [INFO ] Sensors: 2 [INFO ] Type: Accel [INFO ] Location: Lid [INFO ] Chip: Bma422 [INFO ] Type: Accel [INFO ] Location: Base [INFO ] Chip: Bma422 Accelerometers: Lid Angle: 118 Deg Lid Sensor: X=+0.00G Y=+0.86G, Z=+0.53G Base Sensor: X=-0.03G Y=-0.07G, Z=+1.02G ``` Framework 13 ``` > framework_tool --sensors ALS: 130 Lux ``` Signed-off-by: Daniel Schaefer --- EXAMPLES.md | 8 +- framework_lib/src/chromium_ec/command.rs | 1 + framework_lib/src/chromium_ec/commands.rs | 128 ++++++++++++++++++++++ framework_lib/src/chromium_ec/mod.rs | 37 +++++++ framework_lib/src/power.rs | 71 +++++++++--- framework_lib/src/smbios.rs | 6 +- 6 files changed, 232 insertions(+), 19 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index 7b915984..8ed7d1c0 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -173,13 +173,13 @@ ALS: 76 Lux ``` ### Accelerometer (Framework 12) + ``` > sudo framework_tool --sensors -ALS: 0 Lux Accelerometers: - Lid Angle: 122 Deg - Sensor 1: X=+0.00G Y=+0.84G, Z=+0.52G - Sensor 2: X=-0.03G Y=+0.00G, Z=+1.01G + Lid Angle: 118 Deg + Lid Sensor: X=+0.00G Y=+0.86G, Z=+0.53G + Base Sensor: X=-0.03G Y=-0.07G, Z=+1.02G ``` ## Set custom fan duty/RPM diff --git a/framework_lib/src/chromium_ec/command.rs b/framework_lib/src/chromium_ec/command.rs index 54b8db52..e1048ea9 100644 --- a/framework_lib/src/chromium_ec/command.rs +++ b/framework_lib/src/chromium_ec/command.rs @@ -33,6 +33,7 @@ pub enum EcCommands { PwmSetKeyboardBacklight = 0x0023, PwmSetFanDuty = 0x0024, PwmSetDuty = 0x0025, + MotionSense = 0x002B, PwmGetDuty = 0x0026, SetTabletMode = 0x0031, AutoFanCtrl = 0x0052, diff --git a/framework_lib/src/chromium_ec/commands.rs b/framework_lib/src/chromium_ec/commands.rs index 38cafeb6..1dec8b19 100644 --- a/framework_lib/src/chromium_ec/commands.rs +++ b/framework_lib/src/chromium_ec/commands.rs @@ -282,6 +282,134 @@ impl EcRequest for EcRequestPwmGetDuty { } } +#[repr(u8)] +pub enum MotionSenseCmd { + Dump = 0, + Info = 1, +} + +#[repr(C, packed)] +pub struct EcRequestMotionSenseDump { + /// MotionSenseCmd::Dump + pub cmd: u8, + /// Maximal number of sensor the host is expecting. + /// 0 means the host is only interested in the number + /// of sensors controlled by the EC. + pub max_sensor_count: u8, +} + +#[repr(C, packed)] +pub struct EcResponseMotionSenseDump { + /// Flags representing the motion sensor module + pub module_flags: u8, + + /// Number of sensors managed directly by the EC + pub sensor_count: u8, + + /// Sensor data is truncated if response_max is too small + /// for holding all the data. + pub sensor: [u8; 0], +} + +impl EcRequest for EcRequestMotionSenseDump { + fn command_id() -> EcCommands { + EcCommands::MotionSense + } + fn command_version() -> u8 { + 1 + } +} + +#[derive(Debug, FromPrimitive, PartialEq)] +pub enum MotionSenseType { + Accel = 0, + Gyro = 1, + Mag = 2, + Prox = 3, + Light = 4, + Activity = 5, + Baro = 6, + Sync = 7, + LightRgb = 8, +} + +#[derive(Debug, FromPrimitive)] +pub enum MotionSenseLocation { + Base = 0, + Lid = 1, + Camera = 2, +} + +#[derive(Debug, FromPrimitive)] +pub enum MotionSenseChip { + Kxcj9 = 0, + Lsm6ds0 = 1, + Bmi160 = 2, + Si1141 = 3, + Si1142 = 4, + Si1143 = 5, + Kx022 = 6, + L3gd20h = 7, + Bma255 = 8, + Bmp280 = 9, + Opt3001 = 10, + Bh1730 = 11, + Gpio = 12, + Lis2dh = 13, + Lsm6dsm = 14, + Lis2de = 15, + Lis2mdl = 16, + Lsm6ds3 = 17, + Lsm6dso = 18, + Lng2dm = 19, + Tcs3400 = 20, + Lis2dw12 = 21, + Lis2dwl = 22, + Lis2ds = 23, + Bmi260 = 24, + Icm426xx = 25, + Icm42607 = 26, + Bma422 = 27, + Bmi323 = 28, + Bmi220 = 29, + Cm32183 = 30, + Veml3328 = 31, +} + +#[repr(C, packed)] +pub struct EcRequestMotionSenseInfo { + /// MotionSenseCmd::Info + pub cmd: u8, + /// Sensor index + pub sensor_num: u8, +} + +#[repr(C)] +pub struct EcResponseMotionSenseInfo { + /// See enum MotionSenseInfo + pub sensor_type: u8, + /// See enum MotionSenseLocation + pub location: u8, + /// See enum MotionSenseChip + pub chip: u8, +} + +#[derive(Debug)] +pub struct MotionSenseInfo { + pub sensor_type: MotionSenseType, + pub location: MotionSenseLocation, + pub chip: MotionSenseChip, +} + +impl EcRequest for EcRequestMotionSenseInfo { + fn command_id() -> EcCommands { + EcCommands::MotionSense + } + fn command_version() -> u8 { + 1 + } +} + pub enum TabletModeOverride { Default = 0, ForceTablet = 1, diff --git a/framework_lib/src/chromium_ec/mod.rs b/framework_lib/src/chromium_ec/mod.rs index afdaef0c..fcda9ecb 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -353,6 +353,43 @@ impl CrosEc { )) } + pub fn motionsense_sensor_count(&self) -> EcResult { + EcRequestMotionSenseDump { + cmd: MotionSenseCmd::Dump as u8, + max_sensor_count: 0, + } + .send_command(self) + .map(|res| res.sensor_count) + } + + pub fn motionsense_sensor_info(&self) -> EcResult> { + let count = self.motionsense_sensor_count()?; + + let mut sensors = vec![]; + for sensor_num in 0..count { + let info = EcRequestMotionSenseInfo { + cmd: MotionSenseCmd::Info as u8, + sensor_num, + } + .send_command(self)?; + sensors.push(MotionSenseInfo { + sensor_type: FromPrimitive::from_u8(info.sensor_type).unwrap(), + location: FromPrimitive::from_u8(info.location).unwrap(), + chip: FromPrimitive::from_u8(info.chip).unwrap(), + }); + } + Ok(sensors) + } + + pub fn motionsense_sensor_list(&self) -> EcResult { + EcRequestMotionSenseDump { + cmd: MotionSenseCmd::Dump as u8, + max_sensor_count: 0, + } + .send_command(self) + .map(|res| res.sensor_count) + } + /// Get current status of Framework Laptop's microphone and camera privacy switches /// [true = device enabled/connected, false = device disabled] pub fn get_privacy_info(&self) -> EcResult<(bool, bool)> { diff --git a/framework_lib/src/power.rs b/framework_lib/src/power.rs index f365d57a..ba89af1d 100644 --- a/framework_lib/src/power.rs +++ b/framework_lib/src/power.rs @@ -1,5 +1,6 @@ //! Get information about system power (battery, AC, PD ports) +use alloc::format; use alloc::string::String; use alloc::vec; use alloc::vec::Vec; @@ -10,11 +11,11 @@ use log::Level; use crate::ccgx::{AppVersion, Application, BaseVersion, ControllerVersion, MainPdVersions}; use crate::chromium_ec::command::EcRequestRaw; -use crate::chromium_ec::commands::{EcRequestReadPdVersion, EcRequestUsbPdPowerInfo}; -use crate::chromium_ec::{print_err_ref, CrosEc, CrosEcDriver, EcResult}; +use crate::chromium_ec::commands::*; +use crate::chromium_ec::*; use crate::smbios; use crate::smbios::get_platform; -use crate::util::Platform; +use crate::util::{Platform, PlatformFamily}; /// Maximum length of strings in memmap const EC_MEMMAP_TEXT_MAX: u16 = 8; @@ -245,9 +246,15 @@ pub fn print_memmap_version_info(ec: &CrosEc) { } /// Not supported on TGL EC -pub fn get_als_reading(ec: &CrosEc) -> Option { +pub fn get_als_reading(ec: &CrosEc, index: usize) -> Option { let als = ec.read_memory(EC_MEMMAP_ALS, 0x04)?; - Some(u32::from_le_bytes([als[0], als[1], als[2], als[3]])) + let offset = index + 4 * index; + Some(u32::from_le_bytes([ + als[offset], + als[1 + offset], + als[2 + offset], + als[3 + offset], + ])) } pub fn get_accel_data(ec: &CrosEc) -> (AccelData, AccelData, LidAngle) { @@ -274,8 +281,40 @@ pub fn get_accel_data(ec: &CrosEc) -> (AccelData, AccelData, LidAngle) { } pub fn print_sensors(ec: &CrosEc) { - let als_int = get_als_reading(ec).unwrap(); - println!("ALS: {:>4} Lux", als_int); + let mut has_als = false; + let mut accel_locations = vec![]; + + match ec.motionsense_sensor_info() { + Ok(sensors) => { + info!("Sensors: {}", sensors.len()); + for sensor in sensors { + info!(" Type: {:?}", sensor.sensor_type); + info!(" Location: {:?}", sensor.location); + info!(" Chip: {:?}", sensor.chip); + if sensor.sensor_type == MotionSenseType::Light { + has_als = true; + } + if sensor.sensor_type == MotionSenseType::Accel { + accel_locations.push(sensor.location); + } + } + } + Err(EcError::Response(EcResponseStatus::InvalidCommand)) => { + debug!("Motionsense commands not supported") + } + err => _ = print_err(err), + } + + // If we can't detect it based on motionsense + let als_family = matches!( + smbios::get_family(), + Some(PlatformFamily::Framework13) | Some(PlatformFamily::Framework16) + ); + + if has_als || als_family { + let als_int = get_als_reading(ec, 0).unwrap(); + println!("ALS: {:>4} Lux", als_int); + } // bit 4 = busy // bit 7 = present @@ -294,18 +333,22 @@ pub fn print_sensors(ec: &CrosEc) { debug!(" Status Bit: {} 0x{:X}", acc_status, acc_status); debug!(" Present: {}", present); debug!(" Busy: {}", (acc_status & 0x8) > 0); - print!(" Lid Angle: "); + print!(" Lid Angle: "); if lid_angle == LID_ANGLE_UNRELIABLE { println!("Unreliable"); } else { println!("{} Deg", lid_angle); } - println!(" Sensor 1: {}", AccelData::from(accel_1)); - println!(" Sensor 2: {}", AccelData::from(accel_2)); - // Accelerometers - // Lid Angle: 26 Deg - // Sensor 1: 00.00 X 00.00 Y 00.00 Z - // Sensor 2: 00.00 X 00.00 Y 00.00 Z + println!( + " {:<12} {}", + format!("{:?} Sensor:", accel_locations[0]), + AccelData::from(accel_1) + ); + println!( + " {:<12} {}", + format!("{:?} Sensor:", accel_locations[1]), + AccelData::from(accel_2) + ); } } diff --git a/framework_lib/src/smbios.rs b/framework_lib/src/smbios.rs index c5cfef29..935f0dc7 100644 --- a/framework_lib/src/smbios.rs +++ b/framework_lib/src/smbios.rs @@ -6,7 +6,7 @@ use std::prelude::v1::*; use std::io::ErrorKind; use crate::util::Config; -pub use crate::util::Platform; +pub use crate::util::{Platform, PlatformFamily}; use num_derive::FromPrimitive; use num_traits::FromPrimitive; use smbioslib::*; @@ -271,6 +271,10 @@ pub fn get_baseboard_version() -> Option { }) } +pub fn get_family() -> Option { + get_platform().and_then(Platform::which_family) +} + pub fn get_platform() -> Option { #[cfg(feature = "uefi")] let mut cached_platform = CACHED_PLATFORM.lock(); From 98810c5f3e94b43e47c28605f01f0310ad8c0a11 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 13 May 2025 18:26:47 +0800 Subject: [PATCH 05/22] --ps2-enable: Hide command Normally this command will not do what you think. Unless you know what you're doing, you should not be using it. It works in the following case: ``` framework_tool --ps2-enable true sudo modprobe -r i2c_hid_acpi sudo modprobe i2c_hid_acpi ``` Signed-off-by: Daniel Schaefer --- framework_lib/src/commandline/clap_std.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework_lib/src/commandline/clap_std.rs b/framework_lib/src/commandline/clap_std.rs index 9ace517f..735267d8 100644 --- a/framework_lib/src/commandline/clap_std.rs +++ b/framework_lib/src/commandline/clap_std.rs @@ -188,8 +188,8 @@ struct ClapCli { #[arg(long, value_parser=maybe_hex::)] rgbkbd: Vec, - /// Enable/disable PS2 touchpad emulation - #[clap(value_enum)] + /// Control PS2 touchpad emulation (DEBUG COMMAND, if touchpad not working, reboot system) + #[clap(value_enum, hide(true))] #[arg(long)] ps2_enable: Option, From 6db35792397adca663a3ebb8b4c28faf361eaca8 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 13 May 2025 20:03:50 +0800 Subject: [PATCH 06/22] EXAMPLES: Add --dp-hdmi-info Signed-off-by: Daniel Schaefer --- EXAMPLES.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/EXAMPLES.md b/EXAMPLES.md index 2098d223..3705fa87 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -114,6 +114,17 @@ LED Matrix [...] ``` +### DisplayPort or HDMI Expansion Card + +``` +> framework_tool --dp-hdmi-info +DisplayPort Expansion Card + Serial Number: 11AD1D0030123F17142C0B00 + Active Firmware: 101 (3.0.11.065) + Inactive Firmware: 008 (3.0.11.008) + Operating Mode: MainFw (#2) +``` + ## Check input deck status ### On Framework 12 From 441ec74eff7e78474fa36dcb5a1cfd4086989b53 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 13 May 2025 20:12:14 +0800 Subject: [PATCH 07/22] versions: Print DP and HDMI card firmware Signed-off-by: Daniel Schaefer --- EXAMPLES.md | 8 ++++ framework_lib/src/ccgx/hid.rs | 56 ++++++++++++++++------------ framework_lib/src/commandline/mod.rs | 10 +++-- 3 files changed, 47 insertions(+), 27 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index 3705fa87..d0d94f53 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -123,6 +123,14 @@ DisplayPort Expansion Card Active Firmware: 101 (3.0.11.065) Inactive Firmware: 008 (3.0.11.008) Operating Mode: MainFw (#2) + +# Or +> framework_tool --versions +[...] +DisplayPort Expansion Card + Active Firmware: 101 (3.0.11.065) + Inactive Firmware: 008 (3.0.11.008) + Operating Mode: MainFw (#2) ``` ## Check input deck status diff --git a/framework_lib/src/ccgx/hid.rs b/framework_lib/src/ccgx/hid.rs index 64dcc748..c36aeebb 100644 --- a/framework_lib/src/ccgx/hid.rs +++ b/framework_lib/src/ccgx/hid.rs @@ -132,10 +132,10 @@ fn get_fw_info(device: &HidDevice) -> HidFirmwareInfo { decode_fw_info(&buf) } -pub fn check_ccg_fw_version(device: &HidDevice) { +pub fn check_ccg_fw_version(device: &HidDevice, verbose: bool) { magic_unlock(device); let info = get_fw_info(device); - print_fw_info(&info); + print_fw_info(&info, verbose); } fn decode_fw_info(buf: &[u8]) -> HidFirmwareInfo { @@ -152,13 +152,13 @@ fn decode_fw_info(buf: &[u8]) -> HidFirmwareInfo { info } -fn print_fw_info(info: &HidFirmwareInfo) { +fn print_fw_info(info: &HidFirmwareInfo, verbose: bool) { assert_eq!(info.report_id, ReportIdCmd::E0Read as u8); info!(" Signature: {:X?}", info.signature); // Something's totally off if the signature is invalid if info.signature != [b'C', b'Y'] { - println!("Firmware Signature is invalid."); + error!("Firmware Signature is invalid."); return; } @@ -219,23 +219,33 @@ fn print_fw_info(info: &HidFirmwareInfo) { FwMode::BackupFw => (base_version_1, image_1_valid, base_version_2, image_2_valid), }; - println!( - " Active Firmware: {:03} ({}){}", - active_ver.build_number, - active_ver, - if active_valid { "" } else { " - INVALID!" } - ); - println!( - " Inactive Firmware: {:03} ({}){}", - inactive_ver.build_number, - inactive_ver, - if inactive_valid { "" } else { " - INVALID!" } - ); - println!( - " Operating Mode: {:?} (#{})", - FwMode::try_from(info.operating_mode).unwrap(), - info.operating_mode - ); + if verbose || active_ver != inactive_ver { + println!( + " Active Firmware: {:03} ({}){}", + active_ver.build_number, + active_ver, + if active_valid { "" } else { " - INVALID!" } + ); + println!( + " Inactive Firmware: {:03} ({}){}", + inactive_ver.build_number, + inactive_ver, + if inactive_valid { "" } else { " - INVALID!" } + ); + println!( + " Operating Mode: {:?} (#{})", + FwMode::try_from(info.operating_mode).unwrap(), + info.operating_mode + ); + } else { + println!( + " Active Firmware: {:03} ({}, {:?}){}", + active_ver.build_number, + active_ver, + FwMode::try_from(info.operating_mode).unwrap(), + if active_valid { "" } else { " - INVALID!" } + ); + } } /// Turn CCG3 Expansion Card VID/PID into their name @@ -332,7 +342,7 @@ pub fn flash_firmware(fw_binary: &[u8]) { magic_unlock(&device); let info = get_fw_info(&device); println!("Before Updating"); - print_fw_info(&info); + print_fw_info(&info, true); println!("Updating..."); match info.operating_mode { @@ -369,7 +379,7 @@ pub fn flash_firmware(fw_binary: &[u8]) { wait_to_reappear(&mut api, &filter_devs, sn).expect("Device did not reappear"); println!("After Updating"); - print_fw_info(&info); + print_fw_info(&info, true); } } diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index 6676ca07..0632aa22 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -246,7 +246,7 @@ fn print_audio_card_details() { } #[cfg(feature = "hidapi")] -fn print_dp_hdmi_details() { +fn print_dp_hdmi_details(verbose: bool) { match HidApi::new() { Ok(api) => { for dev_info in find_devices(&api, &[HDMI_CARD_PID, DP_CARD_PID], None) { @@ -264,11 +264,11 @@ fn print_dp_hdmi_details() { dev_info.product_string().unwrap_or(NOT_SET) ); - println!( + debug!( " Serial Number: {}", dev_info.serial_number().unwrap_or(NOT_SET) ); - check_ccg_fw_version(&device); + check_ccg_fw_version(&device, verbose); } } Err(e) => { @@ -521,6 +521,8 @@ fn print_versions(ec: &CrosEc) { if let Some(Platform::Framework12IntelGen13) = smbios::get_platform() { let _ignore_err = touchscreen::print_fw_ver(); } + #[cfg(feature = "hidapi")] + print_dp_hdmi_details(false); } fn print_esrt() { @@ -913,7 +915,7 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { print_pd_details(&ec); } else if args.dp_hdmi_info { #[cfg(feature = "hidapi")] - print_dp_hdmi_details(); + print_dp_hdmi_details(true); } else if let Some(pd_bin_path) = &args.dp_hdmi_update { #[cfg(feature = "hidapi")] flash_dp_hdmi_card(pd_bin_path); From f4cb313a9ba80fc71f97617c96cdcb6b322239a6 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 13 May 2025 22:08:01 +0800 Subject: [PATCH 08/22] --versions: Print protocols in a single line Signed-off-by: Daniel Schaefer --- EXAMPLES.md | 3 +-- framework_lib/src/touchscreen.rs | 10 ++++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index d0d94f53..c341ee13 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -56,8 +56,7 @@ Laptop Webcam Module (2nd Gen) [...] Touchscreen Firmware Version: v7.0.0.5.0.0.0.0 - USI Protocol: false - MPP Protocol: true + Protocols: USI ``` ### Stylus (Framework 12) diff --git a/framework_lib/src/touchscreen.rs b/framework_lib/src/touchscreen.rs index 256df139..de74c9f9 100644 --- a/framework_lib/src/touchscreen.rs +++ b/framework_lib/src/touchscreen.rs @@ -207,8 +207,14 @@ pub trait TouchScreen { println!(" Firmware Version: v{}", ver); let res = self.send_message(0x20, 16, vec![0])?; - println!(" USI Protocol: {:?}", (res[15] & USI_BITMAP) > 0); - println!(" MPP Protocol: {:?}", (res[15] & MPP_BITMAP) > 0); + let mut protocols = vec![]; + if (res[15] & USI_BITMAP) > 0 { + protocols.push("USI"); + } + if (res[15] & MPP_BITMAP) > 0 { + protocols.push("MPP"); + } + println!(" Protocols: {}", protocols.join(", ")); Some(()) } From 48b08f3dba1d699536ec2c8f4495161e398db241 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 13 May 2025 22:13:48 +0800 Subject: [PATCH 09/22] --versions: Don't show both EC versions if they're the same Signed-off-by: Daniel Schaefer --- EXAMPLES.md | 4 +--- framework_lib/src/commandline/mod.rs | 8 +++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index c341ee13..ecaf2de4 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -15,9 +15,7 @@ UEFI BIOS Version: 03.00 Release Date: 03/10/2025 EC Firmware - Build version: "lilac-3.0.0-1541dc6 2025-05-05 11:31:24 zoid@localhost" - RO Version: "lilac-3.0.0-1541dc6" - RW Version: "lilac-3.0.0-1541dc6" + Build version: lilac-3.0.0-1541dc6 2025-05-05 11:31:24 zoid@localhost Current image: RO PD Controllers Right (01) diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index 0632aa22..b9705dc5 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -373,11 +373,13 @@ fn print_versions(ec: &CrosEc) { println!("EC Firmware"); let ver = print_err(ec.version_info()).unwrap_or_else(|| "UNKNOWN".to_string()); - println!(" Build version: {:?}", ver); + println!(" Build version: {}", ver); if let Some((ro, rw, curr)) = ec.flash_version() { - println!(" RO Version: {:?}", ro); - println!(" RW Version: {:?}", rw); + if ro != rw || log_enabled!(Level::Info) { + println!(" RO Version: {}", ro); + println!(" RW Version: {}", rw); + } print!(" Current image: "); if curr == chromium_ec::EcCurrentImage::RO { println!("RO"); From fefe256f08fe98792f4c5cea0873b65633c6f07c Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 13 May 2025 22:24:35 +0800 Subject: [PATCH 10/22] --versions: Hide touchpad IC type It's not normally possible to use a different type of touchpad IC on our systems. Signed-off-by: Daniel Schaefer --- EXAMPLES.md | 1 - framework_lib/src/touchpad.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index ecaf2de4..1a4a2e85 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -76,7 +76,6 @@ Stylus > framework_tool --versions [...] Touchpad - IC Type: 0239 Firmware Version: v0E07 ``` diff --git a/framework_lib/src/touchpad.rs b/framework_lib/src/touchpad.rs index e767c7e6..35c4fc55 100644 --- a/framework_lib/src/touchpad.rs +++ b/framework_lib/src/touchpad.rs @@ -59,7 +59,7 @@ pub fn print_touchpad_fw_ver() -> Result<(), HidError> { let device = dev_info.open_device(&api).unwrap(); println!("Touchpad"); - println!(" IC Type: {:04X}", pid); + info!(" IC Type: {:04X}", pid); let ver = match pid { 0x0239 => format!("{:04X}", read_239_ver(&device)?), From ec0d113ae80b1f1d18e7f4ab2e84497a3b399bbb Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 13 May 2025 22:27:05 +0800 Subject: [PATCH 11/22] --versions: Hide extra CSME versions if they're the same Signed-off-by: Daniel Schaefer --- EXAMPLES.md | 10 ++++++++++ framework_lib/src/commandline/mod.rs | 10 ++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index 1a4a2e85..08948ae8 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -129,6 +129,16 @@ DisplayPort Expansion Card Operating Mode: MainFw (#2) ``` +### CSME Version (Linux on Intel systems) + +``` +> framework_tool --versions +[...] +CSME + Firmware Version: 0:16.1.32.2473 +[...] +``` + ## Check input deck status ### On Framework 12 diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index b9705dc5..b115140c 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -502,10 +502,12 @@ fn print_versions(ec: &CrosEc) { { println!("CSME"); if let Ok(csme) = csme::csme_from_sysfs() { - println!(" Enabled: {}", csme.enabled); - println!(" Version: {}", csme.main_ver); - println!(" Recovery Ver: {}", csme.recovery_ver); - println!(" Original Ver: {}", csme.fitc_ver); + info!(" Enabled: {}", csme.enabled); + println!(" Firmware Version: {}", csme.main_ver); + if csme.main_ver != csme.recovery_ver || csme.main_ver != csme.fitc_ver { + println!(" Recovery Ver: {}", csme.recovery_ver); + println!(" Original Ver: {}", csme.fitc_ver); + } } else { println!(" Unknown"); } From 46114f91ccf52beab5d8897d114d2e729c2e3f70 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 13 May 2025 22:37:35 +0800 Subject: [PATCH 12/22] --versions: Hide PD backup version if it's the same Signed-off-by: Daniel Schaefer --- EXAMPLES.md | 8 +-- framework_lib/src/commandline/mod.rs | 77 ++++++++++++++++++---------- 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index 08948ae8..33445eeb 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -18,12 +18,8 @@ EC Firmware Build version: lilac-3.0.0-1541dc6 2025-05-05 11:31:24 zoid@localhost Current image: RO PD Controllers - Right (01) - Main: 0.0.0E (Active) - Backup: 0.0.0E - Left (23) - Main: 0.0.0E (Active) - Backup: 0.0.0E + Right (01): 0.0.0E (MainFw) + Left (23): 0.0.0E (MainFw) [...] ``` diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index b115140c..22d3c73e 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -399,53 +399,78 @@ fn print_versions(ec: &CrosEc) { if let Ok(pd_versions) = ccgx::get_pd_controller_versions(ec) { let right = &pd_versions.controller01; let left = &pd_versions.controller23; - println!(" Right (01)"); // let active_mode = if let Some(Platform::IntelGen11) = smbios::get_platform() { + if right.main_fw.base != right.backup_fw.base { + println!(" Right (01)"); + println!( + " Main: {}{}", + right.main_fw.base, + active_mode(&right.active_fw, FwMode::MainFw) + ); + println!( + " Backup: {}{}", + right.backup_fw.base, + active_mode(&right.active_fw, FwMode::BackupFw) + ); + } else { + println!( + " Right (01): {} ({:?})", + right.main_fw.base, right.active_fw + ); + } + } else if right.main_fw.app != right.backup_fw.app { println!( - " Main: {}{}", - right.main_fw.base, + " Main: {}{}", + right.main_fw.app, active_mode(&right.active_fw, FwMode::MainFw) ); println!( - " Backup: {}{}", - right.backup_fw.base, + " Backup: {}{}", + right.backup_fw.app, active_mode(&right.active_fw, FwMode::BackupFw) ); } else { println!( - " Main: {}{}", - right.main_fw.app, - active_mode(&right.active_fw, FwMode::MainFw) - ); - println!( - " Backup: {}{}", - right.backup_fw.app, - active_mode(&right.active_fw, FwMode::BackupFw) + " Right (01): {} ({:?})", + right.main_fw.app, right.active_fw ); } - println!(" Left (23)"); if let Some(Platform::IntelGen11) = smbios::get_platform() { + if left.main_fw.base != left.backup_fw.base { + println!(" Left (23)"); + println!( + " Main: {}{}", + left.main_fw.base, + active_mode(&left.active_fw, FwMode::MainFw) + ); + println!( + " Backup: {}{}", + left.backup_fw.base, + active_mode(&left.active_fw, FwMode::BackupFw) + ); + } else { + println!( + " Left (23): {} ({:?})", + left.main_fw.base, left.active_fw + ); + } + } else if left.main_fw.app != left.backup_fw.app { + println!(" Left (23)"); println!( - " Main: {}{}", - left.main_fw.base, + " Main: {}{}", + left.main_fw.app, active_mode(&left.active_fw, FwMode::MainFw) ); println!( - " Backup: {}{}", - left.backup_fw.base, + " Backup: {}{}", + left.backup_fw.app, active_mode(&left.active_fw, FwMode::BackupFw) ); } else { println!( - " Main: {}{}", - left.main_fw.app, - active_mode(&left.active_fw, FwMode::MainFw) - ); - println!( - " Backup: {}{}", - left.backup_fw.app, - active_mode(&left.active_fw, FwMode::BackupFw) + " Left (23): {} ({:?})", + left.main_fw.app, left.active_fw ); } } else if let Ok(pd_versions) = power::read_pd_version(ec) { From c75cff2a2c04ac6a85b5a84536d9281e1376bba4 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Fri, 9 May 2025 15:04:50 +0800 Subject: [PATCH 13/22] Allow keyboard remapping Signed-off-by: Daniel Schaefer --- framework_lib/src/chromium_ec/command.rs | 1 + framework_lib/src/chromium_ec/commands.rs | 25 +++++++++++++++++++++++ framework_lib/src/chromium_ec/mod.rs | 14 +++++++++++++ 3 files changed, 40 insertions(+) diff --git a/framework_lib/src/chromium_ec/command.rs b/framework_lib/src/chromium_ec/command.rs index c6c68385..e009a9ec 100644 --- a/framework_lib/src/chromium_ec/command.rs +++ b/framework_lib/src/chromium_ec/command.rs @@ -62,6 +62,7 @@ pub enum EcCommands { /// Change charge limit ChargeLimitControl = 0x3E03, DisablePs2Emulation = 0x3E08, + UpdateKeyboardMatrix = 0x3E0C, /// Get/Set Fingerprint LED brightness FpLedLevelControl = 0x3E0E, /// Get information about the current chassis open/close status diff --git a/framework_lib/src/chromium_ec/commands.rs b/framework_lib/src/chromium_ec/commands.rs index 2e72c947..4a8fd2bf 100644 --- a/framework_lib/src/chromium_ec/commands.rs +++ b/framework_lib/src/chromium_ec/commands.rs @@ -927,6 +927,31 @@ impl EcRequest for EcRequestFlashNotify { } } +#[repr(C, packed)] +pub struct KeyboardMatrixMap { + pub row: u8, + pub col: u8, + pub scanset: u16, +} +#[repr(C, packed)] +pub struct EcRequestUpdateKeyboardMatrix { + pub num_items: u32, + pub write: u32, + pub scan_update: [KeyboardMatrixMap; 1], +} +#[repr(C, packed)] +pub struct EcResponseUpdateKeyboardMatrix { + pub num_items: u32, + pub write: u32, + pub scan_update: [KeyboardMatrixMap; 32], +} + +impl EcRequest for EcRequestUpdateKeyboardMatrix { + fn command_id() -> EcCommands { + EcCommands::UpdateKeyboardMatrix + } +} + #[repr(C, packed)] pub struct EcRequestChassisOpenCheck {} diff --git a/framework_lib/src/chromium_ec/mod.rs b/framework_lib/src/chromium_ec/mod.rs index 9ba22117..9bd367a0 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -390,6 +390,20 @@ impl CrosEc { .map(|res| res.sensor_count) } + pub fn remap_caps_to_ctrl(&self) -> EcResult<()> { + self.remap_key(6, 15, 0x0014) + } + + pub fn remap_key(&self, row: u8, col: u8, scanset: u16) -> EcResult<()> { + let _current_matrix = EcRequestUpdateKeyboardMatrix { + num_items: 1, + write: 1, + scan_update: [KeyboardMatrixMap { row, col, scanset }], + } + .send_command(self)?; + Ok(()) + } + /// Get current status of Framework Laptop's microphone and camera privacy switches /// [true = device enabled/connected, false = device disabled] pub fn get_privacy_info(&self) -> EcResult<(bool, bool)> { From 51776de85c1543c399889be1130f5b2881d58958 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Fri, 9 May 2025 23:50:06 +0800 Subject: [PATCH 14/22] Add --remap-key command Signed-off-by: Daniel Schaefer --- EXAMPLES.md | 36 +++++++++++++++++++++++ framework_lib/src/commandline/clap_std.rs | 14 +++++++++ framework_lib/src/commandline/mod.rs | 17 ++++++----- framework_lib/src/commandline/uefi.rs | 1 + 4 files changed, 61 insertions(+), 7 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index 2098d223..c36da6e2 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -382,3 +382,39 @@ sudo framework_tool --rgbkbd 2 0xFF0000 > sudo framework_tool --stylus-battery Stylus Battery Strength: 77% ``` + +## Remap keyboard + +Note that the keyboard matrix on Framework 12 and Framework 13 are +different. +The scancodes are the same. + +- Left-Ctrl 0x0014 +- Left-Alt 0x0014 +- Tab 0x0058 + +### Framework 12 + +``` +# Remap capslock key as left-ctrl +> framework_tool --remap-key 6 15 0x0014 + +# Swap left-ctrl and alt +> framework_tool --remap-key 1 14 0x0011 +> framework_tool --remap-key 6 13 0x0014 +``` + +### Framework 13 + +``` +# Remap capslock key as left-ctrl +> framework_tool --remap-key 4 4 0x0014 + +# Swap left-ctrl and alt +> framework_tool --remap-key 1 12 0x0011 +> framework_tool --remap-key 1 3 0x0014 +``` + +### Framework 16 + +It's not controlled by the EC, use https://keyboard.frame.work. diff --git a/framework_lib/src/commandline/clap_std.rs b/framework_lib/src/commandline/clap_std.rs index 4b17646c..aabd5468 100644 --- a/framework_lib/src/commandline/clap_std.rs +++ b/framework_lib/src/commandline/clap_std.rs @@ -181,6 +181,11 @@ struct ClapCli { #[arg(long)] kblight: Option>, + /// Set keyboard backlight percentage or get, if no value provided + #[arg(long, value_parser=maybe_hex::)] + #[clap(num_args = 3)] + remap_key: Vec, + /// Set the color of to . Multiple colors for adjacent keys can be set at once. /// [ ...] /// Example: 0 0xFF000 0x00FF00 0x0000FF @@ -338,6 +343,14 @@ pub fn parse(args: &[String]) -> Cli { 1 => Some((args.charge_rate_limit[0], None)), _ => None, }; + let remap_key = match args.remap_key.len() { + 3 => Some(( + args.remap_key[0] as u8, + args.remap_key[1] as u8, + args.remap_key[2], + )), + _ => None, + }; Cli { verbosity: args.verbosity.log_level_filter(), @@ -397,6 +410,7 @@ pub fn parse(args: &[String]) -> Cli { fp_led_level: args.fp_led_level, fp_brightness: args.fp_brightness, kblight: args.kblight, + remap_key, rgbkbd: args.rgbkbd, ps2_enable: args.ps2_enable, tablet_mode: args.tablet_mode, diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index ce11646d..0b9aa39d 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -181,6 +181,7 @@ pub struct Cli { pub fp_led_level: Option>, pub fp_brightness: Option>, pub kblight: Option>, + pub remap_key: Option<(u8, u8, u16)>, pub rgbkbd: Vec, pub ps2_enable: Option, pub tablet_mode: Option, @@ -809,6 +810,15 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { } else if let Some(Some(kblight)) = args.kblight { assert!(kblight <= 100); ec.set_keyboard_backlight(kblight); + } else if let Some(None) = args.kblight { + print!("Keyboard backlight: "); + if let Some(percentage) = print_err(ec.get_keyboard_backlight()) { + println!("{}%", percentage); + } else { + println!("Unable to tell"); + } + } else if let Some((row, col, scanset)) = args.remap_key { + print_err(ec.remap_key(row, col, scanset)); } else if !args.rgbkbd.is_empty() { if args.rgbkbd.len() < 2 { println!( @@ -826,13 +836,6 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { } } else if let Some(enable) = args.ps2_enable { print_err(ec.ps2_emulation_enable(enable)); - } else if let Some(None) = args.kblight { - print!("Keyboard backlight: "); - if let Some(percentage) = print_err(ec.get_keyboard_backlight()) { - println!("{}%", percentage); - } else { - println!("Unable to tell"); - } } else if let Some(tablet_arg) = &args.tablet_mode { let mode = match tablet_arg { TabletModeArg::Auto => TabletModeOverride::Default, diff --git a/framework_lib/src/commandline/uefi.rs b/framework_lib/src/commandline/uefi.rs index 63924450..097c006f 100644 --- a/framework_lib/src/commandline/uefi.rs +++ b/framework_lib/src/commandline/uefi.rs @@ -94,6 +94,7 @@ pub fn parse(args: &[String]) -> Cli { fp_led_level: None, fp_brightness: None, kblight: None, + remap_key: None, rgbkbd: vec![], ps2_enable: None, tablet_mode: None, From 6ebb5de044bc5efc0e24c0f6417348a48facf48b Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Thu, 15 May 2025 10:10:07 +0800 Subject: [PATCH 15/22] Build Rufus compatible ISO Signed-off-by: Daniel Schaefer --- .github/workflows/ci.yml | 13 +++++++++++-- framework_uefi/Makefile | 15 +++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92f5299d..3f8dc7d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,12 +74,21 @@ jobs: name: framework.efi path: framework_uefi/build/x86_64-unknown-uefi/boot.efi - - name: Install mtools to build ESP (Linux) - run: sudo apt-get install -y mtools + - name: Install mtools to build ESP and ISO (Linux) + run: sudo apt-get install -y mtools genisoimage - name: Build ESP (Linux) run: make -C framework_uefi + - name: Build ISO (Linux) + run: make -C framework_uefi iso + + - name: Upload UEFI App ISO + uses: actions/upload-artifact@v4 + with: + name: UEFI-Shell-fwk.iso + path: framework_uefi/build/x86_64-unknown-uefi/UEFI-Shell-fwk.iso + build-windows: name: Build Windows runs-on: windows-2022 diff --git a/framework_uefi/Makefile b/framework_uefi/Makefile index 6963d8f2..a571ba17 100644 --- a/framework_uefi/Makefile +++ b/framework_uefi/Makefile @@ -15,6 +15,8 @@ QEMU_FLAGS=\ all: $(BUILD)/boot.img +iso: $(BUILD)/UEFI-Shell-fwk.iso + clean: rm -r $(BUILD) @@ -39,6 +41,19 @@ $(BUILD)/efi.img: $(BUILD)/boot.efi mcopy -i $@.tmp $< ::efi/boot/bootx64.efi mv $@.tmp $@ +$(BUILD)/shellx64.efi: + wget https://github.com/pbatard/UEFI-Shell/releases/download/24H2/shellx64.efi -O $@ + +$(BUILD)/UEFI-Shell-fwk.iso: $(BUILD)/boot.efi $(BUILD)/shellx64.efi + mkdir -p $(BUILD)/$@.tmp/efi/boot + cp $(BUILD)/boot.efi $(BUILD)/$@.tmp/efi/boot/fwk.efi + cp $(BUILD)/shellx64.efi $(BUILD)/$@.tmp/efi/boot/bootx64.efi + genisoimage -v \ + -V "UEFI SHELL with fwk.efi" \ + -JR \ + -o "$(BUILD)/UEFI-Shell-fwk.iso" \ + $(BUILD)/$@.tmp + $(BUILD)/boot.efi: ../Cargo.lock $(SRC_DIR)/Cargo.toml $(SRC_DIR)/src/* mkdir -p $(BUILD) cargo rustc \ From 7c075b1803008d5e4dca50c787badc5c73c1be03 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Wed, 14 May 2025 18:26:05 +0800 Subject: [PATCH 16/22] Allow installing with cargo install ``` > cargo install --path framework_tool > which framework_tool /home/zoid/.cargo/bin/framework_tool ``` Signed-off-by: Daniel Schaefer --- README.md | 12 +++++------- framework_tool/Cargo.toml | 4 ++++ 2 files changed, 9 insertions(+), 7 deletions(-) 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_tool/Cargo.toml b/framework_tool/Cargo.toml index 7cdfd1f6..92cc7d04 100644 --- a/framework_tool/Cargo.toml +++ b/framework_tool/Cargo.toml @@ -3,6 +3,10 @@ name = "framework_tool" version = "0.4.1" edition = "2021" +[[bin]] +name = "framework_tool" +path = "src/main.rs" + [dependencies.framework_lib] path = "../framework_lib" From f69b4fc1c43ca2ddc2b8f42cfc799d4e00d92adb Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Wed, 14 May 2025 22:43:04 +0800 Subject: [PATCH 17/22] bump version to 0.4.2 Signed-off-by: Daniel Schaefer --- Cargo.lock | 6 +++--- framework_lib/Cargo.toml | 2 +- framework_tool/Cargo.toml | 2 +- framework_uefi/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f0b1984..ccb8e0d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -408,7 +408,7 @@ dependencies = [ [[package]] name = "framework_lib" -version = "0.4.1" +version = "0.4.2" dependencies = [ "built", "clap", @@ -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", diff --git a/framework_lib/Cargo.toml b/framework_lib/Cargo.toml index f0477678..28a58354 100644 --- a/framework_lib/Cargo.toml +++ b/framework_lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "framework_lib" -version = "0.4.1" +version = "0.4.2" edition = "2021" # Minimum Supported Rust Version # Ubuntu 24.04 LTS ships 1.75 diff --git a/framework_tool/Cargo.toml b/framework_tool/Cargo.toml index 92cc7d04..d31040db 100644 --- a/framework_tool/Cargo.toml +++ b/framework_tool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "framework_tool" -version = "0.4.1" +version = "0.4.2" edition = "2021" [[bin]] diff --git a/framework_uefi/Cargo.toml b/framework_uefi/Cargo.toml index d0ad0cc4..9e2a185f 100644 --- a/framework_uefi/Cargo.toml +++ b/framework_uefi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "framework_uefi" -version = "0.4.1" +version = "0.4.2" edition = "2021" # Minimum Supported Rust Version rust-version = "1.74" From cf24bdd6f5b0246a639229e4e5814b9c73403b2f Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Wed, 14 May 2025 23:03:53 +0800 Subject: [PATCH 18/22] Add more fields in Cargo.toml What's required based on https://doc.rust-lang.org/cargo/reference/publishing.html#before-publishing-a-new-crate Signed-off-by: Daniel Schaefer --- framework_lib/Cargo.toml | 5 +++++ framework_tool/Cargo.toml | 5 +++++ framework_uefi/Cargo.toml | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/framework_lib/Cargo.toml b/framework_lib/Cargo.toml index 28a58354..5e19867a 100644 --- a/framework_lib/Cargo.toml +++ b/framework_lib/Cargo.toml @@ -1,6 +1,11 @@ [package] name = "framework_lib" 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 diff --git a/framework_tool/Cargo.toml b/framework_tool/Cargo.toml index d31040db..8da6a35c 100644 --- a/framework_tool/Cargo.toml +++ b/framework_tool/Cargo.toml @@ -1,6 +1,11 @@ [package] name = "framework_tool" 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]] diff --git a/framework_uefi/Cargo.toml b/framework_uefi/Cargo.toml index 9e2a185f..852fa7ec 100644 --- a/framework_uefi/Cargo.toml +++ b/framework_uefi/Cargo.toml @@ -1,6 +1,11 @@ [package] name = "framework_uefi" 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" From 7b010b65c3673ed8347b736a0e4fc71028dc4b1d Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Wed, 14 May 2025 23:46:00 +0800 Subject: [PATCH 19/22] Remove vendored guid_macros crate Replace with guid-create from crates.io Signed-off-by: Daniel Schaefer --- Cargo.lock | 11 +- Cargo.toml | 3 - framework_lib/Cargo.toml | 2 +- framework_lib/src/capsule.rs | 10 +- framework_lib/src/commandline/mod.rs | 9 +- framework_lib/src/esrt/mod.rs | 193 +++++++++++++++++---------- framework_lib/src/guid.rs | 173 ------------------------ framework_lib/src/lib.rs | 2 - guid_macros/Cargo.toml | 23 ---- guid_macros/src/lib.rs | 101 -------------- 10 files changed, 138 insertions(+), 389 deletions(-) delete mode 100644 framework_lib/src/guid.rs delete mode 100644 guid_macros/Cargo.toml delete mode 100644 guid_macros/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index ccb8e0d1..2f9f5c9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -415,7 +415,7 @@ dependencies = [ "clap-num", "clap-verbosity-flag", "env_logger", - "guid_macros", + "guid-create", "hidapi", "lazy_static", "libc", @@ -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/framework_lib/Cargo.toml b/framework_lib/Cargo.toml index 5e19867a..8d362370 100644 --- a/framework_lib/Cargo.toml +++ b/framework_lib/Cargo.toml @@ -31,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..74221196 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,115 @@ 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 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_BIOS_GUID: GUID = GUID::build_from_components( + 0xb5f7dcc1, + 0x568c, + 0x50f8, + &[0xa4, 0xdd, 0xe3, 0x9d, 0x1f, 0x93, 0xfd, 0xa1], +); +pub const RPL_CSME_GUID: GUID = GUID::build_from_components( + 0x865d322c, + 0x6ac7, + 0x4734, + &[0xb4, 0x3e, 0x55, 0xdb, 0x5a, 0x55, 0x7d, 0x63], +); +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 +149,7 @@ pub enum FrameworkGuidKind { AdlBios, RplBios, MtlBios, + Fw12RplBios, TglRetimer01, TglRetimer23, AdlRetimer01, @@ -122,7 +167,7 @@ pub enum FrameworkGuidKind { } 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, @@ -288,8 +333,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 +404,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 +425,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 +474,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 +494,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 +513,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/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)?, - )) -} From faa158701ce8b700a01e4b30b4045ccb96b8439b Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Thu, 15 May 2025 00:13:41 +0800 Subject: [PATCH 20/22] esrt: Add Framework 12 GUIDs Signed-off-by: Daniel Schaefer --- framework_lib/src/esrt/mod.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/framework_lib/src/esrt/mod.rs b/framework_lib/src/esrt/mod.rs index 74221196..492821e9 100644 --- a/framework_lib/src/esrt/mod.rs +++ b/framework_lib/src/esrt/mod.rs @@ -57,6 +57,12 @@ pub const MTL_BIOS_GUID: GUID = GUID::build_from_components( 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, @@ -125,6 +131,12 @@ pub const RPL_CSME_GUID: GUID = GUID::build_from_components( 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, @@ -159,6 +171,7 @@ pub enum FrameworkGuidKind { MtlRetimer01, MtlRetimer23, RplCsme, + RplUCsme, MtlCsme, Fl16Bios, Amd13Bios, @@ -172,6 +185,7 @@ pub fn match_guid_kind(guid: &Guid) -> FrameworkGuidKind { 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, TGL_RETIMER01_GUID => FrameworkGuidKind::TglRetimer01, @@ -183,6 +197,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, From a087756c8ab990e501abd1ed52474c62d79e32c2 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Thu, 15 May 2025 09:02:46 +0800 Subject: [PATCH 21/22] esrt: Add Framework 13 AMD Ryzen AI 300 GUID Signed-off-by: Daniel Schaefer --- framework_lib/src/esrt/mod.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/framework_lib/src/esrt/mod.rs b/framework_lib/src/esrt/mod.rs index 492821e9..15daea4c 100644 --- a/framework_lib/src/esrt/mod.rs +++ b/framework_lib/src/esrt/mod.rs @@ -119,12 +119,18 @@ pub const FL16_BIOS_GUID: GUID = GUID::build_from_components( 0x5d64, &[0x8e, 0x18, 0x65, 0x8d, 0x20, 0x5a, 0xcf, 0x34], ); -pub const AMD13_BIOS_GUID: GUID = GUID::build_from_components( +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, @@ -174,7 +180,8 @@ pub enum FrameworkGuidKind { RplUCsme, MtlCsme, Fl16Bios, - Amd13Bios, + Amd13Ryzen7040Bios, + Amd13Ai300Bios, WinUx, Unknown, } @@ -187,7 +194,8 @@ pub fn match_guid_kind(guid: &Guid) -> FrameworkGuidKind { 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, From 521907282a35a1f875b5c46b359ef82eba0febdc Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Thu, 15 May 2025 14:38:18 +0800 Subject: [PATCH 22/22] Allow flashing EC RW region Works well on Linux. It's disabled by the windows driver at the moment though. No need to block it in this application, users could also use ectool. Signed-off-by: Daniel Schaefer --- framework_lib/src/commandline/mod.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index 0477cbbe..7f11c87f 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -570,19 +570,14 @@ fn flash_ec(ec: &CrosEc, ec_bin_path: &str, flash_type: EcFlashType) { let data = crate::uefi::fs::shell_read_file(ec_bin_path); #[cfg(not(feature = "uefi"))] let data: Option> = { - let _data = match fs::read(ec_bin_path) { + match fs::read(ec_bin_path) { Ok(data) => Some(data), // TODO: Perhaps a more user-friendly error Err(e) => { println!("Error {:?}", e); None } - }; - - // EC communication from OS is not stable enough yet, - // it can't be trusted to reliably flash the EC without risk of damage. - println!("Sorry, flashing EC from the OS is not supported yet."); - None + } }; if let Some(data) = data { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy