Skip to content

Commit 53c15fa

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 70595f7 commit 53c15fa

File tree

6 files changed

+140
-8
lines changed

6 files changed

+140
-8
lines changed

framework_lib/src/chromium_ec/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,7 @@ impl CrosEcDriver for CrosEc {
871871
}
872872

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

framework_lib/src/chromium_ec/portio.rs

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

228-
let res = ioperm(NPC_MEMMAP_OFFSET as u64, super::EC_MEMMAP_SIZE as u64, 1);
228+
let res = ioperm(
229+
NPC_MEMMAP_OFFSET as u64,
230+
(super::EC_MEMMAP_SIZE * 2) as u64,
231+
1,
232+
);
229233
assert_eq!(res, 0);
230234
}
231235
}

framework_lib/src/commandline/clap_std.rs

+5
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ struct ClapCli {
3333
#[arg(long)]
3434
thermal: bool,
3535

36+
/// Print expansion bay information
37+
#[arg(long)]
38+
expansion_bay: bool,
39+
3640
/// Show information about USB-C PD ports
3741
#[arg(long)]
3842
pdports: bool,
@@ -196,6 +200,7 @@ pub fn parse(args: &[String]) -> Cli {
196200
esrt: args.esrt,
197201
power: args.power,
198202
thermal: args.thermal,
203+
expansion_bay: args.expansion_bay,
199204
pdports: args.pdports,
200205
pd_info: args.pd_info,
201206
dp_hdmi_info: args.dp_hdmi_info,

framework_lib/src/commandline/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ pub struct Cli {
122122
pub esrt: bool,
123123
pub power: bool,
124124
pub thermal: bool,
125+
pub expansion_bay: bool,
125126
pub pdports: bool,
126127
pub privacy: bool,
127128
pub pd_info: bool,
@@ -606,6 +607,8 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 {
606607
power::get_and_print_power_info(&ec);
607608
} else if args.thermal {
608609
power::print_thermal(&ec);
610+
} else if args.expansion_bay {
611+
power::print_expansion_bay_info(&ec);
609612
} else if args.pdports {
610613
power::get_and_print_pd_info(&ec);
611614
} else if args.info {
@@ -784,7 +787,8 @@ Options:
784787
--version Show tool version information (Add -vv for more detailed information)
785788
--esrt Display the UEFI ESRT table
786789
--power Show current power status (battery and AC)
787-
--thermal Show current power status (battery and AC)
790+
--thermal Print thermal information (Temperatures and Fan speed)
791+
--expansion-bay Print expansion bay information
788792
--pdports Show information about USB-C PD ports
789793
--info Show info from SMBIOS (Only on UEFI)
790794
--pd-info Show details about the PD controllers

framework_lib/src/commandline/uefi.rs

+4
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ pub fn parse(args: &[String]) -> Cli {
6060
esrt: false,
6161
power: false,
6262
thermal: false,
63+
expansion_bay: false,
6364
pdports: false,
6465
pd_info: false,
6566
dp_hdmi_info: false,
@@ -131,6 +132,9 @@ pub fn parse(args: &[String]) -> Cli {
131132
} else if arg == "--thermal" {
132133
cli.thermal = true;
133134
found_an_option = true;
135+
} else if arg == "--expansion-bay" {
136+
cli.expansion_bay = true;
137+
found_an_option = true;
134138
} else if arg == "--pdports" {
135139
cli.pdports = true;
136140
found_an_option = true;

framework_lib/src/power.rs

+120-5
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,114 @@ fn in_c(t: u8) -> u8 {
169169
}
170170
}
171171

172+
pub fn print_expansion_bay_info(ec: &CrosEc) {
173+
let platform = smbios::get_platform();
174+
if !matches!(
175+
platform,
176+
Some(Platform::Framework13Amd) | Some(Platform::Framework16)
177+
) {
178+
println!("Only applicable to Framework 16 and Framework AMD systems");
179+
return;
180+
}
181+
182+
println!("AMD");
183+
// TODO: This is also on Azalea?
184+
let power_slider = ec.read_memory(0x151, 0x02).unwrap()[0];
185+
let dc_ac = if power_slider <= 0b1000 { "DC" } else { "AC" };
186+
let mode = match power_slider {
187+
0b0000_0001 | 0b0001_0000 => "Best Performance",
188+
0b0000_0010 | 0b0010_0000 => "Balanced",
189+
0b0000_0100 | 0b0100_0000 => "Best Power Efficiency",
190+
0b0000_1000 => "Battery Saver",
191+
_ => "Unknown Mode",
192+
};
193+
println!(
194+
" Power Slider: {}, {} ({:#09b})",
195+
dc_ac, mode, power_slider
196+
);
197+
198+
// TODO: This is also on Azalea?
199+
let stt_table = ec.read_memory(0x154, 0x01).unwrap()[0];
200+
println!(" STT Table: {:?}", stt_table);
201+
202+
// TODO: What's this? Always [0x00, 0x00] so far
203+
// TODO: This is also on Azalea?
204+
// Core Performance Boost
205+
let cbp = ec.read_memory(0x155, 0x02).unwrap();
206+
println!(" CBP: {} ({:?})", cbp == [0x00, 0x00], cbp);
207+
208+
// TODO: When is this changed?
209+
// TODO: This is also on Azalea?
210+
let dtt_temp = ec.read_memory(0x160, 0x0F).unwrap();
211+
println!(" DTT Temp: {:?}", dtt_temp);
212+
213+
if !matches!(platform, Some(Platform::Framework16)) {
214+
return;
215+
}
216+
217+
println!("Expansion Bay");
218+
219+
// TODO: This is the serial struct in the Expansion Bay?
220+
let serial_struct = ec.read_memory(0x140, 0x04).unwrap();
221+
println!(" Serial Struct: {:?}", serial_struct);
222+
223+
// TODO: Why is this in the same namespace?
224+
// let batt_manuf_day = ec.read_memory(0x144, 0x01).unwrap()[0];
225+
// let batt_manuf_month = ec.read_memory(0x145, 0x01).unwrap()[0];
226+
// let batt_manuf_year = ec.read_memory(0x146, 0x02).unwrap();
227+
// let batt_manuf_year = u16::from_le_bytes([batt_manuf_year[0], batt_manuf_year[1]]);
228+
// println!(" Batt Manuf {:?}-{:?}-{:?}", batt_manuf_year, batt_manuf_month, batt_manuf_day);
229+
230+
// TODO: This is the PD in the dGPU module?
231+
let pd_ver = ec.read_memory(0x14C, 0x04).unwrap();
232+
println!(" PD Version: {:?}", pd_ver);
233+
234+
let gpu_ctrl = ec.read_memory(0x150, 0x01).unwrap()[0];
235+
// Unused, this is for the BIOS to set
236+
let _set_mux_status = match gpu_ctrl & 0b11 {
237+
0b00 => "EC Received and Clear",
238+
0b01 => "BIOS Set APU",
239+
0b10 => "BIOS Set GPU",
240+
_ => "Unknown",
241+
};
242+
let mux_status = if (gpu_ctrl & 0b100) > 0 { "APU" } else { "GPU" };
243+
let board_status = if (gpu_ctrl & 0b1000) > 0 {
244+
"Present"
245+
} else {
246+
"Absent"
247+
};
248+
// Unused, set by BIOS: (gpu_ctrl & 0b10000)
249+
let pcie_config = match gpu_ctrl & 0b01100000 {
250+
0b00 => "8x1",
251+
0b01 => "4x1",
252+
0b10 => "4x2",
253+
0b11 => "Disabled",
254+
_ => "Unknown",
255+
};
256+
println!(" GPU CTRL: {:#x}", gpu_ctrl);
257+
println!(" MUX Status: {}", mux_status);
258+
println!(" Board Status: {}", board_status);
259+
println!(" PCIe Config: {}", pcie_config);
260+
261+
// TODO: This seems like it's not correctly working? It's always false
262+
let display_on = ec.read_memory(0x153, 0x01).unwrap()[0];
263+
println!(" Display On: {:?}", display_on == 0x01);
264+
265+
let gpu_type = ec.read_memory(0x157, 0x01).unwrap()[0];
266+
let gpu_name = match gpu_type {
267+
0x00 => "Initializing",
268+
0x01 => "Fan Only",
269+
0x02 => "AMD R23M",
270+
0x03 => "SSD",
271+
0x04 => "PCIe Accessory",
272+
_ => "Unknown",
273+
};
274+
println!(" GPU Type: {} ({:?})", gpu_name, gpu_type);
275+
}
276+
172277
pub fn print_thermal(ec: &CrosEc) {
173278
let temps = ec.read_memory(EC_MEMMAP_TEMP_SENSOR, 0x0F).unwrap();
279+
println!("Temps: {:?}", temps);
174280
let fans = ec.read_memory(EC_MEMMAP_FAN, 0x08).unwrap();
175281

176282
let platform = smbios::get_platform();
@@ -184,10 +290,13 @@ pub fn print_thermal(ec: &CrosEc) {
184290
println!(" F57397_VCCGT: {:>4} C", in_c(temps[5]));
185291
}
186292
Some(Platform::Framework13Amd | Platform::Framework16) => {
187-
println!(" F75303_Local: {:>4} C", in_c(temps[0]));
188-
println!(" F75303_CPU: {:>4} C", in_c(temps[1]));
189-
println!(" F75303_DDR: {:>4} C", in_c(temps[2]));
190-
println!(" APU: {:>4} C", in_c(temps[3]));
293+
// TODO: Check names. EC names are like this. But EC namespace spreadsheet is different
294+
println!(" Ambient: {:>4} C", in_c(temps[0]));
295+
println!(" Charger: {:>4} C", in_c(temps[1]));
296+
println!(" APU: {:>4} C", in_c(temps[2]));
297+
println!(" CPU: {:>4} C", in_c(temps[3]));
298+
// TODO: Only display if dGPU is present
299+
// TODO: Sometimes these show 0 even if the GPU is present. Why?
191300
if matches!(platform, Some(Platform::Framework16)) {
192301
println!(" dGPU VR: {:>4} C", in_c(temps[4]));
193302
println!(" dGPU VRAM: {:>4} C", in_c(temps[5]));
@@ -208,7 +317,13 @@ pub fn print_thermal(ec: &CrosEc) {
208317
}
209318

210319
let fan0 = u16::from_le_bytes([fans[0], fans[1]]);
211-
println!(" Fan Speed: {:>4} RPM", fan0);
320+
let fan1 = u16::from_le_bytes([fans[2], fans[3]]);
321+
if matches!(platform, Some(Platform::Framework16)) {
322+
println!(" Fan L Speed: {:>4} RPM", fan0);
323+
println!(" Fan R Speed: {:>4} RPM", fan1);
324+
} else {
325+
println!(" Fan Speed: {:>4} RPM", fan0);
326+
}
212327
}
213328

214329
// TODO: Use Result

0 commit comments

Comments
 (0)