blob: c1cdd094938e8db589344154e5455affcc0a3bc2 [file] [log] [blame]
Ingo Molnar55f327f2006-07-03 00:24:43 -07001/*
2 * include/asm-i386/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
Ingo Molnarc8558fc2006-07-03 00:24:44 -07008 * raw_local_irq_*() functions from the lowlevel headers.
Ingo Molnar55f327f2006-07-03 00:24:43 -07009 */
10#ifndef _ASM_IRQFLAGS_H
11#define _ASM_IRQFLAGS_H
12
Rusty Russell90a0a062007-05-02 19:27:10 +020013#ifndef __ASSEMBLY__
14static inline unsigned long native_save_fl(void)
15{
16 unsigned long f;
17 asm volatile("pushfl ; popl %0":"=g" (f): /* no input */);
18 return f;
19}
20
21static inline void native_restore_fl(unsigned long f)
22{
23 asm volatile("pushl %0 ; popfl": /* no output */
24 :"g" (f)
25 :"memory", "cc");
26}
27
28static inline void native_irq_disable(void)
29{
30 asm volatile("cli": : :"memory");
31}
32
33static inline void native_irq_enable(void)
34{
35 asm volatile("sti": : :"memory");
36}
37
38static inline void native_safe_halt(void)
39{
40 asm volatile("sti; hlt": : :"memory");
41}
42
43static inline void native_halt(void)
44{
45 asm volatile("hlt": : :"memory");
46}
47#endif /* __ASSEMBLY__ */
48
Rusty Russelld3561b72006-12-07 02:14:07 +010049#ifdef CONFIG_PARAVIRT
50#include <asm/paravirt.h>
51#else
Ingo Molnarc8558fc2006-07-03 00:24:44 -070052#ifndef __ASSEMBLY__
Ingo Molnar55f327f2006-07-03 00:24:43 -070053
Ingo Molnarc8558fc2006-07-03 00:24:44 -070054static inline unsigned long __raw_local_save_flags(void)
55{
Rusty Russell90a0a062007-05-02 19:27:10 +020056 return native_save_fl();
Ingo Molnarc8558fc2006-07-03 00:24:44 -070057}
58
Ingo Molnarc8558fc2006-07-03 00:24:44 -070059static inline void raw_local_irq_restore(unsigned long flags)
60{
Rusty Russell90a0a062007-05-02 19:27:10 +020061 native_restore_fl(flags);
Ingo Molnarc8558fc2006-07-03 00:24:44 -070062}
63
64static inline void raw_local_irq_disable(void)
65{
Rusty Russell90a0a062007-05-02 19:27:10 +020066 native_irq_disable();
Ingo Molnarc8558fc2006-07-03 00:24:44 -070067}
68
69static inline void raw_local_irq_enable(void)
70{
Rusty Russell90a0a062007-05-02 19:27:10 +020071 native_irq_enable();
Ingo Molnarc8558fc2006-07-03 00:24:44 -070072}
73
74/*
75 * Used in the idle loop; sti takes one instruction cycle
76 * to complete:
77 */
78static inline void raw_safe_halt(void)
79{
Rusty Russell90a0a062007-05-02 19:27:10 +020080 native_safe_halt();
Ingo Molnarc8558fc2006-07-03 00:24:44 -070081}
82
83/*
84 * Used when interrupts are already enabled or to
85 * shutdown the processor:
86 */
87static inline void halt(void)
88{
Rusty Russell90a0a062007-05-02 19:27:10 +020089 native_halt();
Ingo Molnarc8558fc2006-07-03 00:24:44 -070090}
91
Ingo Molnarc8558fc2006-07-03 00:24:44 -070092/*
93 * For spinlocks, etc:
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
Rusty Russelld3561b72006-12-07 02:14:07 +0100104#else
Rusty Russell139ec7c2006-12-07 02:14:08 +0100105#define DISABLE_INTERRUPTS(clobbers) cli
106#define ENABLE_INTERRUPTS(clobbers) sti
Rusty Russelld3561b72006-12-07 02:14:07 +0100107#define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
108#define INTERRUPT_RETURN iret
109#define GET_CR0_INTO_EAX movl %cr0, %eax
110#endif /* __ASSEMBLY__ */
111#endif /* CONFIG_PARAVIRT */
112
113#ifndef __ASSEMBLY__
114#define raw_local_save_flags(flags) \
115 do { (flags) = __raw_local_save_flags(); } while (0)
116
Ingo Molnarc8558fc2006-07-03 00:24:44 -0700117#define raw_local_irq_save(flags) \
118 do { (flags) = __raw_local_irq_save(); } while (0)
119
Rusty Russelld3561b72006-12-07 02:14:07 +0100120static inline int raw_irqs_disabled_flags(unsigned long flags)
121{
122 return !(flags & (1 << 9));
123}
124
125static inline int raw_irqs_disabled(void)
126{
127 unsigned long flags = __raw_local_save_flags();
128
129 return raw_irqs_disabled_flags(flags);
130}
Ingo Molnarc8558fc2006-07-03 00:24:44 -0700131#endif /* __ASSEMBLY__ */
Ingo Molnar55f327f2006-07-03 00:24:43 -0700132
133/*
134 * Do the CPU's IRQ-state tracing from assembly code. We call a
135 * C function, so save all the C-clobbered registers:
136 */
137#ifdef CONFIG_TRACE_IRQFLAGS
138
139# define TRACE_IRQS_ON \
140 pushl %eax; \
141 pushl %ecx; \
142 pushl %edx; \
143 call trace_hardirqs_on; \
144 popl %edx; \
145 popl %ecx; \
146 popl %eax;
147
148# define TRACE_IRQS_OFF \
149 pushl %eax; \
150 pushl %ecx; \
151 pushl %edx; \
152 call trace_hardirqs_off; \
153 popl %edx; \
154 popl %ecx; \
155 popl %eax;
156
157#else
158# define TRACE_IRQS_ON
159# define TRACE_IRQS_OFF
160#endif
161
162#endif