#define local_save_flags(flags) \
do { \
// raw_local_save_flags(flags);
typecheck(unsigned long, flags); \
flags = arch_local_save_flags(); \
} while (0)
static inline unsigned long arch_local_save_flags(void){
// return native_save_fl();
unsigned long flags;
// “=rm”在这里是安全的,
// 因为“pop”在评估其有效地址之前会调整堆栈——这是“pop”指令的记录行为的一部分。
asm volatile("# __raw_save_flags\n\t"
// 先将 flags 寄存器压栈,然后再弹出到 flags 对应的寄存器中
"pushf ; pop %0"
: "=rm" (flags) // r:编译器指定一个寄存器,m:数据也会输出到内存中
: /* no input */
: "memory");
return flags;
}
#define local_irq_restore(flags) \
do { \
// if (raw_irqs_disabled_flags(flags)) {
if ({ \
typecheck(unsigned long, flags); \
arch_irqs_disabled_flags(flags); \
}) {
// 如果 IF 的值是0(禁用中断),则中断启用成功。
// raw_local_irq_restore(flags);
typecheck(unsigned long, flags);
arch_local_irq_restore(flags);
// trace_hardirqs_off();
} else { \
// 如果 IF 的值是1(启用中断),则说明原本中断就是打开的。
// trace_hardirqs_on();
// raw_local_irq_restore(flags);
typecheck(unsigned long, flags);
arch_local_irq_restore(flags);
} \
} while (0)
static inline int arch_irqs_disabled_flags(unsigned long flags) {
// X86_EFLAGS_IF = 0x00000200。右边数第10是 IF 标志位
return !(flags & X86_EFLAGS_IF);
}
static inline void arch_local_irq_restore(unsigned long flags) {
// native_restore_fl(flags);
// 将 flags 压栈,并弹出到 flags 寄存器中
asm volatile("push %0 ; popf"
: /* no output */
:"g" (flags)
:"memory", "cc"); // 本次操作修改了内存,和标志寄存器
}
#define local_irq_enable() \
do { \
// trace_hardirqs_on();
// raw_local_irq_enable();
arch_local_irq_enable();
} while (0)
#define local_irq_disable() \
do { \
// raw_local_irq_disable();
arch_local_irq_disable();
// trace_hardirqs_off();
} while (0)
static inline void arch_local_irq_enable(void) {
// native_irq_enable();
// 启用中断
asm volatile("sti": : :"memory");
}
static inline void arch_local_irq_disable(void) {
// native_irq_disable();
// 禁用中断
asm volatile("cli": : :"memory");
}