Nothing to see here, move along meow
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 2.6 kB View raw
1use crate::sync::IrqMutex; 2 3use crate::arch::idt::IrqVector; 4use crate::cap::object::IrqSource; 5use crate::cap::pool::POOL; 6use crate::ipc::notification; 7use crate::proc::PROCESSES; 8use crate::types::{Generation, NotificationBit, ObjPhys}; 9 10const MAX_IRQ_HANDLERS: usize = 32; 11 12#[derive(Clone, Copy)] 13struct IrqBinding { 14 vector: IrqVector, 15 notification_phys: ObjPhys, 16 notification_gen: Generation, 17 bit: NotificationBit, 18} 19 20static BINDINGS: IrqMutex<[Option<IrqBinding>; MAX_IRQ_HANDLERS], 2> = 21 IrqMutex::new([None; MAX_IRQ_HANDLERS]); 22 23pub fn bind( 24 vector: IrqVector, 25 source: IrqSource, 26 notification_phys: ObjPhys, 27 notification_gen: Generation, 28 bit: NotificationBit, 29) -> Result<(), crate::error::KernelError> { 30 let mut bindings = BINDINGS.lock(); 31 let slot = bindings 32 .iter() 33 .enumerate() 34 .find(|(_, b)| b.is_none()) 35 .map(|(i, _)| i); 36 37 match slot { 38 Some(i) => { 39 bindings[i] = Some(IrqBinding { 40 vector, 41 notification_phys, 42 notification_gen, 43 bit, 44 }); 45 match source { 46 IrqSource::Ioapic { gsi } => { 47 crate::arch::ioapic::route_irq(gsi, vector, 0); 48 crate::arch::ioapic::mask_irq(gsi); 49 } 50 IrqSource::Msix { .. } => {} 51 } 52 Ok(()) 53 } 54 None => Err(crate::error::KernelError::ResourceExhausted), 55 } 56} 57 58pub fn unbind_by_vector(vector: IrqVector) { 59 let mut bindings = BINDINGS.lock(); 60 bindings.iter_mut().for_each(|slot| { 61 if slot.as_ref().is_some_and(|b| b.vector == vector) { 62 *slot = None; 63 } 64 }); 65} 66 67pub fn handle_irq(vector: IrqVector) { 68 let bindings = BINDINGS.lock(); 69 let found = bindings 70 .iter() 71 .find_map(|b| b.as_ref().filter(|binding| binding.vector == vector)); 72 73 if let Some(binding) = found { 74 let bits = binding.bit.mask(); 75 let obj_id = binding.notification_phys; 76 let obj_gen = binding.notification_gen; 77 drop(bindings); 78 79 let mut ptable = PROCESSES.lock(); 80 let mut pool = POOL.lock_after(&ptable); 81 if let Ok(notif) = 82 pool.write_as::<lancer_core::object_layout::NotificationObject>(obj_id, obj_gen) 83 { 84 notif.word |= bits; 85 match notif.waiter_count > 0 { 86 true => notification::drain_and_wake(notif, &mut ptable), 87 false => {} 88 } 89 } 90 } 91}