diff options
author | Paul Irofti <pirofti@cvs.openbsd.org> | 2011-07-09 01:49:17 +0000 |
---|---|---|
committer | Paul Irofti <pirofti@cvs.openbsd.org> | 2011-07-09 01:49:17 +0000 |
commit | 0e24d57589d795d2810330512b1a8fdbb1fa3326 (patch) | |
tree | 534560b81883fdcd83b8c60ab0f1b46f3c6dcb31 | |
parent | 0b8204a2db961a2245f156cae3343e695aaa9a42 (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.s | 36 | ||||
-rw-r--r-- | sys/arch/i386/include/atomic.h | 5 |
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 |