Blackfin: work around testset anomaly 05000477
authorMike Frysinger <vapier@gentoo.org>
Tue, 3 Nov 2009 03:14:38 +0000 (03:14 +0000)
committerMike Frysinger <vapier@gentoo.org>
Wed, 25 Nov 2009 07:35:39 +0000 (02:35 -0500)
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>
arch/blackfin/mach-bf561/atomic.S

index 0261a5e751b35189d79f5684ff227f6552145ff3..f99f174b129f694609710faf9fe653f01f76b503 100644 (file)
        \reg\().h = _corelock;
 .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).
  *
@@ -33,7 +43,7 @@ ENTRY(_get_core_lock)
        cli r0;
        coreslot_loadaddr p0;
 .Lretry_corelock:
-       testset (p0);
+       safe_testset p0, r2;
        if cc jump .Ldone_corelock;
        SSYNC(r2);
        jump .Lretry_corelock
@@ -56,7 +66,7 @@ ENTRY(_get_core_lock_noflush)
        cli r0;
        coreslot_loadaddr p0;
 .Lretry_corelock_noflush:
-       testset (p0);
+       safe_testset p0, r2;
        if cc jump .Ldone_corelock_noflush;
        SSYNC(r2);
        jump .Lretry_corelock_noflush