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:
parent
62626b2c33
commit
abc5579e8c
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user