Repository navigation
gk710x: SD recovery, boot-image swap in the flash driver, eFuse table as on cameras - #45
Conversation
The boot ROM reads the boot image as raw chip bytes, while the controller packs every word MSB first: whatever goes through it comes back as it went in, but lands on the chip byte-swapped. The release image is in chip order, and cmd/sf.c swapped it back before sf write or sf update. Any other writer (SD recovery, spi_flash_write() from anywhere) put it on the flash swapped twice, and every reader saw the boot image in the controller's order rather than as the file. Move it into gk_sflash.c, for every caller, both ways: from offset 0 to the end of the boot image (its header table plus the U-Boot length the header gives) data is swapped on write and on read. The window is the image found at offset 0 at probe; a write at 0 that starts with the swapped magic opens it as long as that image, however the caller splits the rest, and any other write at 0 closes it. The table is walked entry by entry, as a register value of 0 is not its end. cmd/sf.c is mainline's again. Under qemu-hisilicon gk7102 and gk7102s: the image written by SD recovery at 0 is byte-for-byte the release file on the flash and boots; sf read of it gives the file's CRC32; on the next boot the "already on the flash" check matches it.
On a GK7102C camera with no Ethernet, designware_initialize() finds no
PHY ("Could not get PHY for dwmac.9000e000") and leaves phydev NULL.
The first network command (the fwupd/recovery flow) then dereferenced it
in designware_eth_init() and _dw_eth_halt(): a data abort and a reset
loop.
Fail eth init with -ENODEV and skip phy_shutdown() when there is no PHY.
The qemu-hisilicon machines always have the PHY, so this ran only in
the boots where it does nothing (gk7102 and gk7102s to login).
A GK7102 camera (rb ov9712, GD25Q128) did not start with our U-Boot. Its own boot header, and those of two more GK7102 flash dumps (vendor U-Boots of 2016 and 2017), differ from the SDK prebuilts' in the eFuse lines only: they never write 0xFF39C119 to 0x6000B100, and after starting the eFuse load (0x6000B104 = 1) they wait for it to finish (0x6000B104 == 3). Do the same in both tables. The GK7102 header is now word for word that camera's: header words and all 62 table entries. qemu-hisilicon does not model the eFuse block, so silicon has to confirm it. GK7101 follows the same SDK change; no GK7101 field dump is at hand.
…ecovery The file is meant to be the same on every branch; this one had drifted from openipc-hisilicon's. Take that one, together with the recovery change proposed there (OpenIPC/u-boot recovery/wrapper-payload), so the two are byte for byte the same: - script.txt on the card or stick still runs first; - otherwise every *.img in its root, in directory order, that is a valid uImage (magic, header CRC, data CRC) whose load address and size fit the flash, on an erase boundary, gets its payload written there -- never the wrapper header. That covers U-Boot at 0 as well; - an image already on the flash is skipped, and the boot goes on; - the split firmware.bin path and the per-name lookups are gone; the NAND path is as it was. It builds here only with CONFIG_MMC, which the next commit enables.
A GK7102C camera has no Ethernet, so TFTP recovery cannot bring it back; the SD card can (common/openipc.c). - arch/arm/mach-gk710x/sdhci.c: GK7101/GK7102 have a standard SDHCI at 0x60002000. The GK710xS has it at 0x90000000 in the vendor halfword layout, with registers moved and bits swapped; the accessors map every SDHCI register through a table taken from the S HAL. The version reads SDHCI_SPEC_200, and the base clock comes from the RCT SD PLL and scaler. - gpio_map.c: also set the map's SD pins and SD power pin. - openipc_config: MMC, SDHCI, DOS partitions, FAT; LTO and a few unused commands off to stay in the 256 KiB boot partition (gk7101/gk7102 231892, gk7101s 222548, gk7102s 222808 bytes). Under qemu-hisilicon gk7102 and gk7102s (the latter on a GK7102C flash dump), from an MBR + FAT32 card, two boots with the card left in: the U-Boot, kernel and rootfs images are written at their load addresses and boot to login; a bad data CRC, a non-uImage, an image past the flash end and one off an erase boundary are skipped; on the second boot all three are already on the flash and the saved environment loads.
PR Summary by QodoEnable GK710x SD recovery and correct boot-image flash handling
AI Description
Diagram
High-Level Assessment
Files changed (13)
|
Code Review by Qodo
1.
|
| CONFIG_MMC=y | ||
| CONFIG_MMC_SDHCI=y | ||
| # CONFIG_MMC_HW_PARTITIONING is not set | ||
| CONFIG_CMD_MMC=y | ||
| CONFIG_DOS_PARTITION=y | ||
| CONFIG_FS_FAT=y |
There was a problem hiding this comment.
3. Failed scripts block image recovery 🐞 Bug ≡ Correctness
recovery_run_script records the command result in ret but returns success regardless of whether execution failed. With SD recovery now enabled, a failing script.txt on the card stops the subsequent *.img search and is reported as completed recovery.
Agent Prompt
## Issue description
A failed SD recovery script is treated as successful and prevents image recovery.
## Fix Focus Areas
- common/openipc.c[524-556]
- common/openipc.c[559-575]
- openipc/openipc_config[83-88]
## Recommended Fix
Propagate script execution and read failures distinctly from successful execution and an absent script; ensure `recovery_try` does not report a failed script as successful recovery.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
There was a problem hiding this comment.
Partly by design: when script.txt is present, the card author has chosen a script over the images, so a failed script still ends recovery. It is now reported as failed (9e09c42).
…iled script - script.txt was read to CONFIG_SYS_LOAD_ADDR whatever its size; one larger than the free RAM below the stack would have run over U-Boot. It now gets the same bound as the images (recovery_ram_room()). - a uImage wrapper with a data size of 0 passed every check and was then read with length 0, which the FAT read takes as "the rest of the file", past the RAM bound. It is skipped now. - a script that fails is reported as failed. It still ends recovery: the card author chose a script over the images. Under qemu-hisilicon gk7102: a 0-length wrapper in front of 2 MiB is "has no data, skipped", and the rest of the card recovers as before. Reported by Qodo on #44, #45 and #46.
…iled script - script.txt was read to CONFIG_SYS_LOAD_ADDR whatever its size; one larger than the free RAM below the stack would have run over U-Boot. It now gets the same bound as the images (recovery_ram_room()). - a uImage wrapper with a data size of 0 passed every check and was then read with length 0, which the FAT read takes as "the rest of the file", past the RAM bound. It is skipped now. - a script that fails is reported as failed. It still ends recovery: the card author chose a script over the images. Under qemu-hisilicon gk7102: a 0-length wrapper in front of 2 MiB is "has no data, skipped", and the rest of the card recovers as before. Reported by Qodo on #44, #45 and #46.
The window swapped on write is the boot image's span. A programmer's whole-chip dump written in one go at 0 (sf write, or a recovery image at 0) is in chip order throughout, so everything past U-Boot -- env, kernel, rootfs -- landed swapped twice. A write at 0 that starts with the swapped magic is now swapped over its whole length when it is longer than the boot image, as cmd/sf.c did before. The read window stays the boot image. Under qemu-hisilicon gk7102: a recovery image holding a 16 MiB GK7102 camera dump, at 0, leaves the flash byte for byte the dump. Reported by Qodo on #45.
The SD pins came from the default map even with gpiomap unset. On the GK7101/GK7102 that default (v2) is a guess, and its SD pins are a v1 board's PHY reset, audio clock and external-PHY data lines -- v1 boards have no SD. They are now set on the GK710xS, which has one map, and on the GK7101/GK7102 once gpiomap names the board's. CLAUDE.md: what a whole-chip dump through sf write, sf update and sf read comes to. Reported by Qodo on #45.
…iled script - script.txt was read to CONFIG_SYS_LOAD_ADDR whatever its size; one larger than the free RAM below the stack would have run over U-Boot. It now gets the same bound as the images (recovery_ram_room()). - a uImage wrapper with a data size of 0 passed every check and was then read with length 0, which the FAT read takes as "the rest of the file", past the RAM bound. It is skipped now. - a script that fails is reported as failed. It still ends recovery: the card author chose a script over the images. Under qemu-hisilicon gk7102: a 0-length wrapper in front of 2 MiB is "has no data, skipped", and the rest of the card recovers as before. Reported by Qodo on #44, #45 and #46.
cmd/sf.cis mainline again).sf readof U-Boot gives the release file byte for byte, so SD recovery's already-on-flash check matches U-Boot too.0x6000B100, and a wait for0x6000B104 == 3. A GK7102 (rb ov9712, GD25Q128) did not start with the SDK's lines. The GK7102 header is now word for word that camera's. qemu doesn't model the eFuse block, so silicon has to confirm.common/openipc.cas on openipc-hisilicon, with the generic recovery (the openipc-hisilicon PR fromrecovery/wrapper-payload).Tested in qemu-hisilicon gk7102 and gk7102s (on a GK7102C dump), with the qemu-hisilicon SD model PR: two boots with the card left in. U-Boot, kernel and rootfs were written, then found already on the flash; bad images were skipped; both boots reached login.