summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <justus@gnupg.org>2016-02-26 17:48:27 +0100
committerJustus Winter <justus@gnupg.org>2016-02-28 00:16:48 +0100
commit55b55f51325893542005763a7e50adcf60548112 (patch)
treeed553ab2c860d0d42789147461948c6d7cbb98c1
parent30426d4313733dc64f08d3d2c2ef3c36df252ef3 (diff)
i386: add parts of cpu.h from x15
* i386/Makefrag.am (libkernel_a_SOURCES): Add new file. * i386/i386/cpu.h: New file.
-rw-r--r--i386/Makefrag.am1
-rw-r--r--i386/i386/cpu.h110
2 files changed, 111 insertions, 0 deletions
diff --git a/i386/Makefrag.am b/i386/Makefrag.am
index 0c5faa32..4e56543f 100644
--- a/i386/Makefrag.am
+++ b/i386/Makefrag.am
@@ -97,6 +97,7 @@ libkernel_a_SOURCES += \
i386/i386/ast.h \
i386/i386/ast_check.c \
i386/i386/ast_types.h \
+ i386/i386/cpu.h \
i386/i386/cpu_number.h \
i386/i386/cswitch.S \
i386/i386/db_disasm.c \
diff --git a/i386/i386/cpu.h b/i386/i386/cpu.h
new file mode 100644
index 00000000..1bf40dce
--- /dev/null
+++ b/i386/i386/cpu.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2010-2014 Richard Braun.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _X86_CPU_H
+#define _X86_CPU_H
+
+#include <kern/macros.h>
+
+/*
+ * EFLAGS register flags.
+ */
+#define CPU_EFL_ONE 0x00000002
+#define CPU_EFL_IF 0x00000200
+
+/*
+ * Return the content of the EFLAGS register.
+ *
+ * Implies a compiler barrier.
+ */
+static __always_inline unsigned long
+cpu_get_eflags(void)
+{
+ unsigned long eflags;
+
+ asm volatile("pushf\n"
+ "pop %0\n"
+ : "=r" (eflags)
+ : : "memory");
+
+ return eflags;
+}
+
+/*
+ * Enable local interrupts.
+ *
+ * Implies a compiler barrier.
+ */
+static __always_inline void
+cpu_intr_enable(void)
+{
+ asm volatile("sti" : : : "memory");
+}
+
+/*
+ * Disable local interrupts.
+ *
+ * Implies a compiler barrier.
+ */
+static __always_inline void
+cpu_intr_disable(void)
+{
+ asm volatile("cli" : : : "memory");
+}
+
+/*
+ * Restore the content of the EFLAGS register, possibly enabling interrupts.
+ *
+ * Implies a compiler barrier.
+ */
+static __always_inline void
+cpu_intr_restore(unsigned long flags)
+{
+ asm volatile("push %0\n"
+ "popf\n"
+ : : "r" (flags)
+ : "memory");
+}
+
+/*
+ * Disable local interrupts, returning the previous content of the EFLAGS
+ * register.
+ *
+ * Implies a compiler barrier.
+ */
+static __always_inline void
+cpu_intr_save(unsigned long *flags)
+{
+ *flags = cpu_get_eflags();
+ cpu_intr_disable();
+}
+
+/*
+ * Return true if interrupts are enabled.
+ *
+ * Implies a compiler barrier.
+ */
+static __always_inline int
+cpu_intr_enabled(void)
+{
+ unsigned long eflags;
+
+ eflags = cpu_get_eflags();
+ return (eflags & CPU_EFL_IF) ? 1 : 0;
+}
+
+#endif /* _X86_CPU_H */