From 854149ee977a71003ed14bc934d7d46b465dcda6 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 19 Jul 2020 10:24:15 -0600 Subject: [PATCH] Support for debugging to system76 EC --- Cargo.toml | 1 + src/arch/x86_64/debug.rs | 13 ++++ src/arch/x86_64/device/mod.rs | 2 + src/arch/x86_64/device/system76_ec.rs | 91 +++++++++++++++++++++++++++ src/arch/x86_64/start.rs | 3 + 5 files changed, 110 insertions(+) create mode 100644 src/arch/x86_64/device/system76_ec.rs diff --git a/Cargo.toml b/Cargo.toml index d38edb7..21bf399 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,4 +42,5 @@ multi_core = ["acpi"] pti = [] qemu_debug = [] serial_debug = [] +system76_ec_debug = [] slab = ["slab_allocator"] diff --git a/src/arch/x86_64/debug.rs b/src/arch/x86_64/debug.rs index c2dd73a..70f79db 100644 --- a/src/arch/x86_64/debug.rs +++ b/src/arch/x86_64/debug.rs @@ -19,6 +19,8 @@ use super::graphical_debug::{DEBUG_DISPLAY, DebugDisplay}; use super::device::serial::LPSS; #[cfg(feature = "serial_debug")] use super::device::serial::COM1; +#[cfg(feature = "system76_ec_debug")] +use super::device::system76_ec::{SYSTEM76_EC, System76Ec}; #[cfg(feature = "qemu_debug")] pub static QEMU: Mutex> = Mutex::new(Pio::::new(0x402)); @@ -33,6 +35,8 @@ pub struct Writer<'a> { qemu: MutexGuard<'a, Pio>, #[cfg(feature = "serial_debug")] serial: MutexGuard<'a, SerialPort>>, + #[cfg(feature = "system76_ec_debug")] + system76_ec: MutexGuard<'a, Option>, } impl<'a> Writer<'a> { @@ -47,6 +51,8 @@ impl<'a> Writer<'a> { qemu: QEMU.lock(), #[cfg(feature = "serial_debug")] serial: COM1.lock(), + #[cfg(feature = "system76_ec_debug")] + system76_ec: SYSTEM76_EC.lock(), } } @@ -82,6 +88,13 @@ impl<'a> Writer<'a> { { self.serial.write(buf); } + + #[cfg(feature = "system76_ec_debug")] + { + if let Some(ref mut system76_ec) = *self.system76_ec { + system76_ec.print_slice(buf); + } + } } } diff --git a/src/arch/x86_64/device/mod.rs b/src/arch/x86_64/device/mod.rs index 9460f65..e5e8601 100644 --- a/src/arch/x86_64/device/mod.rs +++ b/src/arch/x86_64/device/mod.rs @@ -9,6 +9,8 @@ pub mod rtc; pub mod serial; #[cfg(feature = "acpi")] pub mod hpet; +#[cfg(feature = "system76_ec_debug")] +pub mod system76_ec; pub unsafe fn init(active_table: &mut ActivePageTable) { pic::init(); diff --git a/src/arch/x86_64/device/system76_ec.rs b/src/arch/x86_64/device/system76_ec.rs new file mode 100644 index 0000000..49f3a29 --- /dev/null +++ b/src/arch/x86_64/device/system76_ec.rs @@ -0,0 +1,91 @@ +use spin::Mutex; +use syscall::io::{Io, Pio}; + +pub static SYSTEM76_EC: Mutex> = Mutex::new(None); + +pub fn init() { + *SYSTEM76_EC.lock() = System76Ec::new(); +} + +pub struct System76Ec { + base: u16, +} + +impl System76Ec { + pub fn new() -> Option { + let mut system76_ec = Self { + base: 0x0E00, + }; + if system76_ec.probe() { + Some(system76_ec) + } else { + None + } + } + + #[inline(always)] + pub fn read(&mut self, addr: u8) -> u8 { + Pio::::new(self.base + addr as u16).read() + } + + #[inline(always)] + pub fn write(&mut self, addr: u8, data: u8) { + Pio::::new(self.base + addr as u16).write(data) + } + + pub fn probe(&mut self) -> bool { + // Send probe command + self.write(0, 1); + + // Wait for response + let mut timeout = 1_000_000; + while timeout > 0 { + if self.read(0) == 0 { + break; + } + timeout -= 1; + } + if timeout == 0 { + return false; + } + + // Return false on command error + if self.read(1) != 0 { + return false; + } + + // Must receive 0x76, 0xEC as signature + self.read(2) == 0x76 && self.read(3) == 0xEC + } + + pub fn flush(&mut self) { + // Send command + self.write(0, 4); + + // TODO: timeout + while self.read(0) != 0 {} + + // Clear length + self.write(3, 0); + } + + pub fn print(&mut self, byte: u8) { + // Read length + let len = self.read(3); + // Write data at offset + self.write(len + 4, byte); + // Update length + self.write(3, len + 1); + + // If we hit the end of the buffer, or were given a newline, flush + if byte == b'\n' || len >= 128 { + self.flush(); + } + } + + pub fn print_slice(&mut self, bytes: &[u8]) { + for &byte in bytes { + self.print(byte); + } + } +} diff --git a/src/arch/x86_64/start.rs b/src/arch/x86_64/start.rs index 7cdec3d..5829943 100644 --- a/src/arch/x86_64/start.rs +++ b/src/arch/x86_64/start.rs @@ -141,6 +141,9 @@ pub unsafe extern fn kstart(args_ptr: *const KernelArgs) -> ! { #[cfg(feature="graphical_debug")] graphical_debug::init(&mut active_table); + #[cfg(feature = "system76_ec_debug")] + device::system76_ec::init(); + // Initialize devices device::init(&mut active_table);