#!/usr/bin/env python3
import sys, pandas as pd

IMPORTANT_ADDRS = {
    0x05CD:"real Step8 40->00; clears at 90021696 when preseeded",
    0xD95C:"real Step8 24->04",
    0x077C:"real Step8 0C->00 low; scheduler aggregate",
    0x077D:"real Step8 01->00 high; scheduler aggregate",
    0x0722:"real Step8 00->01 candidate",
    0x071E:"real Step8 01->02 candidate",
    0x076D:"real Step8 01->F2 candidate",
    0x076E:"real Step8 03->02 candidate",
    0x07F8:"real Step8 21->44 candidate",
    0x07F9:"real Step8 00->84 candidate",
    0x05B1:"generic packet bit; not auth proof",
    0x05B6:"secondary flag",
    0x06E1:"packet result byte",
    0x06EC:"packet result byte",
    0x06ED:"packet result byte",
    0x06F1:"packet phase/result",
    0xDA0C:"packet/media active",
    0xD95C:"packet/status byte",
}
IMPORTANT_PCS = {
    0x9001CFCA:"writes 0x0722",
    0x90021696:"clears 0x05CD bit 0x40",
    0x9001B71B:"consumes 0x05B1 bit 0x20 and enters packet-auth service",
    0x9001B72C:"sets 0x06E1=0B",
    0x9001B731:"sets 0x06EC=4E",
    0x9001B735:"clears 0x06ED",
    0x9001B73E:"clears 0x06F1",
    0x9001B75C:"sets DA0C=01",
    0x9001B75F:"clears 0x05B1 bit 0x40 in emulator",
    0x9001B764:"clears 0x05B6 bit 0x01",
    0x9001EF54:"reads aggregate 0x077C dword",
    0x9001EF66:"writes aggregate to 0x077C if mismatch",
    0x9001EF71:"returns after aggregate check",
    0x9001BC3B:"old 0x05CD candidate, expect no hit here",
    0x9001D086:"old 0x071E candidate, expect no hit here",
    0x9001EE4A:"old 0x07F8 candidate, expect no hit here",
}
def hx(x):
    if pd.isna(x): return None
    x=str(x)
    try: return int(x,16) if x.startswith("0x") else int(x)
    except Exception: return None

if len(sys.argv)<2:
    print("usage: analyze_gdr8050l_partition_trace_v102.py trace.csv")
    raise SystemExit(2)
df=pd.read_csv(sys.argv[1], low_memory=False)
for c in ("pc","addr","value"):
    df[c+"_i"]=df[c].map(hx)
print(f"rows={len(df)} events={df.event.value_counts().to_dict()}")
print("\nPC hits:")
for pc,label in IMPORTANT_PCS.items():
    sub=df[df.pc_i==pc]
    if len(sub):
        print(f"  0x{pc:08X} rows={len(sub)} events={sub.event.value_counts().to_dict()} first_cycle={sub.cycle.min()}  {label}")
print("\nAddress writes:")
for addr,label in IMPORTANT_ADDRS.items():
    sub=df[(df.addr_i==addr)&(df.event=="watch_write")]
    if len(sub):
        pcs=", ".join(f"{pc}:{n}" for pc,n in sub.pc.value_counts().items())
        last=sub.iloc[-1]
        vals=", ".join(str(x) for x in sub.value.tail(8).tolist())
        print(f"  0x{addr:04X} writes={len(sub)} last={last.value} pc={last.pc} cycle={last.cycle} vals={vals}  {label}  pcs={pcs}")
    else:
        print(f"  0x{addr:04X} writes=0  {label}")
