Skip to content

Commit 4421678

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 8ff67b6 commit 4421678

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
@@ -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
@@ -226,7 +226,11 @@ fn init() -> bool {
226226
let res = ioperm(EC_LPC_ADDR_HOST_DATA as u64, 1, 1);
227227
assert_eq!(res, 0);
228228

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

framework_lib/src/commandline/clap_std.rs

+5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ struct ClapCli {
3737
#[arg(long)]
3838
sensors: bool,
3939

40+
/// Print expansion bay information
41+
#[arg(long)]
42+
expansion_bay: bool,
43+
4044
/// Show information about USB-C PD ports
4145
#[arg(long)]
4246
pdports: bool,
@@ -201,6 +205,7 @@ pub fn parse(args: &[String]) -> Cli {
201205
power: args.power,
202206
thermal: args.thermal,
203207
sensors: args.sensors,
208+
expansion_bay: args.expansion_bay,
204209
pdports: args.pdports,
205210
pd_info: args.pd_info,
206211
dp_hdmi_info: args.dp_hdmi_info,

framework_lib/src/commandline/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ pub struct Cli {
123123
pub power: bool,
124124
pub thermal: bool,
125125
pub sensors: bool,
126+
pub expansion_bay: bool,
126127
pub pdports: bool,
127128
pub privacy: bool,
128129
pub pd_info: bool,
@@ -658,6 +659,8 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 {
658659
power::print_thermal(&ec);
659660
} else if args.sensors {
660661
power::print_sensors(&ec);
662+
} else if args.expansion_bay {
663+
power::print_expansion_bay_info(&ec);
661664
} else if args.pdports {
662665
power::get_and_print_pd_info(&ec);
663666
} else if args.info {
@@ -838,6 +841,7 @@ Options:
838841
--power Show current power status (battery and AC)
839842
--thermal Print thermal information (Temperatures and Fan speed)
840843
--sensors Print sensor information (ALS, G-Sensor)
844+
--expansion-bay Print expansion bay information
841845
--pdports Show information about USB-C PD ports
842846
--info Show info from SMBIOS (Only on UEFI)
843847
--pd-info Show details about the PD controllers

framework_lib/src/commandline/uefi.rs

+3
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ pub fn parse(args: &[String]) -> Cli {
6161
power: false,
6262
thermal: false,
6363
sensors: false,
64+
expansion_bay: false,
6465
pdports: false,
6566
pd_info: false,
6667
dp_hdmi_info: false,
@@ -134,6 +135,8 @@ pub fn parse(args: &[String]) -> Cli {
134135
found_an_option = true;
135136
} else if arg == "--sensors" {
136137
cli.sensors = true;
138+
} else if arg == "--expansion-bay" {
139+
cli.expansion_bay = true;
137140
found_an_option = true;
138141
} else if arg == "--pdports" {
139142
cli.pdports = true;

framework_lib/src/power.rs

+115-1
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,114 @@ pub fn print_sensors(ec: &CrosEc) {
198198
println!("ALS: {:>4} Lux", als_int);
199199
}
200200

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

205311
let platform = smbios::get_platform();
@@ -217,6 +323,8 @@ pub fn print_thermal(ec: &CrosEc) {
217323
println!(" F75303_CPU: {:>4}", TempSensor::from(temps[1]));
218324
println!(" F75303_DDR: {:>4}", TempSensor::from(temps[2]));
219325
println!(" APU: {:>4}", TempSensor::from(temps[3]));
326+
// TODO: Only display if dGPU is present
327+
// TODO: Sometimes these show 0 even if the GPU is present. Why?
220328
if matches!(platform, Some(Platform::Framework16)) {
221329
println!(" dGPU VR: {:>4}", TempSensor::from(temps[4]));
222330
println!(" dGPU VRAM: {:>4}", TempSensor::from(temps[5]));
@@ -237,7 +345,13 @@ pub fn print_thermal(ec: &CrosEc) {
237345
}
238346

239347
let fan0 = u16::from_le_bytes([fans[0], fans[1]]);
240-
println!(" Fan Speed: {:>4} RPM", fan0);
348+
let fan1 = u16::from_le_bytes([fans[2], fans[3]]);
349+
if matches!(platform, Some(Platform::Framework16)) {
350+
println!(" Fan L Speed: {:>4} RPM", fan0);
351+
println!(" Fan R Speed: {:>4} RPM", fan1);
352+
} else {
353+
println!(" Fan Speed: {:>4} RPM", fan0);
354+
}
241355
}
242356

243357
// TODO: Use Result

0 commit comments

Comments
 (0)