Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F165174211
D39837.id121107.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D39837.id121107.diff
View Options
diff --git a/sys/arm64/arm64/support.S b/sys/arm64/arm64/support.S
--- a/sys/arm64/arm64/support.S
+++ b/sys/arm64/arm64/support.S
@@ -32,6 +32,8 @@
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
+#include <sys/errno.h>
+
#include <machine/setjmp.h>
#include <machine/param.h>
#include <machine/vmparam.h>
@@ -55,6 +57,123 @@
ret
END(fsu_fault)
+ENTRY(swapuword8_llsc)
+ check_user_access 0, (VM_MAXUSER_ADDRESS-3), fsu_fault_nopcb
+ adr x6, fsu_fault /* Load the fault handler */
+ mov w5, #1
+ SET_FAULT_HANDLER(x6, x4) /* And set it */
+ ENTER_USER_ACCESS(w6, x4)
+
+ /*
+ * x1 holds the address of our swap value; we pull the new value from it
+ * and stash the old value there since the caller will need it. The
+ * return value of swp_emulate_atomic() matches store(9)/fetch(9)
+ * semantics so that we can just re-use the existing fault handler.
+ */
+ ldr w7, [x1]
+
+ ldxrb w2, [x0]
+ stxrb w3, w7, [x0]
+ cbnz w3, 1f /* Don't clobber return on failure */
+
+ mov w5, #0 /* Return success */
+
+ str x2, [x1] /* Stash old value in *val */
+
+1: EXIT_USER_ACCESS(w6)
+ SET_FAULT_HANDLER(xzr, x6)
+ mov w0, w5
+ ret
+END(swapuword8_llsc)
+
+ENTRY(swapuword8_lse)
+ check_user_access 0, (VM_MAXUSER_ADDRESS-3), fsu_fault_nopcb
+ adr x6, fsu_fault /* Load the fault handler */
+ mov w5, #1
+ SET_FAULT_HANDLER(x6, x4) /* And set it */
+ ENTER_USER_ACCESS(w6, x4)
+
+ /*
+ * x1 holds the address of our swap value; we pull the new value from it
+ * and stash the old value there since the caller will need it. The
+ * return value of swp_emulate_atomic() matches store(9)/fetch(9)
+ * semantics so that we can just re-use the existing fault handler.
+ */
+ ldr w7, [x1]
+
+ .arch_extension lse
+ swpb w7, w2, [x0]
+ .arch_extension nolse
+
+ mov w5, #0 /* Return success */
+
+ str x2, [x1] /* Stash old value in *val */
+
+ EXIT_USER_ACCESS(w6)
+ SET_FAULT_HANDLER(xzr, x6)
+ mov w0, w5
+ ret
+END(swapuword8_lse)
+
+ENTRY(swapuword32_llsc)
+ check_user_access 0, (VM_MAXUSER_ADDRESS-3), fsu_fault_nopcb
+ adr x6, fsu_fault /* Load the fault handler */
+ mov w5, #1
+ SET_FAULT_HANDLER(x6, x4) /* And set it */
+ ENTER_USER_ACCESS(w6, x4)
+
+ /*
+ * x1 holds the address of our swap value; we pull the new value from it
+ * and stash the old value there since the caller will need it. The
+ * return value of swp_emulate_atomic() matches store(9)/fetch(9)
+ * semantics so that we can just re-use the existing fault handler.
+ */
+ ldr w7, [x1]
+
+ ldxr w2, [x0] /* Stash the old value in w2 */
+ stxr w3, w7, [x0] /* Store new value */
+ cbnz w3, 1f /* Don't clobber return on failure */
+
+ mov w5, #0 /* Return success */
+
+ str x2, [x1] /* Stash old value in *val */
+
+1: EXIT_USER_ACCESS(w6)
+ SET_FAULT_HANDLER(xzr, x6)
+ mov w0, w5
+ ret
+END(swapuword32_llsc)
+
+ENTRY(swapuword32_lse)
+ check_user_access 0, (VM_MAXUSER_ADDRESS-3), fsu_fault_nopcb
+ adr x6, fsu_fault /* Load the fault handler */
+ mov w5, #1
+ SET_FAULT_HANDLER(x6, x4) /* And set it */
+ ENTER_USER_ACCESS(w6, x4)
+
+ /*
+ * x1 holds the address of our swap value; we pull the new value from it
+ * and stash the old value there since the caller will need it. The
+ * return value of swp_emulate_atomic() matches store(9)/fetch(9)
+ * semantics so that we can just re-use the existing fault handler.
+ */
+ ldr w7, [x1]
+
+ .arch_extension lse
+ swp w7, w2, [x0]
+ .arch_extension nolse
+
+ mov w5, #0 /* Return success */
+
+ str x2, [x1] /* Stash old value in *val */
+
+ EXIT_USER_ACCESS(w6)
+ SET_FAULT_HANDLER(xzr, x6)
+ mov w0, w5
+ ret
+END(swapuword32_llsc)
+
+
/*
* int casueword32_llsc(volatile uint32_t *, uint32_t, uint32_t *, uint32_t)
*/
diff --git a/sys/arm64/arm64/support_ifunc.c b/sys/arm64/arm64/support_ifunc.c
--- a/sys/arm64/arm64/support_ifunc.c
+++ b/sys/arm64/arm64/support_ifunc.c
@@ -39,6 +39,12 @@
int casueword_llsc(volatile u_long *, u_long, u_long *, u_long);
int casueword_lse(volatile u_long *, u_long, u_long *, u_long);
+int swapuword8_llsc(volatile uint8_t *, uint8_t *);
+int swapuword8_lse(volatile uint8_t *, uint8_t *);
+
+int swapuword32_llsc(volatile uint32_t *, uint32_t *);
+int swapuword32_lse(volatile uint32_t *, uint32_t *);
+
DEFINE_IFUNC(, int, casueword32, (volatile uint32_t *base, uint32_t oldval,
uint32_t *oldvalp, uint32_t newval))
{
@@ -56,3 +62,19 @@
return (casueword_llsc);
}
+
+DEFINE_IFUNC(, int, swapuword8, (volatile uint8_t *base, uint8_t *val))
+{
+ if (lse_supported)
+ return (swapuword8_lse);
+
+ return (swapuword8_llsc);
+}
+
+DEFINE_IFUNC(, int, swapuword32, (volatile uint32_t *base, uint32_t *val))
+{
+ if (lse_supported)
+ return (swapuword32_lse);
+
+ return (swapuword32_llsc);
+}
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -321,6 +321,10 @@
int suword16(volatile void *base, int word);
int suword32(volatile void *base, int32_t word);
int suword64(volatile void *base, int64_t word);
+#ifdef __aarch64__
+int swapuword8(volatile uint8_t *base, uint8_t *val);
+int swapuword32(volatile uint32_t *base, uint32_t *val);
+#endif
uint32_t casuword32(volatile uint32_t *base, uint32_t oldval, uint32_t newval);
u_long casuword(volatile u_long *p, u_long oldval, u_long newval);
int casueword32(volatile uint32_t *base, uint32_t oldval, uint32_t *oldvalp,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Aug 7, 1:48 PM (7 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36177460
Default Alt Text
D39837.id121107.diff (5 KB)
Attached To
Mode
D39837: arm64: add swapuword8/32
Attached
Detach File
Event Timeline
Log In to Comment