diff --git a/xhcid/Cargo.toml b/xhcid/Cargo.toml new file mode 100644 index 0000000000..f411d57c42 --- /dev/null +++ b/xhcid/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "xhcid" +version = "0.1.0" + +[dependencies] +bitflags = "*" +spin = "*" +redox_syscall = { git = "https://github.com/redox-os/syscall.git" } diff --git a/xhcid/src/main.rs b/xhcid/src/main.rs new file mode 100644 index 0000000000..fb94771704 --- /dev/null +++ b/xhcid/src/main.rs @@ -0,0 +1,80 @@ +extern crate syscall; + +use std::{env, slice}; +use syscall::io::{Mmio, Io}; + +#[repr(packed)] +pub struct XhciCap { + len: Mmio, + _rsvd: Mmio, + hci_ver: Mmio, + hcs_params1: Mmio, + hcs_params2: Mmio, + hcs_params3: Mmio, + hcc_params1: Mmio, + db_offset: Mmio, + rts_offset: Mmio, + hcc_params2: Mmio +} + +#[repr(packed)] +pub struct XhciOp { + usb_cmd: Mmio, + usb_std: Mmio, + page_size: Mmio, + _rsvd: [Mmio; 2], + dn_ctrl: Mmio, + crcr: [Mmio; 2], + _rsvd2: [Mmio; 4], + dcbaap: [Mmio; 2], + config: Mmio, +} + +pub struct Xhci { + cap: &'static mut XhciCap, + op: &'static mut XhciOp, + ports: &'static mut [Mmio] +} + +impl Xhci { + pub fn new(address: usize) -> Xhci { + let cap = unsafe { &mut *(address as *mut XhciCap) }; + + let op_base = address + cap.len.read() as usize; + let op = unsafe { &mut *(op_base as *mut XhciOp) }; + + let port_base = op_base + 0x400; + let port_len = ((cap.hcs_params1.read() & 0xFF000000) >> 24) as usize; + let ports = unsafe { slice::from_raw_parts_mut(port_base as *mut Mmio, port_len) }; + + Xhci { + cap: cap, + op: op, + ports: ports + } + } +} + +fn main() { + let mut args = env::args().skip(1); + + let mut name = args.next().expect("xhcid: no name provided"); + name.push_str("_xhci"); + + let bar_str = args.next().expect("xhcid: no address provided"); + let bar = usize::from_str_radix(&bar_str, 16).expect("xhcid: failed to parse address"); + + print!("{}", format!(" + XHCI {} on: {:X}\n", name, bar)); + + // Daemonize + if unsafe { syscall::clone(0).unwrap() } == 0 { + let address = unsafe { syscall::physmap(bar, 4096, syscall::MAP_WRITE).expect("xhcid: failed to map address") }; + { + let mut xhci = Xhci::new(address); + for (i, port) in xhci.ports.iter().enumerate() { + println!("XHCI Port {}: {:X}", i, port.read()); + } + } + unsafe { let _ = syscall::physunmap(address); } + } +}