bhx
community★ featuredBoot stock Linux cloud images on the SiFive X280 RISC-V cores inside Tenstorrent Blackhole AI accelerators. Per-card Rust daemon with virtio-mmio block/net/console and U-Boot/EFI support.
Links
📦
Repo
📋 Changelog
# Changelog Notable changes per release. Format loosely follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project does not yet promise SemVer compatibility on the RPC wire format or library API surface (we're not 1.0). ## Unreleased V2 virtio-dispatch redesign. The kick ring + completion ring + host- side throttle that grew up around #184 are gone; in their place is a per-(slot, queue) dirty bitmap in BRISC L1. The bitmap is level- sensitive — guest QUEUE_NOTIFY storms coalesce into a single set byte, so the dispatch path can't fall behind under any burst. Wire incompatible with 0.9.0; `TENSIX_PROTOCOL_VERSION` bumped 4 → 5. ### Added - **V2 dirty-bitmap dispatch** (`#187` / `#188` / `#189`). BRISC writes 1 to `CTRL_OFF_DIRTY[slot][queue]` on every guest QUEUE_NOTIFY; the daemon's `Dispatcher` clears the byte and dispatches each pass. Replaces V1's 2048-entry kick ring + daemon-side `consume_kick_ring_pass` consumer. - **V2 processed-cursor table** at `CTRL_OFF_PROCESSED`. Daemon publishes `used.idx` after each successful dispatch so warm-resume reads cursors directly without re-probing guest DRAM. - **`bhx_notify_events_total`, `bhx_dispatch_passes_total`, `bhx_dispatch_queues_drained`** Prometheus counters surface the new dispatch path. The burst regression test (`scripts/ soak_virtio_burst.py`) asserts `dispatch_passes_total > 0` to confirm the workload reached the new path. - **`scripts/soak_virtio_burst.py`** — multi-queue burst regression test. Sustains 16-job direct=1 fio randwrite + a tight `printf` loop to `/dev/console`, samples `/metrics` every 1 s, and verifies the daemon log contains zero `kick.*drop|rescue|throttle.*ENGAGE` matches. - **`DaemonState.chip_reset_this_session`** flag — gates `maybe_opportunistic_reset_board` so 4-way parallel cold boots reset the chip exactly once, not once per L2CPU. Without this the second-and-later resets blip the chip while earlier-booted L2CPUs hold mmap pages, SIGBUSing their workers. - **`Dispatcher` (was `KickPoller`)** with documented testability seam (`CtrlL1Access` trait); `drain_dirty_bitmap` is unit-tested against an in-memory L1 fake covering all five visit/clear semantics cases plus the address-formula pins. ### Changed - **`KickPoller` → `Dispatcher`**, plus `kick_poller` → `dispatcher` field on `DaemonState`, `tensix-kick-poller` → `tensix-dispatcher` thread name, `[kick-poller]` → `[dispatcher]` log tag, `kicks_consumed` → `dispatches_total`, `last_kick_slot_queue` → `last_dispatch_slot_queue`. Pure rename; no behavior change. V1 vocabulary scrubbed throughout the codebase (firmware, daemon, scripts, docs). - **`CTRL_SIZE` shrinks 36 KiB → 4 KiB**. V2 footprint is ~1.5 KiB; the rest is reserved for future fields. - **Stats-page offsets repacked** — V1 `STATS_OFF_KICK_DROPS`, `STATS_OFF_COMPL_EVENTS`, `STATS_OFF_LAST_COMPL` retired with V1 (#190); deprecated PRECAP / BLINDCAP / POSTCAP slots dropp
Works on
blackhole