From abc5579e8c138a8c0d3aaad6059bb3ed809dd585 Mon Sep 17 00:00:00 2001 From: Benno Rice Date: Wed, 27 Jun 2001 12:17:23 +0000 Subject: [PATCH] Fix the atomic_*_32 operations. These were written before I had the ability to test them properly and before I had a working knowledge of GCC asm constraints. --- sys/powerpc/include/atomic.h | 38 ++++++++-------- sys/powerpc/include/cpufunc.h | 82 ++++++++++++++++++++++------------- sys/powerpc/include/intr.h | 13 +++--- 3 files changed, 78 insertions(+), 55 deletions(-) diff --git a/sys/powerpc/include/atomic.h b/sys/powerpc/include/atomic.h index c705e1150176..218e973c5156 100644 --- a/sys/powerpc/include/atomic.h +++ b/sys/powerpc/include/atomic.h @@ -54,13 +54,13 @@ atomic_set_32(volatile u_int32_t *p, u_int32_t v) u_int32_t temp; __asm __volatile ( - "1:\tlwarx %0, 0, %2\n\t" /* load old value */ - "or %0, %0, %3\n\t" /* calculate new value */ + "1:\tlwarx %0, 0, %1\n\t" /* load old value */ + "or %0, %0, %2\n\t" /* calculate new value */ "stwcx. %0, 0, %1\n\t" /* attempt to store */ "bne- 1\n\t" /* spin if failed */ "eieio\n" /* drain to memory */ - : "=&r" (temp), "=r" (*p) - : "r" (*p), "r" (v) + : "=&r" (temp) + : "r" (p), "r" (v) : "memory"); } @@ -70,13 +70,13 @@ atomic_clear_32(volatile u_int32_t *p, u_int32_t v) u_int32_t temp; __asm __volatile ( - "1:\tlwarx %0, 0, %2\n\t" /* load old value */ - "andc %0, %0, %3\n\t" /* calculate new value */ + "1:\tlwarx %0, 0, %1\n\t" /* load old value */ + "andc %0, %0, %2\n\t" /* calculate new value */ "stwcx. %0, 0, %1\n\t" /* attempt to store */ "bne- 1\n\t" /* spin if failed */ "eieio\n" /* drain to memory */ - : "=&r" (temp), "=r" (*p) - : "r" (*p), "r" (v) + : "=&r" (temp) + : "r" (p), "r" (v) : "memory"); } @@ -86,13 +86,13 @@ atomic_add_32(volatile u_int32_t *p, u_int32_t v) u_int32_t temp; __asm __volatile ( - "1:\tlwarx %0, 0, %2\n\t" /* load old value */ - "add %0, %0, %3\n\t" /* calculate new value */ + "1:\tlwarx %0, 0, %1\n\t" /* load old value */ + "add %0, %0, %2\n\t" /* calculate new value */ "stwcx. %0, 0, %1\n\t" /* attempt to store */ "bne- 1\n\t" /* spin if failed */ "eieio\n" /* Old McDonald had a farm */ - : "=&r" (temp), "=r" (*p) - : "r" (*p), "r" (v) + : "=&r" (temp) + : "r" (p), "r" (v) : "memory"); } @@ -102,13 +102,13 @@ atomic_subtract_32(volatile u_int32_t *p, u_int32_t v) u_int32_t temp; __asm __volatile ( - "1:\tlwarx %0, 0, %2\n\t" /* load old value */ - "sub %0, %3, %0\n\t" /* calculate new value */ + "1:\tlwarx %0, 0, %1\n\t" /* load old value */ + "sub %0, %2, %0\n\t" /* calculate new value */ "stwcx. %0, 0, %1\n\t" /* attempt to store */ "bne- 1\n\t" /* spin if failed */ "eieio\n" /* drain to memory */ - : "=&r" (temp), "=r" (*p) - : "r" (*p), "r" (v) + : "=&r" (temp) + : "r" (p), "r" (v) : "memory"); } @@ -119,13 +119,13 @@ atomic_readandclear_32(volatile u_int32_t *addr) __asm __volatile ( "\teieio\n" /* memory barrier */ - "1:\tlwarx %0, 0, %3\n\t" /* load old value */ + "1:\tlwarx %0, 0, %2\n\t" /* load old value */ "li %1, 0\n\t" /* load new value */ "stwcx. %1, 0, %2\n\t" /* attempt to store */ "bne- 1\n\t" /* spin if failed */ "eieio\n" /* drain to memory */ - : "=&r"(result), "=&r"(temp), "=r" (*addr) - : "r"(*addr) + : "=&r"(result), "=&r"(temp) + : "r"(addr) : "memory"); return result; diff --git a/sys/powerpc/include/cpufunc.h b/sys/powerpc/include/cpufunc.h index d9ad6ae01063..829653f60bd4 100644 --- a/sys/powerpc/include/cpufunc.h +++ b/sys/powerpc/include/cpufunc.h @@ -33,6 +33,8 @@ #include +#include + #ifdef __GNUC__ static __inline void @@ -43,45 +45,67 @@ breakpoint(void) #endif +/* CPU register mangling inlines */ + +static __inline void +mtmsr(unsigned int value) +{ + __asm __volatile ("mtmsr %0" :: "r"(value)); +} + +static __inline unsigned int +mfmsr(void) +{ + unsigned int value; + + __asm __volatile ("mfmsr %0" : "=r"(value)); + + return (value); +} + +static __inline void +mtdec(unsigned int value) +{ + __asm __volatile ("mtdec %0" :: "r"(value)); +} + +static __inline unsigned int +mfdec(void) +{ + unsigned int value; + + __asm __volatile ("mfdec %0" : "=r"(value)); + + return (value); +} + /* * Bogus interrupt manipulation */ static __inline void disable_intr(void) { - u_int32_t msr; + unsigned int msr; - msr = 0; - __asm __volatile( - "mfmsr %0\n\t" - "rlwinm %0, %0, 0, 17, 15\n\t" - "mtmsr %0" - : "+r" (msr)); - - return; + msr = mfmsr(); + mtmsr(msr & ~PSL_EE); } static __inline void enable_intr(void) { - u_int32_t msr; + unsigned int msr; - msr = 0; - __asm __volatile( - "mfmsr %0\n\t" - "ori %0, %0, 0x8000\n\t" - "mtmsr %0" - : "+r" (msr)); - - return; + msr = mfmsr(); + mtmsr(msr | PSL_EE); } -static __inline u_int +static __inline unsigned int save_intr(void) { - u_int msr; + unsigned int msr; - __asm __volatile("mfmsr %0" : "=r" (msr)); + msr = mfmsr(); return msr; } @@ -93,31 +117,29 @@ critical_enter(void) } static __inline void -restore_intr(u_int msr) +restore_intr(unsigned int msr) { - __asm __volatile("mtmsr %0" : : "r" (msr)); - - return; + mtmsr(msr); } static __inline void critical_exit(critical_t msr) { - return (restore_intr((u_int)msr)); + return (restore_intr((unsigned int)msr)); } static __inline void powerpc_mb(void) { - __asm __volatile("eieio;" : : : "memory"); + __asm __volatile("eieio; sync" : : : "memory"); } -static __inline void +static __inline struct globaldata *powerpc_get_globalp(void) { - void *ret; + struct globaldata *ret; - __asm __volatile("mfsprg %0, 0" : "=r" (ret)); + __asm ("mfsprg %0, 0" : "=r"(ret)); return(ret); } diff --git a/sys/powerpc/include/intr.h b/sys/powerpc/include/intr.h index dac84ec8213f..a723bd4190d8 100644 --- a/sys/powerpc/include/intr.h +++ b/sys/powerpc/include/intr.h @@ -93,15 +93,16 @@ extern int imask[]; /* Following code should be implemented with lwarx/stwcx to avoid * the disable/enable. i need to read the manual once more.... */ static __inline void -softintr(ipl) - int ipl; +softintr(int ipl) { - int msrsave; + unsigned int msrsave; + + msrsave = mfmsr(); + mtmsr(msrsave & ~PSL_EE); - __asm__ volatile("mfmsr %0" : "=r"(msrsave)); - __asm__ volatile("mtmsr %0" :: "r"(msrsave & ~PSL_EE)); ipending |= 1 << ipl; - __asm__ volatile("mtmsr %0" :: "r"(msrsave)); + + mtmsr(msrsave); } #define ICU_LEN 64