aboutsummaryrefslogtreecommitdiff
path: root/include/cmpxchg.h
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2017-12-20 13:16:22 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-12-20 22:15:36 -0600
commitca612b802adac0c72cd0f10c51a51275e5914101 (patch)
tree8a42ac046e4f368dace165e3c62b2f0644374dcf /include/cmpxchg.h
parentc7f2fab5c7854b11da909e79dd6c835d6ab91754 (diff)
downloadskiboot-ca612b802adac0c72cd0f10c51a51275e5914101.zip
skiboot-ca612b802adac0c72cd0f10c51a51275e5914101.tar.gz
skiboot-ca612b802adac0c72cd0f10c51a51275e5914101.tar.bz2
lock: Move cmpxchg() primitives to their own file
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'include/cmpxchg.h')
-rw-r--r--include/cmpxchg.h78
1 files changed, 78 insertions, 0 deletions
diff --git a/include/cmpxchg.h b/include/cmpxchg.h
new file mode 100644
index 0000000..28911c0
--- /dev/null
+++ b/include/cmpxchg.h
@@ -0,0 +1,78 @@
+/* Copyright 2017 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CMPXCHG_H
+#define __CMPXCHG_H
+
+#ifndef __TEST__
+/*
+ * Bare cmpxchg, no barriers.
+ */
+static inline uint32_t __cmpxchg32(uint32_t *mem, uint32_t old, uint32_t new)
+{
+ uint32_t prev;
+
+ asm volatile(
+ "# __cmpxchg32 \n"
+ "1: lwarx %0,0,%2 \n"
+ " cmpw %0,%3 \n"
+ " bne- 2f \n"
+ " stwcx. %4,0,%2 \n"
+ " bne- 1b \n"
+ "2: \n"
+
+ : "=&r"(prev), "+m"(*mem)
+ : "r"(mem), "r"(old), "r"(new)
+ : "cr0");
+
+ return prev;
+}
+
+static inline uint64_t __cmpxchg64(uint64_t *mem, uint64_t old, uint64_t new)
+{
+ uint64_t prev;
+
+ asm volatile(
+ "# __cmpxchg64 \n"
+ "1: ldarx %0,0,%2 \n"
+ " cmpd %0,%3 \n"
+ " bne- 2f \n"
+ " stdcx. %4,0,%2 \n"
+ " bne- 1b \n"
+ "2: \n"
+
+ : "=&r"(prev), "+m"(*mem)
+ : "r"(mem), "r"(old), "r"(new)
+ : "cr0");
+
+ return prev;
+}
+
+static inline uint32_t cmpxchg32(uint32_t *mem, uint32_t old, uint32_t new)
+{
+ uint32_t prev;
+
+ sync();
+ prev = __cmpxchg32(mem, old,new);
+ sync();
+
+ return prev;
+}
+#endif /* __TEST_ */
+
+#endif /* __CMPXCHG_H */
+
+