[U-Boot-Users] PPC sync/eieio (was cfi_flash.c and lost volatile qualifier)
Jerry Van Baren
gerald.vanbaren at ge.com
Wed Apr 30 17:35:41 CEST 2008
Joakim Tjernlund wrote:
>> [1] Sync is a big hammer, eieio is a medium size hammer. Don't use
>> both, PPC people will know you don't know what you are doing. ;-)
>
> Yet the in_bex()/out_bex() functions in PowerPC linux uses sync and all
> SOC drivers are encouraged to use them. What a waste :(
>
> Jocke
Well, I was a little terse because I was cross-applying PPC instructions
in a ARM discussion. Personally, I prefer to use sync vs. eieio. The
size of the hammer isn't that different, I don't believe. The advantage
of sync is that it flushes the read/write operation out on the bus
*now*. When I'm writing to hardware to control the hardware, *now* is
what I want.
The eieio merely guarantees the preceding operations will go out on the
bus before following bus operations. The preceding operations could be
hung up in the bus interface unit *indefinitely* if no "following" bus
operations occur. This is an unlikely occurrence, but could be the
result of running out of cache in a tight loop.
For instance, if you do a write to a hardware register, a eieio, and
then wait in a tight loop until time goes by (reading the decrementer
register) followed by another write, the write1/delay/write2 sequence
could actually be delay/write1/write2. Note that the order of the
writes on the bus is correct per the eieio, but it isn't what the
hardware *needed*.
Illustration - what you did in code and intended to occur:
write1 (eieio)
delay
write2 (eieio)
What actually may happen on the bus:
delay
write1 (eieio)
write2 (eieio)
By using a sync, you guarantee the write isn't delayed:
write1 (sync)
delay
write2 (sync)
Disclaimer: the above explanation is from my fertile imagination. It
may or may not happen and *will* happen differently on different PPC
processors. For instance, the eieio instruction is actually a NOP in
the 603e core because it doesn't reorder bus operations, but it *does*
have a BIU that can buffer and delay the bus operations, causing the
above timing problem.
I contend using the "sync" instruction will always work correctly and
the "eieio" instruction is at best a false economy and at worst a lot of
very difficult, mysterious bugs to find, so I'm in agreement with the
linux in_bex/out_bex recommendation.
Side note: I don't know if I communicated it properly, but when you see
"eieio ; sync" or "sync ; eieio", you know the author of that code
doesn't understand sync and eieio. "isync ; sync" is occasionally a
valid combination, but I don't believe it is necessary other than when
called for by the Users Manual in conjunction with writing to special
purpose registers.
Best regards,
gvb
More information about the U-Boot
mailing list