fdt_edit/node/
interrupt_controller.rs

1use core::ops::Deref;
2
3use alloc::vec::Vec;
4
5use crate::node::gerneric::NodeRefGen;
6
7/// 中断控制器节点引用
8#[derive(Clone)]
9pub struct NodeRefInterruptController<'a> {
10    pub node: NodeRefGen<'a>,
11}
12
13impl<'a> NodeRefInterruptController<'a> {
14    pub fn try_from(node: NodeRefGen<'a>) -> Result<Self, NodeRefGen<'a>> {
15        if !is_interrupt_controller_node(&node) {
16            return Err(node);
17        }
18        Ok(Self { node })
19    }
20
21    /// 获取 #interrupt-cells 值
22    ///
23    /// 这决定了引用此控制器的中断需要多少个 cell 来描述
24    pub fn interrupt_cells(&self) -> Option<u32> {
25        self.find_property("#interrupt-cells")
26            .and_then(|prop| prop.get_u32())
27    }
28
29    /// 获取 #address-cells 值(用于 interrupt-map)
30    pub fn interrupt_address_cells(&self) -> Option<u32> {
31        self.find_property("#address-cells")
32            .and_then(|prop| prop.get_u32())
33    }
34
35    /// 检查是否是中断控制器
36    pub fn is_interrupt_controller(&self) -> bool {
37        // 检查 interrupt-controller 属性(空属性标记)
38        self.find_property("interrupt-controller").is_some()
39    }
40
41    /// 获取 compatible 列表
42    pub fn compatibles(&self) -> Vec<&str> {
43        self.node.compatibles().collect()
44    }
45}
46
47impl<'a> Deref for NodeRefInterruptController<'a> {
48    type Target = NodeRefGen<'a>;
49
50    fn deref(&self) -> &Self::Target {
51        &self.node
52    }
53}
54
55/// 检查节点是否是中断控制器
56fn is_interrupt_controller_node(node: &NodeRefGen) -> bool {
57    // 名称以 interrupt-controller 开头
58    if node.name().starts_with("interrupt-controller") {
59        return true;
60    }
61
62    // 或者有 interrupt-controller 属性
63    node.find_property("interrupt-controller").is_some()
64}