|
3 | 3 | //! Can be easily re-used from any OS or UEFI shell.
|
4 | 4 | //! We have implemented both in the `framework_tool` and `framework_uefi` crates.
|
5 | 5 |
|
| 6 | +use alloc::format; |
6 | 7 | use alloc::string::String;
|
7 | 8 | use alloc::string::ToString;
|
8 | 9 | use alloc::vec::Vec;
|
@@ -54,7 +55,7 @@ use sha2::{Digest, Sha256, Sha384, Sha512};
|
54 | 55 | //use smbioslib::*;
|
55 | 56 | use smbioslib::{DefinedStruct, SMBiosInformation};
|
56 | 57 |
|
57 |
| -use crate::chromium_ec::{CrosEc, CrosEcDriverType}; |
| 58 | +use crate::chromium_ec::{CrosEc, CrosEcDriverType, HardwareDeviceType}; |
58 | 59 |
|
59 | 60 | #[cfg(feature = "uefi")]
|
60 | 61 | use core::prelude::rust_2021::derive;
|
@@ -120,6 +121,8 @@ pub struct Cli {
|
120 | 121 | pub versions: bool,
|
121 | 122 | pub version: bool,
|
122 | 123 | pub esrt: bool,
|
| 124 | + pub device: Option<HardwareDeviceType>, |
| 125 | + pub compare_version: Option<String>, |
123 | 126 | pub power: bool,
|
124 | 127 | pub thermal: bool,
|
125 | 128 | pub sensors: bool,
|
@@ -506,6 +509,119 @@ fn dump_ec_flash(ec: &CrosEc, dump_path: &str) {
|
506 | 509 | }
|
507 | 510 | }
|
508 | 511 |
|
| 512 | +fn compare_version(device: Option<HardwareDeviceType>, version: String, ec: &CrosEc) -> i32 { |
| 513 | + println!("Target Version {:?}", version); |
| 514 | + |
| 515 | + if let Some(smbios) = get_smbios() { |
| 516 | + let bios_entries = smbios.collect::<SMBiosInformation>(); |
| 517 | + let bios = bios_entries.get(0).unwrap(); |
| 518 | + |
| 519 | + if device == Some(HardwareDeviceType::BIOS) { |
| 520 | + println!("Comparing BIOS version {:?}", bios.version().to_string()); |
| 521 | + if version.to_uppercase() == bios.version().to_string().to_uppercase() { |
| 522 | + return 0; |
| 523 | + } else { |
| 524 | + return 1; |
| 525 | + } |
| 526 | + } |
| 527 | + } |
| 528 | + |
| 529 | + match device { |
| 530 | + Some(HardwareDeviceType::EC) => { |
| 531 | + let ver = print_err(ec.version_info()).unwrap_or_else(|| "UNKNOWN".to_string()); |
| 532 | + println!("Comparing EC version {:?}", ver); |
| 533 | + |
| 534 | + if ver.contains(&version) { |
| 535 | + return 0; |
| 536 | + } else { |
| 537 | + return 1; |
| 538 | + } |
| 539 | + } |
| 540 | + Some(HardwareDeviceType::PD0) => { |
| 541 | + if let Ok(pd_versions) = ccgx::get_pd_controller_versions(ec) { |
| 542 | + let ver = pd_versions.controller01.active_fw_ver(); |
| 543 | + println!("Comparing PD0 version {:?}", ver); |
| 544 | + |
| 545 | + if ver.contains(&version) { |
| 546 | + return 0; |
| 547 | + } else { |
| 548 | + return 1; |
| 549 | + } |
| 550 | + } |
| 551 | + } |
| 552 | + Some(HardwareDeviceType::PD1) => { |
| 553 | + if let Ok(pd_versions) = ccgx::get_pd_controller_versions(ec) { |
| 554 | + let ver = pd_versions.controller23.active_fw_ver(); |
| 555 | + println!("Comparing PD1 version {:?}", ver); |
| 556 | + |
| 557 | + if ver.contains(&version) { |
| 558 | + return 0; |
| 559 | + } else { |
| 560 | + return 1; |
| 561 | + } |
| 562 | + } |
| 563 | + } |
| 564 | + Some(HardwareDeviceType::AcLeft) => { |
| 565 | + if let Ok((_right, left)) = power::is_charging(ec) { |
| 566 | + let ver = format!("{}", left as i32); |
| 567 | + println!("Comparing AcLeft {:?}", ver); |
| 568 | + if ver == version { |
| 569 | + return 0; |
| 570 | + } else { |
| 571 | + return 1; |
| 572 | + } |
| 573 | + } else { |
| 574 | + error!("Failed to get charging information"); |
| 575 | + // Not charging is the safe default |
| 576 | + return 1; |
| 577 | + } |
| 578 | + } |
| 579 | + Some(HardwareDeviceType::AcRight) => { |
| 580 | + if let Ok((right, _left)) = power::is_charging(ec) { |
| 581 | + let ver = format!("{}", right as i32); |
| 582 | + println!("Comparing AcRight {:?}", ver); |
| 583 | + if ver == version { |
| 584 | + return 0; |
| 585 | + } else { |
| 586 | + return 1; |
| 587 | + } |
| 588 | + } else { |
| 589 | + error!("Failed to get charging information"); |
| 590 | + // Not charging is the safe default |
| 591 | + return 1; |
| 592 | + } |
| 593 | + } |
| 594 | + _ => {} |
| 595 | + } |
| 596 | + |
| 597 | + if let Some(esrt) = esrt::get_esrt() { |
| 598 | + for entry in &esrt.entries { |
| 599 | + match entry.fw_class { |
| 600 | + esrt::TGL_RETIMER01_GUID | esrt::ADL_RETIMER01_GUID | esrt::RPL_RETIMER01_GUID => { |
| 601 | + if device == Some(HardwareDeviceType::RTM01) { |
| 602 | + println!("Comparing RTM01 version {:?}", entry.fw_version.to_string()); |
| 603 | + |
| 604 | + if entry.fw_version.to_string().contains(&version) { |
| 605 | + return 0; |
| 606 | + } |
| 607 | + } |
| 608 | + } |
| 609 | + esrt::TGL_RETIMER23_GUID | esrt::ADL_RETIMER23_GUID | esrt::RPL_RETIMER23_GUID => { |
| 610 | + if device == Some(HardwareDeviceType::RTM23) { |
| 611 | + println!("Comparing RTM23 version {:?}", entry.fw_version.to_string()); |
| 612 | + if entry.fw_version.to_string().contains(&version) { |
| 613 | + return 0; |
| 614 | + } |
| 615 | + } |
| 616 | + } |
| 617 | + _ => {} |
| 618 | + } |
| 619 | + } |
| 620 | + } |
| 621 | + |
| 622 | + 1 |
| 623 | +} |
| 624 | + |
509 | 625 | pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 {
|
510 | 626 | #[cfg(feature = "uefi")]
|
511 | 627 | {
|
@@ -563,6 +679,10 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 {
|
563 | 679 | print_tool_version();
|
564 | 680 | } else if args.esrt {
|
565 | 681 | print_esrt();
|
| 682 | + } else if let Some(compare_version_ver) = &args.compare_version { |
| 683 | + let compare_ret = compare_version(args.device, compare_version_ver.to_string(), &ec); |
| 684 | + println!("Comparison Result: {}", compare_ret); |
| 685 | + return compare_ret; |
566 | 686 | } else if args.intrusion {
|
567 | 687 | println!("Chassis status:");
|
568 | 688 | if let Some(status) = print_err(ec.get_intrusion_status()) {
|
@@ -653,7 +773,7 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 {
|
653 | 773 | return 1;
|
654 | 774 | }
|
655 | 775 | } else if args.power {
|
656 |
| - power::get_and_print_power_info(&ec); |
| 776 | + return power::get_and_print_power_info(&ec); |
657 | 777 | } else if args.thermal {
|
658 | 778 | power::print_thermal(&ec);
|
659 | 779 | } else if args.sensors {
|
@@ -835,6 +955,8 @@ Options:
|
835 | 955 | --versions List current firmware versions
|
836 | 956 | --version Show tool version information (Add -vv for more detailed information)
|
837 | 957 | --esrt Display the UEFI ESRT table
|
| 958 | + --device <DEVICE> Device used to compare firmware version [possible values: bios, ec, pd0, pd1, rtm01, rtm23] |
| 959 | + --compare-version Version string used to match firmware version (use with --device) |
838 | 960 | --power Show current power status (battery and AC)
|
839 | 961 | --thermal Print thermal information (Temperatures and Fan speed)
|
840 | 962 | --sensors Print sensor information (ALS, G-Sensor)
|
|
0 commit comments