Set some more registers
This commit is contained in:
parent
e9c540b777
commit
8b0aabaf10
17
src/buffers.rs
Normal file
17
src/buffers.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(Debug, Copy, Clone, Default)]
|
||||||
|
pub struct PhysicalAddress(u64);
|
||||||
|
|
||||||
|
/// Device Context Base Address Array
|
||||||
|
/// TODO: make more page size independent
|
||||||
|
/// Align to a page because it shouldn't cross a page and needs to be
|
||||||
|
/// 64-byte aligned anyway
|
||||||
|
#[repr(C, align(4096))]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DCBAA([PhysicalAddress; 256]);
|
||||||
|
|
||||||
|
impl Default for DCBAA {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self([PhysicalAddress::default(); 256])
|
||||||
|
}
|
||||||
|
}
|
55
src/main.rs
55
src/main.rs
|
@ -1,7 +1,9 @@
|
||||||
|
mod buffers;
|
||||||
mod pci;
|
mod pci;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use buffers::DCBAA;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use pci_driver::{backends::vfio::VfioPciDevice, device::PciDevice};
|
use pci_driver::{backends::vfio::VfioPciDevice, device::PciDevice};
|
||||||
|
|
||||||
|
@ -10,10 +12,6 @@ struct Args {
|
||||||
/// Path of the PCIe device, e.g. /sys/bus/pci/devices/0000:02:00.0
|
/// Path of the PCIe device, e.g. /sys/bus/pci/devices/0000:02:00.0
|
||||||
#[arg(short = 'd', long)]
|
#[arg(short = 'd', long)]
|
||||||
device: std::path::PathBuf,
|
device: std::path::PathBuf,
|
||||||
|
|
||||||
/// Attempt to reset the device with sysfs
|
|
||||||
#[arg(short = 'r', long)]
|
|
||||||
reset: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> eyre::Result<()> {
|
fn main() -> eyre::Result<()> {
|
||||||
|
@ -22,16 +20,61 @@ fn main() -> eyre::Result<()> {
|
||||||
|
|
||||||
let device = Arc::new(VfioPciDevice::open(&args.device)?);
|
let device = Arc::new(VfioPciDevice::open(&args.device)?);
|
||||||
|
|
||||||
if args.reset {
|
|
||||||
device.reset()?;
|
device.reset()?;
|
||||||
|
|
||||||
|
if device.iommu().alignment() != 4096 {
|
||||||
|
todo!("Support non-4K page size")
|
||||||
}
|
}
|
||||||
|
|
||||||
let registers = crate::pci::load_registers(device)?;
|
let mut registers = crate::pci::load_registers(device.clone())?;
|
||||||
|
|
||||||
log::info!(
|
log::info!(
|
||||||
"xHCI version: {:04x}",
|
"xHCI version: {:04x}",
|
||||||
registers.capability.hciversion.read_volatile().get()
|
registers.capability.hciversion.read_volatile().get()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
while registers
|
||||||
|
.operational
|
||||||
|
.usbsts
|
||||||
|
.read_volatile()
|
||||||
|
.controller_not_ready()
|
||||||
|
{
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
let device_slots = registers
|
||||||
|
.capability
|
||||||
|
.hcsparams1
|
||||||
|
.read_volatile()
|
||||||
|
.number_of_device_slots();
|
||||||
|
log::debug!("Controller supports {} device slots", device_slots);
|
||||||
|
registers.operational.config.update_volatile(|reg| {
|
||||||
|
reg.set_max_device_slots_enabled(device_slots);
|
||||||
|
});
|
||||||
|
|
||||||
|
let dcbaa = DCBAA::default();
|
||||||
|
|
||||||
|
log::trace!(
|
||||||
|
"valid_iova_ranges: {:#x?}",
|
||||||
|
device.iommu().valid_iova_ranges()
|
||||||
|
);
|
||||||
|
log::trace!("max_num_mappings: {}", device.iommu().max_num_mappings());
|
||||||
|
|
||||||
|
let dcbaa_physaddr = 0x1000u64;
|
||||||
|
// TODO: Actually deal with valid iova ranges
|
||||||
|
unsafe {
|
||||||
|
device.iommu().map(
|
||||||
|
dcbaa_physaddr,
|
||||||
|
std::mem::size_of::<DCBAA>(),
|
||||||
|
&dcbaa as *const DCBAA as *const u8,
|
||||||
|
pci_driver::regions::Permissions::Read,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
registers
|
||||||
|
.operational
|
||||||
|
.dcbaap
|
||||||
|
.update_volatile(|reg| reg.set(dcbaa_physaddr));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue