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++
12600 Discussions

problems with Flash by redboot on eCos with NIOS2

Altera_Forum
Honored Contributor II
1,077 Views

Hello, 

 

I tryed to make reboot working for StratixII Board with NIOSII Processor. 

 

Redboot permanently failed on detecting the flash device correctly. As it turns out, the flash detection routine reads out completly wrong flash ID 

(in file \redboot_install\include\cyg\io\flash_am29xxxxx_parts.inl, function flash_query(void* data) ) 

 

i did recognize it by inserting printouts in flash_hwr_init(void) 

 

   flash_data_t id;      flash_dev_query(id);    diag_printf("My Flash ID is %.2x:%.2x:%.2x:%.2x \n", id,id,id,id); 

 

i have a AM29LV128M Flash which should return ID 01:7E:12:0 in 8 Bit mode but the 

flash_dev_query(..) returns something like 14:44:3A:00, differs sometimes. 

 

So i took a look to the flash_dev_query(...) 

 

Here some part of the routine where it reads out the id (all pointers are declared with volatile)  

   *f_s1 = FLASH_Setup_Code1;    *f_s2 = FLASH_Setup_Code2;    *f_s1 = FLASH_Read_ID;    id = -1;    id = -1;    // Manufacturers' code    id = *(FLASH_P2V(ROM+FLASH_VendorID_Addr));    // Part number    id = *(FLASH_P2V(ROM+FLASH_DeviceID_Addr));    id = *(FLASH_P2V(ROM+FLASH_DeviceID_Addr2));    id = *(FLASH_P2V(ROM+FLASH_DeviceID_Addr3)); 

 

So, after many testing an trying with own test programms i took a close look to this "volatile"-pointer usage and I found this in the NIOS2 Manual, which would explain the whole problem: 

 

<div class='quotetop'>QUOTE </div> 

--- Quote Start ---  

For C programmers, note that declaring a pointer as volatile does not  

cause accesses using that volatile pointer to bypass the data cache. The  

volatile keyword only prevents the compiler from optimizing out  

accesses using the pointer.  

this volatile behavior is different from the methodology for  

the first-generation nios processor. [/b] 

--- Quote End ---  

 

 

In this case, accessing the flash memory, which io range is memorymapped into the cpu address space, each access has to BYPASS the data cache, to success. To do this with NIOS2 Prozessor, one need to use the ldio/stio instruction instead normal memory instructions. The Altera provided HAL gives Macros like iord_directxx to do this. 

 

I tryed this out in my testprogramm, and now, id is readden correctly: 

   IOWR_8DIRECT(EXT_FLASH_BASE,FLASH_Setup_Addr1, FLASH_Setup_Code1);    IOWR_8DIRECT(EXT_FLASH_BASE,FLASH_Setup_Addr2, FLASH_Setup_Code2);    IOWR_8DIRECT(EXT_FLASH_BASE,FLASH_Setup_Addr1, FLASH_Read_ID);    id = -1;    id = -1;    // Manufacturers&#39; code    id=IORD_8DIRECT(ROM,FLASH_VendorID_Addr);    // Part number    id=IORD_8DIRECT(ROM,FLASH_DeviceID_Addr);    id=IORD_8DIRECT(ROM,FLASH_DeviceID_Addr2);    id=IORD_8DIRECT(ROM,FLASH_DeviceID_Addr3); 

 

 

So my question now: 

Does anyone knows a solution to tell the compiler to automatically convert volatile pointer memory instructions to correct ldio/stio instructions? Or needs this code to be rewritten completly. I guess that there are much more volatile pointer operations in ecos/redboot source like i found here... 

Any solutions? 

 

Best regards, http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/smile.gif  

Marek
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
357 Views

Hi Marek, 

 

> Does anyone knows a solution to tell the compiler to automatically convert volatile 

> pointer memory instructions to correct ldio/stio instructions? 

 

There is none :-( -- the volatile keyword has nothing to do with cache. It _may_ 

however, affect optimizations with respect to memory access (cache or no-cache). 

 

> Any solutions? 

 

The quick &#39;n dirty is to use cache bypass (set bit 31 of the address). The "purist" 

way is a rewrite. Unfortunately, you may find a rewrite is like peeling an 

onion -- it seems like there&#39;s always another module that needs a re-write. 

 

Regards, 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
357 Views

Marek, 

 

I think the following Nios II processor-specific options might help: 

 

-mno-cache-volatile 

-mcache-volatile 

 

You can find this, and other processor options in : 

 

<nios2_root>/documents/gnu-tools/gcc/Altera-Nios-II-Options.html 

 

Best of luck, 

 

- slacker
0 Kudos
Altera_Forum
Honored Contributor II
357 Views

Thank you a lot for the advice, this was something i didnt know yet 

 

So, I just tried out the compiler switches with my test program and  

-mbypass-cache and -mno-cache-volatile made the pointer operations work like io-instructions. For unknown reason, -mno-bypass-cache did not success.  

But within my test-program, it works. 

But when adding this options to compiler options for building redboot, * i was really wondering * it did not work... http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/sad.gif  

 

I tried to modify the flash_driver function flash_query(void* data) to make sure and replaced all direct io operations... i thought, this should work for sure, but i don&#39;t know why the hell, but it doesn&#39;t http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/mad.gif  

... // Marek: made some helper macros# if (_16AS8 == 0)# define FIO_WR(ADDR, DATA) HAL_WRITE_UINT8(CYGNUM_FLASH_BASE + ADDR, DATA)# define FIO_RD(ADDR, VALUE) HAL_READ_UINT8(CYGNUM_FLASH_BASE + ADDR, VALUE)# else# define FIO_WR(ADDR, DATA) HAL_WRITE_UINT16(CYGNUM_FLASH_BASE + ADDR, DATA)# define FIO_RD(ADDR, VALUE) HAL_READ_UINT16(CYGNUM_FLASH_BASE + ADDR, VALUE)# endif # define FIO_S1_WR( DATA ) FIO_WR( FLASH_Setup_Addr1 , DATA)# define FIO_S2_WR( DATA ) FIO_WR( FLASH_Setup_Addr2 , DATA) ... void flash_query(void* data) {    //volatile flash_data_t *ROM;    //volatile flash_data_t *f_s1, *f_s2;    flash_data_t* id = (flash_data_t*) data;    flash_data_t w,w2;    long timeout = CYGNUM_FLASH_TIMEOUT_QUERY;         //ROM = (flash_data_t*) CYGNUM_FLASH_BASE;    //f_s1 = FLASH_P2V(ROM+FLASH_Setup_Addr1);    //f_s2 = FLASH_P2V(ROM+FLASH_Setup_Addr2);          // *f_s1 = FLASH_Reset;    FIO_S1_WR(FLASH_Reset); //    w = *(FLASH_P2V(ROM));     FIO_RD(0, w);    // *f_s1 = FLASH_Setup_Code1;     FIO_S1_WR(FLASH_Setup_Code1);    // *f_s2 = FLASH_Setup_Code2;     FIO_S2_WR(FLASH_Setup_Code2);    // *f_s1 = FLASH_Read_ID;     FIO_S1_WR(FLASH_Read_ID);        id = -1;    id = -1;    // Manufacturers&#39; code    // id = *(FLASH_P2V(ROM+FLASH_VendorID_Addr));     FIO_RD(FLASH_VendorID_Addr, id);    // Part number    // id = *(FLASH_P2V(ROM+FLASH_DeviceID_Addr));    FIO_RD(FLASH_DeviceID_Addr, id); //    id = *(FLASH_P2V(ROM+FLASH_DeviceID_Addr2));    FIO_RD(FLASH_DeviceID_Addr2, id); //    id = *(FLASH_P2V(ROM+FLASH_DeviceID_Addr3));    FIO_RD(FLASH_DeviceID_Addr3, id);     // *(FLASH_P2V(ROM)) = FLASH_Reset;     FIO_WR(0, FLASH_Reset);    // Stall, waiting for flash to return to read mode.     FIO_RD(0,w2);    while ((--timeout != 0) && (w !=  w2/* *(FLASH_P2V(ROM))*/))     {  FIO_RD(0,w2);     }; } 

Did I something wrong?? The nearly same code works in my testing program ... 

 

Note: 

I put a look into the source of ecos 2.01 and found that someone already tried to fix that problem by using hal_dcache_xxxx in a function that wrapp&#39;s flash_query. But this depends on that the prozessor is able to switch dcache&#39;ing on/off, which the NIOS prozessor isn&#39;t able to. So these Macros actually do nothing when build for NIOS. 

void flash_query(void* data) {    int cache_on;    HAL_DCACHE_IS_ENABLED(cache_on);    if (cache_on) {        HAL_DCACHE_SYNC();        HAL_DCACHE_DISABLE();    }    _flash_query(data);    if (cache_on) {        HAL_DCACHE_ENABLE();    } } 

I currently give up trying to build redboot and wonder, if  

all people have such problems, when trying nios with redboot or if i&#39;m just an anomalie... 

 

Regards, 

Marek 

PS: Sorry for posting much code, i hope it helps more than ti does struggeling you
0 Kudos
Altera_Forum
Honored Contributor II
357 Views

Hello, 

 

I tryed some more out and came now to the conclusion that it cannot be some dcache problem of the volatile pointer, because: 

 

- The Flash Base Address ( CYGNUM_FLASH_BASE ) has allready the 31 Bit set (which should tell nios2/f cores to bypass cache -> thanks to you, smcnutt) 

 

- I&#39;m tryed also on nios2/s core, which does not have dcache 

 

I now think, that the real problem is, that the flash is not addressed in right mode (can be 8 bit or 16 bit). In my testprogramm, i did a 8 bit access, which succeed, but in redboot code, it seems, it does a 16 bit access, when i print out the access addresses.  

The define constant _16AS8 is set to 0, which switches access mode to 16 Bit, as I suppose. To reproduce the problem, i tryed 16bit access in my test programm, and it fails to, nearly the same as redboot - so wide ok. 

 

So i manually set accessmode to 8 bit (in sourcecode) and hope that it whould fix my problem with red boot... but now redboot crashes (and restarts), exactly behind the line, were the read_id command is written to the flash. Curiously, my testprogramm with same code, does not. 

 

Anyone an idea? 

 

Best regards, 

Marek
0 Kudos
Altera_Forum
Honored Contributor II
357 Views

Hi Marek, 

 

I think I had the same problem as you today when I was using my AM29LV128 flash. The device ID made no sense. I found that the code which reads the device ID was assuming that the flash was connected in 16 bit mode. I followed the suggestion in this post: 

 

http://forum.niosforum.com/forum/lofiversi....php/t1841.html (http://forum.niosforum.com/forum/lofiversion/index.php/t1841.html

 

and this fixed my problem. The flash ID was then read as 01:7E:12:0 as it should be. 

 

Mike
0 Kudos
Reply