From 01ebf09e12bb4c20a6d409232573d5b031b75bcc Mon Sep 17 00:00:00 2001 From: Ivan Velickovic Date: Tue, 20 Feb 2024 11:41:55 +1100 Subject: [PATCH] Add support for x86 MSI and IOAPIC IRQs Signed-off-by: Ivan Velickovic --- crates/sel4-capdl-initializer/core/src/lib.rs | 22 ++++++++ .../sel4-capdl-initializer/types/src/spec.rs | 50 +++++++++++++++++ .../types/src/traverse.rs | 2 + .../sel4/src/arch/x86/arch/x64/invocations.rs | 56 ++++++++++++++++++- 4 files changed, 127 insertions(+), 3 deletions(-) diff --git a/crates/sel4-capdl-initializer/core/src/lib.rs b/crates/sel4-capdl-initializer/core/src/lib.rs index c911ee169..e4aee78be 100644 --- a/crates/sel4-capdl-initializer/core/src/lib.rs +++ b/crates/sel4-capdl-initializer/core/src/lib.rs @@ -359,6 +359,28 @@ impl<'a, N: ObjectName, D: Content, M: GetEmbeddedFrame, B: BorrowMut<[PerObject } } } + #[sel4_cfg(any(ARCH_IA32, ARCH_X86_64))] + Object::IrqMsi(obj) => { + init_thread::slot::IRQ_CONTROL.cap().irq_control_get_msi( + obj.extra.pci_bus, + obj.extra.pci_dev, + obj.extra.pci_func, + obj.extra.handle, + *irq, + &cslot_to_relative_cptr(slot), + )?; + } + #[sel4_cfg(any(ARCH_IA32, ARCH_X86_64))] + Object::IrqIoapic(obj) => { + init_thread::slot::IRQ_CONTROL.cap().irq_control_get_ioapic( + obj.extra.ioapic, + obj.extra.pin, + obj.extra.level, + obj.extra.polarity, + *irq, + &cslot_to_relative_cptr(slot), + )?; + } _ => { panic!(); } diff --git a/crates/sel4-capdl-initializer/types/src/spec.rs b/crates/sel4-capdl-initializer/types/src/spec.rs index f0bfa01a3..643695734 100644 --- a/crates/sel4-capdl-initializer/types/src/spec.rs +++ b/crates/sel4-capdl-initializer/types/src/spec.rs @@ -76,6 +76,8 @@ pub enum Object<'a, D, M> { PageTable(object::PageTable<'a>), AsidPool(object::AsidPool), ArmIrq(object::ArmIrq<'a>), + IrqMsi(object::IrqMsi<'a>), + IrqIoapic(object::IrqIoapic<'a>), SchedContext(object::SchedContext), Reply, } @@ -104,6 +106,8 @@ pub enum Cap { PageTable(cap::PageTable), AsidPool(cap::AsidPool), ArmIrqHandler(cap::ArmIrqHandler), + IrqMSIHandler(cap::IrqMSIHandler), + IrqIOAPICHandler(cap::IrqIOAPICHandler), SchedContext(cap::SchedContext), Reply(cap::Reply), } @@ -122,6 +126,8 @@ impl Cap { Cap::PageTable(cap) => cap.object, Cap::AsidPool(cap) => cap.object, Cap::ArmIrqHandler(cap) => cap.object, + Cap::IrqMSIHandler(cap) => cap.object, + Cap::IrqIOAPICHandler(cap) => cap.object, Cap::SchedContext(cap) => cap.object, Cap::Reply(cap) => cap.object, } @@ -221,6 +227,38 @@ pub mod object { pub target: Word, } + #[derive(Debug, Clone, Eq, PartialEq, IsObject, IsObjectWithCapTable)] + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + pub struct IrqMsi<'a> { + pub slots: Indirect<'a, [CapTableEntry]>, + pub extra: Indirect<'a, IrqMSIExtraInfo>, + } + + #[derive(Debug, Clone, Eq, PartialEq)] + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + pub struct IrqMSIExtraInfo { + pub handle: Word, + pub pci_bus: Word, + pub pci_dev: Word, + pub pci_func: Word, + } + + #[derive(Debug, Clone, Eq, PartialEq, IsObject, IsObjectWithCapTable)] + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + pub struct IrqIoapic<'a> { + pub slots: Indirect<'a, [CapTableEntry]>, + pub extra: Indirect<'a, IrqIOAPICExtraInfo>, + } + + #[derive(Debug, Clone, Eq, PartialEq)] + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + pub struct IrqIOAPICExtraInfo { + pub ioapic: Word, + pub pin: Word, + pub level: Word, + pub polarity: Word, + } + #[derive(Debug, Clone, Eq, PartialEq, IsObject)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct SchedContext { @@ -319,6 +357,18 @@ pub mod cap { pub object: ObjectId, } + #[derive(Debug, Clone, Eq, PartialEq, IsCap)] + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + pub struct IrqMSIHandler { + pub object: ObjectId, + } + + #[derive(Debug, Clone, Eq, PartialEq, IsCap)] + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + pub struct IrqIOAPICHandler { + pub object: ObjectId, + } + #[derive(Debug, Clone, Eq, PartialEq, IsCap)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct SchedContext { diff --git a/crates/sel4-capdl-initializer/types/src/traverse.rs b/crates/sel4-capdl-initializer/types/src/traverse.rs index b8c9bc0b0..c33aff46b 100644 --- a/crates/sel4-capdl-initializer/types/src/traverse.rs +++ b/crates/sel4-capdl-initializer/types/src/traverse.rs @@ -40,6 +40,8 @@ impl<'a, N, D, M> Spec<'a, N, D, M> { Object::PageTable(obj) => Object::PageTable(obj.clone()), Object::AsidPool(obj) => Object::AsidPool(obj.clone()), Object::ArmIrq(obj) => Object::ArmIrq(obj.clone()), + Object::IrqMsi(obj) => Object::IrqMsi(obj.clone()), + Object::IrqIoapic(obj) => Object::IrqIoapic(obj.clone()), Object::SchedContext(obj) => Object::SchedContext(obj.clone()), Object::Reply => Object::Reply, }, diff --git a/crates/sel4/src/arch/x86/arch/x64/invocations.rs b/crates/sel4/src/arch/x86/arch/x64/invocations.rs index 235c740aa..0b9aa7fd4 100644 --- a/crates/sel4/src/arch/x86/arch/x64/invocations.rs +++ b/crates/sel4/src/arch/x86/arch/x64/invocations.rs @@ -5,7 +5,8 @@ // use crate::{ - cap::*, AbsoluteCPtr, Cap, CapRights, Error, FrameType, InvocationContext, Result, VmAttributes, + cap::*, AbsoluteCPtr, Cap, CapRights, Error, FrameType, InvocationContext, Result, + VmAttributes, Word, }; impl Cap { @@ -91,8 +92,57 @@ impl PageTable { } } -// TODO -impl IrqControl {} +impl IrqControl { + /// Corresponds to `seL4_IRQControl_GetIOAPIC`. + pub fn irq_control_get_ioapic( + self, + ioapic: Word, + pin: Word, + level: Word, + polarity: Word, + vector: Word, + dst: &AbsoluteCPtr, + ) -> Result<()> { + Error::wrap(self.invoke(|cptr, ipc_buffer| { + ipc_buffer.inner_mut().seL4_IRQControl_GetIOAPIC( + cptr.bits(), + dst.root().bits(), + dst.path().bits(), + dst.path().depth_for_kernel(), + ioapic, + pin, + level, + polarity, + vector, + ) + })) + } + + /// Corresponds to `seL4_IRQControl_GetMSI`. + pub fn irq_control_get_msi( + self, + pci_bus: Word, + pci_dev: Word, + pci_func: Word, + handle: Word, + vector: Word, + dst: &AbsoluteCPtr, + ) -> Result<()> { + Error::wrap(self.invoke(|cptr, ipc_buffer| { + ipc_buffer.inner_mut().seL4_IRQControl_GetMSI( + cptr.bits(), + dst.root().bits(), + dst.path().bits(), + dst.path().depth_for_kernel(), + pci_bus, + pci_dev, + pci_func, + handle, + vector, + ) + })) + } +} impl AsidControl { /// Corresponds to `seL4_X86_ASIDControl_MakePool`.