mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-25 05:34:00 +08:00
99d113b17e
Reclaim 16 IDT vectors and make them available for general allocation. Reclaim vectors 0x20-0x2f by reallocating the IRQ_MOVE_CLEANUP_VECTOR to vector 0x1f. This is in the range of vector numbers that is officially reserved for the CPU (for exceptions), however, the use of the APIC to generate any vector 0x10 or above is documented, and the CPU internally can receive any vector number (the legacy BIOS uses INT 0x08-0x0f for interrupts, as messed up as that is.) Since IRQ_MOVE_CLEANUP_VECTOR has to be alone in the lowest-numbered priority level (block of 16), this effectively enables us to reclaim an otherwise-unusable APIC priority level and put it to use. Since this is a transient kernel-only allocation we can change it at any time, and if/when there is an exception at vector 0x1f this assignment needs to be changed as part of OS enabling that new feature. Signed-off-by: Yinghai Lu <yinghai@kernel.org> LKML-Reference: <4B4284C6.9030107@kernel.org> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
190 lines
5.5 KiB
C
190 lines
5.5 KiB
C
#ifndef _ASM_X86_IRQ_VECTORS_H
|
|
#define _ASM_X86_IRQ_VECTORS_H
|
|
|
|
/*
|
|
* Linux IRQ vector layout.
|
|
*
|
|
* There are 256 IDT entries (per CPU - each entry is 8 bytes) which can
|
|
* be defined by Linux. They are used as a jump table by the CPU when a
|
|
* given vector is triggered - by a CPU-external, CPU-internal or
|
|
* software-triggered event.
|
|
*
|
|
* Linux sets the kernel code address each entry jumps to early during
|
|
* bootup, and never changes them. This is the general layout of the
|
|
* IDT entries:
|
|
*
|
|
* Vectors 0 ... 31 : system traps and exceptions - hardcoded events
|
|
* Vectors 32 ... 127 : device interrupts
|
|
* Vector 128 : legacy int80 syscall interface
|
|
* Vectors 129 ... 237 : device interrupts
|
|
* Vectors 238 ... 255 : special interrupts
|
|
*
|
|
* 64-bit x86 has per CPU IDT tables, 32-bit has one shared IDT table.
|
|
*
|
|
* This file enumerates the exact layout of them:
|
|
*/
|
|
|
|
#define NMI_VECTOR 0x02
|
|
#define MCE_VECTOR 0x12
|
|
|
|
/*
|
|
* IDT vectors usable for external interrupt sources start
|
|
* at 0x20:
|
|
* hpa said we can start from 0x1f.
|
|
* 0x1f is documented as reserved. However, the ability for the APIC
|
|
* to generate vectors starting at 0x10 is documented, as is the
|
|
* ability for the CPU to receive any vector number as an interrupt.
|
|
* 0x1f is used for IRQ_MOVE_CLEANUP_VECTOR since that vector needs
|
|
* an entire privilege level (16 vectors) all by itself at a higher
|
|
* priority than any actual device vector. Thus, by placing it in the
|
|
* otherwise-unusable 0x10 privilege level, we avoid wasting a full
|
|
* 16-vector block.
|
|
*/
|
|
#define FIRST_EXTERNAL_VECTOR 0x1f
|
|
|
|
#define IA32_SYSCALL_VECTOR 0x80
|
|
#ifdef CONFIG_X86_32
|
|
# define SYSCALL_VECTOR 0x80
|
|
#endif
|
|
|
|
/*
|
|
* Reserve the lowest usable priority level 0x10 - 0x1f for triggering
|
|
* cleanup after irq migration.
|
|
* this overlaps with the reserved range for cpu exceptions so this
|
|
* will need to be changed to 0x20 - 0x2f if the last cpu exception is
|
|
* ever allocated.
|
|
*/
|
|
|
|
#define IRQ_MOVE_CLEANUP_VECTOR FIRST_EXTERNAL_VECTOR
|
|
|
|
/*
|
|
* Vectors 0x20-0x2f are used for ISA interrupts.
|
|
* round up to the next 16-vector boundary
|
|
*/
|
|
#define IRQ0_VECTOR ((FIRST_EXTERNAL_VECTOR + 16) & ~15)
|
|
|
|
#define IRQ1_VECTOR (IRQ0_VECTOR + 1)
|
|
#define IRQ2_VECTOR (IRQ0_VECTOR + 2)
|
|
#define IRQ3_VECTOR (IRQ0_VECTOR + 3)
|
|
#define IRQ4_VECTOR (IRQ0_VECTOR + 4)
|
|
#define IRQ5_VECTOR (IRQ0_VECTOR + 5)
|
|
#define IRQ6_VECTOR (IRQ0_VECTOR + 6)
|
|
#define IRQ7_VECTOR (IRQ0_VECTOR + 7)
|
|
#define IRQ8_VECTOR (IRQ0_VECTOR + 8)
|
|
#define IRQ9_VECTOR (IRQ0_VECTOR + 9)
|
|
#define IRQ10_VECTOR (IRQ0_VECTOR + 10)
|
|
#define IRQ11_VECTOR (IRQ0_VECTOR + 11)
|
|
#define IRQ12_VECTOR (IRQ0_VECTOR + 12)
|
|
#define IRQ13_VECTOR (IRQ0_VECTOR + 13)
|
|
#define IRQ14_VECTOR (IRQ0_VECTOR + 14)
|
|
#define IRQ15_VECTOR (IRQ0_VECTOR + 15)
|
|
|
|
/*
|
|
* Special IRQ vectors used by the SMP architecture, 0xf0-0xff
|
|
*
|
|
* some of the following vectors are 'rare', they are merged
|
|
* into a single vector (CALL_FUNCTION_VECTOR) to save vector space.
|
|
* TLB, reschedule and local APIC vectors are performance-critical.
|
|
*/
|
|
|
|
#define SPURIOUS_APIC_VECTOR 0xff
|
|
/*
|
|
* Sanity check
|
|
*/
|
|
#if ((SPURIOUS_APIC_VECTOR & 0x0F) != 0x0F)
|
|
# error SPURIOUS_APIC_VECTOR definition error
|
|
#endif
|
|
|
|
#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
|
|
|
|
/* f0-f7 used for spreading out TLB flushes: */
|
|
#define INVALIDATE_TLB_VECTOR_END 0xf7
|
|
#define INVALIDATE_TLB_VECTOR_START 0xf0
|
|
#define NUM_INVALIDATE_TLB_VECTORS 8
|
|
|
|
/*
|
|
* Local APIC timer IRQ vector is on a different priority level,
|
|
* to work around the 'lost local interrupt if more than 2 IRQ
|
|
* sources per level' errata.
|
|
*/
|
|
#define LOCAL_TIMER_VECTOR 0xef
|
|
|
|
/*
|
|
* Generic system vector for platform specific use
|
|
*/
|
|
#define X86_PLATFORM_IPI_VECTOR 0xed
|
|
|
|
/*
|
|
* Performance monitoring pending work vector:
|
|
*/
|
|
#define LOCAL_PENDING_VECTOR 0xec
|
|
|
|
#define UV_BAU_MESSAGE 0xea
|
|
|
|
/*
|
|
* Self IPI vector for machine checks
|
|
*/
|
|
#define MCE_SELF_VECTOR 0xeb
|
|
|
|
/*
|
|
* First APIC vector available to drivers: (vectors 0x30-0xee) we
|
|
* start at 0x31 to spread out vectors evenly between priority
|
|
* levels. (0x80 is the syscall vector)
|
|
*/
|
|
#define FIRST_DEVICE_VECTOR (IRQ15_VECTOR + 2)
|
|
|
|
#define NR_VECTORS 256
|
|
|
|
#define FPU_IRQ 13
|
|
|
|
#define FIRST_VM86_IRQ 3
|
|
#define LAST_VM86_IRQ 15
|
|
|
|
#ifndef __ASSEMBLY__
|
|
static inline int invalid_vm86_irq(int irq)
|
|
{
|
|
return irq < FIRST_VM86_IRQ || irq > LAST_VM86_IRQ;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Size the maximum number of interrupts.
|
|
*
|
|
* If the irq_desc[] array has a sparse layout, we can size things
|
|
* generously - it scales up linearly with the maximum number of CPUs,
|
|
* and the maximum number of IO-APICs, whichever is higher.
|
|
*
|
|
* In other cases we size more conservatively, to not create too large
|
|
* static arrays.
|
|
*/
|
|
|
|
#define NR_IRQS_LEGACY 16
|
|
|
|
#define IO_APIC_VECTOR_LIMIT ( 32 * MAX_IO_APICS )
|
|
|
|
#ifdef CONFIG_X86_IO_APIC
|
|
# ifdef CONFIG_SPARSE_IRQ
|
|
# define CPU_VECTOR_LIMIT (64 * NR_CPUS)
|
|
# define NR_IRQS \
|
|
(CPU_VECTOR_LIMIT > IO_APIC_VECTOR_LIMIT ? \
|
|
(NR_VECTORS + CPU_VECTOR_LIMIT) : \
|
|
(NR_VECTORS + IO_APIC_VECTOR_LIMIT))
|
|
# else
|
|
# define CPU_VECTOR_LIMIT (32 * NR_CPUS)
|
|
# define NR_IRQS \
|
|
(CPU_VECTOR_LIMIT < IO_APIC_VECTOR_LIMIT ? \
|
|
(NR_VECTORS + CPU_VECTOR_LIMIT) : \
|
|
(NR_VECTORS + IO_APIC_VECTOR_LIMIT))
|
|
# endif
|
|
#else /* !CONFIG_X86_IO_APIC: */
|
|
# define NR_IRQS NR_IRQS_LEGACY
|
|
#endif
|
|
|
|
#endif /* _ASM_X86_IRQ_VECTORS_H */
|