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])
|
||||
}
|
||||
}
|
57
src/main.rs
57
src/main.rs
|
@ -1,7 +1,9 @@
|
|||
mod buffers;
|
||||
mod pci;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use buffers::DCBAA;
|
||||
use clap::Parser;
|
||||
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
|
||||
#[arg(short = 'd', long)]
|
||||
device: std::path::PathBuf,
|
||||
|
||||
/// Attempt to reset the device with sysfs
|
||||
#[arg(short = 'r', long)]
|
||||
reset: bool,
|
||||
}
|
||||
|
||||
fn main() -> eyre::Result<()> {
|
||||
|
@ -22,16 +20,61 @@ fn main() -> eyre::Result<()> {
|
|||
|
||||
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!(
|
||||
"xHCI version: {:04x}",
|
||||
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(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue