1/* 2 * include/asm-x86_64/irqflags.h 3 * 4 * IRQ flags handling 5 * 6 * This file gets included from lowlevel asm headers too, to provide 7 * wrapped versions of the local_irq_*() APIs, based on the 8 * raw_local_irq_*() functions from the lowlevel headers. 9 */ 10#ifndef _ASM_IRQFLAGS_H 11#define _ASM_IRQFLAGS_H 12#include <asm/processor-flags.h> 13 14#ifndef __ASSEMBLY__ 15/* 16 * Interrupt control: 17 */ 18 19static inline unsigned long __raw_local_save_flags(void) 20{ 21 unsigned long flags; 22 23 __asm__ __volatile__( 24 "# __raw_save_flags\n\t" 25 "pushfq ; popq %q0" 26 : "=g" (flags) 27 : /* no input */ 28 : "memory" 29 ); 30 31 return flags; 32} 33 34#define raw_local_save_flags(flags) \ 35 do { (flags) = __raw_local_save_flags(); } while (0) 36 37static inline void raw_local_irq_restore(unsigned long flags) 38{ 39 __asm__ __volatile__( 40 "pushq %0 ; popfq" 41 : /* no output */ 42 :"g" (flags) 43 :"memory", "cc" 44 ); 45} 46 47#ifdef CONFIG_X86_VSMP 48 49/* 50 * Interrupt control for the VSMP architecture: 51 */ 52 53static inline void raw_local_irq_disable(void) 54{ 55 unsigned long flags = __raw_local_save_flags(); 56 57 raw_local_irq_restore((flags & ~X86_EFLAGS_IF) | X86_EFLAGS_AC); 58} 59 60static inline void raw_local_irq_enable(void) 61{ 62 unsigned long flags = __raw_local_save_flags(); 63 64 raw_local_irq_restore((flags | X86_EFLAGS_IF) & (~X86_EFLAGS_AC)); 65} 66 67static inline int raw_irqs_disabled_flags(unsigned long flags) 68{ 69 return !(flags & X86_EFLAGS_IF) || (flags & X86_EFLAGS_AC); 70} 71 72#else /* CONFIG_X86_VSMP */ 73 74static inline void raw_local_irq_disable(void) 75{ 76 __asm__ __volatile__("cli" : : : "memory"); 77} 78 79static inline void raw_local_irq_enable(void) 80{ 81 __asm__ __volatile__("sti" : : : "memory"); 82} 83 84static inline int raw_irqs_disabled_flags(unsigned long flags) 85{ 86 return !(flags & X86_EFLAGS_IF); 87} 88 89#endif 90 91/* 92 * For spinlocks, etc.: 93 */ 94 95static inline unsigned long __raw_local_irq_save(void) 96{ 97 unsigned long flags = __raw_local_save_flags(); 98 99 raw_local_irq_disable(); 100 101 return flags; 102} 103 104#define raw_local_irq_save(flags) \ 105 do { (flags) = __raw_local_irq_save(); } while (0) 106 107static inline int raw_irqs_disabled(void) 108{ 109 unsigned long flags = __raw_local_save_flags(); 110 111 return raw_irqs_disabled_flags(flags); 112} 113 114/* 115 * Used in the idle loop; sti takes one instruction cycle 116 * to complete: 117 */ 118static inline void raw_safe_halt(void) 119{ 120 __asm__ __volatile__("sti; hlt" : : : "memory"); 121} 122 123/* 124 * Used when interrupts are already enabled or to 125 * shutdown the processor: 126 */ 127static inline void halt(void) 128{ 129 __asm__ __volatile__("hlt": : :"memory"); 130} 131 132#else /* __ASSEMBLY__: */ 133# ifdef CONFIG_TRACE_IRQFLAGS 134# define TRACE_IRQS_ON call trace_hardirqs_on_thunk 135# define TRACE_IRQS_OFF call trace_hardirqs_off_thunk 136# else 137# define TRACE_IRQS_ON 138# define TRACE_IRQS_OFF 139# endif 140#endif 141 142#endif 143