Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Valued Contributor III
999 Views

NIOS II SBT Configuration with EPCS Controller

Hi All, 

 

I have a basic NIOS II system with a EPCS Controller used for booting. I have successfully flashed the EPCS device and on power-up the FPGA configures and the NIOS boots. 

 

However, I can now no longer 'Run' the system from Software Build Tools. The Console output is: 

Using cable "USB-Blaster ", device 1, instance 0x00 Resetting and pausing target processor: OK Reading System ID at address 0x00009840: verified Initializing CPU cache (if present) OK Downloading 00004020 ( 0%) Downloading 00007124 (93%) Downloading 00008800 (99%) Downloaded 13KB in 0.2s (65.0KB/s) Verifying 00004020 ( 0%) Verifying 00007124 (93%) Verifying 00008800 (99%) Verify failed between address 0x8800 and 0x881F Leaving target processor paused 

 

0x8800 is the base address of the EPCS Controller. Surely the SBT should only be writing to the onchip RAM (address 0x4000 to 0x7FFF)? 

 

Another concern is how the processor will be reset. The reset vector is set to the EPCS controller base address within QSYS. However, will the SBT Run Configuration reset to the base of the on-chip RAM? 

 

The qsys, spocinfo and bsp settings files are attached 

 

Any ideas? 

Thanks 

Andy
0 Kudos
14 Replies
Highlighted
Valued Contributor III
6 Views

Looks like something has made the linker put some code/data at the epcs address. Might be easiest to sort out from the elf symbol table and/or program sections. objdump is your friend here! -p will give the program headers (ie what is loaded).

0 Kudos
Highlighted
Valued Contributor III
6 Views

Hi DSL, 

Over the weekend I had a similar thought. It looks like a simple reset branch is 'trying' to be placed in the EPCS controller memory location. 

 

Some select parts from objdump 

 

Program Header: LOAD off 0x00001020 vaddr 0x00004020 paddr 0x00004020 align 2**12 filesz 0x00002e8c memsz 0x00002e8c flags r-x LOAD off 0x00003eac vaddr 0x00006eac paddr 0x0000718c align 2**12 filesz 0x000002e0 memsz 0x000002e0 flags rw- LOAD off 0x0000446c vaddr 0x0000746c paddr 0x0000746c align 2**12 filesz 0x00000000 memsz 0x0000011c flags rw- LOAD off 0x00004800 vaddr 0x00008800 paddr 0x00008800 align 2**12 filesz 0x00000020 memsz 0x00000020 flags r-x 

 

Sections: Idx Name Size VMA LMA File off Algn 0 .entry 00000020 00008800 00008800 00004800 2**5 CONTENTS, ALLOC, LOAD, READONLY, CODE 

 

 

Disassembly of section .entry: 00008800 <__reset>: 8800: 00400034 movhi at,0 8804: 08506d14 ori at,at,16820 8808: 0800683a jmp at 

 

All this does make sense as to use the EPCS Controller Boot Loader you need to set the NIOS reset vector to the base address of the EPCS Controller. However, this of course makes things awkward when trying to load a binary over JTAG from the BST. 

 

Is there anything I can do to make this work? 

 

Thanks again 

Andy
0 Kudos
Highlighted
Valued Contributor III
6 Views

You might be able to use objcopy to remove (or mark non-loadable) the .entry section, but you'll probably also need to change the elf entry point as well. 

Might be easier to decypher the linker script and write one that DTRT. 

 

You may also want one that leads the initialised .data(?) with its correct physaddr, and excludes the code to copy it on startup - if you look carefully the second program area has paddr != vaddr. This is particularly fubar if you are trying to run from internal memory. 

(I suspect the EPCS loader is only capable of loading one contiguous memeory area!) 

 

I think the jtag loader loads all the program sections then jumps to the entry point - it has a 'magic' method of overriding the reset address.
0 Kudos
Highlighted
Valued Contributor III
6 Views

This is starting to sounds a bit more complicated than I'd hoped! 

 

I suppose I'd imagined that given how seemless the approach to booting from EPCS had been (good support and documentation), I'd imagined that the BST would have been 'setup' to deal with that approach. 

 

The easiest path at the moment is probably to develop with the NIOS reset vector set to the base of the on chip memory, then change it over to the EPCS controller when I want to flash the EPCS. 

 

Out of interest, what is the inconsistency between paddr and vaddr a sign of? I've certainly not done anything deliberate to make it that way! 

 

Sections: Idx Name Size VMA LMA File off Algn 0 .entry 00000020 00008800 00008800 00004800 2**5 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .exceptions 00000194 00004020 00004020 00001020 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .text 00002c80 000041b4 000041b4 000011b4 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 3 .rodata 00000078 00006e34 00006e34 00003e34 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .rwdata 000002e0 00006eac 0000718c 00003eac 2**2 CONTENTS, ALLOC, LOAD, DATA, SMALL_DATA 5 .bss 0000011c 0000746c 0000746c 0000446c 2**2 ALLOC, SMALL_DATA
0 Kudos
Highlighted
Valued Contributor III
6 Views

You haven't done anything, the Altera supplied linker script goes out of its way to make life difficult! 

 

For some reason the Altera linker script puts all the initialised memory into one contiguous block - at the end of one of the code areas - and adds code to alt_main() to copy it to the correct physical address. 

I'm not sure why you have a gap between the .rodata and .rwdata, a unix program has a gap there so that the permissions on the pages can be different (sometime a page-sized gap, rather than aligning the .rwdata on the next page). 

 

The real problems arise when you are trying to load into multiple internal memory areas when the 'code' memory area is unlikely to be large enough to hold the initialised data - especially when it is a big lookup table! 

 

My suspicions are that Altera do this for EPCS loads into external SDRAM (etc) when there is likely to be enough space that it doesn't matter. Whether the code arranges the copies in a suitable order (eg reverse copies from highest address) to ensure they don't crap on each other is dubious! 

 

For tightly coupled systems the whole linker script is wrong. The .rodata needs to be in the 'data' memory, not the 'code' memory. As do any jump tables generated by the compiler for switch statements - which cannot be done with the gcc 4 Altera built.
0 Kudos
Highlighted
Valued Contributor III
6 Views

So it sounds like the altera tool chain is a little less polished than it could be. If I'd still been running Gentoo, I'd have had a stab at creating a new NIOSII gcc cross-compiler toolchain, but I'm having to use Win7 these days. 

 

I'm a little concerned about deviating too far from a 'standard' Altera setup. If I do it will make future maintenance (either by myself or others) more prone to difficulties. 

 

I admit to being a little sceptical about how the toolchain is setup when I saw the size of the generated binaries. There seems to be a lot of stuff linked in that doesn't need to be. 

 

Out of interest, what is your opinion on the BST? Would I be better off going back to Vim, make and a custom toolchain? 

 

BTW, thanks for your help and quick feedback. Much appreciated! 

Andy
0 Kudos
Highlighted
Valued Contributor III
6 Views

I built (and patched) the compiler, and use vi + make and my own scripts. 

Not tried to build it for cygwin on windows - but will probably build ok. 

It reality for a release build you need scripts, not a gui - otherwise you can't reproduce and automate things very easily. 

 

The code we use is loaded via the PCIe slave interface from a ppc (running linux). I actually extract the nios code+data, convert them to ppc .o, and link into the ppc binary - then link the ppc binary with the nios symbol table! This guarantees the two parts match. 

 

No IDE is going to support that sequence! I need two different cross compilers on the build system.
0 Kudos
Highlighted
Valued Contributor III
6 Views

The Altera tools seem to be designed to run their examples and not much else. 

Parts of the compiler are optimised for linux - well de-optimised for small code blocks. 

 

I run without ANY of the Altera initialisation (etc) code, I setup %sp, %gp and %et (only used for fatal faults) in the linker script, then jump to my C code.
0 Kudos
Highlighted
Valued Contributor III
6 Views

I have the same problem that the RUN command from SBT failes on a Nios system that is set to boot from an EPCS device.  

There are however a simple solution that worked for me. It did not require to change Nios reset vector address, it was just to start the RUN command twice: First run your project. After that fails, choose "Run Configurations...". Then close the "Run configuration" window, do not press Run.
0 Kudos
Highlighted
Valued Contributor III
6 Views

I have now found the final solution to the problem with the run command: 

There is a parameter in the settings.bsp file, ALT_ALLOW_CODE_AT_RESET, that must be set to 0 in order to get the flash bootloader code to work with the Run command. 

I have not found how to set this parameter from the BSP-editor, so just edit the bsp file directly.
0 Kudos
Highlighted
Valued Contributor III
6 Views

 

--- Quote Start ---  

 

...Another concern is how the processor will be reset. The reset vector is set to the EPCS controller base address within QSYS. However, will the SBT Run Configuration reset to the base of the on-chip RAM?... 

 

--- Quote End ---  

 

 

Inside SOPC builder GUI (Q11.1 SP2) it appears there is no way to set the reset vector to the EPCS base address. Epcs is absent in the reset vector pull-down menu of the NIOS II processor.  

 

In Qsys it seems to be possible but only by entering the absolute address of the EPCS flash "manually". Not by menu selection. This lack of pull-down menu selection does make me suspicious as to the validity of the method. 

 

is setting reset=absolute base address of the epcs (a part of) the way to direct nios to boot from the epcs flash it in qsys? 

 

Thanks for hints. 

 

And out of curiosity - because I'm switched to Qsys now - how would you possibly do this in SOPC builder?
0 Kudos
Highlighted
Valued Contributor III
6 Views

Are you sure the Nios II instruction master is connected to the EPCS controller and not just tho data mastor? If you don't see the controller in the reset menu it means there is a problem with the way all the components are connected, or at least in how SOPC builder / QSys sees those connections.

0 Kudos
Highlighted
Valued Contributor III
6 Views

 

--- Quote Start ---  

Are you sure the Nios II instruction master is connected to the EPCS controller and not just tho data mastor?.. 

--- Quote End ---  

 

spot on! The EPCS was only connected to the data master. Did once a similar thing with a dma where a bus was missing. One day I will learn it. 

 

The board is working nicely out of boot now running FreeRTOS. I would be embarrassed to tell how much time I have wasted on this boot problem. Well, at least I have had the occasion to read some application notes and manuals! 

 

A million thanks for your help. 

 

henning
0 Kudos
Highlighted
Valued Contributor III
6 Views

 

--- Quote Start ---  

I have now found the final solution to the problem with the run command: 

There is a parameter in the settings.bsp file, ALT_ALLOW_CODE_AT_RESET, that must be set to 0 in order to get the flash bootloader code to work with the Run command. 

I have not found how to set this parameter from the BSP-editor, so just edit the bsp file directly. 

--- Quote End ---  

 

 

Thank you. This resolved a similar issue I was having. I had my reset vector in EPCS flash. I could flash my sof and elf (converted to jic) and run from flash with no problem. However, when I tried to connect with JTAG I would get "Verify failed" at my reset vector offset. Changing ALT_ALLOW_CODE_AT_RESET to zero in my bsp settings resolved this issue for me. 

 

I was able to find this setting in the BSP Editor (I am using SBT 12.1sp1). Go to BSP Editor -> Main -> Settings -> Advanced -> hal -> linker -> allow_code_at_reset. Disable checkbox. Hope this helps future users. 

 

-JQ
0 Kudos