Skip to content

HiSilicon V5 + aarch64 support (3519DV500 / 3516CV610)#168

Merged
widgetii merged 4 commits into
masterfrom
hisi-v5-aarch64-support
Jun 2, 2026
Merged

HiSilicon V5 + aarch64 support (3519DV500 / 3516CV610)#168
widgetii merged 4 commits into
masterfrom
hisi-v5-aarch64-support

Conversation

@widgetii
Copy link
Copy Markdown
Member

@widgetii widgetii commented Jun 2, 2026

Brings up the HiSilicon V5 (HISI_OT) family on both 32-bit (Hi3516CV610 / Hi3516CV613) and 64-bit (Hi3516DV500 / Hi3519DV500) variants, and clears three latent bugs that aarch64 surfaces on the way.

Verified end-to-end on a Hi3519DV500 demo board (OS08A10 sensor) and rebuilt without warnings on a 32-bit ARMv7 toolchain.

Summary

1. chipid: V5 dispatch on aarch64 — the case for UART 0x11040000 → SC_CTRL 0x11020000 was previously gated by #ifdef __arm__ together with the legacy V1..V4 dispatches, which made the 64-bit V5 chips fall through to generic_detect_cpu(). Lifted out so both ARMv7 and aarch64 hit it; legacy V1..V4 cases stay 32-bit-only.

2. backup / tools: aarch64-only bugs — pre-existing UB that's invisible on 32-bit ARM / musl but fatal on aarch64 / glibc:

  • backup.c:1005 uint32_t payload is passed to fread_to_buf(..., size_t *); sizes coincide on ARMv7, mismatch on aarch64. Switched the local to size_t.
  • tools.c:get_god_pid did strncpy(NULL, ..., 0); aarch64 glibc faults on NULL dst even when n == 0. Guarded.
  • tools.c:get_pid_cmdline did fclose(fp) on fp == NULL when a /proc/PID disappeared mid-scan. Restructured.

3. mtd: stream-hash UBI volumescb_mtd_info() mallocs the entire UBI volume just to SHA1 it. On Hi3519DV500 the rootfs UBI vol is data_bytes = 0x1D008000 (~464 MB) on a 512 MB device, so a bare ipctool immediately exits 137 (kernel oom-killer: Killed process N (ipctool) total-vm:495608kB, anon-rss:450564kB). Added sha1_ubi_volume() that streams 64 KB chunks through SHA1Init/Update/Final. read_ubi_volume() is unchanged because backup.c still needs the buffer.

4. clocks: V5 family — adds clocks_family_v5 (HISI_OT). PLL field layout is identical to V4 so the existing struct pll_info carries the four PLLs. DDR data rate is a three-stage chain (CRG ddr_cksel → DPLL post-divider → PHY dficlk_ratio) that doesn't fit struct mux_info, so this also adds an optional .extra(cJSON *root, bool brief) callback to clock_family. The V5 extra decodes DDR rate, DRAM type, SSMOD (DPLL spread-spectrum), and per-site live HPM samples; the canonical HPM binning value goes through the standard hpm_info table.

Output on Hi3519DV500 (OS08A10)

# bare `ipctool` brief survey
clocks:
  cpu_pll: { freq_mhz: 750 }
  hpm:     { bin: high }
  ddr:     { dram_type: DDR4, data_rate_mtps: 1328 }
  ssmod:   { enabled: true }

ipctool clocks produces full detail: each PLL's ctrl_reg1/2_raw + decoded fb/ref/postdiv/fracdiv + locked bit; HPM value=300 bin=high binning_window=[210,310] aux=hpm_core_reg0; SSMOD raw + cken/disable; hpm_sites block with 4 raw samples each for NPU / MDA / CORE.

Register map sources

All V5 addresses cross-referenced against the vendor SDK (Hi3516CV610_SDK_V1.0.2.0):

  • PLL/CRG layout: bsp/components/gsl/include/platform.h, boot/reset.c, drivers/secure_driver/include/platform.h
  • DDR map: bsp/components/gsl/drivers/ddr_init/include/hal/chip/hi3516cv610/{ddrtrn_training_custom.h,ddrtrn_low_freq.h}, hal/phy/ddrtrn_hal_phy_s14.h
  • HPM map: bsp/components/gsl/include/svb.h
  • SSMOD: open_source/u-boot/u-boot-2022.07.patch around line 30246

Test plan

  • Bare ipctool produces full YAML on Hi3519DV500 (was: exit 137)
  • ipctool clocks decodes APLL/VPLL/DPLL/EPLL, DDR4-1333, SSMOD active, HPM=300 high
  • ipctool -c / -s / -t / printenv / dmesg / membw work
  • Rebuilds clean with arm-linux-gnueabihf-gcc 11.1 (ARMv7) and aarch64-linux-gnu-gcc 15.2 (aarch64); no new warnings
  • Both stripped binaries contain identical V5 symbol strings
  • Runtime verification on an actual Hi3516CV610 (32-bit V5) board — should produce chip_name="3516CV610" and the same shape of clocks output

🤖 Generated with Claude Code

widgetii and others added 4 commits June 2, 2026 18:07
The V5 family (Hi3516CV610 / Hi3516CV613 / Hi3516DV500 / Hi3519DV500)
all share UART0 @ 0x11040000 and SC_CTRL @ 0x11020000. The case was
previously gated by `#ifdef __arm__` together with the legacy V1..V4
dispatches, which made the 64-bit V5 chips (Hi3516DV500, Hi3519DV500)
fall through to generic_detect_cpu() on aarch64.

Lift the V5 case to the top of hw_detect_system()'s switch so it's
reachable from both ARMv7 (Hi3516CV610/613) and aarch64
(Hi3516DV500/3519DV500). Legacy V1..V4 cases stay 32-bit-only.

Verified on Hi3519DV500 (aarch64): SCSYSID0 at 0x11020EE0 reads
0x3519D500, which hal_hisi.c's existing chip table already maps to
"3519DV500" / HISI_OT.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three pre-existing bugs invisible on 32-bit ARM / musl but fatal on
aarch64 / glibc:

backup.c: `uint32_t payload` is passed by address to fread_to_buf()
which takes `size_t *`. ARMv7 size_t == uint32_t so the mismatch never
fired; on aarch64 size_t == uint64_t and the build fails outright.
Switch the local to size_t.

tools.c (get_god_pid): `strncpy(shortname, maxname, shortsz)` is called
unconditionally, but the only in-tree caller (get_god_app) passes
(NULL, 0). aarch64 glibc faults on strncpy with NULL dst even when
n == 0. Guard with `if (shortname && shortsz)`.

tools.c (get_pid_cmdline): after fopen("/proc/PID/cmdline") fails
(common when a PID exits mid-/proc walk), the function falls through to
fclose(fp) on fp == NULL. Restructure to early-return on NULL fp.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
cb_mtd_info() computed each UBI volume's SHA1 by calling
read_ubi_volume() with a single malloc(data_bytes), then SHA1'ing the
buffer in one shot. On targets whose rootfs UBI volume approaches
system RAM size the malloc OOMs the process: Hi3519DV500 has a
data_bytes = 0x1D008000 (~464 MB) rootfs vol on 512 MB total, which
makes a bare ipctool exit 137 immediately (kernel oom-killer log:
"Killed process N (ipctool) total-vm:495608kB, anon-rss:450564kB").

Add sha1_ubi_volume() that streams the volume in 64 KB chunks through
SHA1Init / SHA1Update / SHA1Final, and switch cb_mtd_info() to it.

read_ubi_volume() is left untouched because backup.c legitimately
needs the full buffer to dump volume contents.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…+ HPM

Decodes the full clock tree of the HiSilicon V5 (HISI_OT) family.
Same clocks_family_v5 covers both 32-bit (3516CV610/3516CV613) and
64-bit (3516DV500/3519DV500) variants since they share the same CRG /
PHY / HPM register map.

Wired through HISI_OT in clocks.c's families[] dispatch.

PLLs (CRG @ 0x11010000):
  APLL (CPU)       ctrl 0x000/0x004, lock 0x038
  VPLL (Video)     ctrl 0x080/0x084, lock 0x0B8
  DPLL (DDR)       ctrl 0x180/0x184, lock 0x1B8
  EPLL (Ethernet)  ctrl 0x200/0x204, lock 0x238
Same V4 field layout (FRACDIV[23:0], POSTDIV1[26:24], POSTDIV2[30:28],
FBDIV[11:0], REFDIV[17:12]); lock bit 4 = apll_lock_final per the
vendor's apll_lock_status union in bsp/components/gsl/boot/reset.c.

DDR data rate is a 3-stage chain (CRG ddr_cksel → DPLL → PHY
dficlk_ratio) that doesn't fit struct mux_info, so this also adds an
optional `extra(cJSON *root, bool brief)` callback to clock_family.
V5's v5_extra() decodes:
  - DDR data rate     = phy_clk_mhz * (1 << dficlk_ratio)
                        with ddr_cksel @ CRG+0x2000 [18:16],
                             dficlk_ratio @ DDR_PHY0+0x78 [1:0]
  - DRAM type         @ DDR_PHY0+0x2C [3:0]
  - SSMOD (DPLL SSC)  @ CRG+0x190 (cken bit 0, disable bit 2)
  - per-site HPM      @ HPM_BASE 0x1102B000 (NPU/MDA/CORE, 4 samples each)
Canonical HPM binning value @ SYSCTRL+0x340 [9:0] goes through the
standard hpm_info table.

Ground-truth on Hi3519DV500 demo board: APLL 750 MHz, DPLL 664 MHz,
DDR4-1333 (1328 MT/s), SSMOD active, HPM core_hpm_value=300 (high).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@widgetii widgetii merged commit 5735420 into master Jun 2, 2026
3 checks passed
@widgetii widgetii deleted the hisi-v5-aarch64-support branch June 2, 2026 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant