pci: Refactor ptr alignment

This commit is contained in:
Yuke Peng 2025-08-19 09:58:13 +03:00 committed by Tate, Hongliang Tian
parent ecdc8c3fe7
commit 701b8f6f92
2 changed files with 25 additions and 19 deletions

View File

@ -6,12 +6,13 @@
use alloc::vec::Vec;
use align_ext::AlignExt;
use self::{msix::CapabilityMsixData, vendor::CapabilityVndrData};
use super::{
cfg_space::{PciDeviceCommonCfgOffset, Status},
common_device::PciCommonDevice,
};
use crate::PciDeviceLocation;
pub mod msix;
pub mod vendor;
@ -91,15 +92,15 @@ impl Capability {
return Vec::new();
}
let mut capabilities = Vec::new();
let mut cap_ptr = PciDeviceLocation::align_ptr(
dev.location()
.read8(PciDeviceCommonCfgOffset::CapabilitiesPointer as u16) as u16,
);
let mut cap_ptr =
(dev.location()
.read8(PciDeviceCommonCfgOffset::CapabilitiesPointer as u16) as u16)
.align_down(align_of::<u32>() as _);
let mut cap_ptr_vec = Vec::new();
// read all cap_ptr so that it is easy for us to get the length.
while cap_ptr > 0 {
cap_ptr_vec.push(cap_ptr);
cap_ptr = PciDeviceLocation::align_ptr(dev.location().read8(cap_ptr + 1) as u16);
cap_ptr = (dev.location().read8(cap_ptr + 1) as u16).align_down(align_of::<u32>() as _);
}
cap_ptr_vec.sort();
// Push here so that we can calculate the length of the last capability.

View File

@ -56,22 +56,20 @@ impl PciDeviceLocation {
}
impl PciDeviceLocation {
const BIT32_ALIGN_MASK: u16 = 0xFFFC;
/// Aligns the given pointer to a 32-bit boundary.
pub const fn align_ptr(ptr: u16) -> u16 {
ptr & Self::BIT32_ALIGN_MASK
}
/// Reads an 8-bit value from the PCI configuration space at the specified offset.
pub fn read8(&self, offset: u16) -> u8 {
let val = self.read32(offset & Self::BIT32_ALIGN_MASK);
let val = self.read32(offset & !0b11);
((val >> ((offset as usize & 0b11) << 3)) & 0xFF) as u8
}
/// Reads a 16-bit value from the PCI configuration space at the specified offset.
pub fn read16(&self, offset: u16) -> u16 {
let val = self.read32(offset & Self::BIT32_ALIGN_MASK);
debug_assert!(
(offset & 0b1) == 0,
"misaligned PCI configuration dword u16 read"
);
let val = self.read32(offset & !0b11);
((val >> ((offset as usize & 0b10) << 3)) & 0xFFFF) as u16
}
@ -81,27 +79,33 @@ impl PciDeviceLocation {
(offset & 0b11) == 0,
"misaligned PCI configuration dword u32 read"
);
crate::arch::read32(self, offset as u32).unwrap()
}
/// Writes an 8-bit value to the PCI configuration space at the specified offset.
pub fn write8(&self, offset: u16, val: u8) {
let old = self.read32(offset & Self::BIT32_ALIGN_MASK);
let old = self.read32(offset & !0b11);
let dest = (offset as usize & 0b11) << 3;
let mask = (0xFF << dest) as u32;
self.write32(
offset & Self::BIT32_ALIGN_MASK,
offset & !0b11,
(((val as u32) << dest) | (old & !mask)).to_le(),
);
}
/// Writes a 16-bit value to the PCI configuration space at the specified offset.
pub fn write16(&self, offset: u16, val: u16) {
let old = self.read32(offset & Self::BIT32_ALIGN_MASK);
debug_assert!(
(offset & 0b1) == 0,
"misaligned PCI configuration dword u16 write"
);
let old = self.read32(offset & !0b11);
let dest = (offset as usize & 0b10) << 3;
let mask = (0xFFFF << dest) as u32;
self.write32(
offset & Self::BIT32_ALIGN_MASK,
offset & !0b11,
(((val as u32) << dest) | (old & !mask)).to_le(),
);
}
@ -112,6 +116,7 @@ impl PciDeviceLocation {
(offset & 0b11) == 0,
"misaligned PCI configuration dword u32 write"
);
crate::arch::write32(self, offset as u32, val).unwrap()
}
}