[U-Boot-Users] Endian conundrum [long]

Joseph E. Sacco, Ph.D. joseph_sacco at comcast.net
Thu Nov 1 02:57:32 CET 2007


I am working on a board with:
* 1 mpc8270
* 2 Spansion S29JL064H memory devices 
   - connected in parallel [(32x16): 16 MB in 142 Sectors]
   - seemingly wired as little endian devices

Working with u-boot-1.2.0, I  created a unique board type loosely based
upon the work done for the mpc8260ads board. Because the flash is CFI
compliant I would like to use the common CFI driver rather than a custom
driver. By enabling the common CFI driver I have encountered some endian
issues that have broken 'saveenv'.

When I first enabled the common CFI driver, it reported that 'CFI
detect' failed to identify the flash. 

        ## Unknown FLASH on Bank 1 - Size = 0x00000000 = 0 MB
        *** failed ***
        ### ERROR ### Please RESET the board ###


I enabled debugging in the driver directory which pointed to the source
of the problem:

FLASH: flash detect cfi
                 ...
fwc addr ff000000 cmd 0 00000000 32bit x 16 bit
fwc addr ff000154 cmd 98 00980098 32bit x 16 bit
is= cmd 51(Q) addr ff000040 is= 00000000 00510051
                ...

Using "peak and poke" I was able to ascertain that:

* the CFI query command that works with my board is '98009800', 
not '00980098'
* the data at ff000040 should be '51005100', not '00510051'

==> looks like an Endian problem of some sort.

The CFI flash driver source, drivers/cfi_flash.c, supports little ENDIAN
when a preprocessor macro, __LITTLE_ENDIAN, is defined.  As quick an
dirty hack I edited the Makefile in the drivers directory and added
'-D__LITTLE_ENDIAN' to the CFLAGS list. This hack actually 'worked':
     
        [from flinfo]
         Bank # 1: CFI conformant FLASH (32 x 16)  Size: 16 MB in 142 Sectors
           AMD Standard command set, Manufacturer ID: 0x01, Device ID 0x7E0201
           Erase timeout: 8192 ms, write timeout: 1 ms

The driver Makefile hack is far too encompassing, which leads to a question: 

     "Where is the right place to define this preprocessor macro definition?"

The board configuration header file is the obvious place.  However, defining 
__LITTLE_ENDIAN in a the board configuration header file for a board with a big 
ENDIAN processor causes all sorts of mischief. Changing the name of the 
__LITTLE_ENDIAN macro in drivers/cfi_flash.c to something less generic would 
also be a bad idea.

I used the following approach which 'works' on this particular board.

* in the board configuration header file

        #define CFG_FLASH_LITTLE_ENDIAN
        
* in drivers/cfi_flash.c
        
        --- u-boot-1.2.0/drivers/cfi_flash.c.orig       2007-10-26 14:36:00.060179333 
        -0400
        +++ u-boot-1.2.0/drivers/cfi_flash.c    2007-10-26 15:18:01.485629019 -0400
        @@ -56,6 +56,10 @@
          *
          */
        
        +#ifdef CFG_FLASH_LITTLE_ENDIAN
        +#define __LITTLE_ENDIAN
        +#endif
        +
         #ifndef CFG_FLASH_BANKS_LIST
         #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE }
         #endif



All seemed well until I ran 'saveenv' from the u-boot prompt. An odd
thing happened:

        All of the words in u-boot environment stored in flash changed
        their endianness.  
        
For example,

        ==> md ffffc000
        ffffc000: abb4f7d5 626f6f74 64656c61
        793d3500    ....bootdelay=5.
        ffffc010: 65746861 63743d46 43433120 45544845    ethact=FCC1
        ETHE
        ffffc020: 524e4554 006d7464 70617274 733d7068
        RNET.mtdparts=ph
        ffffc030: 79733a32 35366b40 30287562 6f6f7429
        ys:256k at 0(uboot)
        ffffc040: 2c373535 326b4032 35366b28
        70617274    ,7552k at 256k(part
        ffffc050: 31292c37 3535326b 40373830 386b2870
        1),7552k at 7808k(p
        ffffc060: 61727432 292c3839 366b4031 35333630
        art2),896k at 15360
                             ...

became

        ==> md ffffc000 90
        ffffc000: d5f7b4ab 746f6f62 616c6564
        00353d79    ....toobaled.5=y
        ffffc010: 61687465 463d7463 20314343 45485445    ahteF=tc
        1CCEHTE
        ffffc020: 54454e52 64746d00 74726170 68703d73
        TENRdtm.traphp=s
        ffffc030: 323a7379 406b3635 62752830 29746f6f
        2:sy at k65bu(0)too
        ffffc040: 3535372c 32406b32 286b3635 74726170
        557,2 at k2(k65trap
        ffffc050: 372c2931 6b323535 30383740 70286b38
        7,)1k255087 at p(k8
        ffffc060: 32747261 39382c29 31406b36 30363335
        2tra98,)1 at k60635
                    ...


So... My  '__LITTLE_ENDIAN' hack is not correct. 

The question is, 

        "What is the right way to configure/enable the common CFI driver
        for a board with a big endian processor and little endian wired
        flash?



Thoughts???


-Joseph

-- 
joseph_sacco [at] comcast [dot] net





More information about the U-Boot mailing list