driver_interface/
interrupt_controller.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
use core::{error::Error, fmt::Debug};

use crate::{custom_type, DriverGeneric, RegAddress};
use alloc::{boxed::Box, vec::Vec};

custom_type!(IrqId, usize, "{:#x}");
custom_type!(CpuId, usize, "{:#x}");

pub type Hardware = Box<dyn Interface>;
pub type ProbeFn = fn(regs: Vec<RegAddress>) -> Hardware;
pub type HardwareCPU = Box<dyn InterfaceCPU>;

pub trait InterfaceCPU: Send {
    fn get_and_acknowledge_interrupt(&self) -> Option<IrqId>;
    fn end_interrupt(&self, irq: IrqId);
    fn irq_enable(&self, irq: IrqId);
    fn irq_disable(&self, irq: IrqId);
    fn set_priority(&self, irq: IrqId, priority: usize);
    fn set_trigger(&self, irq: IrqId, triger: Trigger);
    fn set_bind_cpu(&self, irq: IrqId, cpu_list: &[CpuId]);
    fn parse_fdt_config(&self, prop_interrupts: &[u32]) -> Result<IrqConfig, Box<dyn Error>>;
}

pub trait Interface: DriverGeneric {
    fn current_cpu_setup(&self) -> HardwareCPU;
}

/// The trigger configuration for an interrupt.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Trigger {
    EdgeBoth,
    EdgeRising,
    EdgeFailling,
    LevelHigh,
    LevelLow,
}

#[derive(Debug, Clone)]
pub struct IrqConfig {
    pub irq: IrqId,
    pub trigger: Trigger,
}