xhci: WIP grab device information
This commit is contained in:
+6
-2
@@ -25,13 +25,17 @@ fn main() {
|
||||
|
||||
match Xhci::new(address) {
|
||||
Ok(mut xhci) => {
|
||||
xhci.probe();
|
||||
if let Err(err) = xhci.probe() {
|
||||
println!("xhcid: probe error: {}", err);
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
println!("xhcid: error: {}", err);
|
||||
println!("xhcid: open error: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe { let _ = syscall::physunmap(address); }
|
||||
|
||||
let _ = syscall::kill(1, syscall::SIGINT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,19 +5,43 @@ use super::event::EventRing;
|
||||
use super::trb::Trb;
|
||||
|
||||
pub struct CommandRing {
|
||||
pub trbs: Dma<[Trb; 256]>,
|
||||
trbs: Dma<[Trb; 256]>,
|
||||
cmd_i: usize,
|
||||
pub events: EventRing,
|
||||
event_i: usize,
|
||||
}
|
||||
|
||||
impl CommandRing {
|
||||
pub fn new() -> Result<CommandRing> {
|
||||
Ok(CommandRing {
|
||||
trbs: Dma::zeroed()?,
|
||||
cmd_i: 0,
|
||||
events: EventRing::new()?,
|
||||
event_i: 0,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn crcr(&self) -> u64 {
|
||||
self.trbs.physical() as u64 | 1
|
||||
}
|
||||
|
||||
pub fn next_cmd(&mut self) -> &mut Trb {
|
||||
let i = self.cmd_i;
|
||||
self.cmd_i += 1;
|
||||
if self.cmd_i >= self.trbs.len() {
|
||||
self.cmd_i = 0;
|
||||
}
|
||||
|
||||
&mut self.trbs[i]
|
||||
}
|
||||
|
||||
pub fn next_event(&mut self) -> &mut Trb {
|
||||
let i = self.event_i;
|
||||
self.event_i += 1;
|
||||
if self.event_i >= self.events.trbs.len() {
|
||||
self.event_i = 0;
|
||||
}
|
||||
|
||||
&mut self.events.trbs[i]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,21 @@ use syscall::io::{Dma, Mmio};
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct SlotContext {
|
||||
inner: [u8; 32]
|
||||
pub a: Mmio<u32>,
|
||||
pub b: Mmio<u32>,
|
||||
pub c: Mmio<u32>,
|
||||
pub d: Mmio<u32>,
|
||||
_rsvd: [Mmio<u32>; 4],
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct EndpointContext {
|
||||
inner: [u8; 32]
|
||||
pub a: Mmio<u32>,
|
||||
pub b: Mmio<u32>,
|
||||
pub trl: Mmio<u32>,
|
||||
pub trh: Mmio<u32>,
|
||||
pub c: Mmio<u32>,
|
||||
_rsvd: [Mmio<u32>; 3],
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
|
||||
+78
-24
@@ -1,6 +1,6 @@
|
||||
use std::slice;
|
||||
use syscall::error::Result;
|
||||
use syscall::io::Io;
|
||||
use syscall::io::{Dma, Io};
|
||||
|
||||
mod capability;
|
||||
mod command;
|
||||
@@ -59,6 +59,12 @@ impl Xhci {
|
||||
println!(" - Waiting for XHCI stopped");
|
||||
}
|
||||
|
||||
println!(" - Reset");
|
||||
op.usb_cmd.writef(1 << 1, true);
|
||||
while op.usb_sts.readf(1 << 1) {
|
||||
println!(" - Waiting for XHCI reset");
|
||||
}
|
||||
|
||||
println!(" - Read max slots");
|
||||
// Read maximum slots and ports
|
||||
let hcs_params1 = cap.hcs_params1.read();
|
||||
@@ -111,10 +117,10 @@ impl Xhci {
|
||||
|
||||
// Set event ring segment table registers
|
||||
println!(" - Interrupter 0: {:X}", self.run.ints.as_ptr() as usize);
|
||||
println!(" - Write ERDP");
|
||||
self.run.ints[0].erdp.write(self.cmd.events.trbs.physical() as u64);
|
||||
println!(" - Write ERSTZ");
|
||||
self.run.ints[0].erstsz.write(1);
|
||||
println!(" - Write ERDP");
|
||||
self.run.ints[0].erdp.write(self.cmd.events.trbs.physical() as u64);
|
||||
println!(" - Write ERSTBA: {:X}", self.cmd.events.ste.physical() as u64);
|
||||
self.run.ints[0].erstba.write(self.cmd.events.ste.physical() as u64);
|
||||
|
||||
@@ -135,34 +141,82 @@ impl Xhci {
|
||||
println!(" - XHCI initialized");
|
||||
}
|
||||
|
||||
pub fn probe(&mut self) {
|
||||
pub fn probe(&mut self) -> Result<()> {
|
||||
for (i, port) in self.ports.iter().enumerate() {
|
||||
let data = port.read();
|
||||
let state = port.state();
|
||||
let speed = port.speed();
|
||||
let flags = port.flags();
|
||||
println!(" + XHCI Port {}: {:X}, State {}, Speed {}, Flags {:?}", i, data, state, speed, flags);
|
||||
|
||||
if flags.contains(port::PORT_CCS) {
|
||||
println!(" - Running Enable Slot command");
|
||||
|
||||
let db = &mut self.dbs[0];
|
||||
let crcr = &mut self.op.crcr;
|
||||
let mut run = || {
|
||||
db.write(0);
|
||||
while crcr.readf(1 << 3) {
|
||||
println!(" - Waiting for command completion");
|
||||
}
|
||||
};
|
||||
|
||||
{
|
||||
let cmd = self.cmd.next_cmd();
|
||||
cmd.enable_slot(0, true);
|
||||
println!(" - Command: {}", cmd);
|
||||
|
||||
run();
|
||||
|
||||
cmd.reserved(false);
|
||||
}
|
||||
|
||||
let slot;
|
||||
{
|
||||
let event = self.cmd.next_event();
|
||||
println!(" - Response: {}", event);
|
||||
slot = (event.control.read() >> 24) as u8;
|
||||
|
||||
event.reserved(false);
|
||||
}
|
||||
|
||||
println!(" Slot {}", slot);
|
||||
|
||||
let mut trbs = Dma::<[trb::Trb; 256]>::zeroed()?;
|
||||
let mut input = Dma::<device::InputContext>::zeroed()?;
|
||||
{
|
||||
input.add_context.write(1 << 1 | 1);
|
||||
|
||||
input.device.slot.a.write(1 << 27);
|
||||
input.device.slot.b.write(((i as u32 + 1) & 0xFF) << 16);
|
||||
println!("{:>08X}", input.device.slot.b.read());
|
||||
|
||||
input.device.endpoints[0].b.write(4096 << 16 | 4 << 3 | 3 << 1);
|
||||
input.device.endpoints[0].trh.write((trbs.physical() >> 32) as u32);
|
||||
input.device.endpoints[0].trl.write(trbs.physical() as u32 | 1);
|
||||
}
|
||||
|
||||
{
|
||||
let cmd = self.cmd.next_cmd();
|
||||
cmd.address_device(slot, input.physical(), true);
|
||||
println!(" - Command: {}", cmd);
|
||||
|
||||
run();
|
||||
|
||||
cmd.reserved(false);
|
||||
}
|
||||
|
||||
let address;
|
||||
{
|
||||
let event = self.cmd.next_event();
|
||||
println!(" - Response: {}", event);
|
||||
address = (event.control.read() >> 24) as u8;
|
||||
|
||||
event.reserved(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!(" - Running Enable Slot command");
|
||||
|
||||
self.cmd.trbs[0].enable_slot(0, true);
|
||||
|
||||
println!(" - Command");
|
||||
println!(" - data: {:X}", self.cmd.trbs[0].data.read());
|
||||
println!(" - status: {:X}", self.cmd.trbs[0].status.read());
|
||||
println!(" - control: {:X}", self.cmd.trbs[0].control.read());
|
||||
|
||||
self.dbs[0].write(0);
|
||||
|
||||
println!(" - Wait for command completion");
|
||||
while self.op.crcr.readf(1 << 3) {
|
||||
println!(" - Waiting for command completion");
|
||||
}
|
||||
|
||||
println!(" - Response");
|
||||
println!(" - data: {:X}", self.cmd.events.trbs[0].data.read());
|
||||
println!(" - status: {:X}", self.cmd.events.trbs[0].status.read());
|
||||
println!(" - control: {:X}", self.cmd.events.trbs[0].control.read());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
+26
-4
@@ -1,3 +1,4 @@
|
||||
use std::fmt;
|
||||
use syscall::io::{Io, Mmio};
|
||||
|
||||
#[repr(u8)]
|
||||
@@ -101,11 +102,10 @@ pub struct Trb {
|
||||
}
|
||||
|
||||
impl Trb {
|
||||
pub fn reset(&mut self, param: u64, status: u32, control: u16, trb_type: TrbType, evaluate_next: bool, cycle: bool) {
|
||||
pub fn reset(&mut self, param: u64, status: u32, control: u16, trb_type: TrbType, cycle: bool) {
|
||||
let full_control =
|
||||
(control as u32) << 16 |
|
||||
((trb_type as u32) & 0x3F) << 10 |
|
||||
if evaluate_next { 1 << 1 } else { 0 } |
|
||||
if cycle { 1 << 0 } else { 0 };
|
||||
|
||||
self.data.write(param);
|
||||
@@ -113,11 +113,33 @@ impl Trb {
|
||||
self.control.write(full_control);
|
||||
}
|
||||
|
||||
pub fn reserved(&mut self, cycle: bool) {
|
||||
self.reset(0, 0, 0, TrbType::Reserved, cycle);
|
||||
}
|
||||
|
||||
pub fn no_op_cmd(&mut self, cycle: bool) {
|
||||
self.reset(0, 0, 0, TrbType::NoOpCmd, false, cycle);
|
||||
self.reset(0, 0, 0, TrbType::NoOpCmd, cycle);
|
||||
}
|
||||
|
||||
pub fn enable_slot(&mut self, slot_type: u8, cycle: bool) {
|
||||
self.reset(0, 0, (slot_type as u16) & 0x1F, TrbType::EnableSlot, false, cycle);
|
||||
self.reset(0, 0, (slot_type as u16) & 0x1F, TrbType::EnableSlot, cycle);
|
||||
}
|
||||
|
||||
pub fn address_device(&mut self, slot_id: u8, input: usize, cycle: bool) {
|
||||
self.reset(input as u64, 0, (slot_id as u16) << 8, TrbType::AddressDevice, cycle);
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Trb {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Trb {{ data: {:>016X}, status: {:>08X}, control: {:>08X} }}",
|
||||
self.data.read(), self.status.read(), self.control.read())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Trb {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "({:>016X}, {:>08X}, {:>08X})",
|
||||
self.data.read(), self.status.read(), self.control.read())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user