Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

Nios II Gen2 core error

Altera_Forum
Honored Contributor II
3,659 Views

I just migrated my nios II to Nios II Gen2 core. I got a error as below. i tried to set instruction and data cache size to none. still give same error. 

 

/HAL/src/alt_remap_uncached.c:52: warning: alt_remap_uncached() is not available because Nios II Gen2 cores with data caches don't support mixing cacheable and uncacheable data on the same line.
0 Kudos
11 Replies
Altera_Forum
Honored Contributor II
989 Views

I wonder what they've done... 

There always were issues if you ever dirtied the cache lines for areas you wanted uncached access to - but that is no reason to error the function itself.
0 Kudos
Altera_Forum
Honored Contributor II
989 Views

Did you migrate your software application as well? Probably you need to update your bsp folder or recreate a new one. 

Furthermore, what peripherals are you using in your Qsys system?
0 Kudos
Altera_Forum
Honored Contributor II
989 Views

Hi, 

 

kind of hijacking that thread. 

 

I just hit the same phenomena after Quartus 14.1 proposed me to upgrade to the Gen2 core. I have a design with 2 Nios and some DMA cores that all communicate via DPRam using - of course - uncached access. While implementing the software I stuck to the alt_remap_uncached function, as somewhere in documentation this was suggested (in case the underlying hardware mechanism is changed, it would provide an abstraction. Didn't work tooo well...). 

 

So what is the proper way to access an area of uncached memory with den Gen2 core? I searched the web and couldn't find any information on that. Just that one: http://www.altera.com/support/kdb/solutions/rd07072014_334.html, but no proper way is shown. 

 

Thanks!
0 Kudos
Altera_Forum
Honored Contributor II
989 Views

Interesting read and kind of a tough problem to find out about the hard way... 

 

Anyway: per that knowledgebase article, I believe they're simply saying it's up to you to make sure your uncached and cached data are stored in separate memory regions (at least cache-line-size). 

 

If all of your accesses to your DPRAM are via alt_remap_uncached() pointers, I don't think you should have a problem. Maybe you're running into something else.
0 Kudos
Altera_Forum
Honored Contributor II
989 Views

I'm pretty sure you can still use the high address bit to request uncached accesses. 

You also have to option of using the full 32bit address range and marking a smaller amount uncached (probably the very top). 

There is a subtle difference in that writes with the high address bit set will no longer update any resident cache line - so if such a line exists, then when it is written back, the contents will be wrong. 

Any sensible code won't be doing that anyway, writes by the hardware/dma have always got lost if there was a cache line. 

OTOH if you use alt_remap_uncached() on buffers returned by malloc (etc) then you deserve what you get. 

 

Get the linker script to assign the DPR area address with the high bit set.
0 Kudos
Altera_Forum
Honored Contributor II
989 Views

In the meanwhile I saw the options in the Gen2 Parameters dialog - one to keep the 32nd bit mechanism, the other to assign a peripheral (I assume uncached) memory range. There you can define the size of the uncached region and the base address. Afterwards you most probably have to manually assign the peripherals in question to addresses in that range. 

 

But no matter if the 32nd bit mechanism is enabled or not, the linker throws an arrow when you call the alt_remap_uncached function. How I used the function looks like this: 

dpr_interface = (tDPRInterface*) alt_remap_uncached((void*) (DPRAM_BUFFER_BASE), sizeof(tDPRInterface)); 

And I never access the stuff with a cached pointer. I do get an cached pointer but purely by  

dpr_interface_c = (tDPRInterface*) (DPRAM_BUFFER_BASE); 

This I need to issue DMA transfers to/from the DPRAM. If you use "uncached" addresses the DMA transfer is not happening - lost somewhere in the avalon interconnect I guess. 

 

In the beginning I considered going down the linker path, what I think is what you suggested. That would mean working with  

__attribute__((section(".mysection"))).  

Somehow I preffered the prior solution because I felt, that it lets me manipulate the ongoings more freely - of course having the pitfalls in mind. I build a system where two Nios CPUs and 4 DMAs are acting on the DPRAM and everything goes smooth. 

 

If I build my system by 14.1 - using Nios classic or Gen2, doesn't matter - I can't get any of the two CPUs to run. If I build under 13.1 everything runs fine. But this would be subject to another thread...
0 Kudos
Altera_Forum
Honored Contributor II
989 Views

Just use: 

 

dpr_interface = (void *)(0x80000000 + DPRAM_BUFFER_BASE); 

 

For non-mmu BSP alt_remap_uncached() should be based on that# define. 

There is no point having real function calls for a lot of the 'BSP' stuff. 

 

David
0 Kudos
Altera_Forum
Honored Contributor II
989 Views

 

--- Quote Start ---  

 

But no matter if the 32nd bit mechanism is enabled or not, the linker throws an arrow when you call the alt_remap_uncached function.  

--- Quote End ---  

 

 

This sounds like something basic is wrong. What linker error are you getting? 

alt_remap_uncached() is a pretty simple function in the BSP HAL/src/alt_remap_uncached.c file.
0 Kudos
Altera_Forum
Honored Contributor II
989 Views

 

--- Quote Start ---  

Just use: 

 

dpr_interface = (void *)(0x80000000 + DPRAM_BUFFER_BASE); 

 

For non-mmu BSP alt_remap_uncached() should be based on that# define. 

There is no point having real function calls for a lot of the 'BSP' stuff. 

 

David 

--- Quote End ---  

 

 

Of course, I refuged to  

 

dpr_interface = (tDPRInterface*) ((DPRAM_BUFFER_BASE) | 0x80000000);  

 

 

--- Quote Start ---  

This sounds like something basic is wrong. What linker error are you getting? 

alt_remap_uncached() is a pretty simple function in the BSP HAL/src/alt_remap_uncached.c file. 

--- Quote End ---  

 

 

I don't have the literal output at hand, but the linker-error is clearly stating, that the alt_remap_uncached function is considered invalid with the NIOS Gen2.
0 Kudos
Altera_Forum
Honored Contributor II
989 Views

I see now, yes the message is quite explicit telling you what your problem is: 

 

/* * Convert a pointer to a block of cached memory into a block of uncached memory. * Return a pointer that should be used to access the uncached memory. * * This routine was created for Nios II Gen1 cores which allow mixing cacheable and * uncachable data in the same data cache line. So, they could take any memory region * and make it uncached. However, Nios II Gen2 cores don't support mixing cacheable * and uncachable data in the same data cache line so require the memory region to * be aligned to a cache line boundary and must be an integer number of cache line * bytes in size. So, software on a Nios II Gen2 core shouldn't really be using this * function so it fails with a link error. */ volatile void* alt_remap_uncached(void* ptr, alt_u32 len) { /* Generate a link time error, should this function ever be called. */ ALT_LINK_ERROR("alt_remap_uncached() is not available because Nios II Gen2 cores with data caches don't support mixing cacheable and uncacheable data on the same line."); return NULL; }
0 Kudos
Altera_Forum
Honored Contributor II
989 Views

Mixed mappings didn't work before either. 

If you search the forum you'll find that the caller had to ensure the buffer was cache line aligned, invalidate any cache lines, and to ensure that the cached address wasn't accessed. 

Exactly the same restrictions apply with the nios2.
0 Kudos
Reply