Skip to main content

Module arena

Module arena 

Source
Expand description

A driver’s ARENA: the memory its device reads and writes, granted at spawn, and laid out by name.

§Why this exists

A device that does DMA is given an arena: physically contiguous memory the kernel mapped into the driver, whose physical addresses the driver programs into the device (CLAUDE.md 12.3, 6.4). Every driver reached past the standard library for it, with the SDK’s ctx.dma_region(), and then laid it out by hand (AHCI and GENET were the first to come through gs, 2026-10-19, and every compiled driver did by the next day, docs/driver-library.md step 3): seven drivers placed their rings, buffers and tables at offset constants of their own, 33 of them, and two asserts between them checked that nothing overlapped. The day this was written, the RTL8168’s 24 receive buffers filled its arena to the last 4 KiB, and one hand-written assert was all that kept its counters from landing inside a buffer.

So the arena comes through gs (docs/driver-library.md, step 3), with the one mechanism every one of those drivers wrote out: parts, taken by name, size and alignment, that cannot overlap.

§The shape

ⓘ
let Some(arena) = gs::driver::arena(&ctx) else { /* say so and park */ };
let mut parts = arena.layout();
let rx_ring = parts.take("rx ring", 24 * 16, 256)?;
let rx_bufs = parts.take("rx buffers", 24 * 2048, 8)?;
let tally = parts.take("tally", 64, 64)?;

rx_ring.write32(i * 16, own | len);      // offsets are within the part
let buf = rx_bufs.phys_at(i * 2048);     // the address the device is given
  • A part that does not fit is refused, with its name (NoRoom), before anything is written: the arena (64 KiB) has no room for `tally` (64 bytes, aligned to 64, after 64 KiB).
  • Alignment is of the PHYSICAL address, because that is what the device checks. A ring a device requires on a 256-byte boundary is on one, whatever the arena’s base.
  • Every access is bounded to its part. An offset past the part ends the driver loudly, naming the part, as an offset past the arena always did (SEC-4) - so a ring’s index running off its end is caught at the ring, not when it reaches someone else’s buffer.
  • Laying out takes the arena: once laid out it is reached only through its parts. A driver that wants the whole arena, one buffer and nothing else, uses the Arena directly and needs no layout.

What a part HOLDS - a descriptor’s fields, a ring’s ownership bits - is the device’s, and stays in its driver. What is here is only where things are, which is the same for every device.

§Coherency

None is done here, as none is done beneath (the SDK’s Dma, SEC-28): each port maps the arena so the CPU and the device agree - uncached where DMA is not coherent. A part is a view of that mapping.

Structs§

Arena
The DMA arena the kernel granted this driver. Not Copy: Arena::layout takes it, so a laid-out arena is reached only through its parts.
Layout
An arena being laid out: parts are taken in order, each after the last, and never overlap.
NoRoom
Why a part was refused. Its Display is a sentence a driver can log as it stands.
Part
One named part of the arena. Offsets are within the part, and an access past it ends the driver naming the part. Copies are views of the same bytes.

Enums§

Why
What made a part impossible.

Functions§

arena
This driver’s arena, or None when the spawn granted none.
place
Where a part of len bytes, aligned to align, goes in an arena of arena bytes whose physical base is phys and whose first used bytes are taken: its offset, or why it cannot go anywhere.