Skip to content

Commit e24fbdf

Browse files
Merge pull request #157 from FrameworkComputer/pd-version-v2
--versions: Show any number of PD versions
2 parents 25f3212 + dd59912 commit e24fbdf

File tree

6 files changed

+175
-43
lines changed

6 files changed

+175
-43
lines changed

framework_lib/src/ccgx/device.rs

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,17 @@ enum ControlRegisters {
2626
pub enum PdPort {
2727
Left01,
2828
Right23,
29+
Back,
2930
}
3031

3132
impl PdPort {
3233
/// SMBUS/I2C Address
3334
fn i2c_address(&self) -> EcResult<u16> {
3435
let config = Config::get();
3536
let platform = &(*config).as_ref().unwrap().platform;
37+
let unsupported = Err(EcError::DeviceError(
38+
"Controller does not exist on this platform".to_string(),
39+
));
3640

3741
Ok(match (platform, self) {
3842
(Platform::GenericFramework((left, _), _), PdPort::Left01) => *left,
@@ -50,21 +54,40 @@ impl PdPort {
5054
| Platform::Framework16Amd7080,
5155
PdPort::Right23,
5256
) => 0x40,
53-
// TODO: It only has a single PD controller
54-
(Platform::FrameworkDesktopAmdAiMax300, _) => 0x08,
57+
(Platform::FrameworkDesktopAmdAiMax300, PdPort::Back) => 0x08,
58+
(Platform::FrameworkDesktopAmdAiMax300, _) => unsupported?,
59+
// Framework Intel Platforms (CCG5 and CCG6)
60+
(
61+
Platform::Framework12IntelGen13
62+
| Platform::IntelGen11
63+
| Platform::IntelGen12
64+
| Platform::IntelGen13
65+
| Platform::IntelCoreUltra1,
66+
PdPort::Left01,
67+
) => 0x08,
68+
(
69+
Platform::Framework12IntelGen13
70+
| Platform::IntelGen11
71+
| Platform::IntelGen12
72+
| Platform::IntelGen13
73+
| Platform::IntelCoreUltra1,
74+
PdPort::Right23,
75+
) => 0x40,
5576
(Platform::UnknownSystem, _) => {
5677
Err(EcError::DeviceError("Unsupported platform".to_string()))?
5778
}
58-
// Framework Intel Platforms (CCG5 and CCG6)
59-
(_, PdPort::Left01) => 0x08,
60-
(_, PdPort::Right23) => 0x40,
79+
(_, PdPort::Back) => unsupported?,
6180
})
6281
}
6382

6483
/// I2C port on the EC
6584
fn i2c_port(&self) -> EcResult<u8> {
6685
let config = Config::get();
6786
let platform = &(*config).as_ref().unwrap().platform;
87+
let unsupported = Err(EcError::DeviceError(format!(
88+
"Controller {:?}, does not exist on {:?}",
89+
self, platform
90+
)));
6891

6992
Ok(match (platform, self) {
7093
(Platform::GenericFramework(_, (left, _)), PdPort::Left01) => *left,
@@ -88,11 +111,12 @@ impl PdPort {
88111
| Platform::Framework12IntelGen13,
89112
PdPort::Right23,
90113
) => 2,
91-
// TODO: It only has a single PD controller
92-
(Platform::FrameworkDesktopAmdAiMax300, _) => 1,
114+
(Platform::FrameworkDesktopAmdAiMax300, PdPort::Back) => 1,
115+
(Platform::FrameworkDesktopAmdAiMax300, _) => unsupported?,
93116
(Platform::UnknownSystem, _) => {
94117
Err(EcError::DeviceError("Unsupported platform".to_string()))?
95118
}
119+
(_, PdPort::Back) => unsupported?,
96120
})
97121
}
98122
}

framework_lib/src/ccgx/mod.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
use alloc::format;
44
use alloc::string::String;
55
use alloc::string::ToString;
6+
use alloc::vec;
7+
use alloc::vec::Vec;
68
#[cfg(feature = "uefi")]
79
use core::prelude::rust_2021::derive;
810
use num_derive::FromPrimitive;
@@ -234,23 +236,32 @@ impl ControllerFirmwares {
234236
}
235237

236238
#[derive(Debug, PartialEq)]
237-
pub struct PdVersions {
238-
pub controller01: ControllerFirmwares,
239-
pub controller23: ControllerFirmwares,
239+
pub enum PdVersions {
240+
RightLeft((ControllerFirmwares, ControllerFirmwares)),
241+
Single(ControllerFirmwares),
242+
Many(Vec<ControllerFirmwares>),
240243
}
241244

242245
/// Same as PdVersions but only the main FW
243246
#[derive(Debug)]
244-
pub struct MainPdVersions {
245-
pub controller01: ControllerVersion,
246-
pub controller23: ControllerVersion,
247+
pub enum MainPdVersions {
248+
RightLeft((ControllerVersion, ControllerVersion)),
249+
Single(ControllerVersion),
250+
Many(Vec<ControllerVersion>),
247251
}
248252

249253
pub fn get_pd_controller_versions(ec: &CrosEc) -> EcResult<PdVersions> {
250-
Ok(PdVersions {
251-
controller01: PdController::new(PdPort::Left01, ec.clone()).get_fw_versions()?,
252-
controller23: PdController::new(PdPort::Right23, ec.clone()).get_fw_versions()?,
253-
})
254+
let pd01 = PdController::new(PdPort::Left01, ec.clone()).get_fw_versions();
255+
let pd23 = PdController::new(PdPort::Right23, ec.clone()).get_fw_versions();
256+
let pd_back = PdController::new(PdPort::Back, ec.clone()).get_fw_versions();
257+
258+
match (pd01, pd23, pd_back) {
259+
(Err(_), Err(_), Ok(pd_back)) => Ok(PdVersions::Single(pd_back)),
260+
(Ok(pd01), Ok(pd23), Err(_)) => Ok(PdVersions::RightLeft((pd01, pd23))),
261+
(Ok(pd01), Ok(pd23), Ok(pd_back)) => Ok(PdVersions::Many(vec![pd01, pd23, pd_back])),
262+
(Err(err), _, _) => Err(err),
263+
(_, Err(err), _) => Err(err),
264+
}
254265
}
255266

256267
fn parse_metadata_ccg3(buffer: &[u8]) -> Option<(u32, u32)> {

framework_lib/src/chromium_ec/commands.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -987,18 +987,38 @@ impl EcRequest<EcResponseChassisIntrusionControl> for EcRequestChassisIntrusionC
987987
}
988988

989989
#[repr(C, packed)]
990-
pub struct EcRequestReadPdVersion {}
990+
pub struct EcRequestReadPdVersionV0 {}
991991

992992
#[repr(C, packed)]
993-
pub struct _EcResponseReadPdVersion {
993+
pub struct _EcResponseReadPdVersionV0 {
994994
pub controller01: [u8; 8],
995995
pub controller23: [u8; 8],
996996
}
997997

998-
impl EcRequest<_EcResponseReadPdVersion> for EcRequestReadPdVersion {
998+
impl EcRequest<_EcResponseReadPdVersionV0> for EcRequestReadPdVersionV0 {
999999
fn command_id() -> EcCommands {
10001000
EcCommands::ReadPdVersion
10011001
}
1002+
fn command_version() -> u8 {
1003+
0
1004+
}
1005+
}
1006+
1007+
#[repr(C, packed)]
1008+
pub struct EcRequestReadPdVersionV1 {}
1009+
#[repr(C, packed)]
1010+
pub struct _EcResponseReadPdVersionV1 {
1011+
pub pd_chip_count: u8,
1012+
pub pd_controllers: [u8; 0],
1013+
}
1014+
1015+
impl EcRequest<_EcResponseReadPdVersionV1> for EcRequestReadPdVersionV1 {
1016+
fn command_id() -> EcCommands {
1017+
EcCommands::ReadPdVersion
1018+
}
1019+
fn command_version() -> u8 {
1020+
1
1021+
}
10021022
}
10031023

10041024
#[repr(C, packed)]

framework_lib/src/commandline/mod.rs

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use crate::capsule_content::{
3333
use crate::ccgx::device::{FwMode, PdController, PdPort};
3434
#[cfg(feature = "hidapi")]
3535
use crate::ccgx::hid::{check_ccg_fw_version, find_devices, DP_CARD_PID, HDMI_CARD_PID};
36-
use crate::ccgx::{self, SiliconId::*};
36+
use crate::ccgx::{self, MainPdVersions, PdVersions, SiliconId::*};
3737
use crate::chromium_ec;
3838
use crate::chromium_ec::commands::DeckStateMode;
3939
use crate::chromium_ec::commands::FpLedBrightnessLevel;
@@ -59,8 +59,7 @@ use crate::touchpad::print_touchpad_fw_ver;
5959
use crate::touchscreen;
6060
#[cfg(feature = "uefi")]
6161
use crate::uefi::enable_page_break;
62-
use crate::util;
63-
use crate::util::{Config, Platform, PlatformFamily};
62+
use crate::util::{self, Config, Platform, PlatformFamily};
6463
#[cfg(feature = "hidapi")]
6564
use hidapi::HidApi;
6665
use sha2::{Digest, Sha256, Sha384, Sha512};
@@ -398,11 +397,8 @@ fn print_versions(ec: &CrosEc) {
398397
}
399398

400399
println!("PD Controllers");
401-
402-
if let Ok(pd_versions) = ccgx::get_pd_controller_versions(ec) {
403-
let right = &pd_versions.controller01;
404-
let left = &pd_versions.controller23;
405-
// let active_mode =
400+
let ccgx_pd_vers = ccgx::get_pd_controller_versions(ec);
401+
if let Ok(PdVersions::RightLeft((right, left))) = ccgx_pd_vers {
406402
if let Some(Platform::IntelGen11) = smbios::get_platform() {
407403
if right.main_fw.base != right.backup_fw.base {
408404
println!(" Right (01)");
@@ -476,10 +472,43 @@ fn print_versions(ec: &CrosEc) {
476472
left.main_fw.app, left.active_fw
477473
);
478474
}
475+
} else if let Ok(PdVersions::Single(pd)) = ccgx_pd_vers {
476+
if pd.main_fw.app != pd.backup_fw.app {
477+
println!(
478+
" Main: {}{}",
479+
pd.main_fw.app,
480+
active_mode(&pd.active_fw, FwMode::MainFw)
481+
);
482+
println!(
483+
" Backup: {}{}",
484+
pd.backup_fw.app,
485+
active_mode(&pd.active_fw, FwMode::BackupFw)
486+
);
487+
} else {
488+
println!(" Version: {} ({:?})", pd.main_fw.app, pd.active_fw);
489+
}
479490
} else if let Ok(pd_versions) = power::read_pd_version(ec) {
480491
// As fallback try to get it from the EC. But not all EC versions have this command
481-
println!(" Right (01): {}", pd_versions.controller01.app);
482-
println!(" Left (23): {}", pd_versions.controller23.app);
492+
debug!(" Fallback to PD Host command");
493+
match pd_versions {
494+
MainPdVersions::RightLeft((controller01, controller23)) => {
495+
if let Some(Platform::IntelGen11) = smbios::get_platform() {
496+
println!(" Right (01): {}", controller01.base);
497+
println!(" Left (23): {}", controller23.base);
498+
} else {
499+
println!(" Right (01): {}", controller01.app);
500+
println!(" Left (23): {}", controller23.app);
501+
}
502+
}
503+
MainPdVersions::Single(version) => {
504+
println!(" Version: {}", version.app);
505+
}
506+
MainPdVersions::Many(versions) => {
507+
for (i, version) in versions.into_iter().enumerate() {
508+
println!(" PD {}: {}", i, version.app);
509+
}
510+
}
511+
}
483512
} else {
484513
println!(" Unknown")
485514
}
@@ -527,7 +556,7 @@ fn print_versions(ec: &CrosEc) {
527556
}
528557

529558
#[cfg(target_os = "linux")]
530-
{
559+
if smbios::get_platform().and_then(Platform::which_cpu_vendor) != Some(util::CpuVendor::Amd) {
531560
println!("CSME");
532561
if let Ok(csme) = csme::csme_from_sysfs() {
533562
info!(" Enabled: {}", csme.enabled);
@@ -638,8 +667,8 @@ fn compare_version(device: Option<HardwareDeviceType>, version: String, ec: &Cro
638667
}
639668
}
640669
Some(HardwareDeviceType::PD0) => {
641-
if let Ok(pd_versions) = ccgx::get_pd_controller_versions(ec) {
642-
let ver = pd_versions.controller01.active_fw_ver();
670+
if let Ok(PdVersions::RightLeft((pd01, _pd23))) = ccgx::get_pd_controller_versions(ec) {
671+
let ver = pd01.active_fw_ver();
643672
println!("Comparing PD0 version {:?}", ver);
644673

645674
if ver.contains(&version) {
@@ -650,8 +679,8 @@ fn compare_version(device: Option<HardwareDeviceType>, version: String, ec: &Cro
650679
}
651680
}
652681
Some(HardwareDeviceType::PD1) => {
653-
if let Ok(pd_versions) = ccgx::get_pd_controller_versions(ec) {
654-
let ver = pd_versions.controller23.active_fw_ver();
682+
if let Ok(PdVersions::RightLeft((_pd01, pd23))) = ccgx::get_pd_controller_versions(ec) {
683+
let ver = pd23.active_fw_ver();
655684
println!("Comparing PD1 version {:?}", ver);
656685

657686
if ver.contains(&version) {

framework_lib/src/power.rs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Get information about system power (battery, AC, PD ports)
22
33
use alloc::format;
4-
use alloc::string::String;
4+
use alloc::string::{String, ToString};
55
use alloc::vec;
66
use alloc::vec::Vec;
77
use core::convert::TryInto;
@@ -798,6 +798,11 @@ pub fn is_charging(ec: &CrosEc) -> EcResult<(bool, bool)> {
798798
Ok((port0 || port1, port2 || port3))
799799
}
800800

801+
fn parse_pd_ver_slice(data: &[u8]) -> ControllerVersion {
802+
parse_pd_ver(&[
803+
data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
804+
])
805+
}
801806
fn parse_pd_ver(data: &[u8; 8]) -> ControllerVersion {
802807
ControllerVersion {
803808
base: BaseVersion {
@@ -815,15 +820,37 @@ fn parse_pd_ver(data: &[u8; 8]) -> ControllerVersion {
815820
}
816821
}
817822

818-
// NOTE: Only works on ADL at the moment!
819-
// TODO: Not on TGL, need to check if RPL and later have it.
823+
// NOTE: TGL (hx20) does not have this host command
820824
pub fn read_pd_version(ec: &CrosEc) -> EcResult<MainPdVersions> {
821-
let info = EcRequestReadPdVersion {}.send_command(ec)?;
825+
let info = EcRequestReadPdVersionV1 {}.send_command_vec(ec);
822826

823-
Ok(MainPdVersions {
824-
controller01: parse_pd_ver(&info.controller01),
825-
controller23: parse_pd_ver(&info.controller23),
826-
})
827+
// If v1 not available, fall back
828+
if let Err(EcError::Response(EcResponseStatus::InvalidVersion)) = info {
829+
let info = EcRequestReadPdVersionV0 {}.send_command(ec)?;
830+
831+
return Ok(if info.controller23 == [0, 0, 0, 0, 0, 0, 0, 0] {
832+
MainPdVersions::Single(parse_pd_ver(&info.controller01))
833+
} else {
834+
MainPdVersions::RightLeft((
835+
parse_pd_ver(&info.controller01),
836+
parse_pd_ver(&info.controller23),
837+
))
838+
});
839+
}
840+
// If any other error, exit
841+
let info = info?;
842+
843+
let mut versions = vec![];
844+
let pd_count = info[0] as usize;
845+
for i in 0..pd_count {
846+
// TODO: Is there a safer way to check the range?
847+
if info.len() < 1 + 8 * (i + 1) {
848+
return Err(EcError::DeviceError("Not enough data returned".to_string()));
849+
}
850+
versions.push(parse_pd_ver_slice(&info[1 + 8 * i..1 + 8 * (i + 1)]));
851+
}
852+
853+
Ok(MainPdVersions::Many(versions))
827854
}
828855

829856
pub fn standalone_mode(ec: &CrosEc) -> bool {

framework_lib/src/util.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,28 @@ pub enum PlatformFamily {
4949
FrameworkDesktop,
5050
}
5151

52+
#[derive(Debug, PartialEq, Clone, Copy)]
53+
pub enum CpuVendor {
54+
Intel,
55+
Amd,
56+
}
57+
5258
impl Platform {
59+
pub fn which_cpu_vendor(self) -> Option<CpuVendor> {
60+
match self {
61+
Platform::Framework12IntelGen13
62+
| Platform::IntelGen11
63+
| Platform::IntelGen12
64+
| Platform::IntelGen13
65+
| Platform::IntelCoreUltra1 => Some(CpuVendor::Intel),
66+
Platform::Framework13Amd7080
67+
| Platform::Framework13AmdAi300
68+
| Platform::Framework16Amd7080
69+
| Platform::FrameworkDesktopAmdAiMax300 => Some(CpuVendor::Amd),
70+
Platform::GenericFramework(..) => None,
71+
Platform::UnknownSystem => None,
72+
}
73+
}
5374
pub fn which_family(self) -> Option<PlatformFamily> {
5475
match self {
5576
Platform::Framework12IntelGen13 => Some(PlatformFamily::Framework12),

0 commit comments

Comments
 (0)