Skip to content

Commit 63dccaf

Browse files
committed
Add --pd-debug and --kbd-debug to control EC debug logging
Uses the new EC_CMD_DEBUG_CONTROL (0x3E2D) host command to toggle the verbose PD message logging, UCSI command tracing and dahlia keyboard controller per-report logging that could previously only be enabled with the cypdctl and kbdebug EC console commands. The log output goes to the EC console, read it with --console follow. > framework_tool --pd-debug status PD debug logging: Verbose: false UCSI: false UCSI tunnel disabled: false > framework_tool --pd-debug verbose > framework_tool --console follow > framework_tool --kbd-debug on Keyboard debug logging: true Read the log output with --console follow Signed-off-by: Daniel Schaefer <dhs@frame.work>
1 parent a338c6a commit 63dccaf

10 files changed

Lines changed: 230 additions & 4 deletions

File tree

framework_lib/src/chromium_ec/command.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ pub enum EcCommands {
127127
GetPdPortState = 0x3E23,
128128
/// Read board ID of specific ADC channel
129129
ReadBoardId = 0x3E26,
130+
/// Control PD debug logging, the output goes to the EC console
131+
DebugControl = 0x3E2D,
130132
}
131133

132134
pub trait EcRequest<R> {

framework_lib/src/chromium_ec/commands.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1999,3 +1999,33 @@ impl EcRequest<EcResponseGetApThrottleStatus> for EcRequestGetApThrottleStatus {
19991999
EcCommands::GetApThrottleStatus
20002000
}
20012001
}
2002+
2003+
/// Verbose PD message logging (cypdctl verbose)
2004+
pub const EC_DEBUG_PD_VERBOSE_MSG: u8 = 0x01;
2005+
/// UCSI command tracing (cypdctl ucsi)
2006+
pub const EC_DEBUG_PD_UCSI: u8 = 0x02;
2007+
/// Disable the UCSI tunnel (cypdctl ucsitun 0)
2008+
pub const EC_DEBUG_PD_UCSI_TUNNEL_DIS: u8 = 0x04;
2009+
/// Log every HID report from the keyboard controller (kbdebug)
2010+
pub const EC_DEBUG_KEYBOARD: u8 = 0x08;
2011+
2012+
#[repr(C, packed)]
2013+
pub struct EcRequestDebugControl {
2014+
/// Which EC_DEBUG_* flags to modify; 0 = pure read, nothing changed
2015+
pub set_mask: u8,
2016+
/// New values for the flags selected in set_mask
2017+
pub flags: u8,
2018+
}
2019+
2020+
#[repr(C, packed)]
2021+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2022+
pub struct EcResponseDebugControl {
2023+
/// Current flag values, after any modification
2024+
pub flags: u8,
2025+
}
2026+
2027+
impl EcRequest<EcResponseDebugControl> for EcRequestDebugControl {
2028+
fn command_id() -> EcCommands {
2029+
EcCommands::DebugControl
2030+
}
2031+
}

framework_lib/src/chromium_ec/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,14 @@ impl CrosEc {
863863
}
864864
}
865865

866+
/// Get or set verbose debug logging flags (see EC_DEBUG_* constants)
867+
/// set_mask selects which flags to change, 0 reads without changing.
868+
/// Returns the current flags. The log output goes to the EC console.
869+
pub fn debug_control(&self, set_mask: u8, flags: u8) -> EcResult<u8> {
870+
let res = EcRequestDebugControl { set_mask, flags }.send_command(self)?;
871+
Ok(res.flags)
872+
}
873+
866874
/// Set tablet mode
867875
pub fn set_tablet_mode(&self, mode: TabletModeOverride) {
868876
let mode = mode as u8;

framework_lib/src/commandline/clap_std.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::chromium_ec::commands::SetGpuSerialMagic;
1616
use crate::chromium_ec::CrosEcDriverType;
1717
use crate::commandline::{
1818
Cli, ClickForceArg, ConsoleArg, FpBrightnessArg, HardwareDeviceType, InputDeckModeArg,
19-
LogLevel, RebootEcArg, TabletModeArg,
19+
KbdDebugArg, LogLevel, PdDebugArg, RebootEcArg, TabletModeArg,
2020
};
2121

2222
/// Swiss army knife for Framework laptops
@@ -129,6 +129,16 @@ struct ClapCli {
129129
#[arg(long)]
130130
pd_enable: Option<u8>,
131131

132+
/// Get or set PD debug logging, read the output via --console
133+
#[clap(value_enum)]
134+
#[arg(long)]
135+
pd_debug: Option<PdDebugArg>,
136+
137+
/// Get or set keyboard controller debug logging, read the output via --console
138+
#[clap(value_enum)]
139+
#[arg(long)]
140+
kbd_debug: Option<KbdDebugArg>,
141+
132142
/// Show details about connected DP or HDMI Expansion Cards
133143
#[arg(long)]
134144
dp_hdmi_info: bool,
@@ -655,6 +665,8 @@ pub fn parse(args: &[String]) -> Cli {
655665
pd_reset: args.pd_reset,
656666
pd_disable: args.pd_disable,
657667
pd_enable: args.pd_enable,
668+
pd_debug: args.pd_debug,
669+
kbd_debug: args.kbd_debug,
658670
dp_hdmi_info: args.dp_hdmi_info,
659671
dp_hdmi_update: args
660672
.dp_hdmi_update

framework_lib/src/commandline/mod.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ use crate::chromium_ec::commands::RebootEcCmd;
4242
use crate::chromium_ec::commands::RgbS;
4343
use crate::chromium_ec::commands::TabletModeOverride;
4444
use crate::chromium_ec::commands::EC_PROTOCOL_INFO_IN_PROGRESS_SUPPORTED;
45+
use crate::chromium_ec::commands::{
46+
EC_DEBUG_KEYBOARD, EC_DEBUG_PD_UCSI, EC_DEBUG_PD_UCSI_TUNNEL_DIS, EC_DEBUG_PD_VERBOSE_MSG,
47+
};
4548
use crate::chromium_ec::commands::{PORT_80_EVENT_RESET, PORT_80_EVENT_RESUME};
4649
use crate::chromium_ec::EcResponseStatus;
4750
use crate::chromium_ec::Port80History;
@@ -99,6 +102,24 @@ pub enum ConsoleArg {
99102
Follow,
100103
}
101104

105+
#[cfg_attr(not(feature = "uefi"), derive(clap::ValueEnum))]
106+
#[derive(Clone, Debug, PartialEq)]
107+
pub enum PdDebugArg {
108+
Status,
109+
Off,
110+
Verbose,
111+
Ucsi,
112+
All,
113+
}
114+
115+
#[cfg_attr(not(feature = "uefi"), derive(clap::ValueEnum))]
116+
#[derive(Clone, Debug, PartialEq)]
117+
pub enum KbdDebugArg {
118+
Status,
119+
Off,
120+
On,
121+
}
122+
102123
#[cfg_attr(not(feature = "uefi"), derive(clap::ValueEnum))]
103124
#[derive(Clone, Debug, PartialEq)]
104125
pub enum RebootEcArg {
@@ -207,6 +228,8 @@ pub struct Cli {
207228
pub pd_reset: Option<u8>,
208229
pub pd_disable: Option<u8>,
209230
pub pd_enable: Option<u8>,
231+
pub pd_debug: Option<PdDebugArg>,
232+
pub kbd_debug: Option<KbdDebugArg>,
210233
pub dp_hdmi_info: bool,
211234
pub dp_hdmi_update: Option<String>,
212235
pub audio_card_info: bool,
@@ -308,6 +331,8 @@ pub fn parse(args: &[String]) -> Cli {
308331
// pd_reset
309332
// pd_disable
310333
// pd_enable
334+
// pd_debug
335+
// kbd_debug
311336
dp_hdmi_info: cli.dp_hdmi_info,
312337
// dp_hdmi_update
313338
audio_card_info: cli.audio_card_info,
@@ -1777,6 +1802,50 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 {
17771802
Ok(())
17781803
}
17791804
});
1805+
} else if let Some(pd_debug) = &args.pd_debug {
1806+
let (set_mask, flags) = match pd_debug {
1807+
PdDebugArg::Status => (0, 0),
1808+
PdDebugArg::Off => (EC_DEBUG_PD_VERBOSE_MSG | EC_DEBUG_PD_UCSI, 0),
1809+
PdDebugArg::Verbose => (EC_DEBUG_PD_VERBOSE_MSG, EC_DEBUG_PD_VERBOSE_MSG),
1810+
PdDebugArg::Ucsi => (EC_DEBUG_PD_UCSI, EC_DEBUG_PD_UCSI),
1811+
PdDebugArg::All => (
1812+
EC_DEBUG_PD_VERBOSE_MSG | EC_DEBUG_PD_UCSI,
1813+
EC_DEBUG_PD_VERBOSE_MSG | EC_DEBUG_PD_UCSI,
1814+
),
1815+
};
1816+
match ec.debug_control(set_mask, flags) {
1817+
Ok(cur) => {
1818+
println!("PD debug logging:");
1819+
println!(
1820+
" Verbose: {}",
1821+
cur & EC_DEBUG_PD_VERBOSE_MSG != 0
1822+
);
1823+
println!(" UCSI: {}", cur & EC_DEBUG_PD_UCSI != 0);
1824+
println!(
1825+
" UCSI tunnel disabled: {}",
1826+
cur & EC_DEBUG_PD_UCSI_TUNNEL_DIS != 0
1827+
);
1828+
if cur & (EC_DEBUG_PD_VERBOSE_MSG | EC_DEBUG_PD_UCSI) != 0 {
1829+
println!("Read the log output with --console follow");
1830+
}
1831+
}
1832+
Err(err) => println!("Failed to control PD debug logging: {:?}", err),
1833+
}
1834+
} else if let Some(kbd_debug) = &args.kbd_debug {
1835+
let (set_mask, flags) = match kbd_debug {
1836+
KbdDebugArg::Status => (0, 0),
1837+
KbdDebugArg::Off => (EC_DEBUG_KEYBOARD, 0),
1838+
KbdDebugArg::On => (EC_DEBUG_KEYBOARD, EC_DEBUG_KEYBOARD),
1839+
};
1840+
match ec.debug_control(set_mask, flags) {
1841+
Ok(cur) => {
1842+
println!("Keyboard debug logging: {}", cur & EC_DEBUG_KEYBOARD != 0);
1843+
if cur & EC_DEBUG_KEYBOARD != 0 {
1844+
println!("Read the log output with --console follow");
1845+
}
1846+
}
1847+
Err(err) => println!("Failed to control keyboard debug logging: {:?}", err),
1848+
}
17801849
} else if args.dp_hdmi_info {
17811850
#[cfg(feature = "hidapi")]
17821851
print_dp_hdmi_details(true);
@@ -2104,6 +2173,8 @@ Options:
21042173
Set the color of a key to RGB. Multiple colors for adjacent keys can be set at once
21052174
--tablet-mode <MODE> Set tablet mode override [possible values: auto, tablet, laptop]
21062175
--console <CONSOLE> Get EC console, choose whether recent or to follow the output [possible values: recent, follow]
2176+
--pd-debug <MODE> Get or set PD debug logging, read it via --console [possible values: status, off, verbose, ucsi, all]
2177+
--kbd-debug <MODE> Get or set keyboard controller debug logging, read it via --console [possible values: status, off, on]
21072178
--hash <HASH> Hash a file of arbitrary data
21082179
--flash-gpu-descriptor <MAGIC> <18 DIGIT SN> Overwrite the GPU bay descriptor SN and type.
21092180
--flash-gpu-descriptor-file <DESCRIPTOR_FILE> Write the GPU bay descriptor with a descriptor file.

framework_lib/src/commandline/uefi.rs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ use crate::chromium_ec::commands::SetGpuSerialMagic;
1111
use crate::chromium_ec::{CrosEcDriverType, HardwareDeviceType};
1212
use crate::commandline::{Cli, LogLevel};
1313

14-
use super::{ConsoleArg, FpBrightnessArg, InputDeckModeArg, RebootEcArg, TabletModeArg};
14+
use super::{
15+
ConsoleArg, FpBrightnessArg, InputDeckModeArg, KbdDebugArg, PdDebugArg, RebootEcArg,
16+
TabletModeArg,
17+
};
1518

1619
/// Get commandline arguments from UEFI environment
1720
pub fn get_args() -> Vec<String> {
@@ -55,6 +58,8 @@ pub fn parse(args: &[String]) -> Cli {
5558
pd_reset: None,
5659
pd_disable: None,
5760
pd_enable: None,
61+
pd_debug: None,
62+
kbd_debug: None,
5863
dp_hdmi_info: false,
5964
dp_hdmi_update: None,
6065
audio_card_info: false,
@@ -662,6 +667,52 @@ pub fn parse(args: &[String]) -> Cli {
662667
None
663668
};
664669
found_an_option = true;
670+
} else if arg == "--pd-debug" {
671+
cli.pd_debug = if args.len() > i + 1 {
672+
let pd_debug_arg = &args[i + 1];
673+
if pd_debug_arg == "status" {
674+
Some(PdDebugArg::Status)
675+
} else if pd_debug_arg == "off" {
676+
Some(PdDebugArg::Off)
677+
} else if pd_debug_arg == "verbose" {
678+
Some(PdDebugArg::Verbose)
679+
} else if pd_debug_arg == "ucsi" {
680+
Some(PdDebugArg::Ucsi)
681+
} else if pd_debug_arg == "all" {
682+
Some(PdDebugArg::All)
683+
} else {
684+
println!(
685+
"Invalid value for --pd-debug: '{}'. Must be one of 'status', 'off', 'verbose', 'ucsi', 'all'.",
686+
pd_debug_arg
687+
);
688+
None
689+
}
690+
} else {
691+
println!("--pd-debug requires specifying the mode");
692+
None
693+
};
694+
found_an_option = true;
695+
} else if arg == "--kbd-debug" {
696+
cli.kbd_debug = if args.len() > i + 1 {
697+
let kbd_debug_arg = &args[i + 1];
698+
if kbd_debug_arg == "status" {
699+
Some(KbdDebugArg::Status)
700+
} else if kbd_debug_arg == "off" {
701+
Some(KbdDebugArg::Off)
702+
} else if kbd_debug_arg == "on" {
703+
Some(KbdDebugArg::On)
704+
} else {
705+
println!(
706+
"Invalid value for --kbd-debug: '{}'. Must be one of 'status', 'off', 'on'.",
707+
kbd_debug_arg
708+
);
709+
None
710+
}
711+
} else {
712+
println!("--kbd-debug requires specifying the mode");
713+
None
714+
};
715+
found_an_option = true;
665716
} else if arg == "--privacy" {
666717
cli.privacy = true;
667718
found_an_option = true;

framework_tool/completions/bash/framework_tool

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ _framework_tool() {
2323

2424
case "${cmd}" in
2525
framework_tool)
26-
opts="-v -q -t -f -h --flash-gpu-descriptor --verbose --quiet --versions --version --features --esrt --device --compare-version --power --smartbattery --smartbattery-auth --thermal --thermalget --thermalset --sensors --fansetduty --fansetrpm --autofanctrl --pdports --pdports-chromebook --info --meinfo --pd-info --pd-reset --pd-disable --pd-enable --dp-hdmi-info --dp-hdmi-update --audio-card-info --privacy --pd-bin --ec-bin --capsule --dump --h2o-capsule --dump-ec-flash --flash-full-ec --flash-ec --flash-ro-ec --flash-rw-ec --intrusion --inputdeck --inputdeck-mode --expansion-bay --charge-limit --charge-current-limit --charge-rate-limit --get-gpio --fp-led-level --fp-brightness --kblight --remap-key --rgbkbd --ps2-enable --tablet-mode --touchscreen-enable --haptic-intensity --click-force --stylus-battery --console --reboot-ec --ec-hib-delay --sysinfo --uptimeinfo --s0ix-counter --hello --protoinfo --switches --port80read --panicinfo --hash --driver --pd-addrs --pd-ports --test --test-retimer --boardid --force --dry-run --flash-gpu-descriptor-file --dump-gpu-descriptor-file --validate-gpu-descriptor-file --nvidia --host-command --generate-completions --generate-manpage --help"
26+
opts="-v -q -t -f -h --flash-gpu-descriptor --verbose --quiet --versions --version --features --esrt --device --compare-version --power --smartbattery --smartbattery-auth --thermal --thermalget --thermalset --sensors --fansetduty --fansetrpm --autofanctrl --pdports --pdports-chromebook --info --meinfo --pd-info --pd-reset --pd-disable --pd-enable --pd-debug --kbd-debug --dp-hdmi-info --dp-hdmi-update --audio-card-info --privacy --pd-bin --ec-bin --capsule --dump --h2o-capsule --dump-ec-flash --flash-full-ec --flash-ec --flash-ro-ec --flash-rw-ec --intrusion --inputdeck --inputdeck-mode --expansion-bay --charge-limit --charge-current-limit --charge-rate-limit --get-gpio --fp-led-level --fp-brightness --kblight --remap-key --rgbkbd --ps2-enable --tablet-mode --touchscreen-enable --haptic-intensity --click-force --stylus-battery --console --reboot-ec --ec-hib-delay --sysinfo --uptimeinfo --s0ix-counter --hello --protoinfo --switches --port80read --panicinfo --hash --driver --pd-addrs --pd-ports --test --test-retimer --boardid --force --dry-run --flash-gpu-descriptor-file --dump-gpu-descriptor-file --validate-gpu-descriptor-file --nvidia --host-command --generate-completions --generate-manpage --help"
2727
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
2828
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
2929
return 0
@@ -77,6 +77,14 @@ _framework_tool() {
7777
COMPREPLY=($(compgen -f "${cur}"))
7878
return 0
7979
;;
80+
--pd-debug)
81+
COMPREPLY=($(compgen -W "status off verbose ucsi all" -- "${cur}"))
82+
return 0
83+
;;
84+
--kbd-debug)
85+
COMPREPLY=($(compgen -W "status off on" -- "${cur}"))
86+
return 0
87+
;;
8088
--dp-hdmi-update)
8189
COMPREPLY=($(compgen -f "${cur}"))
8290
return 0

framework_tool/completions/fish/framework_tool.fish

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ complete -c framework_tool -l meinfo -d 'Show Intel ME information (from SMBIOS
1717
complete -c framework_tool -l pd-reset -d 'Reset a specific PD controller (for debugging only)' -r
1818
complete -c framework_tool -l pd-disable -d 'Disable all ports on a specific PD controller (for debugging only)' -r
1919
complete -c framework_tool -l pd-enable -d 'Enable all ports on a specific PD controller (for debugging only)' -r
20+
complete -c framework_tool -l pd-debug -d 'Get or set PD debug logging, read the output via --console' -r -f -a "status\t''
21+
off\t''
22+
verbose\t''
23+
ucsi\t''
24+
all\t''"
25+
complete -c framework_tool -l kbd-debug -d 'Get or set keyboard controller debug logging, read the output via --console' -r -f -a "status\t''
26+
off\t''
27+
on\t''"
2028
complete -c framework_tool -l dp-hdmi-update -d 'Update the DisplayPort or HDMI Expansion Card' -r -F
2129
complete -c framework_tool -l pd-bin -d 'Parse versions from PD firmware binary file' -r -F
2230
complete -c framework_tool -l ec-bin -d 'Parse versions from EC firmware binary file' -r -F

framework_tool/completions/zsh/_framework_tool

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ _framework_tool() {
2727
'--pd-reset=[Reset a specific PD controller (for debugging only)]:PD_RESET:_default' \
2828
'--pd-disable=[Disable all ports on a specific PD controller (for debugging only)]:PD_DISABLE:_default' \
2929
'--pd-enable=[Enable all ports on a specific PD controller (for debugging only)]:PD_ENABLE:_default' \
30+
'--pd-debug=[Get or set PD debug logging, read the output via --console]:PD_DEBUG:(status off verbose ucsi all)' \
31+
'--kbd-debug=[Get or set keyboard controller debug logging, read the output via --console]:KBD_DEBUG:(status off on)' \
3032
'--dp-hdmi-update=[Update the DisplayPort or HDMI Expansion Card]:UPDATE_BIN:_files' \
3133
'--pd-bin=[Parse versions from PD firmware binary file]:PD_BIN:_files' \
3234
'--ec-bin=[Parse versions from EC firmware binary file]:EC_BIN:_files' \

0 commit comments

Comments
 (0)