diff --git a/crates/domain/src/irq.rs b/crates/domain/src/irq.rs deleted file mode 100644 index 4839573..0000000 --- a/crates/domain/src/irq.rs +++ /dev/null @@ -1,87 +0,0 @@ -use types::id::{IrqId, ThreadId}; - -use crate::error::KernelError; - -const MAX_IRQS: usize = 256; - -pub struct IrqRoutingTable { - owners: [Option; MAX_IRQS], -} - -impl IrqRoutingTable { - pub fn new() -> Self { - Self { - owners: [None; MAX_IRQS], - } - } - - pub fn register(&mut self, irq: IrqId, thread: ThreadId) -> Result<(), KernelError> { - let idx = irq.raw() as usize; - if self.owners[idx].is_some() { - return Err(KernelError::IrqAlreadyOwned(irq)); - } - self.owners[idx] = Some(thread); - Ok(()) - } - - pub fn unregister(&mut self, irq: IrqId) { - self.owners[irq.raw() as usize] = None; - } - - pub fn owner(&self, irq: IrqId) -> Option { - self.owners[irq.raw() as usize] - } -} - -#[cfg(test)] -mod tests { - use super::*; - - fn irq(id: u16) -> IrqId { - IrqId::from_raw(id) - } - - fn thread(id: u16) -> ThreadId { - ThreadId::from_raw(id) - } - - #[test] - fn new_table_has_no_owners() { - let table = IrqRoutingTable::new(); - assert!(table.owner(irq(0)).is_none()); - assert!(table.owner(irq(10)).is_none()); - } - - #[test] - fn register_and_lookup() { - let mut table = IrqRoutingTable::new(); - table.register(irq(5), thread(1)).unwrap(); - assert_eq!(table.owner(irq(5)), Some(thread(1))); - } - - #[test] - fn register_already_owned_fails() { - let mut table = IrqRoutingTable::new(); - table.register(irq(5), thread(1)).unwrap(); - assert!(table.register(irq(5), thread(2)).is_err()); - } - - #[test] - fn unregister_then_reregister() { - let mut table = IrqRoutingTable::new(); - table.register(irq(5), thread(1)).unwrap(); - table.unregister(irq(5)); - assert!(table.owner(irq(5)).is_none()); - table.register(irq(5), thread(2)).unwrap(); - assert_eq!(table.owner(irq(5)), Some(thread(2))); - } - - #[test] - fn different_irqs_independent() { - let mut table = IrqRoutingTable::new(); - table.register(irq(0), thread(10)).unwrap(); - table.register(irq(1), thread(20)).unwrap(); - assert_eq!(table.owner(irq(0)), Some(thread(10))); - assert_eq!(table.owner(irq(1)), Some(thread(20))); - } -} diff --git a/crates/domain/src/irq/mod.rs b/crates/domain/src/irq/mod.rs new file mode 100644 index 0000000..335d4c4 --- /dev/null +++ b/crates/domain/src/irq/mod.rs @@ -0,0 +1,38 @@ +use types::id::{IrqId, ThreadId}; + +use crate::error::KernelError; + +#[cfg(test)] +#[path = "tests.rs"] +mod tests; + +const MAX_IRQS: usize = 256; + +pub struct IrqRoutingTable { + owners: [Option; MAX_IRQS], +} + +impl IrqRoutingTable { + pub fn new() -> Self { + Self { + owners: [None; MAX_IRQS], + } + } + + pub fn register(&mut self, irq: IrqId, thread: ThreadId) -> Result<(), KernelError> { + let idx = irq.raw() as usize; + if self.owners[idx].is_some() { + return Err(KernelError::IrqAlreadyOwned(irq)); + } + self.owners[idx] = Some(thread); + Ok(()) + } + + pub fn unregister(&mut self, irq: IrqId) { + self.owners[irq.raw() as usize] = None; + } + + pub fn owner(&self, irq: IrqId) -> Option { + self.owners[irq.raw() as usize] + } +} diff --git a/crates/domain/src/irq/tests.rs b/crates/domain/src/irq/tests.rs new file mode 100644 index 0000000..2954b97 --- /dev/null +++ b/crates/domain/src/irq/tests.rs @@ -0,0 +1,50 @@ +use super::*; +use types::id::{IrqId, ThreadId}; + +fn irq(id: u16) -> IrqId { + IrqId::from_raw(id) +} + +fn thread(id: u16) -> ThreadId { + ThreadId::from_raw(id) +} + +#[test] +fn new_table_has_no_owners() { + let table = IrqRoutingTable::new(); + assert!(table.owner(irq(0)).is_none()); + assert!(table.owner(irq(10)).is_none()); +} + +#[test] +fn register_and_lookup() { + let mut table = IrqRoutingTable::new(); + table.register(irq(5), thread(1)).unwrap(); + assert_eq!(table.owner(irq(5)), Some(thread(1))); +} + +#[test] +fn register_already_owned_fails() { + let mut table = IrqRoutingTable::new(); + table.register(irq(5), thread(1)).unwrap(); + assert!(table.register(irq(5), thread(2)).is_err()); +} + +#[test] +fn unregister_then_reregister() { + let mut table = IrqRoutingTable::new(); + table.register(irq(5), thread(1)).unwrap(); + table.unregister(irq(5)); + assert!(table.owner(irq(5)).is_none()); + table.register(irq(5), thread(2)).unwrap(); + assert_eq!(table.owner(irq(5)), Some(thread(2))); +} + +#[test] +fn different_irqs_independent() { + let mut table = IrqRoutingTable::new(); + table.register(irq(0), thread(10)).unwrap(); + table.register(irq(1), thread(20)).unwrap(); + assert_eq!(table.owner(irq(0)), Some(thread(10))); + assert_eq!(table.owner(irq(1)), Some(thread(20))); +} diff --git a/crates/platform/src/lib.rs b/crates/platform/src/lib.rs index 78e7dd5..61f0091 100644 --- a/crates/platform/src/lib.rs +++ b/crates/platform/src/lib.rs @@ -1,6 +1,6 @@ #![no_std] -use domain::{resource::MemoryRegion, thread::SavedContext}; +use domain::{memory::MemoryRegion, thread::SavedContext}; use types::{ address::{EntryPoint, StackPointer}, id::{CoreId, IrqId, ProcessId},