pci: Refactor ptr alignment
This commit is contained in:
parent
ecdc8c3fe7
commit
701b8f6f92
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue