Macrized ioread causes multiple accesses
mdavidsaver opened this issue · 3 comments
Andrew Johnson and Shifu Xu of ANL report a nasty bug with epicsMMIO.h effecting all targets except RTEMS/powerpc. This is known to cause incorrect behavior with mrfioc2 on vxWorks, though this particular issue won't manifest on other targets.
On 07/01/2016 05:51 PM, Andrew Johnson wrote:
...
Register reads from the MRF230 are done by calling READ32.In mrfCommonIO.h:
define READ32(base,offset) NAT_READ32(base,offset)
define NAT_READ32(base,offset) \
nat_ioread32 ((epicsUInt8 *)(base) + U32_ ## offset)
In epicsMMIO.h:
define nat_ioread32(address) bswap32(sysPciInLong((UINT32 *)(address)))
For a PowerPC:
define bswap32(value) ( \
(((epicsUInt32)(value) & 0x000000ff) << 24) |
(((epicsUInt32)(value) & 0x0000ff00) << 8) |
(((epicsUInt32)(value) & 0x00ff0000) >> 8) |
(((epicsUInt32)(value) & 0xff000000) >> 24))Expanding out the bswap32() macro in nat_ioread32 results in
define nat_ioread32(address) ( \
(((epicsUInt32)(sysPciInLong((UINT32 *)(address))) & 0x000000ff) <<
24) |
(((epicsUInt32)(sysPciInLong((UINT32 *)(address))) & 0x0000ff00) << 8) |
(((epicsUInt32)(sysPciInLong((UINT32 *)(address))) & 0x00ff0000) >> 8) |
(((epicsUInt32)(sysPciInLong((UINT32 *)(address))) & 0xff000000) >> 24))i.e. four actual reads for every call to READ32. If the register is a
FIFO, that's probably going to throw away entries.
...
This is also https://bugs.launchpad.net/epics-base/+bug/1599903
Candidate fix a13a345
@anjohnson fyi
This fix resolves our problem with the MRF EVR-230 board on VxWorks.