Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 305b92a2 authored by Alan Mayer's avatar Alan Mayer Committed by Ingo Molnar
Browse files

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: default avatarAlan Mayer <ajm@sgi.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 1a331957
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -1351,13 +1351,13 @@ void __init smp_intr_init(void)
	 * The reschedule interrupt is a CPU-to-CPU reschedule-helper
	 * IPI, driven by wakeup.
	 */
	set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
	alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);

	/* IPI for invalidation */
	set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
	alloc_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);

	/* IPI for generic function call */
	set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
	alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
}
#endif

@@ -1370,15 +1370,15 @@ void __init apic_intr_init(void)
	smp_intr_init();
#endif
	/* 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 */
	set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
	set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
	alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
	alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);

	/* thermal monitor LVT interrupt */
#ifdef CONFIG_X86_MCE_P4THERMAL
	set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
	alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
#endif
}

+15 −15
Original line number Diff line number Diff line
@@ -493,33 +493,33 @@ void __init native_init_IRQ(void)
	 * The reschedule interrupt is a CPU-to-CPU reschedule-helper
	 * IPI, driven by wakeup.
	 */
	set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
	alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);

	/* IPIs for invalidation */
	set_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0);
	set_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1);
	set_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2);
	set_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3);
	set_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4);
	set_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5);
	set_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+0, invalidate_interrupt0);
	alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1);
	alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2);
	alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3);
	alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4);
	alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5);
	alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6);
	alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7);

	/* 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 */
	set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
#endif
	set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
	set_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
	alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
	alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);

	/* 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 */
	set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
	set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
	alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
	alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);

	if (!acpi_ioapic)
		setup_irq(2, &irq2);
+6 −2
Original line number Diff line number Diff line
@@ -83,6 +83,10 @@ int mp_irq_entries;

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
 * be changed anytime.
@@ -1176,7 +1180,7 @@ static int __assign_irq_vector(int irq)
	offset = current_offset;
next:
	vector += 8;
	if (vector >= FIRST_SYSTEM_VECTOR) {
	if (vector >= first_system_vector) {
		offset = (offset + 1) % 8;
		vector = FIRST_DEVICE_VECTOR + offset;
	}
@@ -2269,7 +2273,7 @@ void __init setup_IO_APIC(void)
	int i;

	/* 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);

	enable_IO_APIC();
+5 −1
Original line number Diff line number Diff line
@@ -82,6 +82,10 @@ struct irq_cfg irq_cfg[NR_IRQS] __read_mostly = {

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

int sis_apic_bug; /* not actually supported, dummy for compile */
@@ -730,7 +734,7 @@ static int __assign_irq_vector(int irq, cpumask_t mask)
		offset = current_offset;
next:
		vector += 8;
		if (vector >= FIRST_SYSTEM_VECTOR) {
		if (vector >= first_system_vector) {
			/* If we run out of vectors on large boxen, must share them. */
			offset = (offset + 1) % 8;
			vector = FIRST_DEVICE_VECTOR + offset;
+22 −0
Original line number Diff line number Diff line
@@ -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);
}

#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.
 */
Loading