Bootstrapping Arria10 with OpenOCD and barebox
The Arria10 SoCFPGA can boot from multiple sources: SD Card, NAND flash, QSPI flash and eMMC, that can be selected via the BSEL pins. If the bootrom can not find a valid bootloader on that medium, it will fall back to JTAG. So for developing and testing, the BSEL pins can just be set to a medium that is non-existent. In case of bootstrapping, the bootrom falls back to JTAG anyway, as there is no valid bootloader, yet.
Okay, so how to get the bootloader loaded via JTAG? That is where OpenOCD comes into play. OpenOCD has had support for the Cyclone5-based SoCFPGA family for multiple years now. Not so for Arria10. The necessary patches where created by Oleksij Rempel and got included last year.
The problematic part of the Arria10 is the SDRAM controller. For some reason, it was decided, that it is a good idea to not include a hard IP core into the SoC, but put it into the FPGA portion. So, to do anything useful in the bootloader, the FPGA has to be programmed first. As it turned out, before the FPGA can be programmed some setup has to be done or the SoC behaves strangely in different ways. That is why we have to use a two-stage boot approach with OpenOCD.
First, start up barebox and let it setup the clocks and pins:
halt load_image barebox-bringup $OCRAM bin $OCRAM $OCRAM_SIZE resume $OCRAM
load_image is an OpenOCD TCL command to load a file to an address. Remember, that the SDRAM can not be used yet. So, the image must be loaded to the 256KB On-Chip RAM. After the image is transfered, resume from the address we just loaded barebox to. So, barebox does its thing and sets up the clocks and pins and then loops on the FPGA usermode bit. This bit will be set to 1, once the FPGA is loaded successfully and enters user mode, i.e. it can be used.
Next, program the FPGA:
svf -tap $_CHIPNAME.fpga.tap bitstream progress
svf can load FPGA bitstreams that are formatted in the serial vector format. These can be generated with the Altera Quartus tool. Once this is done, barebox can continue with its normal boot process: setting up hardware and boot linux.
Once we are in the userspace, barebox can be written to the boot medium, so we don't have to always boot from JTAG if we don't want to. In our case, we partition the eMMC and write barebox to the first partition and the FPGA bitstream, this time formatted in raw binary file format, to the second partition. Now, after powerup, barebox programs the FPGA itself and boots just like on other hardware.