Skip to content

Decode additional Framework16 and AMD related memmap items #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion framework_lib/src/chromium_ec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,7 @@ impl CrosEcDriver for CrosEc {
}

debug!("read_memory(offset={:#X}, size={:#X})", offset, length);
if offset + length > EC_MEMMAP_SIZE {
if offset + length > (EC_MEMMAP_SIZE * 2) {
return None;
}

Expand Down
6 changes: 5 additions & 1 deletion framework_lib/src/chromium_ec/portio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,11 @@ fn init() -> bool {
let res = ioperm(EC_LPC_ADDR_HOST_DATA as u64, 1, 1);
assert_eq!(res, 0);

let res = ioperm(NPC_MEMMAP_OFFSET as u64, super::EC_MEMMAP_SIZE as u64, 1);
let res = ioperm(
NPC_MEMMAP_OFFSET as u64,
(super::EC_MEMMAP_SIZE * 2) as u64,
1,
);
assert_eq!(res, 0);
}
}
Expand Down
5 changes: 5 additions & 0 deletions framework_lib/src/commandline/clap_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ struct ClapCli {
#[arg(long)]
sensors: bool,

/// Print expansion bay information
#[arg(long)]
expansion_bay: bool,

/// Show information about USB-C PD ports
#[arg(long)]
pdports: bool,
Expand Down Expand Up @@ -289,6 +293,7 @@ pub fn parse(args: &[String]) -> Cli {
power: args.power,
thermal: args.thermal,
sensors: args.sensors,
expansion_bay: args.expansion_bay,
pdports: args.pdports,
pd_info: args.pd_info,
dp_hdmi_info: args.dp_hdmi_info,
Expand Down
4 changes: 4 additions & 0 deletions framework_lib/src/commandline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ pub struct Cli {
pub power: bool,
pub thermal: bool,
pub sensors: bool,
pub expansion_bay: bool,
pub pdports: bool,
pub privacy: bool,
pub pd_info: bool,
Expand Down Expand Up @@ -850,6 +851,8 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 {
power::print_thermal(&ec);
} else if args.sensors {
power::print_sensors(&ec);
} else if args.expansion_bay {
power::print_expansion_bay_info(&ec);
} else if args.pdports {
power::get_and_print_pd_info(&ec);
} else if args.info {
Expand Down Expand Up @@ -1046,6 +1049,7 @@ Options:
--power Show current power status (battery and AC)
--thermal Print thermal information (Temperatures and Fan speed)
--sensors Print sensor information (ALS, G-Sensor)
--expansion-bay Print expansion bay information
--pdports Show information about USB-C PD ports
--info Show info from SMBIOS (Only on UEFI)
--pd-info Show details about the PD controllers
Expand Down
3 changes: 3 additions & 0 deletions framework_lib/src/commandline/uefi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub fn parse(args: &[String]) -> Cli {
power: false,
thermal: false,
sensors: false,
expansion_bay: false,
pdports: false,
pd_info: false,
dp_hdmi_info: false,
Expand Down Expand Up @@ -147,6 +148,8 @@ pub fn parse(args: &[String]) -> Cli {
found_an_option = true;
} else if arg == "--sensors" {
cli.sensors = true;
} else if arg == "--expansion-bay" {
cli.expansion_bay = true;
found_an_option = true;
} else if arg == "--pdports" {
cli.pdports = true;
Expand Down
116 changes: 115 additions & 1 deletion framework_lib/src/power.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,114 @@ pub fn print_sensors(ec: &CrosEc) {
// Sensor 2: 00.00 X 00.00 Y 00.00 Z
}

pub fn print_expansion_bay_info(ec: &CrosEc) {
let platform = smbios::get_platform();
if !matches!(
platform,
Some(Platform::Framework13Amd7080) | Some(Platform::Framework16Amd7080)
) {
println!("Only applicable to Framework 16 and Framework AMD systems");
return;
}

println!("AMD");
// TODO: This is also on Azalea?
let power_slider = ec.read_memory(0x151, 0x02).unwrap()[0];
let dc_ac = if power_slider <= 0b1000 { "DC" } else { "AC" };
let mode = match power_slider {
0b0000_0001 | 0b0001_0000 => "Best Performance",
0b0000_0010 | 0b0010_0000 => "Balanced",
0b0000_0100 | 0b0100_0000 => "Best Power Efficiency",
0b0000_1000 => "Battery Saver",
_ => "Unknown Mode",
};
println!(
" Power Slider: {}, {} ({:#09b})",
dc_ac, mode, power_slider
);

// TODO: This is also on Azalea?
let stt_table = ec.read_memory(0x154, 0x01).unwrap()[0];
println!(" STT Table: {:?}", stt_table);

// TODO: What's this? Always [0x00, 0x00] so far
// TODO: This is also on Azalea?
// Core Performance Boost
let cbp = ec.read_memory(0x155, 0x02).unwrap();
println!(" CBP: {} ({:?})", cbp == [0x00, 0x00], cbp);

// TODO: When is this changed?
// TODO: This is also on Azalea?
let dtt_temp = ec.read_memory(0x160, 0x0F).unwrap();
println!(" DTT Temp: {:?}", dtt_temp);

if !matches!(platform, Some(Platform::Framework16Amd7080)) {
return;
}

println!("Expansion Bay");

// TODO: This is the serial struct in the Expansion Bay?
let serial_struct = ec.read_memory(0x140, 0x04).unwrap();
println!(" Serial Struct: {:?}", serial_struct);

// TODO: Why is this in the same namespace?
// let batt_manuf_day = ec.read_memory(0x144, 0x01).unwrap()[0];
// let batt_manuf_month = ec.read_memory(0x145, 0x01).unwrap()[0];
// let batt_manuf_year = ec.read_memory(0x146, 0x02).unwrap();
// let batt_manuf_year = u16::from_le_bytes([batt_manuf_year[0], batt_manuf_year[1]]);
// println!(" Batt Manuf {:?}-{:?}-{:?}", batt_manuf_year, batt_manuf_month, batt_manuf_day);

// TODO: This is the PD in the dGPU module?
let pd_ver = ec.read_memory(0x14C, 0x04).unwrap();
println!(" PD Version: {:?}", pd_ver);

let gpu_ctrl = ec.read_memory(0x150, 0x01).unwrap()[0];
// Unused, this is for the BIOS to set
let _set_mux_status = match gpu_ctrl & 0b11 {
0b00 => "EC Received and Clear",
0b01 => "BIOS Set APU",
0b10 => "BIOS Set GPU",
_ => "Unknown",
};
let mux_status = if (gpu_ctrl & 0b100) > 0 { "APU" } else { "GPU" };
let board_status = if (gpu_ctrl & 0b1000) > 0 {
"Present"
} else {
"Absent"
};
// Unused, set by BIOS: (gpu_ctrl & 0b10000)
let pcie_config = match gpu_ctrl & 0b01100000 {
0b00 => "8x1",
0b01 => "4x1",
0b10 => "4x2",
0b11 => "Disabled",
_ => "Unknown",
};
println!(" GPU CTRL: {:#x}", gpu_ctrl);
println!(" MUX Status: {}", mux_status);
println!(" Board Status: {}", board_status);
println!(" PCIe Config: {}", pcie_config);

// TODO: This seems like it's not correctly working? It's always false
let display_on = ec.read_memory(0x153, 0x01).unwrap()[0];
println!(" Display On: {:?}", display_on == 0x01);

let gpu_type = ec.read_memory(0x157, 0x01).unwrap()[0];
let gpu_name = match gpu_type {
0x00 => "Initializing",
0x01 => "Fan Only",
0x02 => "AMD R23M",
0x03 => "SSD",
0x04 => "PCIe Accessory",
_ => "Unknown",
};
println!(" GPU Type: {} ({:?})", gpu_name, gpu_type);
}

pub fn print_thermal(ec: &CrosEc) {
let temps = ec.read_memory(EC_MEMMAP_TEMP_SENSOR, 0x0F).unwrap();
println!("Temps: {:?}", temps);
let fans = ec.read_memory(EC_MEMMAP_FAN, 0x08).unwrap();

let platform = smbios::get_platform();
Expand Down Expand Up @@ -346,6 +452,8 @@ pub fn print_thermal(ec: &CrosEc) {
println!(" F75303_CPU: {:>4}", TempSensor::from(temps[1]));
println!(" F75303_DDR: {:>4}", TempSensor::from(temps[2]));
println!(" APU: {:>4}", TempSensor::from(temps[3]));
// TODO: Only display if dGPU is present
// TODO: Sometimes these show 0 even if the GPU is present. Why?
if matches!(platform, Some(Platform::Framework16Amd7080)) {
println!(" dGPU VR: {:>4}", TempSensor::from(temps[4]));
println!(" dGPU VRAM: {:>4}", TempSensor::from(temps[5]));
Expand Down Expand Up @@ -374,7 +482,13 @@ pub fn print_thermal(ec: &CrosEc) {
}

let fan0 = u16::from_le_bytes([fans[0], fans[1]]);
println!(" Fan Speed: {:>4} RPM", fan0);
let fan1 = u16::from_le_bytes([fans[2], fans[3]]);
if matches!(platform, Some(Platform::Framework16Amd7080)) {
println!(" Fan L Speed: {:>4} RPM", fan0);
println!(" Fan R Speed: {:>4} RPM", fan1);
} else {
println!(" Fan Speed: {:>4} RPM", fan0);
}
}

// TODO: Use Result
Expand Down