AnsweredAssumed Answered

MPC5200 Misaligned Transfer Corruption on LocalPlus Bus is a FEATURE.

Question asked by TomE on Aug 3, 2011
Latest reply on Aug 4, 2011 by TomE

This is very old news, but I've just spent a few days tracking this down.


Keywords: MPC520. LocalBus Plus. Unaligned. Misaligned. CRC Errors. Corruptions.


We're running Linux on an MPC5200 based board, and after what was meant to be a very minor change to the code it started intermittently corrupting the data in the JFFS2 filesystem in the FLASH connected to the LocalPlus Bus.


There was a cryptic comment in the drivers/mtd/maps/icecube.c file that looked like this:


static void icecube_copy_from(struct map_info *map,                       void *to, unsigned long from, ssize_t len){#if 0        memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);#else        /* workaround for misaligned memory access: use byte copy. */        flash_memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);#endif}

There was no other explanation about what the workaround was for, and the above comment had been copied to and from various other files. There's nothing in the MPC5200 Errata giving any warning about misaligned or unaligned access on the LocalPlus Bus, so I changed the code to "#if 1" and it all seemed to work fine. The FLASH accesses were now quite a bit faster (which is why I made the change). But less reliable as it turned out.


That's because the User Manual contains the following:


Chapter 9
LocalPlus Bus (External Bus Interface)


9.2 Features
LocalPlus has the following features:


 * NO support of misaligned accesses


I wouldn't call that a "feature"! This is "directly mapped memory space" and it can't handle the normal transfers that work in all the SRAM and DRAM spaces. Unlike other CPUs that truly don't support misaligned transfers, there's no obvious trap available for when this happens by accident.


Sure enough, this is easy to demonstrate, even from U-Boot:


=> md ff040000ff040000: 64677950 626f6f74 61726773 3d726f6f    dgyPbootargs=rooff040010: 743d2f64 65762f6d 7464626c 6f636b32    t=/dev/mtdblock2ff040020: 20726f6f 74667374 7970653d 6a666673     rootfstype=jffs=> md ff040001ff040001: 00006462 00000061 0000003d 00000074    ..db...a...=...tff040011: 00000065 00000074 0000006f 00000020    ...e...t...o...ff040021: 00000074 00000079 0000006a 00000032    ...t...y...j...2=> md ff040003
ff040003: 50000000 74000000 73000000 6f000000    P...t...s...o...
ff040013: 64000000 6d000000 6c000000 32000000    d...m...l...2...
ff040023: 6f000000 74000000 3d000000 73000000    o...t...=...s...

Go to copy 4 bytes misaligned by 1 or 3 and it only copies 1. Sort of.


Surprisingly, the JFFS2 file system almost always performs aligned transfers when reading the FLASH. Only one in many thousands of transfers is from an odd address, at which point it returns data as shown above, and this sort of thing shows ip on the console and in the kernel message buffer:


<4>[   37.75] Data CRC 31563113 != calculated CRC 205982c3 for node at 004c000c<4>[   37.76] Data CRC 31563113 != calculated CRC 205982c3 for node at 004c000c