feat: devices via caps (BootInfo, init assigns devices, drivers map MMIO/DMA themselves, IRQ-driven input); drop boot device wiring and info pages; headless display fallback

This commit is contained in:
2026-10-27 12:28:39 +01:00
parent 8bc5402a29
commit 694c675a40
39 changed files with 731 additions and 387 deletions

View File

@@ -7,7 +7,7 @@ use domain::{error::KernelError, resource::Resource};
use platform::Platform;
use types::{
address::PhysicalAddress,
bounded::PageCount,
bounded::{CapSlot, PageCount},
id::{IrqId, ProcessId, RegionId},
permission::{Permission, PermissionSet},
};
@@ -23,6 +23,13 @@ pub struct BoardDevice {
pub irq: Option<IrqId>,
}
/// Where `grant_boot_authority` put one device's capabilities in init.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BoardCaps {
pub region: CapSlot,
pub irq: Option<CapSlot>,
}
impl<P: Platform> Kernel<P> {
/// Creates one device region per board device, owned by `init`. Fails
/// on the first device that is misaligned, overlaps the frame pool or
@@ -45,28 +52,33 @@ impl<P: Platform> Kernel<P> {
/// Gives `init` a capability to every registered device's region and
/// IRQ line, then one SystemControl capability. All carry Delegate so
/// init can hand them on. Done separately from `register_board` so
/// boot code can wire drivers to the regions first.
/// init can hand them on. Writes where each device's caps went into
/// `placed` (one entry per device, in order) and returns the
/// SystemControl slot, so boot can tell init.
pub fn grant_boot_authority(
&mut self,
init: ProcessId,
devices: &[BoardDevice],
) -> Result<(), KernelError> {
placed: &mut [Option<BoardCaps>],
) -> Result<CapSlot, KernelError> {
let delegate = PermissionSet::empty().with(Permission::Delegate);
let control = delegate.with(Permission::Execute);
let mmio = delegate.with(Permission::Read).with(Permission::Write);
for device in devices {
for (i, device) in devices.iter().enumerate() {
let region = self
.device_region_at(device.base)
.filter(|id| self.regions.get(*id).is_some_and(|r| r.owner() == init))
.ok_or(KernelError::NoSuchObject)?;
self.grant_cap(init, Resource::Memory(region), mmio)?;
if let Some(irq) = device.irq {
self.grant_cap(init, Resource::Interrupt(irq), control)?;
let region = self.grant_cap(init, Resource::Memory(region), mmio)?;
let irq = match device.irq {
Some(irq) => Some(self.grant_cap(init, Resource::Interrupt(irq), control)?),
None => None,
};
if let Some(slot) = placed.get_mut(i) {
*slot = Some(BoardCaps { region, irq });
}
}
self.grant_cap(init, Resource::SystemControl, control)?;
Ok(())
self.grant_cap(init, Resource::SystemControl, control)
}
/// The device region that starts at `base`.