1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _ASM_X86_IRQ_VECTORS_H |
3 | #define _ASM_X86_IRQ_VECTORS_H |
4 | |
5 | #include <linux/threads.h> |
6 | /* |
7 | * Linux IRQ vector layout. |
8 | * |
9 | * There are 256 IDT entries (per CPU - each entry is 8 bytes) which can |
10 | * be defined by Linux. They are used as a jump table by the CPU when a |
11 | * given vector is triggered - by a CPU-external, CPU-internal or |
12 | * software-triggered event. |
13 | * |
14 | * Linux sets the kernel code address each entry jumps to early during |
15 | * bootup, and never changes them. This is the general layout of the |
16 | * IDT entries: |
17 | * |
18 | * Vectors 0 ... 31 : system traps and exceptions - hardcoded events |
19 | * Vectors 32 ... 127 : device interrupts |
20 | * Vector 128 : legacy int80 syscall interface |
21 | * Vectors 129 ... LOCAL_TIMER_VECTOR-1 |
22 | * Vectors LOCAL_TIMER_VECTOR ... 255 : special interrupts |
23 | * |
24 | * 64-bit x86 has per CPU IDT tables, 32-bit has one shared IDT table. |
25 | * |
26 | * This file enumerates the exact layout of them: |
27 | */ |
28 | |
29 | /* This is used as an interrupt vector when programming the APIC. */ |
30 | #define NMI_VECTOR 0x02 |
31 | |
32 | /* |
33 | * IDT vectors usable for external interrupt sources start at 0x20. |
34 | * (0x80 is the syscall vector, 0x30-0x3f are for ISA) |
35 | */ |
36 | #define FIRST_EXTERNAL_VECTOR 0x20 |
37 | |
38 | #define IA32_SYSCALL_VECTOR 0x80 |
39 | |
40 | /* |
41 | * Vectors 0x30-0x3f are used for ISA interrupts. |
42 | * round up to the next 16-vector boundary |
43 | */ |
44 | #define ISA_IRQ_VECTOR(irq) (((FIRST_EXTERNAL_VECTOR + 16) & ~15) + irq) |
45 | |
46 | /* |
47 | * Special IRQ vectors used by the SMP architecture, 0xf0-0xff |
48 | * |
49 | * some of the following vectors are 'rare', they are merged |
50 | * into a single vector (CALL_FUNCTION_VECTOR) to save vector space. |
51 | * TLB, reschedule and local APIC vectors are performance-critical. |
52 | */ |
53 | |
54 | #define SPURIOUS_APIC_VECTOR 0xff |
55 | /* |
56 | * Sanity check |
57 | */ |
58 | #if ((SPURIOUS_APIC_VECTOR & 0x0F) != 0x0F) |
59 | # error SPURIOUS_APIC_VECTOR definition error |
60 | #endif |
61 | |
62 | #define ERROR_APIC_VECTOR 0xfe |
63 | #define RESCHEDULE_VECTOR 0xfd |
64 | #define CALL_FUNCTION_VECTOR 0xfc |
65 | #define CALL_FUNCTION_SINGLE_VECTOR 0xfb |
66 | #define THERMAL_APIC_VECTOR 0xfa |
67 | #define THRESHOLD_APIC_VECTOR 0xf9 |
68 | #define REBOOT_VECTOR 0xf8 |
69 | |
70 | /* |
71 | * Generic system vector for platform specific use |
72 | */ |
73 | #define X86_PLATFORM_IPI_VECTOR 0xf7 |
74 | |
75 | /* |
76 | * IRQ work vector: |
77 | */ |
78 | #define IRQ_WORK_VECTOR 0xf6 |
79 | |
80 | /* 0xf5 - unused, was UV_BAU_MESSAGE */ |
81 | #define DEFERRED_ERROR_VECTOR 0xf4 |
82 | |
83 | /* Vector on which hypervisor callbacks will be delivered */ |
84 | #define HYPERVISOR_CALLBACK_VECTOR 0xf3 |
85 | |
86 | /* Vector for KVM to deliver posted interrupt IPI */ |
87 | #ifdef CONFIG_HAVE_KVM |
88 | #define POSTED_INTR_VECTOR 0xf2 |
89 | #define POSTED_INTR_WAKEUP_VECTOR 0xf1 |
90 | #define POSTED_INTR_NESTED_VECTOR 0xf0 |
91 | #endif |
92 | |
93 | #define MANAGED_IRQ_SHUTDOWN_VECTOR 0xef |
94 | |
95 | #if IS_ENABLED(CONFIG_HYPERV) |
96 | #define HYPERV_REENLIGHTENMENT_VECTOR 0xee |
97 | #define HYPERV_STIMER0_VECTOR 0xed |
98 | #endif |
99 | |
100 | #define LOCAL_TIMER_VECTOR 0xec |
101 | |
102 | #define NR_VECTORS 256 |
103 | |
104 | #ifdef CONFIG_X86_LOCAL_APIC |
105 | #define FIRST_SYSTEM_VECTOR LOCAL_TIMER_VECTOR |
106 | #else |
107 | #define FIRST_SYSTEM_VECTOR NR_VECTORS |
108 | #endif |
109 | |
110 | #define NR_EXTERNAL_VECTORS (FIRST_SYSTEM_VECTOR - FIRST_EXTERNAL_VECTOR) |
111 | #define NR_SYSTEM_VECTORS (NR_VECTORS - FIRST_SYSTEM_VECTOR) |
112 | |
113 | /* |
114 | * Size the maximum number of interrupts. |
115 | * |
116 | * If the irq_desc[] array has a sparse layout, we can size things |
117 | * generously - it scales up linearly with the maximum number of CPUs, |
118 | * and the maximum number of IO-APICs, whichever is higher. |
119 | * |
120 | * In other cases we size more conservatively, to not create too large |
121 | * static arrays. |
122 | */ |
123 | |
124 | #define NR_IRQS_LEGACY 16 |
125 | |
126 | #define CPU_VECTOR_LIMIT (64 * NR_CPUS) |
127 | #define IO_APIC_VECTOR_LIMIT (32 * MAX_IO_APICS) |
128 | |
129 | #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_PCI_MSI) |
130 | #define NR_IRQS \ |
131 | (CPU_VECTOR_LIMIT > IO_APIC_VECTOR_LIMIT ? \ |
132 | (NR_VECTORS + CPU_VECTOR_LIMIT) : \ |
133 | (NR_VECTORS + IO_APIC_VECTOR_LIMIT)) |
134 | #elif defined(CONFIG_X86_IO_APIC) |
135 | #define NR_IRQS (NR_VECTORS + IO_APIC_VECTOR_LIMIT) |
136 | #elif defined(CONFIG_PCI_MSI) |
137 | #define NR_IRQS (NR_VECTORS + CPU_VECTOR_LIMIT) |
138 | #else |
139 | #define NR_IRQS NR_IRQS_LEGACY |
140 | #endif |
141 | |
142 | #endif /* _ASM_X86_IRQ_VECTORS_H */ |
143 | |