[U-Boot-Users] [PATCH] Fixed cfi flash read uchar bug.

Håvard Skinnemoen
2007-01-13T17:53:04Z

On 1/13/07, Tolunay Orkun <listmember@orkun.us> wrote:
> Perhaps, more important issue would be if these areas were cached. In
> that case, every time we change the flash from read mode to special
> query modes, we should probably invalidate the cache. In PowerPC 405
> platform our flash is uncached so this is not necessary. I do not know
> if any platform caches its flash areas.

AVR32 does cache its flash area by default, but it can be worked
around by specifying an uncached virtual mapping (i.e. the physical
address ORed with 0xa0000000, similar to MIPS and SH) as the flash
address instead of the physical address.

However, doing cached flash accesses would probably improve the
performance of things like fsload, so how about using something like
the following interface when uncached access is needed?

void *flash_map(unsigned long paddr, size_t len);
void flash_unmap(void *vaddr, size_t len);

On platforms where the flash is always uncached, flash_map would
simply return paddr cast as a void *, and flash_unmap would do
nothing. Other platforms may invalidate the range and return a virtual
address which will bypass the cache (or simply disable the dcache and
return the physical address.)

> > Actually I might have been wrong in my assessment here, when I stated
> > that memcpy() performs a character-wise copy, too. The simple code
> > from lib_generic/string.c is used only if __HAVE_ARCH_MEMCPY is
> > undefined, and especially on PPC we define this (in
> > include/asm-ppc/string.h). So we might use an optimized versions
> > where it *does* make a difference.
>
> Memcopy might be OK for flash tables but I am not sure if we use the
> same function to access status registers. I would rather access flash
> using bus wide accesses instead of byte by byte. Maybe it is safe but I
> do not know how it behaves in various platforms and bus interface units
> of various processors. I would take the safe route.

I agree. Please don't make any assumptions about how memcpy() accesses
memory -- it might do all kinds of crazy stuff in the name of
optimization, including prefetching. And it may introduce _really_
subtle bugs where adding a field to a struct may cause things to break
because it causes its size to cross some implementation threshold (for
example on avr32 we might switch to 32-byte load/store-multiple
instructions if the size is >= 32 bytes and the start address is
properly aligned. Also, I believe gcc uses some threshold to determine
whether to emit __builtin_memcpy in-line or emit a call to the
out-of-line memcpy implementation, which may cause entirely different
things to happen from the flash chip's point of view.)

Best regards,
Haavard