Commit b4209a6a authored by Jeremy Soller's avatar Jeremy Soller

Refactor XHCI driver

parent 14e1b556
#![feature(core_intrinsics)]
#[macro_use]
extern crate bitflags;
extern crate syscall;
......@@ -27,7 +25,7 @@ fn main() {
match Xhci::new(address) {
Ok(mut xhci) => {
xhci.init();
xhci.probe();
},
Err(err) => {
println!("xhcid: error: {}", err);
......
use syscall::io::Mmio;
#[repr(packed)]
pub struct CapabilityRegs {
pub len: Mmio<u8>,
_rsvd: Mmio<u8>,
pub hci_ver: Mmio<u16>,
pub hcs_params1: Mmio<u32>,
pub hcs_params2: Mmio<u32>,
pub hcs_params3: Mmio<u32>,
pub hcc_params1: Mmio<u32>,
pub db_offset: Mmio<u32>,
pub rts_offset: Mmio<u32>,
pub hcc_params2: Mmio<u32>
}
use syscall::error::Result;
use syscall::io::Dma;
use super::event::EventRing;
use super::trb::Trb;
pub struct CommandRing {
pub trbs: Dma<[Trb; 256]>,
pub events: EventRing,
}
impl CommandRing {
pub fn new() -> Result<CommandRing> {
Ok(CommandRing {
trbs: Dma::zeroed()?,
events: EventRing::new()?,
})
}
pub fn crcr(&self) -> u64 {
self.trbs.physical() as u64 | 1
}
}
use syscall::error::Result;
use syscall::io::Dma;
#[repr(packed)]
pub struct SlotContext {
inner: [u8; 32]
}
#[repr(packed)]
pub struct EndpointContext {
inner: [u8; 32]
}
#[repr(packed)]
pub struct DeviceContext {
pub slot: SlotContext,
pub endpoints: [EndpointContext; 15]
}
#[repr(packed)]
pub struct InputContext {
pub drop_context: Mmio<u32>,
pub add_context: Mmio<u32>,
_rsvd: [Mmio<u32>; 5],
pub control: Mmio<u32>,
pub device: DeviceContext,
}
pub struct DeviceList {
pub dcbaa: Dma<[u64; 256]>,
pub contexts: Vec<Dma<DeviceContext>>,
}
impl DeviceList {
pub fn new(max_slots: u8) -> Result<DeviceList> {
let mut dcbaa = Dma::<[u64; 256]>::zeroed()?;
let mut contexts = vec![];
// Create device context buffers for each slot
for i in 0..max_slots as usize {
println!(" - Setup dev ctx {}", i);
let context: Dma<DeviceContext> = Dma::zeroed()?;
dcbaa[i] = context.physical() as u64;
contexts.push(context);
}
Ok(DeviceList {
dcbaa: dcbaa,
contexts: contexts
})
}
pub fn dcbaap(&self) -> u64 {
self.dcbaa.physical() as u64
}
}
use syscall::io::{Io, Mmio};
#[repr(packed)]
pub struct Doorbell(Mmio<u32>);
impl Doorbell {
pub fn read(&self) -> u32 {
self.0.read()
}
pub fn write(&mut self, data: u32) {
self.0.write(data);
}
}
......@@ -3,6 +3,7 @@ use syscall::io::{Dma, Io, Mmio};
use super::trb::Trb;
#[repr(packed)]
pub struct EventRingSte {
pub address: Mmio<u64>,
pub size: Mmio<u16>,
......
This diff is collapsed.
use syscall::io::Mmio;
#[repr(packed)]
pub struct OperationalRegs {
pub usb_cmd: Mmio<u32>,
pub usb_sts: Mmio<u32>,
pub page_size: Mmio<u32>,
_rsvd: [Mmio<u32>; 2],
pub dn_ctrl: Mmio<u32>,
pub crcr: Mmio<u64>,
_rsvd2: [Mmio<u32>; 4],
pub dcbaap: Mmio<u64>,
pub config: Mmio<u32>,
}
use syscall::io::{Io, Mmio};
bitflags! {
pub flags PortFlags: u32 {
const PORT_CCS = 1 << 0,
const PORT_PED = 1 << 1,
const PORT_OCA = 1 << 3,
const PORT_PR = 1 << 4,
const PORT_PP = 1 << 9,
const PORT_PIC_AMB = 1 << 14,
const PORT_PIC_GRN = 1 << 15,
const PORT_LWS = 1 << 16,
const PORT_CSC = 1 << 17,
const PORT_PEC = 1 << 18,
const PORT_WRC = 1 << 19,
const PORT_OCC = 1 << 20,
const PORT_PRC = 1 << 21,
const PORT_PLC = 1 << 22,
const PORT_CEC = 1 << 23,
const PORT_CAS = 1 << 24,
const PORT_WCE = 1 << 25,
const PORT_WDE = 1 << 26,
const PORT_WOE = 1 << 27,
const PORT_DR = 1 << 30,
const PORT_WPR = 1 << 31,
}
}
#[repr(packed)]
pub struct Port {
pub portsc : Mmio<u32>,
pub portpmsc : Mmio<u32>,
pub portli : Mmio<u32>,
pub porthlpmc : Mmio<u32>,
}
impl Port {
pub fn read(&self) -> u32 {
self.portsc.read()
}
pub fn state(&self) -> u32 {
(self.read() & (0b1111 << 5)) >> 5
}
pub fn speed(&self) -> u32 {
(self.read() & (0b1111 << 10)) >> 10
}
pub fn flags(&self) -> PortFlags {
PortFlags::from_bits_truncate(self.read())
}
}
use syscall::io::Mmio;
#[repr(packed)]
pub struct Interrupter {
pub iman: Mmio<u32>,
pub imod: Mmio<u32>,
pub erstsz: Mmio<u32>,
_rsvd: Mmio<u32>,
pub erstba: Mmio<u64>,
pub erdp: Mmio<u64>,
}
#[repr(packed)]
pub struct RuntimeRegs {
pub mfindex: Mmio<u32>,
_rsvd: [Mmio<u32>; 7],
pub ints: [Interrupter; 1024],
}
use std::cell::RefCell;
use std::ops::{Deref, DerefMut};
use std::rc::Weak;
use syscall::error::{Error, Result, EBADF, EINVAL, EPIPE};
use syscall::flag::{F_GETFL, F_SETFL, O_ACCMODE};
use pty::Pty;
use resource::Resource;
/// Read side of a pipe
#[derive(Clone)]
pub struct PtyTermios {
pty: Weak<RefCell<Pty>>,
flags: usize,
}
impl PtyTermios {
pub fn new(pty: Weak<RefCell<Pty>>, flags: usize) -> Self {
PtyTermios {
pty: pty,
flags: flags,
}
}
}
impl Resource for PtyTermios {
fn boxed_clone(&self) -> Box<Resource> {
Box::new(self.clone())
}
fn pty(&self) -> Weak<RefCell<Pty>> {
self.pty.clone()
}
fn flags(&self) -> usize {
self.flags
}
fn path(&self, buf: &mut [u8]) -> Result<usize> {
if let Some(pty_lock) = self.pty.upgrade() {
pty_lock.borrow_mut().path(buf)
} else {
Err(Error::new(EPIPE))
}
}
fn read(&self, buf: &mut [u8]) -> Result<usize> {
if let Some(pty_lock) = self.pty.upgrade() {
let pty = pty_lock.borrow();
let termios: &[u8] = pty.termios.deref();
let mut i = 0;
while i < buf.len() && i < termios.len() {
buf[i] = termios[i];
i += 1;
}
Ok(i)
} else {
Ok(0)
}
}
fn write(&self, buf: &[u8]) -> Result<usize> {
if let Some(pty_lock) = self.pty.upgrade() {
let mut pty = pty_lock.borrow_mut();
let termios: &mut [u8] = pty.termios.deref_mut();
let mut i = 0;
while i < buf.len() && i < termios.len() {
termios[i] = buf[i];
i += 1;
}
Ok(i)
} else {
Err(Error::new(EPIPE))
}
}
fn sync(&self) -> Result<usize> {
Ok(0)
}
fn fcntl(&mut self, cmd: usize, arg: usize) -> Result<usize> {
match cmd {
F_GETFL => Ok(self.flags),
F_SETFL => {
self.flags = (self.flags & O_ACCMODE) | (arg & ! O_ACCMODE);
Ok(0)
},
_ => Err(Error::new(EINVAL))
}
}
fn fevent(&self) -> Result<()> {
Err(Error::new(EBADF))
}
fn fevent_count(&self) -> Option<usize> {
None
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment