Support for debugging to system76 EC

This commit is contained in:
Jeremy Soller
2020-07-19 10:24:15 -06:00
parent 615e516585
commit 854149ee97
5 changed files with 110 additions and 0 deletions

View File

@@ -42,4 +42,5 @@ multi_core = ["acpi"]
pti = []
qemu_debug = []
serial_debug = []
system76_ec_debug = []
slab = ["slab_allocator"]

View File

@@ -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<Pio<u8>> = Mutex::new(Pio::<u8>::new(0x402));
@@ -33,6 +35,8 @@ pub struct Writer<'a> {
qemu: MutexGuard<'a, Pio<u8>>,
#[cfg(feature = "serial_debug")]
serial: MutexGuard<'a, SerialPort<Pio<u8>>>,
#[cfg(feature = "system76_ec_debug")]
system76_ec: MutexGuard<'a, Option<System76Ec>>,
}
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);
}
}
}
}

View File

@@ -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();

View File

@@ -0,0 +1,91 @@
use spin::Mutex;
use syscall::io::{Io, Pio};
pub static SYSTEM76_EC: Mutex<Option<System76Ec>> = Mutex::new(None);
pub fn init() {
*SYSTEM76_EC.lock() = System76Ec::new();
}
pub struct System76Ec {
base: u16,
}
impl System76Ec {
pub fn new() -> Option<Self> {
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::<u8>::new(self.base + addr as u16).read()
}
#[inline(always)]
pub fn write(&mut self, addr: u8, data: u8) {
Pio::<u8>::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);
}
}
}

View File

@@ -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);