diff --git a/ahcid/src/main.rs b/ahcid/src/main.rs index bd8e6af790..3d661c321f 100644 --- a/ahcid/src/main.rs +++ b/ahcid/src/main.rs @@ -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") diff --git a/e1000d/src/main.rs b/e1000d/src/main.rs index 58a8a9f4ed..dffeb43f4d 100644 --- a/e1000d/src/main.rs +++ b/e1000d/src/main.rs @@ -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; diff --git a/ihdad/src/main.rs b/ihdad/src/main.rs index a4ff9a98f0..860446ad5c 100755 --- a/ihdad/src/main.rs +++ b/ihdad/src/main.rs @@ -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 }; diff --git a/ixgbed/src/main.rs b/ixgbed/src/main.rs index a0b3d46c39..4666b98142 100644 --- a/ixgbed/src/main.rs +++ b/ixgbed/src/main.rs @@ -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; diff --git a/nvmed/src/main.rs b/nvmed/src/main.rs index 07933e1659..09ced15aff 100644 --- a/nvmed/src/main.rs +++ b/nvmed/src/main.rs @@ -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"), }); diff --git a/pcid/src/driver_interface/mod.rs b/pcid/src/driver_interface/mod.rs index 4c01b88282..36c002a15f 100644 --- a/pcid/src/driver_interface/mod.rs +++ b/pcid/src/driver_interface/mod.rs @@ -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> { self.send(&PcidClientRequest::RequestFeatures)?; match self.recv()? { diff --git a/pcid/src/main.rs b/pcid/src/main.rs index 6250e8ec8c..de3203345d 100644 --- a/pcid/src/main.rs +++ b/pcid/src/main.rs @@ -244,11 +244,12 @@ fn handle_parsed_header(state: Arc, 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, 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, config: &Config, addr: PciAddress, he let func = driver_interface::PciFunction { bars, - bar_sizes, addr, legacy_interrupt_line: irq, legacy_interrupt_pin, diff --git a/pcid/src/pci/bar.rs b/pcid/src/pci/bar.rs index f0d3a14911..4ee887d91f 100644 --- a/pcid/src/pci/bar.rs +++ b/pcid/src/pci/bar.rs @@ -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 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) - } - } -} diff --git a/pcid/src/pci/msi.rs b/pcid/src/pci/msi.rs index b4d3c67ca1..ba37e30127 100644 --- a/pcid/src/pci/msi.rs +++ b/pcid/src/pci/msi.rs @@ -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 diff --git a/pcid/src/pci_header.rs b/pcid/src/pci_header.rs index 94fac26dc6..b9918fdba7 100644 --- a/pcid/src/pci_header.rs +++ b/pcid/src/pci_header.rs @@ -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); } diff --git a/rtl8139d/src/main.rs b/rtl8139d/src/main.rs index 62925a1ec2..dc3616a08a 100644 --- a/rtl8139d/src/main.rs +++ b/rtl8139d/src/main.rs @@ -171,24 +171,23 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option { 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), } } diff --git a/rtl8168d/src/main.rs b/rtl8168d/src/main.rs index 284b84c3e4..2592100b2c 100644 --- a/rtl8168d/src/main.rs +++ b/rtl8168d/src/main.rs @@ -169,26 +169,23 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option { 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), } } diff --git a/vboxd/src/main.rs b/vboxd/src/main.rs index 0602649c5c..77f43eb10d 100644 --- a/vboxd/src/main.rs +++ b/vboxd/src/main.rs @@ -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; diff --git a/virtio-core/src/arch/x86_64.rs b/virtio-core/src/arch/x86_64.rs index 2dd3cd27d3..5bccd00c2a 100644 --- a/virtio-core/src/arch/x86_64.rs +++ b/virtio-core/src/arch/x86_64.rs @@ -27,13 +27,12 @@ pub fn enable_msix(pcid_handle: &mut PcidServerHandle) -> Result { 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 { // 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))); } diff --git a/virtio-core/src/probe.rs b/virtio-core/src/probe.rs index 0ad300a673..4f7d48719d 100644 --- a/virtio-core/src/probe.rs +++ b/virtio-core/src/probe.rs @@ -90,7 +90,7 @@ pub fn probe_device(pcid_handle: &mut PcidServerHandle) -> Result _ => 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; diff --git a/xhcid/src/main.rs b/xhcid/src/main.rs index 497fb01a16..9c8dbf542e 100644 --- a/xhcid/src/main.rs +++ b/xhcid/src/main.rs @@ -85,8 +85,7 @@ fn setup_logging(name: &str) -> Option<&'static RedoxLogger> { fn get_int_method(pcid_handle: &mut PcidServerHandle, address: usize) -> (Option, 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 };