summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbenno <benno@FreeBSD.org>2001-06-27 12:17:23 +0000
committerbenno <benno@FreeBSD.org>2001-06-27 12:17:23 +0000
commita304a71cd25c73930405725cfd4fb9ef20765095 (patch)
treef092fa9d1f56dd5b5b191d0706160d1bf47e696e
parentc92b4bbf4fb01530ddb811f7dc6ef6bbf0920d09 (diff)
downloadFreeBSD-src-a304a71cd25c73930405725cfd4fb9ef20765095.zip
FreeBSD-src-a304a71cd25c73930405725cfd4fb9ef20765095.tar.gz
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.
-rw-r--r--sys/powerpc/include/atomic.h38
-rw-r--r--sys/powerpc/include/cpufunc.h82
-rw-r--r--sys/powerpc/include/intr.h13
3 files changed, 78 insertions, 55 deletions
diff --git a/sys/powerpc/include/atomic.h b/sys/powerpc/include/atomic.h
index c705e11..218e973 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 d9ad6ae..829653f 100644
--- a/sys/powerpc/include/cpufunc.h
+++ b/sys/powerpc/include/cpufunc.h
@@ -33,6 +33,8 @@
#include <sys/types.h>
+#include <machine/psl.h>
+
#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;
-
- msr = 0;
- __asm __volatile(
- "mfmsr %0\n\t"
- "rlwinm %0, %0, 0, 17, 15\n\t"
- "mtmsr %0"
- : "+r" (msr));
+ unsigned int msr;
- return;
+ msr = mfmsr();
+ mtmsr(msr & ~PSL_EE);
}
static __inline void
enable_intr(void)
{
- u_int32_t msr;
-
- msr = 0;
- __asm __volatile(
- "mfmsr %0\n\t"
- "ori %0, %0, 0x8000\n\t"
- "mtmsr %0"
- : "+r" (msr));
+ unsigned int 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 dac84ec..a723bd4 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
OpenPOWER on IntegriCloud