Files
k-os/crates/domain/src/capability/mod.rs
Gabriel Kaszewski 76f10ff1f1 feat(kernel): seL4-style IPC, notifications, status ABI
- badges + Mint, Call/Reply/ReplyRecv w/ gen-checked reply slot
- cap transfer (1/msg, copy, needs Delegate, rechecked at delivery)
- notifications: signal/wait/poll/bind, irq -> notification routing
- WaitAny/WaitForInterrupt removed; a0=status, ErrorCode
- libkos: single ecall primitive, compat wrappers + typed new api
- fix: trap return clobbered user t0 on every trap
- fix: wait queues FIFO, delegate keeps badge, fault cap checked
- docs/ipc.md spec, ipc tests, ipc fuzz, kani ntfn + waitqueue
2026-10-26 20:27:38 +01:00

99 lines
2.3 KiB
Rust

use types::{badge::Badge, bounded::CapSlot, generation::Generation, permission::PermissionSet};
pub mod authority;
use crate::{error::KernelError, resource::Resource};
#[cfg(test)]
#[path = "tests.rs"]
mod tests;
// Sized so that every representable `CapSlot` indexes a real slot.
pub const MAX_CAPS_PER_PROCESS: usize = CapSlot::MAX as usize + 1;
#[derive(Clone)]
pub struct Capability {
resource: Resource,
permissions: PermissionSet,
generation: Generation,
badge: Badge,
}
impl Capability {
pub fn new(resource: Resource, permissions: PermissionSet, generation: Generation) -> Self {
Self {
resource,
permissions,
generation,
badge: Badge::NONE,
}
}
/// The same capability with `badge` stamped on it.
pub fn with_badge(mut self, badge: Badge) -> Self {
self.badge = badge;
self
}
pub fn badge(&self) -> Badge {
self.badge
}
pub fn resource(&self) -> &Resource {
&self.resource
}
pub fn permissions(&self) -> &PermissionSet {
&self.permissions
}
pub fn generation(&self) -> &Generation {
&self.generation
}
}
pub struct CapabilityTable {
slots: [Option<Capability>; MAX_CAPS_PER_PROCESS],
}
impl CapabilityTable {
pub fn new() -> Self {
Self {
slots: [const { None }; MAX_CAPS_PER_PROCESS],
}
}
pub fn get(&self, slot: CapSlot) -> Result<&Capability, KernelError> {
let idx = slot.value() as usize;
self.slots[idx]
.as_ref()
.ok_or(KernelError::InvalidSlot(slot))
}
pub fn insert(&mut self, cap: Capability) -> Result<CapSlot, KernelError> {
let idx = self
.slots
.iter()
.position(|s| s.is_none())
.ok_or(KernelError::NoFreeSlot)?;
self.slots[idx] = Some(cap);
CapSlot::new(idx as u8).ok_or(KernelError::NoFreeSlot)
}
pub fn remove(&mut self, slot: CapSlot) -> Result<(), KernelError> {
let idx = slot.value() as usize;
if self.slots[idx].is_none() {
return Err(KernelError::InvalidSlot(slot));
}
self.slots[idx] = None;
Ok(())
}
}
impl Default for CapabilityTable {
fn default() -> Self {
Self::new()
}
}