summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Irofti <pirofti@cvs.openbsd.org>2011-07-09 01:49:17 +0000
committerPaul Irofti <pirofti@cvs.openbsd.org>2011-07-09 01:49:17 +0000
commit0e24d57589d795d2810330512b1a8fdbb1fa3326 (patch)
tree534560b81883fdcd83b8c60ab0f1b46f3c6dcb31
parent0b8204a2db961a2245f156cae3343e695aaa9a42 (diff)
Add an atomic compare and exchange operation dealing with addresses
from userland for i386. Okay art@, assembly okay mlarkin@.
-rw-r--r--sys/arch/i386/i386/locore.s36
-rw-r--r--sys/arch/i386/include/atomic.h5
2 files changed, 39 insertions, 2 deletions
diff --git a/sys/arch/i386/i386/locore.s b/sys/arch/i386/i386/locore.s
index 73d8fb3f534..7df7720ddaa 100644
--- a/sys/arch/i386/i386/locore.s
+++ b/sys/arch/i386/i386/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.138 2011/07/08 21:11:20 pirofti Exp $ */
+/* $OpenBSD: locore.s,v 1.139 2011/07/09 01:49:16 pirofti Exp $ */
/* $NetBSD: locore.s,v 1.145 1996/05/03 19:41:19 christos Exp $ */
/*-
@@ -1695,6 +1695,40 @@ ENTRY(acpi_release_global_lock)
ret
#endif
+/*
+ * ucas_32(volatile int32_t *uptr, int32_t old, int32_t new);
+ */
+ENTRY(ucas_32)
+#ifdef DDB
+ pushl %ebp
+ movl %esp,%ebp
+#endif
+ pushl %esi
+ pushl %edi
+ pushl $0
+
+ movl 16+FPADD(%esp),%esi
+ movl 20+FPADD(%esp),%eax
+ movl 24+FPADD(%esp),%edi
+
+ cmpl $VM_MAXUSER_ADDRESS-4, %esi
+ ja _C_LABEL(copy_fault)
+
+ GET_CURPCB(%edx)
+ movl $_C_LABEL(copy_fault),PCB_ONFAULT(%edx)
+
+ lock
+ cmpxchgl %edi, (%esi)
+
+ popl PCB_ONFAULT(%edx)
+ popl %edi
+ popl %esi
+ xorl %eax,%eax
+#ifdef DDB
+ leave
+#endif
+ ret
+
#if NLAPIC > 0
#include <i386/i386/apicvec.s>
#endif
diff --git a/sys/arch/i386/include/atomic.h b/sys/arch/i386/include/atomic.h
index baa720d3e3c..fc5408cb968 100644
--- a/sys/arch/i386/include/atomic.h
+++ b/sys/arch/i386/include/atomic.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: atomic.h,v 1.8 2011/03/23 16:54:35 pirofti Exp $ */
+/* $OpenBSD: atomic.h,v 1.9 2011/07/09 01:49:16 pirofti Exp $ */
/* $NetBSD: atomic.h,v 1.1.2.2 2000/02/21 18:54:07 sommerfeld Exp $ */
/*-
@@ -99,6 +99,9 @@ i486_atomic_cas_int(volatile u_int *ptr, u_int expect, u_int set)
return (res);
}
+int ucas_32(volatile int32_t *, int32_t, int32_t);
+#define atomic_ucas_32 ucas_32
+
#define atomic_setbits_int i386_atomic_setbits_l
#define atomic_clearbits_int i386_atomic_clearbits_l