Nothing to see here, move along
1use crate::cap::cnode;
2use crate::cap::object::{
3 EndpointData, FramebufferData, IrqHandlerData, IrqSource, NotificationData, ObjectData,
4 ObjectTag, PciDeviceData, PortRange, ProcessObjectData,
5};
6
7const COM1_PORTS: PortRange = match PortRange::new(0x3F8, 8) {
8 Some(pr) => pr,
9 None => unreachable!(),
10};
11
12const PS2_KBD_PORTS: PortRange = match PortRange::new(0x60, 5) {
13 Some(pr) => pr,
14 None => unreachable!(),
15};
16use crate::cap::pool::POOL;
17use crate::cap::table::{CapRef, Rights};
18use crate::error::KernelError;
19use crate::types::Pid;
20
21const SLOT_SELF: u64 = 0;
22
23mod init_slots {
24 pub const SERIAL_EP: u64 = 1;
25 pub const FB_EP: u64 = 2;
26 pub const INIT_NOTIF: u64 = 9;
27 pub const NETSTACK_NOTIF: u64 = 10;
28 pub const VFS_PROC: u64 = 15;
29 pub const NETSTACK_RING_BASE: u64 = 288;
30 pub const NETSTACK_RING_FRAMES: u16 = 2;
31}
32
33mod irq_driver_slots {
34 pub const EP: u64 = 1;
35 pub const IRQ: u64 = 2;
36 pub const NOTIF: u64 = 3;
37}
38
39mod fbconsole_slots {
40 pub const EP: u64 = 1;
41 pub const FB: u64 = 2;
42 pub const CONSOLE_RING_BASE: u64 = 64;
43}
44
45pub fn bootstrap_root_cnode(pid: Pid, size_bits: u8) -> Result<(), KernelError> {
46 let allocator = &crate::mem::phys::BitmapFrameAllocator;
47 let cnode_data = cnode::create_cnode(size_bits, allocator)?;
48 let frame_count = cnode_data.frame_count;
49 let (cnode_id, cnode_gen) = POOL.lock().allocate(ObjectData::CNode(cnode_data))?;
50 let mut ptable = crate::proc::PROCESSES.lock();
51 let proc = ptable
52 .get_mut(pid)
53 .ok_or(KernelError::InvalidObject)?;
54 proc.root_cnode = Some((cnode_id, cnode_gen));
55 proc.cnode_depth = size_bits;
56 proc.charge_frames(frame_count as u16)?;
57 Ok(())
58}
59
60fn install_cap(pid: Pid, slot: u64, data: ObjectData) -> Result<(), KernelError> {
61 let tag = data.tag();
62 let (object_id, generation) = POOL.lock().allocate(data)?;
63 let cap = CapRef::new(tag, object_id, Rights::ALL, generation);
64 let ptable = crate::proc::PROCESSES.lock();
65 let pool = POOL.lock_after(&ptable);
66 match cnode::resolve_caller_insert(pid, slot, cap, &ptable, &pool) {
67 Ok(()) => Ok(()),
68 Err(e) => {
69 drop(pool);
70 let r = POOL.lock_after(&ptable).free(object_id, generation);
71 debug_assert!(r.is_ok());
72 Err(e)
73 }
74 }
75}
76
77fn insert_cap_into(
78 pid: Pid,
79 slot: u64,
80 cap: CapRef,
81 ptable: &crate::sync::IrqMutexGuard<'_, crate::proc::ProcessManager, 0>,
82) -> Result<(), KernelError> {
83 let pool = POOL.lock_after(ptable);
84 cnode::resolve_caller_insert(pid, slot, cap, ptable, &pool)
85}
86
87fn read_cap_from(
88 pid: Pid,
89 slot: u64,
90 expected_tag: ObjectTag,
91 required_rights: Rights,
92 ptable: &crate::sync::IrqMutexGuard<'_, crate::proc::ProcessManager, 0>,
93) -> Result<CapRef, KernelError> {
94 let pool = POOL.lock_after(ptable);
95 cnode::resolve_caller_validate(pid, slot, expected_tag, required_rights, ptable, &pool)
96}
97
98use crate::cap::object::FrameObjectData;
99
100fn create_shared_ring_frames(
101 pid_a: Pid,
102 base_slot_a: u64,
103 pid_b: Pid,
104 base_slot_b: u64,
105 frame_count: u16,
106) -> Result<(), KernelError> {
107 let allocator = crate::mem::phys::BitmapFrameAllocator;
108 (0..frame_count).try_fold((), |(), i| {
109 let owned = allocator.allocate().ok_or(KernelError::PoolExhausted)?;
110 let phys = owned.phys_addr();
111 core::mem::forget(owned);
112 crate::mem::addr::zero_frame(phys);
113 crate::mem::refcount::increment(phys).map_err(|_| {
114 crate::mem::phys::BitmapFrameAllocator::free_frame_by_addr(phys);
115 KernelError::ResourceExhausted
116 })?;
117
118 let data = ObjectData::Frame(FrameObjectData::new(phys));
119 let tag = data.tag();
120 let (obj_id, obj_gen) = POOL.lock().allocate(data).inspect_err(|_| {
121 let _ = crate::mem::refcount::decrement(phys);
122 crate::mem::phys::BitmapFrameAllocator::free_frame_by_addr(phys);
123 })?;
124 let cap = CapRef::new(tag, obj_id, Rights::ALL, obj_gen);
125
126 let ptable = crate::proc::PROCESSES.lock();
127 insert_cap_into(pid_a, base_slot_a + i as u64, cap, &ptable).inspect_err(|_| {
128 let r = POOL.lock_after(&ptable).free(obj_id, obj_gen);
129 debug_assert!(r.is_ok());
130 let _ = crate::mem::refcount::decrement(phys);
131 crate::mem::phys::BitmapFrameAllocator::free_frame_by_addr(phys);
132 })?;
133 POOL.lock_after(&ptable).inc_ref(obj_id, obj_gen)?;
134 insert_cap_into(pid_b, base_slot_b + i as u64, cap, &ptable).inspect_err(|_| {
135 POOL.lock_after(&ptable).dec_ref(obj_id, obj_gen);
136 })?;
137 Ok(())
138 })
139}
140
141fn create_ring_frames_from_phys(
142 pid: Pid,
143 base_slot: u64,
144 phys_addrs: &[x86_64::PhysAddr],
145) -> Result<(), KernelError> {
146 phys_addrs.iter().enumerate().try_fold((), |(), (i, &phys)| {
147 crate::mem::refcount::increment(phys).map_err(|_| KernelError::ResourceExhausted)?;
148 let data = ObjectData::Frame(FrameObjectData::new(phys));
149 install_cap(pid, base_slot + i as u64, data).inspect_err(|_| {
150 let _ = crate::mem::refcount::decrement(phys);
151 })
152 })
153}
154
155pub fn bootstrap_self_cap(pid: Pid, cnode_size_bits: u8) -> Result<(), KernelError> {
156 bootstrap_root_cnode(pid, cnode_size_bits)?;
157 install_cap(pid, SLOT_SELF, ObjectData::Process(ProcessObjectData { pid }))
158}
159
160pub fn bootstrap_serial_driver(
161 init_pid: Pid,
162 driver_pid: Pid,
163 com1_gsi: crate::arch::ioapic::Gsi,
164) -> Result<(), KernelError> {
165 let ep_data = ObjectData::Endpoint(EndpointData::new());
166 let ep_tag = ep_data.tag();
167 let (ep_id, ep_gen) = POOL.lock().allocate(ep_data)?;
168 let ep_cap = CapRef::new(ep_tag, ep_id, Rights::ALL, ep_gen);
169
170 {
171 let ptable = crate::proc::PROCESSES.lock();
172 match insert_cap_into(init_pid, init_slots::SERIAL_EP, ep_cap, &ptable) {
173 Ok(()) => {}
174 Err(e) => {
175 let r = POOL.lock_after(&ptable).free(ep_id, ep_gen);
176 debug_assert!(r.is_ok());
177 return Err(e);
178 }
179 }
180 POOL.lock_after(&ptable).inc_ref(ep_id, ep_gen)?;
181 match insert_cap_into(driver_pid, irq_driver_slots::EP, ep_cap, &ptable) {
182 Ok(()) => {}
183 Err(e) => {
184 POOL.lock_after(&ptable).dec_ref(ep_id, ep_gen);
185 return Err(e);
186 }
187 }
188 }
189
190 crate::show!(boot,
191 "endpoint obj {} shared pid {} slot {} <-> pid {} slot {}",
192 ep_id.raw(),
193 init_pid.raw(),
194 init_slots::SERIAL_EP,
195 driver_pid.raw(),
196 irq_driver_slots::EP
197 );
198
199 let com1_vector = crate::arch::idt::COM1_VECTOR;
200 install_cap(
201 driver_pid,
202 irq_driver_slots::IRQ,
203 ObjectData::IrqHandler(IrqHandlerData {
204 vector: com1_vector,
205 source: IrqSource::Ioapic { gsi: com1_gsi },
206 port_range: COM1_PORTS,
207 }),
208 )?;
209
210 let notif_data = ObjectData::Notification(NotificationData::new());
211 let notif_tag = notif_data.tag();
212 let (notif_id, notif_gen) = POOL.lock().allocate(notif_data)?;
213 let notif_cap = CapRef::new(notif_tag, notif_id, Rights::ALL, notif_gen);
214 {
215 let ptable = crate::proc::PROCESSES.lock();
216 insert_cap_into(driver_pid, irq_driver_slots::NOTIF, notif_cap, &ptable)
217 .inspect_err(|_| {
218 let r = POOL.lock_after(&ptable).free(notif_id, notif_gen);
219 debug_assert!(r.is_ok());
220 })?;
221 }
222
223 crate::irq::bind(
224 com1_vector,
225 IrqSource::Ioapic { gsi: com1_gsi },
226 notif_id,
227 notif_gen,
228 crate::types::NotificationBit::ZERO,
229 )?;
230
231 crate::show!(boot,
232 "serial irq slot {} notif slot {} com1 gsi {} -> vec {}",
233 irq_driver_slots::IRQ,
234 irq_driver_slots::NOTIF,
235 com1_gsi,
236 com1_vector
237 );
238
239 Ok(())
240}
241
242pub fn bootstrap_ps2kbd(
243 init_pid: Pid,
244 ps2kbd_pid: Pid,
245 kbd_gsi: crate::arch::ioapic::Gsi,
246) -> Result<(), KernelError> {
247 let ep_cap = {
248 let ptable = crate::proc::PROCESSES.lock();
249 read_cap_from(init_pid, init_slots::SERIAL_EP, ObjectTag::Endpoint, Rights::ALL, &ptable)?
250 };
251
252 POOL.lock()
253 .inc_ref(ep_cap.object_id(), ep_cap.generation())?;
254 {
255 let ptable = crate::proc::PROCESSES.lock();
256 insert_cap_into(ps2kbd_pid, irq_driver_slots::EP, ep_cap, &ptable)
257 .inspect_err(|_| {
258 POOL.lock_after(&ptable)
259 .dec_ref(ep_cap.object_id(), ep_cap.generation());
260 })?;
261 }
262
263 let kbd_vector = crate::arch::idt::KBD_VECTOR;
264 install_cap(
265 ps2kbd_pid,
266 irq_driver_slots::IRQ,
267 ObjectData::IrqHandler(IrqHandlerData {
268 vector: kbd_vector,
269 source: IrqSource::Ioapic { gsi: kbd_gsi },
270 port_range: PS2_KBD_PORTS,
271 }),
272 )?;
273
274 let notif_data = ObjectData::Notification(NotificationData::new());
275 let notif_tag = notif_data.tag();
276 let (notif_id, notif_gen) = POOL.lock().allocate(notif_data)?;
277 let notif_cap = CapRef::new(notif_tag, notif_id, Rights::ALL, notif_gen);
278 {
279 let ptable = crate::proc::PROCESSES.lock();
280 insert_cap_into(ps2kbd_pid, irq_driver_slots::NOTIF, notif_cap, &ptable)
281 .inspect_err(|_| {
282 let r = POOL.lock_after(&ptable).free(notif_id, notif_gen);
283 debug_assert!(r.is_ok());
284 })?;
285 }
286
287 crate::irq::bind(
288 kbd_vector,
289 IrqSource::Ioapic { gsi: kbd_gsi },
290 notif_id,
291 notif_gen,
292 crate::types::NotificationBit::ZERO,
293 )?;
294
295 crate::show!(boot,
296 "ps2 kbd caps installed irq slot {} notification slot {} kbd gsi {} -> vector {}",
297 irq_driver_slots::IRQ,
298 irq_driver_slots::NOTIF,
299 kbd_gsi,
300 kbd_vector,
301 );
302
303 Ok(())
304}
305
306mod nvme_slots {
307 pub const EP: u64 = 1;
308 pub const PCI: u64 = 2;
309 pub const IRQ: u64 = 3;
310 pub const NOTIF: u64 = 4;
311 pub const CLIENT_NOTIF: u64 = 6;
312 pub const BLOCK_RING_BASE: u64 = 64;
313 pub const BLOCK_RING_FRAMES: u16 = 16;
314}
315
316mod fs_service_slots {
317 pub const NOTIF: u64 = 3;
318 pub const DRIVER_NOTIF: u64 = 4;
319 pub const BLOCK_RING_BASE: u64 = 64;
320}
321
322mod fs_service_client_slots {
323 pub const CLIENT_NOTIF: u64 = 6;
324 pub const CLIENT_RING_BASE: u64 = 96;
325}
326
327mod vfs_slots {
328 pub const NOTIF: u64 = 3;
329 pub const LANCERFS_NOTIF: u64 = 4;
330 pub const LANCERFS_RING_BASE: u64 = 64;
331 pub const LANCERFS_RING_FRAMES: u16 = 16;
332 pub const CLIENT0_RING_BASE: u64 = 160;
333 pub const CLIENT0_RING_FRAMES: u16 = 16;
334 pub const CLIENT0_NOTIF: u64 = 176;
335}
336
337mod ramfs_slots {
338 pub const NOTIF: u64 = 3;
339 pub const VFS_NOTIF: u64 = 4;
340 pub const CLIENT_RING_BASE: u64 = 64;
341}
342
343mod vfs_ramfs_slots {
344 pub const RAMFS_NOTIF: u64 = 6;
345 pub const RAMFS_RING_BASE: u64 = 96;
346 pub const RAMFS_RING_FRAMES: u16 = 16;
347}
348
349mod vfs_client_slots {
350 pub const NOTIF: u64 = 12;
351 pub const VFS_NOTIF: u64 = 13;
352 pub const CLIENT_RING_BASE: u64 = 320;
353}
354
355mod virtio_net_slots {
356 pub const EP: u64 = 1;
357 pub const PCI: u64 = 2;
358 pub const IRQ: u64 = 3;
359 pub const NOTIF: u64 = 4;
360 pub const NETSTACK_NOTIF: u64 = 7;
361 pub const PACKET_RING_BASE: u64 = 64;
362 pub const PACKET_RING_FRAMES: u16 = 16;
363}
364
365mod net_service_slots {
366 pub const EP: u64 = 1;
367 pub const NOTIF: u64 = 3;
368 pub const DRIVER_NOTIF: u64 = 4;
369 pub const SHELL_NOTIF: u64 = 6;
370 pub const INIT_NOTIF: u64 = 8;
371 pub const PACKET_RING_BASE: u64 = 64;
372 pub const SHELL_RING_BASE: u64 = 96;
373 pub const SHELL_RING_FRAMES: u16 = 4;
374 pub const INIT_RING_BASE: u64 = 128;
375}
376
377mod remote_shell_slots {
378 pub const EP: u64 = 1;
379 pub const NOTIF: u64 = 3;
380 pub const NETSTACK_NOTIF: u64 = 4;
381 pub const SHELL_RING_BASE: u64 = 64;
382 pub const VFS_RING_BASE: u64 = 128;
383 pub const VFS_RING_FRAMES: u16 = 16;
384}
385
386pub fn bootstrap_fbconsole(init_pid: Pid, fbconsole_pid: Pid) -> Result<(), KernelError> {
387 let fb = crate::arch::boot::framebuffer().ok_or(KernelError::NotFound)?;
388
389 let ep_data = ObjectData::Endpoint(EndpointData::new());
390 let ep_tag = ep_data.tag();
391 let (ep_id, ep_gen) = POOL.lock().allocate(ep_data)?;
392 let ep_cap = CapRef::new(ep_tag, ep_id, Rights::ALL, ep_gen);
393
394 {
395 let ptable = crate::proc::PROCESSES.lock();
396 insert_cap_into(init_pid, init_slots::FB_EP, ep_cap, &ptable)
397 .inspect_err(|_| {
398 let r = POOL.lock_after(&ptable).free(ep_id, ep_gen);
399 debug_assert!(r.is_ok());
400 })?;
401 POOL.lock_after(&ptable).inc_ref(ep_id, ep_gen)?;
402 insert_cap_into(fbconsole_pid, fbconsole_slots::EP, ep_cap, &ptable)
403 .inspect_err(|_| {
404 POOL.lock_after(&ptable).dec_ref(ep_id, ep_gen);
405 })?;
406 }
407
408 crate::show!(boot,
409 "fb endpoint obj {} shared pid {} slot {} <-> pid {} slot {}",
410 ep_id.raw(),
411 init_pid.raw(),
412 init_slots::FB_EP,
413 fbconsole_pid.raw(),
414 fbconsole_slots::EP,
415 );
416
417 let fb_phys = fb.addr() as u64 - crate::mem::addr::hhdm_offset();
418 let fb_byte_size = fb
419 .pitch()
420 .checked_mul(fb.height())
421 .ok_or(KernelError::InvalidParameter)?;
422 let page_count = fb_byte_size.div_ceil(4096);
423 crate::show!(boot,
424 "fb phys {:#x} {} bytes {} pages pitch {} {}x{} {}bpp",
425 fb_phys,
426 fb_byte_size,
427 page_count,
428 fb.pitch(),
429 fb.width(),
430 fb.height(),
431 fb.bpp(),
432 );
433 let fb_data = FramebufferData::new(
434 fb_phys,
435 fb.width() as u32,
436 fb.height() as u32,
437 fb.pitch() as u32,
438 fb.bpp(),
439 fb_byte_size,
440 )
441 .ok_or(KernelError::InvalidParameter)?;
442
443 install_cap(
444 fbconsole_pid,
445 fbconsole_slots::FB,
446 ObjectData::Framebuffer(fb_data),
447 )?;
448
449 let ring_frame_count = crate::console::phys_frame_count();
450 if ring_frame_count > 0 {
451 let mut ring_phys: [x86_64::PhysAddr; 16] = [x86_64::PhysAddr::zero(); 16];
452 (0..ring_frame_count).fold((), |(), i| {
453 ring_phys[i as usize] = crate::console::phys_addr(i).unwrap();
454 });
455
456 create_ring_frames_from_phys(
457 fbconsole_pid,
458 fbconsole_slots::CONSOLE_RING_BASE,
459 &ring_phys[..ring_frame_count as usize],
460 )?;
461
462 crate::show!(boot,
463 "console ring granted to fbconsole {} frames at base slot {}",
464 ring_frame_count,
465 fbconsole_slots::CONSOLE_RING_BASE,
466 );
467 }
468
469 crate::show!(boot,
470 "fbconsole caps installed endpoint slot {} framebuffer slot {}",
471 fbconsole_slots::EP,
472 fbconsole_slots::FB,
473 );
474
475 Ok(())
476}
477
478pub fn bootstrap_nvme(
479 init_pid: Pid,
480 driver_pid: Pid,
481 device_table_idx: u8,
482 mapper: &mut x86_64::structures::paging::OffsetPageTable,
483 allocator: &mut crate::mem::phys::BitmapFrameAllocator,
484 hhdm_offset: u64,
485) -> Result<(), KernelError> {
486 let ep_cap = {
487 let ptable = crate::proc::PROCESSES.lock();
488 read_cap_from(init_pid, init_slots::SERIAL_EP, ObjectTag::Endpoint, Rights::ALL, &ptable)?
489 };
490
491 POOL.lock()
492 .inc_ref(ep_cap.object_id(), ep_cap.generation())?;
493 {
494 let ptable = crate::proc::PROCESSES.lock();
495 insert_cap_into(driver_pid, nvme_slots::EP, ep_cap, &ptable)
496 .inspect_err(|_| {
497 POOL.lock_after(&ptable)
498 .dec_ref(ep_cap.object_id(), ep_cap.generation());
499 })?;
500 }
501
502 install_cap(
503 driver_pid,
504 nvme_slots::PCI,
505 ObjectData::PciDevice(PciDeviceData { device_table_idx }),
506 )?;
507
508 crate::pci::enable_bus_master(device_table_idx)?;
509
510 if crate::iommu::is_available() {
511 crate::iommu::setup_device_context(device_table_idx, driver_pid, allocator, hhdm_offset)?;
512 }
513
514 let nvme_vector = crate::arch::idt::NVME_VECTOR;
515 let dummy_ports = match PortRange::new(0, 1) {
516 Some(pr) => pr,
517 None => return Err(KernelError::InvalidParameter),
518 };
519
520 crate::pci::msix::ensure_table_mapped(device_table_idx, mapper, allocator, hhdm_offset)?;
521 crate::pci::msix::configure_entry(device_table_idx, 0, nvme_vector, 0)?;
522 crate::pci::msix::enable_msix(device_table_idx)?;
523 crate::pci::msix::unmask_entry(device_table_idx, 0)?;
524 crate::show!(boot, "nvme msi-x configured entry 0 -> vector {}", nvme_vector);
525
526 let irq_source = IrqSource::Msix {
527 device_table_idx,
528 entry_idx: 0,
529 };
530
531 install_cap(
532 driver_pid,
533 nvme_slots::IRQ,
534 ObjectData::IrqHandler(IrqHandlerData {
535 vector: nvme_vector,
536 source: irq_source,
537 port_range: dummy_ports,
538 }),
539 )?;
540
541 let notif_data = ObjectData::Notification(NotificationData::new());
542 let notif_tag = notif_data.tag();
543 let (notif_id, notif_gen) = POOL.lock().allocate(notif_data)?;
544 let notif_cap = CapRef::new(notif_tag, notif_id, Rights::ALL, notif_gen);
545 {
546 let ptable = crate::proc::PROCESSES.lock();
547 insert_cap_into(driver_pid, nvme_slots::NOTIF, notif_cap, &ptable)
548 .inspect_err(|_| {
549 let r = POOL.lock_after(&ptable).free(notif_id, notif_gen);
550 debug_assert!(r.is_ok());
551 })?;
552 }
553
554 crate::irq::bind(
555 nvme_vector,
556 irq_source,
557 notif_id,
558 notif_gen,
559 crate::types::NotificationBit::ZERO,
560 )?;
561
562 crate::show!(boot,
563 "nvme caps installed pci slot {} irq slot {} notification slot {} vector {}",
564 nvme_slots::PCI,
565 nvme_slots::IRQ,
566 nvme_slots::NOTIF,
567 nvme_vector,
568 );
569
570 Ok(())
571}
572
573pub fn bootstrap_nvme_service(driver_pid: Pid, client_pid: Pid) -> Result<(), KernelError> {
574 create_shared_ring_frames(
575 driver_pid,
576 nvme_slots::BLOCK_RING_BASE,
577 client_pid,
578 fs_service_slots::BLOCK_RING_BASE,
579 nvme_slots::BLOCK_RING_FRAMES,
580 )?;
581
582 let client_notif_data = ObjectData::Notification(NotificationData::new());
583 let client_notif_tag = client_notif_data.tag();
584 let (client_notif_id, client_notif_gen) = POOL.lock().allocate(client_notif_data)?;
585 let client_notif_cap = CapRef::new(
586 client_notif_tag,
587 client_notif_id,
588 Rights::ALL,
589 client_notif_gen,
590 );
591 {
592 let ptable = crate::proc::PROCESSES.lock();
593 insert_cap_into(client_pid, fs_service_slots::NOTIF, client_notif_cap, &ptable)
594 .inspect_err(|_| {
595 let r = POOL
596 .lock_after(&ptable)
597 .free(client_notif_id, client_notif_gen);
598 debug_assert!(r.is_ok());
599 })?;
600 POOL.lock_after(&ptable)
601 .inc_ref(client_notif_id, client_notif_gen)?;
602 insert_cap_into(driver_pid, nvme_slots::CLIENT_NOTIF, client_notif_cap, &ptable)
603 .inspect_err(|_| {
604 POOL.lock_after(&ptable)
605 .dec_ref(client_notif_id, client_notif_gen);
606 })?;
607 }
608
609 let driver_notif_cap = {
610 let ptable = crate::proc::PROCESSES.lock();
611 read_cap_from(driver_pid, nvme_slots::NOTIF, ObjectTag::Notification, Rights::ALL, &ptable)?
612 };
613 POOL.lock()
614 .inc_ref(driver_notif_cap.object_id(), driver_notif_cap.generation())?;
615 {
616 let ptable = crate::proc::PROCESSES.lock();
617 insert_cap_into(client_pid, fs_service_slots::DRIVER_NOTIF, driver_notif_cap, &ptable)
618 .inspect_err(|_| {
619 POOL.lock_after(&ptable)
620 .dec_ref(driver_notif_cap.object_id(), driver_notif_cap.generation());
621 })?;
622 }
623
624 crate::show!(boot,
625 "nvme service caps ring base {}/{} notif slots {}/{} driver-notif slot {}",
626 nvme_slots::BLOCK_RING_BASE,
627 fs_service_slots::BLOCK_RING_BASE,
628 nvme_slots::CLIENT_NOTIF,
629 fs_service_slots::NOTIF,
630 fs_service_slots::DRIVER_NOTIF,
631 );
632
633 Ok(())
634}
635
636pub fn bootstrap_vfs_lancerfs(vfs_pid: Pid, lancerfs_pid: Pid) -> Result<(), KernelError> {
637 create_shared_ring_frames(
638 vfs_pid,
639 vfs_slots::LANCERFS_RING_BASE,
640 lancerfs_pid,
641 fs_service_client_slots::CLIENT_RING_BASE,
642 vfs_slots::LANCERFS_RING_FRAMES,
643 )?;
644
645 let vfs_notif_data = ObjectData::Notification(NotificationData::new());
646 let vfs_notif_tag = vfs_notif_data.tag();
647 let (vfs_notif_id, vfs_notif_gen) = POOL.lock().allocate(vfs_notif_data)?;
648 let vfs_notif_cap = CapRef::new(vfs_notif_tag, vfs_notif_id, Rights::ALL, vfs_notif_gen);
649 {
650 let ptable = crate::proc::PROCESSES.lock();
651 insert_cap_into(vfs_pid, vfs_slots::NOTIF, vfs_notif_cap, &ptable)
652 .inspect_err(|_| {
653 let r = POOL.lock_after(&ptable).free(vfs_notif_id, vfs_notif_gen);
654 debug_assert!(r.is_ok());
655 })?;
656 POOL.lock_after(&ptable)
657 .inc_ref(vfs_notif_id, vfs_notif_gen)?;
658 insert_cap_into(lancerfs_pid, fs_service_client_slots::CLIENT_NOTIF, vfs_notif_cap, &ptable)
659 .inspect_err(|_| {
660 POOL.lock_after(&ptable)
661 .dec_ref(vfs_notif_id, vfs_notif_gen);
662 })?;
663 }
664
665 let lancerfs_notif_cap = {
666 let ptable = crate::proc::PROCESSES.lock();
667 read_cap_from(lancerfs_pid, fs_service_slots::NOTIF, ObjectTag::Notification, Rights::ALL, &ptable)?
668 };
669 POOL.lock().inc_ref(
670 lancerfs_notif_cap.object_id(),
671 lancerfs_notif_cap.generation(),
672 )?;
673 {
674 let ptable = crate::proc::PROCESSES.lock();
675 insert_cap_into(vfs_pid, vfs_slots::LANCERFS_NOTIF, lancerfs_notif_cap, &ptable)
676 .inspect_err(|_| {
677 POOL.lock_after(&ptable).dec_ref(
678 lancerfs_notif_cap.object_id(),
679 lancerfs_notif_cap.generation(),
680 );
681 })?;
682 }
683
684 crate::show!(boot,
685 "vfs-lancerfs caps ring base {}/{} vfs-notif slots {}/{} lancerfs-notif slot {}",
686 vfs_slots::LANCERFS_RING_BASE,
687 fs_service_client_slots::CLIENT_RING_BASE,
688 vfs_slots::NOTIF,
689 fs_service_client_slots::CLIENT_NOTIF,
690 vfs_slots::LANCERFS_NOTIF,
691 );
692
693 Ok(())
694}
695
696pub fn bootstrap_vfs_ramfs(vfs_pid: Pid, ramfs_pid: Pid) -> Result<(), KernelError> {
697 create_shared_ring_frames(
698 vfs_pid,
699 vfs_ramfs_slots::RAMFS_RING_BASE,
700 ramfs_pid,
701 ramfs_slots::CLIENT_RING_BASE,
702 vfs_ramfs_slots::RAMFS_RING_FRAMES,
703 )?;
704
705 let vfs_notif_cap = {
706 let ptable = crate::proc::PROCESSES.lock();
707 match read_cap_from(vfs_pid, vfs_slots::NOTIF, ObjectTag::Notification, Rights::ALL, &ptable) {
708 Ok(cap) => {
709 drop(ptable);
710 POOL.lock().inc_ref(cap.object_id(), cap.generation())?;
711 cap
712 }
713 Err(_) => {
714 drop(ptable);
715 let notif_data = ObjectData::Notification(NotificationData::new());
716 let notif_tag = notif_data.tag();
717 let (nid, ngen) = POOL.lock().allocate(notif_data)?;
718 let cap = CapRef::new(notif_tag, nid, Rights::ALL, ngen);
719 let ptable = crate::proc::PROCESSES.lock();
720 insert_cap_into(vfs_pid, vfs_slots::NOTIF, cap, &ptable)
721 .inspect_err(|_| {
722 let r = POOL.lock_after(&ptable).free(nid, ngen);
723 debug_assert!(r.is_ok());
724 })?;
725 cap
726 }
727 }
728 };
729 {
730 POOL.lock()
731 .inc_ref(vfs_notif_cap.object_id(), vfs_notif_cap.generation())?;
732 let ptable = crate::proc::PROCESSES.lock();
733 insert_cap_into(ramfs_pid, ramfs_slots::VFS_NOTIF, vfs_notif_cap, &ptable)
734 .inspect_err(|_| {
735 POOL.lock_after(&ptable)
736 .dec_ref(vfs_notif_cap.object_id(), vfs_notif_cap.generation());
737 })?;
738 }
739
740 let ramfs_notif_data = ObjectData::Notification(NotificationData::new());
741 let ramfs_notif_tag = ramfs_notif_data.tag();
742 let (ramfs_notif_id, ramfs_notif_gen) = POOL.lock().allocate(ramfs_notif_data)?;
743 let ramfs_notif_cap = CapRef::new(
744 ramfs_notif_tag,
745 ramfs_notif_id,
746 Rights::ALL,
747 ramfs_notif_gen,
748 );
749 {
750 let ptable = crate::proc::PROCESSES.lock();
751 insert_cap_into(ramfs_pid, ramfs_slots::NOTIF, ramfs_notif_cap, &ptable)
752 .inspect_err(|_| {
753 let r = POOL
754 .lock_after(&ptable)
755 .free(ramfs_notif_id, ramfs_notif_gen);
756 debug_assert!(r.is_ok());
757 })?;
758 POOL.lock_after(&ptable)
759 .inc_ref(ramfs_notif_id, ramfs_notif_gen)?;
760 insert_cap_into(vfs_pid, vfs_ramfs_slots::RAMFS_NOTIF, ramfs_notif_cap, &ptable)
761 .inspect_err(|_| {
762 POOL.lock_after(&ptable)
763 .dec_ref(ramfs_notif_id, ramfs_notif_gen);
764 })?;
765 }
766
767 crate::show!(boot,
768 "vfs-ramfs caps ring base {}/{} vfs-notif slot {} ramfs-notif slots {}/{}",
769 vfs_ramfs_slots::RAMFS_RING_BASE,
770 ramfs_slots::CLIENT_RING_BASE,
771 ramfs_slots::VFS_NOTIF,
772 ramfs_slots::NOTIF,
773 vfs_ramfs_slots::RAMFS_NOTIF,
774 );
775
776 Ok(())
777}
778
779pub fn bootstrap_vfs_client(client_pid: Pid, vfs_pid: Pid) -> Result<(), KernelError> {
780 create_shared_ring_frames(
781 client_pid,
782 vfs_client_slots::CLIENT_RING_BASE,
783 vfs_pid,
784 vfs_slots::CLIENT0_RING_BASE,
785 vfs_slots::CLIENT0_RING_FRAMES,
786 )?;
787
788 let client_notif_data = ObjectData::Notification(NotificationData::new());
789 let client_notif_tag = client_notif_data.tag();
790 let (client_notif_id, client_notif_gen) = POOL.lock().allocate(client_notif_data)?;
791 let client_notif_cap = CapRef::new(
792 client_notif_tag,
793 client_notif_id,
794 Rights::ALL,
795 client_notif_gen,
796 );
797 {
798 let ptable = crate::proc::PROCESSES.lock();
799 insert_cap_into(client_pid, vfs_client_slots::NOTIF, client_notif_cap, &ptable)
800 .inspect_err(|_| {
801 let r = POOL
802 .lock_after(&ptable)
803 .free(client_notif_id, client_notif_gen);
804 debug_assert!(r.is_ok());
805 })?;
806 POOL.lock_after(&ptable)
807 .inc_ref(client_notif_id, client_notif_gen)?;
808 insert_cap_into(vfs_pid, vfs_slots::CLIENT0_NOTIF, client_notif_cap, &ptable)
809 .inspect_err(|_| {
810 POOL.lock_after(&ptable)
811 .dec_ref(client_notif_id, client_notif_gen);
812 })?;
813 }
814
815 let vfs_notif_cap = {
816 let ptable = crate::proc::PROCESSES.lock();
817 read_cap_from(vfs_pid, vfs_slots::NOTIF, ObjectTag::Notification, Rights::ALL, &ptable)?
818 };
819 POOL.lock()
820 .inc_ref(vfs_notif_cap.object_id(), vfs_notif_cap.generation())?;
821 {
822 let ptable = crate::proc::PROCESSES.lock();
823 insert_cap_into(client_pid, vfs_client_slots::VFS_NOTIF, vfs_notif_cap, &ptable)
824 .inspect_err(|_| {
825 POOL.lock_after(&ptable)
826 .dec_ref(vfs_notif_cap.object_id(), vfs_notif_cap.generation());
827 })?;
828 }
829
830 crate::show!(boot,
831 "vfs client caps ring base {}/{} client-notif slots {}/{} vfs-notif slot {}",
832 vfs_client_slots::CLIENT_RING_BASE,
833 vfs_slots::CLIENT0_RING_BASE,
834 vfs_client_slots::NOTIF,
835 vfs_slots::CLIENT0_NOTIF,
836 vfs_client_slots::VFS_NOTIF,
837 );
838
839 Ok(())
840}
841
842pub fn bootstrap_init_vfs_control(init_pid: Pid, vfs_pid: Pid) -> Result<(), KernelError> {
843 install_cap(
844 init_pid,
845 init_slots::VFS_PROC,
846 ObjectData::Process(ProcessObjectData { pid: vfs_pid }),
847 )?;
848
849 crate::show!(boot,
850 "init vfs control process cap for vfs at init slot {}",
851 init_slots::VFS_PROC,
852 );
853
854 Ok(())
855}
856
857pub fn bootstrap_virtio_net(
858 init_pid: Pid,
859 driver_pid: Pid,
860 virtio_net_gsi: crate::arch::ioapic::Gsi,
861 device_table_idx: u8,
862 mapper: &mut x86_64::structures::paging::OffsetPageTable,
863 allocator: &mut crate::mem::phys::BitmapFrameAllocator,
864 hhdm_offset: u64,
865) -> Result<(), KernelError> {
866 let ep_cap = {
867 let ptable = crate::proc::PROCESSES.lock();
868 read_cap_from(init_pid, init_slots::SERIAL_EP, ObjectTag::Endpoint, Rights::ALL, &ptable)?
869 };
870
871 POOL.lock()
872 .inc_ref(ep_cap.object_id(), ep_cap.generation())?;
873 {
874 let ptable = crate::proc::PROCESSES.lock();
875 insert_cap_into(driver_pid, virtio_net_slots::EP, ep_cap, &ptable)
876 .inspect_err(|_| {
877 POOL.lock_after(&ptable)
878 .dec_ref(ep_cap.object_id(), ep_cap.generation());
879 })?;
880 }
881
882 install_cap(
883 driver_pid,
884 virtio_net_slots::PCI,
885 ObjectData::PciDevice(PciDeviceData { device_table_idx }),
886 )?;
887
888 crate::pci::enable_bus_master(device_table_idx)?;
889
890 if crate::iommu::is_available() {
891 crate::iommu::setup_device_context(device_table_idx, driver_pid, allocator, hhdm_offset)?;
892 }
893
894 let virtio_net_vector = crate::arch::idt::VIRTIO_NET_VECTOR;
895 let dummy_ports = match PortRange::new(0, 1) {
896 Some(pr) => pr,
897 None => return Err(KernelError::InvalidParameter),
898 };
899
900 let has_msix = {
901 let dev_table = crate::pci::DEVICE_TABLE.lock();
902 dev_table
903 .get(device_table_idx as usize)
904 .and_then(|d| d.msix_cap)
905 .is_some()
906 };
907
908 let irq_source = match has_msix {
909 true => {
910 crate::pci::msix::ensure_table_mapped(
911 device_table_idx,
912 mapper,
913 allocator,
914 hhdm_offset,
915 )?;
916 crate::pci::msix::configure_entry(device_table_idx, 0, virtio_net_vector, 0)?;
917 crate::pci::msix::enable_msix(device_table_idx)?;
918 crate::pci::msix::unmask_entry(device_table_idx, 0)?;
919 crate::show!(boot,
920 "virtio-net msi-x configured entry 0 -> vector {}",
921 virtio_net_vector,
922 );
923 IrqSource::Msix {
924 device_table_idx,
925 entry_idx: 0,
926 }
927 }
928 false => IrqSource::Ioapic {
929 gsi: virtio_net_gsi,
930 },
931 };
932
933 install_cap(
934 driver_pid,
935 virtio_net_slots::IRQ,
936 ObjectData::IrqHandler(IrqHandlerData {
937 vector: virtio_net_vector,
938 source: irq_source,
939 port_range: dummy_ports,
940 }),
941 )?;
942
943 let notif_data = ObjectData::Notification(NotificationData::new());
944 let notif_tag = notif_data.tag();
945 let (notif_id, notif_gen) = POOL.lock().allocate(notif_data)?;
946 let notif_cap = CapRef::new(notif_tag, notif_id, Rights::ALL, notif_gen);
947 {
948 let ptable = crate::proc::PROCESSES.lock();
949 insert_cap_into(driver_pid, virtio_net_slots::NOTIF, notif_cap, &ptable)
950 .inspect_err(|_| {
951 let r = POOL.lock_after(&ptable).free(notif_id, notif_gen);
952 debug_assert!(r.is_ok());
953 })?;
954 }
955
956 crate::irq::bind(
957 virtio_net_vector,
958 irq_source,
959 notif_id,
960 notif_gen,
961 crate::types::NotificationBit::ZERO,
962 )?;
963
964 crate::show!(boot,
965 "virtio-net caps installed pci slot {} irq slot {} notification slot {} vector {}",
966 virtio_net_slots::PCI,
967 virtio_net_slots::IRQ,
968 virtio_net_slots::NOTIF,
969 virtio_net_vector,
970 );
971
972 Ok(())
973}
974
975pub fn bootstrap_net_service(
976 init_pid: Pid,
977 driver_pid: Pid,
978 netstack_pid: Pid,
979) -> Result<(), KernelError> {
980 let ep_cap = {
981 let ptable = crate::proc::PROCESSES.lock();
982 read_cap_from(init_pid, init_slots::SERIAL_EP, ObjectTag::Endpoint, Rights::ALL, &ptable)?
983 };
984
985 POOL.lock()
986 .inc_ref(ep_cap.object_id(), ep_cap.generation())?;
987 {
988 let ptable = crate::proc::PROCESSES.lock();
989 insert_cap_into(netstack_pid, net_service_slots::EP, ep_cap, &ptable)
990 .inspect_err(|_| {
991 POOL.lock_after(&ptable)
992 .dec_ref(ep_cap.object_id(), ep_cap.generation());
993 })?;
994 }
995
996 create_shared_ring_frames(
997 driver_pid,
998 virtio_net_slots::PACKET_RING_BASE,
999 netstack_pid,
1000 net_service_slots::PACKET_RING_BASE,
1001 virtio_net_slots::PACKET_RING_FRAMES,
1002 )?;
1003
1004 let netstack_notif_data = ObjectData::Notification(NotificationData::new());
1005 let netstack_notif_tag = netstack_notif_data.tag();
1006 let (netstack_notif_id, netstack_notif_gen) = POOL.lock().allocate(netstack_notif_data)?;
1007 let netstack_notif_cap = CapRef::new(
1008 netstack_notif_tag,
1009 netstack_notif_id,
1010 Rights::ALL,
1011 netstack_notif_gen,
1012 );
1013 {
1014 let ptable = crate::proc::PROCESSES.lock();
1015 insert_cap_into(netstack_pid, net_service_slots::NOTIF, netstack_notif_cap, &ptable)
1016 .inspect_err(|_| {
1017 let r = POOL
1018 .lock_after(&ptable)
1019 .free(netstack_notif_id, netstack_notif_gen);
1020 debug_assert!(r.is_ok());
1021 })?;
1022 POOL.lock_after(&ptable)
1023 .inc_ref(netstack_notif_id, netstack_notif_gen)?;
1024 insert_cap_into(driver_pid, virtio_net_slots::NETSTACK_NOTIF, netstack_notif_cap, &ptable)
1025 .inspect_err(|_| {
1026 POOL.lock_after(&ptable)
1027 .dec_ref(netstack_notif_id, netstack_notif_gen);
1028 })?;
1029 }
1030
1031 let driver_notif_cap = {
1032 let ptable = crate::proc::PROCESSES.lock();
1033 read_cap_from(driver_pid, virtio_net_slots::NOTIF, ObjectTag::Notification, Rights::ALL, &ptable)?
1034 };
1035 POOL.lock()
1036 .inc_ref(driver_notif_cap.object_id(), driver_notif_cap.generation())?;
1037 {
1038 let ptable = crate::proc::PROCESSES.lock();
1039 insert_cap_into(netstack_pid, net_service_slots::DRIVER_NOTIF, driver_notif_cap, &ptable)
1040 .inspect_err(|_| {
1041 POOL.lock_after(&ptable)
1042 .dec_ref(driver_notif_cap.object_id(), driver_notif_cap.generation());
1043 })?;
1044 }
1045
1046 crate::show!(boot,
1047 "net service caps ring base {}/{} notif slots {}/{} driver-notif slot {}",
1048 virtio_net_slots::PACKET_RING_BASE,
1049 net_service_slots::PACKET_RING_BASE,
1050 virtio_net_slots::NETSTACK_NOTIF,
1051 net_service_slots::NOTIF,
1052 net_service_slots::DRIVER_NOTIF,
1053 );
1054
1055 Ok(())
1056}
1057
1058pub fn bootstrap_remote_shell(
1059 init_pid: Pid,
1060 netstack_pid: Pid,
1061 shell_pid: Pid,
1062) -> Result<(), KernelError> {
1063 let ep_cap = {
1064 let ptable = crate::proc::PROCESSES.lock();
1065 read_cap_from(init_pid, init_slots::SERIAL_EP, ObjectTag::Endpoint, Rights::ALL, &ptable)?
1066 };
1067
1068 POOL.lock()
1069 .inc_ref(ep_cap.object_id(), ep_cap.generation())?;
1070 {
1071 let ptable = crate::proc::PROCESSES.lock();
1072 insert_cap_into(shell_pid, remote_shell_slots::EP, ep_cap, &ptable)
1073 .inspect_err(|_| {
1074 POOL.lock_after(&ptable)
1075 .dec_ref(ep_cap.object_id(), ep_cap.generation());
1076 })?;
1077 }
1078
1079 create_shared_ring_frames(
1080 netstack_pid,
1081 net_service_slots::SHELL_RING_BASE,
1082 shell_pid,
1083 remote_shell_slots::SHELL_RING_BASE,
1084 net_service_slots::SHELL_RING_FRAMES,
1085 )?;
1086
1087 let shell_notif_data = ObjectData::Notification(NotificationData::new());
1088 let shell_notif_tag = shell_notif_data.tag();
1089 let (shell_notif_id, shell_notif_gen) = POOL.lock().allocate(shell_notif_data)?;
1090 let shell_notif_cap = CapRef::new(
1091 shell_notif_tag,
1092 shell_notif_id,
1093 Rights::ALL,
1094 shell_notif_gen,
1095 );
1096 {
1097 let ptable = crate::proc::PROCESSES.lock();
1098 insert_cap_into(shell_pid, remote_shell_slots::NOTIF, shell_notif_cap, &ptable)
1099 .inspect_err(|_| {
1100 let r = POOL
1101 .lock_after(&ptable)
1102 .free(shell_notif_id, shell_notif_gen);
1103 debug_assert!(r.is_ok());
1104 })?;
1105 POOL.lock_after(&ptable)
1106 .inc_ref(shell_notif_id, shell_notif_gen)?;
1107 insert_cap_into(netstack_pid, net_service_slots::SHELL_NOTIF, shell_notif_cap, &ptable)
1108 .inspect_err(|_| {
1109 POOL.lock_after(&ptable)
1110 .dec_ref(shell_notif_id, shell_notif_gen);
1111 })?;
1112 }
1113
1114 let netstack_notif_cap = {
1115 let ptable = crate::proc::PROCESSES.lock();
1116 read_cap_from(netstack_pid, net_service_slots::NOTIF, ObjectTag::Notification, Rights::ALL, &ptable)?
1117 };
1118 POOL.lock().inc_ref(
1119 netstack_notif_cap.object_id(),
1120 netstack_notif_cap.generation(),
1121 )?;
1122 {
1123 let ptable = crate::proc::PROCESSES.lock();
1124 insert_cap_into(shell_pid, remote_shell_slots::NETSTACK_NOTIF, netstack_notif_cap, &ptable)
1125 .inspect_err(|_| {
1126 POOL.lock_after(&ptable).dec_ref(
1127 netstack_notif_cap.object_id(),
1128 netstack_notif_cap.generation(),
1129 );
1130 })?;
1131 }
1132
1133 {
1134 let ptable = crate::proc::PROCESSES.lock();
1135 match read_cap_from(init_pid, vfs_client_slots::CLIENT_RING_BASE, ObjectTag::Frame, Rights::ALL, &ptable) {
1136 Ok(_) => {
1137 drop(ptable);
1138 (0..remote_shell_slots::VFS_RING_FRAMES).try_fold((), |(), i| {
1139 let src_slot = vfs_client_slots::CLIENT_RING_BASE + i as u64;
1140 let dst_slot = remote_shell_slots::VFS_RING_BASE + i as u64;
1141 let cap = {
1142 let ptable = crate::proc::PROCESSES.lock();
1143 read_cap_from(init_pid, src_slot, ObjectTag::Frame, Rights::ALL, &ptable)?
1144 };
1145 POOL.lock().inc_ref(cap.object_id(), cap.generation())?;
1146 let ptable = crate::proc::PROCESSES.lock();
1147 insert_cap_into(shell_pid, dst_slot, cap, &ptable)
1148 .inspect_err(|_| {
1149 POOL.lock_after(&ptable)
1150 .dec_ref(cap.object_id(), cap.generation());
1151 })
1152 })?;
1153 [(vfs_client_slots::NOTIF, ObjectTag::Notification),
1154 (vfs_client_slots::VFS_NOTIF, ObjectTag::Notification),
1155 (init_slots::VFS_PROC, ObjectTag::Process)]
1156 .iter()
1157 .try_for_each(|&(slot, tag)| {
1158 let cap = {
1159 let ptable = crate::proc::PROCESSES.lock();
1160 read_cap_from(init_pid, slot, tag, Rights::ALL, &ptable)?
1161 };
1162 POOL.lock().inc_ref(cap.object_id(), cap.generation())?;
1163 let ptable = crate::proc::PROCESSES.lock();
1164 insert_cap_into(shell_pid, slot, cap, &ptable)
1165 .inspect_err(|_| {
1166 POOL.lock_after(&ptable)
1167 .dec_ref(cap.object_id(), cap.generation());
1168 })
1169 })?;
1170 }
1171 Err(_) => {
1172 drop(ptable);
1173 }
1174 }
1175 }
1176
1177 crate::show!(boot,
1178 "remote shell caps ring base {}/{} shell-notif slots {}/{} netstack-notif slot {}",
1179 net_service_slots::SHELL_RING_BASE,
1180 remote_shell_slots::SHELL_RING_BASE,
1181 net_service_slots::SHELL_NOTIF,
1182 remote_shell_slots::NOTIF,
1183 remote_shell_slots::NETSTACK_NOTIF,
1184 );
1185
1186 Ok(())
1187}
1188
1189pub fn bootstrap_init_netring(init_pid: Pid, netstack_pid: Pid) -> Result<(), KernelError> {
1190 create_shared_ring_frames(
1191 init_pid,
1192 init_slots::NETSTACK_RING_BASE,
1193 netstack_pid,
1194 net_service_slots::INIT_RING_BASE,
1195 init_slots::NETSTACK_RING_FRAMES,
1196 )?;
1197
1198 let init_notif_data = ObjectData::Notification(NotificationData::new());
1199 let init_notif_tag = init_notif_data.tag();
1200 let (init_notif_id, init_notif_gen) = POOL.lock().allocate(init_notif_data)?;
1201 let init_notif_cap = CapRef::new(init_notif_tag, init_notif_id, Rights::ALL, init_notif_gen);
1202 {
1203 let ptable = crate::proc::PROCESSES.lock();
1204 insert_cap_into(init_pid, init_slots::INIT_NOTIF, init_notif_cap, &ptable)
1205 .inspect_err(|_| {
1206 let r = POOL.lock_after(&ptable).free(init_notif_id, init_notif_gen);
1207 debug_assert!(r.is_ok());
1208 })?;
1209 POOL.lock_after(&ptable)
1210 .inc_ref(init_notif_id, init_notif_gen)?;
1211 insert_cap_into(netstack_pid, net_service_slots::INIT_NOTIF, init_notif_cap, &ptable)
1212 .inspect_err(|_| {
1213 POOL.lock_after(&ptable)
1214 .dec_ref(init_notif_id, init_notif_gen);
1215 })?;
1216 }
1217
1218 let netstack_notif_cap = {
1219 let ptable = crate::proc::PROCESSES.lock();
1220 read_cap_from(netstack_pid, net_service_slots::NOTIF, ObjectTag::Notification, Rights::ALL, &ptable)?
1221 };
1222 POOL.lock().inc_ref(
1223 netstack_notif_cap.object_id(),
1224 netstack_notif_cap.generation(),
1225 )?;
1226 {
1227 let ptable = crate::proc::PROCESSES.lock();
1228 insert_cap_into(init_pid, init_slots::NETSTACK_NOTIF, netstack_notif_cap, &ptable)
1229 .inspect_err(|_| {
1230 POOL.lock_after(&ptable).dec_ref(
1231 netstack_notif_cap.object_id(),
1232 netstack_notif_cap.generation(),
1233 );
1234 })?;
1235 }
1236
1237 crate::show!(boot,
1238 "init-netstack ring base {}/{} init-notif slots {}/{} netstack-notif slot {}",
1239 init_slots::NETSTACK_RING_BASE,
1240 net_service_slots::INIT_RING_BASE,
1241 init_slots::INIT_NOTIF,
1242 net_service_slots::INIT_NOTIF,
1243 init_slots::NETSTACK_NOTIF,
1244 );
1245
1246 Ok(())
1247}