Nothing to see here, move along
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}