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.
This commit is contained in:
Benno Rice 2001-06-27 12:17:23 +00:00
parent 62626b2c33
commit abc5579e8c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=78878
3 changed files with 78 additions and 55 deletions

View File

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

View File

@ -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;
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);
}

View File

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