Skip to main content

Firmware composition

An EV74 operation declares its identity beside its firmware registration. One build-time inventory generates the host catalogue, ID constants, package lists and selected firmware dispatch. Runtime executes prepared transport constants; it does not discover names or map IDs on each invocation.

Local declarations generate the complete host catalogue and a selected resident firmware.

Declare identity locally​

Use the existing production contribution, for example NativeHistogramFirmware.cmake (EV74/histogram/firmware/NativeHistogramFirmware.cmake):

sima_register_native_kernel(
NAME histogram
GRAPH_ID 500
PACKAGE sima_histogram
)

The file contains one literal declaration, not procedural CMake. The canonical reader never executes it. NAME matches the operation folder; PACKAGE names its explicit native device target. Keep numerical source lists and compiler flags in the operation's device/CMakeLists.txt. Do not add a second registry or edit any generated file. Registration sources and host/route.h remain local and own the capability, packet ABI and authorized relocations.

Readable IDs, unchanged transport​

FamilyDeveloper IDsTransport IDs
Elementwise100–11516–31
Storage200–21532–47
Fused transforms300–31548–63
Image processing400–41564–79
Vision500–53180–111

For an admitted family:

transport = transport_family_base + (graph_id - developer_family_base)

Histogram's graph ID 500 therefore compiles to transport ID 80. IDs outside these intervals fail the build. Customers continue to use typed operation requests; these numbers are kernel-authoring identities, not customer operation enums.

The independent released compatibility contract (EV74/firmware/native/compatibility.json) preserves existing transport values and physical link order, including Dequant before Quant. New operations do not edit that released snapshot. A retired operation retains its declaration with RETIRED TRUE; its identity cannot be silently reused. ABI versions remain independent of graph IDs.

On the development host, inspect the derived inventory:

python3 tools/native_catalogue.py --source . --list
# Show an explicit deployment union without renumbering the complete catalogue:
python3 tools/native_catalogue.py --source . --list --operations cast quanttess preproc

Normal configuration generates native_routes.def, authoring constants, native-inventory.json and a human-readable ID reference. Packaging, qualification and documentation consume the same inventory. Generated headers are installed from the build tree; there is no stale source-owned catalogue to overwrite them.

Choose a resident operation union​

The installed host catalogue describes all active operations. A firmware target may select only the capabilities needed by a deployment:

# In the platform's private firmware project, after creating its firmware target:
sima_runtime_add_native_firmware(cvu_bridge
OPERATIONS cast quanttess preproc
)

Omit OPERATIONS for the all-operation development default. An explicit empty, duplicate, unknown or retired selection fails configuration. Selection does not renumber IDs or reorder the remaining providers. The checked selected inventory controls linked registrations, dispatcher and optional memory telemetry together. An omitted operation has no dangling handler or startup reference.

Compose against matching installed Kernels contributions and native-only device packages. Runtime and the full host schema must be rebuilt for newly introduced routes; an old Runtime binary does not discover arbitrary future operations. Missing or unprobed capabilities fail before numerical submission. Firmware stays resident during execution: no per-frame swapping, registration constructors or module loader is introduced.

Inspect actual linked placement​

Composition requires a MetaWare map. The default is map.txt in the firmware build directory; pass MAP /absolute/path/to/map.txt for a different platform setting. Each successful link writes <target>-layout.json beside the target. It records firmware/map/inventory hashes, allocated sections and load segments, entry symbols, operation and platform input contributions, initialized footprint and reserved heap extents. Map ownership includes operation registration objects and native archive members; SDK imports remain platform-owned. Output-section padding is reported separately, not invented as operation-owned code.

Optional cold composition arguments:

ArgumentPurpose
BEFOREPrevious layout report for address, size and content comparison
RESOURCESReviewed compiled resource report, retained with its hash
POLICYVersioned bounded placement policy checked after linking

A missing or unreadable map is a build failure. A policy rejects overlapping regions, unadmitted allocated sections, component overflow and changed explicit shared-section contracts. Inspect movement without claiming it caused a latency change. Relocation changes can change code hashes even without math changes.

On the development host, replay a report from actual artifacts:

python3 tools/native_layout.py \
--elf build/native/cvu_bridge.out \
--map build/native/map.txt \
--inventory build/native/native-composition.json \
--before build/reference/cvu_bridge-layout.json \
--output build/native/cvu_bridge-layout.json

A layout report is not device qualification. Symbol addresses do not prove transitive stack use or DMA safety; retain existing compiled-resource admission, malformed-packet tests and guarded real-device correctness/latency checks. Reports can contain private build paths: keep them in approved build/artifact storage, not public numerical source or documentation.

Placement is a separate platform decision​

Identity, transport and physical addresses are independent. Deterministic link order does not isolate addresses when a component grows. Bounded placement must use capacities sized from actual compiled code, constants, state and shared resources—not a giant slot multiplied by graph ID. Kernel authors do not choose addresses, and splitting code must not duplicate shared scratch.

tools/native_placement.py provides an opt-in platform workflow. Generated policies and layout reports do not themselves establish qualification:

  1. Build the default firmware and retain its actual layout report.
  2. Propose capacities from that report, supplying reviewed arena bounds, stack placement and a headroom percentage. The tool refuses to overwrite a proposal.
  3. Review and version the policy in platform build inputs. No policy or physical addresses belong in an ordinary operation declaration.
  4. Render the supported MetaWare template from the current build's map and the versioned policy; use it as the platform's explicit EVSS_CFG_LNK_PATH.
  5. Relink with POLICY enabled. Verify the actual ELF/map and resident footprint; fail on overflow or ownership ambiguity instead of silently resizing slots.
  6. Qualify matching device correctness/resources and paired cross-kernel latency before enabling it in a deployment. A successful link does not satisfy this.

The renderer uses extracted object members and final registration paths—not GNU archive-selector assumptions. It rejects ambiguous member names and unknown platform template forms. Exact input sections retain their actual linked order within a component: grouping all functions by source filename can destroy the default linker's branch/call locality. Unmatched sections of admitted members remain bounded; new members require a fresh default map, not manual selectors. Regions have separate bounded memory cursors; the platform DRAM region excludes the numerical arena. Shared scratch arrangements remain unchanged. Unwind, constructor and thread-local metadata stay in their platform ABI sections so range-based runtime readers are not silently broken; these are explicit shared dependencies, not a promise of complete module independence.

Component BSS needs explicit initialization: the platform loader skips segments with no file bytes, and the CRT clears only its conventional BSS ranges. The renderer adds a bounded, aligned zero anchor so private BSS becomes file-backed; the post-link gate verifies the actual LOAD coverage. This adds only initialization bytes, not per-invocation work. Do not rename BSS into private NOLOAD sections and assume the loader or CRT will clear it.

The policy checker enforces the supplied layout; it does not qualify one. The default composer keeps existing placement. Enable a new policy only after the actual linker output, memory footprint, device correctness and cross-kernel performance pass. Do not present an unqualified layout as a fix for a historical latency regression or relax a baseline to make it pass.

Safety boundaries​

Reviewed native source and the private compiler are trusted build inputs, not sandboxed extensions. Static generation rejects conflicting identities and stale installed declarations; generated host schemas still constrain admitted packets. Keep check_inference(), actual binding capacity/alignment/alias checks, authorized relocations, lifetime ownership, device packet admission and DMA retirement. Capability probes establish compatibility, not cryptographic authenticity.