Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21581 Discussions

Cyclone V SoC Preloader will not run bare metal app

Altera_Forum
Honored Contributor II
13,138 Views

Hello all, 

 

I've been working on this problem for several days now. I've read every website/pdf I can find (e.g. these forums, rocketboards, altera pdfs, etc, etc, etc, etc) regarding bare metal applications on Cyclone V SoC and I still can't get this to work. I've gotten pretty far but I've basically run out of steam. I usually never post on forums unless I've tried every possible thing I can think of and have totally run out of ideas and places to search. I think I must just be missing something very simple. 

 

Here's what I've done so far (targetting DE10-Nano board): 

 

1) Created basic HPS design with UART and SDMMC peripherals enabled and DDR3 settings configured same as golden reference design that was provided with the board 

 

2) Built hardware design to .SOF without error and converted SOF to RBF so that it can be loaded by pre-loader 

 

3) Using the 'hps_isw_handoff' I created the spl_bsp with bsp-editor and configured to boot from SDMMC 

 

4) Compiled preloader using 'make' which generated preloader-mkpimage.bin without error 

 

5) Ran alt-boot-disk-util to update pre-loader image on special partition of SD card 

 

6) Created SD/MMC example C project in SoC EDS application (from https://www.altera.com/content/dam/altera-www/global/en_us/others/support/examples/soc/altera-socfpga-hardwarelib-sdmmc-cv-gnu.tar.gz

 

7) Compiled example C project to .AXF with no errors using baremetal GCC arm-altera-eabi- toolchain 

 

8) Copied AXF file to SD card FAT partition and inserted SD card into board 

 

9) Powered on board 

 

Pre-loader uboot output is as follows: 

U-Boot SPL 2013.01.01 (Sep 04 2017 - 20:01:43) BOARD : Altera SOCFPGA Cyclone V Board CLOCK: EOSC1 clock 25000 KHz CLOCK: EOSC2 clock 25000 KHz CLOCK: F2S_SDR_REF clock 0 KHz CLOCK: F2S_PER_REF clock 0 KHz CLOCK: MPU clock 800 MHz CLOCK: DDR clock 400 MHz CLOCK: UART clock 100000 KHz CLOCK: MMC clock 50000 KHz CLOCK: QSPI clock 3125 KHz RESET: COLD INFO : Watchdog enabled SDRAM: Initializing MMR registers SDRAM: Calibrating PHY SEQ.C: Preparing to start memory calibration SEQ.C: CALIBRATION PASSED SDRAM: 1024 MiB ALTERA DWMMC: 0 U-Boot 2017.03-rc2 (Mar 30 2017 - 19:07:16 -0700) CPU: Altera SoCFPGA Platform FPGA: Altera Cyclone V, SE/A6 or SX/C6 or ST/D6, version 0x0 BOOT: SD/MMC Internal Transceiver (3.0V) Watchdog enabled I2C: timeout in enabling I2C adapter timeout in enabling I2C adapter ready DRAM: 1 GiB MMC: dwmmc0@ff704000: 0 timeout in enabling I2C adapter timeout in enabling I2C adapter In: serial Out: serial Err: serial Model: Terasic DE10-Nano Net: No ethernet found. Hit any key to stop autoboot: 0 => run fpga_cfg reading de10-nano.rbf 1952756 bytes read in 192 ms (9.7 MiB/s) => load mmc 0:1 0x01000000 sdmmc_example.axf reading sdmmc_example.axf 669244 bytes read in 73 ms (8.7 MiB/s) => bootelf CACHE: Misaligned operation at range CACHE: Misaligned operation at range CACHE: Misaligned operation at range CACHE: Misaligned operation at range CACHE: Misaligned operation at range CACHE: Misaligned operation at range # # Starting application at 0x00100040 ... INFO: System Initialization.INFO: Setting up Global Timer.INFO: Setting up SDMMC.RESULT: Some failures detected. 

 

As you can see the pre-loader loads the FPGA design file. The configuration DONE light turns on so I know configuration is successful. 

 

However, the example application fails. Clearly there are some cache issues but I have no idea what they mean or why they are happening. But then the example application starts and just fails with no indication as to why. I inserted some printfs into the example code and it fails at the call to alt_sdmmc_card_identify(). 

 

I'm not sure if the 0x01000000 address that I'm loading to makes sense. The only reason that I'm using it is because that's the address that the 'bootelf' command tries to load from. 

 

It's obvious that the SD card peripheral is working since the pre-loader can read from it. I also tried changing the u-boot environment variables and writing them back to the SD card and that worked as well. So SD card read/write operation seems OK. 

 

It's also obvious that the DDR is working because the pre-loader can clearly write the ELF file to the DDR at address 0x01000000 and the HPS can obviously read from it since the application does in fact run (just not successfully). 

 

Can someone please help me figure this out? 

 

Regards 

 

P.S. I'm not interested in using the debugger to load the application. I need the fpga design and application to be loaded off of the SD card as I've shown. So please don't reply with "use the debugger and make a debug script" or similar. I need the board to boot and just start running without cables attached. 

 

UPDATE: I've also tried the GPIO example from the altera website (https://www.altera.com/content/dam/altera-www/global/en_us/others/support/examples/soc/altera-socfpga-hardwarelib-gpio-cv-gnu.tar.gz) and doesn't even successfully print the first printf statement. Instead it just prints a bunch of garbage: 

 

=> load mmc 0:1 0x01000000 gpio_example.axf reading gpio_example.axf 610864 bytes read in 64 ms (9.1 MiB/s) => bootelf CACHE: Misaligned operation at range CACHE: Misaligned operation at range CACHE: Misaligned operation at range CACHE: Misaligned operation at range CACHE: Misaligned operation at range CACHE: Misaligned operation at range # # Starting application at 0x00100040 ...-ÊÊêJåÍѵ%¹¥Ñ¥±¥é?½¹¹J9=éJ¹¥ÑA%=j½Õ±¹J9=éÑÑ¥¹ÕÁA%=¥¹ÑÉÉÕÁ?J9=??ÕÁ:A%=½Éb?J9=é?ÕÁA%=½ÉAÕÍ¡ ÕÑ?¹¹J9=?¥ÍÑ?¥¹ÑÉÉÕÁ?¢¹±É¹J9=é?ÍÍ"AM}A }UMI}ÁéBAM0? ±¥¹*¹J9=??ÍÍ!AM}A }UMI}ÅéB5b5E5??±±?¡Ñ¹J9=??ÍÍBAM}A }UMI}ÉêBAM"???±±b?J9=??ÍÍ!AM}A }UMI}ÍÒB5b)E5ÒÕ?½¹á¥Ñ¢µ½¹
0 Kudos
26 Replies
Altera_Forum
Honored Contributor II
2,284 Views

Cris72, 

The objdump command that was mentioned earlier creates a raw binary file, whereas the mkimage command 

creates a "u-boot image file" that is readable by the "bootm" command of u-boot. The mkimage command 

can add some information to the executable/binary to allow the u-boot bootloader to correctly parse and load  

the u-boot image file that gets loaded into the memory. I would stick with the raw binary to make things less 

confusing. 

 

Check that the memory dump is actually dumping 4 bytes at a time, instead of 2 bytes at a time. In gdb, 

the first command dumps out 2-bytes (or half-word) at a time, while the 2nd dumps out 4-bytes (or full word): 

 

(gdb) x/8xh main 

0x8520 <main>: 0xb580 0xb08c 0xaf02 0xf248 0x60dc 0xf2c0 0x0000 0xf241 

(gdb) x/8xw main 

0x8520 <main>: 0xb08cb580 0xf248af02 0xf2c060dc 0xf2410000 

0x8530 <main+16>: 0xf2c00102 0xf7ff0110 0x6138ef62 0xf1b3693b 

(gdb) x/8i main 

0x8520 <main>: push {r7, lr} 

0x8522 <main+2>: sub sp,# 48 ; 0x30 

0x8524 <main+4>: add r7, sp,# 8 

0x8526 <main+6>: movw r0,# 34524 ; 0x86dc 

0x852a <main+10>: movt r0,# 0 

0x852e <main+14>: movw r1,# 4098 ; 0x1002 

0x8532 <main+18>: movt r1,# 16 

0x8536 <main+22>: blx 0x83fc <open@plt>
0 Kudos
Altera_Forum
Honored Contributor II
2,284 Views

Hi austin944, 

I eventually could boot my application from SD. 

The memory issue of my previous post was actually a false problem: data gets loaded correctly; I don't know why, but sometimes the disassembly in the debugger is correct, sometimes is completely messed up because of the half-word shift. I haven't investigated further on this point for the moment.  

The data 0xEA00024 at address 0x100040 is correct, too: I made some sort of copy&paste error when I compared the memory. 

 

You were right, I had to use the raw memory image directly from objcopy output; no need to use the one created by mkimage. 

 

As I said above, the application starts but then it hangs when the code initializes irq and peripherals, and that's why I thought I could not boot it. 

Actually it did boot and run for a very short moment: I added a LED blink at the very beginning of main() to confirm this. 

 

My next task is to find out the missing initializazion (or whatever) which prevents the code execution to go further. 

It runs perfectly when I start with the debugger, so there's no problem with the application itself.
0 Kudos
Altera_Forum
Honored Contributor II
2,284 Views

Cris72, 

My SDMMC baremetal code starts execution, but eventually fails when using both the preloader and the bootloader, 

however it works with just the preloader. I don't have access to the debugger since I am using the free SW version. 

 

Today I found that if I turn off the data cache, then my baremetal application works with the bootloader. Maybe you 

can try that as well. Here's what I do at the bootloader prompt: 

 

=> dcache 

Data (writethrough) Cache is ON 

=> dcache off 

=> dcache 

Data (writethrough) Cache is OFF 

=> fatload mmc 0:1 0x100040 sdmmc_demo.bin 

reading sdmmc_demo.bin 

129408 bytes read in 18 ms (6.9 MiB/s) 

=> go 0x100040 

... 

RESULT: All tests successful. 

 

 

There is also a "dcache flush" command for flushing the data cache, as well as a corresponding "icache" 

command for the Instruction Cache, but various combinations of flushing the two caches after loading the 

application and before starting code execution do not allow my application to run correctly. I am also 

doing IO operations to the SDMMC in my baremetal application (reading and writing data to it). 

 

Maybe there is some unwanted interaction between the data cache and the IO operations in my case,  

like the dcache is inadvertently caching the IO address space, which would cause a lot of weird issues.
0 Kudos
Altera_Forum
Honored Contributor II
2,284 Views

Hi austin944 

I was not completely clear in my previous post. Now, I definitely can boot and execute the application. 

As I said, I excluded the main code (where I initialize timers IRQs, MMU and all bells and whistles) and replaced witha simple loop where I test buttons and blink LEDs according to them.  

This limited application boots from SD card and works perfectly. 

Now I'm planning to add the excluded part one at a time, until I find out which one blocks my system. 

Anyway, tomorrow I'll try the dcache command and I'll let you know. Thank you
0 Kudos
Altera_Forum
Honored Contributor II
2,284 Views

Yes, I believe I understood what you meant. I was sharing my experience as it seemed somewhat similar to yours, in that 

my full application starts and runs, but eventually fails.
0 Kudos
Altera_Forum
Honored Contributor II
2,284 Views

Yahoo! After a few tries enabling and disabling code lines I eventually found out what caused my application to fail. 

It was simply due to some of the printf calls I added when I used the debugger jtag uart. I removed them and now the full application boots and runs smoothly. 

I need more tests to be 100% sure, but I think the problem is solved. 

 

Anyway I'm concerned on some points, although now they are not greatly relevant: 

- I said above 'some' of the printf calls. Actually most of them are still there, but somehow they don't affect the execution 

- when I compiled the reference design source code, I got many errors regarding printf and I had to change some includes: for example I had to comment out the# include <alt_printf.h> lines; probably I'm now using a wrong HAL function? 

- I wonder if it's possible to connect to jtag uart even without the debugger and get that printfs out. When I developed Nios2 application I used the nios2-terminal command from the shell to activate the console, but I can't find a similar function for CV SoC
0 Kudos
Reply