@@ -2,6 +2,7 @@ use core::ops::{Deref, Range};
22
33use alloc:: vec:: Vec ;
44use fdt_raw:: { FdtError , Phandle , data:: U32Iter } ;
5+ use log:: debug;
56
67use crate :: node:: gerneric:: NodeRefGen ;
78
@@ -139,7 +140,11 @@ impl<'a> NodeRefPci<'a> {
139140 // 获取 interrupt-map 和 mask
140141 let interrupt_map = self . interrupt_map ( ) ?;
141142
142- let mut mask = self . interrupt_map_mask ( ) . ok_or ( FdtError :: NotFound ) ?;
143+ // 将 mask 转换为 Vec 以便索引访问
144+ let mask: Vec < u32 > = self
145+ . interrupt_map_mask ( )
146+ . ok_or ( FdtError :: NotFound ) ?
147+ . collect ( ) ;
143148
144149 // 构造 PCI 设备的子地址
145150 // 格式: [bus_num, device_num, func_num] 在适当的位
@@ -151,41 +156,35 @@ impl<'a> NodeRefPci<'a> {
151156
152157 let child_addr_cells = self . address_cells ( ) . unwrap_or ( 3 ) as usize ;
153158 let child_irq_cells = self . interrupt_cells ( ) as usize ;
154- let required_mask_len = child_addr_cells + child_irq_cells;
155- if mask. len ( ) < required_mask_len {
156- mask. resize ( required_mask_len, 0xffff_ffff ) ;
157- }
158159
159160 let encoded_address = [ child_addr_high, child_addr_mid, child_addr_low] ;
160161 let mut masked_child_address = Vec :: with_capacity ( child_addr_cells) ;
161162
162- // 使用迭代器替代不必要的范围循环
163- for ( idx, value) in encoded_address. iter ( ) . enumerate ( ) {
164- masked_child_address. push ( value & mask[ idx] ) ;
163+ // 应用 mask 到子地址
164+ for ( idx, value) in encoded_address. iter ( ) . take ( child_addr_cells) . enumerate ( ) {
165+ let mask_value = mask. get ( idx) . copied ( ) . unwrap_or ( 0xffff_ffff ) ;
166+ masked_child_address. push ( value & mask_value) ;
165167 }
166168
167- // 如果 encoded_address 比 mask 短,处理剩余的 mask 值
168- if encoded_address. len ( ) < child_addr_cells {
169- // 如果 encoded_address 比 mask 短,填充剩余的 0 值
170- let remaining_zeros = child_addr_cells - encoded_address. len ( ) ;
171- masked_child_address. extend ( core:: iter:: repeat_n ( 0 , remaining_zeros) ) ;
172- }
169+ // 如果 encoded_address 比 child_addr_cells 短,填充 0
170+ let remaining = child_addr_cells. saturating_sub ( encoded_address. len ( ) ) ;
171+ masked_child_address. extend ( core:: iter:: repeat_n ( 0 , remaining) ) ;
173172
174173 let encoded_irq = [ interrupt_pin as u32 ] ;
175174 let mut masked_child_irq = Vec :: with_capacity ( child_irq_cells) ;
176175
177- // 使用迭代器替代不必要的范围循环
178- let mask_start = child_addr_cells;
179- let mask_end = child_addr_cells + encoded_irq. len ( ) . min ( child_irq_cells) ;
180- for ( value, mask_value) in encoded_irq. iter ( ) . zip ( & mask[ mask_start..mask_end] ) {
176+ // 应用 mask 到子 IRQ
177+ for ( idx, value) in encoded_irq. iter ( ) . take ( child_irq_cells) . enumerate ( ) {
178+ let mask_value = mask
179+ . get ( child_addr_cells + idx)
180+ . copied ( )
181+ . unwrap_or ( 0xffff_ffff ) ;
181182 masked_child_irq. push ( value & mask_value) ;
182183 }
183184
184- // 如果 encoded_irq 比 child_irq_cells 短,处理剩余的 mask 值
185- if encoded_irq. len ( ) < child_irq_cells {
186- let remaining_zeros = child_irq_cells - encoded_irq. len ( ) ;
187- masked_child_irq. extend ( core:: iter:: repeat_n ( 0 , remaining_zeros) ) ;
188- }
185+ // 如果 encoded_irq 比 child_irq_cells 短,填充 0
186+ let remaining_irq = child_irq_cells. saturating_sub ( encoded_irq. len ( ) ) ;
187+ masked_child_irq. extend ( core:: iter:: repeat_n ( 0 , remaining_irq) ) ;
189188
190189 // 在 interrupt-map 中查找匹配的条目
191190 for mapping in & interrupt_map {
@@ -211,74 +210,102 @@ impl<'a> NodeRefPci<'a> {
211210 . find_property ( "interrupt-map" )
212211 . ok_or ( FdtError :: NotFound ) ?;
213212
214- let mut mask = self . interrupt_map_mask ( ) . ok_or ( FdtError :: NotFound ) ?;
213+ // 将 mask 和 data 转换为 Vec 以便索引访问
214+ let mask: Vec < u32 > = self
215+ . interrupt_map_mask ( )
216+ . ok_or ( FdtError :: NotFound ) ?
217+ . collect ( ) ;
215218
216- let mut data = prop. get_u32_iter ( ) ;
219+ let mut data = prop. as_reader ( ) ;
217220 let mut mappings = Vec :: new ( ) ;
218221
219222 // 计算每个条目的大小
220223 // 格式: <child-address child-irq interrupt-parent parent-address parent-irq...>
221224 let child_addr_cells = self . address_cells ( ) . unwrap_or ( 3 ) as usize ;
222225 let child_irq_cells = self . interrupt_cells ( ) as usize ;
223226
224- let required_mask_len = child_addr_cells + child_irq_cells;
225- if mask. len ( ) < required_mask_len {
226- mask. resize ( required_mask_len, 0xffff_ffff ) ;
227- }
228-
229- let mut idx = 0 ;
230- while idx < data. len ( ) {
227+ loop {
231228 // 解析子地址
232- if idx + child_addr_cells > data. len ( ) {
233- break ;
229+ let mut child_address = Vec :: with_capacity ( child_addr_cells) ;
230+ for _ in 0 ..child_addr_cells {
231+ match data. read_u32 ( ) {
232+ Some ( v) => child_address. push ( v) ,
233+ None => return Ok ( mappings) , // 数据结束
234+ }
234235 }
235- let child_address = data[ idx..idx + child_addr_cells] . to_vec ( ) ;
236- idx += child_addr_cells;
237236
238237 // 解析子 IRQ
239- if idx + child_irq_cells > data. len ( ) {
240- break ;
238+ let mut child_irq = Vec :: with_capacity ( child_irq_cells) ;
239+ for _ in 0 ..child_irq_cells {
240+ match data. read_u32 ( ) {
241+ Some ( v) => child_irq. push ( v) ,
242+ None => return Ok ( mappings) ,
243+ }
241244 }
242- let child_irq = data[ idx..idx + child_irq_cells] . to_vec ( ) ;
243- idx += child_irq_cells;
244245
245246 // 解析中断父 phandle
246- if idx >= data. len ( ) {
247- break ;
248- }
249- let interrupt_parent_raw = data [ idx ] ;
247+ let interrupt_parent_raw = match data. read_u32 ( ) {
248+ Some ( v ) => v ,
249+ None => return Ok ( mappings ) ,
250+ } ;
250251 let interrupt_parent = Phandle :: from ( interrupt_parent_raw) ;
251- idx += 1 ;
252252
253- // 通过 phandle 查找中断父节点以获取其 address_cells 和 interrupt_cells
253+ debug ! (
254+ "Looking for interrupt parent phandle: 0x{:x} (raw: {})" ,
255+ interrupt_parent. raw( ) ,
256+ interrupt_parent_raw
257+ ) ;
258+ debug ! (
259+ "Context phandle_map keys: {:?}" ,
260+ self . ctx
261+ . phandle_map
262+ . keys( )
263+ . map( |p| format!( "0x{:x}" , p. raw( ) ) )
264+ . collect:: <Vec <_>>( )
265+ ) ;
266+
267+ // 通过 phandle 查找中断父节点以获取其 #address-cells 和 #interrupt-cells
268+ // 根据 devicetree 规范,interrupt-map 中的 parent unit address 使用中断父节点的 #address-cells
254269 let ( parent_addr_cells, parent_irq_cells) =
255270 if let Some ( irq_parent) = self . ctx . find_by_phandle ( interrupt_parent) {
271+ debug ! ( "Found interrupt parent: {:?}" , irq_parent. name) ;
272+
273+ // 直接使用中断父节点的 #address-cells
256274 let addr_cells = irq_parent. address_cells ( ) . unwrap_or ( 0 ) as usize ;
275+
257276 let irq_cells = irq_parent
258- . find_property ( "#interrupt-cells" )
259- . and_then ( |p| match & p. kind {
260- PropertyKind :: Num ( v) => Some ( * v as usize ) ,
261- _ => None ,
262- } )
263- . unwrap_or ( 3 ) ;
277+ . get_property ( "#interrupt-cells" )
278+ . and_then ( |p| p. get_u32 ( ) )
279+ . unwrap_or ( 3 ) as usize ;
280+ debug ! (
281+ "irq_parent addr_cells: {}, irq_cells: {}" ,
282+ addr_cells, irq_cells
283+ ) ;
264284 ( addr_cells, irq_cells)
265285 } else {
286+ debug ! (
287+ "Interrupt parent phandle 0x{:x} NOT FOUND in context!" ,
288+ interrupt_parent. raw( )
289+ ) ;
266290 // 默认值:address_cells=0, interrupt_cells=3 (GIC 格式)
267291 ( 0 , 3 )
268292 } ;
269293
270294 // 跳过父地址 cells
271- if idx + parent_addr_cells > data. len ( ) {
272- break ;
295+ for _ in 0 ..parent_addr_cells {
296+ if data. read_u32 ( ) . is_none ( ) {
297+ return Ok ( mappings) ;
298+ }
273299 }
274- idx += parent_addr_cells;
275300
276301 // 解析父 IRQ
277- if idx + parent_irq_cells > data. len ( ) {
278- break ;
302+ let mut parent_irq = Vec :: with_capacity ( parent_irq_cells) ;
303+ for _ in 0 ..parent_irq_cells {
304+ match data. read_u32 ( ) {
305+ Some ( v) => parent_irq. push ( v) ,
306+ None => return Ok ( mappings) ,
307+ }
279308 }
280- let parent_irq = data[ idx..idx + parent_irq_cells] . to_vec ( ) ;
281- idx += parent_irq_cells;
282309
283310 // 应用 mask 到子地址和 IRQ
284311 let masked_address: Vec < u32 > = child_address
@@ -308,8 +335,6 @@ impl<'a> NodeRefPci<'a> {
308335 parent_irq,
309336 } ) ;
310337 }
311-
312- Ok ( mappings)
313338 }
314339}
315340
0 commit comments