A previous article on this blog, “Everything mainline from the ground up”, shows how to build mainline U-boot and Linux for Altera socfpgas. While the Cyclone V and the Stratix 10 are widely used and well supported, much cannot be said about the Arria 10.
The Arria 10’s bitstream is separated in two parts: the so-called “peripheral” and “core” bitstreams (the A10 Reference Manual gives more information about this). While a single .sof file may contain both the peripheral and the core sections, it is possible to separate it in two files from Quartus tools. The peripheral section, which is lighter, can be programmed first and the core section, which contains the heavier user logic, can be programmed later on, whenever one feels like it, effectively speeding up the boot process. Exploring the single-file version with your favorite hex editor (xxd) reveals that it really is merely a concatenation of both files with (nearly) no extra information.
So what’s the purpose of all of this? Some A10 peripherals may only be accessed after that the peripheral region has been loaded. For example, UART0, which is in the “Shared IO” region [1], and specifically the DDR controller are one of those peripherals. The consequence of this is that the SPL, which is executed from OCRAM, will not be able to relocate U-boot to the DDR and will crash before U-boot will even start executing. Note that this can be circumvented when the FPGA is programmed by any other mean, such as by using a JTAG probe (Blaster) or an EPCQ memory that programs the FPGA before running any HPS code.
On a side note, if you want to be able to program the FPGA from the HPS, it is required that the MSEL pins be correctly wired on the board. According to Intel’s documentation, the MSEL pins dictacte how the FPGA controller programs the FPGA logic. Depending on its configuration, it will be impossible to load any bitstream from the HPS. This was the case on an early version of the Reflex CES SoM which had them hardwired. A quick hardware mod was needed to allow programmation from the ARM processor.
While I am unsure about the current state of the A10’s development [2], it seems that mainline U-boot misses a way to program the FPGA while booting. However, this feature may be found in the maintainer’s custodian repository on the arria10_sdmmc branch, along other patches which may also be of importance. Be aware that this branch is not meant to be stable, may be rebased or even deleted at any time.
Using this branch, the u-boot-with-spl.sfp embeds a copy of the whole bitstream (read: periph + core) that is reprogrammed by the SPL before U-boot relocates itself into DDR and successfully runs from there. An .its file [3] tells the build system how to integrate the bitstream into the binary.
[1] As opposed to UART0, UART1 is in the “Dedicated IO” region and is available without any configuration. While the original Altera A10 socdk uses UART1, the A10 SoM by Reflex CES uses UART0 which may catch some developpers off guard.
[2] I recommend watching this excellent talk given by Marek Vasut at the Embedded Recipes 2018, “SoC+FPGA support in 2018”
[3] board/altera/arria10-socdk/fit_spl_fpga.its
3 comments
Hello , I am designing Linux OS for custom board which contains Arria 10 SoC. In our custom board , we replaced DDR4 with DDR3 which is connected at HPS side, also debug UART port is UART1 which is configured at shared I/O bank. After loading uboot_w_mkpimage.bin in our QSPI flash at 0x0 address and periph.rbf.mkimage at 0x720000 , the uboot is not booting. There is no output on uart console , also uart pin is not toggling.
In the system manager file I updated boot select pins #define SYSMGR_BOOTINFO_BSEL_MASK 0x6 (as QSPI is connected to 1.8 V supply).
Can you please reply why the uboot is not booting, Do i need to make any changes in uboot source code or my rbf file is not configuring the FPGA ?
Hello Priya,
Without the specifics of your problem, it will be hard for me to give you a satisfying answer. I don’t know which environment you used (Quartus IDE, u-boot from scratch) nor which version of the tools you used.
The fact that you don’t have an output on UART might be the result of an issue occurring anytime before U-Boot’s TPL (Tertiary Program Loader) is loaded into SDRAM.
First, make sure the UBoot’s SPL (Secondary Program Loader) is correctly loaded to SRAM from QSPI.
Second, make sure the SPL correctly loads the TPL’s image from QSPI and writes it to SDRAM. This image should contain the TPL, device tree and the perif.rbf file at known addresses. Once the perif.rbf file is loaded into SDRAM by the SPL, the latter should program this file into the FPGA before passing the execution flow to the TPL. Once the TPL starts to execute, the UART interface should be ready.
Lastly, make sure Uboot’s TPL is compiled with UART support.
You said that your periph.rbf file is stored at 0x7200000 (in SDRAM). Then the SPL should be configured to load the content of this file located at this address. If you see another address in the configuration of the SPL, load your file at this address instead.
Hello Sydney Hauke,
I am using Quartus tool 17.1 version and I used ghrd_10as066n2 as the reference project from the examples in the embedded folder. I have modified my project , and initialized UART at dedicated I/O, so the console window is showing output also. In our custom board we replaced DDR4 with DDR3 at HPS side. The DDR3 which we used is MT41K512M16HA-107 , so the timing parameter (data rate – 1866 , CL -13 , CWL -10) were changed in quartus tool , also the memory clock frequency(800 MHz) and PLL reference clock frequency(200MHz) were updated.
The DDR got successfully calibrated , but uboot hangs after DDR calibration.
U-Boot 2014.10 (Sep 19 2019 – 11:13:27)
CPU : Altera SOCFPGA Arria 10 Platform
BOARD : Altera SOCFPGA Arria 10 Dev Kit
I2C: ready
DRAM: WARNING: Caches not enabled
SF: Read data capture delay calibrated to 1 (0 – 2)
SF: Detected N25Q1024A with page size 256 Bytes, erase size 4 KiB, total 128 MiB
FPGA: Early Release Succeeded.
SF: Detected N25Q1024A with page size 256 Bytes, erase size 4 KiB, total 128 MiB
DDRCAL: Success
INFO : Skip relocation as SDRAM is non secure memory
Reserving 2048 Bytes for IRQ stack at: ffe3a6e8
DRAM : 2 GiB
Wdata abort
prefetch aààort
As I searched in the uboot source code, the misc.c file in arch/arm/cpu/armv7/socfpga_arria10 , the code hangs at below line :
/* assign the global data to new location, no longer in stack */
gd = id;
/* rebase the stack pointer as we won’t jump back here */
asm volatile (“mov sp, %0” : : “r” (gd->start_addr_sp)
: “r0”, “r1”, “r2”, “r3”, “ip”, “lr”, “memory”, “cc”);
I am not able to understand where do need to do modification to remove data abort after ddr calibration?
It would be great ,If you could help with the same?