local_irq_disable()

<kernel v5.0>

Local IRQ 제어

  • local
    • 현재 cpu
  • raw
    • 커널 옵션에 따른 논리적인 구현의 차이
  • arch
    • 아키텍처 의존적인 구현의 차이

 

Local IRQ Disable

 local_irq_disable()

include/linux/irqflags.h”

#define local_irq_disable()     do { raw_local_irq_disable(); } while (0)

현재 CPU의 인터럽트를 disable

 

raw_local_irq_disable()

include/linux/irqflags.h

#define raw_local_irq_disable()         arch_local_irq_disable()

 

arch_local_irq_disable() – ARM

arch/arm/include/asm/irqflags.h

static inline void arch_local_irq_disable(void)
{
        asm volatile(
                "       cpsid i                 @ arch_local_irq_disable"
                :
                :
                : "memory", "cc");
}

 

arch_local_irq_disable() – ARM64

arch/arm64/include/asm/irqflags.h

static inline void arch_local_irq_disable(void)
{
        asm volatile(
                "msr    daifset, #2             // arch_local_irq_disable"
                :
                :
                : "memory");
}

 

Local IRQ Enable

local_irq_enable()

include/linux/irqflags.h”

#define local_irq_enable()      do { raw_local_irq_enable(); } while (0)

현재 CPU의 인터럽트를 enable

 

raw_local_irq_enaable()

include/linux/irqflags.h

#define raw_local_irq_enable()          arch_local_irq_enable()

 

arch_local_irq_enable() – ARM

arch/arm/include/asm/irqflags.h

static inline void arch_local_irq_enable(void)
{
        asm volatile(
                "       cpsie i                 @ arch_local_irq_enable"
                :
                :
                : "memory", "cc");
}

 

arch_local_irq_enable() – ARM64

arch/arm64/include/asm/irqflags.h

static inline void arch_local_irq_enable(void)
{
        asm volatile(
                "msr    daifclr, #2             // arch_local_irq_enable"
                :
                :
                : "memory");
}

 

IRQ 백업 & Disable

local_irq_save()

include/linux/irqflags.h

#define local_irq_save(flags)                                   \
        do {                                                    \
                raw_local_irq_save(flags);                      \
        } while (0)

현재 CPU의 irq 상태를 백업하고 disable 한다.

 

raw_local_irq_save()

include/linux/irqflags.h

#define raw_local_irq_save(flags)                       \
        do {                                            \
                typecheck(unsigned long, flags);        \
                flags = arch_local_irq_save();          \
        } while (0)

현재 CPU의 cpsr값을 변수에 저장한다.

 

arch_local_irq_save() – ARM

arch/arm64/include/asm/irqflags.h

static inline unsigned long arch_local_irq_save(void)
{
        unsigned long flags;

        asm volatile(
                "       mrs     %0, " IRQMASK_REG_NAME_R "      
                "       cpsid   i"
                : "=r" (flags) : : "memory", "cc");
        return flags;
}

#define IRQMASK_REG_NAME_R "cpsr"

 

arch/arm64/include/asm/irqflags.h

static inline unsigned long arch_local_save_flags(void)
{
        unsigned long flags;
        asm volatile(
                "mrs    %0, daif                // arch_local_save_flags"
                : "=r" (flags)
                :
                : "memory");
        return flags;
}

 

IRQ 복귀

local_irq_restore()

include/linux/irqflags.h

#define local_irq_restore(flags) do { raw_local_irq_restore(flags); } while (0)

현재 cpu에서 백업해둔 irq 상태를 복구한다.

 

raw_local_irq_restore()
#define raw_local_irq_restore(flags)                    \
        do {                                            \
                typecheck(unsigned long, flags);        \
                arch_local_irq_restore(flags);          \
        } while (0)

변수에 저장된 cpsr값을 읽어 현재 CPU의 cpsr_c 부분을 변경(현재 CPU의 인터럽트 상태를 저장되었던 상태로 되돌림)

 

arch_local_irq_restore() – ARM

arch/arm/include/asm/irqflags.h

static inline void arch_local_irq_restore(unsigned long flags)
{
        asm volatile(
                "       msr     " IRQMASK_REG_NAME_W ", %0      
                :
                : "r" (flags)
                : "memory", "cc");
}

#define IRQMASK_REG_NAME_W "cpsr_c"

 

arch_local_irq_restore() – ARM64

arch/arm64/include/asm/irqflags.h

static inline void arch_local_irq_restore(unsigned long flags)
{
        asm volatile(
                "msr    daif, %0                // arch_local_irq_restore"
        :
        : "r" (flags)
        : "memory");
}

 

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다