diff --git a/crosec/src/wait_event/event.rs b/crosec/src/wait_event/event.rs index 7d197ed..3708273 100644 --- a/crosec/src/wait_event/event.rs +++ b/crosec/src/wait_event/event.rs @@ -1,12 +1,14 @@ +use async_std::io::ReadExt; use std::io; use std::mem::size_of; -use async_std::io::ReadExt; use bytemuck::{from_bytes, Pod, Zeroable}; use num_derive::FromPrimitive; use crate::wait_event::fingerprint::EcMkbpEventFingerprint; +use super::host_event::EcMkbpEventHostEvent; + #[derive(Debug, Clone, Copy, Pod, Zeroable)] #[repr(C, packed)] pub struct EcResponseMotionSenseFifoInfo { @@ -21,7 +23,7 @@ pub struct EcResponseMotionSenseFifoInfo { #[repr(u8)] pub enum EcMkbpEvent { KeyMatrix([u8; 13]), - HostEvent(u32), + HostEvent(EcMkbpEventHostEvent), HostEvent64(u64), SensorFifo(EcResponseMotionSenseFifoInfo), Buttons(u32), @@ -74,6 +76,9 @@ impl EcMkbpEventType { EcMkbpEventType::Fingerprint => { EcMkbpEvent::Fingerprint(from_bytes::(&data).to_owned()) } + EcMkbpEventType::HostEvent => { + EcMkbpEvent::HostEvent(from_bytes::(&data).to_owned()) + } event_type => panic!("{event_type:#?} from_bytes not implemented yet"), } } @@ -84,7 +89,10 @@ impl EcMkbpEventType { Ok(self.parse_event(&mut event)) } - pub(crate) async fn read_async(&self, stream: &mut T) -> io::Result { + pub(crate) async fn read_async( + &self, + stream: &mut T, + ) -> io::Result { let mut event = vec![Default::default(); size_of::() + self.data_size()]; stream.read_exact(&mut event).await?; Ok(self.parse_event(&mut event)) diff --git a/crosec/src/wait_event/host_event.rs b/crosec/src/wait_event/host_event.rs new file mode 100644 index 0000000..051588e --- /dev/null +++ b/crosec/src/wait_event/host_event.rs @@ -0,0 +1,94 @@ +use std::fmt::Debug; + +use bytemuck::{Pod, Zeroable}; +use num::FromPrimitive; +use num_derive::FromPrimitive; +use strum_macros::IntoStaticStr; + +/// Host event codes. ACPI query EC command uses code 0 to mean "no event +/// pending". We explicitly specify each value in the enum listing so they won't +/// change if we delete/insert an item or rearrange the list (it needs to be +/// stable across platforms, not just within a single compiled instance). +#[repr(u32)] +#[derive(FromPrimitive, IntoStaticStr, Debug)] +pub enum HostEventCode { + None = 0, + LidClosed = 1 << 0, + LidOpen = 1 << 1, + PowerButton = 1 << 2, + AcConnected = 1 << 3, + AcDisconnected = 1 << 4, + BatteryLow = 1 << 5, + BatteryCritical = 1 << 6, + Battery = 1 << 7, + ThermalThreshold = 1 << 8, + /// Event generated by a device attached to the EC + Device = 1 << 9, + Thermal = 1 << 10, + /// GPU related event. Formerly named EC_HOST_EVENT_USB_CHARGER. + Gpu = 1 << 11, + KeyPressed = 1 << 12, + /// EC has finished initializing the host interface. The host can check + /// for this event following sending a EC_CMD_REBOOT_EC command to + /// determine when the EC is ready to accept subsequent commands. + InterfaceReady = 1 << 13, + /// Keyboard recovery combo has been pressed + KeyboardRecovery = 1 << 14, + /// Shutdown due to thermal overload + ThermalShutdown = 1 << 15, + /// Shutdown due to battery level too low + BatteryShutdown = 1 << 16, + /// Suggest that the AP throttle itself + ThrottleStart = 1 << 17, + /// Suggest that the AP resume normal speed + ThrottleStop = 1 << 18, + /// Hang detect logic detected a hang and host event timeout expired + HangDetect = 1 << 19, + /// Hang detect logic detected a hang and warm rebooted the AP + HangReboot = 1 << 20, + /// PD MCU triggering host event + PdMcu = 1 << 21, + /// Battery Status flags have changed + BatteryStatus = 1 << 22, + /// EC encountered a panic, triggering a reset + Panic = 1 << 23, + /// Keyboard fastboot combo has been pressed + KeyboardFastboot = 1 << 24, + /// EC RTC event occurred + Rtc = 1 << 25, + /// Emulate MKBP event + Mkbp = 1 << 26, + /// EC desires to change state of host-controlled USB mux + UsbMux = 1 << 27, + /// The device has changed "modes". This can be one of the following: + /// - TABLET/LAPTOP mode + /// - detachable base attach/detach event + ModeChange = 1 << 28, + /// Keyboard recovery combo with hardware reinitialization + KeyboardRecoveryHwReinit = 1 << 29, + /// WoV + Wov = 1 << 30, + /// The high bit of the event mask is not used as a host event code. If + /// it reads back as set, then the entire event mask should be considered + /// invalid by the host. This can happen when reading the raw event status + /// via EC_MEMMAP_HOST_EVENTS but the LPC interface is not initialized on + /// the EC, or improperly configured on the host. + Invalid = 1 << 31, +} + +#[derive(Pod, Zeroable, Clone, Copy)] +#[repr(C)] +pub struct EcMkbpEventHostEvent { + host_event: u32, +} +impl EcMkbpEventHostEvent { + /// Try getting the host event code enum. If it for some reason is something else, that's an error. + pub fn rust(self) -> Result { + HostEventCode::from_u32(self.host_event).ok_or(self.host_event) + } +} +impl Debug for EcMkbpEventHostEvent { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.rust().fmt(f) + } +} diff --git a/crosec/src/wait_event/mod.rs b/crosec/src/wait_event/mod.rs index faca0f9..cf027d9 100644 --- a/crosec/src/wait_event/mod.rs +++ b/crosec/src/wait_event/mod.rs @@ -12,6 +12,7 @@ use crate::CROS_EC_IOC_MAGIC; pub mod event; pub mod fingerprint; +pub mod host_event; const POLL_IN: i16 = 0x001; diff --git a/ectool/src/main.rs b/ectool/src/main.rs index b123a8d..9615699 100644 --- a/ectool/src/main.rs +++ b/ectool/src/main.rs @@ -14,6 +14,7 @@ use fp_download_subcommand::{fp_download_subcommand, FpDownloadSubcommand}; use fp_upload_template_command::fp_upload_template_command; use num_traits::cast::FromPrimitive; +use crate::fp_get_encryption_status_command::fp_get_encryption_status_command; use crosec::battery::battery; use crosec::commands::board_version::ec_cmd_board_version; use crosec::commands::get_cmd_versions::ec_cmd_get_cmd_versions; @@ -29,13 +30,12 @@ use crosec::{ CROS_EC_PATH, CROS_FP_PATH, EC_FAN_SPEED_ENTRIES, EC_FAN_SPEED_NOT_PRESENT, EC_FAN_SPEED_STALLED, EC_MEM_MAP_FAN, }; -use crate::fp_get_encryption_status_command::fp_get_encryption_status_command; mod charge_control_subcommand; mod check_seed; mod fp_download_subcommand; -mod fp_upload_template_command; mod fp_get_encryption_status_command; +mod fp_upload_template_command; #[derive(Parser)] #[command(version, about)] @@ -266,6 +266,7 @@ fn main() -> Result<()> { timeout, } => { let mut file = File::open(device.unwrap_or_default().get_path())?; + println!("Waiting for event..."); let result = wait_event_sync(&mut file, event_type, timeout).unwrap(); println!("{result:#?}"); }