diff options
author | Justus Winter <justus@gnupg.org> | 2016-02-26 17:48:27 +0100 |
---|---|---|
committer | Justus Winter <justus@gnupg.org> | 2016-02-26 17:49:52 +0100 |
commit | d8210eecee55d4848b391fef280fe1b5afc84201 (patch) | |
tree | 9dac382c6e8f2f7bac5b39969252d579ca468ddf /i386 | |
parent | 6d18c2969e248918fc663fd3ee309fb6f8f481c4 (diff) |
i386: add parts of cpu.h from x15
* i386/Makefrag.am (libkernel_a_SOURCES): Add new file.
* i386/i386/cpu.h: New file.
Diffstat (limited to 'i386')
-rw-r--r-- | i386/Makefrag.am | 1 | ||||
-rw-r--r-- | i386/i386/cpu.h | 110 |
2 files changed, 111 insertions, 0 deletions
diff --git a/i386/Makefrag.am b/i386/Makefrag.am index 0c5faa3..4e56543 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 0000000..1bf40dc --- /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 */ |