Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 26 additions & 17 deletions artifacts/phase2-pixhawk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -567,26 +567,35 @@ artifacts:

- id: TEST-PIX-019
type: test-spec
title: Renode multi-node vehicle (Track B) - M7 + F100 real binaries co-execute in one emulation joined by the IPC hub (the real-hardware mirror of TEST-PIX-018)
title: Renode multi-node vehicle (Track B) - THREE-CORE M7+M4+F100 co-execute in one emulation with a live M7<->M4 shared-mem link (real-hardware mirror of TEST-PIX-018)
status: draft
description: >
hardware/renode/vehicle/run-vehicle-multinode.sh - the Renode (real synth->ARM)
mirror of the wasmtime combined harness (TEST-PIX-018), same two-node scenario
(DD-019). Instantiates BOTH nodes in one Renode emulation: mach m7-fmu
(pixhawk6xrt.repl + a bring-up firmware) + mach f100-io (gale gust_m3_8k.repl +
gust_wasm.elf, the real dissolved failsafe), joined by a UARTHub "relaybus" (the
relay-bus carrier proxy, relay#177 / DD-009). CONFIRMED 2026-06-22: both machines
co-execute - `mach` lists m7-fmu (RT1176, SP 0x20040000) + f100-io (gust, bss 4256
@0x20000214, SP 0x20002000), both Machine started, M7 lpuart1 connected to the hub.
hardware/renode/vehicle/run-vehicle-multinode.sh - the Renode (real ISA) mirror of
the wasmtime combined harness (TEST-PIX-018), DD-019, now the FULL THREE-CORE
topology of the 6X-RT (Stage 4): mach "rt1176" = rt1176-dualcore.repl with cpu_m7
(smoke bring-up -> LPUART1 banner) + cpu_m4 (Cortex-M4 FPv4-SP, the on-die
SENSOR-OFFLOAD core, DD-018 T2) on the SHARED RT1176 sysbus, plus an OCRAM-adjacent
SHMEM ring @ 0x20400000 (relay-bus carrier region, DD-009) + an MU mailbox stub;
mach "f100-io" = gale gust_m3_8k.repl + gust_wasm.elf (the real dissolved failsafe).
Per-core NVIC via Renode BusPointRegistration (dual-core pattern, cf.
renesas-da14592). rt1176-dualcore.repl is SEPARATE from the CI-gated pixhawk6xrt.repl
(M7-only smoke), left untouched.
CONFIRMED 2026-06-25 (jess local, Renode v1.16.1): all THREE cores co-execute -
cpu_m7 boots smoke -> LPUART1 "JESS-RT1176 boot OK"; cpu_m4 boots the heartbeat
firmware (vectors/text/stack in OCRAM @0x20240000, SP 0x20250000) and WRITES AN
ADVANCING HEARTBEAT to the SHMEM ring @0x20400000 (read back ~0xA2C29 after 0.02s
sim) - proving the on-die M7<->M4 SHARED-MEMORY LINK is LIVE, not just that the M4
instantiates; f100-io (gust) co-executes. ORACLE PASS (M7 banner + M4 heartbeat>0).
DEFERRED (honest scope, hence status=draft): the REACTIVE failsafe handoff (gust
consuming the M7 heartbeat over ipc-rx + tripping on loss) needs a gust ipc-rx build
with a connectable UART (gale - gust_m3_8k.repl has only a SemihostingUart, so only
the M7 side is hub-wired today); and real falcon on the M7 is a bring-up STUB until
the on-target punch-list clears (#369 hard-float/AFD-024, #275 dispatch/AFD-008).
Until then the handoff is orchestration-modeled (pause m7-fmu = M7 fault), mirroring
how the wasmtime track host-models the arbitration. Track A (TEST-PIX-018) carries
the handoff LOGIC end-to-end; the two together are the DD-010/DD-019 SIL-differential
at vehicle scale.
consuming the M7/M4 heartbeat over ipc-rx + tripping on loss) needs a gust build
whose ipc-rx is wired to a connectable transport (gale's gust_m3_8k.repl has only a
SemihostingUart) - asked gale for the driver + access (gale#65). Real falcon on the
M7 + real sensor drivers on the M4 are bring-up STUBS until the synth poles clear
(#369 hard-float/AFD-024, #275 dispatch/AFD-008); the M4 heartbeat stands in for the
sensor-offload workload. The MU mailbox is a plain-memory stub (doorbell-IRQ later);
the shared-mem ring itself is live. Until the reactive path lands the handoff is
orchestration-modeled; Track A (TEST-PIX-018) carries the handoff LOGIC end-to-end -
together the DD-010/DD-019 SIL-differential at vehicle scale.
tags: [phase-2, simulation, renode, multi-node, vehicle, on-target]
links:
- type: verifies
Expand Down
60 changes: 35 additions & 25 deletions hardware/renode/vehicle/README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,46 @@
# Track B — Renode multi-node vehicle (the real-hardware mirror of the wasmtime sim)

The Renode (real synth→ARM, modeled silicon) counterpart of `sim/vehicle-wasmtime.sh`.
Same two-node scenario (DD-019 / REQ-PIX-017), exercised on real ISA models instead of
in wasmtime.
The Renode (real ISA, modeled silicon) counterpart of `sim/vehicle-wasmtime.sh`. Same
two-node scenario (DD-019 / REQ-PIX-017), now the **full three-core topology** of the
Pixhawk 6X-RT (Stage 4): M7 + M4 on the RT1176 die + the F100 IO-MCU.

```
mach "m7-fmu" : hardware/renode/pixhawk6xrt.repl + bring-up firmware (M7 / RT1176)
mach "f100-io" : gale gust_m3_8k.repl + gust_wasm.elf (F100 / real dissolved failsafe)
└── UARTHub "relaybus" ── the inter-node IPC link (relay-bus carrier, relay#177 / DD-009)
mach "rt1176" (rt1176-dualcore.repl — two cores on one shared sysbus):
cpu_m7 : hardware/renode/smoke/rt1176-smoke.elf — bring-up, LPUART1 banner
(real falcon pending the synth poles #369/#275)
cpu_m4 : m4/m4-heartbeat.elf — the on-die SENSOR-OFFLOAD core (DD-018 T2),
publishes a heartbeat to the M7<->M4 shared-memory ring
└── SHMEM @ 0x20400000 (relay-bus carrier region, DD-009) + MU mailbox stub
mach "f100-io" : gale gust_m3_8k.repl + gust_wasm.elf — the real dissolved failsafe
└── FMU<->F100 link = relay-bus carrier (relay#177)
```

Run: `RENODE=~/renode-…/renode hardware/renode/vehicle/run-vehicle-multinode.sh`

## What this rung CONFIRMS (2026-06-22)
Both real node binaries **co-execute in one Renode emulation**: `mach` lists `m7-fmu`
(RT1176, SP 0x20040000) and `f100-io` (gust, `.bss` 4256 @ 0x20000214, SP 0x20002000 =
top of 8 KB), both `Machine started`, joined by the `relaybus` UART hub (M7 `lpuart1`
connected). This is the multi-node **topology** of the real-hardware vehicle sim — the
Track-B structural mirror of the wasmtime combined harness.
## What this rung CONFIRMS
All **three cores co-execute** in one Renode emulation, and the **M7<->M4 shared-memory
link is live**:
- `cpu_m7` boots the smoke firmware → LPUART1 banner `JESS-RT1176 boot OK`.
- `cpu_m4` (Cortex-M4, FPv4-SP) runs on the shared RT1176 sysbus and **writes an
advancing heartbeat to the SHMEM ring @ 0x20400000** (read back ~0xA2C29 after a
short run) — proving the on-die M7<->M4 shared-memory carrier works, not just that
the core instantiates.
- `f100-io` (gust) co-executes as the failsafe node.
Per-core NVIC via `BusPointRegistration` (Renode dual-core pattern). `rt1176-dualcore.repl`
is separate from the CI-gated `pixhawk6xrt.repl` (M7-only smoke gate), left untouched.

## What is DEFERRED (honest scope) and why
- **Reactive failsafe handoff** (gust *consuming* the M7 heartbeat over `ipc-rx` and
tripping on loss) needs a **gust `ipc-rx` build with a connectable UART** — gale's
`gust_m3_8k.repl` exposes only a `SemihostingUart`, so only the M7 side is wired to the
hub today. Until then the handoff is **orchestration-modeled** (pausing the `m7-fmu`
machine = M7 fault), exactly as the wasmtime track host-models the arbitration.
- **Real falcon on the M7** is a bring-up stub here because falcon's synth→ARM image is
still blocked by the on-target punch-list (**#369 hard-float / AFD-024**, **#275
dispatch / AFD-008**). When those land, the M7 node runs real falcon and the Renode
rung becomes a full real-binary vehicle sim.
- **Reactive failsafe handoff** (gust *consuming* the M7/M4 heartbeat over `ipc-rx` and
tripping on loss) needs a **gust build whose `ipc-rx` is wired to a connectable
transport** — gale's `gust_m3_8k.repl` exposes only a `SemihostingUart`. Asked gale for
the driver + access (gale#65). Until then the handoff is orchestration-modeled, exactly
as the wasmtime track host-models it; the handoff LOGIC is proven on Track A
(TEST-PIX-018).
- **Real falcon on the M7**, and **real sensor drivers on the M4**, are bring-up stubs
until the synth poles (#369 hard-float / AFD-024, #275 dispatch / AFD-008) clear; the
M4 heartbeat stands in for the sensor-offload workload.
- **The MU mailbox** is a plain-memory stub (the doorbell-IRQ semantics are a later
increment); the shared-mem ring itself is live.

So Track B = multi-node co-execution + IPC scaffold **now**; full reactive handoff gated
on (a) gust `ipc-rx` (gale) and (b) the synth punch-list. The wasmtime track (Track A)
already demonstrates the *logic* of the handoff end-to-end (TEST-PIX-018) — the
SIL-differential pairing (DD-010 / DD-019) is what makes that division productive.
So Track B is now the three-core co-execution + a live on-die M7<->M4 shared-mem link;
full reactive behavior is gated on gale's gust-ipc + the synth poles.
Binary file added hardware/renode/vehicle/m4/m4-heartbeat.elf
Binary file not shown.
25 changes: 25 additions & 0 deletions hardware/renode/vehicle/m4/m4_boot.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@ Minimal i.MX RT1176 Cortex-M4 (FPv4-SP) bring-up for the jess 3-core vehicle sim.
@ The M4 is the on-die sensor-offload core (DD-018 T2). This stub writes an
@ incrementing heartbeat to the M7<->M4 shared-memory ring (SHMEM @ 0x20400000,
@ the relay-bus carrier region, DD-009) so the multi-core model demonstrates the
@ M4 executing + the shared-mem link live. Vectors/text/stack in OCRAM (shared by
@ both cores on the RT1176 sysbus). (TEST-PIX-019, Stage 4 multi-core.)
.syntax unified
.cpu cortex-m4
.thumb

.section .vectors, "a"
.word _m4_stack_top @ initial SP
.word reset + 1 @ reset vector (thumb bit)

.text
.thumb_func
.global reset
reset:
ldr r0, =_m4_stack_top
mov sp, r0
ldr r0, =0x20400000 @ SHMEM heartbeat word (M7<->M4 ring)
movs r1, #0
1: adds r1, #1
str r1, [r0] @ publish heartbeat -> shared memory
b 1b
7 changes: 7 additions & 0 deletions hardware/renode/vehicle/m4/m4_link.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
MEMORY { OCRAM (rwx) : ORIGIN = 0x20240000, LENGTH = 0x10000 }
ENTRY(reset)
_m4_stack_top = 0x20250000;
SECTIONS {
.vectors 0x20240000 : { KEEP(*(.vectors)) } > OCRAM
.text : { *(.text*) *(.rodata*) } > OCRAM
}
46 changes: 46 additions & 0 deletions hardware/renode/vehicle/rt1176-dualcore.repl
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// jess RT1176 DUAL-CORE (M7 + M4) platform for the multi-node vehicle sim
// (TEST-PIX-019, Stage 4). Extends the M7-only pixhawk6xrt.repl (the CI smoke
// gate, left untouched) with the second on-die core — Cortex-M4 (FPv4-SP), the
// sensor-offload core (DD-018 T2) — sharing the RT1176 sysbus, plus an OCRAM-
// adjacent shared-memory ring + an MU mailbox stub = the M7<->M4 AMP topology
// (DD-009, the relay-bus carrier relay#177). Per-core NVIC via BusPointRegistration
// (Renode dual-core pattern, cf. platforms/cpus/renesas-da14592.repl).

nvic_m7: IRQControllers.NVIC @ sysbus new Bus.BusPointRegistration { address: 0xE000E000; cpu: cpu_m7 }
systickFrequency: 1000000000
priorityMask: 0xF0
IRQ -> cpu_m7@0

cpu_m7: CPU.CortexM @ sysbus
cpuType: "cortex-m7"
nvic: nvic_m7

nvic_m4: IRQControllers.NVIC @ sysbus new Bus.BusPointRegistration { address: 0xE000E000; cpu: cpu_m4 }
systickFrequency: 400000000
priorityMask: 0xF0
IRQ -> cpu_m4@0

cpu_m4: CPU.CortexM @ sysbus
cpuType: "cortex-m4"
nvic: nvic_m4

// shared RT1176 memory (OCRAM is accessible by both cores)
itcm: Memory.MappedMemory @ sysbus 0x00000000
size: 0x40000
dtcm: Memory.MappedMemory @ sysbus 0x20000000
size: 0x40000
ocram: Memory.MappedMemory @ sysbus 0x20240000
size: 0x1C0000
flexspi2: Memory.MappedMemory @ sysbus 0x30000000
size: 0x4000000
lpuart1: UART.NXP_LPUART @ sysbus 0x4007C000
IRQ -> nvic_m7@20

// M7<->M4 shared-memory ring (relay-bus carrier region, DD-009) — both cores see it.
shmem: Memory.MappedMemory @ sysbus 0x20400000
size: 0x1000

// MU (Messaging Unit) mailbox stub — the M7<->M4 doorbell path; plain memory for
// the topology rung (real MU/IRQ semantics are a later increment).
mu: Memory.MappedMemory @ sysbus 0x40C4C000
size: 0x1000
56 changes: 30 additions & 26 deletions hardware/renode/vehicle/run-vehicle-multinode.sh
Original file line number Diff line number Diff line change
@@ -1,43 +1,47 @@
#!/usr/bin/env bash
# Track B (Renode real-hardware) mirror of the combined-vehicle wasmtime sim
# (sim/vehicle-wasmtime.sh): BOTH nodes as real ARM binaries in ONE Renode emulation.
# M7 (FMU) : pixhawk6xrt.repl + a bring-up firmware (real falcon pending #369/#275)
# F100 (IO) : gale gust_m3_8k.repl + gust_wasm.elf (the real dissolved failsafe)
# IPC link : a Renode UARTHub (the relay-bus carrier proxy, relay#177 / DD-009)
# Confirms the multi-node TOPOLOGY: both real node binaries co-execute in one emulation
# joined by the inter-node link. The reactive failsafe handoff (gust consuming the M7
# heartbeat over ipc-rx) needs a gust ipc-rx build (gale) + real falcon on the M7; until
# then the handoff is orchestration-modeled (pausing the M7 machine = fault injection),
# exactly as the wasmtime track host-models the arbitration.
# Track B (Renode real-hardware) multi-node vehicle — the THREE-CORE topology of the
# Pixhawk 6X-RT (TEST-PIX-019, Stage 4), mirror of the wasmtime sim (sim/vehicle-wasmtime.sh).
# mach "rt1176" : rt1176-dualcore.repl — cpu_m7 (smoke bring-up, LPUART banner) +
# cpu_m4 (sensor-offload stub, writes a heartbeat to the M7<->M4
# shared-memory ring @ 0x20400000), both on the shared RT1176 sysbus.
# mach "f100-io": gale gust_m3_8k.repl + gust_wasm.elf — the real dissolved failsafe.
# links: M7<->M4 = OCRAM-adjacent SHMEM ring + MU stub (on-die, DD-009); FMU<->F100
# = relay-bus carrier (relay#177; reactive consume pending gust ipc-rx, gale#65).
# Confirms all THREE cores co-execute and the M7<->M4 shared-mem link is live. The
# reactive failsafe handoff (gust consuming the heartbeat) is orchestration-modeled
# until gale exposes gust ipc-rx; the handoff LOGIC is proven on the wasmtime track.
set -euo pipefail
RENODE="${RENODE:?set RENODE to the renode binary}"
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
M7ELF="$ROOT/hardware/renode/smoke/rt1176-smoke.elf"
# fetch gale's gust artifacts (not vendored — avoid stale gale binary)
M4ELF="$ROOT/hardware/renode/vehicle/m4/m4-heartbeat.elf"
GUSTREPL=/tmp/gust_m3_8k.repl; GUSTELF=/tmp/gust_wasm.elf
gh api repos/pulseengine/gale/contents/benches/gust/renode-test/gust_m3_8k.repl --jq '.content' | base64 -d > "$GUSTREPL"
gh api repos/pulseengine/gale/contents/benches/gust/renode-test/gust_wasm.elf --jq '.content' | base64 -d > "$GUSTELF"
RESC=$(mktemp -t vehicle).resc
UART="$(mktemp -t m7uart).txt"; : > "$UART"
RESC=$(mktemp -t vehicle3).resc
cat > "$RESC" <<RESC
:name: jess vehicle multi-node (M7 + F100)
emulation CreateUARTHub "relaybus"
mach create "m7-fmu"
machine LoadPlatformDescription @$ROOT/hardware/renode/pixhawk6xrt.repl
mach create "rt1176"
machine LoadPlatformDescription @$ROOT/hardware/renode/vehicle/rt1176-dualcore.repl
sysbus LoadELF @$M7ELF
connector Connect sysbus.lpuart1 relaybus
sysbus LoadELF @$M4ELF
sysbus.lpuart1 CreateFileBackend @$UART true
cpu_m7 VectorTableOffset 0x0
cpu_m4 VectorTableOffset 0x20240000
mach clear
mach create "f100-io"
machine LoadPlatformDescription @$GUSTREPL
sysbus LoadELF @$GUSTELF
emulation RunFor "0.02"
echo "--- machines ---"
mach
echo "--- m7 executed ---"
mach set "m7-fmu"
sysbus.cpu ExecutedInstructions
echo "--- f100 executed ---"
mach set "f100-io"
sysbus.cpu ExecutedInstructions
mach set "rt1176"
sysbus ReadDoubleWord 0x20400000
quit
RESC
"$RENODE" --console --disable-xwt -e "include @$RESC" 2>&1 | grep -iE 'm7-fmu|f100-io|machines|executed|[0-9]{5,}|relaybus|fault|error' | tail -20
HB=$("$RENODE" --console --disable-xwt -e "include @$RESC" 2>&1 | grep -oE '0x000[0-9A-Fa-f]{5}' | tail -1)
M7=$(tr -dc '[:print:]\n' < "$UART" | head -1)
echo "M7 (cpu_m7) LPUART banner : ${M7:-<none>}"
echo "M4 (cpu_m4) SHMEM heartbeat: ${HB:-<none>} (M7<->M4 shared-mem ring @ 0x20400000)"
ok=1
echo "$M7" | grep -q 'JESS-RT1176 boot OK' || { echo "FAIL: M7 banner missing"; ok=0; }
[ -n "$HB" ] && [ "$HB" != "0x00000000" ] || { echo "FAIL: M4 heartbeat not advancing (M7<->M4 shmem dead)"; ok=0; }
[ "$ok" = 1 ] && echo "ORACLE PASS: M7+M4+F100 three-core topology co-executes; M7<->M4 shared-mem link live." || exit 1
Loading