Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 31 additions & 16 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,20 @@ jobs:
strategy:
fail-fast: false
matrix:
board: [hi3518ev200, hi3516cv200]
# `name` is what gets published, `config` is the u-boot board config,
# and `reg` is the DDR register table dd'd in at offset 64 of
# mini-boot.bin. They are separate because hi3518ev200 ships twice:
# its stock table programs the memory controller for DDR2
# (0x20111050 = 0x15) and a board built with DDR3 never comes up on
# it -- the SPL runs, DDR does not, and the camera looks bricked.
# See OpenIPC/firmware#2299. reg_info_hi3516cv200.bin is the DDR3
# table for this silicon; it is byte-identical to the one read out of
# the vendor bootloader of the hi3518ev200 board in that issue, so it
# is shared rather than copied.
include:
- { name: hi3518ev200, config: hi3518ev200, reg: reg_info_hi3518ev200.bin }
- { name: hi3518ev200-ddr3, config: hi3518ev200, reg: reg_info_hi3516cv200.bin }

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

1. Ddr3 selection remains undocumented 📎 Requirement gap ⚙ Maintainability

The PR publishes a new hi3518ev200-ddr3 artifact but adds no installation guidance for checking
0x20111050 or choosing DDR2 versus DDR3 images. Users can therefore flash the wrong DRAM variant
and leave the device unable to boot.
Agent Prompt
## Issue description
The newly published `hi3518ev200-ddr3` variant lacks user-facing installation guidance for determining the board's DRAM type and selecting the matching image.

## Issue Context
Document running `md.l 0x20111050 1` from a working HiSilicon U-Boot, explain that a final hexadecimal digit of `5` means DDR2 and `6` means DDR3, and map those results to the standard and `-ddr3` artifacts respectively.

## Fix Focus Areas
- README[24-31]
- .github/workflows/build.yml[15-27]

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

- { name: hi3516cv200, config: hi3516cv200, reg: reg_info_hi3516cv200.bin }

steps:
- name: Install 32-bit libs
Expand Down Expand Up @@ -53,16 +66,16 @@ jobs:
- name: Build
run: |
export PATH="$PWD/toolchain/arm-hisiv510-linux/bin:$PATH"
make ${{ matrix.board }}_config
cp reg_info_${{ matrix.board }}.bin .reg
make ${{ matrix.config }}_config
cp ${{ matrix.reg }} .reg
make CROSS_COMPILE=arm-hisiv510-linux- -j$(nproc)
make CROSS_COMPILE=arm-hisiv510-linux- mini-boot.bin
cp mini-boot.bin u-boot-${{ matrix.board }}-universal.bin
cp mini-boot.bin u-boot-${{ matrix.name }}-universal.bin
# The UART-recovery image: same sources, no DDR training, small
# enough for the boot ROM to accept. Built second because it
# cleans the compressed dir (the two variants share object names).
make CROSS_COMPILE=arm-hisiv510-linux- mini-boot-recovery.bin
cp mini-boot-recovery.bin u-boot-${{ matrix.board }}-recovery.bin
cp mini-boot-recovery.bin u-boot-${{ matrix.name }}-recovery.bin

- name: Check partition fit
run: |
Expand All @@ -71,8 +84,8 @@ jobs:
# overflows into env at offset 0x40000 and bricks the device
# on upgrade. Mirrors OpenIPC/firmware Makefile CHECK_SIZE.
LIMIT_KB=256
for FILE in u-boot-${{ matrix.board }}-universal.bin \
u-boot-${{ matrix.board }}-recovery.bin; do
for FILE in u-boot-${{ matrix.name }}-universal.bin \
u-boot-${{ matrix.name }}-recovery.bin; do
SIZE_KB=$(($(stat -c %s "$FILE") / 1024))
echo "- $FILE: [${SIZE_KB}KB/${LIMIT_KB}KB]"
if [ "$SIZE_KB" -gt "$LIMIT_KB" ]; then
Expand Down Expand Up @@ -106,8 +119,8 @@ jobs:
# do, having only the image -- can match a coincidental byte
# sequence in the prelude and validate a boundary that is not the
# payload's, i.e. pass while the real prelude is oversized.
python3 - "u-boot-${{ matrix.board }}-universal.bin" \
"u-boot-${{ matrix.board }}-recovery.bin" \
python3 - "u-boot-${{ matrix.name }}-universal.bin" \
"u-boot-${{ matrix.name }}-recovery.bin" \
$(find arch/arm/cpu -name image_data.lzma) <<'EOF'
import sys
WINDOW = 0x3B00 # what the bootrom can actually load into SRAM
Expand Down Expand Up @@ -165,14 +178,14 @@ jobs:
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: u-boot-${{ matrix.board }}-universal
path: u-boot-${{ matrix.board }}-universal.bin
name: u-boot-${{ matrix.name }}-universal
path: u-boot-${{ matrix.name }}-universal.bin

- name: Upload recovery artifact
uses: actions/upload-artifact@v4
with:
name: u-boot-${{ matrix.board }}-recovery
path: u-boot-${{ matrix.board }}-recovery.bin
name: u-boot-${{ matrix.name }}-recovery
path: u-boot-${{ matrix.name }}-recovery.bin


# QEMU smoke test — gates publish on actually-bootable binaries.
Expand All @@ -185,13 +198,15 @@ jobs:
strategy:
fail-fast: false
matrix:
# Both binaries target V2-generation Hi3516CV200/Hi3518EV200
# Every binary here targets V2-generation Hi3516CV200/Hi3518EV200
# silicon (ARM926EJ-S); widgetii/qemu-hisilicon's
# `hi3516cv200` machine emulates that family. There is no
# standalone `hi3518ev200` machine — the binary boots fine in
# the cv200 model since they share the SoC.
# the cv200 model since they share the SoC. `board` here is the
# published artifact name, so it carries the -ddr3 suffix too.
include:
- { board: hi3518ev200, machine: hi3516cv200 }
- { board: hi3518ev200-ddr3, machine: hi3516cv200 }
- { board: hi3516cv200, machine: hi3516cv200 }
steps:
- name: Install QEMU build deps
Expand Down Expand Up @@ -312,7 +327,7 @@ jobs:
sleep $((i*10))
done
}
for soc in hi3518ev200 hi3516cv200; do
for soc in hi3518ev200 hi3518ev200-ddr3 hi3516cv200; do
for variant in universal recovery; do
f="artifacts/u-boot-${soc}-${variant}/u-boot-${soc}-${variant}.bin"
test -f "$f"
Expand Down
70 changes: 70 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# u-boot-hi3516cv200

OpenIPC's U-Boot for HiSilicon V2-generation silicon: **Hi3516CV200** and
**Hi3518EV200** (ARM926EJ-S). Hi3518EV201 has a config and a register table
in tree but no published build.

Builds are published automatically to the
[OpenIPC/firmware `latest` release](https://github.com/OpenIPC/firmware/releases/tag/latest).

## Which image do I flash?

| board | DRAM | flash this | recover over UART with |
|---|---|---|---|
| Hi3516CV200 | DDR3 | `u-boot-hi3516cv200-universal.bin` | `u-boot-hi3516cv200-recovery.bin` |
| Hi3518EV200 | DDR2 | `u-boot-hi3518ev200-universal.bin` | `u-boot-hi3518ev200-recovery.bin` |
| Hi3518EV200 | DDR3 | `u-boot-hi3518ev200-ddr3-universal.bin` | `u-boot-hi3518ev200-ddr3-recovery.bin` |

`-universal` is the image you write to flash. `-recovery` is the same
bootloader built to fit the boot ROM's SRAM window, for uploading over UART
to a board that will not boot; do not flash it.

### Hi3518EV200 comes in both DDR2 and DDR3

**Check before you flash.** These two are not interchangeable — the DRAM type
is set by a register table baked into the image, so a DDR2 image on a DDR3
board (or the reverse) has no working memory at all. The symptom is a camera
that flashes and verifies perfectly and then boots nothing, which reads as a
bad flash or a dead chip and is neither. See
[OpenIPC/firmware#2299](https://github.com/OpenIPC/firmware/issues/2299).

From a working HiSilicon U-Boot prompt — the vendor's own bootloader will do,
you do not need OpenIPC running yet:

```
hisilicon # md.l 0x20111050 1
20111050: 00000016 ....
```

The last hex digit is the DRAM type, per `DMC_CFG_DRAM_TYPE_MASK` in
`drivers/ddr/ddr_ddrc_v500.h` (`[2:0]` 101=DDR2, 110=DDR3, 111=DDR4):

| last digit | DRAM | image |
|---|---|---|
| `5` | DDR2 | `u-boot-hi3518ev200-*.bin` |
| `6` | DDR3 | `u-boot-hi3518ev200-ddr3-*.bin` |

If you cannot get a prompt at all, read the part number off the DRAM package
and look it up — the datasheet states the type outright. The board in #2299
carried a Nanya `NT5CC128M16IP-DI`, a 2 Gbit DDR3L device, which agreed with
the register.

## Building

```sh
make hi3518ev200_config # or hi3516cv200_config
cp reg_info_hi3518ev200.bin .reg # the DDR register table for the board
make CROSS_COMPILE=arm-hisiv510-linux-
make CROSS_COMPILE=arm-hisiv510-linux- mini-boot.bin
```

`mini-boot.bin` is assembled as 64 bytes of vectors, then the 4096-byte
register table from `.reg`, then code, then the LZMA-compressed U-Boot. The
table is copied in with `dd bs=4096 conv=sync` and nothing checksums it, so
selecting a different `.reg` is a table swap and nothing else — which is
exactly how the `-ddr3` variant is built, from `hi3518ev200_config` with
`reg_info_hi3516cv200.bin`.

Toolchain: `arm-hisiv510-linux` from
[OpenIPC/toolchains](https://github.com/OpenIPC/toolchains/releases/tag/v1).
`make mini-boot-recovery.bin` builds the UART-recovery variant.
Loading