agent/cv6xx: flash agent support for hi3516cv608 / hi3516cv610#110
Merged
Conversation
Adds end-to-end agent support for the HiSilicon CV6xx family
(hi3516cv608, hi3516cv610, hi3516dv500, hi3519dv500) by wiring up the
CV6xx fastboot path through `defib agent upload`.
CV6xx fastboot is structurally different from HiSilicon Standard
(SPL + agent two-stage) — it loads a single composite (GSL + DDR
tables + U-Boot section) and the bootrom parses the 1024-byte U-Boot
header at byte 0 of the final stage. The header's code-offset field
at byte 8 is 0x400, so the bootrom jumps to `load_addr + 0x400`, not
`load_addr`. Existing CV6xx agent attempts crashed because the binary
was linked at 0x41000000 but actually executed at 0x41000400, so all
link-time absolute references (page table, etc.) pointed at wrong
memory.
Changes:
* `agent/Makefile` hi3516cv610 stanza:
- LOAD_ADDR 0x41000000 → 0x41000400 (account for U-Boot header).
- CRG_BASE 0x12010000 → 0x11010000 (CV6xx moved the peripheral
CRG block; the old V3/V4 address is unmapped on CV6xx and the
read triggered an external abort during flash_init).
- WDT_BASE 0x12030000 → 0x11030000 and SYSCTRL_REBOOT
0x12020004 → 0x11020004 for the same reason.
- FLASH_MEM 0x14000000 → 0x0F000000 (CV6xx FMC MMIO window).
- New per-SoC `FMC_CRG_OFFSET` / `FMC_CRG_CLK_BIT` so the FMC
clock-gate register layout can differ per family (CV6xx puts
`fmc_cken` on bit 4 at CRG+0x3F40 instead of bit 1 at CRG+0x0144).
* `agent/spi_flash.c`: REG_FMC_CRG now uses the configurable
FMC_CRG_OFFSET / FMC_CRG_CLK_BIT macros, with the V3/V4 default
preserved.
* `src/defib/protocol/hisilicon_cv6xx.py`:
- `wrap_cv6xx_payload(header_source, payload)` helper — clones the
1024-byte U-Boot header from a known-good composite and patches
the length field at byte 36 so the bootrom validates and jumps
to the wrapped payload.
- `HiSiliconCV6xx.send_firmware(..., uboot_override=None)` so the
caller can replace the U-Boot section with an arbitrary payload
(the agent, in our case) while reusing the composite's GSL +
DDR tables.
* `src/defib/cli/app.py` `_agent_upload_async`:
- Dispatches on protocol family via `find_protocol(chip)`. The
HiSilicon Standard path is unchanged; CV6xx routes to a new
`_agent_upload_cv6xx` helper.
- The CV6xx path takes a `-f/--file` composite (no auto-download
yet — OpenIPC doesn't ship a prebuilt for these SoCs), parses
it, wraps the agent with `wrap_cv6xx_payload`, and runs the
full handshake → GSL → DDR → wrapped-agent flow. Uses the
spawn-handshake-before-power-cycle ordering (PR #109) so it
works on Vectis-bridged boards via `--power-cycle`.
* `src/defib/agent/client.py`: alias `hi3516cv608 → hi3516cv610`
agent binary, mirroring the existing same-family aliases for
hi3516av300 / hi3516dv300 → hi3516cv500.
Verified live on a Vectis-bridged hi3516cv608 (OpenIPC Vectis on
`rfc2217://127.0.0.1:35240`): `defib agent upload --power-cycle`
brings the agent up cleanly — RAM 0x40000000, flash 16 MiB, sector
64 KiB, agent_version 4, capabilities 0xFF.
Known follow-up: the agent's `flash_read_id` returns 0x00 0x00 0x00
on this CV6xx board even though flash_size is correct via the
detect_size fallback. The FMC register-mode result path (currently
reads from FLASH_MEM after issuing READ_ID) likely needs CV6xx
pinmux or FMC data-buffer tuning. Tracked separately — does not
affect the upload/INFO path.
68 pytest tests + 5412 agent C unit tests still pass. Ruff and mypy
clean. agent-hi3516cv610.bin still built by `make SOC=hi3516cv610`.
The first CV6xx agent commit got the upload path running but
flash_read_id returned zeros and flash CMD_READ failed because the
agent was writing to the V3/V4 pinctrl block (0x100C0000) with V3/V4
pad-drive values. On CV6xx the pinctrl block lives at 0x10260000 and
the register offsets + drive values are different.
Source of truth: dimerr/u-boot-hi3516cv6xx
`drivers/mtd/fmc_hi3516cv610.c::hi3516cv610_spi_io_config()`.
Changes:
* `agent/spi_flash.c::fmc_enter_normal()` — pinmux config now
parameterised by `SPI_PIN_BASE` and a `SPI_PINS_CV6XX` family flag.
Default (V3/V4) layout is preserved; with `-DSPI_PINS_CV6XX=1` the
function uses CV6xx offsets / values (CLK 0x10=0x1291, CS0 0x18=
0x1131, MOSI_IO0 0x0C=0x1261, MISO_IO1 0x1C=0x1261, WP_IO2 0x20=
0x12E1, HOLD_IO3 0x14=0x1161 — 3.3V single-CS).
* `agent/Makefile` hi3516cv610 stanza now sets
`SPI_PIN_BASE=0x10260000` and `SPI_PINS_CV6XX=1`, and the global
CFLAGS pass them through.
Verified live on hi3516cv608 over Vectis:
jedec_id=a14018 (FM25Q128A 16 MiB ✓)
flash_size=16777216, sector_size=65536, ram_base=0x40000000
flash[0..64] via MMIO window matches the U-Boot composite we
burned earlier, byte-for-byte — proving real flash content is
being read through 0x0F000000.
68 pytest + 5412 agent C tests still pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds end-to-end flash agent support for the HiSilicon CV6xx family
(hi3516cv608, hi3516cv610, hi3516dv500, hi3519dv500), verified live on a
Vectis-bridged hi3516cv608.
CV6xx fastboot is structurally different from HiSilicon Standard: a single
composite (GSL + DDR tables + U-Boot-shaped section) gets uploaded and the
bootrom parses the 1024-byte U-Boot header to decide where to jump. That
changed the whole agent-bring-up shape, and also surfaced two stale V3/V4
addresses in the existing cv610 stanza that turn out to never have been
exercised on real CV6xx silicon.
What's in the change set
HiSiliconCV6xx.send_firmware(..., uboot_override=)+ new modulehelper
wrap_cv6xx_payload(header_source, payload)— clones the1024-byte U-Boot header from a known-good composite and patches the
length field at byte 36 so the bootrom validates and jumps to the
wrapped payload.
_agent_upload_asyncincli/app.pydispatches on protocol viafind_protocol(chip). HiSiliconStandard path unchanged; CV6xx takes anew
-f/--file(composite for GSL + DDR), wraps the agent, and runshandshake → GSL → DDR → wrapped-agent. Uses the spawn-handshake-before-
power-cycle ordering from recovery/session: blast proactive handshake magic before power-cycle #109 so it works with Vectis
--power-cycle.src/defib/agent/client.py—hi3516cv608→hi3516cv610agentalias, mirroring the existing same-family aliases.
agent/Makefilehi3516cv610 stanza, fixing several latent V3/V4copy-paste errors:
LOAD_ADDR0x41000000→0x41000400so the agent's link-timeaddresses match where the bootrom actually jumps after the
U-Boot-header offset (
load_addr + 0x400).CRG_BASE0x12010000→0x11010000,WDT_BASEandSYSCTRL_REBOOTlikewise moved into0x11xxxxxx(matches the UARTaddress and the kernel's
earlycon=pl011,0x11040000arg).FLASH_MEM0x14000000→0x0F000000(FMC MMIO window on CV6xx).FMC_CRG_OFFSET=0x3F40+FMC_CRG_CLK_BIT=4because the FMCclock-gate register moved from
CRG+0x144bit1 toCRG+0x3F40bit4.SPI_PIN_BASE=0x10260000+SPI_PINS_CV6XX=1because the SPIpinctrl block moved from
0x100C0000and the per-pin registeroffsets + pad-drive values changed.
agent/spi_flash.cuses the newFMC_CRG_OFFSET/FMC_CRG_CLK_BITand
SPI_PIN_BASE/SPI_PINS_CV6XXmacros, falling back to V3/V4defaults when not defined.
Source of truth for the CV6xx pinmux + FMC sequencing is the dimerr u-boot
fork:
drivers/mtd/fmc_hi3516cv610.c::hi3516cv610_spi_io_config().Test plan
uv run pytest tests/ -x -v --ignore=tests/fuzz— 68/68 passuv run ruff check src/anduv run mypy src/defib/cleanmake -C agent test HOST_CC=gcc— 5412/5412 agent C tests passmake -C agent SOC=hi3516cv610— buildsagent-hi3516cv610.bin(18 KiB)
End-to-end on live hi3516cv608 over Vectis
(
rfc2217://127.0.0.1:35240withDEFIB_POWER_TYPE=vectis):