Use pci_types for reading BARs
This simplifies a lot of code and adds support for 64bit BARs.
This commit is contained in:
+3
-4
@@ -9,7 +9,7 @@ use std::io::{ErrorKind, Read, Write};
|
||||
use std::os::unix::io::{FromRawFd, RawFd};
|
||||
use std::usize;
|
||||
|
||||
use pcid_interface::{PciBar, PcidServerHandle};
|
||||
use pcid_interface::PcidServerHandle;
|
||||
use syscall::error::{Error, ENODEV};
|
||||
use syscall::data::{Event, Packet};
|
||||
use syscall::flag::EVENT_READ;
|
||||
@@ -81,8 +81,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
let mut name = pci_config.func.name();
|
||||
name.push_str("_ahci");
|
||||
|
||||
let bar = pci_config.func.bars[5].expect_mem();
|
||||
let bar_size = pci_config.func.bar_sizes[5];
|
||||
let (bar, bar_size) = pci_config.func.bars[5].expect_mem();
|
||||
|
||||
let irq = pci_config.func.legacy_interrupt_line;
|
||||
|
||||
@@ -93,7 +92,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
let address = unsafe {
|
||||
common::physmap(
|
||||
bar,
|
||||
bar_size as usize,
|
||||
bar_size,
|
||||
common::Prot { read: true, write: true },
|
||||
common::MemoryType::Uncacheable,
|
||||
).expect("ahcid: failed to map address")
|
||||
|
||||
+2
-3
@@ -10,7 +10,7 @@ use std::process;
|
||||
use std::sync::Arc;
|
||||
|
||||
use event::EventQueue;
|
||||
use pcid_interface::{PciBar, PcidServerHandle};
|
||||
use pcid_interface::PcidServerHandle;
|
||||
use syscall::{EventFlags, Packet, SchemeBlockMut};
|
||||
|
||||
pub mod device;
|
||||
@@ -68,8 +68,7 @@ fn main() {
|
||||
let mut name = pci_config.func.name();
|
||||
name.push_str("_e1000");
|
||||
|
||||
let bar = pci_config.func.bars[0].expect_mem();
|
||||
let bar_size = pci_config.func.bar_sizes[0] as usize;
|
||||
let (bar, bar_size) = pci_config.func.bars[0].expect_mem();
|
||||
|
||||
let irq = pci_config.func.legacy_interrupt_line;
|
||||
|
||||
|
||||
+2
-3
@@ -160,13 +160,12 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
let mut name = pci_config.func.name();
|
||||
name.push_str("_ihda");
|
||||
|
||||
let bar_ptr = pci_config.func.bars[0].expect_mem();
|
||||
let bar_size = pci_config.func.bar_sizes[0];
|
||||
let (bar_ptr, bar_size) = pci_config.func.bars[0].expect_mem();
|
||||
|
||||
log::info!(" + IHDA {} on: {:#X} size: {}", name, bar_ptr, bar_size);
|
||||
|
||||
let address = unsafe {
|
||||
common::physmap(bar_ptr, bar_size as usize, common::Prot::RW, common::MemoryType::Uncacheable)
|
||||
common::physmap(bar_ptr, bar_size, common::Prot::RW, common::MemoryType::Uncacheable)
|
||||
.expect("ihdad: failed to map address") as usize
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ use std::sync::Arc;
|
||||
use std::thread;
|
||||
|
||||
use event::EventQueue;
|
||||
use pcid_interface::{PciBar, PcidServerHandle};
|
||||
use pcid_interface::PcidServerHandle;
|
||||
use std::time::Duration;
|
||||
use syscall::{EventFlags, Packet, SchemeBlockMut};
|
||||
|
||||
@@ -76,7 +76,7 @@ fn main() {
|
||||
let mut name = pci_config.func.name();
|
||||
name.push_str("_ixgbe");
|
||||
|
||||
let bar = pci_config.func.bars[0].expect_mem();
|
||||
let (bar, _) = pci_config.func.bars[0].expect_mem();
|
||||
|
||||
let irq = pci_config.func.legacy_interrupt_line;
|
||||
|
||||
|
||||
+8
-10
@@ -9,7 +9,7 @@ use std::ptr::NonNull;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::{slice, usize};
|
||||
|
||||
use pcid_interface::{PciBar, PciFeature, PciFeatureInfo, PciFunction, PcidServerHandle};
|
||||
use pcid_interface::{PciFeature, PciFeatureInfo, PciFunction, PcidServerHandle};
|
||||
use syscall::{
|
||||
Event, Mmio, Packet, Result, SchemeBlockMut,
|
||||
PAGE_SIZE,
|
||||
@@ -93,10 +93,9 @@ fn get_int_method(
|
||||
match &mut *bar_guard {
|
||||
&mut Some(ref bar) => Ok(bar.ptr),
|
||||
bar_to_set @ &mut None => {
|
||||
let bar = function.bars[bir].expect_mem();
|
||||
let bar_size = function.bar_sizes[bir];
|
||||
let (bar, bar_size) = function.bars[bir].expect_mem();
|
||||
|
||||
let bar = Bar::allocate(bar as usize, bar_size as usize)?;
|
||||
let bar = Bar::allocate(bar, bar_size)?;
|
||||
*bar_to_set = Some(bar);
|
||||
Ok(bar_to_set.as_ref().unwrap().ptr)
|
||||
}
|
||||
@@ -293,8 +292,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
|
||||
let _logger_ref = setup_logging(&scheme_name);
|
||||
|
||||
let bar = pci_config.func.bars[0].expect_mem();
|
||||
let bar_size = pci_config.func.bar_sizes[0];
|
||||
let (bar, bar_size) = pci_config.func.bars[0].expect_mem();
|
||||
let irq = pci_config.func.legacy_interrupt_line;
|
||||
|
||||
log::debug!("NVME PCI CONFIG: {:?}", pci_config);
|
||||
@@ -303,16 +301,16 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
|
||||
let address = unsafe {
|
||||
common::physmap(
|
||||
bar as usize,
|
||||
bar_size as usize,
|
||||
bar,
|
||||
bar_size,
|
||||
common::Prot { read: true, write: true },
|
||||
common::MemoryType::Uncacheable,
|
||||
)
|
||||
.expect("nvmed: failed to map address")
|
||||
} as usize;
|
||||
*allocated_bars.0[0].lock().unwrap() = Some(Bar {
|
||||
physical: bar as usize,
|
||||
bar_size: bar_size as usize,
|
||||
physical: bar,
|
||||
bar_size,
|
||||
ptr: NonNull::new(address as *mut u8).expect("Physmapping BAR gave nullptr"),
|
||||
});
|
||||
|
||||
|
||||
@@ -54,9 +54,6 @@ pub struct PciFunction {
|
||||
/// PCI Base Address Registers
|
||||
pub bars: [PciBar; 6],
|
||||
|
||||
/// BAR sizes
|
||||
pub bar_sizes: [u32; 6],
|
||||
|
||||
/// Legacy IRQ line: It's the responsibility of pcid to make sure that it be mapped in either
|
||||
/// the I/O APIC or the 8259 PIC, so that the subdriver can map the interrupt vector directly.
|
||||
/// The vector to map is always this field, plus 32.
|
||||
@@ -282,6 +279,7 @@ impl PcidServerHandle {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME turn into struct with bool fields
|
||||
pub fn fetch_all_features(&mut self) -> Result<Vec<(PciFeature, FeatureStatus)>> {
|
||||
self.send(&PcidClientRequest::RequestFeatures)?;
|
||||
match self.recv()? {
|
||||
|
||||
+4
-41
@@ -244,11 +244,12 @@ fn handle_parsed_header(state: Arc<State>, config: &Config, addr: PciAddress, he
|
||||
_ => ()
|
||||
}
|
||||
|
||||
for (i, bar) in header.bars().iter().enumerate() {
|
||||
let bars = header.bars(&state.pcie);
|
||||
for (i, bar) in bars.iter().enumerate() {
|
||||
match bar {
|
||||
PciBar::None => {},
|
||||
PciBar::Memory32(addr) => string.push_str(&format!(" {i}={addr:08X}")),
|
||||
PciBar::Memory64(addr) => string.push_str(&format!(" {i}={addr:016X}")),
|
||||
PciBar::Memory32{addr,..} => string.push_str(&format!(" {i}={addr:08X}")),
|
||||
PciBar::Memory64{addr,..} => string.push_str(&format!(" {i}={addr:016X}")),
|
||||
PciBar::Port(port) => string.push_str(&format!(" {i}=P{port:04X}")),
|
||||
}
|
||||
}
|
||||
@@ -286,43 +287,6 @@ fn handle_parsed_header(state: Arc<State>, config: &Config, addr: PciAddress, he
|
||||
state.pcie.write(addr, 0x3C, data);
|
||||
};
|
||||
|
||||
// Find BAR sizes
|
||||
//TODO: support 64-bit BAR sizes?
|
||||
let mut bars = [PciBar::None; 6];
|
||||
let mut bar_sizes = [0; 6];
|
||||
unsafe {
|
||||
let count = match header.header_type() {
|
||||
PciHeaderType::GENERAL => 6,
|
||||
PciHeaderType::PCITOPCI => 2,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
for i in 0..count {
|
||||
bars[i] = header.get_bar(i);
|
||||
|
||||
let offset = 0x10 + (i as u8) * 4;
|
||||
|
||||
let original = state.pcie.read(addr, offset.into());
|
||||
state.pcie.write(addr, offset.into(), 0xFFFFFFFF);
|
||||
|
||||
let new = state.pcie.read(addr, offset.into());
|
||||
state.pcie.write(addr, offset.into(), original);
|
||||
|
||||
let masked = if new & 1 == 1 {
|
||||
new & 0xFFFFFFFC
|
||||
} else {
|
||||
new & 0xFFFFFFF0
|
||||
};
|
||||
|
||||
let size = (!masked).wrapping_add(1);
|
||||
bar_sizes[i] = if size <= 1 {
|
||||
0
|
||||
} else {
|
||||
size
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let capabilities = if header.status() & (1 << 4) != 0 {
|
||||
let func = PciFunc {
|
||||
pci: &state.pcie,
|
||||
@@ -351,7 +315,6 @@ fn handle_parsed_header(state: Arc<State>, config: &Config, addr: PciAddress, he
|
||||
|
||||
let func = driver_interface::PciFunction {
|
||||
bars,
|
||||
bar_sizes,
|
||||
addr,
|
||||
legacy_interrupt_line: irq,
|
||||
legacy_interrupt_pin,
|
||||
|
||||
+11
-27
@@ -5,8 +5,8 @@ use serde::{Deserialize, Serialize};
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum PciBar {
|
||||
None,
|
||||
Memory32(u32),
|
||||
Memory64(u64),
|
||||
Memory32 { addr: u32, size: u32 },
|
||||
Memory64 { addr: u64, size: u64 },
|
||||
Port(u16),
|
||||
}
|
||||
|
||||
@@ -21,40 +21,24 @@ impl PciBar {
|
||||
pub fn expect_port(&self) -> u16 {
|
||||
match *self {
|
||||
PciBar::Port(port) => port,
|
||||
PciBar::Memory32(_) | PciBar::Memory64(_) => {
|
||||
PciBar::Memory32 { .. } | PciBar::Memory64 { .. } => {
|
||||
panic!("expected port BAR, found memory BAR");
|
||||
}
|
||||
PciBar::None => panic!("expected BAR to exist"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_mem(&self) -> usize {
|
||||
pub fn expect_mem(&self) -> (usize, usize) {
|
||||
match *self {
|
||||
PciBar::Memory32(ptr) => ptr as usize,
|
||||
PciBar::Memory64(ptr) => ptr
|
||||
.try_into()
|
||||
.expect("conversion from 64bit BAR to usize failed"),
|
||||
PciBar::Memory32 { addr, size } => (addr as usize, size as usize),
|
||||
PciBar::Memory64 { addr, size } => (
|
||||
addr.try_into()
|
||||
.expect("conversion from 64bit BAR to usize failed"),
|
||||
size.try_into()
|
||||
.expect("conversion from 64bit BAR size to usize failed"),
|
||||
),
|
||||
PciBar::Port(_) => panic!("expected memory BAR, found port BAR"),
|
||||
PciBar::None => panic!("expected BAR to exist"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for PciBar {
|
||||
fn from(bar: u32) -> Self {
|
||||
if bar & 0xFFFFFFFC == 0 {
|
||||
PciBar::None
|
||||
} else if bar & 1 == 0 {
|
||||
match (bar >> 1) & 3 {
|
||||
0 => PciBar::Memory32(bar & 0xFFFFFFF0),
|
||||
2 => PciBar::Memory64((bar & 0xFFFFFFF0) as u64),
|
||||
other => {
|
||||
log::warn!("unsupported PCI memory type {}", other);
|
||||
PciBar::None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PciBar::Port((bar & 0xFFFC) as u16)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -285,7 +285,7 @@ impl MsixCapability {
|
||||
if self.table_bir() > 5 {
|
||||
panic!("MSI-X Table BIR contained a reserved enum value: {}", self.table_bir());
|
||||
}
|
||||
bars[usize::from(self.table_bir())].expect_mem() + self.table_offset() as usize
|
||||
bars[usize::from(self.table_bir())].expect_mem().0 + self.table_offset() as usize
|
||||
}
|
||||
pub fn table_pointer(&self, bars: [PciBar; 6], k: u16) -> usize {
|
||||
self.table_base_pointer(bars) + k as usize * 16
|
||||
@@ -295,7 +295,7 @@ impl MsixCapability {
|
||||
if self.pba_bir() > 5 {
|
||||
panic!("MSI-X PBA BIR contained a reserved enum value: {}", self.pba_bir());
|
||||
}
|
||||
bars[usize::from(self.pba_bir())].expect_mem() + self.pba_offset() as usize
|
||||
bars[usize::from(self.pba_bir())].expect_mem().0 + self.pba_offset() as usize
|
||||
}
|
||||
pub fn pba_pointer_dword(&self, bars: [PciBar; 6], k: u16) -> usize {
|
||||
self.pba_base_pointer(bars) + (k as usize / 32) * 4
|
||||
|
||||
+55
-69
@@ -1,6 +1,10 @@
|
||||
use std::convert::TryInto;
|
||||
|
||||
use bitflags::bitflags;
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use pci_types::{ConfigRegionAccess, PciAddress, PciHeader as TyPciHeader};
|
||||
use pci_types::{
|
||||
Bar as TyBar, ConfigRegionAccess, EndpointHeader, PciAddress, PciHeader as TyPciHeader,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::pci::{FullDeviceId, PciBar, PciClass};
|
||||
@@ -28,20 +32,20 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct SharedPciHeader {
|
||||
full_device_id: FullDeviceId,
|
||||
command: u16,
|
||||
status: u16,
|
||||
header_type: PciHeaderType,
|
||||
addr: PciAddress,
|
||||
}
|
||||
|
||||
// FIXME move out of pcid_interface
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum PciHeader {
|
||||
General {
|
||||
shared: SharedPciHeader,
|
||||
bars: [PciBar; 6],
|
||||
subsystem_vendor_id: u16,
|
||||
subsystem_id: u16,
|
||||
cap_pointer: u8,
|
||||
@@ -50,7 +54,6 @@ pub enum PciHeader {
|
||||
},
|
||||
PciToPci {
|
||||
shared: SharedPciHeader,
|
||||
bars: [PciBar; 2],
|
||||
secondary_bus_num: u8,
|
||||
cap_pointer: u8,
|
||||
interrupt_line: u8,
|
||||
@@ -60,33 +63,6 @@ pub enum PciHeader {
|
||||
}
|
||||
|
||||
impl PciHeader {
|
||||
fn get_bars(bytes: &[u8], bars: &mut [PciBar]) {
|
||||
let mut i = 0;
|
||||
while i < bars.len() {
|
||||
let offset = i * 4;
|
||||
let bar_bytes = match bytes.get(offset..offset + 4) {
|
||||
Some(some) => some,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
match PciBar::from(LittleEndian::read_u32(bar_bytes)) {
|
||||
PciBar::Memory64(mut addr) => {
|
||||
let high_bytes = match bytes.get(offset + 4..offset + 8) {
|
||||
Some(some) => some,
|
||||
None => continue,
|
||||
};
|
||||
addr |= (LittleEndian::read_u32(high_bytes) as u64) << 32;
|
||||
bars[i] = PciBar::Memory64(addr);
|
||||
i += 2;
|
||||
}
|
||||
bar => {
|
||||
bars[i] = bar;
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse the bytes found in the Configuration Space of the PCI device into
|
||||
/// a more usable PciHeader.
|
||||
pub fn from_reader(
|
||||
@@ -118,10 +94,12 @@ impl PciHeader {
|
||||
command,
|
||||
status,
|
||||
header_type,
|
||||
addr,
|
||||
};
|
||||
|
||||
match header_type & PciHeaderType::HEADER_TYPE {
|
||||
PciHeaderType::GENERAL => {
|
||||
let endpoint_header = EndpointHeader::from_header(header, access).unwrap();
|
||||
let bytes = unsafe {
|
||||
let mut ret = Vec::with_capacity(48);
|
||||
for offset in (16..64).step_by(4) {
|
||||
@@ -129,16 +107,11 @@ impl PciHeader {
|
||||
}
|
||||
ret
|
||||
};
|
||||
let mut bars = [PciBar::None; 6];
|
||||
Self::get_bars(&bytes, &mut bars);
|
||||
let subsystem_vendor_id = LittleEndian::read_u16(&bytes[28..30]);
|
||||
let subsystem_id = LittleEndian::read_u16(&bytes[30..32]);
|
||||
let (subsystem_id, subsystem_vendor_id) = endpoint_header.subsystem(access);
|
||||
let cap_pointer = bytes[36];
|
||||
let interrupt_line = bytes[44];
|
||||
let interrupt_pin = bytes[45];
|
||||
let (interrupt_pin, interrupt_line) = endpoint_header.interrupt(access);
|
||||
Ok(PciHeader::General {
|
||||
shared,
|
||||
bars,
|
||||
subsystem_vendor_id,
|
||||
subsystem_id,
|
||||
cap_pointer,
|
||||
@@ -154,8 +127,6 @@ impl PciHeader {
|
||||
}
|
||||
ret
|
||||
};
|
||||
let mut bars = [PciBar::None; 2];
|
||||
Self::get_bars(&bytes, &mut bars);
|
||||
let secondary_bus_num = bytes[9];
|
||||
let cap_pointer = bytes[36];
|
||||
let interrupt_line = bytes[44];
|
||||
@@ -163,7 +134,6 @@ impl PciHeader {
|
||||
let bridge_control = LittleEndian::read_u16(&bytes[46..48]);
|
||||
Ok(PciHeader::PciToPci {
|
||||
shared,
|
||||
bars,
|
||||
secondary_bus_num,
|
||||
cap_pointer,
|
||||
interrupt_line,
|
||||
@@ -242,29 +212,52 @@ impl PciHeader {
|
||||
}
|
||||
|
||||
/// Return the Headers BARs.
|
||||
pub fn bars(&self) -> &[PciBar] {
|
||||
match self {
|
||||
&PciHeader::General { ref bars, .. } => bars,
|
||||
&PciHeader::PciToPci { ref bars, .. } => bars,
|
||||
}
|
||||
}
|
||||
// FIXME use pci_types::Bar instead
|
||||
pub fn bars(&self, access: &impl ConfigRegionAccess) -> [PciBar; 6] {
|
||||
let endpoint_header = match *self {
|
||||
PciHeader::General {
|
||||
shared: SharedPciHeader { addr, .. },
|
||||
..
|
||||
} => EndpointHeader::from_header(TyPciHeader::new(addr), access).unwrap(),
|
||||
PciHeader::PciToPci { .. } => unreachable!(),
|
||||
};
|
||||
|
||||
/// Return the BAR at the given index.
|
||||
///
|
||||
/// # Panics
|
||||
/// This function panics if the requested BAR index is beyond the length of the header
|
||||
/// types BAR array.
|
||||
pub fn get_bar(&self, idx: usize) -> PciBar {
|
||||
match self {
|
||||
&PciHeader::General { bars, .. } => {
|
||||
assert!(idx < 6, "the general PCI device only has 6 BARs");
|
||||
bars[idx]
|
||||
let mut bars = [PciBar::None; 6];
|
||||
let mut skip = false;
|
||||
for i in 0..6 {
|
||||
if skip {
|
||||
skip = false;
|
||||
continue;
|
||||
}
|
||||
&PciHeader::PciToPci { bars, .. } => {
|
||||
assert!(idx < 2, "the general PCI device only has 2 BARs");
|
||||
bars[idx]
|
||||
match endpoint_header.bar(i, access) {
|
||||
Some(TyBar::Io { port }) => {
|
||||
bars[i as usize] = PciBar::Port(port.try_into().unwrap())
|
||||
}
|
||||
Some(TyBar::Memory32 {
|
||||
address,
|
||||
size,
|
||||
prefetchable: _,
|
||||
}) => {
|
||||
bars[i as usize] = PciBar::Memory32 {
|
||||
addr: address,
|
||||
size,
|
||||
}
|
||||
}
|
||||
Some(TyBar::Memory64 {
|
||||
address,
|
||||
size,
|
||||
prefetchable: _,
|
||||
}) => {
|
||||
bars[i as usize] = PciBar::Memory64 {
|
||||
addr: address,
|
||||
size,
|
||||
};
|
||||
skip = true; // Each 64bit memory BAR occupies two slots
|
||||
}
|
||||
None => bars[i as usize] = PciBar::None,
|
||||
}
|
||||
}
|
||||
bars
|
||||
}
|
||||
|
||||
/// Return the Interrupt Line field.
|
||||
@@ -304,7 +297,7 @@ mod test {
|
||||
use pci_types::{ConfigRegionAccess, PciAddress};
|
||||
|
||||
use super::{PciHeader, PciHeaderError, PciHeaderType};
|
||||
use crate::pci::{PciBar, PciClass};
|
||||
use crate::pci::PciClass;
|
||||
|
||||
struct TestCfgAccess<'a> {
|
||||
addr: PciAddress,
|
||||
@@ -365,13 +358,6 @@ mod test {
|
||||
assert_eq!(header.interface(), 0);
|
||||
assert_eq!(header.class(), PciClass::Network);
|
||||
assert_eq!(header.subclass(), 0);
|
||||
assert_eq!(header.bars().len(), 6);
|
||||
assert_eq!(header.get_bar(0), PciBar::Memory32(0xf7500000));
|
||||
assert_eq!(header.get_bar(1), PciBar::None);
|
||||
assert_eq!(header.get_bar(2), PciBar::Port(0xb000));
|
||||
assert_eq!(header.get_bar(3), PciBar::Memory32(0xf7580000));
|
||||
assert_eq!(header.get_bar(4), PciBar::None);
|
||||
assert_eq!(header.get_bar(5), PciBar::None);
|
||||
assert_eq!(header.interrupt_line(), 10);
|
||||
}
|
||||
|
||||
|
||||
+14
-21
@@ -171,24 +171,23 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option<File> {
|
||||
let pba_base = capability.pba_base_pointer(pci_config.func.bars);
|
||||
|
||||
let bir = capability.table_bir() as usize;
|
||||
let bar_ptr = pci_config.func.bars[bir].expect_mem() as u64;
|
||||
let bar_size = pci_config.func.bar_sizes[bir] as u64;
|
||||
let (bar_ptr, bar_size) = pci_config.func.bars[bir].expect_mem();
|
||||
|
||||
let address = unsafe {
|
||||
common::physmap(bar_ptr as usize, bar_size as usize, common::Prot::RW, common::MemoryType::Uncacheable)
|
||||
common::physmap(bar_ptr, bar_size, common::Prot::RW, common::MemoryType::Uncacheable)
|
||||
.expect("rtl8139d: failed to map address") as usize
|
||||
};
|
||||
|
||||
if !(bar_ptr..bar_ptr + bar_size).contains(&(table_base as u64 + table_min_length as u64)) {
|
||||
if !(bar_ptr as u64..bar_ptr as u64 + bar_size as u64).contains(&(table_base as u64 + table_min_length as u64)) {
|
||||
panic!("Table {:#x}{:#x} outside of BAR {:#x}:{:#x}", table_base, table_base + table_min_length as usize, bar_ptr, bar_ptr + bar_size);
|
||||
}
|
||||
|
||||
if !(bar_ptr..bar_ptr + bar_size).contains(&(pba_base as u64 + pba_min_length as u64)) {
|
||||
if !(bar_ptr as u64..bar_ptr as u64 + bar_size as u64).contains(&(pba_base as u64 + pba_min_length as u64)) {
|
||||
panic!("PBA {:#x}{:#x} outside of BAR {:#x}:{:#X}", pba_base, pba_base + pba_min_length as usize, bar_ptr, bar_ptr + bar_size);
|
||||
}
|
||||
|
||||
let virt_table_base = ((table_base - bar_ptr as usize) + address) as *mut MsixTableEntry;
|
||||
let virt_pba_base = ((pba_base - bar_ptr as usize) + address) as *mut u64;
|
||||
let virt_table_base = ((table_base - bar_ptr) + address) as *mut MsixTableEntry;
|
||||
let virt_pba_base = ((pba_base - bar_ptr) + address) as *mut u64;
|
||||
|
||||
let mut info = MsixInfo {
|
||||
virt_table_base: NonNull::new(virt_table_base).unwrap(),
|
||||
@@ -299,20 +298,14 @@ fn find_bar(pci_config: &SubdriverArguments) -> Option<(usize, usize)> {
|
||||
// RTL8139 uses BAR2, RTL8169 uses BAR1, search in that order
|
||||
for &barnum in &[2, 1] {
|
||||
match pci_config.func.bars[barnum] {
|
||||
pcid_interface::PciBar::Memory32(ptr) => match ptr {
|
||||
0 => log::warn!("BAR {} is mapped to address 0", barnum),
|
||||
_ => return Some((
|
||||
ptr.try_into().unwrap(),
|
||||
pci_config.func.bar_sizes[barnum].try_into().unwrap()
|
||||
)),
|
||||
},
|
||||
pcid_interface::PciBar::Memory64(ptr) => match ptr {
|
||||
0 => log::warn!("BAR {} is mapped to address 0", barnum),
|
||||
_ => return Some((
|
||||
ptr.try_into().unwrap(),
|
||||
pci_config.func.bar_sizes[barnum].try_into().unwrap()
|
||||
)),
|
||||
},
|
||||
pcid_interface::PciBar::Memory32 { addr, size } => return Some((
|
||||
addr.try_into().unwrap(),
|
||||
size.try_into().unwrap()
|
||||
)),
|
||||
pcid_interface::PciBar::Memory64 { addr, size } => return Some((
|
||||
addr.try_into().unwrap(),
|
||||
size.try_into().unwrap()
|
||||
)),
|
||||
other => log::warn!("BAR {} is {:?} instead of memory BAR", barnum, other),
|
||||
}
|
||||
}
|
||||
|
||||
+14
-23
@@ -169,26 +169,23 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option<File> {
|
||||
let pba_base = capability.pba_base_pointer(pci_config.func.bars);
|
||||
|
||||
let bir = capability.table_bir() as usize;
|
||||
let bar = pci_config.func.bars[bir];
|
||||
let bar_size = pci_config.func.bar_sizes[bir] as u64;
|
||||
|
||||
let bar_ptr = bar.expect_mem() as u64;
|
||||
let (bar_ptr, bar_size) = pci_config.func.bars[bir].expect_mem();
|
||||
|
||||
let address = unsafe {
|
||||
common::physmap(bar_ptr as usize, bar_size as usize, common::Prot::RW, common::MemoryType::Uncacheable)
|
||||
common::physmap(bar_ptr, bar_size, common::Prot::RW, common::MemoryType::Uncacheable)
|
||||
.expect("rtl8168d: failed to map address") as usize
|
||||
};
|
||||
|
||||
if !(bar_ptr..bar_ptr + bar_size).contains(&(table_base as u64 + table_min_length as u64)) {
|
||||
if !(bar_ptr as u64..bar_ptr as u64 + bar_size as u64).contains(&(table_base as u64 + table_min_length as u64)) {
|
||||
panic!("Table {:#x}{:#x} outside of BAR {:#x}:{:#x}", table_base, table_base + table_min_length as usize, bar_ptr, bar_ptr + bar_size);
|
||||
}
|
||||
|
||||
if !(bar_ptr..bar_ptr + bar_size).contains(&(pba_base as u64 + pba_min_length as u64)) {
|
||||
if !(bar_ptr as u64..bar_ptr as u64 + bar_size as u64).contains(&(pba_base as u64 + pba_min_length as u64)) {
|
||||
panic!("PBA {:#x}{:#x} outside of BAR {:#x}:{:#X}", pba_base, pba_base + pba_min_length as usize, bar_ptr, bar_ptr + bar_size);
|
||||
}
|
||||
|
||||
let virt_table_base = ((table_base - bar_ptr as usize) + address) as *mut MsixTableEntry;
|
||||
let virt_pba_base = ((pba_base - bar_ptr as usize) + address) as *mut u64;
|
||||
let virt_table_base = ((table_base - bar_ptr) + address) as *mut MsixTableEntry;
|
||||
let virt_pba_base = ((pba_base - bar_ptr) + address) as *mut u64;
|
||||
|
||||
let mut info = MsixInfo {
|
||||
virt_table_base: NonNull::new(virt_table_base).unwrap(),
|
||||
@@ -299,20 +296,14 @@ fn find_bar(pci_config: &SubdriverArguments) -> Option<(usize, usize)> {
|
||||
// RTL8168 uses BAR2, RTL8169 uses BAR1, search in that order
|
||||
for &barnum in &[2, 1] {
|
||||
match pci_config.func.bars[barnum] {
|
||||
pcid_interface::PciBar::Memory32(ptr) => match ptr {
|
||||
0 => log::warn!("BAR {} is mapped to address 0", barnum),
|
||||
_ => return Some((
|
||||
ptr.try_into().unwrap(),
|
||||
pci_config.func.bar_sizes[barnum].try_into().unwrap()
|
||||
)),
|
||||
},
|
||||
pcid_interface::PciBar::Memory64(ptr) => match ptr {
|
||||
0 => log::warn!("BAR {} is mapped to address 0", barnum),
|
||||
_ => return Some((
|
||||
ptr.try_into().unwrap(),
|
||||
pci_config.func.bar_sizes[barnum].try_into().unwrap()
|
||||
)),
|
||||
},
|
||||
pcid_interface::PciBar::Memory32 { addr, size } => return Some((
|
||||
addr.try_into().unwrap(),
|
||||
size.try_into().unwrap()
|
||||
)),
|
||||
pcid_interface::PciBar::Memory64 { addr, size } => return Some((
|
||||
addr.try_into().unwrap(),
|
||||
size.try_into().unwrap()
|
||||
)),
|
||||
other => log::warn!("BAR {} is {:?} instead of memory BAR", barnum, other),
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -196,7 +196,7 @@ fn main() {
|
||||
|
||||
let bar0 = pci_config.func.bars[0].expect_port();
|
||||
|
||||
let bar1 = pci_config.func.bars[1].expect_mem();
|
||||
let (bar1, _) = pci_config.func.bars[1].expect_mem();
|
||||
|
||||
let irq = pci_config.func.legacy_interrupt_line;
|
||||
|
||||
|
||||
@@ -27,13 +27,12 @@ pub fn enable_msix(pcid_handle: &mut PcidServerHandle) -> Result<File, Error> {
|
||||
let pba_base = capability.pba_base_pointer(pci_config.func.bars);
|
||||
|
||||
let bir = capability.table_bir() as usize;
|
||||
let bar_ptr = pci_config.func.bars[bir].expect_mem() as u64;
|
||||
let bar_size = pci_config.func.bar_sizes[bir] as u64;
|
||||
let (bar_ptr, bar_size) = pci_config.func.bars[bir].expect_mem();
|
||||
|
||||
let address = unsafe {
|
||||
common::physmap(
|
||||
bar_ptr as usize,
|
||||
bar_size as usize,
|
||||
bar_ptr,
|
||||
bar_size,
|
||||
common::Prot::RW,
|
||||
common::MemoryType::Uncacheable,
|
||||
)? as usize
|
||||
@@ -41,7 +40,7 @@ pub fn enable_msix(pcid_handle: &mut PcidServerHandle) -> Result<File, Error> {
|
||||
|
||||
// Ensure that the table and PBA are be within the BAR.
|
||||
{
|
||||
let bar_range = bar_ptr..bar_ptr + bar_size;
|
||||
let bar_range = bar_ptr as u64..bar_ptr as u64 + bar_size as u64;
|
||||
assert!(bar_range.contains(&(table_base as u64 + table_min_length as u64)));
|
||||
assert!(bar_range.contains(&(pba_base as u64 + pba_min_length as u64)));
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ pub fn probe_device(pcid_handle: &mut PcidServerHandle) -> Result<Device, Error>
|
||||
_ => continue,
|
||||
}
|
||||
|
||||
let addr = pci_config.func.bars[capability.bar as usize].expect_mem();
|
||||
let (addr, _) = pci_config.func.bars[capability.bar as usize].expect_mem();
|
||||
|
||||
let address = unsafe {
|
||||
let addr = addr + capability.offset as usize;
|
||||
|
||||
+5
-7
@@ -85,8 +85,7 @@ fn setup_logging(name: &str) -> Option<&'static RedoxLogger> {
|
||||
fn get_int_method(pcid_handle: &mut PcidServerHandle, address: usize) -> (Option<File>, InterruptMethod) {
|
||||
let pci_config = pcid_handle.fetch_config().expect("xhcid: failed to fetch config");
|
||||
|
||||
let bar_ptr = pci_config.func.bars[0].expect_mem() as u64;
|
||||
let bar_size = pci_config.func.bar_sizes[0] as u64;
|
||||
let (bar_ptr, bar_size) = pci_config.func.bars[0].expect_mem();
|
||||
let irq = pci_config.func.legacy_interrupt_line;
|
||||
|
||||
let all_pci_features = pcid_handle.fetch_all_features().expect("xhcid: failed to fetch pci features");
|
||||
@@ -146,11 +145,11 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle, address: usize) -> (Option
|
||||
|
||||
let pba_base = capability.pba_base_pointer(pci_config.func.bars);
|
||||
|
||||
if !(bar_ptr..bar_ptr + bar_size).contains(&(table_base as u64 + table_min_length as u64)) {
|
||||
if !(bar_ptr as u64..bar_ptr as u64 + bar_size as u64).contains(&(table_base as u64 + table_min_length as u64)) {
|
||||
panic!("Table {:#x}{:#x} outside of BAR {:#x}:{:#x}", table_base, table_base + table_min_length as usize, bar_ptr, bar_ptr + bar_size);
|
||||
}
|
||||
|
||||
if !(bar_ptr..bar_ptr + bar_size).contains(&(pba_base as u64 + pba_min_length as u64)) {
|
||||
if !(bar_ptr as u64..bar_ptr as u64 + bar_size as u64).contains(&(pba_base as u64 + pba_min_length as u64)) {
|
||||
panic!("PBA {:#x}{:#x} outside of BAR {:#x}:{:#X}", pba_base, pba_base + pba_min_length as usize, bar_ptr, bar_ptr + bar_size);
|
||||
}
|
||||
|
||||
@@ -235,12 +234,11 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
let _logger_ref = setup_logging(&name);
|
||||
|
||||
log::debug!("XHCI PCI CONFIG: {:?}", pci_config);
|
||||
let bar_ptr = pci_config.func.bars[0].expect_mem();
|
||||
let bar_size = pci_config.func.bar_sizes[0];
|
||||
let (bar_ptr, bar_size) = pci_config.func.bars[0].expect_mem();
|
||||
let irq = pci_config.func.legacy_interrupt_line;
|
||||
|
||||
let address = unsafe {
|
||||
common::physmap(bar_ptr as usize, bar_size as usize, common::Prot::RW, common::MemoryType::Uncacheable)
|
||||
common::physmap(bar_ptr, bar_size, common::Prot::RW, common::MemoryType::Uncacheable)
|
||||
.expect("xhcid: failed to map address") as usize
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user