Skip to content

Efuse logical-map override: end-user loadable patch file (RAM-only) #284

Description

@josephnef

Motivation

The efuse logical map is the root of almost every per-adapter parameter we consume: MAC, xtal cap, thermal baseline, RFE type, PA/LNA types, per-channel TX-power PG base. Today it is read-only and invisible except for the stderr DEVOURER_EFUSE_DUMP text (Jaguar2/3 only). A RAM-only override lets us:

  • test "what would this adapter do with rfe_type=N / xtal=M" without touching hardware state,
  • resurrect adapters with corrupted efuse (force the autoload-OK ID, supply a sane map),
  • act as the validation harness for physical efuse programming (see follow-up issue): dump → edit → run with override → validate on-air → only then burn.

Shape

A sparse patch file applied after logical-map materialization, before field parsing.

  • DeviceConfig::Debug::efuse_override (path, std::optional<std::string>), env-mapped as DEVOURER_EFUSE_OVERRIDE in examples/common/env_config.cpp — same pattern as replay_wseq, which is the existing precedent for a library-loaded file path.
  • Grammar: 0xCA=0x04 single bytes, 0x22:8=xxxxxxxxxxxxxxxx runs. A full-map binary replace can be a second, explicitly named mode later — it must not be the default (a full dump from adapter X replayed on adapter Y silently clobbers Y's calibration).
  • The patch parser and the apply helper are generation-neutral pure functions → live in src/ next to PhyTableLoader, unit-testable headlessly (ctest).

Implementation details / hazards

  1. Four materialization sites, not one. Jaguar1 decodes into efuse_eeprom_data (src/jaguar1/EepromManager.cpp:1382), Jaguar2 into _efuse_map (src/jaguar2/HalJaguar2.cpp:305), Jaguar3 has two variant paths — 8822C standard walk and 8822E packed 2-byte headers into a one-shot cache (src/jaguar3/HalJaguar3.cpp:621-719). One shared apply_efuse_override(map, len) called at each site.
  2. 8814A re-reads efuse after FW download (LateInitFor8814A, src/jaguar1/EepromManager.cpp:89). The override must re-apply on that second read or the 8814 silently loses the patch. Needs a dedicated test.
  3. 8822E PA bias bypasses the logical map — it reads physical addresses 0x5c5–0x5c8 during the power-cut bracket (src/jaguar3/HalJaguar3.cpp:580). A logical override cannot affect it. v1: document the hole; a phys: patch plane doubles the surface and is not worth it yet.
  4. Autoload/ID semantics cut both ways. Jaguar1 gates on ID 0x8129 at offset 0x00 (Hal_EfuseParseIDCode8812A). A wrong override flips the device into autoload-fail defaults; forcing it right is how you resurrect a corrupt-efuse adapter. Both directions need tests.
  5. Dump tooling is a prerequisite. You cannot author an override without a dump in the same grammar. Extend DEVOURER_EFUSE_DUMP to emit a machine-readable logical map on all three generations (JSONL efuse.map event or file) — today it is stderr text and Jaguar2/3 only; Jaguar1 only has the physical ReadPhysicalEfuseMap health probe.
  6. Footgun visibility. One-shot W diagnostic diffing every overridden byte + an efuse.override JSONL event, so test scripts can assert the patch took effect and nobody benchmarks on doctored calibration without noticing.

Suggested milestones

  1. Machine-readable logical-map dump, all generations (efuse.map event).
  2. Sparse-patch parser + apply_efuse_override in src/, headless selftests.
  3. Wire into the four materialization sites (incl. the 8814A late re-read) + efuse.override event.
  4. Hardware validation: override rfe_type / xtal on a bench adapter, confirm the parsed-field logs and on-air behavior follow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions