bsp_define 0.1.57

微内核 BSP 硬件配置 trait 定义
Documentation
//! 中断控制器驱动 trait 定义

use core::{fmt::Display, result};

use semx_cpumask::Cpumask;

/// 中断错误
#[derive(Debug)]
pub enum IrqError {
    /// 无效参数
    Invalid,
    /// 操作不支持
    NotSupported,
}

/// 中断结果
pub type Result<T> = result::Result<T, IrqError>;

impl Display for IrqError {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        let error = match self {
            Self::Invalid => "Invalid args",
            Self::NotSupported => "Not supported",
        };
        write!(f, "{error}")
    }
}

bitflags::bitflags! {
    /// 中断触发类型
    #[derive(Clone, Copy, Default)]
    pub struct IrqType: u32 {
        /// 无类型
        const IRQ_TYPE_NONE = 0;
        /// 上升沿触发
        const IRQ_TYPE_EDGE_RISING = 0x1;
        /// 下降沿触发
        const IRQ_TYPE_EDGE_FALLING = 0x2;
        /// 上升沿触发或者下降沿触发
        const IRQ_TYPE_EDGE_BOTH = IrqType::IRQ_TYPE_EDGE_RISING.bits() | IrqType::IRQ_TYPE_EDGE_FALLING.bits();
        /// 高电平触发
        const IRQ_TYPE_LEVEL_HIGH = 0x4;
        /// 低电平触发
        const IRQ_TYPE_LEVEL_LOW = 0x8;
        /// 高低电平掩码
        const IRQ_TYPE_LEVEL_MASK = IrqType::IRQ_TYPE_LEVEL_HIGH.bits() | IrqType::IRQ_TYPE_LEVEL_LOW.bits();
        /// 总掩码
        const IRQ_TYPE_MASK = IrqType::IRQ_TYPE_EDGE_BOTH.bits() | IrqType::IRQ_TYPE_LEVEL_MASK.bits();
    }
}

/// 中断控制器特定的状态
#[derive(Clone, Copy)]
pub enum IrqchipIrqState {
    /// 中断挂起
    Pending,
    /// 中断在处理
    Active,
    /// 中断被禁用
    Masked,
    /// 中断信号高电平
    LineLevel,
}

/// 中断控制器实现
pub trait IrqchipImpl {
    /// 中断控制器名字
    const NAME: &'static str;

    /// 该中断控制器管理的中断数量
    const IRQS_MAX: usize;

    /// 应答中断
    fn irq_ack(&self, _hwirq: u32) {}
    /// 结束中断
    fn irq_eoi(&self, hwirq: u32);

    /// 禁用中断
    fn irq_disable(&self, hwirq: u32);
    /// 激活中断
    fn irq_enable(&self, hwirq: u32);

    /// 设置中断亲和性
    ///
    /// # Errors
    /// 中断号或者 cpumask 不正确会返回错误
    fn irq_set_affinity(&self, _hwirq: u32, _cpumask: Cpumask) -> Result<()> {
        Ok(())
    }

    /// 设置中断触发类型
    ///
    /// # Errors
    /// 中断号不正确会返回错误
    fn irq_set_type(&self, _hwirq: u32, _irq_type: IrqType) -> Result<()> {
        Ok(())
    }

    /// 获取中断控制器特定状态是否激活
    ///
    /// # Errors
    /// 中断号不正确会返回错误
    fn irq_get_irqchip_state(&self, _hwirq: u32, _which: IrqchipIrqState) -> Result<bool> {
        Err(IrqError::NotSupported)
    }

    /// 设置中断控制器特定状态
    ///
    /// # Errors
    /// 中断号或者设置状态不正确会返回错误
    fn irq_set_irqchip_state(
        &self,
        _hwirq: u32,
        _which: IrqchipIrqState,
        _state: bool,
    ) -> Result<()> {
        Err(IrqError::NotSupported)
    }

    /// 向特定处理器发送 IPI 中断
    fn ipi_send_single(&self, hwirq: u32, cpu: usize) {
        let cpumask = Cpumask::new();
        cpumask.set(cpu);
        self.ipi_send_mask(hwirq, &cpumask);
    }

    /// 向一组处理器发送 IPI 中断
    fn ipi_send_mask(&self, hwirq: u32, cpumask: &Cpumask);

    /// 硬中断回调
    ///
    /// 对应架构处理器直接调用该回调
    fn irq_handler(&self);

    /// 中断控制器初始化
    fn irq_init(&self);

    /// 中断控制器处理器初始化
    ///
    /// 该回调将在每个处理器上调用初始化 CPU 接口
    fn irq_init_cpu(&self) {}
}