# Standing constraints (user-set) ## NO TSU / NO SPI FLASH WORK The user does not want flash touched unattended. This rules out, until explicitly re-authorised: * the **TSU mailbox** update path (`C2PMSG_115/116` + doorbell `73`) — any command that can reach `spi_erase_range` / `spi_write_status` / `tsu_write_block`; * the **TSU SRAM disclosure primitive** (`ANALYSIS-PSP-CODE-EXEC-AVENUES.md`) and the open `mapped_base` question it depends on — **dropped**, not deferred; * `PLAN-BOOT-WINDOW-ROMSW.md` — its entire payoff is a mid-boot flash write (Phase 3). Phases 0-2 are read-only but lead nowhere else, so the plan is shelved; * using **BIOS-1 as a sacrificial flash lab**; * `extra/amdflash/romless.py` and `fw_live.py` in any writing mode (`flash`, `ifwi-step`, `live-flash`, `ifwi-all`). Reading flash for analysis of an image we already hold on disk is fine; issuing flash commands to the card is not. ### Still in scope * static analysis of all modules (sOS, SYS_DRV, ASD, HDCP, DTM, RAS, MEC, VCN); * the 38-build version-diff corpus (`decompiled/`, `phase3/`, `phase4_diffs.json`); * non-destructive hardware probing: BAR5 register reads, SMN reads via the index/data windows, `regguard`-validated; * host-reachable TA exercise via `INVOKE_CMD` (HDCP), which does not touch flash; * the TRNG/canary line (`LEAD-TRNG-CANARY-PREDICTION.md`) — its remaining trigger is fault injection via power sequencing, not flash. ### Check before using **Firmware rollback** (`CONFIRMED-FIRMWARE-ROLLBACK-WORKS.md`): confirm whether the method used there writes flash or only supplies an alternate image over the normal PSP load path. If it writes flash, it falls under this constraint too. ## LOAD_TA must not be aimed outside VRAM (added after wedging the card) Submitting `GFX_CMD_ID_LOAD_TA` with `app_phy_addr` beyond the end of VRAM does not produce an error status. It produces a flood of `SOC21_IH_CLIENTID_VMC` VM-fault interrupts and wedges the SMU: `SMU msg 0x2 timeout`, `mode1_reset` fails, and the device disappears (`0 devices available`). Recovery is a cold ATX cycle (`$PSP_PY atx_power.py cycle 25`), which does restore it — heartbeat confirmed advancing afterwards. This is the **same wedge signature as the broad-SMN-sweep hazard**, reached by a completely different route. That suggests the rule is general rather than specific to SMN: **any probe that makes an on-die engine access unbacked memory can take out the SMU.** Probe addresses must lie inside a real allocation unless the resulting fault flood is bounded first. ## Do not sweep PSP LOAD_IP_FW firmware types (added 2026-09) Submitting junk payloads across the `GFX_FW_TYPE_*` space to discover which types a card supports **wedges the PSP**: the sOS ring stops responding ("sOS ring not responding", fence stuck) and the SMU times out (`SMU msg 0x1a`), while the PCIe link stays up. Only a cold ATX cycle (`work/atx_power.py cycle 25`) recovers it — verified. The `SMU` and `PPTABLE` types are the suspected trigger. The measured result is already recorded in `FIRMWARE-COVERAGE-MATRIX.md`, so there is no reason to repeat the sweep. ## A compute pipe that will not fetch leaves a stuck HQD (added 2026-09) Standing up a compute/KIQ queue on a pipe that is not fully initialised (see `MEC-PM4-FOOTHOLD.md` round 8: pipe 3 without its HPD/EOP programming) produces a queue that activates but never fetches — and then **cannot be dequeued**: `CP_HQD_DEQUEUE_REQUEST` leaves `CP_HQD_ACTIVE = 1`, `GRBM_STATUS` sits at `0xa800302c` instead of `0x0000302c`, and neither `AM_GFX.reset_mec()` nor a full driver re-init clears it. Only a cold ATX cycle (`work/atx_power.py cycle 25`) recovers. Do this work only when a power cycle is acceptable, and check `GRBM_STATUS` afterwards rather than assuming the driver cleaned up. ## Never kill a hardware script mid-flight, and never delete its USB lock (added 2026-10) Wedged the card this way: a probe was running (holding `/tmp/am_usb:2-11.lock` and the USB handle), it was `kill`ed mid-operation, the lock file was then removed by hand, and a second process was started. Result was the documented wedge signature -- `AMD:0 does not exist (0 devices available)`, then `SMU msg 0x2 timeout` from `mode1_reset` inside tinygrad's own init. Only `$PSP_PY work/atx_power.py cycle 25` recovered it (power-only, no flash, safe under this file). Rules: * Let hardware scripts finish. If one must be stopped, stop it and then ATX-cycle before the next run -- do not reuse the device in between. * `env.sh` removes stale locks on purpose; that is for the case where NO process holds the device. Removing the lock while a process still holds the USB handle is the hazard, not the fix. * Run long probes detached with a logfile (`setsid nohup ... > log 2>&1 < /dev/null &`) and poll the log. Piping to `tail` over ssh loses all output when the connection drops. * Do not use `pkill -f ` over ssh when the pattern also matches your own command line -- it kills the ssh session and returns silently, which reads exactly like a hang. ## FE0A with *(params+0x818) large leaves the TA unable to open a session (added 2026-10) `*(params+0x818) = 0xFFFFFFFB` on an FE0A path makes the handler replicate the param block across the whole command buffer, write no completion status, and leave GCP in a state where `FE07` fails 8/8. Needs an ATX cycle. Keep `0x818` small on FE0A; see Addendum 144 of `fw/FINDING-GCP-FE09-CONFIGINIT-HOST-OFFSET-WRITE.md`.