Skip to content

novatek: add U-Boot for NT98562 and NT98566 - #53

Merged
dimerr merged 17 commits into
openipc-novatekfrom
novatek/nor-port
Oct 23, 2026
Merged

dimerr merged 17 commits into
openipc-novatekfrom
novatek/nor-port

Conversation

@dimerr

@dimerr dimerr commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator

U-Boot for Novatek's NA51089 camera SoCs, NT98562 (64 MiB) and NT98566 (128 MiB): mainline v2022.10 with the same OpenIPC boot layer as openipc-anyka (identical common/openipc.c).

One image for a programmer, written at offset 0 (u-boot-<soc>-nor.bin, 256 KiB):

Offset Contents
0x00000 the NT9856x SDK v1.01.007 loader, built from source in board/novatek/na51089/loader
0x10000 the device tree: the loader reads it, and the kernel gets it too (a Xiongmai NT98562 camera's, with the OpenIPC boot chain)
0x20000 U-Boot in an LZMA BCL1 container (96 KiB of a 128 KiB slot)
0x40000 the environment; kernel at 0x50000, as on the other families
  • The loader comes in as two commits: the SDK's files exactly as shipped, then the changes needed to build it with a distribution Arm toolchain (-fshort-enums, a raise() stub, two GCC 13 fixes). It still links Novatek's closed libraries (the DDR training) and runs their Linux host tools from Tools/Bin.
  • OpenIPC kernels carry no device tree. U-Boot boots them with the loader's (${fdtaddr}, a small boot/image-fdt.c change). Like the vendor's nvt_boot, it gives Linux the first osmem of memory and the vendor media pool the rest.
  • New drivers, all non-DM: SPI NOR (nvt_sflash), Ethernet with the embedded PHY (nvt_eqos), SD on SDIO1 (nvt_mmc).
  • CLAUDE.md has the boot flow, the image layout and what was verified where.

Verified under qemu-hisilicon nt98562/nt98566:

  • The two-boot smoke test.
  • The OpenIPC lite firmware boots to login, with the right memory split in its device tree, and fw_printenv works.
  • sf write and read at unaligned offsets.
  • saveenv and reset.
  • TFTP recovery from an empty flash.
  • The boot-limit failsafe.
  • Ethernet: dhcp, ping and tftp.
  • SD: fatload, raw read and write, and SD recovery.

Not verified on silicon yet. qemu does not run the loader, so DDR, pins, clocks, the PHY and SD timing are untested. Keep a flash backup and a programmer at hand.

CI (build-novatek.yml) comes in the PR against openipc. Its smoke test needs a qemu-hisilicon whose loader stand-in unpacks LZMA BCL1 (that change is in its own PR).

dimerr and others added 13 commits October 22, 2026 18:49
NETDEVICES selected DM_ETH, so with CONFIG_DM off a board with a network
driver failed to link on uclass and dev_get_priv references. Select it
only when DM is on, as openipc-hisilicon and openipc-xm do, so the legacy
designware_initialize() path still builds.
The firmware scan, recovery and boot-limit failsafe of the
openipc-hisilicon branch, for the Anyka AK39 SoCs: common/openipc.c and
include/openipc.h as on openipc-xm and openipc-gk710x (7208b96,
itself from openipc-hisilicon 655d32f), unchanged. CONFIG_OPENIPC
builds it; PRODUCT_SOC and PRODUCT_SOCMODEL name the target in the
environment.
With MMC on, firmware_recovery() runs at every boot, and on NOR it did
not recover anything:

- Every fs_*() call closes the filesystem when it returns, but
  recovery_mount() selected the card once: the fs_exists() worked and the
  fs_size()/fs_read() after it failed ("Recovery: failed to stat
  script.txt"). The medium found is now remembered and selected again
  before each call.
- recovery_write() wrote a file to the flash offset in its uImage
  header's load field, header included. A wrapper made for that
  (`mkimage -T firmware -a 0x250000`) left its header in front of the
  squashfs, so the scan found no rootfs; a kernel uImage as built went to
  its RAM load address. Now a wrapper's payload goes to its offset without
  the header, a kernel uImage or FIT as built goes to kernaddr, and a
  squashfs as built to rootaddr; the kernel must end before rootaddr and
  the rootfs within the flash.
- Erase and write errors were ignored and the file reported written.

The same code is on openipc-hisilicon, openipc-xm and openipc-gk710x,
where it has the same faults.

Under qemu-hisilicon's ak3918ev300, from an empty flash with only U-Boot:
a card with uImage.ak3918ev300.img and rootfs.squashfs.ak3918ev300.img,
as wrappers or as built, is written to 0x50000/0x250000 and boots to
login; script.txt runs on ak3918ev200 and ak3919ev330.
The rule is the uImage's: its payload goes to the flash offset in its
load field, header stripped (mkimage -T firmware -a <offset>), whatever
that offset is -- the card maker decides. The fallbacks of the previous
commit (a kernel uImage as built to kernaddr, a raw squashfs to rootaddr)
are dropped; a FIT kernel still goes to kernaddr.

A card left in no longer reflashes NOR at every boot: an image the flash
already holds is compared chunk by chunk and skipped (Qodo, #33).

Under qemu-hisilicon's ak3918ev300, from an empty flash: the card's
uImage.ak3918ev300.img (-a 0x50000) and rootfs.squashfs.ak3918ev300.img
(-a 0x250000) are written and boot to login; the next boot with the card
still in reports both "already in flash" and writes nothing.
The loader of Novatek's NT9856x Linux SDK v1.01.007
(nt9856x_loader_release_v1.01.007), 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 (Tools/ConfigRam/560), and
what it links against and post-processes with, which Novatek ships as
binaries: the driver and DRAM libraries (ARC/Lib/Release) and the Linux
host tools that lay out, pack and sum the image and write the DRAM
parameters into it (Tools/Bin).

The mask ROM loads it into SRAM; it trains the DDR, reads the device
tree at 0x10000, loads U-Boot as the tree says and starts it. Left out:
the documentation, the Windows tools and the in-house build scripts.

.gitattributes keeps the vendor bytes as they are (CRLF sources, host
binaries); .gitignore lets the libraries in.
What the SDK loader needs to build with the Arm toolchains of a Linux
distribution (arm-none-eabi, or arm-linux-gnueabi as U-Boot's), not the
SDK's own Linaro 6.4 arm-eabi:

- 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
  bare-metal ABI, which a Linux toolchain does not default to;
- the link does not ask for libstdc++, which nothing uses;
- a raise() for libgcc's division by zero handler, which a Linux
  toolchain's libgcc calls;
- the model defaults to the NT98562 with the SPI NOR, as Xiongmai's
  NT98562 loaders are built (DDR 666 MHz, 512 Mbit); build.sh sets CHIP
  and DRAM1_CLK for each SoC.
The NA51089 camera SoCs: one Cortex-A9, DDR in the package (64 MiB on
the NT98562, 128 MiB on the NT98566), Novatek's peripherals from
0xF0000000. After the NT9856x SDK v1.01.007's U-Boot 2019.04 (board
nvt-na51089) and the loader's sources.

- The SDK's loader trains the DDR, then starts U-Boot where its device
  tree's /nvt_memory_cfg/uboot says, once the HEADINFO 0x300 into the
  image names that address as its CodeEntry and the image sums up.
  board/novatek/na51089/u-boot.lds (mainline's, with the HEADINFO at
  0x300) and soc.c place it; the image builder fills in the length and
  the sum.
- Console: UART0, a 16550 at 24 MHz, mainline's NS16550. Timer: timer 0
  of the timer block, which the loader leaves running at 1 MHz.
  Reset: the watchdog, as the vendor U-Boot.
- The loader leaves its device tree and SHMINFO in DDR. The board copies
  the tree out of the way of the kernel and gives its address in
  ${fdtaddr}; ft_board_setup() splits the DDR at ${osmem} between
  /memory and the media pool (/hdal-memory/media), as the vendor
  U-Boot's nvt_boot does, and board_lmb_reserve() keeps the tree below
  ${osmem}.
- include/configs/openipc-common.h: openipc-anyka's, with the Novatek
  parameters (osmem 32M, load address 0x01000000, ttyS0, MTD spi_nor.0).

Verified under qemu-hisilicon nt98562 and nt98566.
OpenIPC's NT9856x kernels are uImages without a device tree, booted by
bootflash's "bootm ${baseaddr}"; the board's tree is the one the loader
read from flash, which the board keeps at ${fdtaddr}. With ARCH_NOVATEK,
a legacy image given no device tree boots with that one, as an Android
image already does.

Verified under qemu-hisilicon nt98562: the OpenIPC nt98562 kernel boots
to login with the loader's tree.
The controller at 0xF0400000 runs one operation at a time: a bare
command, a command with a status byte back, the JEDEC ID, a command with
an address, a block erase that polls the status itself, an automatic
status poll, N bytes in or out. Reads and programs hold the chip selected
by hand across the command-and-address operation and the data one.

After the vendor U-Boot's nvt_flash_spi and spinor.c: its clock, reset,
pins, timing and PHY set-up, READ 0x03 at 48 MHz single lane, whole cache
lines by DMA and the rest through the 64-byte FIFO, 256-byte pages by
DMA and shorter programs by PIO, 64 KiB erases. Like ak_sflash, it
provides spi_flash_probe() itself, for the sf command, the environment
and common/openipc.c, without the SPI and spi-nor layers. Block
protection a vendor loader left is cleared.

Verified under qemu-hisilicon nt98562: sf erase/write/read with an
unaligned offset, length and buffer against crc32, saveenv and the
environment back after a reset, the OpenIPC firmware read and booted.
The Synopsys Ethernet QoS MAC at 0xF02B0000 with the embedded PHY at
0xF02B3800, non-DM: drivers/net/nvt_eqos.c, after the vendor U-Boot's
eth_na51089.c (a cut-down early dwc_eth_qos): one TX and one RX ring,
MDIO clause 22 through the MAC, the PHY by phylib.

board_eth_init() takes the wiring from the loader's device tree
(/top@f0010000/eth pinmux; Xiongmai boards: the embedded PHY, its LEDs on
the second pads) and brings up the clocks, the SRAM, the PHY PLL and the
PHY's power as the vendor does, before the MAC: its DMA reset only
completes once the PHY gives it an RX clock. An RMII PHY is wired the
vendor's way too, untested.

Verified under qemu-hisilicon nt98562: dhcp, ping, a 3 MB tftpboot
against crc32, Linux's driver up after U-Boot used the MAC.
Novatek's own SD host at 0xF0420000, non-DM, after the vendor U-Boot's
nvt_ivot_mmc.c: its pins, clock and pad drive (the Xiongmai device tree's
table), 4-bit, PIO through the 16-word FIFO, 400 kHz then up to 24 MHz,
no card detect: with no card the first command times out in about 10 ms.

Verified under qemu-hisilicon nt98562: mmc info, fatls, fatload and mmc
read/write against the host's CRCs, no delay without a card, and
common/openipc.c's SD recovery of a changed kernel.
build.sh builds, for each SoC, U-Boot, the loader (in a copy, with the
DDR clock of Xiongmai's loaders: NT98562 666 MHz, NT98566 933 MHz) and
the device tree, and openipc/nvt-image.py lays them out as the 256 KiB
image a programmer writes at offset 0: the loader, the tree at 0x10000,
U-Boot at 0x20000 in an LZMA BCL1 container with its HEADINFO length and
sum filled in. The environment is at 0x40000.

The device tree is the one a Xiongmai NT98562 camera's loader carries
(IPC_NT98562_80N40_S38), which the vendor kernels need whole, with the
OpenIPC boot chain in /nor and its nvtpack index, through which the
loader finds U-Boot; nt98566.dts makes the changes Xiongmai's NT98566
tree makes.

The config fragments follow openipc-anyka's: the OpenIPC layer and boot
limit, the SPI NOR environment, the SD card, the Ethernet.

Verified under qemu-hisilicon nt98562 and nt98566: two boots of an image
holding only U-Boot (the second loads the environment the first saved),
the OpenIPC lite firmware to login, TFTP recovery from a flash holding
only the image, the boot limit's failsafe boot.
ci.yml only calls build-novatek.yml on the openipc branch, as on the
other families' branches. CLAUDE.md covers the loader, the image layout,
the hand-off to the kernel, the drivers and what was verified where.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Add OpenIPC U-Boot support for Novatek NT98562 and NT98566

✨ Enhancement 🐞 Bug fix ⚙️ Configuration changes 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Add programmer-ready NOR images and U-Boot support for two Novatek camera SoCs.
• Add flash, Ethernet, SD, kernel handoff, and OpenIPC recovery support.
• Fix SD recovery and enable non-DM Ethernet; document emulator coverage and silicon risks.
Diagram

graph TD
  B["Build script"] --> L["SDK loader"] --> I["NOR image"] --> R["ROM and loader"] --> U["Novatek U-Boot"] --> K["OpenIPC Linux"]
  B --> D["Board device tree"] --> I
  B --> P["Packed U-Boot"] --> I
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use a mainline-style first-stage loader
  • ➕ Could remove dependence on vendor host executables and closed DDR libraries.
  • ➖ Requires reverse-engineering DDR initialization before either SoC can boot; substantially raises bring-up risk.
2. Port peripherals to driver model
  • ➕ Better alignment with current U-Boot driver architecture and potential reuse.
  • ➖ Requires a broader device-model conversion and increases image-size pressure in the fixed 128 KiB U-Boot slot.

Recommendation: Keep the vendor-derived loader and focused non-DM port for initial bring-up: they preserve the known boot contract and fit the image budget. Treat hardware validation and the provenance and portability of supplied binary tools and libraries as explicit release gates; reconsider a mainline first stage or DM conversion after silicon boot is established.

Files changed (158) +26142 / -7

Enhancement (10) +2536 / -0
KconfigRegister the Novatek architecture +11/-0

Register the Novatek architecture

• Adds the architecture selection and sources its SoC configuration.

arch/arm/Kconfig

na51089.hDefine NA51089 hardware addresses +61/-0

Define NA51089 hardware addresses

• Provides peripheral addresses and loader handoff, timer, clock, and watchdog constants.

arch/arm/mach-novatek/include/mach/na51089.h

soc.cImplement Novatek SoC initialization +74/-0

Implement Novatek SoC initialization

• Places loader-required HEADINFO in U-Boot and implements DRAM sizing, reset, and CPU identification.

arch/arm/mach-novatek/soc.c

na51089.cInitialize board handoff and Ethernet +305/-0

Initialize board handoff and Ethernet

• Copies the loader FDT, partitions DDR between Linux and media, reserves non-OS memory, and initializes Ethernet pins, clocks, and PHY.

board/novatek/na51089/na51089.c

image-fdt.cPass loader FDT to plain uImages +12/-0

Pass loader FDT to plain uImages

• Allows Novatek legacy kernel images without an embedded FDT to use the validated tree at fdtaddr.

boot/image-fdt.c

openipc.cAdd OpenIPC scan, recovery, and failsafe +765/-0

Add OpenIPC scan, recovery, and failsafe

• Imports firmware detection and boot preparation; reselects FAT media between filesystem calls, writes uImage payloads without wrappers, and skips identical NOR contents during SD recovery.

common/openipc.c

nvt_mmc.cSupport SD cards through SDIO1 +351/-0

Support SD cards through SDIO1

• Implements non-DM command handling and PIO transfers for 4-bit SD access and recovery.

drivers/mmc/nvt_mmc.c

nvt_sflash.cImplement NA51089 SPI NOR operations +567/-0

Implement NA51089 SPI NOR operations

• Provides non-DM flash probing, reads, page programming, and sector erase through controller DMA and FIFO paths.

drivers/mtd/spi/nvt_sflash.c

nvt_eqos.cImplement polled EQoS networking +383/-0

Implement polled EQoS networking

• Adds non-DM Synopsys EQoS MAC, descriptor-ring DMA, MDIO, and PHY-based link configuration.

drivers/net/nvt_eqos.c

openipc.hDeclare OpenIPC boot helpers +7/-0

Declare OpenIPC boot helpers

• Exposes boot-layer entry points to board initialization.

include/openipc.h

Bug fix (1) +10 / -1
KconfigAllow legacy Ethernet without DM +10/-1

Allow legacy Ethernet without DM

• Makes DM_ETH conditional on DM and adds the Novatek EQoS MAC option.

drivers/net/Kconfig

Documentation (1) +238 / -0
CLAUDE.mdDocument the Novatek port +238/-0

Document the Novatek port

• Explains the boot chain, image layout, build, memory handoff, verification, and untested hardware paths.

CLAUDE.md

Other (146) +23358 / -6
ci.ymlCall the Novatek build workflow +25/-0

Call the Novatek build workflow

• Runs the reusable build and smoke-test workflow for branch pushes and pull requests.

.github/workflows/ci.yml

MakefileBuild the Novatek SoC directory +1/-0

Build the Novatek SoC directory

• Connects the new architecture implementation to the ARM build.

arch/arm/Makefile

KconfigDefine the two NA51089 targets +36/-0

Define the two NA51089 targets

• Selects NT98562 or NT98566 and their shared SoC, board, vendor, and configuration names.

arch/arm/mach-novatek/Kconfig

MakefileWire up Novatek SoC objects +3/-0

Wire up Novatek SoC objects

• Adds the SoC implementation to the target build.

arch/arm/mach-novatek/Makefile

MakefileBuild the NA51089 board +3/-0

Build the NA51089 board

• Adds board initialization to the Novatek target.

board/novatek/na51089/Makefile

.gitattributesPreserve vendor loader bytes +2/-0

Preserve vendor loader bytes

• Disables text conversion for SDK sources and binary assets.

board/novatek/na51089/loader/.gitattributes

CMacro.hImport SDK C macros +35/-0

Import SDK C macros

• Supplies the vendor loader's common C macro definitions.

board/novatek/na51089/loader/Include/CMacro.h

CC.hImport SDK compiler definitions +41/-0

Import SDK compiler definitions

• Supplies compiler-facing definitions required by the vendor loader.

board/novatek/na51089/loader/Include/Driver/CC.h

Cache.hImport cache interface +511/-0

Import cache interface

• Defines cache operations used by the SDK loader and libraries.

board/novatek/na51089/loader/Include/Driver/Cache.h

Clock.hImport clock interface +26/-0

Import clock interface

• Declares vendor loader clock controls.

board/novatek/na51089/loader/Include/Driver/Clock.h

GPIO.hImport GPIO interface +316/-0

Import GPIO interface

• Defines GPIO identifiers and operations for early hardware setup.

board/novatek/na51089/loader/Include/Driver/GPIO.h

Memory.hImport memory interface +437/-0

Import memory interface

• Defines vendor memory and DDR-related interfaces for loader integration.

board/novatek/na51089/loader/Include/Driver/Memory.h

crypto.hImport loader crypto declarations +98/-0

Import loader crypto declarations

• Provides SDK cryptographic interfaces used by its boot components.

board/novatek/na51089/loader/Include/Driver/crypto.h

nand.hImport NAND driver definitions +121/-0

Import NAND driver definitions

• Retains SDK NAND interfaces within the vendor loader source.

board/novatek/na51089/loader/Include/Driver/nand.h

nor.hImport NOR driver definitions +51/-0

Import NOR driver definitions

• Defines the loader's NOR storage interface.

board/novatek/na51089/loader/Include/Driver/nor.h

pad.hImport pad configuration definitions +874/-0

Import pad configuration definitions

• Provides vendor pin and pad controls for early boot.

board/novatek/na51089/loader/Include/Driver/pad.h

regdef.hImport register definitions +199/-0

Import register definitions

• Defines SDK hardware register fields and access constants.

board/novatek/na51089/loader/Include/Driver/regdef.h

IOReg.hImport I/O register definitions +190/-0

Import I/O register definitions

• Supplies register-level interfaces used by vendor boot code.

board/novatek/na51089/loader/Include/IOReg.h

SMacro.hImport SDK assembly macros +129/-0

Import SDK assembly macros

• Provides low-level macros needed by the loader build.

board/novatek/na51089/loader/Include/SMacro.h

StorageDef.hImport storage definitions +448/-0

Import storage definitions

• Defines vendor storage types and boot-medium constants.

board/novatek/na51089/loader/Include/StorageDef.h

Type.hImport SDK types +9/-0

Import SDK types

• Supplies base types expected by vendor headers.

board/novatek/na51089/loader/Include/Type.h

constant.hImport SDK constants +115/-0

Import SDK constants

• Defines shared constants for the vendor loader.

board/novatek/na51089/loader/Include/constant.h

ctype.hImport loader ctype header +36/-0

Import loader ctype header

• Provides the SDK's freestanding character-classification interface.

board/novatek/na51089/loader/Include/ctype.h

debug.hImport loader debug interface +31/-0

Import loader debug interface

• Defines vendor diagnostic declarations and macros.

board/novatek/na51089/loader/Include/debug.h

fat.hImport FAT interface +48/-0

Import FAT interface

• Declares the loader's FAT filesystem hooks.

board/novatek/na51089/loader/Include/fat.h

compiler.hImport SDK FDT compiler helpers +56/-0

Import SDK FDT compiler helpers

• Supplies compatibility definitions for bundled libfdt.

board/novatek/na51089/loader/Include/fdt/compiler.h

fdt.hImport FDT format definitions +111/-0

Import FDT format definitions

• Defines flattened-device-tree structures used by the loader.

board/novatek/na51089/loader/Include/fdt/fdt.h

libfdt.hImport bundled libfdt API +1580/-0

Import bundled libfdt API

• Provides the SDK device-tree parsing API used to locate memory and boot partitions.

board/novatek/na51089/loader/Include/fdt/libfdt.h

libfdt_env.hImport libfdt environment bindings +64/-0

Import libfdt environment bindings

• Defines the SDK loader's libfdt platform types.

board/novatek/na51089/loader/Include/fdt/libfdt_env.h

fuart.hImport early UART interface +85/-0

Import early UART interface

• Declares loader serial output facilities.

board/novatek/na51089/loader/Include/fuart.h

gic.hImport interrupt-controller definitions +195/-0

Import interrupt-controller definitions

• Provides vendor GIC register and interrupt interfaces.

board/novatek/na51089/loader/Include/gic.h

global.hImport loader global definitions +66/-0

Import loader global definitions

• Shares vendor loader-wide state and declarations.

board/novatek/na51089/loader/Include/global.h

limits.hImport freestanding limits +31/-0

Import freestanding limits

• Supplies integer limits for the SDK build.

board/novatek/na51089/loader/Include/limits.h

loader.hImport loader interfaces +83/-0

Import loader interfaces

• Defines the vendor loader's boot structures and entry interfaces.

board/novatek/na51089/loader/Include/loader.h

lz.hImport compression interface +31/-0

Import compression interface

• Declares SDK loader compression support.

board/novatek/na51089/loader/Include/lz.h

bin_info.hImport model binary metadata +191/-0

Import model binary metadata

• Defines vendor metadata for boot binaries.

board/novatek/na51089/loader/Include/modelext/bin_info.h

dram_partition_info.hImport DRAM partition metadata +55/-0

Import DRAM partition metadata

• Defines the model-extension representation of memory partitions.

board/novatek/na51089/loader/Include/modelext/dram_partition_info.h

emb_partition_info.hImport embedded partition metadata +56/-0

Import embedded partition metadata

• Defines SDK storage partition descriptors.

board/novatek/na51089/loader/Include/modelext/emb_partition_info.h

gpio_info.hImport model GPIO metadata +42/-0

Import model GPIO metadata

• Defines GPIO settings carried in model extensions.

board/novatek/na51089/loader/Include/modelext/gpio_info.h

interrupt.hImport interrupt identifiers +764/-0

Import interrupt identifiers

• Provides SDK interrupt definitions for the loader.

board/novatek/na51089/loader/Include/modelext/interrupt.h

model_cfg.hImport model configuration interface +8/-0

Import model configuration interface

• Supplies model-specific SDK configuration declarations.

board/novatek/na51089/loader/Include/modelext/model_cfg.h

modelext_info.hImport model-extension metadata +35/-0

Import model-extension metadata

• Defines vendor model-extension information used at boot.

board/novatek/na51089/loader/Include/modelext/modelext_info.h

modelext_parser.hImport model-extension parser API +78/-0

Import model-extension parser API

• Declares parsing interfaces for vendor model data.

board/novatek/na51089/loader/Include/modelext/modelext_parser.h

shm_info.hImport shared-memory layout +131/-0

Import shared-memory layout

• Defines loader handoff metadata shared with later boot stages.

board/novatek/na51089/loader/Include/modelext/shm_info.h

top.hImport TOP register definitions +1382/-0

Import TOP register definitions

• Provides the SDK's extensive SoC top-level pin and hardware definitions.

board/novatek/na51089/loader/Include/modelext/top.h

nvtpack.hImport NVT package definitions +193/-0

Import NVT package definitions

• Defines vendor package structures consumed by loader components.

board/novatek/na51089/loader/Include/nvtpack/nvtpack.h

rtc.hImport RTC interface +49/-0

Import RTC interface

• Declares the SDK loader's real-time clock operations.

board/novatek/na51089/loader/Include/rtc.h

scsi_op.hImport storage command definitions +205/-0

Import storage command definitions

• Provides SDK SCSI-operation declarations for storage components.

board/novatek/na51089/loader/Include/scsi_op.h

signal.hDeclare freestanding raise stub +4/-0

Declare freestanding raise stub

• Declares raise for linking loader code against distribution toolchains.

board/novatek/na51089/loader/Include/signal.h

stdarg.hImport freestanding varargs header +19/-0

Import freestanding varargs header

• Supplies argument-list definitions expected by SDK code.

board/novatek/na51089/loader/Include/stdarg.h

stdio.hImport freestanding stdio header +23/-0

Import freestanding stdio header

• Provides the loader's minimal formatted-output declarations.

board/novatek/na51089/loader/Include/stdio.h

stdlib.hImport freestanding stdlib header +4/-0

Import freestanding stdlib header

• Supplies minimal standard-library declarations for the loader.

board/novatek/na51089/loader/Include/stdlib.h

string.hImport loader string interface +47/-0

Import loader string interface

• Declares string and memory functions used by SDK code.

board/novatek/na51089/loader/Include/string.h

timer.hImport loader timer interface +31/-0

Import loader timer interface

• Declares early-boot timing functions.

board/novatek/na51089/loader/Include/timer.h

MakefileBuild loader control-flow sources +59/-0

Build loader control-flow sources

• Defines compilation of SDK loader control-flow objects.

board/novatek/na51089/loader/LibExt/LIBExt_src/Ctrl_Flow/Makefile

bl_func.cImport loader boot flow +3211/-0

Import loader boot flow

• Contains vendor logic for locating the device tree and U-Boot partition, unpacking the image, and handing off control.

board/novatek/na51089/loader/LibExt/LIBExt_src/Ctrl_Flow/bl_func.c

bl_func.hImport boot-flow declarations +302/-0

Import boot-flow declarations

• Defines the structures and interfaces used by loader control flow.

board/novatek/na51089/loader/LibExt/LIBExt_src/Ctrl_Flow/bl_func.h

bl_u2.cImport auxiliary loader flow +404/-0

Import auxiliary loader flow

• Provides SDK secondary boot-flow implementation.

board/novatek/na51089/loader/LibExt/LIBExt_src/Ctrl_Flow/bl_u2.c

bl_u2.hImport auxiliary loader declarations +7/-0

Import auxiliary loader declarations

• Declares interfaces for the secondary boot-flow source.

board/novatek/na51089/loader/LibExt/LIBExt_src/Ctrl_Flow/bl_u2.h

main.cImport loader control entry +178/-0

Import loader control entry

• Supplies the SDK control-flow entry and a raise stub for toolchain compatibility.

board/novatek/na51089/loader/LibExt/LIBExt_src/Ctrl_Flow/main.c

main.hImport loader entry declarations +55/-0

Import loader entry declarations

• Defines the control-flow entry interfaces.

board/novatek/na51089/loader/LibExt/LIBExt_src/Ctrl_Flow/main.h

nand_ids.cImport loader NAND identifiers +40/-0

Import loader NAND identifiers

• Provides the SDK's NAND device identification data.

board/novatek/na51089/loader/LibExt/LIBExt_src/Ctrl_Flow/nand_ids.c

spi_nor_ids.cImport loader SPI NOR identifiers +38/-0

Import loader SPI NOR identifiers

• Provides flash identifiers used by the SDK loader.

board/novatek/na51089/loader/LibExt/LIBExt_src/Ctrl_Flow/spi_nor_ids.c

MakefileBuild vendor loader extensions +62/-0

Build vendor loader extensions

• Connects SDK extension sources and libraries to the loader build.

board/novatek/na51089/loader/LibExt/Makefile

InputSource.txtImport loader source manifest +177/-0

Import loader source manifest

• Enumerates source inputs for the SDK build.

board/novatek/na51089/loader/MakeCommon/InputSource.txt

MakeCommon.txtImport common build rules +663/-0

Import common build rules

• Defines vendor compiler and linker flags, including short enums for library ABI compatibility.

board/novatek/na51089/loader/MakeCommon/MakeCommon.txt

MakeOption.txtImport SDK build options +298/-0

Import SDK build options

• Defines shared vendor build switches and tool choices.

board/novatek/na51089/loader/MakeCommon/MakeOption.txt

MakefileImport top-level loader Makefile +126/-0

Import top-level loader Makefile

• Coordinates SDK project, extension, and release build targets.

board/novatek/na51089/loader/MakeCommon/Makefile

OutputImg.txtImport loader image recipes +556/-0

Import loader image recipes

• Defines SDK image-generation and host-tool steps.

board/novatek/na51089/loader/MakeCommon/OutputImg.txt

OutputLib.txtImport loader library recipes +155/-0

Import loader library recipes

• Defines how SDK libraries participate in the loader build.

board/novatek/na51089/loader/MakeCommon/OutputLib.txt

LDS_LZ.ldsImport compressed loader link layout +172/-0

Import compressed loader link layout

• Defines the SDK compressed-loader memory and section layout.

board/novatek/na51089/loader/Project/Model/LDS_LZ.lds

LDS_NM.ldsImport normal loader link layout +161/-0

Import normal loader link layout

• Defines the SDK normal-loader memory and section layout.

board/novatek/na51089/loader/Project/Model/LDS_NM.lds

MakeConfig.txtConfigure vendor loader variants +907/-0

Configure vendor loader variants

• Selects chip, DDR, storage, and project options used to generate the loader.

board/novatek/na51089/loader/Project/Model/MakeConfig.txt

MakefileBuild the SDK model project +131/-0

Build the SDK model project

• Defines model-specific loader build targets and output.

board/novatek/na51089/loader/Project/Model/Makefile

ModelConfig.txtImport model selection +5/-0

Import model selection

• Provides the SDK project's model configuration entry.

board/novatek/na51089/loader/Project/Model/ModelConfig.txt

ModelConfig_EMU_EVB.txtImport evaluation-board settings +206/-0

Import evaluation-board settings

• Retains the SDK model's emulator and evaluation-board settings.

board/novatek/na51089/loader/Project/Model/ModelConfig_EMU_EVB.txt

uart_upgrade.cImport loader UART upgrade code +212/-0

Import loader UART upgrade code

• Provides the SDK's serial upgrade implementation.

board/novatek/na51089/loader/Project/Model/Src/UART/uart_upgrade.c

uart_upgrade.hImport UART upgrade interface +101/-0

Import UART upgrade interface

• Declares vendor serial-upgrade structures and operations.

board/novatek/na51089/loader/Project/Model/Src/UART/uart_upgrade.h

usb_update.cImport loader USB update code +1231/-0

Import loader USB update code

• Provides the SDK's USB update implementation.

board/novatek/na51089/loader/Project/Model/Src/USB/usb_update.c

usb_update.hImport USB update interface +323/-0

Import USB update interface

• Declares vendor USB-update structures and operations.

board/novatek/na51089/loader/Project/Model/Src/USB/usb_update.h

prj_main.cImport model boot entry +206/-0

Import model boot entry

• Provides SDK project initialization and boot-entry logic.

board/novatek/na51089/loader/Project/Model/Src/prj_main.c

prj_main.hImport model boot declarations +90/-0

Import model boot declarations

• Defines interfaces for model-specific loader startup.

board/novatek/na51089/loader/Project/Model/Src/prj_main.h

Configram560Supply vendor DDR configuration tool +0/-0

Supply vendor DDR configuration tool

• Adds a binary host tool that writes package-specific DDR parameters into the loader.

board/novatek/na51089/loader/Tools/Bin/Configram560

bfcSupply vendor compression tool +0/-0

Supply vendor compression tool

• Adds the SDK host executable used in loader image production.

board/novatek/na51089/loader/Tools/Bin/bfc

encrypt_bootSupply vendor boot image tool +0/-0

Supply vendor boot image tool

• Adds a binary SDK host tool for boot-image processing.

board/novatek/na51089/loader/Tools/Bin/encrypt_boot

encrypt_boot_dumpSupply vendor boot inspection tool +0/-0

Supply vendor boot inspection tool

• Adds a binary SDK host tool used in boot-image production.

board/novatek/na51089/loader/Tools/Bin/encrypt_boot_dump

nvt-ld-opSupply vendor linker-script tool +0/-0

Supply vendor linker-script tool

• Adds the binary host utility used by the SDK loader build.

board/novatek/na51089/loader/Tools/Bin/nvt-ld-op

51089A_DRAM1_400_1024.iniAdd 400 MHz 1024 DDR preset +138/-0

Add 400 MHz 1024 DDR preset

• Supplies vendor ConfigRam register and timing settings.

board/novatek/na51089/loader/Tools/ConfigRam/560/51089A_DRAM1_400_1024.ini

51089A_DRAM1_400_2048.iniAdd 400 MHz 2048 DDR preset +138/-0

Add 400 MHz 2048 DDR preset

• Supplies vendor ConfigRam register and timing settings.

board/novatek/na51089/loader/Tools/ConfigRam/560/51089A_DRAM1_400_2048.ini

51089A_DRAM1_400_4096.iniAdd 400 MHz 4096 DDR preset +138/-0

Add 400 MHz 4096 DDR preset

• Supplies vendor ConfigRam register and timing settings.

board/novatek/na51089/loader/Tools/ConfigRam/560/51089A_DRAM1_400_4096.ini

51089A_DRAM1_507_1024.iniAdd 507 MHz 1024 DDR preset +138/-0

Add 507 MHz 1024 DDR preset

• Supplies vendor ConfigRam register and timing settings.

board/novatek/na51089/loader/Tools/ConfigRam/560/51089A_DRAM1_507_1024.ini

51089A_DRAM1_507_2048.iniAdd 507 MHz 2048 DDR preset +138/-0

Add 507 MHz 2048 DDR preset

• Supplies vendor ConfigRam register and timing settings.

board/novatek/na51089/loader/Tools/ConfigRam/560/51089A_DRAM1_507_2048.ini

51089A_DRAM1_507_4096.iniAdd 507 MHz 4096 DDR preset +138/-0

Add 507 MHz 4096 DDR preset

• Supplies vendor ConfigRam register and timing settings.

board/novatek/na51089/loader/Tools/ConfigRam/560/51089A_DRAM1_507_4096.ini

51089A_DRAM1_507_8192.iniAdd 507 MHz 8192 DDR preset +138/-0

Add 507 MHz 8192 DDR preset

• Supplies vendor ConfigRam register and timing settings.

board/novatek/na51089/loader/Tools/ConfigRam/560/51089A_DRAM1_507_8192.ini

51089A_DRAM1_760_1024.iniAdd 760 MHz 1024 DDR preset +138/-0

Add 760 MHz 1024 DDR preset

• Supplies vendor ConfigRam register and timing settings.

board/novatek/na51089/loader/Tools/ConfigRam/560/51089A_DRAM1_760_1024.ini

51089A_DRAM1_760_2048.iniAdd 760 MHz 2048 DDR preset +138/-0

Add 760 MHz 2048 DDR preset

• Supplies vendor ConfigRam register and timing settings.

board/novatek/na51089/loader/Tools/ConfigRam/560/51089A_DRAM1_760_2048.ini

51089A_DRAM1_760_4096.iniAdd 760 MHz 4096 DDR preset +138/-0

Add 760 MHz 4096 DDR preset

• Supplies vendor ConfigRam register and timing settings.

board/novatek/na51089/loader/Tools/ConfigRam/560/51089A_DRAM1_760_4096.ini

51089A_DRAM1_760_8192.iniAdd 760 MHz 8192 DDR preset +138/-0

Add 760 MHz 8192 DDR preset

• Supplies vendor ConfigRam register and timing settings.

board/novatek/na51089/loader/Tools/ConfigRam/560/51089A_DRAM1_760_8192.ini

51089A_DRAM1_933_1024.iniAdd 933 MHz 1024 DDR preset +138/-0

Add 933 MHz 1024 DDR preset

• Supplies vendor ConfigRam register and timing settings.

board/novatek/na51089/loader/Tools/ConfigRam/560/51089A_DRAM1_933_1024.ini

51089A_DRAM1_933_2048.iniAdd 933 MHz 2048 DDR preset +138/-0

Add 933 MHz 2048 DDR preset

• Supplies vendor ConfigRam register and timing settings.

board/novatek/na51089/loader/Tools/ConfigRam/560/51089A_DRAM1_933_2048.ini

51089A_DRAM1_933_4096.iniAdd 933 MHz 4096 DDR preset +138/-0

Add 933 MHz 4096 DDR preset

• Supplies vendor ConfigRam register and timing settings.

board/novatek/na51089/loader/Tools/ConfigRam/560/51089A_DRAM1_933_4096.ini

51089A_DRAM1_933_8192.iniAdd 933 MHz 8192 DDR preset +138/-0

Add 933 MHz 8192 DDR preset

• Supplies vendor ConfigRam register and timing settings.

board/novatek/na51089/loader/Tools/ConfigRam/560/51089A_DRAM1_933_8192.ini

u-boot.ldsReserve the loader HEADINFO location +249/-0

Reserve the loader HEADINFO location

• Places the Novatek header at offset 0x300 in the U-Boot binary.

board/novatek/na51089/u-boot.lds

build.shBuild and package both Novatek targets +104/-0

Build and package both Novatek targets

• Combines configuration fragments, builds U-Boot and isolated SDK loader copies, compiles DTBs, and emits per-SoC NOR images.

build.sh

KconfigEnable sf with the Novatek controller +1/-1

Enable sf with the Novatek controller

• Accepts NVT_SFLASH as a provider for the SPI flash command.

cmd/Kconfig

KconfigExpose OpenIPC boot configuration +21/-0

Expose OpenIPC boot configuration

• Adds the OpenIPC boot helper and target identity options.

common/Kconfig

MakefileBuild the OpenIPC helper +2/-0

Build the OpenIPC helper

• Includes OpenIPC boot logic when enabled.

common/Makefile

KconfigConfigure the SDIO1 host +7/-0

Configure the SDIO1 host

• Adds the non-DM Novatek MMC host option.

drivers/mmc/Kconfig

MakefileBuild the Novatek MMC driver +1/-0

Build the Novatek MMC driver

• Connects the SDIO1 implementation to the MMC build.

drivers/mmc/Makefile

KconfigConfigure direct Novatek SPI NOR +12/-4

Configure direct Novatek SPI NOR

• Adds NVT_SFLASH and makes default flash parameters available without generic SPI flash drivers.

drivers/mtd/spi/Kconfig

MakefileBuild the Novatek flash driver +1/-0

Build the Novatek flash driver

• Includes the controller-specific NOR implementation.

drivers/mtd/spi/Makefile

MakefileBuild the Novatek Ethernet driver +1/-0

Build the Novatek Ethernet driver

• Connects the new MAC driver to the network build.

drivers/net/Makefile

KconfigAllow NOR-backed environment +1/-1

Allow NOR-backed environment

• Accepts the Novatek flash implementation for SPI-flash environment storage.

env/Kconfig

novatek.hDefine board memory and console settings +40/-0

Define board memory and console settings

• Specifies per-SoC DDR sizes, loader link address, UART, timer, and shared OpenIPC configuration.

include/configs/novatek.h

openipc-common.hDefine Novatek OpenIPC environment +130/-0

Define Novatek OpenIPC environment

• Sets NOR partitions, update and recovery commands, kernel arguments, and boot-limit failsafe behavior.

include/configs/openipc-common.h

na51089.dtsiDescribe the shared camera hardware +978/-0

Describe the shared camera hardware

• Imports the NT98562 camera tree and sets loader memory and NOR partition metadata for the OpenIPC boot chain.

openipc/na51089.dtsi

nt98562.dtsSelect the NT98562 device tree +4/-0

Select the NT98562 device tree

• Defines the NT98562 board using the shared NA51089 description.

openipc/nt98562.dts

nt98562_configSet NT98562 build identity +2/-0

Set NT98562 build identity

• Selects the 64 MiB SoC and its product identity.

openipc/nt98562_config

nt98566.dtsOverride NT98566 board properties +40/-0

Override NT98566 board properties

• Adjusts DDR and media memory, SD card power, media paths, and firmware identity for the 128 MiB variant.

openipc/nt98566.dts

nt98566_configSet NT98566 build identity +2/-0

Set NT98566 build identity

• Selects the 128 MiB SoC and its product identity.

openipc/nt98566_config

nvt-image.pyAssemble the programmer-ready NOR image +107/-0

Assemble the programmer-ready NOR image

• Fills HEADINFO, compresses U-Boot into BCL1, checks partition sizes, and places loader, DTB, and U-Boot at fixed offsets.

openipc/nvt-image.py

openipc_configEnable the shared Novatek feature set +105/-0

Enable the shared Novatek feature set

• Configures non-DM boot, console, NOR environment, networking, SD recovery, boot count, and device-tree handoff.

openipc/openipc_config

CA9.aSupply vendor Cortex-A9 library +0/-0

Supply vendor Cortex-A9 library

• Adds a prebuilt SDK library linked into the first-stage loader.

board/novatek/na51089/loader/ARC/Lib/Release/CA9.a

Common_exFAT.aSupply vendor exFAT library +0/-0

Supply vendor exFAT library

• Adds a prebuilt SDK library retained for loader variants.

board/novatek/na51089/loader/ARC/Lib/Release/Common_exFAT.a

Common_normal.aSupply vendor common library +0/-0

Supply vendor common library

• Adds prebuilt shared routines for the SDK loader.

board/novatek/na51089/loader/ARC/Lib/Release/Common_normal.a

Compress.aSupply vendor compression library +0/-0

Supply vendor compression library

• Adds prebuilt compression support for the loader.

board/novatek/na51089/loader/ARC/Lib/Release/Compress.a

Debug.aSupply vendor debug library +0/-0

Supply vendor debug library

• Adds prebuilt SDK diagnostic routines.

board/novatek/na51089/loader/ARC/Lib/Release/Debug.a

Driver.aSupply vendor hardware library +0/-0

Supply vendor hardware library

• Adds prebuilt loader hardware routines, including vendor initialization dependencies.

board/novatek/na51089/loader/ARC/Lib/Release/Driver.a

Remap_LZ560.aSupply LZ560 remap library +0/-0

Supply LZ560 remap library

• Adds a prebuilt SDK chip-remap variant.

board/novatek/na51089/loader/ARC/Lib/Release/Remap_LZ560.a

Remap_LZ561.aSupply LZ561 remap library +0/-0

Supply LZ561 remap library

• Adds a prebuilt SDK chip-remap variant.

board/novatek/na51089/loader/ARC/Lib/Release/Remap_LZ561.a

Remap_LZ562.aSupply LZ562 remap library +0/-0

Supply LZ562 remap library

• Adds the prebuilt SDK remap variant used by the NT98562 loader.

board/novatek/na51089/loader/ARC/Lib/Release/Remap_LZ562.a

Remap_LZ563.aSupply LZ563 remap library +0/-0

Supply LZ563 remap library

• Adds a prebuilt SDK chip-remap variant.

board/novatek/na51089/loader/ARC/Lib/Release/Remap_LZ563.a

Remap_LZ565.aSupply LZ565 remap library +0/-0

Supply LZ565 remap library

• Adds a prebuilt SDK chip-remap variant.

board/novatek/na51089/loader/ARC/Lib/Release/Remap_LZ565.a

Remap_LZ566.aSupply LZ566 remap library +0/-0

Supply LZ566 remap library

• Adds the prebuilt SDK remap variant used by the NT98566 loader.

board/novatek/na51089/loader/ARC/Lib/Release/Remap_LZ566.a

Reset_560.aSupply vendor reset library +0/-0

Supply vendor reset library

• Adds the prebuilt reset component for SDK loader variants.

board/novatek/na51089/loader/ARC/Lib/Release/Reset_560.a

STRGEXT_Eth.aSupply Ethernet storage-exten...

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Neither loader build finds its DRAM profile 🐞 Bug ≡ Correctness
Description
build_nvt passes chip numbers 562 and 566 to the loader make system, which uses those numbers as
DRAM-profile directory names. The checked-in profiles are only under Tools/ConfigRam/560, and
there is no 512-size profile for the 562 selection, so the profile paths passed to Configram560 do
not exist for either target.
Code

build.sh[R84-87]

+        nt98562)
+            build_nvt "${soc}" 562 666 ;;
+        nt98566)
+            build_nvt "${soc}" 566 933 ;;
Evidence
The build passes the selected chip into loader make; the loader constructs a chip-specific .ini
path and passes it to Configram. The added profiles are in the 560 directory, and none has the
512-size suffix selected for chip 562.

build.sh[36-47]
board/novatek/na51089/loader/Project/Model/MakeConfig.txt[50-76]
board/novatek/na51089/loader/Project/Model/MakeConfig.txt[689-702]
board/novatek/na51089/loader/MakeCommon/OutputImg.txt[475-480]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The loader builds select DRAM-profile paths that do not exist for either SoC.
## Fix Focus Areas
- build.sh[84-87]
- board/novatek/na51089/loader/Project/Model/MakeConfig.txt[689-702]
- board/novatek/na51089/loader/MakeCommon/OutputImg.txt[475-480]
## Recommended Fix
Provide profiles matching the selected chip, clock, and SDRAM size, or map each build to an existing, verified profile. Run both loader builds and confirm the resulting Configram inputs.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Rootfs scans assign the wrong partition size 🐞 Bug ≡ Correctness
Description
get_squashfs_size() reads the SquashFS size at offset 0x58, although the bytes_used field is
at 0x28. When a rootfs is found, the unrelated value is rounded, clamped, and used in the
generated rootfs and firmware partition layout.
Code

common/openipc.c[39]

+#define SQSH_SIZE_OFF 0x58
Evidence
The repository's SquashFS superblock puts bytes_used after root_inode, at byte 0x28. The scanner
instead reads byte 0x58 and passes its result into the generated MTD partition strings.

fs/squashfs/sqfs_filesystem.h[52-67]
common/openipc.c[96-112]
common/openipc.c[176-180]
common/openipc.c[610-619]
common/openipc.c[632-658]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Automatic NOR scanning reads rootfs size from the wrong SquashFS superblock offset.
## Fix Focus Areas
- common/openipc.c[39-41]
- common/openipc.c[96-106]
## Recommended Fix
Read the `bytes_used` field at offset `0x28`, preferably through a shared superblock definition, and reject sizes that exceed the remaining flash.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Recovery images can overwrite boot flash 🐞 Bug ☼ Reliability
Description
NOR recovery_write() trusts a uImage's load address and payload length as a flash destination and
read size without checking the available RAM, flash capacity, or partition boundaries. If an
oversized or incorrectly addressed .img is present on the recovery card, the read can exceed its
load buffer or the erase and write can reach the rootfs or reserved boot area.
Code

common/openipc.c[R398-401]

+  if (image_check_magic(&hdr)) {
+    addr = image_get_load(&hdr);
+    offset = sizeof(hdr);
+    size = image_get_data_size(&hdr);
Evidence
The image header supplies both addr and size; the path uses them directly for fs_read, erase,
and write. The configured NOR layout reserves the first 0x50000 bytes for boot and environment and
starts rootfs at 0x250000, but this path performs no corresponding boundary check.

common/openipc.c[383-426]
include/configs/openipc-common.h[36-48]
include/configs/openipc-common.h[112-116]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
NOR SD recovery accepts image-controlled sizes and destinations without bounding memory or flash writes.
## Fix Focus Areas
- common/openipc.c[398-426]
- include/configs/openipc-common.h[36-48]
## Recommended Fix
Validate the complete image size against the available load buffer and validate the destination, erase range, and payload against flash capacity and the appropriate kernel or rootfs region before reading or erasing.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. Protected flash writes can appear to pass ✓ Resolved
Description
sf_unprotect() discards errors from both calls that clear block-protection bits, allowing probe to
report a writable flash even when that operation failed. If a device remains protected, later
program and erase operations wait for completion but do not establish that protection was removed or
that the requested contents changed.
Code

drivers/mtd/spi/nvt_sflash.c[336]

+			sf_write_sr(sr, 2);
Evidence
sf_write_sr() returns controller or write-enable errors, but sf_unprotect() is void and ignores
them. Probe continues, while subsequent programming reports success after the ready poll without
verifying protection or contents.

drivers/mtd/spi/nvt_sflash.c[296-320]
drivers/mtd/spi/nvt_sflash.c[323-343]
drivers/mtd/spi/nvt_sflash.c[393-420]
drivers/mtd/spi/nvt_sflash.c[526-535]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Probe ignores failures while removing NOR block protection.
## Fix Focus Areas
- drivers/mtd/spi/nvt_sflash.c[323-343]
- drivers/mtd/spi/nvt_sflash.c[509-535]
## Recommended Fix
Return and check status-write failures during probe, then read back the protection bits and reject a still-protected device before exposing writes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Flash erases leave their status unset ✓ Resolved
Description
nvt_sf_erase() returns after erasing or encountering a sector error without setting
erase_info.state. Nonempty erases reach this callback through mtd_erase(), which sets a
completion state only for zero-length requests, so callers inspecting the result receive a stale or
unset status.
Code

drivers/mtd/spi/nvt_sflash.c[R473-478]

+		if (ret) {
+			instr->fail_addr = addr;
+			return ret;
+		}
+	}
+	return 0;
Evidence
The MTD wrapper delegates nonempty erases to the driver without setting state; the added callback
never sets it. Existing SPI-NOR implementations set failed or done states before returning.

drivers/mtd/mtdcore.c[908-920]
drivers/mtd/spi/nvt_sflash.c[460-479]
drivers/mtd/spi/spi-nor-core.c[979-981]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Nonempty NOR erase requests return without updating their MTD completion state.
## Fix Focus Areas
- drivers/mtd/spi/nvt_sflash.c[460-479]
## Recommended Fix
Set `MTD_ERASING` when work starts, `MTD_ERASE_FAILED` with `fail_addr` on failure, and `MTD_ERASE_DONE` after all sectors finish.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Secure OP-TEE builds omit decryption ✓ Resolved
Description
The OP-TEE decrypt selection checks SECUREBOOT_DECRYPT_UBOOT in its secure branch instead of
SECUREBOOT_DECRYPT_OPTEE. When OP-TEE decryption is selected independently of U-Boot decryption,
the emitted OP-TEE macro disables it; the inverse combination enables it unexpectedly.
Code

board/novatek/na51089/loader/Project/Model/MakeConfig.txt[R849-850]

+else ifeq "$(SECUREBOOT_DECRYPT_UBOOT)" "Secure"
+  OPTEE_DECRYPT_TYPE = _SECURE_DECRYPT_OPTEE_ENABLE_
Evidence
The model exposes an independent OP-TEE setting, but this conditional reads the U-Boot setting and
feeds its result into the OP-TEE compile-time macro.

board/novatek/na51089/loader/Project/Model/ModelConfig_EMU_EVB.txt[190-195]
board/novatek/na51089/loader/Project/Model/MakeConfig.txt[847-859]
board/novatek/na51089/loader/LibExt/LIBExt_src/Ctrl_Flow/Makefile[46-53]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The loader's independently configurable OP-TEE decrypt option follows the U-Boot decrypt setting instead.
## Fix Focus Areas
- board/novatek/na51089/loader/Project/Model/MakeConfig.txt[847-859]
## Recommended Fix
Use `SECUREBOOT_DECRYPT_OPTEE` for the secure branch and verify the emitted macro with the two options set to different values.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View review recommended (2)
7. 32 MiB flash chips are treated as 8 MiB ✓ Resolved
Description
spi_flash_probe() takes the size from the JEDEC capacity byte only when it is 0x14–0x18. Any other
value, including 0x19 for a 32 MiB part, silently becomes SZ_8M, and every read, program and erase
is hardwired to 3-byte addresses. On a board with a 32 MiB NOR, U-Boot sizes the flash at 8 MiB
without any warning, so mtdsultimate writes past 8 MiB (rootfs at 0x350000+0xa00000) and sf use
above that point fail with -EINVAL. Rejecting unsupported parts outright would at least make the
limit visible.
Code

drivers/mtd/spi/nvt_sflash.c[R531-532]

+	/* The last ID byte is log2 of the size on the parts these boards carry */
+	size = id[2] >= 0x14 && id[2] <= 0x18 ? 1 << id[2] : SZ_8M;
Evidence
The size fallback at line 532 maps every capacity byte outside 0x14..0x18 to 8 MiB. That value goes
into both flash->size and mtd->size (538-550), and the bounds checks in nvt_sf_read/write/erase use
it. The header comment (line 21) says only parts up to 16 MiB are supported, but probe does not
refuse larger ones. The ultimate layout in openipc-common.h needs more than 8 MiB.

drivers/mtd/spi/nvt_sflash.c[527-550]
drivers/mtd/spi/nvt_sflash.c[347-356]
drivers/mtd/spi/nvt_sflash.c[17-21]
include/configs/openipc-common.h[112-116]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
spi_flash_probe() in nvt_sflash.c turns any JEDEC capacity byte outside 0x14..0x18 into 8 MiB. Because the driver only uses 3-byte addressing, a 32 MiB part ends up silently mis-sized.
## Fix Focus Areas
- drivers/mtd/spi/nvt_sflash.c[531-532]
## Recommended Fix
If id[2] > 0x18, print a clear message: either refuse the part (return NULL) or cap the size at 16 MiB and warn that only the first 16 MiB can be reached. Do not fall back to 8 MiB without saying so. For values below 0x14, pick an explicit default and print a warning.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. Flash reads by DMA can be overwritten by stale cache data ✓ Resolved
Description
sf_read_chunk() starts the DMA into buf without cleaning or invalidating its cache lines first,
and invalidates them only after the transfer. If buf has dirty lines, for example from an earlier
tftp or memcpy to ${baseaddr}, they can be evicted to DDR during or after the DMA. That overwrites
the data just read from flash, so sf read, loadkernel, recovery_same() and environment loads
can return corrupted data now and then.
Code

drivers/mtd/spi/nvt_sflash.c[R357-362]

+		clrbits_le32(FL_SPI_CFG, CFG_BUS_WIDTH_MASK);
+		if (dma) {
+			writel((ulong)buf, FL_DMASTART);
+			fl_setup(OP_READ_N, 0, len, FIFO_DMA);
+			fl_start(CMD_READ, false);
+			ret = fl_wait();
Evidence
The DMA branch writes FL_DMASTART and starts the transfer right away. The only cache maintenance on
the buffer is invalidate_dcache_range() after fl_wait(). The write path (sf_program) does flush
before its DMA, which shows the controller is not cache-coherent. bulk is aligned to
ARCH_DMA_MINALIGN, so it is safe to invalidate the range before starting the DMA.

drivers/mtd/spi/nvt_sflash.c[347-371]
drivers/mtd/spi/nvt_sflash.c[396-412]
include/configs/openipc-common.h[104-104]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
sf_read_chunk() DMA-reads into buf without any cache maintenance before the transfer starts. Dirty lines can be written back over the data the DMA delivered.
## Fix Focus Areas
- drivers/mtd/spi/nvt_sflash.c[357-362]
## Recommended Fix
Before writel((ulong)buf, FL_DMASTART), call invalidate_dcache_range((ulong)buf, (ulong)buf + len), or flush_dcache_range if you prefer clean+invalidate. buf and len are already aligned to ARCH_DMA_MINALIGN. Keep the invalidate after fl_wait() to drop any lines fetched speculatively during the transfer.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can reply 'qodo' on any finding to push back, ask questions, or dig deeper

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread build.sh
Comment thread common/openipc.c
#define UBI_MAGIC_ASCII "UBI#"
#define FDT_MAGIC 0xd00dfeed

#define SQSH_SIZE_OFF 0x58

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Rootfs scans assign the wrong partition size 🐞 Bug ≡ Correctness

get_squashfs_size() reads the SquashFS size at offset 0x58, although the bytes_used field is
at 0x28. When a rootfs is found, the unrelated value is rounded, clamped, and used in the
generated rootfs and firmware partition layout.
Agent Prompt
## Issue description
Automatic NOR scanning reads rootfs size from the wrong SquashFS superblock offset.
## Fix Focus Areas
- common/openipc.c[39-41]
- common/openipc.c[96-106]
## Recommended Fix
Read the `bytes_used` field at offset `0x28`, preferably through a shared superblock definition, and reject sizes that exceed the remaining flash.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread common/openipc.c
Comment on lines +398 to +401
if (image_check_magic(&hdr)) {
addr = image_get_load(&hdr);
offset = sizeof(hdr);
size = image_get_data_size(&hdr);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Recovery images can overwrite boot flash 🐞 Bug ☼ Reliability

NOR recovery_write() trusts a uImage's load address and payload length as a flash destination and
read size without checking the available RAM, flash capacity, or partition boundaries. If an
oversized or incorrectly addressed .img is present on the recovery card, the read can exceed its
load buffer or the erase and write can reach the rootfs or reserved boot area.
Agent Prompt
## Issue description
NOR SD recovery accepts image-controlled sizes and destinations without bounding memory or flash writes.
## Fix Focus Areas
- common/openipc.c[398-426]
- include/configs/openipc-common.h[36-48]
## Recommended Fix
Validate the complete image size against the available load buffer and validate the destination, erase range, and payload against flash capacity and the appropriate kernel or rootfs region before reading or erasing.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread drivers/mtd/spi/nvt_sflash.c Outdated
Comment thread drivers/mtd/spi/nvt_sflash.c
Comment thread board/novatek/na51089/loader/Project/Model/MakeConfig.txt Outdated
Comment thread drivers/mtd/spi/nvt_sflash.c Outdated
Comment thread drivers/mtd/spi/nvt_sflash.c
…, DMA cache

From the Qodo review of #53:

- sf_unprotect() checks that the block protection went: a program or
  erase of a protected block is accepted and dropped by the flash. If
  clearing it fails, the probe says so and writes and erases return
  -EROFS instead of passing for success.
- Erases set erase_info.state (MTD_ERASING, then MTD_ERASE_DONE, or
  MTD_ERASE_FAILED with fail_addr).
- A capacity byte past 16 MiB is no longer taken for 8 MiB: the driver
  uses the first 16 MiB (3-byte addresses) and says so; an unknown one
  is taken for 8 MiB with a warning. Both are printed once.
- A DMA read invalidates the buffer's cache lines before the transfer
  too, so no dirty line lands on the data afterwards. (D-cache is off on
  these targets; this keeps the driver right if it is turned on.)

Verified under qemu-hisilicon nt98562: sf erase/write/read with an
unaligned offset, length and buffer against crc32, saveenv, the OpenIPC
firmware to login; a 32 MiB flash image probes as its first 16 MiB.
MakeConfig.txt chose SECURE_DECRYPT_OPTEE_OS from
SECUREBOOT_DECRYPT_UBOOT in its secure branch. A vendor typo found by
the Qodo review of #53; these builds leave both at Normal, so their
loaders do not change.
The loader's make system names ConfigRam/562/... and ConfigRam/566/...,
which do not exist, as Qodo noted on #53. For these in-package parts
Configram560 writes the DDR parameters from its own tables (-package=562
or 566) and does not read the profile: built with the default path, a
real 933 MHz 1 Gbit profile and a 400 MHz 8 Gbit one, the NT98566 loader
differs only in its build time stamp and the sums over it.
@dimerr
dimerr merged commit f2d95ad into openipc-novatek Oct 23, 2026
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