From 6552fa8059a9e2f63d009d0bad6e8a6a68634a1e Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Thu, 14 Aug 2025 11:34:00 +0300 Subject: [PATCH] irq: FullIrq -> IrqHandle --- kernel/driver/bsp/arm/src/pl011.rs | 12 +++++------- kernel/driver/bsp/arm/src/pl061.rs | 11 +++++------ kernel/driver/bsp/bcm283x/src/aux_uart.rs | 11 +++++------ kernel/driver/bsp/bcm283x/src/gpio.rs | 10 ++++------ kernel/driver/bsp/riscv/src/plic.rs | 8 ++++---- kernel/driver/net/stmmac/src/lib.rs | 11 ++++------- kernel/lib/device-api/src/interrupt.rs | 15 +++++++++++++-- kernel/lib/device-tree/src/driver/controller.rs | 8 ++++---- kernel/lib/device-tree/src/driver/traits.rs | 4 ++-- kernel/lib/device-tree/src/driver/tree.rs | 6 +++--- kernel/lib/device-tree/src/driver/util.rs | 5 ++--- kernel/src/arch/aarch64/exception.rs | 1 + kernel/src/arch/aarch64/gic/mod.rs | 11 ++++++----- kernel/src/arch/aarch64/timer.rs | 14 ++++++-------- kernel/src/device/serial/ns16550a.rs | 9 ++++----- kernel/src/device/serial/snps_dw_apb_uart.rs | 9 ++++----- 16 files changed, 72 insertions(+), 73 deletions(-) diff --git a/kernel/driver/bsp/arm/src/pl011.rs b/kernel/driver/bsp/arm/src/pl011.rs index af8eca24..ac2fd05e 100644 --- a/kernel/driver/bsp/arm/src/pl011.rs +++ b/kernel/driver/bsp/arm/src/pl011.rs @@ -1,12 +1,12 @@ use alloc::sync::Arc; use device_api::{ device::{Device, DeviceInitContext}, - interrupt::{FullIrq, InterruptHandler, IrqVector}, + interrupt::{InterruptHandler, IrqHandle, IrqVector}, }; use device_tree::driver::{device_tree_driver, Node, ProbeContext}; use libk::{ debug::DebugSink, - device::{external_interrupt_controller, manager::DEVICE_REGISTRY}, + device::manager::DEVICE_REGISTRY, vfs::{Terminal, TerminalInput, TerminalOutput}, }; use libk_mm::{address::PhysicalAddress, device::DeviceMemoryIo}; @@ -68,7 +68,7 @@ struct Pl011Inner { pub struct Pl011 { inner: OneTimeInit>>, base: PhysicalAddress, - irq: FullIrq, + irq: IrqHandle, } impl Io { @@ -164,14 +164,12 @@ impl Device for Pl011 { } unsafe fn init_irq(self: Arc) -> Result<(), Error> { - let intc = external_interrupt_controller()?; - - intc.register_irq(self.irq.irq, self.irq.options, self.clone())?; + self.irq.register(self.clone())?; { let io = self.inner.get().output().io.lock(); io.regs.IMSC.modify(IMSC::RXIM::SET); } - intc.enable_irq(self.irq.irq)?; + self.irq.enable()?; Ok(()) } diff --git a/kernel/driver/bsp/arm/src/pl061.rs b/kernel/driver/bsp/arm/src/pl061.rs index 5e96da9e..47d4e747 100644 --- a/kernel/driver/bsp/arm/src/pl061.rs +++ b/kernel/driver/bsp/arm/src/pl061.rs @@ -8,7 +8,7 @@ use device_api::{ GpioController, GpioInterruptEvent, GpioInterruptMode, GpioPinLevel, PinHandle, SinglePinDirection, }, - interrupt::{FullIrq, InterruptHandler, IrqVector}, + interrupt::{InterruptHandler, IrqHandle, IrqVector}, }; use device_tree::{ driver::{ @@ -17,7 +17,7 @@ use device_tree::{ }, DeviceTreePropertyRead, TProp, }; -use libk::{device::external_interrupt_controller, event::signal_gpio_event}; +use libk::event::signal_gpio_event; use libk_mm::device::DeviceMemoryIo; use libk_util::{bit::BitField, sync::IrqSafeSpinlock}; use tock_registers::{ @@ -50,7 +50,7 @@ register_structs! { struct Pl061 { #[allow(unused)] regs: IrqSafeSpinlock>, - irq: FullIrq, + irq: IrqHandle, clocks: Vec, resets: Vec, gpio_events: [AtomicU64; 8], @@ -69,9 +69,8 @@ impl Device for Pl061 { } unsafe fn init_irq(self: Arc) -> Result<(), Error> { - let intc = external_interrupt_controller()?; - intc.register_irq(self.irq.irq, self.irq.options, self.clone())?; - intc.enable_irq(self.irq.irq)?; + self.irq.register(self.clone())?; + self.irq.enable()?; Ok(()) } diff --git a/kernel/driver/bsp/bcm283x/src/aux_uart.rs b/kernel/driver/bsp/bcm283x/src/aux_uart.rs index 18420a6f..f5e256e7 100644 --- a/kernel/driver/bsp/bcm283x/src/aux_uart.rs +++ b/kernel/driver/bsp/bcm283x/src/aux_uart.rs @@ -2,12 +2,12 @@ use alloc::sync::Arc; use device_api::{ clock::ClockHandle, device::{Device, DeviceInitContext}, - interrupt::{FullIrq, InterruptHandler, IrqVector}, + interrupt::{InterruptHandler, IrqHandle, IrqVector}, }; use device_tree::driver::{device_tree_driver, Node, ProbeContext}; use libk::{ debug::DebugSink, - device::{external_interrupt_controller, manager::DEVICE_REGISTRY}, + device::manager::DEVICE_REGISTRY, vfs::{Terminal, TerminalInput, TerminalOutput}, }; use libk_mm::{address::PhysicalAddress, device::DeviceMemoryIo}; @@ -61,7 +61,7 @@ struct Inner { /// Broadcom 283x mini-UART driver pub struct Bcm2835AuxUart { base: PhysicalAddress, - irq: FullIrq, + irq: IrqHandle, clock: ClockHandle, inner: OneTimeInit>>, } @@ -171,9 +171,8 @@ impl Device for Bcm2835AuxUart { } unsafe fn init_irq(self: Arc) -> Result<(), Error> { - let intc = external_interrupt_controller()?; - intc.register_irq(self.irq.irq, self.irq.options, self.clone())?; - intc.enable_irq(self.irq.irq)?; + self.irq.register(self.clone())?; + self.irq.enable()?; let inner = self.inner.get().output(); let regs = inner.regs.lock(); diff --git a/kernel/driver/bsp/bcm283x/src/gpio.rs b/kernel/driver/bsp/bcm283x/src/gpio.rs index e6e15f58..bdc5879f 100644 --- a/kernel/driver/bsp/bcm283x/src/gpio.rs +++ b/kernel/driver/bsp/bcm283x/src/gpio.rs @@ -2,7 +2,7 @@ use alloc::sync::Arc; use device_api::{ device::{Device, DeviceInitContext}, gpio::{GpioController, GpioInterruptEvent, PinHandle}, - interrupt::{FullIrq, InterruptHandler, IrqVector}, + interrupt::{InterruptHandler, IrqHandle, IrqVector}, }; use device_tree::{ driver::{ @@ -11,7 +11,6 @@ use device_tree::{ }, DeviceTreePropertyRead, TProp, }; -use libk::device::external_interrupt_controller; use libk_mm::device::DeviceMemoryIo; use libk_util::sync::IrqSafeSpinlock; use tock_registers::{ @@ -69,7 +68,7 @@ register_structs! { struct Bcm2711Gpio { regs: IrqSafeSpinlock>, #[allow(unused)] - irqs: [FullIrq; 2], + irqs: [IrqHandle; 2], } impl Regs { @@ -142,10 +141,9 @@ impl Device for Bcm2711Gpio { regs.configure_pin_interrupts(pin, false, false, false, false); } - let intc = external_interrupt_controller()?; for irq in self.irqs.iter() { - intc.register_irq(irq.irq, irq.options, self.clone())?; - intc.enable_irq(irq.irq)?; + irq.register(self.clone())?; + irq.enable()?; } Ok(()) diff --git a/kernel/driver/bsp/riscv/src/plic.rs b/kernel/driver/bsp/riscv/src/plic.rs index b161e85c..70419f5d 100644 --- a/kernel/driver/bsp/riscv/src/plic.rs +++ b/kernel/driver/bsp/riscv/src/plic.rs @@ -2,8 +2,8 @@ use alloc::{sync::Arc, vec::Vec}; use device_api::{ device::{Device, DeviceInitContext}, interrupt::{ - ExternalInterruptController, FixedInterruptTable, FullIrq, InterruptHandler, - InterruptTable, Irq, IrqOptions, IrqVector, + ExternalInterruptController, FixedInterruptTable, InterruptHandler, InterruptTable, Irq, + IrqHandle, IrqOptions, IrqVector, }, }; use device_tree::{ @@ -261,9 +261,9 @@ impl Device for Plic { } impl DeviceTreeInterruptController for Plic { - fn map_interrupt(&self, property: &TProp, offset: usize) -> Option { + fn map_interrupt(&self, property: &TProp, offset: usize) -> Option { let num = property.read_cell(offset, 1)?; - Some(FullIrq { + Some(IrqHandle { irq: Irq::External(num as _), options: IrqOptions::default(), }) diff --git a/kernel/driver/net/stmmac/src/lib.rs b/kernel/driver/net/stmmac/src/lib.rs index 2831dffd..598315f8 100644 --- a/kernel/driver/net/stmmac/src/lib.rs +++ b/kernel/driver/net/stmmac/src/lib.rs @@ -8,14 +8,13 @@ use device_api::{ clock::{ClockHandle, ResetHandle}, device::{Device, DeviceInitContext}, dma::DmaAllocator, - interrupt::{FullIrq, InterruptHandler, IrqVector}, + interrupt::{InterruptHandler, IrqHandle, IrqVector}, }; use device_tree::driver::{ device_tree_driver, util::read_mac_address, InitSequence, Node, ProbeContext, }; use futures_util::task::AtomicWaker; use libk::{ - device::external_interrupt_controller, dma::DmaBuffer, error::Error, task::runtime::{self, psleep, pwait}, @@ -68,7 +67,7 @@ struct Stmmac { rst_stmmaceth: ResetHandle, rst_ahb: ResetHandle, - irq: FullIrq, + irq: IrqHandle, softirq_events: BitmapEvent, inner: OneTimeInit, @@ -184,9 +183,7 @@ impl Device for Stmmac { } let dma = self.dma.init(cx.dma_allocator.clone()); - let intc = external_interrupt_controller()?; - - intc.register_irq(self.irq.irq, self.irq.options, self.clone())?; + self.irq.register(self.clone())?; let tx_ring_capacity = 32; let rx_ring_capacity = 32; @@ -350,7 +347,7 @@ impl Device for Stmmac { ygg_driver_net_core::register_interface(NetworkInterfaceType::Ethernet, self.clone()); self.iface_id.init(iface.id()); - intc.enable_irq(self.irq.irq)?; + self.irq.enable()?; let p = self.clone(); runtime::spawn(async move { p.softirq().await })?; diff --git a/kernel/lib/device-api/src/interrupt.rs b/kernel/lib/device-api/src/interrupt.rs index 1cc4b5bc..ed130a70 100644 --- a/kernel/lib/device-api/src/interrupt.rs +++ b/kernel/lib/device-api/src/interrupt.rs @@ -3,10 +3,11 @@ use yggdrasil_abi::error::Error; use crate::device::Device; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct FullIrq { +#[derive(Clone)] +pub struct IrqHandle { pub irq: Irq, pub options: IrqOptions, + pub intc: Arc, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -154,6 +155,16 @@ pub struct FixedInterruptTable { rows: [Option>; N], } +impl IrqHandle { + pub fn register(&self, handler: Arc) -> Result<(), Error> { + self.intc.register_irq(self.irq, self.options, handler) + } + + pub fn enable(&self) -> Result<(), Error> { + self.intc.enable_irq(self.irq) + } +} + impl FixedInterruptTable { pub const fn new() -> Self { Self { diff --git a/kernel/lib/device-tree/src/driver/controller.rs b/kernel/lib/device-tree/src/driver/controller.rs index 423abd31..183db688 100644 --- a/kernel/lib/device-tree/src/driver/controller.rs +++ b/kernel/lib/device-tree/src/driver/controller.rs @@ -3,7 +3,7 @@ use alloc::sync::Arc; use device_api::{ clock::{ClockHandle, ResetHandle}, gpio::PinHandle, - interrupt::FullIrq, + interrupt::IrqHandle, }; use fdt_rs::spec::Phandle; @@ -83,14 +83,14 @@ pub fn map_interrupt_at( interrupt_controller: &Arc, property: &TProp, offset: usize, -) -> Option { +) -> Option { let interrupt_controller = interrupt_controller.interrupt_controller.try_get()?; - interrupt_controller.map_interrupt(property, offset) + interrupt_controller.clone().map_interrupt(property, offset) } /// Same as [map_interrupt_at], but uses a phandle to address the `interrupt-controller` node /// and a scaled `index`. -pub fn map_interrupt(phandle: Phandle, property: &TProp, index: usize) -> Option { +pub fn map_interrupt(phandle: Phandle, property: &TProp, index: usize) -> Option { let interrupt_controller = lookup_phandle(phandle, true)?; let interrupt_cells = interrupt_controller.self_interrupt_cells()?; map_interrupt_at(&interrupt_controller, property, index * interrupt_cells) diff --git a/kernel/lib/device-tree/src/driver/traits.rs b/kernel/lib/device-tree/src/driver/traits.rs index 50bdc510..359430bf 100644 --- a/kernel/lib/device-tree/src/driver/traits.rs +++ b/kernel/lib/device-tree/src/driver/traits.rs @@ -7,7 +7,7 @@ use device_api::{ clock::{ClockHandle, ResetHandle}, device::Device, gpio::PinHandle, - interrupt::{ExternalInterruptController, FullIrq}, + interrupt::{ExternalInterruptController, IrqHandle}, }; use libk::error::Error; @@ -25,7 +25,7 @@ pub trait Driver: Sync { pub trait DeviceTreeInterruptController { /// Reads interrupt information from `property` at given `offset` and maps it to /// the interrupt used by the controller - fn map_interrupt(&self, property: &TProp, offset: usize) -> Option; + fn map_interrupt(self: Arc, property: &TProp, offset: usize) -> Option; /// Returns the [ExternalInterruptController] implementor of this node fn as_interrupt_controller(self: Arc) -> Arc; diff --git a/kernel/lib/device-tree/src/driver/tree.rs b/kernel/lib/device-tree/src/driver/tree.rs index 33eff3ec..47f65fdf 100644 --- a/kernel/lib/device-tree/src/driver/tree.rs +++ b/kernel/lib/device-tree/src/driver/tree.rs @@ -10,7 +10,7 @@ use device_api::{ clock::{ClockController, ClockHandle, ResetHandle}, device::{Device, DeviceInitContext}, gpio::PinHandle, - interrupt::{ExternalInterruptController, FullIrq, MessageInterruptController}, + interrupt::{ExternalInterruptController, IrqHandle, MessageInterruptController}, }; use fdt_rs::spec::Phandle; use libk::dma::DummyDmaAllocator; @@ -410,7 +410,7 @@ impl Node { /// Reads interrupt information from `interrupts[index]` property, mapped by the node's /// `interrupt-parent`. - pub fn interrupt(&self, index: usize) -> Option { + pub fn interrupt(&self, index: usize) -> Option { let interrupts = self.property("interrupts")?; let phandle = self.interrupt_parent?; map_interrupt(phandle, &interrupts, index) @@ -418,7 +418,7 @@ impl Node { /// Same as [Node::interrupt], but allows specifying other property to read the information /// from. - pub fn interrupt_from(&self, property: &TProp, index: usize) -> Option { + pub fn interrupt_from(&self, property: &TProp, index: usize) -> Option { let phandle = self.interrupt_parent?; map_interrupt(phandle, property, index) } diff --git a/kernel/lib/device-tree/src/driver/util.rs b/kernel/lib/device-tree/src/driver/util.rs index 83c50ec1..2406215d 100644 --- a/kernel/lib/device-tree/src/driver/util.rs +++ b/kernel/lib/device-tree/src/driver/util.rs @@ -3,7 +3,7 @@ use alloc::sync::Arc; use device_api::{ gpio::{GpioPinConfig, GpioPinLevel, InputPinBias, OutputPinBias}, - interrupt::{FullIrq, MessageInterruptController}, + interrupt::{IrqHandle, MessageInterruptController}, }; use fdt_rs::prelude::PropReader; use yggdrasil_abi::net::MacAddress; @@ -44,7 +44,6 @@ pub struct GenericPinctrlConfig { } /// Represents an entry in a PCIe-controller's `interrupt-map` field -#[derive(Debug)] pub struct PcieInterruptEntry { /// PCI address bus pub bus: u8, @@ -57,7 +56,7 @@ pub struct PcieInterruptEntry { /// Destination interrupt controller pub interrupt_controller: Arc, /// Destination IRQ options - pub irq: FullIrq, + pub irq: IrqHandle, } /// Represents a single PCI address (Requester ID for a MSI(-x)) diff --git a/kernel/src/arch/aarch64/exception.rs b/kernel/src/arch/aarch64/exception.rs index f641cc82..7d41dab0 100644 --- a/kernel/src/arch/aarch64/exception.rs +++ b/kernel/src/arch/aarch64/exception.rs @@ -310,6 +310,7 @@ fn el0_sync_inner(frame: &mut ExceptionFrame) { } fn irq_common() { + // TODO some concept of "root" interrupt controller external_interrupt_controller() .unwrap() .handle_pending_irqs(); diff --git a/kernel/src/arch/aarch64/gic/mod.rs b/kernel/src/arch/aarch64/gic/mod.rs index c181447b..8557e4e4 100644 --- a/kernel/src/arch/aarch64/gic/mod.rs +++ b/kernel/src/arch/aarch64/gic/mod.rs @@ -8,9 +8,9 @@ use alloc::sync::Arc; use device_api::{ device::{Device, DeviceInitContext}, interrupt::{ - ExternalInterruptController, FixedInterruptTable, FullIrq, InterruptHandler, - InterruptTable, IpiDeliveryTarget, IpiMessage, Irq, IrqLevel, IrqOptions, IrqTrigger, - IrqVector, LocalInterruptController, + ExternalInterruptController, FixedInterruptTable, InterruptHandler, InterruptTable, + IpiDeliveryTarget, IpiMessage, Irq, IrqHandle, IrqLevel, IrqOptions, IrqTrigger, IrqVector, + LocalInterruptController, }, }; use device_tree::{ @@ -204,7 +204,7 @@ impl LocalInterruptController for Gic { } impl DeviceTreeInterruptController for Gic { - fn map_interrupt(&self, property: &TProp, offset: usize) -> Option { + fn map_interrupt(self: Arc, property: &TProp, offset: usize) -> Option { // IRQ_TYPE_NONE - 0 // IRQ_TYPE_EDGE_RISING - 1 // IRQ_TYPE_EDGE_FALLING - 2 @@ -230,9 +230,10 @@ impl DeviceTreeInterruptController for Gic { _ => return None, }; - Some(FullIrq { + Some(IrqHandle { irq, options: IrqOptions { trigger, level }, + intc: self.clone(), }) } diff --git a/kernel/src/arch/aarch64/timer.rs b/kernel/src/arch/aarch64/timer.rs index 5242ca86..8e7e1d61 100644 --- a/kernel/src/arch/aarch64/timer.rs +++ b/kernel/src/arch/aarch64/timer.rs @@ -7,16 +7,16 @@ use abi::{error::Error, time::NANOSECONDS_IN_SECOND}; use alloc::sync::Arc; use device_api::{ device::{Device, DeviceInitContext}, - interrupt::{FullIrq, InterruptHandler, IrqVector}, + interrupt::{InterruptHandler, IrqHandle, IrqVector}, }; use device_tree::driver::{device_tree_driver, Node, ProbeContext}; use kernel_arch::task::Scheduler; -use libk::{arch::Cpu, device::external_interrupt_controller, task::runtime, time}; +use libk::{arch::Cpu, task::runtime, time}; use tock_registers::interfaces::{ReadWriteable, Readable, Writeable}; /// ARM Generic Timer driver pub struct ArmTimer { - irq: FullIrq, + irq: IrqHandle, } /// ARM timer tick interval (in some time units?) @@ -63,14 +63,12 @@ impl Device for ArmTimer { unsafe fn init_irq(self: Arc) -> Result<(), Error> { log::info!("ARM Generic Timer frequency={}Hz", CNTFRQ_EL0.get()); - let intc = external_interrupt_controller()?; - - intc.register_irq(self.irq.irq, self.irq.options, self.clone())?; + self.irq.register(self.clone())?; CNTP_CTL_EL0.modify(CNTP_CTL_EL0::IMASK::CLEAR); CNTP_TVAL_EL0.set(TICK_INTERVAL); - intc.enable_irq(self.irq.irq)?; + self.irq.enable()?; Ok(()) } @@ -82,7 +80,7 @@ impl ArmTimer { /// # Safety /// /// The caller must ensure the function has not been called before. - pub const unsafe fn new(irq: FullIrq) -> Self { + pub const unsafe fn new(irq: IrqHandle) -> Self { Self { irq } } } diff --git a/kernel/src/device/serial/ns16550a.rs b/kernel/src/device/serial/ns16550a.rs index 240ee2f2..706102e8 100644 --- a/kernel/src/device/serial/ns16550a.rs +++ b/kernel/src/device/serial/ns16550a.rs @@ -3,7 +3,7 @@ use abi::{error::Error, io::TerminalOptions}; use alloc::sync::Arc; use device_api::{ device::{Device, DeviceInitContext}, - interrupt::{FullIrq, InterruptHandler, IrqVector}, + interrupt::{InterruptHandler, IrqHandle, IrqVector}, }; use device_tree::driver::{device_tree_driver, Node, ProbeContext}; use libk::{ @@ -79,7 +79,7 @@ struct Inner { pub struct Ns16550a { inner: OneTimeInit>>, base: PhysicalAddress, - irq: FullIrq, + irq: IrqHandle, } impl Io { @@ -135,9 +135,8 @@ impl Device for Ns16550a { } unsafe fn init_irq(self: Arc) -> Result<(), Error> { - let intc = external_interrupt_controller()?; - intc.register_irq(self.irq.irq, self.irq.options, self.clone())?; - intc.enable_irq(self.irq.irq)?; + self.irq.register(self.clone())?; + self.irq.enable()?; let io = self.inner.get().output().io.lock(); io.regs.IER.modify(IER::RDR::SET); Ok(()) diff --git a/kernel/src/device/serial/snps_dw_apb_uart.rs b/kernel/src/device/serial/snps_dw_apb_uart.rs index b1f5ba4b..dc8bc3b3 100644 --- a/kernel/src/device/serial/snps_dw_apb_uart.rs +++ b/kernel/src/device/serial/snps_dw_apb_uart.rs @@ -4,7 +4,7 @@ use alloc::sync::Arc; use device_api::{ clock::{ClockHandle, Hertz, ResetHandle}, device::{Device, DeviceInitContext}, - interrupt::{FullIrq, InterruptHandler, IrqVector}, + interrupt::{InterruptHandler, IrqHandle, IrqVector}, }; use device_tree::driver::{device_tree_driver, Node, ProbeContext}; use libk::{ @@ -110,7 +110,7 @@ struct Inner { /// Synopsys DesignWare 8250 UART pub struct DwUart { base: PhysicalAddress, - irq: FullIrq, + irq: IrqHandle, clk_baud: ClockHandle, #[allow(unused)] clk_apb: Option, @@ -241,9 +241,8 @@ impl Device for DwUart { } unsafe fn init_irq(self: Arc) -> Result<(), Error> { - let intc = external_interrupt_controller()?; - intc.register_irq(self.irq.irq, Default::default(), self.clone())?; - intc.enable_irq(self.irq.irq)?; + self.irq.register(self.clone())?; + self.irq.enable()?; let output = self.inner.get().output(); let io = output.io.lock();