From e5e753a426e9d9df4eb4bb7ca168e0adb7a05330 Mon Sep 17 00:00:00 2001 From: Andrey Turkin Date: Sat, 16 Nov 2024 09:16:00 +0300 Subject: [PATCH] Sync up with changes to kernel's phandle irq scheme --- pcid/src/cfg_access/mod.rs | 8 +++++--- pcid/src/driver_interface/mod.rs | 33 +++++++++++++++++++++++--------- pcid/src/main.rs | 13 +++++++------ 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/pcid/src/cfg_access/mod.rs b/pcid/src/cfg_access/mod.rs index 72c0c6b001..a8ea2b16e8 100644 --- a/pcid/src/cfg_access/mod.rs +++ b/pcid/src/cfg_access/mod.rs @@ -15,6 +15,7 @@ pub struct InterruptMap { pub interrupt: u32, pub parent_phandle: u32, pub parent_interrupt: [u32; 3], + pub parent_interrupt_cells: usize, } // https://elinux.org/Device_Tree_Usage has a lot of useful information @@ -55,11 +56,11 @@ fn locate_ecam_dtb( let mut interrupt_map = Vec::::new(); while let Ok([addr1, addr2, addr3, int1, phandle]) = interrupt_map_data.next_chunk::<5>() { let parent = dt.find_phandle(phandle).unwrap(); - let interrupt_cells = parent.interrupt_cells().unwrap(); - let parent_interrupt = match interrupt_cells { + let parent_interrupt_cells = parent.interrupt_cells().unwrap(); + let parent_interrupt = match parent_interrupt_cells { 1 if let Some(a) = interrupt_map_data.next() => [a, 0, 0], 2 if let Ok([a, b]) = interrupt_map_data.next_chunk::<2>() => [a, b, 0], - 2 if let Ok([a, b, c]) = interrupt_map_data.next_chunk::<3>() => [a, b, c], + 3 if let Ok([a, b, c]) = interrupt_map_data.next_chunk::<3>() => [a, b, c], _ => break, }; interrupt_map.push(InterruptMap { @@ -67,6 +68,7 @@ fn locate_ecam_dtb( interrupt: int1, parent_phandle: phandle, parent_interrupt, + parent_interrupt_cells, }); } diff --git a/pcid/src/driver_interface/mod.rs b/pcid/src/driver_interface/mod.rs index 2b103353c5..183f5036c3 100644 --- a/pcid/src/driver_interface/mod.rs +++ b/pcid/src/driver_interface/mod.rs @@ -25,18 +25,26 @@ pub mod msi; pub struct LegacyInterruptLine { #[doc(hidden)] pub irq: u8, - pub phandled: Option<(u32, [u32; 3])>, + pub phandled: Option<(u32, [u32; 3], usize)>, } impl LegacyInterruptLine { /// Get an IRQ handle for this interrupt line. pub fn irq_handle(self, driver: &str) -> File { - if let Some((phandle, addr)) = self.phandled { - File::create(format!( - "/scheme/irq/phandle-{}/{},{},{}", - phandle, addr[0], addr[1], addr[2] - )) - .unwrap_or_else(|err| panic!("{driver}: failed to open IRQ file: {err}")) + if let Some((phandle, addr, cells)) = self.phandled { + let path = match cells { + 1 => format!("/scheme/irq/phandle-{}/{}", phandle, addr[0]), + 2 => format!("/scheme/irq/phandle-{}/{},{}", phandle, addr[0], addr[1]), + 3 => format!( + "/scheme/irq/phandle-{}/{},{},{}", + phandle, addr[0], addr[1], addr[2] + ), + _ => panic!( + "unexpected number of IRQ description cells for phandle {phandle}: {cells}" + ), + }; + File::create(path) + .unwrap_or_else(|err| panic!("{driver}: failed to open IRQ file: {err}")) } else { File::open(format!("/scheme/irq/{}", self.irq)) .unwrap_or_else(|err| panic!("{driver}: failed to open IRQ file: {err}")) @@ -46,8 +54,15 @@ impl LegacyInterruptLine { impl fmt::Display for LegacyInterruptLine { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if let Some((phandle, addr)) = self.phandled { - write!(f, "(phandle {}, {:?})", phandle, addr) + if let Some((phandle, addr, cells)) = self.phandled { + match cells { + 1 => write!(f, "(phandle {}, {:?})", phandle, addr[0]), + 2 => write!(f, "(phandle {}, {:?},{:?})", phandle, addr[0], addr[1]), + 3 => write!(f, "(phandle {}, {:?})", phandle, addr), + _ => panic!( + "unexpected number of IRQ description cells for phandle {phandle}: {cells}" + ), + } } else { write!(f, "{}", self.irq) } diff --git a/pcid/src/main.rs b/pcid/src/main.rs index 2b7f120b1d..231463df73 100644 --- a/pcid/src/main.rs +++ b/pcid/src/main.rs @@ -136,7 +136,7 @@ fn handle_parsed_header( } }; - let mut phandled: Option<(u32, [u32; 3])> = None; + let mut phandled: Option<(u32, [u32; 3], usize)> = None; if legacy_interrupt_enabled { let pci_address = endpoint_header.header().address(); let dt_address = ((pci_address.bus() as u32) << 16) @@ -154,11 +154,12 @@ fn handle_parsed_header( .iter() .find(|x| x.addr == addr[0..3] && x.interrupt == addr[3]); if let Some(mapping) = mapping { - debug!( - "found mapping: addr={:?} => (phandle={} irq={:?})", - addr, mapping.parent_phandle, mapping.parent_interrupt - ); - phandled = Some((mapping.parent_phandle, mapping.parent_interrupt)); + phandled = Some(( + mapping.parent_phandle, + mapping.parent_interrupt, + mapping.parent_interrupt_cells, + )); + debug!("found mapping: addr={:?} => {:?}", addr, phandled); } }