summaryrefslogtreecommitdiff
path: root/include/asm.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm.h')
-rw-r--r--include/asm.h56
1 files changed, 56 insertions, 0 deletions
diff --git a/include/asm.h b/include/asm.h
new file mode 100644
index 00000000..8458d5d2
--- /dev/null
+++ b/include/asm.h
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+
+#ifndef SHIM_ASM_H_
+#define SHIM_ASM_H_
+
+#define __stringify_1(x...) #x
+#define __stringify(x...) __stringify_1(x)
+
+static inline uint64_t read_counter(void)
+{
+ uint64_t val;
+#if defined (__x86_64__)
+ unsigned long low, high;
+ __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high));
+ val = (low) | (high) << 32;
+#elif defined(__i386__) || defined(__i686__)
+ __asm__ __volatile__("rdtsc" : "=A" (val));
+#elif defined(__aarch64__)
+ __asm__ __volatile__ ("mrs %0, pmccntr_el0" : "=r" (val));
+#elif defined(__arm__)
+ __asm__ __volatile__ ("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
+#else
+#error unsupported arch
+#endif
+ return val;
+}
+
+#if defined(__x86_64__) || defined(__i386__) || defined(__i686__)
+static inline void pause(void)
+{
+ __asm__ __volatile__("pause");
+}
+#elif defined(__aarch64__)
+static inline void pause(void)
+{
+ __asm__ __volatile__("wfi");
+}
+#else
+static inline void pause(void)
+{
+ uint64_t a, b;
+ int x;
+ extern void msleep(unsigned long msecs);
+
+ a = read_counter();
+ for (x = 0; x < 1000; x++) {
+ msleep(1000);
+ b = read_counter();
+ if (a != b)
+ break;
+ }
+}
+#endif
+
+#endif /* !SHIM_ASM_H_ */
+// vim:fenc=utf-8:tw=75:et