From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jerry Van Baren Date: Wed, 30 Apr 2008 11:35:41 -0400 Subject: [U-Boot-Users] PPC sync/eieio (was cfi_flash.c and lost volatile qualifier) In-Reply-To: <1209568270.16926.32.camel@gentoo-jocke.transmode.se> References: <20080429204348.1ED4C247B4@gemini.denx.de> <48179041.6080008@ge.com> <48188584.3060109@ge.com> <1209568270.16926.32.camel@gentoo-jocke.transmode.se> Message-ID: <481891CD.7010907@ge.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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