Now have a so-called mapper
This commit is contained in:
parent
697c4bfdc2
commit
e9c540b777
56
Cargo.lock
generated
56
Cargo.lock
generated
|
@ -2,6 +2,12 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "accessor"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd8b2abd55bf1f9cffbf00fd594566c51a9d31402553284920c1309ca8351086"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
|
@ -66,6 +72,12 @@ version = "1.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "bit_field"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.9"
|
||||
|
@ -97,7 +109,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.71",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -196,6 +208,18 @@ dependencies = [
|
|||
"eyre",
|
||||
"log",
|
||||
"pci-driver",
|
||||
"xhci",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -213,6 +237,12 @@ version = "1.19.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "pci-driver"
|
||||
version = "0.1.4"
|
||||
|
@ -276,6 +306,17 @@ version = "0.11.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.71"
|
||||
|
@ -371,3 +412,16 @@ name = "windows_x86_64_msvc"
|
|||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "xhci"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09f3f0483969259f2adb6524054400d94ac352e59fa37da6c6ca3b9b3d83ff83"
|
||||
dependencies = [
|
||||
"accessor",
|
||||
"bit_field",
|
||||
"num-derive",
|
||||
"num-traits",
|
||||
"paste",
|
||||
]
|
||||
|
|
|
@ -9,3 +9,4 @@ env_logger = "0.11.3"
|
|||
eyre = "0.6.12"
|
||||
log = "0.4.22"
|
||||
pci-driver = "0.1.4"
|
||||
xhci = "0.9.2"
|
||||
|
|
23
src/main.rs
23
src/main.rs
|
@ -1,3 +1,7 @@
|
|||
mod pci;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use clap::Parser;
|
||||
use pci_driver::{backends::vfio::VfioPciDevice, device::PciDevice};
|
||||
|
||||
|
@ -16,28 +20,17 @@ fn main() -> eyre::Result<()> {
|
|||
env_logger::init();
|
||||
let args = Args::parse();
|
||||
|
||||
let device = VfioPciDevice::open(&args.device)?;
|
||||
let device = Arc::new(VfioPciDevice::open(&args.device)?);
|
||||
|
||||
if args.reset {
|
||||
device.reset()?;
|
||||
}
|
||||
|
||||
let config = device.config();
|
||||
// This library got the order backwards...
|
||||
let class = (
|
||||
config.class_code().programming_interface().read()?,
|
||||
config.class_code().sub_class_code().read()?,
|
||||
config.class_code().base_class_code().read()?,
|
||||
);
|
||||
println!("{:?}", class);
|
||||
if class != (0x0c, 0x03, 0x30) {
|
||||
eyre::bail!("Device is not xHCI controller!");
|
||||
}
|
||||
let registers = crate::pci::load_registers(device)?;
|
||||
|
||||
log::info!(
|
||||
"Found PCIe device {:04x}:{:04x}",
|
||||
config.vendor_id().read()?,
|
||||
config.device_id().read()?
|
||||
"xHCI version: {:04x}",
|
||||
registers.capability.hciversion.read_volatile().get()
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
|
74
src/pci.rs
Normal file
74
src/pci.rs
Normal file
|
@ -0,0 +1,74 @@
|
|||
use std::{num::NonZeroUsize, sync::Arc};
|
||||
|
||||
use eyre::OptionExt;
|
||||
use pci_driver::{
|
||||
backends::vfio::VfioPciDevice,
|
||||
device::PciDevice,
|
||||
regions::{MappedOwningPciRegion, PciRegion},
|
||||
};
|
||||
use xhci::Registers;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PciMapper {
|
||||
pub device: Arc<VfioPciDevice>,
|
||||
pub mapped_region: Arc<MappedOwningPciRegion>,
|
||||
pub phys_base: usize,
|
||||
}
|
||||
|
||||
impl xhci::accessor::Mapper for PciMapper {
|
||||
unsafe fn map(&mut self, phys_start: usize, bytes: usize) -> std::num::NonZeroUsize {
|
||||
log::trace!("Map {:#018x}: {:#x} bytes", phys_start, bytes);
|
||||
if phys_start < self.phys_base
|
||||
|| phys_start - self.phys_base + bytes > self.mapped_region.len()
|
||||
{
|
||||
panic!("Tried to access invalid address");
|
||||
}
|
||||
|
||||
NonZeroUsize::try_from(
|
||||
(self.mapped_region.as_ptr() as usize) + (phys_start - self.phys_base),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn unmap(&mut self, virt_start: usize, bytes: usize) {
|
||||
log::trace!("Unmap {:#018x}: {:#x} bytes", virt_start, bytes);
|
||||
// no-op, we mapped the entire BAR 0 anyway
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_registers(device: Arc<VfioPciDevice>) -> eyre::Result<Registers<PciMapper>> {
|
||||
let config = device.config();
|
||||
let class = config.read_le_u32(0x08)? >> 8;
|
||||
if class != 0x0c_03_30 {
|
||||
eyre::bail!("Device is not xHCI controller!");
|
||||
}
|
||||
|
||||
log::info!(
|
||||
"Found xHCI controller device {:04x}:{:04x}",
|
||||
config.vendor_id().read()?,
|
||||
config.device_id().read()?
|
||||
);
|
||||
|
||||
let mut bar = [0u8; 8];
|
||||
device.config().read_bytes(0x10, &mut bar)?;
|
||||
let phys_base = u64::from_le_bytes(bar) & 0xffff_fff8;
|
||||
|
||||
log::debug!("BAR physical base: {:#018x}", phys_base);
|
||||
|
||||
let region = device.bar(0).ok_or_eyre("Device does not have BAR 0")?;
|
||||
let mapped_region =
|
||||
Arc::new(region.map(0..region.len(), pci_driver::regions::Permissions::ReadWrite)?);
|
||||
|
||||
log::debug!(
|
||||
"BAR virtual base: {:#018x}",
|
||||
mapped_region.as_ptr() as usize
|
||||
);
|
||||
|
||||
let mapper = PciMapper {
|
||||
device,
|
||||
mapped_region,
|
||||
phys_base: phys_base.try_into()?,
|
||||
};
|
||||
|
||||
unsafe { Ok(Registers::new(phys_base as usize, mapper)) }
|
||||
}
|
Loading…
Reference in a new issue