Use pci_types for reading BARs

This simplifies a lot of code and adds support for 64bit BARs.
This commit is contained in:
bjorn3
2024-01-22 15:54:18 +01:00
parent d1b6009e3d
commit a5d0c7c354
16 changed files with 129 additions and 222 deletions
+3 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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"),
});
+1 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+4 -5
View File
@@ -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)));
}
+1 -1
View File
@@ -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
View File
@@ -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
};