diff --git a/agent/Makefile b/agent/Makefile index d6de9cc..bbba356 100644 --- a/agent/Makefile +++ b/agent/Makefile @@ -105,8 +105,22 @@ else ifeq ($(SOC),hi3516cv610) WDT_BASE = 0x12030000 CRG_BASE = 0x12010000 SYSCTRL_REBOOT = 0x12020004 +else ifeq ($(SOC),hi3519v101) + # V3A generation (3519v101 family: hi3519v101, hi3516av200) — Cortex-A7 + # with V3-era peripheral addresses (UART 0x12100000, WDT 0x12080000) + # but DDR at 0x80000000 like cv500-family. Memory map per + # qemu-hisilicon hi3519v101_soc. + UART_BASE = 0x12100000 + UART_CLOCK = 24000000 + LOAD_ADDR = 0x81000000 + FLASH_MEM = 0x14000000 + FMC_BASE = 0x10000000 + RAM_BASE = 0x80000000 + WDT_BASE = 0x12080000 + CRG_BASE = 0x12010000 + SYSCTRL_REBOOT = 0x12020004 else - $(error Unknown SOC: $(SOC). Supported: hi3516ev300 hi3516ev200 gk7205v200 gk7205v300 hi3516cv300 hi3516cv500 hi3518ev200 hi3516cv610) + $(error Unknown SOC: $(SOC). Supported: hi3516ev300 hi3516ev200 gk7205v200 gk7205v300 hi3516cv300 hi3516cv500 hi3518ev200 hi3516cv610 hi3519v101) endif # Per-SoC CPU. V3 chips (cv300) are ARM926EJ-S (ARMv5TEJ); diff --git a/src/defib/agent/client.py b/src/defib/agent/client.py index c47838d..f81e691 100644 --- a/src/defib/agent/client.py +++ b/src/defib/agent/client.py @@ -115,6 +115,8 @@ def get_agent_binary(chip: str) -> Path | None: "hi3516cv500": "hi3516cv500", "hi3516av300": "hi3516cv500", # cv500-family, same memory map "hi3516dv300": "hi3516cv500", # cv500-family, same memory map + "hi3519v101": "hi3519v101", + "hi3516av200": "hi3519v101", # 3519v101 family, same memory map "hi3516cv610": "hi3516cv610", "hi3518ev200": "hi3518ev200", } diff --git a/src/defib/cli/app.py b/src/defib/cli/app.py index c6df023..20662c6 100644 --- a/src/defib/cli/app.py +++ b/src/defib/cli/app.py @@ -933,11 +933,16 @@ async def _agent_upload_async(chip: str, port: str, output: str) -> None: if output == "human": console.print("Downloading U-Boot for SPL...") cached_fw = download_firmware(chip) - spl_data = cached_fw.read_bytes()[:profile.spl_max_size] + # Pass the full U-Boot binary as spl_override; _send_spl detects the + # actual SPL/u-boot boundary via LZMA/gzip signature scan and slices + # accordingly. Pre-truncating to profile.spl_max_size hides the real + # boundary on chips where the OpenIPC SPL is larger than the HiTool + # reference (e.g. hi3516av200's SVB-enabled SPL is 0x6800, not 0x4F00). + spl_data = cached_fw.read_bytes() if output == "human": console.print(f"Agent: [cyan]{agent_path.name}[/cyan] ({len(agent_data)} bytes)") - console.print(f"SPL: {len(spl_data)} bytes (from OpenIPC U-Boot)") + console.print(f"SPL: full U-Boot ({len(spl_data)} bytes — boundary auto-detected)") console.print("\n[yellow]Power-cycle the camera now![/yellow]\n") transport = await SerialTransport.create(port) @@ -1073,7 +1078,10 @@ async def _agent_flash_async( if output == "human": console.print("Downloading U-Boot for SPL...") cached_fw = download_firmware(chip) - spl_data = cached_fw.read_bytes()[:profile.spl_max_size] + # Pass full u-boot; _send_spl detects the actual SPL boundary so chips + # where OpenIPC SPL is larger than HiTool's profile_max (e.g. av200's + # SVB-enabled SPL = 0x6800 vs profile_max = 0x4F00) get the right size. + spl_data = cached_fw.read_bytes() if output == "human": console.print(f"Firmware: [cyan]{fw_path.name}[/cyan] ({len(firmware)} bytes, CRC {fw_crc:#010x})")