Repository navigation
allwinner: add U-Boot for V831 and V833 - #65
Conversation
The firmware scan, recovery and boot-limit failsafe of the openipc-hisilicon branch, for the Allwinner V831/V833: common/openipc.c and include/openipc.h as on openipc-novatek and openipc-anyka, unchanged. CONFIG_OPENIPC builds it; PRODUCT_SOC and PRODUCT_SOCMODEL name the target in the environment.
LzmaTools.c was guarded by CONFIG_LZMA, so with SPL_LZMA alone the SPL's spl_load_legacy_img() did not link (undefined lzmaBuffToBuffDecompress). CONFIG_IS_ENABLED(LZMA), as later mainline has it.
One Cortex-A7 with the H6's peripherals, clocks and memory map, and the DDR in the package (V831: 64 MiB DDR2, V833: 128 MiB DDR3): a new SoC, MACH_SUN8I_V831, selecting SUN50I_GEN_H6, with its own SPL in place of the vendor's boot0, OP-TEE and boot package. - DRAM: dram_sun8i_v831.c is the vendor boot0's DRAM library (libdram, shipped as a binary object), translated to C function for function and register write for register write. It drives the D1/T113 controller of mainline's dram_sun20i_d1.c, at 0x04002000/0x04003000, in an older revision of the library (timings computed and stored back, DDR2/DDR3 scan). Checked under QEMU against the vendor's boot0 on a camera's flash: with the V831's and with the V833's parameters every DRAM controller, PHY, PLL_DDR, MBUS, DRAM clock and ZQ register is equal after both. The size it finds is checked with get_ram_size(). - Clocks as boot0 sets them: PLL_PERI0 1.2 GHz (2X), AHB 200, APB1 100 MHz, the MBUS reset released (its clock follows the DRAM's), CPU 816 MHz after the DDR, as the vendor U-Boot sets it. - SPL from SPI NOR: the H6's SPI0 on the H3's pins (PC0-PC3, function 4), and an LZMA legacy image (U-Boot does not fit the 256 KiB boot partition unpacked). The images boot from SPI NOR alone, so a valid eGON header means SPI: QEMU's boot ROM does not write the boot-media byte. - UART0 on PH9/PH10 (function 5). The SPL's BSS inside 64 MiB. - PSCI 1.0 for the vendor kernels, which expect OP-TEE's: version, features, CPU_OFF, SYSTEM_RESET (the watchdog). One core, no CPU_ON. - U-Boot's device tree (sun8i-v831.dtsi): the CCU is the H6's for every gate U-Boot uses (vendor clk-sun8iw19.h), so it maps to the H6 table; a V831 pinctrl table; SPI as the H3's, MMC as the H6's, the EMAC as the A64's (no internal PHY). - No binman for this SoC: it needs pylibfdt, which current setuptools no longer builds for 2022.10; build.sh puts the image together.
OpenIPC's V83x kernels (Linux 4.9) carry no device tree; the vendor
U-Boot gives them its own. v83x-kernel.dts is that tree: the Tina V83x
SDK's reference board over the kernel's sun8iw19p1.dtsi, flattened, with
what the vendor U-Boot changes in it before booting from SPI NOR, traced
under QEMU from a camera's flash: SPI0 enabled (the flash, the root
filesystem); OP-TEE's memreserve dropped. It is gzipped into U-Boot
(12 KiB), unpacked at misc_init_r() to ${fdtaddr}, and a plain uImage
boots with it (boot/image-fdt.c, as on openipc-novatek). ft_board_setup()
sets /dram/dram_para2 to the size, as the vendor does.
The board also clocks the RMII PHY (EPHY_25M, the vendor tree's
use_ephy25m) and runs the OpenIPC helper from misc_init_r().
Under QEMU an OpenIPC allwinner-v83x kernel boots on it to a shell:
PSCIv1.0, HYP mode, cmdlinepart on spi0.0, SquashFS root on mtdblock3,
sunxi-gmac pings the host, reboot comes back through the SPL.
build.sh builds u-boot-v831-nor.bin and u-boot-v833-nor.bin: the SPL (eGON.BT0) padded to 0x8000, then U-Boot as an LZMA legacy image, ~170 KiB in all; it fails a build over the 256 KiB boot partition or with an SPL over 32 KiB. The configuration is openipc/openipc_config plus the SoC's fragment, which carries the vendor's dram_para words: the V831 reference boards' (DDR2, 528 MHz, fixed geometry) and the V833 lindenis board's (DDR3, 792 MHz, scanned). include/configs/openipc-common.h is openipc-novatek's environment with this family's parameters: vendor "allwinner", mem= the whole DDR, the kernel staged at 0x41000000, the flash's MTD name spi0.0, console ttyS0. Under QEMU (qemu-bench -M v831/v833) both images reach the autoboot prompt, and a second boot loads the environment the first saved.
The boot ROM tries the SD card before the SPI NOR: an eGON.BT0 at sector 16 wins. build.sh now also builds u-boot-<soc>-mmc.bin, the NOR image's layout with an SPL that loads U-Boot from the card (openipc/mmc_config: SPL_MMC; U-Boot 32 KiB after the SPL, sunxi's default), to be written to the card at 8 KiB. It is the unbricking path: - Booted from the card, `source` is `fatload mmc 0` for that boot (as after srcmmc, not saved), so ub, ur, uk and fwupd take their files from the card's FAT partition and write them to the NOR. - The environment stays in the SPI NOR. sunxi's env_get_location() picks FAT or MMC after an MMC boot, neither of which is built in, and env_init() failed with -ENODEV before the console came up: fall back to the SPI flash. - The SPL's MMC raw loader read legacy images to their load address as they are; an LZMA one is now read whole and unpacked by spl_load_legacy_img(). Under qemu-bench (whose ROM stand-in now tries the card first and writes the boot-media byte): both SoCs boot from a card with an erased NOR, and a second boot loads the environment the first saved. A card with the -mmc image and u-boot-v831-nor.bin, uImage.v831, rootfs.squashfs.v831 unbricks an erased NOR: run ub, run fwupd, then the NOR boots the kernel to its root without the card.
PR Summary by QodoAdd OpenIPC U-Boot support for Allwinner V831 and V833
AI Description
Diagram
High-Level Assessment
Files changed (43)
|
Code Review by Qodo
1. Target builds fail without model names
|
- The kernel device tree advertised three PSCI CPU idle states, which U-Boot's PSCI does not implement (no CPU_SUSPEND): left out of v83x-kernel.dts, as is the cpu node's reference to them. - The SPI flash fallback in sunxi's env_get_location() applied to every sunxi board with ENV_IS_IN_SPI_FLASH, which would have moved theirs to the NOR after an MMC or FEL boot: V831/V833 only. - DRAM_SUN8I_V831_TPR3 went nowhere: in the vendor library dram_tpr3 carries the DRAM supply voltages for dram_vol_set(), the PMIC step that is not translated. The option is gone; the struct keeps the word, so the parameter block is still the vendor's. Both SoCs' NOR and SD images pass the two-boot smoke test, and the OpenIPC kernel boots on the new device tree as before.
U-Boot for the Allwinner V831 (64 MiB DDR2 in the package) and V833 (128 MiB DDR3): mainline v2022.10 with the same OpenIPC boot layer as
openipc-novatek(identicalcommon/openipc.c), as a new mainline sunxi SoC,MACH_SUN8I_V831(H6-style peripherals, clocks and memory map). It has its own SPL, so no vendor boot0, OP-TEE or boot package is carried. The base branch isv2022.10, asopenipc-novatek's was.Two images per SoC, the same layout:
0x000000x080000x400000x50000, as on the other familiesu-boot-<soc>-nor.bin(~170 KiB) is written at flash offset 0.u-boot-<soc>-mmc.binis for unbricking. Write it to an SD card at 8 KiB (dd ... bs=1k seek=8); the boot ROM tries the card before the flash. Booted from the card,sourceisfatload mmc 0, sorun ubandrun fwupdtakeu-boot-<soc>-nor.bin,uImage.<soc>androotfs.squashfs.<soc>from its FAT partition. The environment stays in the NOR.DRAM
libdram, shipped as a binary object) is translated to C function for function:arch/arm/mach-sunxi/dram_sun8i_v831.c. It is an older revision of mainline's D1/T113dram_sun20i_d1.c, at other addresses.dram_para, fromsys_config.fex.Kernel hand-off
allwinner-v83xkernels carry no device tree. U-Boot boots them with the vendor one it carries, gzipped (12 KiB): the Tina SDK's reference board, with the changes the vendor U-Boot makes before booting from NOR, traced under qemu.${fdtaddr}, the same smallboot/image-fdt.cchange as onopenipc-novatek.Small mainline patches
lib/lzma/LzmaTools.c: the SPL link fix forSPL_LZMA.common/spl/spl_mmc.c: unpack an LZMA image from the card.env_get_location(): fall back to the SPI flash after an MMC boot.ARCH_SUNXIwithout binman for this SoC: pylibfdt no longer builds with current setuptools, sobuild.shputs the image together.CLAUDE.mdhas the boot flow, the patched mainline files and what was verified where.Verified under qemu-bench
v831/v833:allwinner-v83xkernel (v83x.generic.config) boots on a SquashFS root to a shell: PSCI 1.0,cmdlinepartonspi0.0with the OpenIPC partitions, root onmtdblock3. Itssunxi-gmacpings the host, andrebootcomes back through the SPL.mmc infoandfatls,saveenvandreset, the boot-limit failsafe, TFTP and SD unbricking of an erased flash.Not verified on silicon yet.
Keep a flash backup and a programmer (or the SD card) at hand.
CI (
build-allwinner.yml) comes in the PR againstopenipc. Its-mmcsmoke legs need OpenIPC/qemu-bench#204, the boot ROM stand-in booting from the SD card.