Repository navigation
novatek: 14 more SoCs (NT9852x, NT98532/533, NT9832x, NT98332/633) and the loader's MMU hand-off - #99
Conversation
Both are the NA51089 die, chip ID 0x7021, as the NT98562 and NT98566; the SDK (nt9856x v1.01.007) has a board and a prebuilt loader for each. - NT98561: the NT98562's 64 MiB DDR2 package. The SDK's cfg_561_IPCAM1_EVB differs from cfg_562_IPCAM1_EVB in the firmware's name alone; its loader runs the DDR at 522 MHz. - NT98560: external DDR3, 512 MiB on cfg_560_IPCAM1_EVB, at 933 MHz. The loader reads that DDR's profile, ConfigRam/560/51089A_DRAM1_933_ 4096.ini, so build.sh passes the loader its size too. Linux gets the first 256 MiB by default (osmem), as on the SDK's board, and the media pool the rest. U-Boot stays at 0x03900000, below 64 MiB, as on the other parts: the loader reads our device tree, not the SDK's, which puts it at 0x1E000000. The DDR size is now NVT_DDR_SIZE in Kconfig. Verified under qemu-hisilicon's nt98560 and nt98561 machines (OpenIPC/ qemu-hisilicon#222), which run the image's own loader: it reports 560_DRAM1_933_4096Mb / 561_DRAM1_522_512Mb as the SDK's prebuilt loaders do, trains the DDR, unpacks U-Boot, and U-Boot reaches the prompt twice, the second time with the environment the first saved.
The loader of Novatek's NT9852x Linux SDK, release nt9852x_loader_release_v2.05.013 (the same sources as the SDK tree's na51055_ldr), as the SDK ships it: the boot flow sources (LibExt/ LIBExt_src/Ctrl_Flow, Project/Model/Src), the headers, the make system, the DRAM parameter tables of the NT985xx parts (Tools/ConfigRam: 520, 522, 523, 523_A, 525, 528, 529), and what Novatek ships as binaries: the driver and DRAM libraries (ARC/Lib/Release) and the Linux host tools (Tools/Bin: nvt-ld-op, bfc, Configram520, encrypt_boot, encrypt_boot_dump). One loader serves both dies of the SDK: NA51055 (chip ID 0x4821; NT98520/522/523/525, ModelConfig_EMU_EVB.txt) and NA51084 (0x5021; NT98528/529, ModelConfig_EMU_EVB_528.txt). The mask ROM loads it into SRAM; it trains the DDR, reads the device tree at flash block 1, loads U-Boot as the tree says and starts it, as NA51089's does. Left out: the documentation, the Windows tools and scripts, the ICE and debugger scripts, the sample AES/RSA keys (secure boot is off), the tables of the NT96xxx parts (570, 575, 580, NC520), and the build output the archive carries (Project/Model/Loader520_Data, Loader525_Data and the Ctrl_Flow objects), which a build would otherwise pick up. .gitattributes keeps the vendor bytes as they are; .gitignore lets the libraries in.
The NA51089 loader's changes (cf32065, 784be2b, 1098fc3), made again for the NT9852x one, so that a distribution's Arm toolchain builds it (arm-none-eabi, or arm-linux-gnueabi as U-Boot's): - target("thumb2") is not a GCC target attribute: target("thumb"); - bin_info.h's header guard defined a different name than it tested; - -fshort-enums: the vendor libraries are built with short enums; - the link asks for neither libstdc++ nor libm, which nothing uses and Ubuntu's arm-none-eabi does not have; - a raise() for libgcc's division by zero handler; - the OP-TEE decrypt option follows its own setting (the vendor typo NA51089's MakeConfig.txt had too; both are Normal here). And for OpenIPC's images: - both models boot from the SPI NOR (STORAGEINT SpiFlash); - LOADER_TYPE follows CHIP: the NA51084 parts (528, 529) take bl_func.h's stand-alone 528 flow, the others the 52x one. The SDK's make_combo_loader.sh got there by editing bl_func.h with sed before building MODEL=EMU_EVB_528; build.sh passes MODEL instead.
U-Boot is ~235 KiB, ~94 KiB in an LZMA BCL1 container: its 128 KiB slot in the 256 KiB boot partition holds nothing larger. Novatek's LZ (algorithm 9), the only method the NT9852x loader unpacks, leaves it at ~176 KiB. NA51089's loader calls the LZMA decoder in its mask ROM; NA51055's mask ROM has none (its table holds memcpy, Dec2HexStr and the efuse reader only), so the loader carries one: Igor Pavlov's public domain LzmaDec, as U-Boot has it in lib/lzma, with the loader's memcpy and a 32 KiB static heap for the probabilities (lc=3, lp=0 needs 16 KiB). bl_load_uboot_from_flash() takes BCL1 algorithm 11 to it, as NA51089's loader takes it to the ROM, and anything else to LZ_Uncompress() as before. openipc/nvt-image.py's image is then the same on both dies. The loader's image is limited to 32 KiB (64 KiB for the 528 flow). Built in Thumb, at -Os, with _LZMA_SIZE_OPT, the decoder adds 4.6 KiB; the 52x loaders end at 32722-32741 bytes, the 528/529 ones at 65047.
The loader of Novatek's NT9832x DVR/NVR SDK v1.02.024, release na51068_loader_v1.08.014 (software/board/loader/source_code), as the SDK ships it: the boot flow sources (LibExt/LIBExt_src/Ctrl_Flow, Project/Model/Src), the headers, the make system, the model files, the DRAM parameter tables of the parts it builds for (Tools/ConfigRam: 321, 323, 621, 623, NC321, NC323), and what Novatek ships as binaries: the driver and DRAM libraries (ARC/Lib/Release) and the Linux host tools (Tools/Bin: nvt-ld-op, bfc, Configram321, encrypt_boot, encrypt_boot_dump). The die is NA51068 (NT98321, NT98323): two Cortex-A9s, SRAM at 0xFE080000. The mask ROM loads the loader into SRAM; it trains the DDR, reads the device tree at flash block 1 (0x10000 on NOR), loads U-Boot from the tree's /nor/partition_uboot to /nvt_memory_cfg/uboot (a BCL1 container through its LZ decoder, whatever the algorithm field says; anything else copied by the HEADINFO's length at 0x300) and starts it, as NA51089's does. Its mask ROM exports no routines. Left out: the git metadata the archive carries, the Jenkins scripts (admin/), History.txt, the Windows tools and the ICE / debugger scripts (*.exe, *.bat, *.ttl, gdb*), the sample AES/RSA keys and their tools (aes.txt, rsa_*, rsa_genkey; secure boot is off), packtool (the make system does not call it), and the build output the archive carries (Project/Model/loader.bin, ld_d.tmp, and ld.script, which nothing reads). .gitattributes keeps the vendor bytes as they are; .gitignore lets the libraries in.
The NA51089 and NA51055 loaders' changes (cf32065, 38ec5ad), made again for the NT9832x one, so that a distribution's Arm toolchain builds it (arm-none-eabi, or arm-linux-gnueabi as U-Boot's): - target("thumb2") is not a GCC target attribute: target("thumb"); - two header guards defined a different name than they tested (bin_info.h, nvt_rdata_sys.h), which GCC 15 makes an error; - -fshort-enums: the vendor libraries are built with short enums; - the link asks for neither libstdc++ nor libm, which nothing uses and Ubuntu's arm-none-eabi does not have. Unlike the other two, no raise() is added: the DRAM remap libraries (Remap_*.a) define one already. Built with Ubuntu's arm-linux-gnueabi-gcc 15.2 (CHIP 323, SpiFlash): LD98323A.bin, 65536 bytes as always (the image is padded to its 64 KiB); the compressed part is 64464 bytes, 64664 with the SDK's Linaro 6.4 arm-eabi.
U-Boot, ~94 KiB in an LZMA BCL1 container on NA51089, has a 128 KiB slot in OpenIPC's 256 KiB boot partition. The NT9832x loader unpacks BCL1 with Novatek's LZ alone, whatever the algorithm field says, which leaves it far larger. Its library Compress.a has an LZMA decoder as well, lzma_inflate(), which only the bound-U-Boot flow (UBOOT_BIND_ON, bl_boot_bind_uboot()) calls, with the 64 KiB .lzma scratch area the linker script reserves after the heap for it. bl_load_uboot_from_flash() now takes BCL1 algorithm 11 to it, and anything else to LZ_Uncompress() as before; openipc/nvt-image.py's image is then the same as on NA51089 and NA51055. The decoder reads the stream's own header (properties, dictionary, the unpacked size) and returns the unpacked length, or -1. Two NOR models for OpenIPC, made from the SDK's NAND ones: - 323_DDR4_4GX1_NOR_EVB (the default MODEL now): 321_DDR4_8GX1_NAND_SYS with CHIP 323, SDRAM_SIZE 4096, DRAM_MUX FB, the SDK's cfg_98323_DDR4_4GX1_NOR_EVB board, as qemu-hisilicon's build-novatek-loader.sh derives its nt98323 loader; - 321_DDR3_4GX1_NOR_EVB: 321_DDR3_4Gx1_NAND_SYS. Both boot from the SPI NOR (STORAGEINT SpiFlash) and have no SD card update at boot (STORAGEEXT NONE): with the card code and the decoder the image does not fit its 64 KiB (65968 bytes compressed), without the card code it is 60816; U-Boot does OpenIPC's SD recovery instead. Verified under qemu-hisilicon (PR u-boot#222, -M nt98323,flash-file=, the mask ROM model running the loader): the 323 loader built with Ubuntu's arm-linux-gnueabi-gcc trains the DDR, reads the tree at 0x10000, finds partition_uboot through nvtpack/index, unpacks an 80 KiB LZMA BCL1 test image to 0x03900000 and starts it ("Single core ... jump 0x03900000").
38ec5ad passed -DLOADER_TYPE from Project/Model/Makefile, whose sources do not read it; bl_func.c, which does, is built by LibExt/LIBExt_src/Ctrl_Flow/Makefile, with its own C_DEFINE_EXT. So the 528 and 529 loaders took the 52x flow and stopped after the DDR training. With the 528 flow in, the 528 model's loader is 65800 bytes with the LZMA decoder, past its 64 KiB; build.sh builds it without the loader's own SD card update (STORAGEEXT=NONE), 62833 bytes. Verified under qemu-hisilicon's nt98528 (OpenIPC/qemu-bench#222), whose mask ROM model runs the image's loader: DDR1 and DDR2 trained, U-Boot unpacked from its LZMA BCL1 container, the prompt reached twice, the second time with the environment the first saved. Built with arm-none-eabi 13.2 (Ubuntu 24.04, as CI) and with the SDK's Linaro 6.4 arm-eabi; arm-linux-gnueabi's build stops after the training (open).
gd->ram_size is a phys_size_t, 64 bits on AArch64: "%ld" warned there. Print it as an unsigned long. Built for nt98562 (arm) and nt98332 (aarch64), no warning.
NA51103 is Novatek's two Cortex-A53 NVR die. Its boards boot: mask ROM,
the board's loader (Xiongmai's FW98332A on the NBD80N36RA; no loader
source exists for this die), DDR training, a warm reset (RMR) of the
A53s into AArch64, the board's BL31 (TF-A v2.2), then U-Boot. BL31 enters
BL33 at the address in its own header (0x1E000000, the loader's
/nvt_memory_cfg/uboot) with a fixed SPSR 0x3C9: AArch64 EL2h, so U-Boot
is an AArch64 one. The vendor's _a32 configs for the die are template
copies of NA51000's and cannot be entered from this BL31.
- arch/arm/Kconfig: ARCH_NOVATEK selects CPU_V7A only without ARM64;
NVT_NA511XX selects ARM64 (mach-novatek/Kconfig), TARGET_NT98332.
- mach/na511xx.h: the blocks at 0x2_F000_0000 (vendor
arch-nvt-na51103_a64/IOAddress.h, the dump's tree), SHMINFO at
0xA00000, BL31 at 0x1F00000, U-Boot's region 0x1E000000 + 32 MiB.
mach/hardware.h picks a die's header for the drivers and the board.
- soc.c: HEADINFO "ub51103 ", BinFlag 2 as the vendor's SMP builds;
the vendor's watchdog reset (CG 0x9C bit 12, 0x7C bit 4); the MMU map
(DDR normal, 0x2_F000_0000 device: with the MMU off every access is
a device one and U-Boot's unaligned ones fault); nvt_loader_fdt().
- board/novatek/na511xx: the loader's tree to ${fdtaddr}, relocation
inside the U-Boot region, mem=/hdal-memory/media split at ${osmem}
(the media node's 4-cell addresses), and the first MAC's pins, clocks
and PHY reset as eth_na51103.c (RGMII, RMII, embedded PHY).
- novatek.h: UART at 48 MHz, the architected timer, osmem 0x15e00000
and staging at 0x2000000 as the board's firmware; ubwrite writes only
U-Boot's slot (0x20000) and openipc-common.h lets a SoC say so.
- MMC_NVT is NA51089's.
Verified under qemu-hisilicon nt98332 (-smp 3) from the Xiongmai dump
with U-Boot's slot replaced: ROM -> FW98332A -> BL31 -> U-Boot 2022.10
at EL2, "chip id 8b20", 1 GiB; and the dump's own kernel (4.19.148
arm64, repacked as an LZMA uImage) boots from it: PSCI CPU1, squashfs
root, Xiongmai's userland.
The NVR dies keep NA51089's flash controller at 0x2_F018_0000; what differs is around it, as the vendor U-Boot's nvt_spinor_reset() and nand_phy_config() do it per chip: - clock CG 0x74 bit 10, reset CG 0x98 bit 1, divider CG 0x48 [21:16]; - pins TOP 0x04 [1:0] (bit 2 for the second chip select), TOP 0xA0; - pad drive PAD 0x50, by clock; no clock auto-gate to hold off; - TSLCH of 3 at least on NA51103, DLL input delay 0 (NA51090: 8); - the clock is the tree's /nor clock-frequency (Xiongmai: 12 MHz); - chip select 0 is SPI_CFG bit 3 clear. Their FIFO is 128 bytes: a PIO read now waits for the bytes it takes or a full FIFO, not for exactly 64 bytes, which a 128-byte FIFO holding the tail of a longer read would never show (the count field also tops out at 31 words). Same waits as before on NA51089's 64-byte FIFO. Verified under qemu-hisilicon nt98332, from the board's loader and BL31: JEDEC ef4018 16 MiB; sf erase 256 KiB, sf write from 0x3000001 to 0x800003 0x2fffd bytes and sf read back to 0x4000002, crc32 equal (c28efca1), the flash file holding the data and 0xff around it; saveenv, reset, env loaded. nt98562 and nt98566 still pass the two-boot smoke test.
The NA51103 / NA51090 MACs are the same Synopsys EQoS core with Novatek's glue at +0x3000. Its CSR clock is the 150 MHz APB there, so the MDC divider is fixed (CR 1, /62, as eth_na51103.c's mdc_div), not read from NA51089's CG. Gigabit needs nothing more: the MAC configuration already leaves PS/FES clear at 1000 Mb/s. Verified under qemu-hisilicon nt98332, from the board's loader and BL31, user networking: ping 192.168.1.107, dhcp (bound 192.168.1.15), tftpboot of a 3 MB file with crc32 equal to the host's (e7287026), and of a 2.8 MB kernel.
The board's loader (DDR training, BL31) and device tree are the
board's and stay: the image is U-Boot's slot alone,
output/u-boot-nt98332-nor.bin, 128 KiB for flash 0x20000..0x40000
(${ubwrite} writes it there). Xiongmai's FW98332A reads its tree's
partition_boot as a bare LZMA stream ("compress header 0x5D", 16 MiB
dictionary, end marker) and unpacks it to 0x1E000000; the HEADINFO is
filled in as for NA51089 (length, checksum). The OpenIPC NOR layout
follows unchanged: env 0x40000, kernel 0x50000, rootfs 0x250000.
- openipc/nvt-nvr-image.py: the slot (and, given a dump of the board's
flash, a copy of it with the slot written, for a programmer).
- openipc/nt98332_config: text base 0x1E000000, caches on, load and
staging address 0x2000000, the boot counter at 0x1E20000 (the other
families' 0x1F20000 is BL31's secure megabyte here), no SD.
- openipc/nt98332.dts: what U-Boot reads of the board's tree, plain,
for the emulator's stand-in loader; build.sh puts it with the slot
into output/u-boot-nt98332-qemu.bin for CI's smoke test.
- build.sh: nt98332 with CROSS_COMPILE_A64 (aarch64-linux-gnu-).
U-Boot is 230 KiB, 90 KiB packed. Verified: the two-boot smoke test
passes on qemu-hisilicon nt98332 -smp 2 (stand-in loader) with
u-boot-nt98332-qemu.bin; the slot written into the Xiongmai dump boots
on nt98332 -smp 3 through the board's own FW98332A and BL31.
nt98562/nt98566/nt98560/nt98561 still build.
The NA51068 (NT98321, NT98323) has two of NA51089's Ethernet QoS MACs, at 0xFCC00000 and 0xFCD00000, with the same glue and embedded PHY at +0x3000 / +0x3800. The driver's state, rings and buffers move into a per-MAC struct (two at most, in .bss as before), the registers are taken from its base, and nvt_eqos_register() registers a MAC by name, base, PHY interface and MDC divider. nvt_eqos_initialize() stays NA51089's entry point, its one MAC "eqos" at NVT_ETH_BASE with the divider from the CSR clock, so board/novatek/na51089 is unchanged. Verified: nt98562 and nt98566 build; under qemu-hisilicon both MACs of the nt98323 machine (-nic user twice) take a DHCP lease, answer ping and pass a 3 MB tftpboot with the host's CRC32.
The NA51090 NVRs boot from SPI NAND (a W25N01GV on the N2032-8HDD) on the flash controller nvt_sflash runs for NOR. This driver runs it the same way, as a plain SPI master: a command and its address bytes, then the data, the chip held selected by hand. PAGE DATA READ, GET FEATURE polling, READ from the cache, PROGRAM LOAD/EXECUTE and BLOCK ERASE go out byte for byte, a page and its spare area by DMA through one buffer. The controller's own NAND mode, which the vendor U-Boot uses, is not needed for that. The chip's on-die ECC is on, as the vendor runs it; its status after a page read becomes the MTD layer's corrected/failed counts. The raw NAND framework drives it through cmdfunc (non-DM, SYS_NAND_SELF_INIT), with the parts' geometry from a table: W25N01GV, W25N02KV, GD5F1GQ4UB, GD5F1GQ5UE, MX35LF1GE4AB, XT26G01C. Clock, pins and PHY as the vendor's spinand.c does on NA51090, at the tree's /nand clock (24 MHz on the NVR). Verified under qemu-hisilicon nt98633, from the board's own FW98633A and BL31 on its NAND dump: "NAND: 128 MiB"; nand erase 256 KiB, nand write 192 KiB, nand read back, crc32 equal (23dc90b5) and the image file holding the data; saveenv, reset, env loaded; nand erase.part ubi, ubi part, ubi create/write/read of a 3 MB volume, crc32 equal to the host's, and the volume intact after a reset. Only the on-die ECC's "no error" path runs there: the model never reports ECC errors.
NA51090 is the four Cortex-A53 NVR die, 2 GiB on the N2032-8HDD. Its
boot chain is NA51103's: the board's loader (FW98633A), DDR training,
the RMR warm reset, the board's BL31 v2.2, which enters BL33 at its
header's address (0x3E000000 here) with SPSR 0x3C9, AArch64 EL2h.
U-Boot shares NA51103's code: the map differs in the watchdog
(0x110000), and the MAC is the one at 0x2_F021_0000, the boards'
tree's and Linux's eth0 (the vendor U-Boot's MAC1), set up as
eth_na51090.c's mac1_*: RGMII or RMII on either pad set, the PHY's
clock from the SoC, its reset on E_GPIO 17 or S_GPIO 19.
On SPI NAND the OpenIPC layer takes openipc-hisilicon's NAND medium:
the environment in the board's uenv partition (0x1A0000, two blocks),
UBI after it (0x1E0000), the kernel in the UBIFS rootfs;
mtdparts spi_nand.0:1664k(boot),256k(env),-(ubi), where boot is the
board's loader, tree, BL31 and U-Boot's slot (0xC0000, written alone
by ${ubwrite}). openipc-common.h gains that medium under
CONFIG_ENV_IS_IN_NAND; the NOR one is unchanged.
Verified under qemu-hisilicon nt98633 -smp 5, the board's loader and
BL31 from its NAND dump, U-Boot's slot and env replaced: U-Boot 2022.10
at EL2, "chip id bc21", 2 GiB; ping, dhcp, tftpboot of 3 MB with the
host's crc32 on the first -nic; and the dump's own kernel (4.19.148,
repacked as an LZMA uImage) with its initramfs: four CPUs through BL31's
PSCI, the SPI NAND and eth0 probed.
As for NT98332, the board's loader, tree and BL31 stay: the image is U-Boot's slot, output/u-boot-nt98633-nand.bin, 896 KiB for NAND 0xC0000..0x1A0000, a BCL1 LZMA container (algorithm 11, its 64-bit size field the 32-bit length twice, as the board's own U-Boot is packed). - openipc/nt98633_config: text base 0x3E000000, caches on, the boot counter at 0x1E20000, no SPI NOR, the NAND driver, the environment in NAND, UBI and UBIFS. - openipc/nt98633.dts: what U-Boot reads of the board's tree, for the emulator's stand-in loader; output/u-boot-nt98633-qemu.bin puts it at 0x40000 and the slot at 0xC0000. - build.sh: build_nvr takes the flash and the layout per SoC; nt98633. U-Boot is 444 KiB, 169 KiB packed. Verified: the two-boot smoke test passes on qemu-hisilicon nt98633 -smp 4 (stand-in) with a 128 MiB image holding u-boot-nt98633-qemu.bin, and on nt98332 -smp 2; the slot written into the NT98633 NAND dump boots on nt98633 -smp 5 through the board's own loader and BL31.
What the board's loader and BL31 expect of U-Boot and why only its slot is OpenIPC's, the two layouts, how to install, the peripherals, and what was verified under qemu-hisilicon and what was not.
The loader starts U-Boot with its MMU, data and instruction caches on: SCTLR 0x00c5187d, its translation table at 0x1018000 (in its DRAM area, /nvt_memory_cfg/loader) mapping the DDR write-back write-allocate (sections 0x...5de6) and the registers as device memory. This U-Boot is built with SYS_DCACHE_OFF, so its cache maintenance is compiled out, and with SKIP_LOWLEVEL_INIT, which also skipped cpu_init_cp15: it ran with a live write-back cache and no flush or invalidate around the DMA of the Ethernet MAC and the flash controller, on a table anything loaded to 0x1000000-0x1100000 overwrites. SKIP_LOWLEVEL_INIT_ONLY instead: no lowlevel_init (the loader has the clocks and DDR up), but cpu_init_cp15 invalidates the TLBs and turns the MMU and the data cache off, as the vendor U-Boot's start does (it then builds its own tables; this one stays uncached). The loader cleans its caches before it jumps. Found under qemu-hisilicon's machines of OpenIPC/qemu-bench#222, which run the image's own loader: a TFTP to 0x1000000, OpenIPC's ${baseaddr}, overwrote the table and the transfer died; on nt98562, `mw.l 0x1018000 0 0x2000` hung U-Boot. Now SCTLR reads 0x00c5187a at the prompt (M and C clear, A and I set), and the same TFTP and mw work on nt98562 and nt98525. qemu does not model caches, so what this changes on silicon it cannot show; a write-back cache with no maintenance fits #95 (NT98566: no ping, TFTP timeouts, the PHY up and configured).
NA51055 (chip ID 0x4821) and NA51084 (0x5021), the two dies of the NT9852x SDK, have NA51089's blocks at NA51089's addresses; their vendor U-Boot 2019.04 tells them apart at run time by the chip ID, as this does now (nvt_chip_id()). What differs, from that U-Boot's nvt_na51055_a32/clock.c, eth_na51055.c and nvt_ivot_mmc.c: - CPU clock: PLL8's ratio is at CG+0x1188 on NA51055 and CG+0x47E0 on NA51084 (CG+0x4420 on NA51089). NA51084 runs 1000 MHz unless the tree asks for 1200 or 1350, which only the NT98529 is cleared for: the vendor reads that from the eFuse, here the target says it. The NT9852x trees spell apb-frequency right; both spellings are read. - Ethernet: their own pinmux and LED bits (one-LED flags in [9:8]), the external PHY selected by bit 8 of 0x3004 (bit 4 on NA51089), NA51084's RMII_2 and RGMII, PLL16 for its external PHYs, and no PHY PLL reset before the embedded PHY's power-on. - The MAC's DMA: the descriptor skip (DSL) counts in bus-width units, 4 bytes on NA51055, so no skip reaches a 64-byte line there. The NT9852x targets pack the descriptors (16 bytes, no skip), which the data cache being off allows (a build-time check says so). Their vendor driver also sets DMA_SYSBUS_MODE AALE. - SD: NA51055 samples on the internal clock after the pad (SRC_CLK_SEL), NA51089 and NA51084 on the pad's before it. - ft_board_setup(): a second DDR die's range in /hdal-memory/media (<0x40000000 0x20000000> on the SDK's boards) stays the pool's. - HEADINFO: the vendor's tag, "ub51055 ". Verified under qemu-hisilicon (OpenIPC/qemu-bench#222) with the targets of the next commit: on nt98525 (0x4821) and nt98528 (0x5021) PLL8 reads 0xA00000 and 0x14D555 (0x190000 on nt98529); dhcp, ping, a 3 MB tftpboot with the host's crc32, an unaligned sf erase/write/read, mmc info, fatls and a 64 KiB mmc write/read compare; bootm prep of the SDK's 4.19.91 kernel leaves /memory <0 0x10000000> and media <0x10000000 0x10000000 0x40000000 0x20000000>, and that kernel boots with the tree. nt98562 and nt98566 still pass their smoke test.
The NT9852x SDK's parts: NA51055 (NT98520/522/523/525) and NA51084 (NT98528/529), two Cortex-A9s each, booted by the NT9852x loader (board/novatek/na51055/loader) into the same image layout as NA51089's. - Kconfig: TARGET_NT985xx, NVT_NA51055 for both dies, NVT_DDR_SIZE as each loader is built, and NVT_OSMEM, what Linux gets by default: 32M as before, 64M on the NT98523 (its SDK board's; its CMA is at 48 MiB), 256M on the 512 MiB parts. - Device trees: openipc/na51055.dtsi and na51084.dtsi are the SDK's NT98525 and NT98528 NOR boards (cfg_IPCAM1_NOR_EVB, cfg_528_IPCAM1_NOR_EVB) flattened, with the OpenIPC chain in /nor, U-Boot at 0x03900000 and the loader's scratch below it. The parts' trees carry what their SDK boards change: the NT98523's DDR and split (cfg_IPCAM1_523_NOR_EVB), the NT98529's 1.2 GHz CPUs and PLL15 (cfg_529_IPCAM1_RAMDISK_EVB). The NT98520 and NT98522 have no SDK board: the NT98525's tree with one DDR die, the NT98523's with 64 MiB. The SDK's NA51055 boards describe one CPU, its NA51084 ones two. - build.sh: build_loader takes the die and the loader's make variables. DDR: the in-package 512 Mbit / 1 Gbit of the NT98522/523 with no DDR2; the SDK boards' external 4 Gbit dies otherwise (DDR3, 933 MHz; 1066 MHz on the NT98528/529). The 528 model's loader is built without its own SD card update to fit its 64 KiB, and needs a bare-metal toolchain (see a051a70). Verified under qemu-hisilicon's nt98523, nt98525, nt98528 and nt98529 (OpenIPC/qemu-bench#222), which run the image's loader; the NT98520 and NT98522 images on nt98525 and nt98523, the same dies. Built as CI builds them (Ubuntu 24.04, arm-none-eabi 13.2, gcc-arm-linux-gnueabi), every image reaches the prompt twice, the second time with the environment the first saved; the loaders report 520_DRAM1_933_4096Mb, 522_DRAM1_933_512Mb, 523_DRAM1_933_1024Mb, 525_..._4096Mb and 528_DRAM1_1066_4096Mb_DRAM2_1066_4096Mb. Not on silicon: the external DDR's settings are the SDK boards', and must match a board's.
AArch64 U-Boots for NA51103 (NT98332) and NA51090 (NT98633), started by the board's own loader and BL31; the image is U-Boot's slot alone. Resolved against this branch's NT9852x work: both sets of targets and die symbols in Kconfig; the NVRs' osmem defaults moved into NVT_OSMEM (ahead of the 512 MiB rule, which their 1 and 2 GiB would hit); per-die HEADINFO tags; build.sh's cases and ALL_SOCS from both. Two fixes the merge needed: nvt_eqos sets AALE by the NVT_NA51055 die symbol, not nvt_chip_id() (NA51089's header, which the NVR builds do not include), and MMC_NVT depends on NVT_NA51089 || NVT_NA51055 (the NVR branch had narrowed it to NA51089, which dropped SD on NT9852x). Verified: all twelve targets build as CI would (Ubuntu 24.04, arm-none-eabi, gcc-arm-linux-gnueabi, gcc-aarch64-linux-gnu); every image passes the two-boot smoke test under qemu-hisilicon (OpenIPC/qemu-bench#222): the ten camera images through their own loaders, the NVR stand-in images on nt98332 (-smp 2) and nt98633 (-smp 4).
… qemu CLAUDE.md: the SoCs this branch now builds, a section on the NT9852x dies (their loader and its LZMA decoder, DDR, trees, what differs from NA51089), the loader's hand-off with its MMU and caches on and why cpu_init_cp15 runs, and qemu-hisilicon#222's machines running the image's own loader.
The loader of Novatek's NS02501 Linux SDK, release ns02501_loader_v3.07.101 (the same sources as the SDK tree's ns02501_ldr), as the SDK ships it: the boot flow sources (LibExt/ LIBExt_src/Ctrl_Flow, LibExt/LIBExt_src/compress, Project/Model/Src), the headers, the make system, and what Novatek ships as binaries: the driver and DRAM libraries (ARC/Lib/Release) and the Linux host tools the build runs (Tools/Bin: nvt-ld-op, bfc, Configram533, encrypt_boot, encrypt_boot_dump). The SDK has no Tools/ConfigRam: the DDR of every package is in Configram533's own tables. One loader serves every package of the die, NS02501 (chip ID 0x5521): NT98532 and NT98533 with 512 Mbit (QB), 1 or 2 Gbit (QC/QD) of DDR in the package, or 1, 2 or 4 Gbit (BC/BD/BE), picked by CHIP in ModelConfig_EMU_EVB.txt. The mask ROM loads it into SRAM; it trains the DDR, reads the device tree at flash block 1, loads U-Boot as the tree says and starts it, as NA51089's does. Left out: the documentation, the Windows tools and scripts, the ICE and debugger scripts, the sample AES/RSA/ECDSA keys and the key tools (gen_key, key_app_writer, rsa_genkey, ecdsa_genkey.sh; secure boot is off), and the host tools no build step runs (bch_8bit, bin2byte_linux). The archive carries no build output. 162 files in the SDK, 28 left out, .gitattributes and .gitignore added: 136; the other 134 match the SDK's byte for byte. .gitattributes keeps the vendor bytes as they are; .gitignore lets the libraries in.
The NA51068 is Novatek's DVR/NVR die, sold as NT98321 (DDR3) and NT98323
(DDR4): two Cortex-A9s with the A9 MPCore at 0xF9C00000 and Faraday-
heritage peripherals, external DDR (512 MiB or more on every SDK board).
Its boot chain is NA51089's: the mask ROM starts the SDK's loader
(board/novatek/na51068/loader), which trains the DDR, reads the device
tree at flash 0x10000, unpacks U-Boot from /nor/partition_uboot to
/nvt_memory_cfg/uboot and checks the HEADINFO at 0x300.
- Kconfig: NVT_NA51068 and TARGET_NT98321 / TARGET_NT98323; SYS_BOARD
"na51068"; NVT_SFLASH and MMC_NVT, NA51089's own blocks, depend on
NVT_NA51089 now.
- arch/arm/mach-novatek/na51068.c: the HEADINFO ("ub51068", BinCtrl
SMP as the vendor U-Boot sets it, so that the loader parks the second
core at /nvt_memory_cfg/core2entry2 for Linux); the A9 global timer,
64 bits at PLL16's rate (an eighth of the CPU's, CG+0x107C0); reset
through the watchdog, as the vendor kernel does; the DRAM size from
the loader's tree (/nvt_memory_cfg/dram), NVT_DDR_SIZE (512 MiB) as
the fallback.
- include/configs/novatek.h: the UART at 0xFE200000 runs at 48 MHz;
Linux gets the SDK boards' share, 192 MiB (NT98323) or 160 MiB
(NT98321), the media pool the rest; the device tree and an initrd
stay in the first 128 MiB (CONFIG_SYS_BOOTMAPSZ): just below 192 MiB,
where bootm would put them, the SDK's kernel 4.9 hangs before its
first message.
- board/novatek/na51068: the loader's tree copied to ${fdtaddr} for
bootm, the /memory and /hdal-memory/media split at ${osmem}, U-Boot
kept in the loader's region for it (0x1E000000, the SDK's: past Linux
and its CMA pools at 0x02000000-0x04800000, below the second core's
pen at 0x1FF80000); the Ethernet glue of both MACs (RGMII, RMII or
the embedded PHY, per /top@fe030000/eth pinmux, as the vendor's
eth_na51068.c, each registered with nvt_eqos); the SD host, a standard
SDHCI at 0xFA600000, pins and clock as the vendor's nvt_ivot_sdc021.c,
through mainline's non-DM sdhci.c.
Not ported: the vendor U-Boot raises the CPU to the tree's 1400 MHz
after setting the core and DDR voltages by PWM from the eFuse trim; here
the CPU stays at the loader's clock, and the timer follows PLL16 either
way.
Verified under qemu-hisilicon (PR u-boot#222), -M nt98323 and nt98321 with
the real loader: the CPU shows 800 MHz (the machine's PLL16), DRAM
512 MiB from the tree, reset restarts through the loader; the SDK's
kernel 4.9.118 boots with ${fdtaddr} and an initrd to a shell on both
CPUs (the loader's pen), mem=192M, its spi020_nor taking OpenIPC's
mtdparts, eth0 linked.
The NA51068 (NT98321, NT98323) boots from a SPI NOR on a Faraday FTSPI020 at 0xFA900000. Each command is the address (CMD0), its length with the dummy cycles (CMD1), the data length (CMD2) and the instruction (CMD3, which starts it); data through the 32-byte FIFO at 0x100, a word at a time; INT_STS bit 0 when done. A status read returns SR1 in READ_STS, or, polled by the controller, completes only once WIP is clear, which is how programs and erases are waited for. After the vendor U-Boot 2016.07 of the NT9832x SDK (nvt_flash_spi020*.c, spi020_nor.c), PIO and single lane as it runs, but: - programs are split at page boundaries and padded to whole words with 0xff (the vendor's write a page from any offset, and pad with whatever follows the buffer); - block protection a vendor firmware left set is cleared, and if it stays, writes and erases fail (-EROFS), as nvt_sflash does; - the size is 2^(the last JEDEC byte), as the vendor driver takes it (trace-stdtable in the SDK's trees); past 16 MiB the 4-byte opcodes (0x13, 0x12, 0xDC), as the vendor's; - the clock divider follows the loader's tree (/nor@fa900000 clock-frequency), the pins are the loader's. As nvt_sflash, it provides spi_flash_probe() itself; CMD_SF and ENV_IS_IN_SPI_FLASH accept it. Verified under qemu-hisilicon (PR u-boot#222), -M nt98323, real loader: - 16 MiB (W25Q128): sf read of 0x12345 bytes at 0x400005 into 0x2000003 matches the host's CRC32; erase of 0x600000+128K, write at 0x600007, read back to 0x3000001: same CRC; the bytes either side stay 0xff, in U-Boot and in the flash file qemu writes back; - 32 MiB (W25Q256): a 0x80001-byte read at 0x1800001, and a 0x1001-byte write at 0x1f00003, against the host's data; - saveenv, reset, the variable is there.
- openipc/na51068.dtsi: the device tree of the NT9832x SDK's NT98323 NOR EVB (cfg_98323_DDR4_4GX1_NOR_EVB, preprocessed and decompiled), with the OpenIPC boot chain in /nor (loader 0, fdt 0x10000, uboot 0x20000, and the nvtpack index the loader looks a partition up in) and its /nvt_memory_cfg but for linuxtmp (the SDK's: U-Boot at 0x1E000000, the pen at 0x1FF80000); nt98323.dts is it, nt98321.dts changes what the SDK's NT98321 EVB does (Linux 160 MiB, the audio SSP). - openipc/nt98321_config, nt98323_config: the SoC, NVT_SPI020 and MMC_SDHCI; SYS_TEXT_BASE 0x1E000000; SKIP_LOWLEVEL_INIT_ONLY instead of SKIP_LOWLEVEL_INIT: the loader jumps to U-Boot with its MMU on and its page tables in DDR (its region, 0x100000-0xA00000), so U-Boot's cpu_init_cp15 must turn the MMU off, else a write there hangs (a kernel load to 0x8000 did). - build.sh: build_loader() takes the die's loader directory and an optional MODEL; build_nvt() a die (default na51089) and a model; the NA51089 SoCs build as before. nt98321 and nt98323 take the loader's 321_DDR3_4GX1_NOR_EVB / 323_DDR4_4GX1_NOR_EVB models, and are in ALL_SOCS. - nvt-image.py: the same 256 KiB image; its comment says so. U-Boot is 242 KiB, 98 KiB in its LZMA BCL1 container (the slot is 128 KiB); the device tree 14 KiB. Verified: bash build.sh nt98562 nt98566 nt98560 nt98561 nt98321 nt98323 with Ubuntu's arm-linux-gnueabi-gcc 15.2; under qemu-hisilicon (PR u-boot#222) the two-boot smoke of an 8 MiB image passes on nt98321 and nt98323 (and still on nt98562, nt98566); see the driver commits for flash, network, SD and kernel checks.
What a teammate needs for the NT98321 / NT98323: the boot chain and
where things land in DDR, the loader's MMU (SKIP_LOWLEVEL_INIT_ONLY),
the timer and clock, the drivers, the kernel hand-off limit
(CONFIG_SYS_BOOTMAPSZ), what is not done (SPI NAND, the CPU's 1400 MHz)
and what was verified.
SD, verified under qemu-hisilicon -M nt98323 with -drive if=sd: mmc info
(4-bit, SD 3.0), mmc read of 1 MiB at block 0x186a0 and mmc write/read
at 0x1c000 against the host's CRC32 and the image file, mmc part,
fatls / fatinfo of a FAT16 partition, and OpenIPC's recovery writing
uImage.nt98323.img to flash 0x50000 (byte-exact), then skipping it at
the next boot ("already in flash").
NA51068, the NT9832x SDK's DVR/NVR die, on SPI NOR: its loader (unpacking an LZMA U-Boot with its own Compress.a), the FTSPI020 NOR driver, two MACs, SDHCI, the A9 global timer, U-Boot at 0x1E000000. Resolved against this branch: - arch/arm/mach-novatek/Makefile: soc.c for every die but NA51068 (the branch built it for NA51089 alone, which dropped it from the NT9852x and NVR targets); hardware.h picks na51068.h. - NVT_SFLASH and MMC_NVT stay on every die that has those blocks (NA51089, NT9852x; NVT_SFLASH also the NVRs): !NVT_NA51068, not NVT_NA51089 alone. - NA51068's osmem defaults (160M, 192M) moved into NVT_OSMEM. - nvt_eqos: the branch's one instance per MAC (nvt_eqos_register()), with this branch's packed descriptors and AALE on the NT9852x dies and the NVRs' fixed MDIO divider (NVT_ETH_MDIO_CR); nvt_eqos_initialize() for every die with one MAC. - build.sh: build_loader keeps taking the loader's make variables; the NA51068 cases pass MODEL= that way. Verified: all fourteen targets build as CI would (Ubuntu 24.04, arm-none-eabi 13.2, gcc-arm-linux-gnueabi, gcc-aarch64-linux-gnu), and every image passes the two-boot smoke test under qemu-hisilicon (OpenIPC/qemu-bench#222): the twelve camera and NA51068 images through their own loaders, the NVR stand-in images on nt98332 and nt98633. Three back-to-back 3 MB TFTPs on nt98525 (packed descriptors), nt98562 and nt98323 (two MACs).
The NA51089 and NA51055 loaders' changes (cf32065, 784be2b, 1098fc3, 38ec5ad), made again for the NS02501 one, so that a distribution's Arm toolchain builds it (arm-none-eabi, or arm-linux-gnueabi as U-Boot's): - target("thumb2") is not a GCC target attribute: target("thumb"); - bin_info.h's header guard defined a different name than it tested; - -fshort-enums: the vendor libraries are built with short enums; - the link asks for neither libstdc++ nor libm, which nothing uses and Ubuntu's arm-none-eabi does not have; - a raise() for libgcc's division by zero handler; - the OP-TEE decrypt option follows its own setting (the same vendor typo as the other loaders'; both are Normal here). And for OpenIPC's images: the model boots from the SPI NOR (STORAGEINT SpiFlash) and defaults to the 533QD, the SDK's NT98533 package, whose loader runs under qemu-hisilicon (its 533QC one checks for a DDR die the board does not have); build.sh passes CHIP for each part. The loader is 45056 bytes (0xB000, what encrypt_boot_dump pads it to; its main part deflated by bfc, 32712 bytes before padding), built with Ubuntu's arm-linux-gnueabi 15 and, in Ubuntu 24.04 as CI, with arm-none-eabi 13.2 and arm-linux-gnueabi 13.3.
U-Boot is ~240 KiB, ~97 KiB in an LZMA BCL1 container, for its 128 KiB slot. The NS02501 loader's LZMA branch is NA51089's call into the mask ROM (ROM_LZMA_POSITION 0xbfd0), but its make system builds it with ROM_PUBLIC_API OFF: as shipped it takes algorithm 11 to "Can not support LZMA" and starts nothing, and what the ROM has at 0xbfd0 is not documented anywhere in the SDK (qemu-hisilicon's model has no ROM calls for this die). So it carries its own decoder, as the NA51055 loader does (22afed1): LzmaDec from U-Boot's lib/lzma and bl_lzma.c, copied from there, in the #else of that branch. The device tree too: the SDK's NS02501 trees are ~95 KiB, the clocks the vendor kernels' clock framework takes from them (nvt-clk) most of it, and the loader reads the tree plainly from flash block 1 for fdt_totalsize() bytes. Plain, it would leave U-Boot 64 KiB before the environment at 0x40000. bl_load_fdt_from_flash() now unpacks a tree in an LZMA BCL1 container (the U-Boot one's format) into its scratch buffer past the packed data, then goes on as for a plain one (the checks, the copy to /nvt_memory_cfg/fdt). openipc/nvt-image.py packs the tree with --fdt-lzma: ~8.5 KiB. The loader stays 45056 bytes (its deflated main part 36088 bytes with arm-none-eabi 13.2, 36124 with arm-linux-gnueabi 13.3, of the 44 KiB encrypt_boot_dump pads it to). Verified under qemu-hisilicon's nt98532 and nt98533 (OpenIPC/qemu-bench#222), whose mask ROM model runs the image's loader: DDR trained, the tree and U-Boot unpacked ("lzma uboot_size 0x0003A818"), U-Boot started at 0x03900000 with the tree at 0x100000 and SHMINFO at 0xA00000. Loaders built with arm-none-eabi 13.2, arm-linux-gnueabi 13.3 (both Ubuntu 24.04, as CI) and the host's arm-linux-gnueabi 15 all boot so; unlike the NT98528 one, no toolchain needs refusing.
NS02501 (chip ID 0x5521), the NT98532/NT98533 die: two Cortex-A32s run in AArch32, NA51089's blocks at NA51089's addresses. It gets its own targets (next commit), so what differs is compiled in under NVT_NS02501. From the NS02501 SDK's U-Boot 2021.10 (nvt_ns02501_a32, nvt-ns02501/ns02501_hw_init.c, eth_ns02501.c, nvt_ivot_mmc_a64.c with nvt_ivot_mmc_ns02501.h, nvt_flash_spi, include/configs/novatek/ ns02501_a32.h): - SHMINFO at 0xA00000, where the SDK's trees put /nvt_memory_cfg/shmem. - Console: UART0 at 48 MHz (the vendor's CONFIG_SYS_NS16550_CLK; its kernel says base_baud 3000000 from the tree), not NA51089's 24. - Reset: the watchdog's reset at CG+0x80 bit 8, its clock CG+0x74 bit 19, its data word cleared, CTRL 0x102 under the key. - HEADINFO: the vendor's tag, "ub02501 ". - board_init(): the eFuse controller's 120 MHz timing with its reset held, the AXI bridge timeouts. Not its otp_init()'s 800 ms power-down wait, nor a USB PHY set-up (compiled out there); the pad power set-up reads /top nodes the SDK trees do not have. The CPU clock stays as the loader set it (the vendor caps it at 800 MHz unless an eFuse code allows more; the trees ask for 800). - ft_board_setup(): /hdal-memory/media in its parent's cells; on NS02501 two address cells, [DDR id][address]. - Ethernet: its own pinmux bits (RMII_1 0x1, RMII_2 0x2, EXTPHYCLK 0x100; the SDK boards' 0 is the embedded PHY), node /eth0@f02b0000, RMII pads at level 1, no PHY PLL reset; the embedded PHY gets MDIO address 1 and the vendor's trims for a part without eFuse ones (its eFuse reader is closed; Linux's driver keeps what it finds); AALE in the MAC's DMA, as the NT9852x one. - SD: CGPIO13-18 off GPIO, clock source code 1 for 192 MHz (0 is 480 there), the pads' 4-bit drive fields from PAD+0x50 at the tree's 2, the host's AXI channel enabled; sampling as on NA51089. - Flash: TOP+0x04 [13:12] = 1 and 0x140F off GPIO, a 240 MHz source, the tree's clock (12 MHz) capped at 48, the vendor's fixed pad drive, TIME2 0x9F51, output delay 3 from 48 MHz; no SRAM shut-down bit and no auto-gating, which the vendor does not touch on this die. Verified under qemu-hisilicon's nt98532 and nt98533 (OpenIPC/ qemu-hisilicon#222) with the targets of the next commit, the image's own loader running: chip id 5521, 256 MiB; dhcp, ping, a 3 MB tftpboot with the host's crc32, an unaligned sf erase/write/read, mmc info, fatls and a 64 KiB mmc write/read compare; saveenv, and a second boot loads it; reset: the watchdog resets the machine (qemu with -no-reboot exits; without, the model does not run its loader again after any reset, its own system_reset included); SCTLR 0x00c5187a at the prompt (the loader enters with 0x00c5187d). The SDK's 5.10.168 kernel boots to its shell with /memory <0 0x2400000> and media <0 0x2400000 0xdc00000>. NT98525's kernel tree still gets <0x10000000 0x10000000 0x40000000 0x20000000>, and nt98562, nt98525 and nt98528 pass the same network, flash and SD checks.
The NS02501 SDK's parts, one die (NVT_NS02501), booted by the NS02501 loader (board/novatek/ns02501/loader) into NA51089's image layout, the device tree packed. - Kconfig: TARGET_NT98532 and TARGET_NT98533, NVT_DDR_SIZE 256 MiB and NVT_OSMEM 36M, what the SDK boards give Linux. - Device trees: openipc/ns02501.dtsi is the SDK's NT98532 NOR board (cfg_532_IPC_NOR_SQUASHFS_BD_EVB) flattened, with the OpenIPC chain in /nor, U-Boot at 0x03900000 and the loader's scratch below it, SHMINFO where the SDK has it (0xA00000). nt98533.dts carries what the SDK's 533QD board (cfg_533_IPC_NAND_UBIFS_QD_EVB, the same memory split) changes past its storage: the engines the NT98533 has more of (DNE, PRE, MI; IME, IPE and IFE's ranges), its sensor list, I2C auto reset, the EIS and gyro modules, SDIO3's clock source, its BIN_NAME. - build.sh: nt98532 builds the loader for CHIP 532BD, nt98533 for 533QD, 2 Gbit at 1066 MHz as the SDK boards; the loader binary is named after the part's first three characters; NS02501 images get nvt-image.py --fdt-lzma. The other packages (532QB..533BE) are the same U-Boot with a loader built for their CHIP and NVT_DDR_SIZE to match, so they get no targets of their own. Built as CI builds them (Ubuntu 24.04, arm-none-eabi 13.2, gcc-arm-linux-gnueabi 13.3, gcc-aarch64-linux-gnu): every target of build.sh builds; the NS02501 images are a 45056-byte loader, an 8487/8658-byte packed tree (96534/97963) and U-Boot 97439 packed (243424). Under qemu-hisilicon (OpenIPC/qemu-bench#222), whose mask ROM model runs the image's loader, nt98532 and nt98533 reach the prompt twice, the second time with the environment the first saved; the loaders report 532BD_DRAM1_1066_2048Mb and 533QD_DRAM1_1066_2048Mb. The other targets' CI images pass the same two-boot test: nt98560, nt98561, nt98562, nt98566, nt98523, nt98525, nt98528, nt98529 (and the NT98520 / NT98522 images on nt98525 / nt98523), nt98332 (-smp 2, 16 MiB) and nt98633 (-smp 4, 128 MiB). Not on silicon: the DDR settings are the SDK boards'.
CLAUDE.md: what NT98532 / NT98533 support is, where it differs from NA51089 (the loader's own LZMA, the packed tree, SHMINFO, UART clock, reset, flash, Ethernet, SD), what is not done, and what was verified under qemu-hisilicon; NS02501 is no longer among the unsupported dies.
NS02501, two Cortex-A32s with NA51089's blocks: its loader (with its own LZMA decoder: the SDK builds it without the ROM API, and its trees are stored LZMA-packed, nvt-image.py --fdt-lzma), SHMINFO at 0xA00000, the NS02501 watchdog, flash, Ethernet (embedded PHY) and SD set-up in the NA51089 board and drivers. Resolved against the NA51068 merge: ALL_SOCS of all sixteen; NVT_SFLASH on every die but NA51068; UART0 at 48 MHz on NA51068 and NS02501; the multi-instance nvt_eqos with AALE on the NT9852x dies and NS02501. Verified: all sixteen targets build as CI would (Ubuntu 24.04, arm-none-eabi 13.2, gcc-arm-linux-gnueabi, gcc-aarch64-linux-gnu) and pass the two-boot smoke test under qemu-hisilicon (OpenIPC/qemu-bench#222); three back-to-back 3 MB TFTPs on nt98525, nt98562, nt98323 and nt98533.
PR Summary by QodoSupport 14 more Novatek SoCs and fix the loader-to-U-Boot hand-off
AI Description
Diagram
High-Level Assessment
Files changed (82)
|
Code Review by Qodo
1.
|
The NA51055, NA51068 and NS02501 loaders took the uncompressed size from the BCL1 header as the decoder's output bound. Refuse an image larger than /nvt_memory_cfg/uboot before decoding, as the plain path does.
sf_read_reg() returned 0xff on a timeout, which write enable took for WEL set and the unprotect check for no status register. Return the transfer's error instead. Capacity codes 0x1b and 0x1c (128, 256 MiB) fell back to 8 MiB with 3-byte addresses.
Its clock and pad set-up is NA511XX's.
The vendor driver sets bit 4 for the external PHY, as on NA51089, but clears bit 8, NT9852x's, for the embedded one. Clear both, so a select left by the loader goes.
The SDK's tree names NA51055 for both dies; keep it as a fallback. The vendor kernel matches only nvt,ca9.
Python's slice assignment grows the image instead of failing.
Adds 14 Novatek SoCs to
openipc-novatek, which now builds 16 (the NT98562 and NT98566 were already here).The image layout is unchanged: loader at 0, FDT at 0x10000, U-Boot at 0x20000, environment at 0x40000.
Fix for the existing NT98562/566 port (likely #95)
Novatek's loader starts U-Boot with the MMU and the D/I caches still on (SCTLR 0x00c5187d, page table at 0x1018000). The port skipped
cpu_init_cp15and does no cache maintenance, so Ethernet and flash DMA ran against a live data cache. Loading anything at OpenIPC's defaultbaseaddralso overwrote the loader's page table and hung U-Boot. d96348d setsSKIP_LOWLEVEL_INIT_ONLY, so U-Boot turns the MMU and caches off at entry. That matches #95 (an NT98566 with no ping and TFTP timeouts). QEMU doesn't model caches, though, so only a board can confirm it.Testing
Nothing has been tested on real hardware yet. Everything below was run in QEMU (OpenIPC/qemu-bench#222), which runs each image's own loader from a mask ROM model, DDR training included:
sfwrite/read and SD write/read pass on representative SoCs of every die.Known limits
arm-linux-gnueabi, cause unknown.arm-none-eabi(what CI uses) works, andbuild.shrefuses the Linux toolchain for those two.The CI and README changes are in a separate PR against
openipc.