内核的中断分布

对于x86架构,定义位于arch/x86/include/asm/irq_vectors.h文件中,linux每可使用的有256个IDT(Interrupt Descriptor Table)表项,64位架构每个CPU有一个IDT表,32位架构共享一个IDT表,其分布如下:

 *  Vectors   0  ...  31 : system traps and exceptions - hardcoded events
                           系统陷阱和异常中断向量
 *  Vectors   32 ... 127 : device interrupts
                           设备中断向量
 *  Vector    128        : legacy int80 syscall interface
                           系统调用中断向量
 *  Vectors   129 ... INVALIDATE_TLB_VECTOR_START-1 except 204 : device interrupts
                                                                 设备中断向量(204除外)
 *  Vectors   INVALIDATE_TLB_VECTOR_START ... 255 : special interrupts
                                                    特殊中断向量

1. 内部中断向量

IDT表项0…31称为CPU-internal中断向量,由相同陷阱和异常中断使用。

2. 外部中断向量

中断向量32为第一个外部中断向量。

/*
 * IDT vectors usable for external interrupt sources start at 0x20.
 * (0x80 is the syscall vector, 0x30-0x3f are for ISA)
 */
#define FIRST_EXTERNAL_VECTOR       0x20

其中,0x80用作系统调用中断使用。

#define IA32_SYSCALL_VECTOR     0x80

0x30-0x3f保留给ISA中断使用。

/*
 * Vectors 0x30-0x3f are used for ISA interrupts.
 *   round up to the next 16-vector boundary
 */
#define ISA_IRQ_VECTOR(irq)     (((FIRST_EXTERNAL_VECTOR + 16) & ~15) + irq)

其余的中断向量可分配给设备使用。

3. 系统中断

内核由大到小从255开始,分配系统中断。

#define SPURIOUS_APIC_VECTOR        0xff
#define ERROR_APIC_VECTOR       0xfe
#define RESCHEDULE_VECTOR       0xfd
#define CALL_FUNCTION_VECTOR        0xfc
#define CALL_FUNCTION_SINGLE_VECTOR 0xfb
#define THERMAL_APIC_VECTOR     0xfa
#define THRESHOLD_APIC_VECTOR       0xf9
#define REBOOT_VECTOR           0xf8

/* Generic system vector for platform specific use */
#define X86_PLATFORM_IPI_VECTOR     0xf7

/* IRQ work vector: */
#define IRQ_WORK_VECTOR         0xf6

#define UV_BAU_MESSAGE          0xf5
#define DEFERRED_ERROR_VECTOR       0xf4

/* Vector on which hypervisor callbacks will be delivered */
#define HYPERVISOR_CALLBACK_VECTOR  0xf3

/* Vector for KVM to deliver posted interrupt IPI */
#ifdef CONFIG_HAVE_KVM
#define POSTED_INTR_VECTOR      0xf2
#define POSTED_INTR_WAKEUP_VECTOR   0xf1
#define POSTED_INTR_NESTED_VECTOR   0xf0
#endif

#define MANAGED_IRQ_SHUTDOWN_VECTOR 0xef

#if IS_ENABLED(CONFIG_HYPERV)
#define HYPERV_REENLIGHTENMENT_VECTOR   0xee
#define HYPERV_STIMER0_VECTOR       0xed
#endif

#define LOCAL_TIMER_VECTOR      0xec

#define NR_VECTORS           256

#ifdef CONFIG_X86_LOCAL_APIC
#define FIRST_SYSTEM_VECTOR     LOCAL_TIMER_VECTOR
#else
#define FIRST_SYSTEM_VECTOR     NR_VECTORS
#endif 

最小的系统中断定义为FIRST_SYSTEM_VECTOR,在定义了CONFIG_X86_LOCAL_APIC的情况下,其等于0xec(LOCAL_TIMER_VECTOR).

4. 中断数量

对于传统中断,不支持IO_APIC,也不支持PCI_MSI的情况下,中断数量为16(NR_IRQS_LEGACY)。

#define NR_IRQS_LEGACY          16

#define CPU_VECTOR_LIMIT        (64 * NR_CPUS)
#define IO_APIC_VECTOR_LIMIT    (32 * MAX_IO_APICS)

#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_PCI_MSI)
#define NR_IRQS                     \
    (CPU_VECTOR_LIMIT > IO_APIC_VECTOR_LIMIT ?  \
        (NR_VECTORS + CPU_VECTOR_LIMIT)  :  \
        (NR_VECTORS + IO_APIC_VECTOR_LIMIT))
#elif defined(CONFIG_X86_IO_APIC)
#define NR_IRQS             (NR_VECTORS + IO_APIC_VECTOR_LIMIT)
#elif defined(CONFIG_PCI_MSI)
#define NR_IRQS             (NR_VECTORS + CPU_VECTOR_LIMIT)
#else
#define NR_IRQS             NR_IRQS_LEGACY
#endif

在支持CONFIG_X86_IO_APIC和CONFIG_PCI_MSI的情况下,中断数量为CPU_VECTOR_LIMIT和IO_APIC_VECTOR_LIMIT两者中的最大值与NR_VECTORS(256)之和。

实际的中断数量与处理器和APIC的数量有关。

内核版本 5.0

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页