diff options
author | Alan Mayer <ajm@sgi.com> | 2008-04-15 16:36:56 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-05-12 15:28:06 -0400 |
commit | 305b92a2323eeaa4b481f409d54f778dd7e21a46 (patch) | |
tree | 0f32832b033de27b2ae5909bb06d4eabdd1a9b0b | |
parent | 1a331957efd214fc3a84f70956dfaec65e70c031 (diff) |
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: Alan Mayer <ajm@sgi.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | arch/x86/kernel/apic_32.c | 14 | ||||
-rw-r--r-- | arch/x86/kernel/i8259_64.c | 30 | ||||
-rw-r--r-- | arch/x86/kernel/io_apic_32.c | 8 | ||||
-rw-r--r-- | arch/x86/kernel/io_apic_64.c | 6 | ||||
-rw-r--r-- | include/asm-x86/desc.h | 22 | ||||
-rw-r--r-- | include/asm-x86/irq_vectors.h | 2 |
6 files changed, 55 insertions, 27 deletions
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c index 4b99b1bdeb6c..807158e4b5d0 100644 --- a/arch/x86/kernel/apic_32.c +++ b/arch/x86/kernel/apic_32.c | |||
@@ -1351,13 +1351,13 @@ void __init smp_intr_init(void) | |||
1351 | * The reschedule interrupt is a CPU-to-CPU reschedule-helper | 1351 | * The reschedule interrupt is a CPU-to-CPU reschedule-helper |
1352 | * IPI, driven by wakeup. | 1352 | * IPI, driven by wakeup. |
1353 | */ | 1353 | */ |
1354 | set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); | 1354 | alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); |
1355 | 1355 | ||
1356 | /* IPI for invalidation */ | 1356 | /* IPI for invalidation */ |
1357 | set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt); | 1357 | alloc_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt); |
1358 | 1358 | ||
1359 | /* IPI for generic function call */ | 1359 | /* IPI for generic function call */ |
1360 | set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); | 1360 | alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); |
1361 | } | 1361 | } |
1362 | #endif | 1362 | #endif |
1363 | 1363 | ||
@@ -1370,15 +1370,15 @@ void __init apic_intr_init(void) | |||
1370 | smp_intr_init(); | 1370 | smp_intr_init(); |
1371 | #endif | 1371 | #endif |
1372 | /* self generated IPI for local APIC timer */ | 1372 | /* self generated IPI for local APIC timer */ |
1373 | set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); | 1373 | alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); |
1374 | 1374 | ||
1375 | /* IPI vectors for APIC spurious and error interrupts */ | 1375 | /* IPI vectors for APIC spurious and error interrupts */ |
1376 | set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); | 1376 | alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); |
1377 | set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); | 1377 | alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); |
1378 | 1378 | ||
1379 | /* thermal monitor LVT interrupt */ | 1379 | /* thermal monitor LVT interrupt */ |
1380 | #ifdef CONFIG_X86_MCE_P4THERMAL | 1380 | #ifdef CONFIG_X86_MCE_P4THERMAL |
1381 | set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); | 1381 | alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); |
1382 | #endif | 1382 | #endif |
1383 | } | 1383 | } |
1384 | 1384 | ||
diff --git a/arch/x86/kernel/i8259_64.c b/arch/x86/kernel/i8259_64.c index c4ae4769ce67..1870e0e86559 100644 --- a/arch/x86/kernel/i8259_64.c +++ b/arch/x86/kernel/i8259_64.c | |||
@@ -493,33 +493,33 @@ void __init native_init_IRQ(void) | |||
493 | * The reschedule interrupt is a CPU-to-CPU reschedule-helper | 493 | * The reschedule interrupt is a CPU-to-CPU reschedule-helper |
494 | * IPI, driven by wakeup. | 494 | * IPI, driven by wakeup. |
495 | */ | 495 | */ |
496 | set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); | 496 | alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); |
497 | 497 | ||
498 | /* IPIs for invalidation */ | 498 | /* IPIs for invalidation */ |
499 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0); | 499 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0); |
500 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1); | 500 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1); |
501 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2); | 501 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2); |
502 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3); | 502 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3); |
503 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4); | 503 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4); |
504 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5); | 504 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5); |
505 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6); | 505 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6); |
506 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7); | 506 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7); |
507 | 507 | ||
508 | /* IPI for generic function call */ | 508 | /* IPI for generic function call */ |
509 | set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); | 509 | alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); |
510 | 510 | ||
511 | /* Low priority IPI to cleanup after moving an irq */ | 511 | /* Low priority IPI to cleanup after moving an irq */ |
512 | set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); | 512 | set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); |
513 | #endif | 513 | #endif |
514 | set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); | 514 | alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); |
515 | set_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt); | 515 | alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt); |
516 | 516 | ||
517 | /* self generated IPI for local APIC timer */ | 517 | /* self generated IPI for local APIC timer */ |
518 | set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); | 518 | alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); |
519 | 519 | ||
520 | /* IPI vectors for APIC spurious and error interrupts */ | 520 | /* IPI vectors for APIC spurious and error interrupts */ |
521 | set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); | 521 | alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); |
522 | set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); | 522 | alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); |
523 | 523 | ||
524 | if (!acpi_ioapic) | 524 | if (!acpi_ioapic) |
525 | setup_irq(2, &irq2); | 525 | setup_irq(2, &irq2); |
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c index a40d54fc1fdd..0ae4a9d00ce8 100644 --- a/arch/x86/kernel/io_apic_32.c +++ b/arch/x86/kernel/io_apic_32.c | |||
@@ -83,6 +83,10 @@ int mp_irq_entries; | |||
83 | 83 | ||
84 | static int disable_timer_pin_1 __initdata; | 84 | static int disable_timer_pin_1 __initdata; |
85 | 85 | ||
86 | int first_system_vector = 0xfe; | ||
87 | |||
88 | char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE}; | ||
89 | |||
86 | /* | 90 | /* |
87 | * Rough estimation of how many shared IRQs there are, can | 91 | * Rough estimation of how many shared IRQs there are, can |
88 | * be changed anytime. | 92 | * be changed anytime. |
@@ -1176,7 +1180,7 @@ static int __assign_irq_vector(int irq) | |||
1176 | offset = current_offset; | 1180 | offset = current_offset; |
1177 | next: | 1181 | next: |
1178 | vector += 8; | 1182 | vector += 8; |
1179 | if (vector >= FIRST_SYSTEM_VECTOR) { | 1183 | if (vector >= first_system_vector) { |
1180 | offset = (offset + 1) % 8; | 1184 | offset = (offset + 1) % 8; |
1181 | vector = FIRST_DEVICE_VECTOR + offset; | 1185 | vector = FIRST_DEVICE_VECTOR + offset; |
1182 | } | 1186 | } |
@@ -2269,7 +2273,7 @@ void __init setup_IO_APIC(void) | |||
2269 | int i; | 2273 | int i; |
2270 | 2274 | ||
2271 | /* Reserve all the system vectors. */ | 2275 | /* Reserve all the system vectors. */ |
2272 | for (i = FIRST_SYSTEM_VECTOR; i < NR_VECTORS; i++) | 2276 | for (i = first_system_vector; i < NR_VECTORS; i++) |
2273 | set_bit(i, used_vectors); | 2277 | set_bit(i, used_vectors); |
2274 | 2278 | ||
2275 | enable_IO_APIC(); | 2279 | enable_IO_APIC(); |
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index ef1a8dfcc529..f1e1ae3e5c7d 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c | |||
@@ -82,6 +82,10 @@ struct irq_cfg irq_cfg[NR_IRQS] __read_mostly = { | |||
82 | 82 | ||
83 | static int assign_irq_vector(int irq, cpumask_t mask); | 83 | static int assign_irq_vector(int irq, cpumask_t mask); |
84 | 84 | ||
85 | int first_system_vector = 0xfe; | ||
86 | |||
87 | char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE}; | ||
88 | |||
85 | #define __apicdebuginit __init | 89 | #define __apicdebuginit __init |
86 | 90 | ||
87 | int sis_apic_bug; /* not actually supported, dummy for compile */ | 91 | 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 | offset = current_offset; | 734 | offset = current_offset; |
731 | next: | 735 | next: |
732 | vector += 8; | 736 | vector += 8; |
733 | if (vector >= FIRST_SYSTEM_VECTOR) { | 737 | if (vector >= first_system_vector) { |
734 | /* If we run out of vectors on large boxen, must share them. */ | 738 | /* If we run out of vectors on large boxen, must share them. */ |
735 | offset = (offset + 1) % 8; | 739 | offset = (offset + 1) % 8; |
736 | vector = FIRST_DEVICE_VECTOR + offset; | 740 | vector = FIRST_DEVICE_VECTOR + offset; |
diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index 268a012bcd79..b3875d4b4fab 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h | |||
@@ -311,6 +311,28 @@ static inline void set_intr_gate(unsigned int n, void *addr) | |||
311 | _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); | 311 | _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); |
312 | } | 312 | } |
313 | 313 | ||
314 | #define SYS_VECTOR_FREE 0 | ||
315 | #define SYS_VECTOR_ALLOCED 1 | ||
316 | |||
317 | extern int first_system_vector; | ||
318 | extern char system_vectors[]; | ||
319 | |||
320 | static inline void alloc_system_vector(int vector) | ||
321 | { | ||
322 | if (system_vectors[vector] == SYS_VECTOR_FREE) { | ||
323 | system_vectors[vector] = SYS_VECTOR_ALLOCED; | ||
324 | if (first_system_vector > vector) | ||
325 | first_system_vector = vector; | ||
326 | } else | ||
327 | BUG(); | ||
328 | } | ||
329 | |||
330 | static inline void alloc_intr_gate(unsigned int n, void *addr) | ||
331 | { | ||
332 | alloc_system_vector(n); | ||
333 | set_intr_gate(n, addr); | ||
334 | } | ||
335 | |||
314 | /* | 336 | /* |
315 | * This routine sets up an interrupt gate at directory privilege level 3. | 337 | * This routine sets up an interrupt gate at directory privilege level 3. |
316 | */ | 338 | */ |
diff --git a/include/asm-x86/irq_vectors.h b/include/asm-x86/irq_vectors.h index daceaaf0a3a4..3cb6d8c77b39 100644 --- a/include/asm-x86/irq_vectors.h +++ b/include/asm-x86/irq_vectors.h | |||
@@ -96,8 +96,6 @@ | |||
96 | # define FIRST_DEVICE_VECTOR (IRQ15_VECTOR + 2) | 96 | # define FIRST_DEVICE_VECTOR (IRQ15_VECTOR + 2) |
97 | #endif | 97 | #endif |
98 | 98 | ||
99 | #define FIRST_SYSTEM_VECTOR 0xef | ||
100 | |||
101 | #define NR_VECTORS 256 | 99 | #define NR_VECTORS 256 |
102 | 100 | ||
103 | #define FPU_IRQ 13 | 101 | #define FPU_IRQ 13 |