提交 305b92a2 编写于 作者: A Alan Mayer 提交者: Ingo Molnar

x86: change FIRST_SYSTEM_VECTOR to a variable

The SGI UV system needs several more system vectors than a vanilla
x86_64 system.  Rather than burden the other archs with extra system
vectors that they don't use, change FIRST_SYSTEM_VECTOR to a variable,
so that it can be dynamic.
Signed-off-by: NAlan Mayer <ajm@sgi.com>
Signed-off-by: NIngo Molnar <mingo@elte.hu>
Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
上级 1a331957
...@@ -1351,13 +1351,13 @@ void __init smp_intr_init(void) ...@@ -1351,13 +1351,13 @@ void __init smp_intr_init(void)
* The reschedule interrupt is a CPU-to-CPU reschedule-helper * The reschedule interrupt is a CPU-to-CPU reschedule-helper
* IPI, driven by wakeup. * IPI, driven by wakeup.
*/ */
set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
/* IPI for invalidation */ /* IPI for invalidation */
set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt); alloc_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
/* IPI for generic function call */ /* IPI for generic function call */
set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
} }
#endif #endif
...@@ -1370,15 +1370,15 @@ void __init apic_intr_init(void) ...@@ -1370,15 +1370,15 @@ void __init apic_intr_init(void)
smp_intr_init(); smp_intr_init();
#endif #endif
/* self generated IPI for local APIC timer */ /* self generated IPI for local APIC timer */
set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
/* IPI vectors for APIC spurious and error interrupts */ /* IPI vectors for APIC spurious and error interrupts */
set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
/* thermal monitor LVT interrupt */ /* thermal monitor LVT interrupt */
#ifdef CONFIG_X86_MCE_P4THERMAL #ifdef CONFIG_X86_MCE_P4THERMAL
set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
#endif #endif
} }
......
...@@ -493,33 +493,33 @@ void __init native_init_IRQ(void) ...@@ -493,33 +493,33 @@ void __init native_init_IRQ(void)
* The reschedule interrupt is a CPU-to-CPU reschedule-helper * The reschedule interrupt is a CPU-to-CPU reschedule-helper
* IPI, driven by wakeup. * IPI, driven by wakeup.
*/ */
set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
/* IPIs for invalidation */ /* IPIs for invalidation */
set_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0); alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0);
set_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1); alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1);
set_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2); alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2);
set_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3); alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3);
set_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4); alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4);
set_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5); alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5);
set_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6); alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6);
set_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7); alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7);
/* IPI for generic function call */ /* IPI for generic function call */
set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
/* Low priority IPI to cleanup after moving an irq */ /* Low priority IPI to cleanup after moving an irq */
set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
#endif #endif
set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
set_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt); alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
/* self generated IPI for local APIC timer */ /* self generated IPI for local APIC timer */
set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
/* IPI vectors for APIC spurious and error interrupts */ /* IPI vectors for APIC spurious and error interrupts */
set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
if (!acpi_ioapic) if (!acpi_ioapic)
setup_irq(2, &irq2); setup_irq(2, &irq2);
......
...@@ -83,6 +83,10 @@ int mp_irq_entries; ...@@ -83,6 +83,10 @@ int mp_irq_entries;
static int disable_timer_pin_1 __initdata; static int disable_timer_pin_1 __initdata;
int first_system_vector = 0xfe;
char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE};
/* /*
* Rough estimation of how many shared IRQs there are, can * Rough estimation of how many shared IRQs there are, can
* be changed anytime. * be changed anytime.
...@@ -1176,7 +1180,7 @@ static int __assign_irq_vector(int irq) ...@@ -1176,7 +1180,7 @@ static int __assign_irq_vector(int irq)
offset = current_offset; offset = current_offset;
next: next:
vector += 8; vector += 8;
if (vector >= FIRST_SYSTEM_VECTOR) { if (vector >= first_system_vector) {
offset = (offset + 1) % 8; offset = (offset + 1) % 8;
vector = FIRST_DEVICE_VECTOR + offset; vector = FIRST_DEVICE_VECTOR + offset;
} }
...@@ -2269,7 +2273,7 @@ void __init setup_IO_APIC(void) ...@@ -2269,7 +2273,7 @@ void __init setup_IO_APIC(void)
int i; int i;
/* Reserve all the system vectors. */ /* Reserve all the system vectors. */
for (i = FIRST_SYSTEM_VECTOR; i < NR_VECTORS; i++) for (i = first_system_vector; i < NR_VECTORS; i++)
set_bit(i, used_vectors); set_bit(i, used_vectors);
enable_IO_APIC(); enable_IO_APIC();
......
...@@ -82,6 +82,10 @@ struct irq_cfg irq_cfg[NR_IRQS] __read_mostly = { ...@@ -82,6 +82,10 @@ struct irq_cfg irq_cfg[NR_IRQS] __read_mostly = {
static int assign_irq_vector(int irq, cpumask_t mask); static int assign_irq_vector(int irq, cpumask_t mask);
int first_system_vector = 0xfe;
char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE};
#define __apicdebuginit __init #define __apicdebuginit __init
int sis_apic_bug; /* not actually supported, dummy for compile */ int sis_apic_bug; /* not actually supported, dummy for compile */
...@@ -730,7 +734,7 @@ static int __assign_irq_vector(int irq, cpumask_t mask) ...@@ -730,7 +734,7 @@ static int __assign_irq_vector(int irq, cpumask_t mask)
offset = current_offset; offset = current_offset;
next: next:
vector += 8; vector += 8;
if (vector >= FIRST_SYSTEM_VECTOR) { if (vector >= first_system_vector) {
/* If we run out of vectors on large boxen, must share them. */ /* If we run out of vectors on large boxen, must share them. */
offset = (offset + 1) % 8; offset = (offset + 1) % 8;
vector = FIRST_DEVICE_VECTOR + offset; vector = FIRST_DEVICE_VECTOR + offset;
......
...@@ -311,6 +311,28 @@ static inline void set_intr_gate(unsigned int n, void *addr) ...@@ -311,6 +311,28 @@ static inline void set_intr_gate(unsigned int n, void *addr)
_set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS);
} }
#define SYS_VECTOR_FREE 0
#define SYS_VECTOR_ALLOCED 1
extern int first_system_vector;
extern char system_vectors[];
static inline void alloc_system_vector(int vector)
{
if (system_vectors[vector] == SYS_VECTOR_FREE) {
system_vectors[vector] = SYS_VECTOR_ALLOCED;
if (first_system_vector > vector)
first_system_vector = vector;
} else
BUG();
}
static inline void alloc_intr_gate(unsigned int n, void *addr)
{
alloc_system_vector(n);
set_intr_gate(n, addr);
}
/* /*
* This routine sets up an interrupt gate at directory privilege level 3. * This routine sets up an interrupt gate at directory privilege level 3.
*/ */
......
...@@ -96,8 +96,6 @@ ...@@ -96,8 +96,6 @@
# define FIRST_DEVICE_VECTOR (IRQ15_VECTOR + 2) # define FIRST_DEVICE_VECTOR (IRQ15_VECTOR + 2)
#endif #endif
#define FIRST_SYSTEM_VECTOR 0xef
#define NR_VECTORS 256 #define NR_VECTORS 256
#define FPU_IRQ 13 #define FPU_IRQ 13
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册