Simplify MSI-X table pointer computation

This commit is contained in:
bjorn3
2024-01-23 14:24:26 +01:00
parent 7dbf22331b
commit f43aa8574c
5 changed files with 41 additions and 70 deletions
+22 -33
View File
@@ -204,37 +204,40 @@ impl MsiCapability {
impl MsixCapability {
pub fn validate(&self, bars: [PciBar; 6]) {
if self.table_bir() > 5 {
panic!("MSI-X Table BIR contained a reserved enum value: {}", self.table_bir());
}
if self.pba_bir() > 5 {
panic!("MSI-X PBA BIR contained a reserved enum value: {}", self.pba_bir());
}
let table_size = self.table_size();
let table_base = self.table_base_pointer(bars);
let table_offset = self.table_offset() as usize;
let table_min_length = table_size * 16;
let pba_offset = self.pba_offset() as usize;
let pba_min_length = table_size.div_ceil(8);
let pba_base = self.pba_base_pointer(bars);
let bir = self.table_bir() as usize;
let bar = &bars[bir];
let (bar_ptr, bar_size) = bar.expect_mem();
let (_, table_bar_size) = bars[self.table_bir() as usize].expect_mem();
let (_, pba_bar_size) = bars[self.pba_bir() as usize].expect_mem();
// Ensure that the table and PBA are within the BAR.
let bar_range = bar_ptr as u64..bar_ptr as u64 + bar_size as u64;
if !bar_range.contains(&(table_base as u64 + table_min_length as u64)) {
if !(0..table_bar_size as u64).contains(&(table_offset 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
"Table {:#x}:{:#x} outside of BAR with length {:#x}",
table_offset,
table_offset + table_min_length as usize,
table_bar_size
);
}
if !bar_range.contains(&(pba_base as u64 + pba_min_length as u64)) {
if !(0..pba_bar_size as u64).contains(&(pba_offset 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
"PBA {:#x}:{:#x} outside of BAR with length {:#x}",
pba_offset,
pba_offset + pba_min_length as usize,
pba_bar_size
);
}
}
@@ -307,20 +310,6 @@ impl MsixCapability {
}
pub fn table_base_pointer(&self, bars: [PciBar; 6]) -> usize {
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().0 + self.table_offset() as usize
}
pub fn pba_base_pointer(&self, bars: [PciBar; 6]) -> usize {
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().0 + self.pba_offset() as usize
}
/// Write the first DWORD into configuration space (containing the partially modifiable Message
/// Control field).
pub unsafe fn write_a<W: ConfigWriter>(&self, writer: &W, offset: u8) {
+5 -10
View File
@@ -162,18 +162,13 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File {
PciFeatureInfo::MsiX(s) => s,
};
capability.validate(pci_config.func.bars);
let table_base = capability.table_base_pointer(pci_config.func.bars);
let pba_base = capability.pba_base_pointer(pci_config.func.bars);
assert_eq!(capability.table_bir(), capability.pba_bir());
let bar = &pci_config.func.bars[capability.table_bir() as usize];
let bar_address = unsafe { bar.physmap_mem("rtl8139d") } as usize;
let bir = capability.table_bir() as usize;
let bar = &pci_config.func.bars[bir];
let (bar_ptr, _) = bar.expect_mem();
let address = unsafe { bar.physmap_mem("rtl8139d") } as usize;
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 virt_table_base = (bar_address + capability.table_offset() as usize) as *mut MsixTableEntry;
let virt_pba_base = (bar_address + capability.pba_offset() as usize) as *mut u64;
let mut info = MsixInfo {
virt_table_base: NonNull::new(virt_table_base).unwrap(),
+5 -9
View File
@@ -160,17 +160,13 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File {
PciFeatureInfo::MsiX(s) => s,
};
capability.validate(pci_config.func.bars);
let table_base = capability.table_base_pointer(pci_config.func.bars);
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_ptr, _) = bar.expect_mem();
assert_eq!(capability.table_bir(), capability.pba_bir());
let bar = &pci_config.func.bars[capability.table_bir() as usize];
let bar_address = unsafe { bar.physmap_mem("rtl8168d") } as usize;
let address = unsafe { bar.physmap_mem("rtl8168d") } as usize;
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 virt_table_base = (bar_address + capability.table_offset() as usize) as *mut MsixTableEntry;
let virt_pba_base = (bar_address + capability.pba_offset() as usize) as *mut u64;
let mut info = MsixInfo {
virt_table_base: NonNull::new(virt_table_base).unwrap(),
+4 -10
View File
@@ -20,16 +20,10 @@ pub fn enable_msix(pcid_handle: &mut PcidServerHandle) -> Result<File, Error> {
};
capability.validate(pci_config.func.bars);
let table_base = capability.table_base_pointer(pci_config.func.bars);
let bir = capability.table_bir() as usize;
let bar = &pci_config.func.bars[bir];
let (bar_ptr, _) = bar.expect_mem();
let address = unsafe { bar.physmap_mem("virtio-core") } as usize;
let virt_table_base = ((table_base - bar_ptr as usize) + address) as *mut MsixTableEntry;
assert_eq!(capability.table_bir(), capability.pba_bir());
let bar = &pci_config.func.bars[capability.table_bir() as usize];
let bar_address = unsafe { bar.physmap_mem("virtio-core") } as usize;
let virt_table_base = (bar_address + capability.table_offset() as usize) as *mut MsixTableEntry;
let mut info = MsixInfo {
virt_table_base: NonNull::new(virt_table_base).unwrap(),
+5 -8
View File
@@ -82,11 +82,9 @@ fn setup_logging(name: &str) -> Option<&'static RedoxLogger> {
}
#[cfg(target_arch = "x86_64")]
fn get_int_method(pcid_handle: &mut PcidServerHandle, address: usize) -> (Option<File>, InterruptMethod) {
fn get_int_method(pcid_handle: &mut PcidServerHandle, bar0_address: usize) -> (Option<File>, InterruptMethod) {
let pci_config = pcid_handle.fetch_config().expect("xhcid: failed to fetch config");
let (bar_ptr, bar_size) = pci_config.func.bars[0].expect_mem();
let all_pci_features = pcid_handle.fetch_all_features().expect("xhcid: failed to fetch pci features");
log::debug!("XHCI PCI FEATURES: {:?}", all_pci_features);
@@ -139,11 +137,10 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle, address: usize) -> (Option
};
capability.validate(pci_config.func.bars);
let table_base = capability.table_base_pointer(pci_config.func.bars);
let pba_base = capability.pba_base_pointer(pci_config.func.bars);
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;
assert_eq!(capability.table_bir(), 0);
assert_eq!(capability.pba_bir(), 0);
let virt_table_base = (bar0_address + capability.table_offset() as usize) as *mut MsixTableEntry;
let virt_pba_base = (bar0_address + capability.pba_offset() as usize) as *mut u64;
let mut info = xhci::MsixInfo {
virt_table_base: NonNull::new(virt_table_base).unwrap(),