Store decoded MSI info instead of full capability in PciFeatureInfo

This commit is contained in:
bjorn3
2024-06-11 16:47:08 +02:00
parent 7a67110109
commit 4f583b1cfb
5 changed files with 24 additions and 10 deletions
+5 -1
View File
@@ -199,7 +199,11 @@ impl DriverHandler {
.iter()
.find_map(|capability| capability.as_msi())
{
PciFeatureInfo::Msi(*info)
PciFeatureInfo::Msi(msi::MsiInfo {
log2_multiple_message_capable: info.multi_message_capable(),
is_64bit: info.has_64_bit_addr(),
has_per_vector_masking: info.is_pvt_capable(),
})
} else {
return PcidClientResponse::Error(
PcidServerResponseError::NonexistentFeature(feature),
+1 -1
View File
@@ -132,7 +132,7 @@ impl PciFeature {
}
#[derive(Debug, Serialize, Deserialize)]
pub enum PciFeatureInfo {
Msi(msi::MsiCapability),
Msi(msi::MsiInfo),
MsiX(msi::MsixInfo),
}
+7
View File
@@ -23,6 +23,13 @@ impl MsiAddrAndData {
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct MsiInfo {
pub log2_multiple_message_capable: u8,
pub is_64bit: bool,
pub has_per_vector_masking: bool,
}
impl MsiCapability {
pub const MC_PVT_CAPABLE_BIT: u16 = 1 << 8;
pub const MC_64_BIT_ADDR_BIT: u16 = 1 << 7;
+5 -2
View File
@@ -149,7 +149,7 @@ fn get_int_method(
Ok((interrupt_method, interrupt_sources))
} else if has_msi {
// Message signaled interrupts.
let capability_struct = match pcid_handle.feature_info(PciFeature::Msi).unwrap() {
let msi_info = match pcid_handle.feature_info(PciFeature::Msi).unwrap() {
PciFeatureInfo::Msi(msi) => msi,
_ => unreachable!(),
};
@@ -171,7 +171,10 @@ fn get_int_method(
(0, irq_handle)
};
let interrupt_method = InterruptMethod::Msi(capability_struct);
let interrupt_method = InterruptMethod::Msi {
msi_info,
log2_multiple_message_enabled: 0,
};
let interrupt_sources =
InterruptSources::Msi(std::iter::once((msi_vector_number, irq_handle)).collect());
+6 -6
View File
@@ -22,7 +22,7 @@ pub mod queues;
use self::cq_reactor::NotifReq;
pub use self::queues::{NvmeCmd, NvmeCmdQueue, NvmeComp, NvmeCompQueue};
use pcid_interface::msi::{MsiCapability, MsixInfo, MsixTableEntry};
use pcid_interface::msi::{MsiInfo, MsixInfo, MsixTableEntry};
use pcid_interface::PcidServerHandle;
#[cfg(target_arch = "aarch64")]
@@ -91,7 +91,7 @@ pub enum InterruptMethod {
/// Traditional level-triggered, INTx# interrupt pins.
Intx,
/// Message signaled interrupts
Msi(MsiCapability),
Msi { msi_info: MsiInfo, log2_multiple_message_enabled: u8 },
/// Extended message signaled interrupts
MsiX(MappedMsixRegs),
}
@@ -104,7 +104,7 @@ impl InterruptMethod {
}
}
fn is_msi(&self) -> bool {
if let Self::Msi(_) = self {
if let Self::Msi { .. } = self {
true
} else {
false
@@ -289,7 +289,7 @@ impl Nvme {
}
match self.interrupt_method.get_mut().unwrap() {
&mut InterruptMethod::Intx | InterruptMethod::Msi(_) => {
&mut InterruptMethod::Intx | InterruptMethod::Msi { .. } => {
self.regs.get_mut().unwrap().intms.write(0xFFFF_FFFF);
self.regs.get_mut().unwrap().intmc.write(0x0000_0001);
}
@@ -371,13 +371,13 @@ impl Nvme {
self.regs.write().unwrap().intmc.write(0x0000_0001);
}
}
&mut InterruptMethod::Msi(ref mut cap) => {
&mut InterruptMethod::Msi { msi_info: _, log2_multiple_message_enabled: log2_enabled_messages } => {
let mut to_mask = 0x0000_0000;
let mut to_clear = 0x0000_0000;
for (vector, mask) in vectors {
assert!(
vector < (1 << cap.multi_message_enable()),
vector < (1 << log2_enabled_messages),
"nvmed: internal error: MSI vector out of range"
);
let vector = vector as u8;