MCF547X/8X cache vs TAS instruction.

Alan Gilgenbach agilgenbach at elutions.com
Thu May 28 14:18:41 UTC 2009


Problem solved?

 

Sincerely,

 

Alan Gilgenbach

Elutions

414 918 4269

 

From: Mike Hench 
Sent: Thursday, May 28, 2009 9:17 AM
To: coldfire-gnu-discuss at codesourcery.com
Cc: Rick Johnson; Alan Gilgenbach
Subject: MCF547X/8X cache vs TAS instruction.

 

The 'TAS' (test and set) instruction on the MCF548X cpu's bypasses the cache

See section 5.5.1 of the reference manual.

 

It is used in a few places for atomic locks.

It doesn't play nice with the cache enabled.

(for some horrible reason, the cache isn't enabled by default in freescale kernels, but that can be fixed)

 

Locks are generally cleared with a simple write

Which won't get to TAS readable (main) memory wirhout a flush.

So

 

TAS memory location à to get a lock, main  mem now has the bit set which may conflict with cached mem.

Write 0 to clear lock (this is now only in cache, main  mem still has lock bit set)

TAS again to get a new lock and it see's the old bit in main mem since the cache has not been flushed to write the clear.

The cache cannot be flushed/invalidated from user space because it uses privileged instructions.

 

So the symptom is a hang waiting for a spinlock.

 

'bset' does a very similar thing however it is not SMP safe

I don't see how that matters, who builds SMP boxes out of microcontrollers anyway?

Bset is used for atomic locking in many places in the m68k code.

 

 

Anyway this fixes the problem: (at least the ones I have seen)

 

diff -aur glibc-linuxthreads-2.5.orig/linuxthreads/sysdeps/m68k/pspinlock.c glibc-linuxthreads-2.5/linuxthreads/sysdeps/m68k/pspinlock.c

--- glibc-linuxthreads-2.5.orig/linuxthreads/sysdeps/m68k/pspinlock.c   2008-09-24 08:41:10.000000000 -0500

+++ glibc-linuxthreads-2.5/linuxthreads/sysdeps/m68k/pspinlock.c  2009-05-26 16:37:17.000000000 -0500

@@ -28,7 +28,7 @@

   unsigned int val;

 

   do

-    asm volatile ("tas %1; sne %0"

+    asm volatile ("bset.b #7, %1; sne %0"

              : "=dm" (val), "=m" (*lock)

              : "m" (*lock)

              : "cc");

@@ -44,7 +44,7 @@

 {

   unsigned int val;

 

-  asm volatile ("tas %1; sne %0"

+  asm volatile ("bset.b #7, %1; sne %0"

            : "=dm" (val), "=m" (*lock)

            : "m" (*lock)

            : "cc");

diff -aur glibc-linuxthreads-2.5.orig/linuxthreads/sysdeps/m68k/pt-machine.h glibc-linuxthreads-2.5/linuxthreads/sysdeps/m68k/pt-machine.h

--- glibc-linuxthreads-2.5.orig/linuxthreads/sysdeps/m68k/pt-machine.h  2008-09-24 08:41:10.000000000 -0500

+++ glibc-linuxthreads-2.5/linuxthreads/sysdeps/m68k/pt-machine.h 2009-05-26 16:36:25.000000000 -0500

@@ -37,7 +37,7 @@

 {

   char ret;

 

-  __asm__ __volatile__("tas %1; sne %0"

+  __asm__ __volatile__("bset.b #7, %1; sne %0"

        : "=dm"(ret), "=m"(*spinlock)

        : "m"(*spinlock)

        : "cc");

 

 

diff -aur gcc-4.3.orig/libstdc++-v3/config/cpu/m68k/atomicity.h gcc-4.3/libstdc++-v3/config/cpu/m68k/atomicity.h

--- gcc-4.3.orig/libstdc++-v3/config/cpu/m68k/atomicity.h   2008-09-24 08:22:07.000000000 -0500

+++ gcc-4.3/libstdc++-v3/config/cpu/m68k/atomicity.h  2009-05-27 10:18:28.000000000 -0500

@@ -89,14 +89,14 @@

     _Atomic_word __result;

     

     // bset with no immediate addressing (not SMP-safe)

-#if defined(__mcfisaa__) || defined(__mcfisaaplus__)

+#if defined(__mcfisaa__) || defined(__mcfisaaplus__) || defined(__mcfisab__)

     __asm__ __volatile__("1: bset.b #7,%0@\n\tjbne 1b"

                   : /* no outputs */

                   : "a"(&_Atomicity_lock<0>::_S_atomicity_lock)

                   : "cc", "memory");

     

     // CPU32 and CF ISAs B & C support test-and-set (SMP-safe).

-#elif defined(__mcpu32__) || defined(__mcfisab__) || defined (__mcfisac__)

+#elif defined(__mcpu32__) || defined (__mcfisac__)

     __asm__ __volatile__("1: tas %0\n\tjbne 1b"

                   : "+m"(_Atomicity_lock<0>::_S_atomicity_lock)

                   : /* none */

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/coldfire-gnu-discuss/attachments/20090528/a0d2e7b1/attachment.html>


More information about the coldfire-gnu-discuss mailing list