Skip to content

sigmastar: infinity2m to Ifliegen, NOR and SPI NAND - #107

Merged
dimerr merged 16 commits into
openipc-sigmastarfrom
sigmastar/more-dies
Nov 7, 2026
Merged

dimerr merged 16 commits into
openipc-sigmastarfrom
sigmastar/more-dies

Conversation

@dimerr

@dimerr dimerr commented Nov 7, 2026 •

Copy link
Copy Markdown
Collaborator

U-Boot for every SigmaStar die we have boot stages for, next to infinity3:

Die SoCs Media
infinity2m ssd201 ssd202d ssr621q NOR, SPI NAND
infinity6 ssc325 ssc325de ssc327de NOR, SPI NAND
infinity6b0 ssc333 ssc335 ssc335de ssc337 ssc337de NOR, SPI NAND
infinity6e ssc30kd ssc30kq ssc338q NOR, SPI NAND
infinity6c ssc377 ssc377d ssc377de ssc377qe ssc378de ssc378qe NOR, SPI NAND
Iford ssc029a ssc029b ssc029c NOR; SPI NAND on ssc029a
Ifado ssc375 NOR
Ifliegen ssc034a ssc034b NOR, SPI NAND

./build.sh makes 52 images. The vendor's first stages (IPL, IPL_CUST, and on Ifliegen TF-A's SP_MIN) and the flash tables they read are carried as binaries in openipc/.

New: ms_spinand (SPI NAND on the FSP-QSPI). Per-die support in ms_sflash, ms_emac, ms_sdmmc. An OpenIPC NAND layout with the kernel and a squashfs rootfs in their own UBI volumes. A save_boot_params hook for a loader that jumps with the MMU on (Ifado).

Not run on silicon. Everything past infinity3 has been tested only under qemu (qemu-hisilicon's per-die machines), and the CI release is the only place the images go: publishing to OpenIPC/firmware is commented out in the companion CI PR. What was checked, per die, is in CLAUDE.md. The main checks:

  • the vendor IPL chain into this U-Boot;
  • sf and nand erase, write and read against the raw flash file;
  • the environment across a reset;
  • ping and TFTP;
  • SD, where the die has it;
  • a kernel boot. OpenIPC's published firmware reaches login: on ssc325de, ssc337de, ssc338q NAND and the NOR dies with published images; the SDK kernels reach a shell or userspace on Iford, Ifado and Ifliegen.

Not covered: Mercury6 (no IPL at hand); Iford 029b/029c NAND (only RTOS/dual-OS sets in the SDK).

The CI matrix for these SoCs is in the companion PR against openipc. Merge this one first: that PR's own run builds the current openipc-sigmastar.

Targets for infinity2m (SSD201, SSD202D, SSR621Q), infinity6 (SSC325,
SSC325DE, SSC327DE), infinity6b0 (SSC333, SSC335, SSC335DE, SSC337,
SSC337DE), infinity6e (SSC30KD, SSC30KQ, SSC338Q), infinity6c (SSC377,
SSC377D, SSC377DE, SSC377QE, SSC378DE, SSC378QE), Iford (SSC029A/B/C),
Ifado (SSC375) and Ifliegen (SSC034A/B), next to infinity3.

Per die: the Ethernet PHY's banks, the FSP the flash is on, the DDR size
(the IPL's register, or probed where none is known), the LX_MEM/mma_heap
values the vendor images pass, the MIU flush. The board file is now the
generic sigmastar/ipc.

lowlevel_init.S: save_boot_params cleans the D-cache and turns the MMU
off when the loader jumps with it on, as Ifado's IPL_CUST does; the
kernel would build its page table over the live one.

Ifliegen: UART0 leaves the URDMA's DMA mode before the console
(board_early_init_f), and U-Boot keeps to the first 48 MiB, as the SDK's
does, since TF-A's SP_MIN stays at 0x23FE0000 as the kernel's PSCI.
The FSP's bank by die (PM or non-PM), the BDMA paths from MIU to the FSP
and back, BDMA_PATH2 cleared where the second path register means
something else, and on infinity6c, Iford, Ifliegen and Ifado the boot
flash's chip select held in software (SS_FSP_SW_CS) for the erase,
program and status writes.
The internal PHY's banks and the EMAC RX/TX clocks in SCGPCTRL per die;
on Iford and Ifliegen the clock gate open and the MCG gating off, as
their mhal_emac.c, and on Iford the MCM control that drops the first
frame after an RBQP reset.
The FCIE5 host is the same; its bank, clock select, DDR_MOD timing, pad
mux, card power and card detect follow each die's vendor
hal_card_platform_<die>.c: infinity2m, infinity6, 6b0, 6e, 6c and Iford.
A raw NAND driver for the SPI NAND that SigmaStar boots from, through
the FSP-QSPI: geometry from the SNI the IPL reads (the published images
carry a generic one), page and spare by BDMA, the chip select held by
QSPI's burst bit, the bad-block table kept in memory like the vendor's.
A W25N's buffer mode is turned back on where Iford's IPL leaves it off.
OPENIPC_NAND_KERNEL_VOLUME: OpenIPC's SigmaStar NAND firmware keeps the
kernel and a squashfs rootfs in UBI volumes of their own; the helper
checks and recovers those. Per die the boot partitions, environment and
UBI offsets (infinity2m by its PNI, infinity6c and Iford by their SDKs),
and root= by the partition count, since gluebi numbers the volumes after
the partitions (mtdblock5, 6 on infinity6c and Iford, 4 on infinity2m).

The NOR flash's MTD name is nor0 for the SGS kernels (Iford, Ifliegen,
Ifado), NOR_FLASH for the older ones.
build.sh builds 50 images: every die's NOR image and the SPI NAND ones.
sigmastar-image.py lays out each die's boot partition around the
vendor's first stages (IPL, IPL_CUST, and on Ifliegen TF-A's SP_MIN),
carried as binaries in openipc/ with the flash tables (MXP, GCIS, CIS,
SNI, PNI) they read: from OpenIPC/u-boot-sigmastar's ipl/, the i2m,
Maruko, Iford and Ifliegen SDKs, and for Ifado a Dahua camera's NOR.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Add SigmaStar infinity2m through Ifliegen NOR and SPI NAND support

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

Grey Divider

AI Description

• Add boot targets for eight later SigmaStar dies across NOR and supported SPI NAND layouts.
• Extend flash, Ethernet, SD, memory hand-off, and recovery support for die-specific hardware.
• Package vendor boot stages into 50 images; document QEMU verification and absent silicon testing.
Diagram

graph TD
  A["Target configs"] --> B["Build script"] --> C["Image packer"] --> D["Flash image"] --> E["Vendor stages"] --> F["U-Boot"] --> G["Kernel boot"]
  F --> H["Flash peripherals"]
  H --> G
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use the generic SPI NAND stack
  • ➕ Would share chip identification and NAND maintenance with upstream drivers.
  • ➖ Requires an FSP/QSPI controller integration and accommodation of SNI-derived geometry and vendor-specific boot behavior.
2. Land die families incrementally
  • ➕ Would reduce review scope and isolate hardware regressions by family.
  • ➖ Would delay the shared NAND layouts and build coverage, and repeat integration work across PRs.

Recommendation: The shared SoC and board layer with die-specific hardware paths is a reasonable way to preserve vendor boot compatibility. Consider whether the custom NAND driver can eventually sit beneath the generic SPI NAND stack, but do not block this integration on that larger redesign. Keep firmware publication gated until representative boards are tested on silicon.

Files changed (64) +2956 / -123

Enhancement (13) +2472 / -91
KconfigDefine later-die SoC targets and shared feature groups +217/-1

Define later-die SoC targets and shared feature groups

• Adds SoC selections from infinity2m through Ifliegen and groups related FSP, memory-argument, and hardware behavior. Selects the shared ipc board.

arch/arm/mach-sigmastar/Kconfig

MakefileLink early boot hand-off assembly +1/-0

Link early boot hand-off assembly

• Includes the new low-level initialization object in SigmaStar builds.

arch/arm/mach-sigmastar/Makefile

sigmastar.hExpose die-dependent register and boot definitions +69/-4

Expose die-dependent register and boot definitions

• Adds PHY and SD bank selections, FSP bank identifiers, DDR-size registers, UART DMA controls, and boot-parameter addresses.

arch/arm/mach-sigmastar/include/mach/sigmastar.h

soc.cHandle later-die DRAM, FSP, UART, and kernel memory +141/-4

Handle later-die DRAM, FSP, UART, and kernel memory

• Adds die-specific DRAM sizing, FSP selection, usable-RAM limits, and LX_MEM/mma_heap environment values. Handles Ifliegen's UART DMA hand-off and skips MIU flushing where unsupported.

arch/arm/mach-sigmastar/soc.c

ipc.cShare board initialization across SigmaStar dies +6/-3

Share board initialization across SigmaStar dies

• Uses each die's boot-parameter address and refreshes memory arguments before OpenIPC boot initialization.

board/sigmastar/ipc/ipc.c

build.shBuild NOR and SPI NAND images for later SoCs +169/-1

Build NOR and SPI NAND images for later SoCs

• Adds die, Iford, Ifado, and Ifliegen build paths, including medium-specific fragments and image packer arguments. Expands the default build to 50 images.

build.sh

openipc.cScan and recover SigmaStar NAND UBI volumes +27/-3

Scan and recover SigmaStar NAND UBI volumes

• Checks the separate kernel and squashfs volumes and chooses matching recovery files when configured. Makes the kernel recovery volume size configurable.

common/openipc.c

ms_sdmmc.cSupport per-die SD clocks, pads, and power +344/-26

Support per-die SD clocks, pads, and power

• Adds platform paths for later dies' SD timing, clock selection, card detect, pad muxing, and power controls.

drivers/mmc/ms_sdmmc.c

ms_spinand.cImplement FSP/QSPI SPI NAND access +765/-0

Implement FSP/QSPI SPI NAND access

• Adds SNI-based geometry probing, FSP commands, BDMA page transfer, on-die ECC reporting, and raw NAND registration. Supports software chip select and the Iford Winbond boot state.

drivers/mtd/nand/raw/ms_spinand.c

ms_sflash.cExtend SPI NOR to later FSP/QSPI variants +257/-30

Extend SPI NOR to later FSP/QSPI variants

• Selects FSP and BDMA paths by die and adds software-chip-select command framing and BDMA reads where XIU reads are unsuitable.

drivers/mtd/spi/ms_sflash.c

ms_emac.cInitialize later-die Ethernet clocks and PHY +41/-9

Initialize later-die Ethernet clocks and PHY

• Selects die-specific clock registers and PHY settings, including Iford-family gate handling and preservation of shared PHY timer bits.

drivers/net/ms_emac.c

openipc-common.hDefine later-die NOR and NAND boot environments +100/-10

Define later-die NOR and NAND boot environments

• Adds LX_MEM/mma_heap arguments and medium-specific partitions, boot commands, recovery commands, and NAND UBI kernel loading while retaining infinity3's mem= path.

include/configs/openipc-common.h

sigmastar-image.pyPackage later-die NOR and NAND boot images +335/-0

Package later-die NOR and NAND boot images

• Creates legacy xz uImages and lays out vendor stages, flash tables, and U-Boot for standard and die-specific NOR and NAND formats. Checks component sizes against their partition space.

openipc/sigmastar-image.py

Bug fix (1) +31 / -0
lowlevel_init.SDisable inherited MMU and cache state before U-Boot +31/-0

Disable inherited MMU and cache state before U-Boot

• Adds a save_boot_params hook that cleans the data cache and disables the MMU and cache when a vendor loader leaves them enabled, notably on Ifado.

arch/arm/mach-sigmastar/lowlevel_init.S

Refactor (1) +1 / -1
MakefileBuild the shared SigmaStar ipc board object +1/-1

Build the shared SigmaStar ipc board object

• Switches the board object name from infinity3 to ipc.

board/sigmastar/ipc/Makefile

Documentation (2) +304 / -22
CLAUDE.mdDocument expanded SigmaStar support and verification +302/-20

Document expanded SigmaStar support and verification

• Describes boot layouts, per-die hardware differences, NAND firmware conventions, build targets, QEMU checks, and untested hardware paths. Explicitly notes that later-die images have not run on silicon.

CLAUDE.md

openipc_configClarify layered target configuration +2/-2

Clarify layered target configuration

• Documents that builds now append both die and SoC fragments to the shared configuration.

openipc/openipc_config

Other (47) +148 / -9
KconfigSelect NAND firmware with separate kernel volume +8/-0

Select NAND firmware with separate kernel volume

• Adds an OpenIPC option for SigmaStar NAND images whose kernel and squashfs rootfs occupy separate UBI volumes.

common/Kconfig

KconfigGeneralize the SigmaStar SD host option +2/-2

Generalize the SigmaStar SD host option

• Removes infinity3-only wording from the SDIO0 driver description.

drivers/mmc/Kconfig

KconfigConfigure SigmaStar FSP SPI NAND +8/-0

Configure SigmaStar FSP SPI NAND

• Adds a SigmaStar-specific SPI NAND option using NAND self-initialization.

drivers/mtd/nand/raw/Kconfig

MakefileBuild the SigmaStar SPI NAND driver +1/-0

Build the SigmaStar SPI NAND driver

• Links ms_spinand when its configuration option is enabled.

drivers/mtd/nand/raw/Makefile

KconfigGeneralize the SigmaStar SPI NOR option +2/-2

Generalize the SigmaStar SPI NOR option

• Removes infinity3-only wording from the FSP SPI NOR driver description.

drivers/mtd/spi/Kconfig

KconfigGeneralize the SigmaStar Ethernet option +2/-2

Generalize the SigmaStar Ethernet option

• Removes infinity3-only wording from the EMAC driver description.

drivers/net/Kconfig

sigmastar.hSet target DRAM bounds and NAND device count +15/-3

Set target DRAM bounds and NAND device count

• Expands maximum DRAM sizing for selected targets and declares one NAND device for NAND builds.

include/configs/sigmastar.h

ifado_configConfigure Ifado kernel hand-off and omit SD +6/-0

Configure Ifado kernel hand-off and omit SD

• Sets the vendor machine type and disables unverified SD support.

openipc/ifado_config

ifliegen-flash-list.nriCarry Ifliegen flash-list data +0/-0

Carry Ifliegen flash-list data

• Adds vendor flash-list data consumed by the Ifliegen NOR image packer.

openipc/ifliegen-flash-list.nri

ifliegen-flash.nriCarry Ifliegen flash identification data +0/-0

Carry Ifliegen flash identification data

• Adds vendor flash data placed in the Ifliegen CIS area.

openipc/ifliegen-flash.nri

ifliegen_configConfigure Ifliegen early console and kernel hand-off +9/-0

Configure Ifliegen early console and kernel hand-off

• Sets the machine type, enables early UART hand-off, and disables SD until modeled and verified.

openipc/ifliegen_config

iford_configSet the Iford machine type +2/-0

Set the Iford machine type

• Adds the machine-type value used for Iford builds.

openipc/iford_config

iford_nand_configSet Iford NAND environment and partitions +3/-0

Set Iford NAND environment and partitions

• Places the environment after the SDK's CIS and boot copies and declares its NAND partition layout.

openipc/iford_nand_config

infinity2m_configSet the infinity2m machine type +2/-0

Set the infinity2m machine type

• Matches the vendor machine-type value for infinity2m targets.

openipc/infinity2m_config

infinity2m_nand_configSet infinity2m NAND environment layout +4/-0

Set infinity2m NAND environment layout

• Uses the SDK PNI's environment offset, range, and partition boundaries.

openipc/infinity2m_nand_config

infinity6_configSet the infinity6 machine type +2/-0

Set the infinity6 machine type

• Matches the vendor machine-type value for infinity6 targets.

openipc/infinity6_config

infinity6b0_configSet the infinity6b0 machine type +2/-0

Set the infinity6b0 machine type

• Matches the vendor machine-type value for infinity6b0 targets.

openipc/infinity6b0_config

infinity6c_configSet the infinity6c vendor machine type +2/-0

Set the infinity6c vendor machine type

• Uses the MERCURY6 machine-type value passed by the vendor U-Boot.

openipc/infinity6c_config

infinity6c_nand_configSet infinity6c NAND environment layout +3/-0

Set infinity6c NAND environment layout

• Places the environment after the SDK's CIS and two boot copies.

openipc/infinity6c_nand_config

infinity6e_configSet the infinity6e machine type +2/-0

Set the infinity6e machine type

• Matches the vendor machine-type value for infinity6e targets.

openipc/infinity6e_config

nand_configEnable SigmaStar NAND and UBI boot +21/-0

Enable SigmaStar NAND and UBI boot

• Replaces NOR options with SPI NAND, UBI, NAND environment, partition, and separate kernel-volume settings.

openipc/nand_config

ssc029a_configSelect SSC029A +2/-0

Select SSC029A

• Sets the Iford SSC029A target and product identifier.

openipc/ssc029a_config

ssc029b_configSelect SSC029B +2/-0

Select SSC029B

• Sets the Iford SSC029B target and product identifier.

openipc/ssc029b_config

ssc029c_configSelect SSC029C +2/-0

Select SSC029C

• Sets the Iford SSC029C target and product identifier.

openipc/ssc029c_config

ssc034a_configSelect SSC034A +2/-0

Select SSC034A

• Sets the Ifliegen SSC034A target and product identifier.

openipc/ssc034a_config

ssc034b_configSelect SSC034B +2/-0

Select SSC034B

• Sets the Ifliegen SSC034B target and product identifier.

openipc/ssc034b_config

ssc30kd_configSelect SSC30KD +2/-0

Select SSC30KD

• Sets the infinity6e SSC30KD target and product identifier.

openipc/ssc30kd_config

ssc30kq_configSelect SSC30KQ +2/-0

Select SSC30KQ

• Sets the infinity6e SSC30KQ target and product identifier.

openipc/ssc30kq_config

ssc325_configSelect SSC325 +2/-0

Select SSC325

• Sets the infinity6 SSC325 target and product identifier.

openipc/ssc325_config

ssc325de_configSelect SSC325DE +2/-0

Select SSC325DE

• Sets the infinity6 SSC325DE target and product identifier.

openipc/ssc325de_config

ssc327de_configSelect SSC327DE +2/-0

Select SSC327DE

• Sets the infinity6 SSC327DE target and product identifier.

openipc/ssc327de_config

ssc333_configSelect SSC333 +2/-0

Select SSC333

• Sets the infinity6b0 SSC333 target and product identifier.

openipc/ssc333_config

ssc335_configSelect SSC335 +2/-0

Select SSC335

• Sets the infinity6b0 SSC335 target and product identifier.

openipc/ssc335_config

ssc335de_configSelect SSC335DE +2/-0

Select SSC335DE

• Sets the infinity6b0 SSC335DE target and product identifier.

openipc/ssc335de_config

ssc337_configSelect SSC337 +2/-0

Select SSC337

• Sets the infinity6b0 SSC337 target and product identifier.

openipc/ssc337_config

ssc337de_configSelect SSC337DE +2/-0

Select SSC337DE

• Sets the infinity6b0 SSC337DE target and product identifier.

openipc/ssc337de_config

ssc338q_configSelect SSC338Q +2/-0

Select SSC338Q

• Sets the infinity6e SSC338Q target and product identifier.

openipc/ssc338q_config

ssc375_configSelect SSC375 +2/-0

Select SSC375

• Sets the Ifado SSC375 target and product identifier.

openipc/ssc375_config

ssc377_configSelect SSC377 +2/-0

Select SSC377

• Sets the infinity6c SSC377 target and product identifier.

openipc/ssc377_config

ssc377d_configSelect SSC377D +2/-0

Select SSC377D

• Sets the infinity6c SSC377D target and product identifier.

openipc/ssc377d_config

ssc377de_configSelect SSC377DE +2/-0

Select SSC377DE

• Sets the infinity6c SSC377DE target and product identifier.

openipc/ssc377de_config

ssc377qe_configSelect SSC377QE +2/-0

Select SSC377QE

• Sets the infinity6c SSC377QE target and product identifier.

openipc/ssc377qe_config

ssc378de_configSelect SSC378DE +2/-0

Select SSC378DE

• Sets the infinity6c SSC378DE target and product identifier.

openipc/ssc378de_config

ssc378qe_configSelect SSC378QE +2/-0

Select SSC378QE

• Sets the infinity6c SSC378QE target and product identifier.

openipc/ssc378qe_config

ssd201_configSelect SSD201 +2/-0

Select SSD201

• Sets the infinity2m SSD201 target and product identifier.

openipc/ssd201_config

ssd202d_configSelect SSD202D +2/-0

Select SSD202D

• Sets the infinity2m SSD202D target and product identifier.

openipc/ssd202d_config

ssr621q_configSelect SSR621Q +2/-0

Select SSR621Q

• Sets the infinity2m SSR621Q target and product identifier.

openipc/ssr621q_config

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

qodo-free-for-open-source-projects Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

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

Grey Divider


Action required

1. Winbond NAND crashes during detection ✓ Resolved
Description
board_nand_init() passes the chip's Winbond or GigaDevice ID to nand_scan_ident(), whose
manufacturer lookup has no entry for either ID and later dereferences the missing description. A
board fitted with either explicitly handled SPI NAND family reaches that dereference during startup,
before NAND can be registered.


Remediation recommended

2. Infinity6c SPI NAND path ships with no NAND check 📘 Rule violation ☼ Reliability
Description
ms_spinand.c selects a separate sn_program_load and chip-select path under
CONFIG_SS_I6C_FAMILY, which is the only route infinity6c NAND takes, and it also changes the
cache-read mode for that family. CLAUDE.md states there is no infinity6c or infinity2m NAND testing
("nothing is published to compare against") and lists no NAND run for the ssc377 parts, so this
branch has never been exercised for NAND writes on those dies. A bad program load or cache read on
infinity6c would go unnoticed until a field board is flashed, since the published build.sh NAND
targets for ssc377* ship with it.
Code

drivers/mtd/nand/raw/ms_spinand.c[R330-332]

+#ifdef CONFIG_SS_I6C_FAMILY
+/* A page load, the chip select held by hand around it; the FSP fires first */
+static int sn_program_load(u16 column, const u8 *buf, unsigned int len)
Evidence
Rule 9 requires verification of affected flash paths. The infinity6c-specific sn_program_load
(framed chip select, FSP fired before BDMA) and the normal-mode cache read have no NAND test in the
PR's verification notes, which only report ssc325de, ssc337de and ssc338q NAND (none of them
infinity6c or infinity2m).

CLAUDE.md: Verify Boot, Persistence, and Affected Peripherals: CLAUDE.md: Verify Boot, Persistence, and Affected Peripherals: CLAUDE.md: Verify Boot, Persistence, and Affected Peripherals: CLAUDE.md: Verify Boot, Persistence, and Affected Peripherals
drivers/mtd/nand/raw/ms_spinand.c[330-341]

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 infinity6c branch of the SPI NAND driver (`sn_program_load` with software chip select, and `sn_cache_read` in QSPI normal mode) has no recorded NAND verification. Its only NAND evidence in the PR is for other dies.
## Fix Focus Areas
- drivers/mtd/nand/raw/ms_spinand.c[330-341]
- drivers/mtd/nand/raw/ms_spinand.c[184-189]
- CLAUDE.md ("The later dies" section, SPI NAND bullet)
## Recommended Fix
On an infinity6c qemu machine (or the per-die machine branch), boot a `ssc377-nand` image and run `nand erase`, `nand write`, and `nand read` against the raw flash file, then `cmp`. Record the result in CLAUDE.md alongside the existing ssc337de checks, or mark the infinity6c NAND path as unverified.

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


3. 512 MiB boards get 64 MiB boot values 🐞 Bug ≡ Correctness
Description
ss_mem_table has no 512 MiB row in its infinity6c branch, so ss_set_mem_env() reaches the
zero-valued fallback and sets the 64 MiB memlx and memsz values. When the IPL reports 512 MiB on
an infinity6c board, those values enter the kernel's LX_MEM and mma_heap boot arguments despite
the larger detected RAM.
Code

arch/arm/mach-sigmastar/soc.c[R169-174]

+#elif defined(CONFIG_SS_I6C_FAMILY) || defined(CONFIG_SS_INFINITY2M) || \
+      defined(CONFIG_SS_IFADO)
+	/* infinity2m has no OpenIPC values; its kernel wants 1 MiB alignment */
+	{ 256, "0x10000000", "0x0A000000" },
+	{ 128, "0x8000000",  "0x4600000" },
+	{ 0,   "0x4000000",  "0x2000000" },
Evidence
The die reads the IPL's DDR-size register, but its table contains only 256 MiB, 128 MiB, and a
fallback row. The selection loop reaches that fallback for 512 MiB, and the default boot arguments
consume both resulting variables.

arch/arm/mach-sigmastar/soc.c[58-74]
arch/arm/mach-sigmastar/soc.c[169-190]
include/configs/openipc-common.h[53-65]
CLAUDE.md[503-511]

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

## Issue description
Infinity6c can report 512 MiB of DDR, but its memory-argument table falls through to the 64 MiB row.
## Fix Focus Areas
- arch/arm/mach-sigmastar/soc.c[169-190]
## Recommended Fix
Add the infinity6c 512 MiB `memlx` and `memsz` values from the applicable vendor configuration. Avoid silently choosing the smallest row for any other detected size the table does not support.

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


4. Valid NAND firmware can fail its scan ✓ Resolved
Description
The new SPI NAND read path reports corrected ECC through a positive read result, but
ubi_marker_present() accepts the first UBI header only when mtd_read() returns exactly zero.
With a correctable bitflip in that header—or a factory-bad first eraseblock—the newly enabled NAND
firmware scan declares the UBI partition absent before UBI can perform its normal scan.

View review recommended (3)
5. Iford SD clock never leaves the boot clock ✓ Resolved
Description
The Iford branch of sd_plat_init() never writes SCGP_SD_CLK (SCGPCTRL bank 0x1135 reg 0x25), the
Iford-only define this PR adds for it. Instead it sets BIT(7) in SD_CLKGEN (CLKGEN 0x43), outside
the SD_CLKGEN_MASK the clock code uses, while the 6c, 6e and CHIPTOP branches all do
setbits_le16(SCGP_SD_CLK, SCGP_SD_BOOTCLK). On real Iford silicon the SDIO0 clock can stay on its
boot source, so card init and SD recovery fail; qemu does not model this gate.

6. SPI NAND DMA path differs from NOR on i6 🐞 Bug ≡ Correctness
Description
ms_spinand's bdma_start() always writes zero to BDMA_PATH2, while ms_sflash sets the
channel-zero-to-MIU bit (0x8000) on infinity6, infinity6b0, and infinity6e. On those dies, NAND
page and SNI reads and program page loads run without the routing used by the NOR driver for the
same hardware, leaving ssc325de/ssc337de/ssc338q transfers unproven on silicon because qemu
ignores the register.
Code

drivers/mtd/nand/raw/ms_spinand.c[R273-277]

+static void bdma_start(u16 path, u32 src, u32 dst, u32 len)
+{
+	writew(0, BDMA_CTRL);
+	writew(path, BDMA_PATH);
+	writew(0, BDMA_PATH2);
Evidence
Both drivers define the SPI-to-MIU DMA path used for flash reads, but ms_spinand.c writes zero to
BDMA_PATH2 unconditionally, including during SNI probing. ms_sflash.c documents and writes
0x8000 to route channel zero to the MIU on infinity6, infinity6b0, and infinity6e; it clears the
register only for infinity2m, Ifado, and the I6C family. The CLAUDE.md peripheral table also lists
BDMA register 3 as 0x8000 for those three dies, though its infinity6c entry differs from the NOR
driver's behavior.

drivers/mtd/spi/ms_sflash.c[162-180]
drivers/mtd/nand/raw/ms_spinand.c[273-285]
CLAUDE.md[345-349]
drivers/mtd/nand/raw/ms_spinand.c[94-101]
drivers/mtd/nand/raw/ms_spinand.c[273-284]
drivers/mtd/nand/raw/ms_spinand.c[296-327]
drivers/mtd/nand/raw/ms_spinand.c[629-637]
drivers/mtd/spi/ms_sflash.c[99-105]
drivers/mtd/spi/ms_sflash.c[163-172]

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

## Issue description
`ms_spinand` clears `BDMA_PATH2` for every die, while `ms_sflash` sets it to `0x8000` for the same SPI-to-MIU hardware on infinity6, infinity6b0, and infinity6e. Resolve the per-die setting for NAND transfers, including reads and program loads.
## Fix Focus Areas
- drivers/mtd/nand/raw/ms_spinand.c[273-285]
- drivers/mtd/spi/ms_sflash.c[162-180]
## Recommended Fix
Verify the per-die `BDMA_PATH2` values against the vendor DMA paths for both cache reads and program loads. Put the verified setting in `mach/sigmastar.h` (for example, as `SS_BDMA_PATH2`) or a shared helper, and use it in both drivers so NAND applies the required routing on infinity6, infinity6b0, and infinity6e. Reconcile the `CLAUDE.md` table's infinity6c value with the resulting code, then exercise the affected dies with DMA routing enforced.

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


7. NAND with an uncommon spare size panics at boot ✓ Resolved
Description
board_nand_init() leaves chip->ecc.layout unset for SNI spare sizes other than 64 bytes, while
nand_scan_tail() calls BUG() when it cannot select a default layout for an OOB size outside
8/16/64/128. A 4 KiB-page part with a 256-byte spare passes the driver's geometry check, then
reaches that BUG() on every boot.

Grey Divider

Tip of the day
💡 Did you know, you can hide the parts of a finding you never read, like the evidence or the agent prompt

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

ms_spinand hands the core a SPI NAND's own ID, Winbond 0xEF or
GigaDevice 0xC8, neither in nand_manuf_ids: the manufacturer
description is then NULL, and nand_get_flash_type() prints its name.
With the default log level that print is compiled out, so qemu's
W25N01 and GD5F parts identified; a debug build would fault.

Reported by Qodo on #107.
The driver sets its own ECC layout for a 64-byte spare and leaves 128
to the core's default; for any other spare the SNI gives (a 4 KiB part
with 256 bytes, say) nand_scan_tail() reaches BUG(). Such a part is now
reported and not registered.

BDMA_PATH2 stays 0 on every die, as the vendor's SPI NAND driver
(drvSPINAND_common_hal.c) writes it, unlike its NOR flash_isp: say so.

Reported by Qodo on #107.
ubi_marker_present() read offset 0 of the ubi partition only. If that
eraseblock is factory-bad, recovery writes the UBI image past it (nand
write skips bad blocks), the marker stays unseen, and every boot goes
back to recovery. It now reads the first good eraseblock, where UBI
keeps an EC header as on every good one, and takes a corrected read
(-EUCLEAN) as data.

Reported by Qodo on #107.
…der it

ss_set_mem_env() took the 64 MiB row for any size without an exact
row: a 512 MiB infinity6c got LX_MEM 64 MiB, as the vendor's
board_late_init() does. It now takes the largest row not above the
DDR's size (256 MiB there); exact sizes keep their rows.

Reported by Qodo on #107.
Iford's hal_card_platform.c sets SC_GP_CTRL (bank 0x1135) reg 0x25 bit
7, taking SDIO0's clock off the 12 MHz boot clock, and CLKGEN 0x43 to
bit 7 alone; each clock change then clears the gate and the select and
sets bit 6 again. The Iford path set CLKGEN bit 7 only and never the
SC_GP_CTRL bit. qemu models neither gate; SD detect, FAT load and raw
read-back still pass.

Reported by Qodo on #107.
SD0 as Ifliegen's hal_card_platform.c and its board's mmc0 set it up:
PADGPIO CLK at 0x0F, CMD and D0-D3 from 0x10, card detect at 0x16
(PAD_PM_SD_CDZ, low with a card in), PADTOP 0x61 SD and CDZ mode, card
power from PAD_FUART_RTS (PADGPIO 0x34, low active), the clock as
Iford's but with SC_GP_CTRL at bank 0x1133, and the host's MCG off (reg
0x3E bit 14). Ifliegen builds with SD now.

qemu ssc034a/ssc034b (mstar-06's SD model): card detect, 4-bit bus, FAT
load with the file's CRC, raw write and read-back.
ssc034a-nand and ssc034b-nand. sigmastar-image.py --ifliegen-sni lays
out what the SDK's image.mk and spinand.squashfs.tfa.partition.config
would: the CIS in each of ten blocks (the SNIB and the part's SNIF, the
PNI, the flash list, with snigenerator's boot blocks and CRCs), BOOT at
0x140000 (IPL and IPL_CUST three blocks each, TF-A's SP_MIN, our uImage
in a 1 MiB UBOOT) and BOOT_BAK at 0x320000, the environment at 0x500000,
UBI from 0x540000. The IPL takes its timeouts from the SNIF, so the CIS
carries the flash list's W25N01GV (record 57); the SDK's generic one
has none and fails to load. The stages and tables are the SDK's
(board/ifliegen/boot/spinand). ms_spinand takes Iford's BDMA path.

qemu ssc034a/ssc034b: the chain from NAND, nand erase/write/read against
the raw file, env across reset, and mstar-06's SDK 4.9.84 kernel from an
OpenIPC UBI (kernel, rootfs, rootfs_data) to a shell, its five
partitions listed, root through the ubiblock override.
@dimerr
dimerr merged commit 2105515 into openipc-sigmastar Nov 7, 2026
10 checks passed
@dimerr
dimerr deleted the sigmastar/more-dies branch November 7, 2026 14:26
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