--- linux/include/asm-i386/apicdef.h.orig Thu Apr 13 06:06:12 2000 +++ linux/include/asm-i386/apicdef.h Thu Apr 13 06:06:23 2000 @@ -7,7 +7,8 @@ * Alan Cox , 1995. * Ingo Molnar , 1999, 2000 */ -#define APIC_PHYS_BASE 0xfee00000 /* IA s/w dev Vol 3, Section 7.4 */ + +#define APIC_DEFAULT_PHYS_BASE 0xfee00000 #define APIC_ID 0x20 #define GET_APIC_ID(x) (((x)>>24)&0x0F) --- linux/include/asm-i386/hw_irq.h.orig Thu Apr 13 06:06:08 2000 +++ linux/include/asm-i386/hw_irq.h Thu Apr 13 06:22:31 2000 @@ -27,36 +27,34 @@ */ /* - * Special IRQ vectors used by the SMP architecture, 0x30-0x4f + * 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. + * + * Vectors 0xf0-0xfa are free (reserved for future Linux use). */ -#define INVALIDATE_TLB_VECTOR 0x30 -#define LOCAL_TIMER_VECTOR 0x31 -#define RESCHEDULE_VECTOR 0x40 - -/* 'rare' vectors: */ -#define CALL_FUNCTION_VECTOR 0x41 +#define SPURIOUS_APIC_VECTOR 0xff +#define ERROR_APIC_VECTOR 0xfe +#define INVALIDATE_TLB_VECTOR 0xfd +#define RESCHEDULE_VECTOR 0xfc +#define CALL_FUNCTION_VECTOR 0xfb /* - * These IRQs should never really happen on perfect hardware running - * a perfect kernel, but we nevertheless print a message to catch the - * rest ;) Subtle, the APIC architecture mandates the spurious vector - * to have bits 0-3 set to 1. Note that these vectors do not occur - * normally, so we violate the 'only 2 vectors per priority level' - * rule here. + * 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 SPURIOUS_APIC_VECTOR 0x3f -#define ERROR_APIC_VECTOR 0x43 +#define LOCAL_TIMER_VECTOR 0xef /* - * First APIC vector available to drivers: (vectors 0x51-0xfe) - * we start at 0x51 to spread out vectors between priority levels - * evenly. (note that 0x80 is the syscall vector) + * 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 IRQ0_TRAP_VECTOR 0x51 +#define FIRST_DEVICE_VECTOR 0x31 +#define FIRST_SYSTEM_VECTOR 0xef extern int irq_vector[NR_IRQS]; #define IO_APIC_VECTOR(irq) irq_vector[irq] --- linux/arch/i386/kernel/mpparse.c.orig Thu Apr 13 06:06:11 2000 +++ linux/arch/i386/kernel/mpparse.c Thu Apr 13 06:06:23 2000 @@ -50,11 +50,6 @@ unsigned long phys_cpu_present_map = 0; /* - * IA s/w dev Vol 3, Section 7.4 - */ -#define APIC_DEFAULT_PHYS_BASE 0xfee00000 - -/* * Intel MP BIOS table parsing routines: */ @@ -65,10 +60,12 @@ static int __init mpf_checksum(unsigned char *mp, int len) { - int sum=0; - while(len--) - sum+=*mp++; - return sum&0xFF; + int sum = 0; + + while (len--) + sum += *mp++; + + return sum & 0xFF; } /* @@ -433,7 +430,7 @@ lintsrc.mpc_irqflag = 0; /* conforming */ lintsrc.mpc_srcbusid = 0; lintsrc.mpc_srcbusirq = 0; - lintsrc.mpc_destapic = MP_APIC_ALL; + lintsrc.mpc_destapic = 0x3; for (i = 0; i < 2; i++) { lintsrc.mpc_irqtype = linttypes[i]; lintsrc.mpc_destapiclint = i; --- linux/arch/i386/kernel/apic.c.orig Thu Apr 13 06:06:11 2000 +++ linux/arch/i386/kernel/apic.c Thu Apr 13 06:06:23 2000 @@ -30,11 +30,6 @@ int prof_old_multiplier[NR_CPUS] = { 1, }; int prof_counter[NR_CPUS] = { 1, }; -/* - * IA s/w dev Vol 3, Section 7.4 - */ -#define APIC_DEFAULT_PHYS_BASE 0xfee00000 - int get_maxlvt(void) { unsigned int v, ver, maxlvt; --- linux/arch/i386/kernel/traps.c.orig Thu Apr 13 06:05:48 2000 +++ linux/arch/i386/kernel/traps.c Thu Apr 13 06:06:23 2000 @@ -790,7 +790,7 @@ * On normal SMP PC this is used only with SMP, but we have to * use it and set it up here to start the Cobalt clock */ - set_fixmap(FIX_APIC_BASE, APIC_PHYS_BASE); + set_fixmap(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE); printk("Local APIC ID %lx\n", apic_read(APIC_ID)); printk("Local APIC Version %lx\n", apic_read(APIC_LVR)); --- linux/arch/i386/kernel/io_apic.c.orig Thu Apr 13 06:06:11 2000 +++ linux/arch/i386/kernel/io_apic.c Thu Apr 13 06:26:42 2000 @@ -48,6 +48,11 @@ /* MP IRQ source entries */ int mp_irq_entries = 0; +#if CONFIG_SMP +# define TARGET_CPUS cpu_online_map +#else +# define TARGET_CPUS 0x01 +#endif /* * Rough estimation of how many shared IRQs there are, can * be changed anytime. @@ -89,7 +94,7 @@ entry->pin = pin; } -#define __DO_ACTION(name,R,ACTION, FINAL) \ +#define __DO_ACTION(R, ACTION, FINAL) \ \ { \ int pin; \ @@ -112,8 +117,8 @@ #define DO_ACTION(name,R,ACTION, FINAL) \ \ -static void name##_IO_APIC_irq(unsigned int irq) \ -__DO_ACTION(name,R,ACTION, FINAL) + static void name##_IO_APIC_irq (unsigned int irq) \ + __DO_ACTION(R, ACTION, FINAL) DO_ACTION( __mask, 0, |= 0x00010000, io_apic_sync(entry->apic))/* mask = 1 */ DO_ACTION( __unmask, 0, &= 0xfffeffff, ) /* mask = 0 */ @@ -542,25 +547,26 @@ return 0; } -int irq_vector[NR_IRQS] = { IRQ0_TRAP_VECTOR , 0 }; +int irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 }; static int __init assign_irq_vector(int irq) { - static int current_vector = IRQ0_TRAP_VECTOR, offset = 0; + static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; if (IO_APIC_VECTOR(irq) > 0) return IO_APIC_VECTOR(irq); - if (current_vector == 0xFF) - panic("ran out of interrupt sources!"); next: current_vector += 8; if (current_vector == SYSCALL_VECTOR) goto next; - if (current_vector > 0xFF) { + if (current_vector > FIRST_SYSTEM_VECTOR) { offset++; - current_vector = IRQ0_TRAP_VECTOR + offset; + current_vector = FIRST_DEVICE_VECTOR + offset; } + if (current_vector == FIRST_SYSTEM_VECTOR) + panic("ran out of interrupt sources!"); + IO_APIC_VECTOR(irq) = current_vector; return current_vector; } @@ -587,7 +593,7 @@ entry.delivery_mode = dest_LowestPrio; entry.dest_mode = 1; /* logical delivery */ entry.mask = 0; /* enable IRQ */ - entry.dest.logical.logical_dest = APIC_ALL_CPUS; + entry.dest.logical.logical_dest = TARGET_CPUS; idx = find_irq_entry(apic,pin,mp_INT); if (idx == -1) { @@ -605,7 +611,7 @@ if (irq_trigger(idx)) { entry.trigger = 1; entry.mask = 1; - entry.dest.logical.logical_dest = APIC_ALL_CPUS; + entry.dest.logical.logical_dest = TARGET_CPUS; } irq = pin_2_irq(idx, apic, pin); @@ -660,7 +666,7 @@ */ entry.dest_mode = 1; /* logical delivery */ entry.mask = 0; /* unmask IRQ now */ - entry.dest.logical.logical_dest = APIC_ALL_CPUS; + entry.dest.logical.logical_dest = TARGET_CPUS; entry.delivery_mode = dest_LowestPrio; entry.polarity = 0; entry.trigger = 0; @@ -1167,7 +1173,7 @@ mask = mask << 24; spin_lock_irqsave(&ioapic_lock, flags); - __DO_ACTION( target, 1, = mask, ) + __DO_ACTION(1, = mask, ) spin_unlock_irqrestore(&ioapic_lock, flags); } --- linux/arch/i386/kernel/irq.c.orig Thu Apr 13 06:06:11 2000 +++ linux/arch/i386/kernel/irq.c Thu Apr 13 06:06:23 2000 @@ -1117,7 +1117,8 @@ struct proc_dir_entry *entry; char name [MAX_NAMELEN]; - if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type)) + if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) || + irq_dir[irq]) return; memset(name, 0, MAX_NAMELEN); @@ -1158,10 +1159,7 @@ /* * Create entries for all existing IRQs. */ - for (i = 0; i < NR_IRQS; i++) { - if (irq_desc[i].handler == &no_irq_type) - continue; + for (i = 0; i < NR_IRQS; i++) register_irq_proc(i); - } } --- linux/arch/i386/kernel/i8259.c.orig Thu Apr 13 06:06:11 2000 +++ linux/arch/i386/kernel/i8259.c Thu Apr 13 06:06:23 2000 @@ -456,7 +456,7 @@ * IRQ0 must be given a fixed assignment and initialized, * because it's used before the IO-APIC is set up. */ - set_intr_gate(IRQ0_TRAP_VECTOR, interrupt[0]); + set_intr_gate(FIRST_DEVICE_VECTOR, interrupt[0]); /* * The reschedule interrupt is a CPU-to-CPU reschedule-helper