pcid: Remove ConfigReader and ConfigWriter traits

Only PciFunc implements this trait.
This commit is contained in:
bjorn3
2024-06-09 18:51:55 +02:00
parent d70cf080bb
commit b04915673d
4 changed files with 97 additions and 107 deletions
-1
View File
@@ -15,7 +15,6 @@ use crate::config::Config;
use crate::driver_interface::LegacyInterruptLine;
use crate::pci::PciFunc;
use crate::pci::cap::Capability as PciCapability;
use crate::pci::func::{ConfigReader, ConfigWriter};
use crate::pci_header::{PciEndpointHeader, PciHeader, PciHeaderError};
mod cfg_access;
+47 -49
View File
@@ -1,22 +1,20 @@
use super::func::ConfigReader;
use super::func::PciFunc;
use serde::{Serialize, Deserialize};
pub struct CapabilitiesIter<'a, R> {
pub struct CapabilitiesIter<'a> {
offset: u8,
reader: &'a R,
func: &'a PciFunc<'a>,
}
impl<'a, R> CapabilitiesIter<'a, R> {
pub fn new(offset: u8, reader: &'a R) -> Self {
impl<'a> CapabilitiesIter<'a> {
pub fn new(offset: u8, func: &'a PciFunc) -> Self {
Self {
offset,
reader,
func,
}
}
}
impl<'a, R> Iterator for CapabilitiesIter<'a, R>
where
R: ConfigReader
{
impl<'a> Iterator for CapabilitiesIter<'a> {
type Item = (u8, Capability);
fn next(&mut self) -> Option<Self::Item> {
@@ -26,7 +24,7 @@ where
if self.offset == 0 { return None };
let first_dword = self.reader.read_u32(u16::from(self.offset));
let first_dword = self.func.read_u32(u16::from(self.offset));
let next = ((first_dword >> 8) & 0xFF) as u8;
let offset = self.offset;
@@ -36,7 +34,7 @@ where
};
let cap = unsafe {
Capability::parse(self.reader, offset)
Capability::parse(self.func, offset)
};
Some((offset, cap))
@@ -159,28 +157,28 @@ impl Capability {
_ => None,
}
}
unsafe fn parse_msi<R: ConfigReader>(reader: &R, offset: u8) -> Self {
Self::Msi(MsiCapability::parse(reader, offset))
unsafe fn parse_msi(func: &PciFunc, offset: u8) -> Self {
Self::Msi(MsiCapability::parse(func, offset))
}
unsafe fn parse_msix<R: ConfigReader>(reader: &R, offset: u8) -> Self {
unsafe fn parse_msix(func: &PciFunc, offset: u8) -> Self {
Self::MsiX(MsixCapability {
a: reader.read_u32(u16::from(offset)),
b: reader.read_u32(u16::from(offset + 4)),
c: reader.read_u32(u16::from(offset + 8)),
a: func.read_u32(u16::from(offset)),
b: func.read_u32(u16::from(offset + 4)),
c: func.read_u32(u16::from(offset + 8)),
})
}
unsafe fn parse_pwr<R: ConfigReader>(reader: &R, offset: u8) -> Self {
unsafe fn parse_pwr(func: &PciFunc, offset: u8) -> Self {
Self::PwrMgmt(PwrMgmtCapability {
a: reader.read_u32(u16::from(offset)),
b: reader.read_u32(u16::from(offset + 4)),
a: func.read_u32(u16::from(offset)),
b: func.read_u32(u16::from(offset + 4)),
})
}
unsafe fn parse_vendor<R: ConfigReader>(reader: &R, offset: u8) -> Self {
let next = reader.read_u8(u16::from(offset+1));
let length = reader.read_u8(u16::from(offset+2));
unsafe fn parse_vendor(func: &PciFunc, offset: u8) -> Self {
let next = func.read_u8(u16::from(offset+1));
let length = func.read_u8(u16::from(offset+2));
log::info!("Vendor specific offset: {offset:#02x} next: {next:#02x} cap len: {length:#02x}");
let data = if length > 0 {
let mut raw_data = reader.read_range(offset.into(), length.into());
let mut raw_data = func.read_range(offset.into(), length.into());
raw_data.drain(3..).collect()
} else {
log::warn!("Vendor specific capability is invalid");
@@ -190,45 +188,45 @@ impl Capability {
data
})
}
unsafe fn parse_pcie<R: ConfigReader>(reader: &R, offset: u8) -> Self {
unsafe fn parse_pcie(func: &PciFunc, offset: u8) -> Self {
let offset = u16::from(offset);
Self::Pcie(PcieCapability {
pcie_caps: reader.read_u32(offset),
dev_caps: reader.read_u32(offset + 0x04),
dev_sts_ctl: reader.read_u32(offset + 0x08),
link_caps: reader.read_u32(offset + 0x0C),
link_sts_ctl: reader.read_u32(offset + 0x10),
slot_caps: reader.read_u32(offset + 0x14),
slot_sts_ctl: reader.read_u32(offset + 0x18),
root_cap_ctl: reader.read_u32(offset + 0x1C),
root_sts: reader.read_u32(offset + 0x20),
dev_caps2: reader.read_u32(offset + 0x24),
dev_sts_ctl2: reader.read_u32(offset + 0x28),
link_caps2: reader.read_u32(offset + 0x2C),
link_sts_ctl2: reader.read_u32(offset + 0x30),
slot_caps2: reader.read_u32(offset + 0x34),
slot_sts_ctl2: reader.read_u32(offset + 0x38),
pcie_caps: func.read_u32(offset),
dev_caps: func.read_u32(offset + 0x04),
dev_sts_ctl: func.read_u32(offset + 0x08),
link_caps: func.read_u32(offset + 0x0C),
link_sts_ctl: func.read_u32(offset + 0x10),
slot_caps: func.read_u32(offset + 0x14),
slot_sts_ctl: func.read_u32(offset + 0x18),
root_cap_ctl: func.read_u32(offset + 0x1C),
root_sts: func.read_u32(offset + 0x20),
dev_caps2: func.read_u32(offset + 0x24),
dev_sts_ctl2: func.read_u32(offset + 0x28),
link_caps2: func.read_u32(offset + 0x2C),
link_sts_ctl2: func.read_u32(offset + 0x30),
slot_caps2: func.read_u32(offset + 0x34),
slot_sts_ctl2: func.read_u32(offset + 0x38),
})
}
unsafe fn parse<R: ConfigReader>(reader: &R, offset: u8) -> Self {
unsafe fn parse(func: &PciFunc, offset: u8) -> Self {
assert_eq!(offset & 0xFC, offset, "capability must be dword aligned");
let dword = reader.read_u32(u16::from(offset));
let dword = func.read_u32(u16::from(offset));
let capability_id = (dword & 0xFF) as u8;
if capability_id == CapabilityId::Msi as u8 {
Self::parse_msi(reader, offset)
Self::parse_msi(func, offset)
} else if capability_id == CapabilityId::MsiX as u8 {
Self::parse_msix(reader, offset)
Self::parse_msix(func, offset)
} else if capability_id == CapabilityId::Pcie as u8 {
Self::parse_pcie(reader, offset)
Self::parse_pcie(func, offset)
} else if capability_id == CapabilityId::PwrMgmt as u8{
Self::parse_pwr(reader, offset)
Self::parse_pwr(func, offset)
} else if capability_id == CapabilityId::Vendor as u8 {
Self::parse_vendor(reader, offset)
Self::parse_vendor(func, offset)
} else if capability_id == CapabilityId::Sata as u8 {
Self::FunctionSpecific(capability_id, reader.read_range(offset.into(), 8))
Self::FunctionSpecific(capability_id, func.read_range(offset.into(), 8))
} else {
log::warn!("unimplemented or malformed capability id: {}", capability_id);
Self::Other(capability_id)
+11 -18
View File
@@ -1,8 +1,13 @@
use byteorder::{ByteOrder, LittleEndian};
use pci_types::{ConfigRegionAccess, PciAddress};
pub trait ConfigReader {
unsafe fn read_range(&self, offset: u16, len: u16) -> Vec<u8> {
pub struct PciFunc<'pci> {
pub pci: &'pci dyn ConfigRegionAccess,
pub addr: PciAddress,
}
impl<'pci> PciFunc<'pci> {
pub unsafe fn read_range(&self, offset: u16, len: u16) -> Vec<u8> {
assert!(len > 3 && len % 4 == 0, "invalid range length: {}", len);
let mut ret = Vec::with_capacity(len as usize);
let results = (offset..offset + len)
@@ -17,32 +22,20 @@ pub trait ConfigReader {
ret
}
unsafe fn read_u32(&self, offset: u16) -> u32;
unsafe fn read_u8(&self, offset: u16) -> u8 {
pub unsafe fn read_u8(&self, offset: u16) -> u8 {
let dword_offset = (offset / 4) * 4;
let dword = self.read_u32(dword_offset);
let shift = (offset % 4) * 8;
((dword >> shift) & 0xFF) as u8
}
}
pub trait ConfigWriter {
unsafe fn write_u32(&self, offset: u16, value: u32);
}
pub struct PciFunc<'pci> {
pub pci: &'pci dyn ConfigRegionAccess,
pub addr: PciAddress,
}
impl<'pci> ConfigReader for PciFunc<'pci> {
unsafe fn read_u32(&self, offset: u16) -> u32 {
pub unsafe fn read_u32(&self, offset: u16) -> u32 {
self.pci.read(self.addr, offset)
}
}
impl<'pci> ConfigWriter for PciFunc<'pci> {
unsafe fn write_u32(&self, offset: u16, value: u32) {
impl<'pci> PciFunc<'pci> {
pub unsafe fn write_u32(&self, offset: u16, value: u32) {
self.pci.write(self.addr, offset, value);
}
}
+39 -39
View File
@@ -2,7 +2,7 @@ use std::fmt;
use super::bar::PciBar;
pub use super::cap::{MsiCapability, MsixCapability};
use super::func::{ConfigReader, ConfigWriter};
use super::func::PciFunc;
use serde::{Deserialize, Serialize};
use syscall::{Io, Mmio};
@@ -35,8 +35,8 @@ impl MsiCapability {
pub const MC_MSI_ENABLED_BIT: u16 = 1;
pub unsafe fn parse<R: ConfigReader>(reader: &R, offset: u8) -> Self {
let dword = reader.read_u32(u16::from(offset));
pub unsafe fn parse(func: &PciFunc, offset: u8) -> Self {
let dword = func.read_u32(u16::from(offset));
let message_control = (dword >> 16) as u16;
@@ -44,34 +44,34 @@ impl MsiCapability {
if message_control & Self::MC_64_BIT_ADDR_BIT != 0 {
Self::_64BitAddressWithPvm {
message_control: dword,
message_address_lo: reader.read_u32(u16::from(offset + 4)),
message_address_hi: reader.read_u32(u16::from(offset + 8)),
message_data: reader.read_u32(u16::from(offset + 12)),
mask_bits: reader.read_u32(u16::from(offset + 16)),
pending_bits: reader.read_u32(u16::from(offset + 20)),
message_address_lo: func.read_u32(u16::from(offset + 4)),
message_address_hi: func.read_u32(u16::from(offset + 8)),
message_data: func.read_u32(u16::from(offset + 12)),
mask_bits: func.read_u32(u16::from(offset + 16)),
pending_bits: func.read_u32(u16::from(offset + 20)),
}
} else {
Self::_32BitAddressWithPvm {
message_control: dword,
message_address: reader.read_u32(u16::from(offset + 4)),
message_data: reader.read_u32(u16::from(offset + 8)),
mask_bits: reader.read_u32(u16::from(offset + 12)),
pending_bits: reader.read_u32(u16::from(offset + 16)),
message_address: func.read_u32(u16::from(offset + 4)),
message_data: func.read_u32(u16::from(offset + 8)),
mask_bits: func.read_u32(u16::from(offset + 12)),
pending_bits: func.read_u32(u16::from(offset + 16)),
}
}
} else {
if message_control & Self::MC_64_BIT_ADDR_BIT != 0 {
Self::_64BitAddress {
message_control: dword,
message_address_lo: reader.read_u32(u16::from(offset + 4)),
message_address_hi: reader.read_u32(u16::from(offset + 8)),
message_data: reader.read_u32(u16::from(offset + 12)) as u16,
message_address_lo: func.read_u32(u16::from(offset + 4)),
message_address_hi: func.read_u32(u16::from(offset + 8)),
message_data: func.read_u32(u16::from(offset + 12)) as u16,
}
} else {
Self::_32BitAddress {
message_control: dword,
message_address: reader.read_u32(u16::from(offset + 4)),
message_data: reader.read_u32(u16::from(offset + 8)) as u16,
message_address: func.read_u32(u16::from(offset + 4)),
message_data: func.read_u32(u16::from(offset + 8)) as u16,
}
}
}
@@ -97,8 +97,8 @@ impl MsiCapability {
| Self::_64BitAddressWithPvm { ref mut message_control, .. } => *message_control = new_message_control,
}
}
pub unsafe fn write_message_control<W: ConfigWriter>(&self, writer: &W, offset: u8) {
writer.write_u32(u16::from(offset), self.message_control_raw());
pub unsafe fn write_message_control(&self, func: &PciFunc, offset: u8) {
func.write_u32(u16::from(offset), self.message_control_raw());
}
pub fn is_pvt_capable(&self) -> bool {
self.message_control() & Self::MC_PVT_CAPABLE_BIT != 0
@@ -186,36 +186,36 @@ impl MsiCapability {
}
Some(())
}
pub unsafe fn write_message_address<W: ConfigWriter>(&self, writer: &W, offset: u8) {
writer.write_u32(u16::from(offset) + 4, self.message_address())
pub unsafe fn write_message_address(&self, func: &PciFunc, offset: u8) {
func.write_u32(u16::from(offset) + 4, self.message_address())
}
pub unsafe fn write_message_upper_address<W: ConfigWriter>(&self, writer: &W, offset: u8) -> Option<()> {
pub unsafe fn write_message_upper_address(&self, func: &PciFunc, offset: u8) -> Option<()> {
let value = self.message_upper_address()?;
writer.write_u32(u16::from(offset + 8), value);
func.write_u32(u16::from(offset + 8), value);
Some(())
}
pub unsafe fn write_message_data<W: ConfigWriter>(&self, writer: &W, offset: u8) {
pub unsafe fn write_message_data(&self, func: &PciFunc, offset: u8) {
match self {
&Self::_32BitAddress { message_data, .. } => writer.write_u32(u16::from(offset + 8), message_data.into()),
&Self::_32BitAddressWithPvm { message_data, .. } => writer.write_u32(u16::from(offset + 8), message_data),
&Self::_64BitAddress { message_data, .. } => writer.write_u32(u16::from(offset + 12), message_data.into()),
&Self::_64BitAddressWithPvm { message_data, .. } => writer.write_u32(u16::from(offset + 12), message_data),
&Self::_32BitAddress { message_data, .. } => func.write_u32(u16::from(offset + 8), message_data.into()),
&Self::_32BitAddressWithPvm { message_data, .. } => func.write_u32(u16::from(offset + 8), message_data),
&Self::_64BitAddress { message_data, .. } => func.write_u32(u16::from(offset + 12), message_data.into()),
&Self::_64BitAddressWithPvm { message_data, .. } => func.write_u32(u16::from(offset + 12), message_data),
}
}
pub unsafe fn write_mask_bits<W: ConfigWriter>(&self, writer: &W, offset: u8) -> Option<()> {
pub unsafe fn write_mask_bits(&self, func: &PciFunc, offset: u8) -> Option<()> {
match self {
&Self::_32BitAddressWithPvm { mask_bits, .. } => writer.write_u32(u16::from(offset + 12), mask_bits),
&Self::_64BitAddressWithPvm { mask_bits, .. } => writer.write_u32(u16::from(offset + 16), mask_bits),
&Self::_32BitAddressWithPvm { mask_bits, .. } => func.write_u32(u16::from(offset + 12), mask_bits),
&Self::_64BitAddressWithPvm { mask_bits, .. } => func.write_u32(u16::from(offset + 16), mask_bits),
&Self::_32BitAddress { .. } | &Self::_64BitAddress { .. } => return None,
}
Some(())
}
pub unsafe fn write_all<W: ConfigWriter>(&self, writer: &W, offset: u8) {
self.write_message_control(writer, offset);
self.write_message_address(writer, offset);
self.write_message_upper_address(writer, offset);
self.write_message_data(writer, offset);
self.write_mask_bits(writer, offset);
pub unsafe fn write_all(&self, func: &PciFunc, offset: u8) {
self.write_message_control(func, offset);
self.write_message_address(func, offset);
self.write_message_upper_address(func, offset);
self.write_message_data(func, offset);
self.write_mask_bits(func, offset);
}
}
@@ -329,8 +329,8 @@ impl MsixCapability {
/// 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) {
writer.write_u32(u16::from(offset), self.a)
pub unsafe fn write_a(&self, func: &PciFunc, offset: u8) {
func.write_u32(u16::from(offset), self.a)
}
}