Till Straumann strauman at SLAC.Stanford.EDU
Tue Jan 21 20:16:29 UTC 2003

Hi Gregory.

Although I don't know if your 'strange results' (what exactly are you 
observing??) could be caused by this, I wanted to bring to your 
attention that the ld_xx/st_xxx macros don't enforce in-order execution 
on PPC. PCI-space is mapped as 'guarded' hence stores are always 
in-order, i.e.

st_le32(address1, val1);
st_le32(address2, val2);

is guaranteed to store val1 to addr1 prior to storing val2 to addr2.

However if you want to have

st_le32(address1, val1);

executed in this order (i.e. enforce reading from address2 only after
val1 has been stored to address1), you should probably use the 
out_xxx/in_xxx macros (which contain a 'eieio' instruction after the
load/store). Hence

out_le32(address1, val1);

guarantees that val2 is read after writing val1. Similarly


guarantees that val2 is written after reading val1.

This is usually an issue when a device changes a CSR as a result to 
writing another register:

st_le32(pReg,val);       /* write register */
EIEIO();                 /* note: out_le32 contains this EIEIO */
result = ld_le32(pCSR);  /* read result/CSR */

Without the EIEIO, it could be that 'result' is assigned a stale value.


-- Till

PS: Note that in special cases, SYNC instructions may be needed by
     a device driver to enforce memory synchronization.

gregory.menke at wrote:
> Hi,
> We're working up some compact pci based 1553 tranceivers for RTEMS-
> actually a PMC card and a cpci board- both the same chipsets.  I can
> find them on the bus OK, but am having some problems getting the
> address decoding right.
> I used the dec21140 ppc support as a model, but I'm seeing strangely
> close but wrong results.  The pci devices implement 3 memory mapped
> address ranges that I've confirmed the sizes of and signature values
> for via writing a Linux driver (which runs fine under ppc linux on the
> target mcp750), so I know the problem is something to do with my base
> address computation in RTEMS.
> I implement it by reading the base address, writing 0xffffffff and
> reading to find the size (which is right), then rewriting the base
> address back.  I then reference the space with the ld_ & st_ macros as
> defined by the bsp.  For the address in those macros, I use the (base
> address & ~0xf) + the pci memory offset, and then add the byte offset
> to the register I want.  This seems to correspond to how the dec21140
> driver does it but I'm not getting reasonable results.
> I checked the pci command and status registers, which yield plausible
> values from which it seems the card is enabled.  The base address
> registers produce reasonable values too- at least they end up in the
> regions configured by the bsp.
> Thanks for any pointers,
> Gregm

More information about the users mailing list