Просмотр исходного кода

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>
Mike Frysinger 15 лет назад
Родитель
Сommit
f99e8c1d0f
1 измененных файлов с 12 добавлено и 2 удалено
  1. 12 2
      arch/blackfin/mach-bf561/atomic.S

+ 12 - 2
arch/blackfin/mach-bf561/atomic.S

@@ -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