Found while validating PR #181 on hardware. Out of scope for that PR, which stays a focused fix.
The model
Device configuration on these devices is runtime-only. Every re-flash returns factory defaults, and we do not write flash. So the working pattern is that a test restores baseline and then makes the configuration changes it needs for that run — each test starts from a clean state rather than hoping the previous one reverted its runtime changes.
Our own code already says this. tools/uci/rig_https_wiki.py:465:
def ensure_reu_16mb(client: Ultimate64Client) -> None:
"""Force (Enabled, 16 MB) — the sink writes REU bank $10, beyond the
flash-saved 512 KB. Runtime-only; reverts on power cycle."""
The gap
Of the five preflight_reu callers, only rig_https_wiki.py configures the REU — and it does it in the right order, ensure_reu_16mb(client) at line 639, then preflight_reu(...) at line 643 as the guard.
The other four read the state and refuse:
tools/uci/bench_ecdsa_u64e.py:450
tools/uci/rig_https_local.py:1571
tools/uci/rig_https_bad_finished.py:560
tools/uci/rig_https_live.py:444
On a device nobody has configured for the run — the factory default, where RAM Expansion Unit has current and default both Disabled — a REU-profile build of any of these four declines instead of configuring and running. Observed exactly that on a U64E at fw 3.15 while validating #181: bench_ecdsa_u64e.py exited 4, correctly, on a device that was simply at its default.
That is the preflight doing its job. It is not the rigs doing theirs. The #97 preflight is the right backstop for a rig that forgot; it is not a substitute for setup.
What to do
Give the four crypto-path rigs the reset-then-configure shape:
- Restore baseline. The harness now provides
apply_factory_baseline(), opt-in via U64_BASELINE_ON_ENTRY.
- Set
RAM Expansion Unit and REU Size to what the linked profile needs, following ensure_reu_16mb's shape. The profile is already detected — detect_crypto_profile() in tools/uci/_reu_preflight.py reads it from build/labels.txt, so a rig knows whether it needs the REU before it asks the device.
- Keep
preflight_reu exactly where it is, after the configuration, as the guard for the case where step 2 was skipped or failed.
An on-chip build should still make no REU call at all — the point of that profile is that it needs none.
The prohibition is narrower than "do not touch config"
reset_to_default on the covered stores is the supported path. apply_factory_baseline() refuses five stores by design, and those five are the real prohibition:
- the three network stores;
SID Sockets Configuration — its reset cuts SID socket power while reporting clean;
Clock Settings — its reset arms an RTC rollback.
Nothing about the REU stores is in that set.
Note on ensure_reu_16mb's probe
rig_https_wiki.py:470 degrades with (REU state probe failed: ...; writing anyway). That is the same shape as #187 but the opposite and correct direction: on a failed probe it writes the configuration it needs, rather than skipping a write it needed to make. Worth preserving that asymmetry when this is generalised — the reason #187 is a defect is that its degrade lands on the hazardous action, not that degrading is wrong per se.
Related
Found while validating PR #181 on hardware. Out of scope for that PR, which stays a focused fix.
The model
Device configuration on these devices is runtime-only. Every re-flash returns factory defaults, and we do not write flash. So the working pattern is that a test restores baseline and then makes the configuration changes it needs for that run — each test starts from a clean state rather than hoping the previous one reverted its runtime changes.
Our own code already says this.
tools/uci/rig_https_wiki.py:465:The gap
Of the five
preflight_reucallers, onlyrig_https_wiki.pyconfigures the REU — and it does it in the right order,ensure_reu_16mb(client)at line 639, thenpreflight_reu(...)at line 643 as the guard.The other four read the state and refuse:
tools/uci/bench_ecdsa_u64e.py:450tools/uci/rig_https_local.py:1571tools/uci/rig_https_bad_finished.py:560tools/uci/rig_https_live.py:444On a device nobody has configured for the run — the factory default, where
RAM Expansion UnithascurrentanddefaultbothDisabled— a REU-profile build of any of these four declines instead of configuring and running. Observed exactly that on a U64E at fw 3.15 while validating #181:bench_ecdsa_u64e.pyexited 4, correctly, on a device that was simply at its default.That is the preflight doing its job. It is not the rigs doing theirs. The #97 preflight is the right backstop for a rig that forgot; it is not a substitute for setup.
What to do
Give the four crypto-path rigs the reset-then-configure shape:
apply_factory_baseline(), opt-in viaU64_BASELINE_ON_ENTRY.RAM Expansion UnitandREU Sizeto what the linked profile needs, followingensure_reu_16mb's shape. The profile is already detected —detect_crypto_profile()intools/uci/_reu_preflight.pyreads it frombuild/labels.txt, so a rig knows whether it needs the REU before it asks the device.preflight_reuexactly where it is, after the configuration, as the guard for the case where step 2 was skipped or failed.An on-chip build should still make no REU call at all — the point of that profile is that it needs none.
The prohibition is narrower than "do not touch config"
reset_to_defaulton the covered stores is the supported path.apply_factory_baseline()refuses five stores by design, and those five are the real prohibition:SID Sockets Configuration— its reset cuts SID socket power while reporting clean;Clock Settings— its reset arms an RTC rollback.Nothing about the REU stores is in that set.
Note on
ensure_reu_16mb's proberig_https_wiki.py:470degrades with(REU state probe failed: ...; writing anyway). That is the same shape as #187 but the opposite and correct direction: on a failed probe it writes the configuration it needs, rather than skipping a write it needed to make. Worth preserving that asymmetry when this is generalised — the reason #187 is a defect is that its degrade lands on the hazardous action, not that degrading is wrong per se.Related