Intel® SoC FPGA Embedded Development Suite
Support for SoC FPGA Software Development, SoC FPGA HPS Architecture, HPS SoC Boot and Configuration, Operating Systems
444 Discussions

Bare-metal application on SDRAM failing to run on DE10-nano

PeterTs
Beginner
1,488 Views

I'm struggling (huge understatement) to get my bare-metal application running and would appreciate some help. 

My set up is:

I'm using a DE10-nano development board and have 4 copies of the preloader plus my bare-metal application (with mkimage header) in the A2 partition of an SD card. The DE10-nano board has 1MB of SDRAM. When I run the code I see this:

U-Boot SPL 2020.10 (Jul 02 2021 - 15:45:56 +0100)
Trying to boot from MMC1
U-Boot SPL 2020.10 (Jul 02 2021 - 15:45:56 +0100)
Trying to boot from MMC1
U-Boot SPL 2020.10 (Jul 02 2021 - 15:45:56 +0100)
Trying to boot from MMC1
U-Boot SPL 2020.10 (Jul 02 2021 - 15:45:56 +0100)
Trying to boot from MMC1

 

I'm pretty sure my preloader is working fine, as I've imported the FPGA handoff files following the instructions and have built the u-boot preloader successfully.  I then enabled the debug messages in the preloader plus added a few of my own and have seen that the SDRAM is calibrated successfully and the load of the application from the SD card to SDRAM was successful. I got the preloader to show the address in SDRAM that it will be jumping to, which matched the address my application has been linked to run from (0x00100040). I also got the preloader to read the 32-bit word in SDRAM at the entry address and this matches the value in my built executable (I used the Cygwin ddx utility to convert the binary file into ASCII). The following is an extract of this debugging:

U-Boot SPL 2020.10 (Jul 05 2021 - 22:32:12 +0100)
drivers/ddr/altera/sequencer.c: CALIBRATION PASSED
drivers/ddr/altera/sequencer.c: Calibration complete
Trying to boot from MMC1
Image Name: LPS App
Image Load addr: 00100000
Image Entry Point: 00100040
Jumping to U-Boot
loaded - jumping to U-Boot...
image entry point: 0x100040
Value at entry point: 0xe59ff018
 
U-Boot SPL 2020.10 (Jul 05 2021 - 22:32:12 +0100)
drivers/ddr/altera/sequencer.c: CALIBRATION PASSED
drivers/ddr/altera/sequencer.c: Calibration complete
Trying to boot from MMC1
Image Name: LPS App
Image Load addr: 00100000
Image Entry Point: 00100040
Jumping to U-Boot
loaded - jumping to U-Boot...
image entry point: 0x100040
Value at entry point: 0xe59ff018
 
U-Boot SPL 2020.10 (Jul 05 2021 - 22:32:12 +0100)
drivers/ddr/altera/sequencer.c: CALIBRATION PASSED
drivers/ddr/altera/sequencer.c: Calibration complete
Trying to boot from MMC1
Image Name: LPS App
Image Load addr: 00100000
Image Entry Point: 00100040
Jumping to U-Boot
loaded - jumping to U-Boot...
image entry point: 0x100040
Value at entry point: 0xe59ff018
 
U-Boot SPL 2020.10 (Jul 05 2021 - 22:32:12 +0100)
drivers/ddr/altera/sequencer.c: CALIBRATION PASSED
drivers/ddr/altera/sequencer.c: Calibration complete
Trying to boot from MMC1
Image Name: LPS App
Image Load addr: 00100000
Image Entry Point: 00100040
Jumping to U-Boot
loaded - jumping to U-Boot...
image entry point: 0x100040
Value at entry point: 0xe59ff018
 
So I assume that my application is starting ok.  As you can't debug an app running fromn SDRAM using JTAG, I've added some toggles of an HPS GPIO pin (which was enabled in Platform designer, handoff-files, etc) to view these on an oscilloscope, but I can't see anything toggling.
 
I've created a startup.s file with the exception vector table and sections to disable the cache and so on before jumping to __main, as this is what the programming guides say is needed. (I've attached this file). 
The other thing I'm not sure about is whether some sort of memory mapping needs to be performed for my application to access the HPS peripheral registers (such as at 0xFF70A000 for GPIO ports)? 
 
Is there any suitable way of seeing what's going on?
0 Kudos
5 Replies
PeterTs
Beginner
1,459 Views

I can confirm preloader successfully launches the application and I can now step through the application under JTAG.

It turns out a breakpoint has to be placed at the internal RAM address in the preloader one or two assembly language instructions before it calls the application, otherwise JTAG debugging won't step through correctly. The breakpoint should be placed at the start or shortly after the start of the jump_to_image_no_args function (the address is in u-boot-spl.map).

 

There are still two issues that cause the application to fail:

  • In startup.s an exception is invoked when the MMU is enabled. This occurs whether the app is running under JTAG or without. Does anyone know why this should be the case? On checking the translation table I see the virtual addresses match the actual addresses. Does the MMU need to be enabled or is this optional?
  •  Once in my main() function I'm calling a series of functions to initialise the various modules I'm using, including setting up interrupts (for both UARTS, I2C, private timer, etc). Shortly after I call alt_int_cpu_enable() and alt_int_global_enable() the PC jumps to address 0x00000000 (the reset exception vector). Why does this occur? I thought all interrupts were handled by the Global Interrupt Controller using addresses programmed into the distributer registers.

 

0 Kudos
AnilErinch_A_Intel
1,357 Views

Hi ,

Please check the below forum thread for a related discussion.

https://forum.rocketboards.org/t/how-to-use-interrupt-in-the-bare-metal-mode-on-cyclone-v/1059/6

Also there are two types of interrupts , cpu interrupts and global interrupts.

The reason for program counter jumping to All zero address can be many ways which is heavily dependent on the implementation.

If you can share your assembly and other files we can have detailed look.

But would suggest to contact a local sales person for dedicated support which involves code debug.

Thanks and Regards

Anil


0 Kudos
PeterTs
Beginner
1,348 Views

Hi Anil,

 

Thank you for your response.

I found the cause of the PC jumping to zero - it was due to the HPS Watchdog0 expiring. This in turn was a result of I2C bus transactions taking longer than the watchdog interval I'd set (because I wasn't handling an I2C NAK from my slave device correctly). 

When debugging via JTAG I've found I need to disable the watchdog to prevent watchdog resets.

 

0 Kudos
AnilErinch_A_Intel
1,337 Views

Hi Peter,

Thanks for sharing your results regarding the program counter issue with the community.

Thanks and Regards

Anil


0 Kudos
AnilErinch_A_Intel
1,204 Views

Hi Peter,

If the question about MMU still exists , you can check that whether MMU is enabled or not by checking the appropriate register.

https://developer.arm.com/documentation/ddi0388/e/the-system-control-coprocessors/summary-of-system-control-coprocessor-registers/system-control-register

You can also verify the MMU status from the logs which you will get while booing the board in the terminal.

Thanks and Regards

Anil


0 Kudos
Reply