Blackfin: work around testset anomaly 05000477

Ironically, the atomic testset instruction cannot be interrupted else it
will produce incorrect results.  So disable interrupts to help it out.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
This commit is contained in:
Mike Frysinger 2009-11-03 03:14:38 +00:00
parent af5d7fc7e4
commit f99e8c1d0f
1 changed files with 12 additions and 2 deletions

View File

@ -19,6 +19,16 @@
\reg\().h = _corelock; \reg\().h = _corelock;
.endm .endm
.macro safe_testset addr:req, scratch:req
#if ANOMALY_05000477
cli \scratch;
testset (\addr);
sti \scratch;
#else
testset (\addr);
#endif
.endm
/* /*
* r0 = address of atomic data to flush and invalidate (32bit). * r0 = address of atomic data to flush and invalidate (32bit).
* *
@ -33,7 +43,7 @@ ENTRY(_get_core_lock)
cli r0; cli r0;
coreslot_loadaddr p0; coreslot_loadaddr p0;
.Lretry_corelock: .Lretry_corelock:
testset (p0); safe_testset p0, r2;
if cc jump .Ldone_corelock; if cc jump .Ldone_corelock;
SSYNC(r2); SSYNC(r2);
jump .Lretry_corelock jump .Lretry_corelock
@ -56,7 +66,7 @@ ENTRY(_get_core_lock_noflush)
cli r0; cli r0;
coreslot_loadaddr p0; coreslot_loadaddr p0;
.Lretry_corelock_noflush: .Lretry_corelock_noflush:
testset (p0); safe_testset p0, r2;
if cc jump .Ldone_corelock_noflush; if cc jump .Ldone_corelock_noflush;
SSYNC(r2); SSYNC(r2);
jump .Lretry_corelock_noflush jump .Lretry_corelock_noflush