PCS alertLog (0x424) decode — 63/84 alerts from firmware layouts #12
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/pcs-alertlog"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Reverse-engineers the PCS (variant-411, F28377D dual-core) alertLog packing and
recovers per-alert log-field bit layouts — the PCS analog of the drive-unit work.
What lands
alert_log.pyframework, fromfirmware-recovered bit layouts (
docs/private/alerts/alertlog_layouts_2022.45.15.json,a new
"PCS"node alongside DI/DIR).a030 = {canRxErrorType:[0,3], canID:[8,16]}(matches DamienMaguire's
handle424), plusa029,a034; 3 hand-traced bench alerts (a018/a044/a076).errorType / badValues positionally, but their catalog order varies (DIR a094 vs a066,
PCS a030). Now matched by field name — fixes PCS and the DU a066 family.
tests/test_alert_log.py: PCS node allowed +test_pcs_layouts_anchor. 24 pass.Mechanism
Each PCS alert builds a 4-word record = the 0x424 frame (word0 code/state, words 1-3
= the 48-bit payload over bytes 2-7, same LE view the framework decodes) then calls the
setter with the alert id as an explicit immediate. A dataflow interpreter over the
mask/shift/OR + FPU-clamp packing idiom recovers each field; counts checked against
libQtCarAlertslog_signals, non-overlap/<=48b gated. Extractor tooling stayslocal/gitignored (
docs/private/alertlog-extractor/), matching the DU convention.Not covered (documented)
~11 alerts have no published field names in any rev; MIA alerts pack only a source bit;
~6 hard packers (a013/a053/a054/a073/a014/a038) have unverifiable internal splits left to
the reason-only fallback rather than guessed.
Ghidra: ~80 functions renamed on both PCS cores (saved to the programs, not in this PR).
Reverse-engineered the PCS (variant-411, F28377D dual-core) alertLog packing and recovered per-alert log-field bit layouts, the PCS analog of the drive-unit work. Each PCS alert builds a 4-word record = the 0x424 frame (word0 code/state, words 1-3 = the 48-bit payload over bytes 2-7, same little-endian view the framework already decodes) then calls the setter with the alert id as an explicit immediate. A dataflow interpreter over the mask/shift/OR + FPU-clamp packing idiom (local tooling in docs/private/alertlog-extractor) recovers each field; field counts are checked against libQtCarAlerts log_signals, non-overlap/<=48b gated, and anchored on a030 = {canRxErrorType:[0,3], canID:[8,16]} (matches Damien Maguire's handle424) plus a029. 60/84 alerts emitted into the shared, rev-tagged layouts file under a "PCS" node (cross-rev names borrowed from 2024/2026 where the 2022 catalog is silent; tail flag groups split into 1-bit fields). The remaining alerts either have no published field names, are MIA source-bit markers, or are register-built packers left to the reason-only fallback. Also fixes a latent drive-unit bug: the CAN-rationality decoder paired the offending-id / errorType / badValues positionally, but their catalog order varies (DIR a094 = [canID, errorType, ...] vs a066 = [badValue1, badValue2, canID, errorType]); now matched by field name, which fixes PCS a030 and the DU a066 family. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>