Skip to main content

Crate consortium_cfg

Crate consortium_cfg 

Source
Expand description

Turns a Consortium.toml manifest into validated configuration, generated Rust, and Linux integration artifacts.

This is the crate that makes Consortium’s “explicit cross-core contracts” idea pay off. A manifest declares what the system is — which cores exist, which memory windows they share, which doorbell rings which — and this crate checks that against the chip’s real capabilities, then emits the bring-up code and device-tree nodes that make it so. Firmware and application authors never write the address arithmetic, the UIO ids, or the doorbell wiring by hand.

§Pipeline

Consortium.toml
  └─ session   parse + resolve the chip database + validate       → Session
       └─ bridge    lower into the components IR                  → ShmNode, BellA, …
            └─ components   each IR node generates its own output
                 ├─ Rust tokens ─ render ─→ src/consortium.gen.rs
                 ├─ DTS nodes   ────────→ merged tree or .dtso
                 └─ Kconfig / boot / systemd fragments
StageModuleProduces
Parse, validatesessionSession — manifest bound to its chip database
LowerbridgeThe components IR, with addresses and UIO ids resolved
GeneratecomponentsRust tokens, DTS nodes, UIO/Kconfig fragments
Formatrender()Formatted Rust source

consortium-builder drives this and adds compilation, staging, and packaging.

§What validation catches

Session::from_toml resolves [profile] chip through the embedded databases in consortium-data and then rejects manifests that ask for things the chip cannot do — the errors in CfgError are the interesting part of this crate’s contract:

  • a doorbell the chip does not have, or a doorbell channel out of its range;
  • a channel whose party is not a visible core, or has no declared endpoint;
  • two channels claiming the same doorbell channel;
  • memory regions out of bounds, overlapping, or misaligned for the MPU;
  • debug regions that collide with IPC regions;
  • a peripheral owned by a core that cannot reach it — checked against the per-core chip map, so the filter is the peripherals that core’s CMSIS view actually contains;
  • [peripheral.*] with secure = true, since the chip HAL’s singletons carry only the non-secure alias.

Catching these at manifest-parse time is the point: each would otherwise be a silent bus error or a link that never wakes.

§Where the fixed decisions live

bridge pins the AP-side address layout so the firmware, NVIC, and Linux DTS outputs cannot disagree:

  • every device — the aggregate IPC shared-memory device, one per distinct doorbell, and the aggregate debug-ring device — gets its uioN id by ascending mapped base, so ids follow the memory map the kernel enumerates;
  • within the IPC device a region’s mmap_id is its index in channel-declaration order, and a doorbell always exposes its register window as mmap_id 0.

§Generated code

The output is src/consortium.gen.rs in each endpoint crate, which the crate include!s. It defines Config, endpoint-local Peripherals and Channels, and synchronous init(config). Init performs local platform bring-up and installs unsplit transports; application code connects each channel token independently before use.

Because a generated crate cannot be cargo checked before the pipeline has run, the melt-pot endpoint crates are excluded from the workspace.

§Adding to the schema

Work outward, because each step’s tests depend on the previous: schema types in consortium-cfg-common → validation in session → lowering in bridge → codegen in components. Then update the snapshot tests under tests/.

Consortium.example.*.toml and session’s own tests are the best references for current syntax — older melt-pot manifests drift.

Re-exports§

pub use render::render;
pub use error::CfgError;
pub use session::Session;

Modules§

bridge
Lowers a validated Session into the components IR.
chipmap
Per-core peripheral and interrupt maps, embedded at compile time from the generated chip dumps (database/chip/*.json).
components
The lowered IR: one node per thing the manifest asks the system to have, each owning the code or device-tree it generates.
config
Vendor-agnostic Consortium.toml schema.
database
Chip-family databases, embedded at compile time and resolved from a chip part number declared in [profile] chip.
error
render
Renders generated codegen tokens to formatted Rust source.
session
Loads a Consortium.toml manifest and binds it to its chip-family database.
signal
Per-family pin-mux and DMA-request maps, embedded at compile time from the generated signal databases (database/signal/<family>.json).