summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonald G. Minnich <rminnich@gmail.com>2009-01-15 16:56:44 +0000
committerRonald G. Minnich <rminnich@gmail.com>2009-01-15 16:56:44 +0000
commit67d036327d60649df19966b3949e83b2ac94a678 (patch)
tree43956bac9ae922d1383244d1a498a6f0a944d6da
parent560ba81528049be1962b447cae427c2deb805ef8 (diff)
downloadcoreboot-67d036327d60649df19966b3949e83b2ac94a678.tar.gz
coreboot-67d036327d60649df19966b3949e83b2ac94a678.tar.bz2
coreboot-67d036327d60649df19966b3949e83b2ac94a678.zip
Right from Linux. I am not comfortable inserting our headers in linux files.
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com> Acked-by: Patrick Georgi <patrick.georgi@coresystems.de> git-svn-id: svn://coreboot.org/repository/coreboot-v3@1116 f3766cd6-281f-0410-b1cd-43a5c92072e9
-rw-r--r--include/arch/x86/arch/atomic.h70
1 files changed, 70 insertions, 0 deletions
diff --git a/include/arch/x86/arch/atomic.h b/include/arch/x86/arch/atomic.h
new file mode 100644
index 000000000000..cdc9b2146297
--- /dev/null
+++ b/include/arch/x86/arch/atomic.h
@@ -0,0 +1,70 @@
+/* this implementation is from Linux. */
+#ifndef ARCH_ATOMIC_H
+#define ARCH_ATOMIC_H
+
+/*
+ * Make sure gcc doesn't try to be clever and move things around
+ * on us. We need to use _exactly_ the address the user gave us,
+ * not some alias that contains the same information.
+ */
+struct atomic { volatile int counter; };
+
+#define ATOMIC_INIT(i) { (i) }
+
+/*
+ * Atomic operations that C can't guarantee us. Useful for
+ * resource counting etc..
+ */
+
+/**
+ * atomic_read - read atomic variable
+ * @v: pointer of type struct atomic
+ *
+ * Atomically reads the value of @v. Note that the guaranteed
+ * useful range of an struct atomic is only 24 bits.
+ */
+#define atomic_read(v) ((v)->counter)
+
+/**
+ * atomic_set - set atomic variable
+ * @v: pointer of type struct atomic
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i. Note that the guaranteed
+ * useful range of an struct atomic is only 24 bits.
+ */
+#define atomic_set(v,i) (((v)->counter) = (i))
+
+/**
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type struct atomic
+ *
+ * Atomically increments @v by 1. Note that the guaranteed
+ * useful range of an struct atomic is only 24 bits.
+ */
+static __inline__ __attribute__((always_inline)) void atomic_inc(struct atomic *v)
+{
+ __asm__ __volatile__(
+ "lock ; incl %0"
+ :"=m" (v->counter)
+ :"m" (v->counter));
+}
+
+/**
+ * atomic_dec - decrement atomic variable
+ * @v: pointer of type struct atomic
+ *
+ * Atomically decrements @v by 1. Note that the guaranteed
+ * useful range of an struct atomic is only 24 bits.
+ */
+static __inline__ __attribute__((always_inline)) void atomic_dec(struct atomic *v)
+{
+ __asm__ __volatile__(
+ "lock ; decl %0"
+ :"=m" (v->counter)
+ :"m" (v->counter));
+}
+
+
+
+#endif /* ARCH_ATOMIC_H */