Skip to content

Commit 3a47334

Browse files
committed
Decode additional Frameowork16 and AMD related memmap items
TODO: - [ ] Handle it better than just increasing EC_MEMMAP_SIZE*2 - [ ] Figure out all items and whether they apply to Lotus and also Azalea - [ ] Figure out Lotus and Azalea fan names Example: ``` cargo build && sudo ./target/debug/framework_tool --driver portio --expansion-bay AMD Power Slider: DC, Battery Saver (0b0001000) STT Table: 7 CBP: true ([0, 0]) DTT Temp: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] Expansion Bay Serial Struct: [0, 0, 0, 0] PD Version: [0, 0, 0, 0] GPU CTRL: 0x8 MUX Status: GPU Board Status: Present PCIe Config: 8x1 Display On: false GPU Type: AMD R23M (2) ``` Reference data: ``` Fan Module Serial Struct: [0, 0, 0, 0] Batt Manuf 2023-22-7 PD Version: [0, 0, 0, 0] GPU CTRL: 0x0 Power Slider: AC, Best Power Efficiency (0b1000000) Display On: false STT Table: 13 CBP: true ([0, 0]) GPU Type: Initializing (0) DTT Temp: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] dGPU Module Serial Struct: [0, 0, 0, 0] Batt Manuf 2023-7-22 PD Version: [0, 0, 0, 0] GPU CTRL: 0x8 Power Slider: DC, Battery Saver (0b0001000) Display On: false STT Table: 7 CBP: true ([0, 0]) GPU Type: AMD R23M (2) DTT Temp: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ``` Signed-off-by: Daniel Schaefer <[email protected]>
1 parent 2200639 commit 3a47334

File tree

6 files changed

+133
-3
lines changed

6 files changed

+133
-3
lines changed

framework_lib/src/chromium_ec/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1023,7 +1023,7 @@ impl CrosEcDriver for CrosEc {
10231023
}
10241024

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

framework_lib/src/chromium_ec/portio.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,11 @@ fn init() -> bool {
227227
let res = ioperm(EC_LPC_ADDR_HOST_DATA as u64, 1, 1);
228228
assert_eq!(res, 0);
229229

230-
let res = ioperm(NPC_MEMMAP_OFFSET as u64, super::EC_MEMMAP_SIZE as u64, 1);
230+
let res = ioperm(
231+
NPC_MEMMAP_OFFSET as u64,
232+
(super::EC_MEMMAP_SIZE * 2) as u64,
233+
1,
234+
);
231235
assert_eq!(res, 0);
232236
}
233237
}

framework_lib/src/commandline/clap_std.rs

+5
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ struct ClapCli {
5757
#[arg(long)]
5858
sensors: bool,
5959

60+
/// Print expansion bay information
61+
#[arg(long)]
62+
expansion_bay: bool,
63+
6064
/// Show information about USB-C PD ports
6165
#[arg(long)]
6266
pdports: bool,
@@ -289,6 +293,7 @@ pub fn parse(args: &[String]) -> Cli {
289293
power: args.power,
290294
thermal: args.thermal,
291295
sensors: args.sensors,
296+
expansion_bay: args.expansion_bay,
292297
pdports: args.pdports,
293298
pd_info: args.pd_info,
294299
dp_hdmi_info: args.dp_hdmi_info,

framework_lib/src/commandline/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ pub struct Cli {
148148
pub power: bool,
149149
pub thermal: bool,
150150
pub sensors: bool,
151+
pub expansion_bay: bool,
151152
pub pdports: bool,
152153
pub privacy: bool,
153154
pub pd_info: bool,
@@ -850,6 +851,8 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 {
850851
power::print_thermal(&ec);
851852
} else if args.sensors {
852853
power::print_sensors(&ec);
854+
} else if args.expansion_bay {
855+
power::print_expansion_bay_info(&ec);
853856
} else if args.pdports {
854857
power::get_and_print_pd_info(&ec);
855858
} else if args.info {
@@ -1046,6 +1049,7 @@ Options:
10461049
--power Show current power status (battery and AC)
10471050
--thermal Print thermal information (Temperatures and Fan speed)
10481051
--sensors Print sensor information (ALS, G-Sensor)
1052+
--expansion-bay Print expansion bay information
10491053
--pdports Show information about USB-C PD ports
10501054
--info Show info from SMBIOS (Only on UEFI)
10511055
--pd-info Show details about the PD controllers

framework_lib/src/commandline/uefi.rs

+3
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ pub fn parse(args: &[String]) -> Cli {
6565
power: false,
6666
thermal: false,
6767
sensors: false,
68+
expansion_bay: false,
6869
pdports: false,
6970
pd_info: false,
7071
dp_hdmi_info: false,
@@ -147,6 +148,8 @@ pub fn parse(args: &[String]) -> Cli {
147148
found_an_option = true;
148149
} else if arg == "--sensors" {
149150
cli.sensors = true;
151+
} else if arg == "--expansion-bay" {
152+
cli.expansion_bay = true;
150153
found_an_option = true;
151154
} else if arg == "--pdports" {
152155
cli.pdports = true;

framework_lib/src/power.rs

+115-1
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,114 @@ pub fn print_sensors(ec: &CrosEc) {
301301
// Sensor 2: 00.00 X 00.00 Y 00.00 Z
302302
}
303303

304+
pub fn print_expansion_bay_info(ec: &CrosEc) {
305+
let platform = smbios::get_platform();
306+
if !matches!(
307+
platform,
308+
Some(Platform::Framework13Amd7080) | Some(Platform::Framework16Amd7080)
309+
) {
310+
println!("Only applicable to Framework 16 and Framework AMD systems");
311+
return;
312+
}
313+
314+
println!("AMD");
315+
// TODO: This is also on Azalea?
316+
let power_slider = ec.read_memory(0x151, 0x02).unwrap()[0];
317+
let dc_ac = if power_slider <= 0b1000 { "DC" } else { "AC" };
318+
let mode = match power_slider {
319+
0b0000_0001 | 0b0001_0000 => "Best Performance",
320+
0b0000_0010 | 0b0010_0000 => "Balanced",
321+
0b0000_0100 | 0b0100_0000 => "Best Power Efficiency",
322+
0b0000_1000 => "Battery Saver",
323+
_ => "Unknown Mode",
324+
};
325+
println!(
326+
" Power Slider: {}, {} ({:#09b})",
327+
dc_ac, mode, power_slider
328+
);
329+
330+
// TODO: This is also on Azalea?
331+
let stt_table = ec.read_memory(0x154, 0x01).unwrap()[0];
332+
println!(" STT Table: {:?}", stt_table);
333+
334+
// TODO: What's this? Always [0x00, 0x00] so far
335+
// TODO: This is also on Azalea?
336+
// Core Performance Boost
337+
let cbp = ec.read_memory(0x155, 0x02).unwrap();
338+
println!(" CBP: {} ({:?})", cbp == [0x00, 0x00], cbp);
339+
340+
// TODO: When is this changed?
341+
// TODO: This is also on Azalea?
342+
let dtt_temp = ec.read_memory(0x160, 0x0F).unwrap();
343+
println!(" DTT Temp: {:?}", dtt_temp);
344+
345+
if !matches!(platform, Some(Platform::Framework16Amd7080)) {
346+
return;
347+
}
348+
349+
println!("Expansion Bay");
350+
351+
// TODO: This is the serial struct in the Expansion Bay?
352+
let serial_struct = ec.read_memory(0x140, 0x04).unwrap();
353+
println!(" Serial Struct: {:?}", serial_struct);
354+
355+
// TODO: Why is this in the same namespace?
356+
// let batt_manuf_day = ec.read_memory(0x144, 0x01).unwrap()[0];
357+
// let batt_manuf_month = ec.read_memory(0x145, 0x01).unwrap()[0];
358+
// let batt_manuf_year = ec.read_memory(0x146, 0x02).unwrap();
359+
// let batt_manuf_year = u16::from_le_bytes([batt_manuf_year[0], batt_manuf_year[1]]);
360+
// println!(" Batt Manuf {:?}-{:?}-{:?}", batt_manuf_year, batt_manuf_month, batt_manuf_day);
361+
362+
// TODO: This is the PD in the dGPU module?
363+
let pd_ver = ec.read_memory(0x14C, 0x04).unwrap();
364+
println!(" PD Version: {:?}", pd_ver);
365+
366+
let gpu_ctrl = ec.read_memory(0x150, 0x01).unwrap()[0];
367+
// Unused, this is for the BIOS to set
368+
let _set_mux_status = match gpu_ctrl & 0b11 {
369+
0b00 => "EC Received and Clear",
370+
0b01 => "BIOS Set APU",
371+
0b10 => "BIOS Set GPU",
372+
_ => "Unknown",
373+
};
374+
let mux_status = if (gpu_ctrl & 0b100) > 0 { "APU" } else { "GPU" };
375+
let board_status = if (gpu_ctrl & 0b1000) > 0 {
376+
"Present"
377+
} else {
378+
"Absent"
379+
};
380+
// Unused, set by BIOS: (gpu_ctrl & 0b10000)
381+
let pcie_config = match gpu_ctrl & 0b01100000 {
382+
0b00 => "8x1",
383+
0b01 => "4x1",
384+
0b10 => "4x2",
385+
0b11 => "Disabled",
386+
_ => "Unknown",
387+
};
388+
println!(" GPU CTRL: {:#x}", gpu_ctrl);
389+
println!(" MUX Status: {}", mux_status);
390+
println!(" Board Status: {}", board_status);
391+
println!(" PCIe Config: {}", pcie_config);
392+
393+
// TODO: This seems like it's not correctly working? It's always false
394+
let display_on = ec.read_memory(0x153, 0x01).unwrap()[0];
395+
println!(" Display On: {:?}", display_on == 0x01);
396+
397+
let gpu_type = ec.read_memory(0x157, 0x01).unwrap()[0];
398+
let gpu_name = match gpu_type {
399+
0x00 => "Initializing",
400+
0x01 => "Fan Only",
401+
0x02 => "AMD R23M",
402+
0x03 => "SSD",
403+
0x04 => "PCIe Accessory",
404+
_ => "Unknown",
405+
};
406+
println!(" GPU Type: {} ({:?})", gpu_name, gpu_type);
407+
}
408+
304409
pub fn print_thermal(ec: &CrosEc) {
305410
let temps = ec.read_memory(EC_MEMMAP_TEMP_SENSOR, 0x0F).unwrap();
411+
println!("Temps: {:?}", temps);
306412
let fans = ec.read_memory(EC_MEMMAP_FAN, 0x08).unwrap();
307413

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

376484
let fan0 = u16::from_le_bytes([fans[0], fans[1]]);
377-
println!(" Fan Speed: {:>4} RPM", fan0);
485+
let fan1 = u16::from_le_bytes([fans[2], fans[3]]);
486+
if matches!(platform, Some(Platform::Framework16Amd7080)) {
487+
println!(" Fan L Speed: {:>4} RPM", fan0);
488+
println!(" Fan R Speed: {:>4} RPM", fan1);
489+
} else {
490+
println!(" Fan Speed: {:>4} RPM", fan0);
491+
}
378492
}
379493

380494
// TODO: Use Result

0 commit comments

Comments
 (0)