Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / x86_64 / kernel / mpparse.c
index 61a63be..083da7e 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include <linux/mm.h>
-#include <linux/irq.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/config.h>
@@ -23,6 +22,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/mc146818rtc.h>
 #include <linux/acpi.h>
+#include <linux/module.h>
 
 #include <asm/smp.h>
 #include <asm/mtrr.h>
@@ -42,10 +42,9 @@ int acpi_found_madt;
  * Various Linux-internal data structures created from the
  * MP-table.
  */
-int apic_version [MAX_APICS];
+unsigned char apic_version [MAX_APICS];
 unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
 int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
-cpumask_t pci_bus_to_cpumask [256] = { [0 ... 255] = CPU_MASK_ALL };
 
 static int mp_current_pci_id = 0;
 /* I/O APIC entries */
@@ -66,13 +65,15 @@ unsigned long mp_lapic_addr = 0;
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_id = -1U;
 /* Internal processor count */
-static unsigned int num_processors = 0;
+unsigned int num_processors __initdata = 0;
+
+unsigned disabled_cpus __initdata;
 
 /* Bitmask of physically existing CPUs */
 physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE;
 
 /* ACPI MADT entry parsing functions */
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
 extern struct acpi_boot_flags acpi_boot;
 #ifdef CONFIG_X86_LOCAL_APIC
 extern int acpi_parse_lapic (acpi_table_entry_header *header);
@@ -82,7 +83,7 @@ extern int acpi_parse_lapic_nmi (acpi_table_entry_header *header);
 #ifdef CONFIG_X86_IO_APIC
 extern int acpi_parse_ioapic (acpi_table_entry_header *header);
 #endif /*CONFIG_X86_IO_APIC*/
-#endif /*CONFIG_ACPI_BOOT*/
+#endif /*CONFIG_ACPI*/
 
 u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
 
@@ -105,13 +106,16 @@ static int __init mpf_checksum(unsigned char *mp, int len)
        return sum & 0xFF;
 }
 
-static void __init MP_processor_info (struct mpc_config_processor *m)
+static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
 {
-       int ver;
-       static int found_bsp=0;
+       int cpu;
+       unsigned char ver;
+       cpumask_t tmp_map;
 
-       if (!(m->mpc_cpuflag & CPU_ENABLED))
+       if (!(m->mpc_cpuflag & CPU_ENABLED)) {
+               disabled_cpus++;
                return;
+       }
 
        printk(KERN_INFO "Processor #%d %d:%d APIC version %d\n",
                m->mpc_apicid,
@@ -130,12 +134,16 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
        }
 
        num_processors++;
+       cpus_complement(tmp_map, cpu_present_map);
+       cpu = first_cpu(tmp_map);
 
-       if (m->mpc_apicid > MAX_APICS) {
+#if MAX_APICS < 255    
+       if ((int)m->mpc_apicid > MAX_APICS) {
                printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n",
                        m->mpc_apicid, MAX_APICS);
                return;
        }
+#endif
        ver = m->mpc_apicver;
 
        physid_set(m->mpc_apicid, phys_cpu_present_map);
@@ -153,13 +161,13 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
                 * in same order as logical cpu numbers. Hence the first
                 * entry is BSP, and so on.
                 */
-               bios_cpu_apicid[0] = m->mpc_apicid;
-               x86_cpu_to_apicid[0] = m->mpc_apicid;
-               found_bsp = 1;
-       } else {
-               bios_cpu_apicid[num_processors - found_bsp] = m->mpc_apicid;
-               x86_cpu_to_apicid[num_processors - found_bsp] = m->mpc_apicid;
+               cpu = 0;
        }
+       bios_cpu_apicid[cpu] = m->mpc_apicid;
+       x86_cpu_to_apicid[cpu] = m->mpc_apicid;
+
+       cpu_set(cpu, cpu_possible_map);
+       cpu_set(cpu, cpu_present_map);
 }
 
 static void __init MP_bus_info (struct mpc_config_bus *m)
@@ -214,7 +222,7 @@ static void __init MP_intsrc_info (struct mpc_config_intsrc *m)
                        m->mpc_irqtype, m->mpc_irqflag & 3,
                        (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus,
                        m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq);
-       if (++mp_irq_entries == MAX_IRQ_SOURCES)
+       if (++mp_irq_entries >= MAX_IRQ_SOURCES)
                panic("Max # of irq sources exceeded!!\n");
 }
 
@@ -277,9 +285,9 @@ static int __init smp_read_mpc(struct mp_config_table *mpc)
 
        memcpy(str,mpc->mpc_productid,12);
        str[12]=0;
-       printk(KERN_INFO "Product ID: %s ",str);
+       printk("Product ID: %s ",str);
 
-       printk(KERN_INFO "APIC at: 0x%X\n",mpc->mpc_lapic);
+       printk("APIC at: 0x%X\n",mpc->mpc_lapic);
 
        /* save the local APIC address, it might be non-default */
        if (!acpi_lapic)
@@ -512,8 +520,6 @@ void __init get_smp_config (void)
        struct intel_mp_floating *mpf = mpf_found;
 
        /*
-        * ACPI may be used to obtain the entire SMP configuration or just to 
-        * enumerate/configure processors (CONFIG_ACPI_BOOT).  Note that 
         * ACPI supports both logical (e.g. Hyper-Threading) and physical 
         * processors, where MPS only supports physical.
         */
@@ -547,7 +553,7 @@ void __init get_smp_config (void)
                 * Read the physical hardware table.  Anything here will
                 * override the defaults.
                 */
-               if (!smp_read_mpc((void *)(unsigned long)mpf->mpf_physptr)) {
+               if (!smp_read_mpc(phys_to_virt(mpf->mpf_physptr))) {
                        smp_found_config = 0;
                        printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
                        printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
@@ -666,7 +672,7 @@ void __init find_smp_config (void)
                             ACPI-based MP Configuration
    -------------------------------------------------------------------------- */
 
-#ifdef CONFIG_ACPI_BOOT
+#ifdef CONFIG_ACPI
 
 void __init mp_register_lapic_address (
        u64                     address)
@@ -682,7 +688,7 @@ void __init mp_register_lapic_address (
 }
 
 
-void __init mp_register_lapic (
+void __cpuinit mp_register_lapic (
        u8                      id, 
        u8                      enabled)
 {
@@ -700,7 +706,7 @@ void __init mp_register_lapic (
 
        processor.mpc_type = MP_PROCESSOR;
        processor.mpc_apicid = id;
-       processor.mpc_apicver = 0x10; /* TBD: lapic version */
+       processor.mpc_apicver = GET_APIC_VERSION(apic_read(APIC_LVR));
        processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0);
        processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0);
        processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | 
@@ -904,20 +910,27 @@ void __init mp_config_acpi_legacy_irqs (void)
        return;
 }
 
-int mp_register_gsi(u32 gsi, int edge_level, int active_high_low)
+#define MAX_GSI_NUM    4096
+
+int mp_register_gsi(u32 gsi, int triggering, int polarity)
 {
        int                     ioapic = -1;
        int                     ioapic_pin = 0;
        int                     idx, bit = 0;
+       static int              pci_irq = 16;
+       /*
+        * Mapping between Global System Interrupts, which
+        * represent all possible interrupts, to the IRQs
+        * assigned to actual devices.
+        */
+       static int              gsi_to_irq[MAX_GSI_NUM];
 
        if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
                return gsi;
 
-#ifdef CONFIG_ACPI_BUS
        /* Don't set up the ACPI SCI because it's already set up */
        if (acpi_fadt.sci_int == gsi)
                return gsi;
-#endif
 
        ioapic = mp_find_ioapic(gsi);
        if (ioapic < 0) {
@@ -943,16 +956,47 @@ int mp_register_gsi(u32 gsi, int edge_level, int active_high_low)
        if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
                Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
                        mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
-               return gsi;
+               return gsi_to_irq[gsi];
        }
 
        mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
 
+       if (triggering == ACPI_LEVEL_SENSITIVE) {
+               /*
+                * For PCI devices assign IRQs in order, avoiding gaps
+                * due to unused I/O APIC pins.
+                */
+               int irq = gsi;
+               if (gsi < MAX_GSI_NUM) {
+                       /*
+                        * Retain the VIA chipset work-around (gsi > 15), but
+                        * avoid a problem where the 8254 timer (IRQ0) is setup
+                        * via an override (so it's not on pin 0 of the ioapic),
+                        * and at the same time, the pin 0 interrupt is a PCI
+                        * type.  The gsi > 15 test could cause these two pins
+                        * to be shared as IRQ0, and they are not shareable.
+                        * So test for this condition, and if necessary, avoid
+                        * the pin collision.
+                        */
+                       if (gsi > 15 || (gsi == 0 && !timer_uses_ioapic_pin_0))
+                               gsi = pci_irq++;
+                       /*
+                        * Don't assign IRQ used by ACPI SCI
+                        */
+                       if (gsi == acpi_fadt.sci_int)
+                               gsi = pci_irq++;
+                       gsi_to_irq[irq] = gsi;
+               } else {
+                       printk(KERN_ERR "GSI %u is too high\n", gsi);
+                       return gsi;
+               }
+       }
+
        io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
-               edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
-               active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
+               triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
+               polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
        return gsi;
 }
 
 #endif /*CONFIG_X86_IO_APIC*/
-#endif /*CONFIG_ACPI_BOOT*/
+#endif /*CONFIG_ACPI*/