summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/include/atomic-v4.h44
-rw-r--r--sys/arm/include/atomic-v6.h46
2 files changed, 59 insertions, 31 deletions
diff --git a/sys/arm/include/atomic-v4.h b/sys/arm/include/atomic-v4.h
index 71587f4..cc7780f 100644
--- a/sys/arm/include/atomic-v4.h
+++ b/sys/arm/include/atomic-v4.h
@@ -115,7 +115,7 @@ atomic_clear_64(volatile uint64_t *address, uint64_t clearmask)
static __inline int
atomic_fcmpset_32(volatile u_int32_t *p, volatile u_int32_t *cmpval, volatile u_int32_t newval)
{
- u_int32_t ret;
+ int ret;
__with_interrupts_disabled(
{
@@ -134,7 +134,7 @@ atomic_fcmpset_32(volatile u_int32_t *p, volatile u_int32_t *cmpval, volatile u_
static __inline int
atomic_fcmpset_64(volatile u_int64_t *p, volatile u_int64_t *cmpval, volatile u_int64_t newval)
{
- u_int64_t ret;
+ int ret;
__with_interrupts_disabled(
{
@@ -149,7 +149,7 @@ atomic_fcmpset_64(volatile u_int64_t *p, volatile u_int64_t *cmpval, volatile u_
return (ret);
}
-static __inline u_int32_t
+static __inline int
atomic_cmpset_32(volatile u_int32_t *p, volatile u_int32_t cmpval, volatile u_int32_t newval)
{
int ret;
@@ -166,7 +166,7 @@ atomic_cmpset_32(volatile u_int32_t *p, volatile u_int32_t cmpval, volatile u_in
return (ret);
}
-static __inline u_int64_t
+static __inline int
atomic_cmpset_64(volatile u_int64_t *p, volatile u_int64_t cmpval, volatile u_int64_t newval)
{
int ret;
@@ -296,7 +296,7 @@ atomic_clear_32(volatile uint32_t *address, uint32_t clearmask)
}
-static __inline u_int32_t
+static __inline int
atomic_cmpset_32(volatile u_int32_t *p, volatile u_int32_t cmpval, volatile u_int32_t newval)
{
int done, ras_start = ARM_RAS_START;
@@ -321,6 +321,33 @@ atomic_cmpset_32(volatile u_int32_t *p, volatile u_int32_t cmpval, volatile u_in
return (done);
}
+static __inline int
+atomic_fcmpset_32(volatile u_int32_t *p, volatile u_int32_t *cmpval, volatile u_int32_t newval)
+{
+ int done, oldval, ras_start = ARM_RAS_START;
+
+ __asm __volatile("1:\n"
+ "adr %1, 1b\n"
+ "str %1, [%0]\n"
+ "adr %1, 2f\n"
+ "str %1, [%0, #4]\n"
+ "ldr %1, [%2]\n"
+ "ldr %5, [%3]\n"
+ "cmp %1, %5\n"
+ "streq %4, [%2]\n"
+ "2:\n"
+ "mov %5, #0\n"
+ "str %5, [%0]\n"
+ "mov %5, #0xffffffff\n"
+ "str %5, [%0, #4]\n"
+ "strne %1, [%3]\n"
+ "moveq %1, #1\n"
+ "movne %1, #0\n"
+ : "+r" (ras_start), "=r" (done) ,"+r" (p)
+ , "+r" (cmpval), "+r" (newval), "+r" (oldval) : : "cc", "memory");
+ return (done);
+}
+
static __inline uint32_t
atomic_fetchadd_32(volatile uint32_t *p, uint32_t v)
{
@@ -409,14 +436,18 @@ atomic_swap_32(volatile u_int32_t *p, u_int32_t v)
#define atomic_fcmpset_rel_32 atomic_fcmpset_32
#define atomic_fcmpset_acq_32 atomic_fcmpset_32
+#ifdef _KERNEL
#define atomic_fcmpset_rel_64 atomic_fcmpset_64
#define atomic_fcmpset_acq_64 atomic_fcmpset_64
+#endif
#define atomic_fcmpset_acq_long atomic_fcmpset_long
#define atomic_fcmpset_rel_long atomic_fcmpset_long
#define atomic_cmpset_rel_32 atomic_cmpset_32
#define atomic_cmpset_acq_32 atomic_cmpset_32
+#ifdef _KERNEL
#define atomic_cmpset_rel_64 atomic_cmpset_64
#define atomic_cmpset_acq_64 atomic_cmpset_64
+#endif
#define atomic_set_rel_32 atomic_set_32
#define atomic_set_acq_32 atomic_set_32
#define atomic_clear_rel_32 atomic_clear_32
@@ -463,8 +494,6 @@ atomic_cmpset_long(volatile u_long *dst, u_long old, u_long newe)
return (atomic_cmpset_32((volatile uint32_t *)dst, old, newe));
}
-#ifdef _KERNEL
-/* atomic_fcmpset_32 is only defined for the kernel */
static __inline u_long
atomic_fcmpset_long(volatile u_long *dst, u_long *old, u_long newe)
{
@@ -472,7 +501,6 @@ atomic_fcmpset_long(volatile u_long *dst, u_long *old, u_long newe)
return (atomic_fcmpset_32((volatile uint32_t *)dst,
(uint32_t *)old, newe));
}
-#endif
static __inline u_long
atomic_fetchadd_long(volatile u_long *p, u_long v)
diff --git a/sys/arm/include/atomic-v6.h b/sys/arm/include/atomic-v6.h
index 2a579db..b0cb408 100644
--- a/sys/arm/include/atomic-v6.h
+++ b/sys/arm/include/atomic-v6.h
@@ -209,7 +209,7 @@ atomic_fcmpset_32(volatile uint32_t *p, uint32_t *cmpval, uint32_t newval)
return (!ret);
}
-static __inline uint64_t
+static __inline int
atomic_fcmpset_64(volatile uint64_t *p, uint64_t *cmpval, uint64_t newval)
{
uint64_t tmp;
@@ -235,7 +235,7 @@ atomic_fcmpset_64(volatile uint64_t *p, uint64_t *cmpval, uint64_t newval)
return (!ret);
}
-static __inline u_long
+static __inline int
atomic_fcmpset_long(volatile u_long *p, u_long *cmpval, u_long newval)
{
@@ -243,38 +243,38 @@ atomic_fcmpset_long(volatile u_long *p, u_long *cmpval, u_long newval)
(uint32_t *)cmpval, newval));
}
-static __inline uint64_t
+static __inline int
atomic_fcmpset_acq_64(volatile uint64_t *p, uint64_t *cmpval, uint64_t newval)
{
- uint64_t ret;
+ int ret;
ret = atomic_fcmpset_64(p, cmpval, newval);
dmb();
return (ret);
}
-static __inline u_long
+static __inline int
atomic_fcmpset_acq_long(volatile u_long *p, u_long *cmpval, u_long newval)
{
- u_long ret;
+ int ret;
ret = atomic_fcmpset_long(p, cmpval, newval);
dmb();
return (ret);
}
-static __inline uint32_t
+static __inline int
atomic_fcmpset_acq_32(volatile uint32_t *p, uint32_t *cmpval, uint32_t newval)
{
- uint32_t ret;
+ int ret;
ret = atomic_fcmpset_32(p, cmpval, newval);
dmb();
return (ret);
}
-static __inline uint32_t
+static __inline int
atomic_fcmpset_rel_32(volatile uint32_t *p, uint32_t *cmpval, uint32_t newval)
{
@@ -282,7 +282,7 @@ atomic_fcmpset_rel_32(volatile uint32_t *p, uint32_t *cmpval, uint32_t newval)
return (atomic_fcmpset_32(p, cmpval, newval));
}
-static __inline uint64_t
+static __inline int
atomic_fcmpset_rel_64(volatile uint64_t *p, uint64_t *cmpval, uint64_t newval)
{
@@ -290,7 +290,7 @@ atomic_fcmpset_rel_64(volatile uint64_t *p, uint64_t *cmpval, uint64_t newval)
return (atomic_fcmpset_64(p, cmpval, newval));
}
-static __inline u_long
+static __inline int
atomic_fcmpset_rel_long(volatile u_long *p, u_long *cmpval, u_long newval)
{
@@ -298,10 +298,10 @@ atomic_fcmpset_rel_long(volatile u_long *p, u_long *cmpval, u_long newval)
return (atomic_fcmpset_long(p, cmpval, newval));
}
-static __inline uint32_t
+static __inline int
atomic_cmpset_32(volatile uint32_t *p, uint32_t cmpval, uint32_t newval)
{
- uint32_t ret;
+ int ret;
__asm __volatile(
"1: ldrex %0, [%1] \n"
@@ -349,44 +349,44 @@ atomic_cmpset_64(volatile uint64_t *p, uint64_t cmpval, uint64_t newval)
return (ret);
}
-static __inline u_long
+static __inline int
atomic_cmpset_long(volatile u_long *p, u_long cmpval, u_long newval)
{
return (atomic_cmpset_32((volatile uint32_t *)p, cmpval, newval));
}
-static __inline uint32_t
+static __inline int
atomic_cmpset_acq_32(volatile uint32_t *p, uint32_t cmpval, uint32_t newval)
{
- uint32_t ret;
+ int ret;
ret = atomic_cmpset_32(p, cmpval, newval);
dmb();
return (ret);
}
-static __inline uint64_t
+static __inline int
atomic_cmpset_acq_64(volatile uint64_t *p, uint64_t cmpval, uint64_t newval)
{
- uint64_t ret;
+ int ret;
ret = atomic_cmpset_64(p, cmpval, newval);
dmb();
return (ret);
}
-static __inline u_long
+static __inline int
atomic_cmpset_acq_long(volatile u_long *p, u_long cmpval, u_long newval)
{
- u_long ret;
+ int ret;
ret = atomic_cmpset_long(p, cmpval, newval);
dmb();
return (ret);
}
-static __inline uint32_t
+static __inline int
atomic_cmpset_rel_32(volatile uint32_t *p, uint32_t cmpval, uint32_t newval)
{
@@ -394,7 +394,7 @@ atomic_cmpset_rel_32(volatile uint32_t *p, uint32_t cmpval, uint32_t newval)
return (atomic_cmpset_32(p, cmpval, newval));
}
-static __inline uint64_t
+static __inline int
atomic_cmpset_rel_64(volatile uint64_t *p, uint64_t cmpval, uint64_t newval)
{
@@ -402,7 +402,7 @@ atomic_cmpset_rel_64(volatile uint64_t *p, uint64_t cmpval, uint64_t newval)
return (atomic_cmpset_64(p, cmpval, newval));
}
-static __inline u_long
+static __inline int
atomic_cmpset_rel_long(volatile u_long *p, u_long cmpval, u_long newval)
{
OpenPOWER on IntegriCloud