1
0

Pin additons

This commit is contained in:
Aiden
2026-05-25 15:18:47 +10:00
parent cdfb811c28
commit a82f3f6628
10 changed files with 3498 additions and 50 deletions

View File

@@ -207,6 +207,29 @@ def board_metadata_for_instruction(
return metadata if isinstance(metadata, dict) else None
def board_json_payload(analysis: Mapping[str, object] | None) -> dict[str, object]:
if not analysis:
return {
"board": None,
"name": None,
"summary": None,
"manual_references": [],
"traces": [],
"channels": {},
"instructions": {},
}
return {
"board": analysis.get("board"),
"name": analysis.get("name"),
"summary": analysis.get("summary"),
"manual_references": analysis.get("manual_references", []),
"traces": analysis.get("traces", []),
"channels": analysis.get("channels", {}),
"instructions": analysis.get("instructions", {}),
"state": analysis.get("state", {}),
}
def _initial_channel_payload(profile: Mapping[str, object]) -> dict[str, dict[str, object]]:
traces = [dict(trace) for trace in profile["traces"] if isinstance(trace, Mapping)]
return {

View File

@@ -4,6 +4,7 @@ import argparse
from pathlib import Path
from .analysis import build_call_graph, collect_labels, linear_sweep, trace
from .board_profile import analyze_board_profile
from .cycles import annotate_cycles
from .data_analysis import analyze_unreached_data
from .dataflow import analyze_dataflow
@@ -16,6 +17,7 @@ from .peripheral_access import analyze_peripheral_access
from .render import format_callgraph_dot, format_listing, write_json
from .rom import Rom
from .sci import analyze_sci
from .sci_protocol import analyze_sci_protocol
from .symbols import discover_symbols
from .timing import summarize_timing
from .vectors import read_dtc_vectors_max, read_dtc_vectors_min, read_vectors_max, read_vectors_min
@@ -40,6 +42,12 @@ def main() -> int:
parser.add_argument("--entry", type=parse_int, action="append", default=[], help="extra entry point to trace")
parser.add_argument("--br", type=parse_int, default=None, help="optional BR value for @aa:8 short absolute operands")
parser.add_argument("--clock-hz", type=parse_int, default=None, help="oscillator clock in Hz for SCI baud inference")
parser.add_argument(
"--board-profile",
choices=("sony_rcp_tx7", "none"),
default="sony_rcp_tx7",
help="emit board-specific annotations for known physical traces",
)
parser.add_argument("--linear", action="store_true", help="linear-sweep the selected range instead of tracing from vectors")
parser.add_argument("--cycles", action="store_true", help="append Appendix A cycle estimates to assembly comments")
parser.add_argument("--timing", action="store_true", help="include straight-line block and loop cycle summaries")
@@ -81,6 +89,12 @@ def main() -> int:
symbols = discover_symbols(instructions, data_candidates=data_candidates)
timing_summary = summarize_timing(instructions, labels, call_graph) if args.timing else None
sci_analysis = analyze_sci(instructions, clock_hz=args.clock_hz)
sci_protocol = analyze_sci_protocol(instructions)
board_profile = (
None
if args.board_profile == "none"
else analyze_board_profile(instructions, board=args.board_profile)
)
peripheral_access = analyze_peripheral_access(instructions)
indirect_flow = analyze_indirect_flow(rom, instructions, labels)
lcd_text = analyze_lcd_text(rom, instructions, start=args.start, end=end)
@@ -101,6 +115,8 @@ def main() -> int:
timing_summary=timing_summary,
show_cycles=args.cycles,
sci_analysis=sci_analysis,
sci_protocol=sci_protocol,
board_profile=board_profile,
peripheral_access=peripheral_access,
indirect_flow=indirect_flow,
dataflow=dataflow,
@@ -122,6 +138,8 @@ def main() -> int:
call_graph=call_graph,
timing_summary=timing_summary,
sci_analysis=sci_analysis,
sci_protocol=sci_protocol,
board_profile=board_profile,
peripheral_access=peripheral_access,
indirect_flow=indirect_flow,
dataflow=dataflow,

View File

@@ -900,6 +900,14 @@ def _metadata_comments(ins: JsonObject) -> list[str]:
if isinstance(inference, dict) and inference.get("comment"):
comments.append(str(inference["comment"]))
for event in ins.get("sci_protocol", []):
if isinstance(event, dict) and event.get("comment"):
comments.append(str(event["comment"]))
board_profile = ins.get("board_profile")
if isinstance(board_profile, dict) and board_profile.get("comment"):
comments.append(str(board_profile["comment"]))
indirect = ins.get("indirect_flow")
if isinstance(indirect, dict) and indirect.get("summary"):
comments.append(str(indirect["summary"]))

View File

@@ -3,6 +3,7 @@ from __future__ import annotations
import json
from pathlib import Path
from .board_profile import board_comment_for_instruction, board_json_payload, board_metadata_for_instruction
from .cycles import cycle_comment
from .dataflow import state_for_instruction
from .dtc import DtcEndpointInfo, DtcRegisterInfo
@@ -19,6 +20,11 @@ from .peripheral_access import (
)
from .rom import Rom
from .sci import sci_comment_for_instruction, sci_json_payload, sci_metadata_for_instruction
from .sci_protocol import (
sci_protocol_comment_for_instruction,
sci_protocol_json_payload,
sci_protocol_metadata_for_instruction,
)
from .symbols import symbol_for_address
from .tables import IO_REGISTERS
from .timing import format_timing_summary
@@ -217,6 +223,31 @@ def _lcd_driver_lines(lcd_driver: dict[str, object] | None) -> list[str]:
return lines
def _board_profile_lines(board_profile: dict[str, object] | None) -> list[str]:
if not board_profile:
return []
traces = board_profile.get("traces", [])
if not isinstance(traces, list) or not traces:
return []
lines = ["; Board Profile"]
summary = board_profile.get("summary")
if summary:
lines.append(f"; {summary}")
for trace in traces:
if not isinstance(trace, dict):
continue
lines.append(
f"; H8 pin {trace['h8_pin']} {trace['h8_pin_name']} "
f"({trace['signal']}) -> MAX202 pin {trace['max202_pin']}",
)
state = board_profile.get("state")
if isinstance(state, dict) and state.get("P9SCI2E") is False:
lines.append("; SCI2 pin routing is disabled by SYSCR2.P9SCI2E=0 in the observed setup.")
lines.append("")
return lines
def format_listing(
rom_path: Path,
rom: Rom,
@@ -230,6 +261,8 @@ def format_listing(
timing_summary: dict[str, list[dict[str, object]]] | None = None,
show_cycles: bool = False,
sci_analysis: dict[str, object] | None = None,
sci_protocol: dict[str, object] | None = None,
board_profile: dict[str, object] | None = None,
peripheral_access: dict[str, object] | None = None,
indirect_flow: dict[str, object] | None = None,
dataflow: dict[str, object] | None = None,
@@ -294,6 +327,7 @@ def format_listing(
lines.append("")
lines.extend(_symbol_lines(symbols))
lines.extend(_board_profile_lines(board_profile))
lines.extend(_lcd_text_lines(lcd_text))
lines.extend(_lcd_driver_lines(lcd_driver))
@@ -312,6 +346,8 @@ def format_listing(
for part in (
ins.comment,
sci_comment_for_instruction(sci_analysis, address),
sci_protocol_comment_for_instruction(sci_protocol, address),
board_comment_for_instruction(board_profile, address),
peripheral_comment_for_instruction(peripheral_access, address),
indirect_comment_for_instruction(indirect_flow, address),
lcd_text_comment_for_instruction(lcd_text, address),
@@ -338,6 +374,8 @@ def write_json(
call_graph: dict[str, object] | None = None,
timing_summary: dict[str, list[dict[str, object]]] | None = None,
sci_analysis: dict[str, object] | None = None,
sci_protocol: dict[str, object] | None = None,
board_profile: dict[str, object] | None = None,
peripheral_access: dict[str, object] | None = None,
indirect_flow: dict[str, object] | None = None,
dataflow: dict[str, object] | None = None,
@@ -365,6 +403,8 @@ def write_json(
"call_graph": call_graph or {"nodes": [], "edges": []},
"timing_summary": timing_summary or {"blocks": [], "loops": []},
"sci": sci_json_payload(sci_analysis),
"sci_protocol": sci_protocol_json_payload(sci_protocol),
"board_profile": board_json_payload(board_profile),
"peripheral_access": peripheral_json_payload(peripheral_access),
"indirect_flow": indirect_flow or {"sites": []},
"dataflow": _dataflow_json_payload(dataflow),
@@ -372,7 +412,18 @@ def write_json(
"lcd_text": lcd_text or {"strings": [], "regions": [], "searches": []},
"lcd_driver": lcd_driver or {"accesses": [], "polling_loops": [], "routines": []},
"instructions": [
_instruction_payload(ins, sci_analysis, peripheral_access, indirect_flow, dataflow, symbols, lcd_text, lcd_driver)
_instruction_payload(
ins,
sci_analysis,
sci_protocol,
board_profile,
peripheral_access,
indirect_flow,
dataflow,
symbols,
lcd_text,
lcd_driver,
)
for ins in (instructions[addr] for addr in sorted(instructions))
],
}
@@ -425,6 +476,8 @@ def _dataflow_instruction_payload(dataflow: dict[str, object] | None, address: i
def _instruction_payload(
ins: Instruction,
sci_analysis: dict[str, object] | None = None,
sci_protocol: dict[str, object] | None = None,
board_profile: dict[str, object] | None = None,
peripheral_access: dict[str, object] | None = None,
indirect_flow: dict[str, object] | None = None,
dataflow: dict[str, object] | None = None,
@@ -458,6 +511,12 @@ def _instruction_payload(
sci_metadata = sci_metadata_for_instruction(sci_analysis, ins.address)
if sci_metadata:
payload["sci"] = sci_metadata
sci_protocol_metadata = sci_protocol_metadata_for_instruction(sci_protocol, ins.address)
if sci_protocol_metadata:
payload["sci_protocol"] = sci_protocol_metadata
board_metadata = board_metadata_for_instruction(board_profile, ins.address)
if board_metadata:
payload["board_profile"] = board_metadata
peripheral_metadata = peripheral_metadata_for_instruction(peripheral_access, ins.address)
if peripheral_metadata:
payload["peripheral_access"] = peripheral_metadata