From 4658baa104cdc4a1504568b864b338e2aeeba9fb Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Thu, 25 Jun 2026 05:26:39 +0200 Subject: [PATCH] =?UTF-8?q?renode(TEST-PIX-019):=20add=20the=20M4=20third?= =?UTF-8?q?=20core=20=E2=80=94=20M7+M4+F100=20co-execute=20with=20a=20LIVE?= =?UTF-8?q?=20M7<->M4=20shared-mem=20link=20(Stage=204)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extends the Renode multi-node vehicle from M7+F100 to the FULL three-core 6X-RT topology, per the M4 plan (DD-018 T2 sensor-offload core). NEW: rt1176-dualcore.repl — cpu_m7 + cpu_m4 on the shared RT1176 sysbus (per-core NVIC via BusPointRegistration), + a SHMEM ring @0x20400000 (relay-bus carrier region, DD-009) + an MU mailbox stub. Kept SEPARATE from the CI-gated pixhawk6xrt.repl (M7-only smoke), which is untouched. NEW: m4/m4-heartbeat.elf (+ boot.S/link.ld) — a tiny Cortex-M4 firmware (OCRAM vectors/text/stack) that publishes an advancing heartbeat to the SHMEM ring, standing in for the sensor-offload workload until real drivers land. CONFIRMED (Renode v1.16.1): all THREE cores co-execute — cpu_m7 -> LPUART1 "JESS-RT1176 boot OK"; cpu_m4 writes ~0xA2C29 to SHMEM @0x20400000 after 0.02s (the on-die M7<->M4 shared-mem link is LIVE, not just instantiated); f100-io (gust) co-executes. ORACLE PASS. run-vehicle-multinode.sh updated to the 3-core model with per-core VTOR (M7=smoke 0x0, M4=heartbeat 0x20240000) + M7-banner and M4-heartbeat assertions. DEFERRED (status=draft): reactive failsafe handoff needs gust ipc-rx wired to a connectable transport (asked gale#65); real falcon/M4-drivers gated on synth #369/#275; MU doorbell-IRQ is a stub (ring is live). rivet validate (v0.18.0): PASS. Co-Authored-By: Claude Opus 4.8 --- artifacts/phase2-pixhawk.yaml | 43 ++++++++----- hardware/renode/vehicle/README.md | 60 ++++++++++-------- hardware/renode/vehicle/m4/m4-heartbeat.elf | Bin 0 -> 4696 bytes hardware/renode/vehicle/m4/m4_boot.S | 25 ++++++++ hardware/renode/vehicle/m4/m4_link.ld | 7 ++ hardware/renode/vehicle/rt1176-dualcore.repl | 46 ++++++++++++++ .../renode/vehicle/run-vehicle-multinode.sh | 56 ++++++++-------- 7 files changed, 169 insertions(+), 68 deletions(-) create mode 100755 hardware/renode/vehicle/m4/m4-heartbeat.elf create mode 100644 hardware/renode/vehicle/m4/m4_boot.S create mode 100644 hardware/renode/vehicle/m4/m4_link.ld create mode 100644 hardware/renode/vehicle/rt1176-dualcore.repl diff --git a/artifacts/phase2-pixhawk.yaml b/artifacts/phase2-pixhawk.yaml index 982d84a..3acd324 100644 --- a/artifacts/phase2-pixhawk.yaml +++ b/artifacts/phase2-pixhawk.yaml @@ -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 diff --git a/hardware/renode/vehicle/README.md b/hardware/renode/vehicle/README.md index 5f34a7e..b9d3ac9 100644 --- a/hardware/renode/vehicle/README.md +++ b/hardware/renode/vehicle/README.md @@ -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. diff --git a/hardware/renode/vehicle/m4/m4-heartbeat.elf b/hardware/renode/vehicle/m4/m4-heartbeat.elf new file mode 100755 index 0000000000000000000000000000000000000000..8df143606cdec450761e495a7173a56b0926361c GIT binary patch literal 4696 zcmeHLJxc>Y5S`8CE(s{cAQCXe1uhZ<4~46&62xF(Q2Yb&a;_L8oZPJ%D=YtpKh4fo zdqLl1vq=OCON$-YosWAnJ9%B+)6q#!2tmdQ)F#d<6!;N*XB}68+=zVC+f*WN`kkuW z5%_!>i1@fTy3T<$%YbFTGGH073|Iy%1C{~HfMvikU>UFsSO)$N11+Eb>pREKz0-Gb zMoqCVESCYMZqOy zGM9=5<7kkpIJp_9^p+^hAIB;l!mCXCYZKkeM5S3yA%41|uzTJQW2Lgu@J`8`pZSw* z0mZtCW&ry_KPfMD8U-ep;XHWep$y!{60SIlciM4 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 diff --git a/hardware/renode/vehicle/m4/m4_link.ld b/hardware/renode/vehicle/m4/m4_link.ld new file mode 100644 index 0000000..d72e623 --- /dev/null +++ b/hardware/renode/vehicle/m4/m4_link.ld @@ -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 +} diff --git a/hardware/renode/vehicle/rt1176-dualcore.repl b/hardware/renode/vehicle/rt1176-dualcore.repl new file mode 100644 index 0000000..81f5603 --- /dev/null +++ b/hardware/renode/vehicle/rt1176-dualcore.repl @@ -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 diff --git a/hardware/renode/vehicle/run-vehicle-multinode.sh b/hardware/renode/vehicle/run-vehicle-multinode.sh index c62a4ba..abaa940 100755 --- a/hardware/renode/vehicle/run-vehicle-multinode.sh +++ b/hardware/renode/vehicle/run-vehicle-multinode.sh @@ -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" <&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:-}" +echo "M4 (cpu_m4) SHMEM heartbeat: ${HB:-} (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