/* * include/asm-i386/irqflags.h * * IRQ flags handling * * This file gets included from lowlevel asm headers too, to provide * wrapped versions of the local_irq_*() APIs, based on the * raw_local_irq_*() functions from the lowlevel headers. */ #ifndef _ASM_IRQFLAGS_H #define _ASM_IRQFLAGS_H #ifndef __ASSEMBLY__ static inline unsigned long __raw_local_save_flags(void) { unsigned long flags; __asm__ __volatile__( "pushfl ; popl %0" : "=g" (flags) : /* no input */ ); return flags; } #define raw_local_save_flags(flags) \ do { (flags) = __raw_local_save_flags(); } while (0) static inline void raw_local_irq_restore(unsigned long flags) { __asm__ __volatile__( "pushl %0 ; popfl" : /* no output */ :"g" (flags) :"memory", "cc" ); } static inline void raw_local_irq_disable(void) { __asm__ __volatile__("cli" : : : "memory"); } static inline void raw_local_irq_enable(void) { __asm__ __volatile__("sti" : : : "memory"); } /* * Used in the idle loop; sti takes one instruction cycle * to complete: */ static inline void raw_safe_halt(void) { __asm__ __volatile__("sti; hlt" : : : "memory"); } /* * Used when interrupts are already enabled or to * shutdown the processor: */ static inline void halt(void) { __asm__ __volatile__("hlt": : :"memory"); } static inline int raw_irqs_disabled_flags(unsigned long flags) { return !(flags & (1 << 9)); } static inline int raw_irqs_disabled(void) { unsigned long flags = __raw_local_save_flags(); return raw_irqs_disabled_flags(flags); } /* * For spinlocks, etc: */ static inline unsigned long __raw_local_irq_save(void) { unsigned long flags = __raw_local_save_flags(); raw_local_irq_disable(); return flags; } #define raw_local_irq_save(flags) \ do { (flags) = __raw_local_irq_save(); } while (0) #endif /* __ASSEMBLY__ */ /* * Do the CPU's IRQ-state tracing from assembly code. We call a * C function, so save all the C-clobbered registers: */ #ifdef CONFIG_TRACE_IRQFLAGS # define TRACE_IRQS_ON \ pushl %eax; \ pushl %ecx; \ pushl %edx; \ call trace_hardirqs_on; \ popl %edx; \ popl %ecx; \ popl %eax; # define TRACE_IRQS_OFF \ pushl %eax; \ pushl %ecx; \ pushl %edx; \ call trace_hardirqs_off; \ popl %edx; \ popl %ecx; \ popl %eax; #else # define TRACE_IRQS_ON # define TRACE_IRQS_OFF #endif #endif