2010-05-31 11:04:06 (OT) interrupt interferes with Async bus read
Rutger Hofman (NETHERLANDS)
This is a bit off-topic here, but I didn't know what other forum to ask.
I have a custom BF547 board with an Asix AX88796B ethernet chip, an NE2000-compatible. I run eCos, as far as this community is concerned, that is a bare-metal application.
The Ethernet works fine (now), except when an interrupt interferes (like the clock). During data read from the Ethernet chip (in DMA mode, data is read by querying the async bus at the offset for DATA, a 16-bit word for each read operation) if an interrupt interferes, one read word can get lost: as appears after the retransmit, the corrupted packet misses one word at some unpredictable location. If I disable the clock interrupt, even directly around the data word read, things are OK. The assembly for the data read looks innocent enough (P5 would be the async address for the Ethernet chip, 0x4 is DATA offset):
0x004335e8 <dp83902a_recv+388>: P2 = [P5 + 0x4];
0x004335ea <dp83902a_recv+390>: R0 = W[P2] (X);
Any hints as to what I may be doing wrong? The interrupt routine saves/restores the following registers:
FP, USP, ASTAT, RETE, RETN, RETX, (special treatment:) RETI, RETS,
L[CBT], M0-3, B0-3, L0-3, I0-3, R0-7, P0-5, A.[WX]
Thanks for suggestions,
2010-05-31 11:13:35 Re: (OT) interrupt interferes with Async bus read
Mike Frysinger (UNITED STATES)
please look at the Blackfin Linux asm/io.h. we make sure that reads to the ASYNC bank are not interrupted by interrupts. this is by hardware design -- interrupted reads will be reissued from the core and obviously that'll screw up when accessing devices mapped in (fifos/etc...).
exceptions will trigger before the read is issued, so that isnt a problem.
nmi is never safe (too many anomalies related to interrupting of insns), so dont use it.
it really makes no sense to ever save/restore RETE/RETN/RETX. the value is destroyed as soon as an emulator/nmi/exception fire, and an interrupt cant occur in the middle of those.
2010-05-31 11:18:30 (OT) interrupt interferes with Async bus read
Michael Hennerich (GERMANY)
Message: 90023 On Blackfin reads can be killed - and reissued later.
However when reading from an FIFO this causes undesired behavior.
This is why interrupts need to be disabled when reads are destructive.
Take a look at the Linux ins() functions.
I recommend you implement them the same way.
2010-05-31 13:03:25 Re: (OT) interrupt interferes with Async bus read
Robin Getz (UNITED STATES)
As Mike/Michael stated - the issue you are seeing is described in the PRM.
See the sections : (1) Speculative Load Execution & (2) Conditional Load Behavior (snippet below from 6-73 in my pdf).
When accessing off-chip memory-mapped devices that have address dependencies on the number of read operations on a given location, disable interrupts before performing the load operation. Use the following sequence to disable and enable interrupts under these conditions. Please note the use of NOP instructions after the CLI instruction. This sequence is required to protect the read phase of the pipeline from seeing the read instruction before interrupts are turned off.
CLI R0 ;
NOP ; NOP ; NOP ; /* added to protect from pipeline */
R1 = [P0] ;
STI R0 ;
This is basically what the io functions that Mike/Michael points to trys to fix up - although there is a low overhead version and a high overhead version.
2010-06-01 05:36:13 Re: (OT) interrupt interferes with Async bus read
Rutger Hofman (NETHERLANDS)
Thanks Mike and Robin, I already thought it would be something like restarted read operation.
(I had searched the PRM for async, then for restart, then (not well enough) for interrupt.)