Nothing to see here, move along
at main 215 lines 5.3 kB view raw
1use crate::types::Pid; 2 3pub use lancer_core::object_tag::ObjectTag; 4 5#[derive(Debug, Clone, Copy)] 6pub struct PidQueue { 7 pub head: Option<Pid>, 8 pub tail: Option<Pid>, 9 len: u16, 10} 11 12impl PidQueue { 13 pub const fn new() -> Self { 14 Self { 15 head: None, 16 tail: None, 17 len: 0, 18 } 19 } 20 21 #[allow(dead_code)] 22 pub const fn len(&self) -> u16 { 23 self.len 24 } 25 26 #[allow(dead_code)] 27 pub const fn is_empty(&self) -> bool { 28 self.len == 0 29 } 30 31 pub fn check_capacity(&self) -> Result<(), crate::error::KernelError> { 32 if (self.len as usize) < crate::types::MAX_PIDS { 33 Ok(()) 34 } else { 35 Err(crate::error::KernelError::ResourceExhausted) 36 } 37 } 38 39 pub fn inc_len(&mut self) -> Result<(), crate::error::KernelError> { 40 self.len = self 41 .len 42 .checked_add(1) 43 .ok_or(crate::error::KernelError::ResourceExhausted)?; 44 Ok(()) 45 } 46 47 pub fn dec_len(&mut self) { 48 match self.len.checked_sub(1) { 49 Some(n) => self.len = n, 50 None => { 51 crate::show!(ipc, error, "pidqueue dec_len underflow, clamping to 0"); 52 self.len = 0; 53 } 54 } 55 } 56 57 pub fn validate(&self, next_link: impl Fn(Pid) -> Option<Pid>) -> bool { 58 let head_tail_ok = match self.len { 59 0 => self.head.is_none() && self.tail.is_none(), 60 _ => self.head.is_some() && self.tail.is_some(), 61 }; 62 if !head_tail_ok { 63 crate::show!( 64 ipc, 65 error, 66 "pidqueue invariant violation len {} head {:?} tail {:?}", 67 self.len, 68 self.head, 69 self.tail 70 ); 71 return false; 72 } 73 74 let max = crate::types::MAX_PIDS; 75 let mut last = None; 76 let chain_len = core::iter::successors(self.head, |&cur| { 77 last = Some(cur); 78 next_link(cur) 79 }) 80 .take(max + 1) 81 .count(); 82 83 if chain_len != self.len as usize { 84 crate::show!( 85 ipc, 86 error, 87 "pidqueue length mismatch chain {} stored {}", 88 chain_len, 89 self.len 90 ); 91 return false; 92 } 93 94 match (self.tail, last) { 95 (Some(t), Some(l)) => { 96 if t == l { 97 true 98 } else { 99 crate::show!( 100 ipc, 101 error, 102 "pidqueue tail mismatch stored {} walked {}", 103 t.raw(), 104 l.raw() 105 ); 106 false 107 } 108 } 109 (None, None) => true, 110 _ => { 111 crate::show!( 112 ipc, 113 error, 114 "pidqueue tail inconsistency stored {:?} walked {:?}", 115 self.tail, 116 last 117 ); 118 false 119 } 120 } 121 } 122 123 pub fn from_repr_c(head: u32, tail: u32, len: u16) -> Self { 124 Self::from_parts(Pid::try_new(head), Pid::try_new(tail), len) 125 } 126 127 pub fn to_repr_c(self) -> (u32, u32, u16) { 128 ( 129 self.head 130 .map_or(lancer_core::header::NONE_SENTINEL, |p| p.raw()), 131 self.tail 132 .map_or(lancer_core::header::NONE_SENTINEL, |p| p.raw()), 133 self.len, 134 ) 135 } 136 137 pub fn from_parts(head: Option<Pid>, tail: Option<Pid>, len: u16) -> Self { 138 if len == 0 || head.is_none() || tail.is_none() { 139 Self::new() 140 } else { 141 Self { head, tail, len } 142 } 143 } 144} 145 146#[derive(Debug, Clone, Copy)] 147pub struct CNodeData { 148 pub slots_phys: x86_64::PhysAddr, 149 pub size_bits: u8, 150 pub frame_count: u8, 151} 152 153#[derive(Debug, Clone, Copy, PartialEq, Eq)] 154pub struct IoPort(u16); 155 156impl IoPort { 157 pub const fn new(port: u16) -> Self { 158 Self(port) 159 } 160 161 pub(crate) const fn raw(self) -> u16 { 162 self.0 163 } 164} 165 166impl core::fmt::Display for IoPort { 167 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 168 write!(f, "{:#x}", self.0) 169 } 170} 171 172#[derive(Debug, Clone, Copy)] 173pub struct PortRange { 174 base: u16, 175 count: u16, 176} 177 178impl PortRange { 179 pub const fn new(base: u16, count: u16) -> Option<Self> { 180 if count == 0 { 181 return None; 182 } 183 let end = base as u32 + count as u32; 184 if end > 0x10000 { 185 return None; 186 } 187 Some(Self { base, count }) 188 } 189 190 #[allow(dead_code)] 191 pub const fn base(self) -> u16 { 192 self.base 193 } 194 195 #[allow(dead_code)] 196 pub const fn count(self) -> u16 { 197 self.count 198 } 199 200 pub fn contains(self, port: IoPort) -> bool { 201 (port.0 as u32) >= (self.base as u32) 202 && (port.0 as u32) < (self.base as u32) + (self.count as u32) 203 } 204} 205 206#[derive(Debug, Clone, Copy)] 207pub enum IrqSource { 208 Ioapic { 209 gsi: crate::arch::ioapic::Gsi, 210 }, 211 Msix { 212 device_table_idx: u8, 213 entry_idx: u16, 214 }, 215}