]> err.no Git - linux-2.6/blobdiff - arch/x86/kernel/mpparse_64.c
x86: unify uniq_io_apic_id
[linux-2.6] / arch / x86 / kernel / mpparse_64.c
index 83a36eed081bba1d2210ad9c5115acac74ca283f..de64a89434c66be4b030c6ad835ce3c28eaf737a 100644 (file)
@@ -35,7 +35,6 @@
 
 /* Have we found an MP table */
 int smp_found_config;
-unsigned int __cpuinitdata maxcpus = NR_CPUS;
 
 /*
  * Various Linux-internal data structures created from the
@@ -45,35 +44,6 @@ DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
 int mp_bus_id_to_pci_bus[MAX_MP_BUSSES] = {[0 ... MAX_MP_BUSSES - 1] = -1 };
 
 static int mp_current_pci_id = 0;
-/* I/O APIC entries */
-struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
-
-/* # of MP IRQ source entries */
-struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
-
-/* MP IRQ source entries */
-int mp_irq_entries;
-
-int nr_ioapics;
-unsigned long mp_lapic_addr = 0;
-
-/* Processor that is doing the boot up */
-unsigned int boot_cpu_physical_apicid = -1U;
-EXPORT_SYMBOL(boot_cpu_physical_apicid);
-
-/* Internal processor count */
-unsigned int num_processors;
-
-unsigned disabled_cpus __cpuinitdata;
-
-/* Bitmask of physically existing CPUs */
-physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE;
-
-u16 x86_bios_cpu_apicid_init[NR_CPUS] __initdata
-    = {[0 ... NR_CPUS - 1] = BAD_APICID };
-void *x86_bios_cpu_apicid_early_ptr;
-DEFINE_PER_CPU(u16, x86_bios_cpu_apicid) = BAD_APICID;
-EXPORT_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
 
 /*
  * Intel MP BIOS table parsing routines:
@@ -95,60 +65,25 @@ static int __init mpf_checksum(unsigned char *mp, int len)
 
 static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
 {
-       int cpu;
-       cpumask_t tmp_map;
+       int apicid;
        char *bootup_cpu = "";
 
        if (!(m->mpc_cpuflag & CPU_ENABLED)) {
                disabled_cpus++;
                return;
        }
+#ifdef CONFIG_X86_NUMAQ
+       apicid = mpc_apic_id(m, translation_table[mpc_record]);
+#else
+       apicid = m->mpc_apicid;
+#endif
        if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
                bootup_cpu = " (Bootup-CPU)";
                boot_cpu_physical_apicid = m->mpc_apicid;
        }
 
        printk(KERN_INFO "Processor #%d%s\n", m->mpc_apicid, bootup_cpu);
-
-       if (num_processors >= NR_CPUS) {
-               printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
-                      " Processor ignored.\n", NR_CPUS);
-               return;
-       }
-
-       if (num_processors >= maxcpus) {
-               printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
-                      " Processor ignored.\n", maxcpus);
-               return;
-       }
-
-       num_processors++;
-       cpus_complement(tmp_map, cpu_present_map);
-       cpu = first_cpu(tmp_map);
-
-       physid_set(m->mpc_apicid, phys_cpu_present_map);
-       if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
-               /*
-                * x86_bios_cpu_apicid is required to have processors listed
-                * in same order as logical cpu numbers. Hence the first
-                * entry is BSP, and so on.
-                */
-               cpu = 0;
-       }
-       /* are we being called early in kernel startup? */
-       if (x86_cpu_to_apicid_early_ptr) {
-               u16 *cpu_to_apicid = x86_cpu_to_apicid_early_ptr;
-               u16 *bios_cpu_apicid = x86_bios_cpu_apicid_early_ptr;
-
-               cpu_to_apicid[cpu] = m->mpc_apicid;
-               bios_cpu_apicid[cpu] = m->mpc_apicid;
-       } else {
-               per_cpu(x86_cpu_to_apicid, cpu) = m->mpc_apicid;
-               per_cpu(x86_bios_cpu_apicid, cpu) = m->mpc_apicid;
-       }
-
-       cpu_set(cpu, cpu_possible_map);
-       cpu_set(cpu, cpu_present_map);
+       generic_processor_info(apicid, m->mpc_apicver);
 }
 
 static void __init MP_bus_info(struct mpc_config_bus *m)
@@ -157,17 +92,43 @@ static void __init MP_bus_info(struct mpc_config_bus *m)
 
        memcpy(str, m->mpc_bustype, 6);
        str[6] = 0;
+
+#ifdef CONFIG_X86_NUMAQ
+       mpc_oem_bus_info(m, str, translation_table[mpc_record]);
+#else
        Dprintk("Bus #%d is %s\n", m->mpc_busid, str);
+#endif
 
-       if (strncmp(str, "ISA", 3) == 0) {
-               set_bit(m->mpc_busid, mp_bus_not_pci);
-       } else if (strncmp(str, "PCI", 3) == 0) {
+#if MAX_MP_BUSSES < 256
+       if (m->mpc_busid >= MAX_MP_BUSSES) {
+               printk(KERN_WARNING "MP table busid value (%d) for bustype %s "
+                      " is too large, max. supported is %d\n",
+                      m->mpc_busid, str, MAX_MP_BUSSES - 1);
+               return;
+       }
+#endif
+
+       if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA) - 1) == 0) {
+                set_bit(m->mpc_busid, mp_bus_not_pci);
+#if defined(CONFIG_EISA) || defined (CONFIG_MCA)
+               mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
+#endif
+       } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI) - 1) == 0) {
+#ifdef CONFIG_X86_NUMAQ
+               mpc_oem_pci_bus(m, translation_table[mpc_record]);
+#endif
                clear_bit(m->mpc_busid, mp_bus_not_pci);
                mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id;
                mp_current_pci_id++;
-       } else {
-               printk(KERN_ERR "Unknown bustype %s\n", str);
-       }
+#if defined(CONFIG_EISA) || defined (CONFIG_MCA)
+               mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
+       } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA) - 1) == 0) {
+               mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
+       } else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA) - 1) == 0) {
+               mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA;
+#endif
+       } else
+               printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
 }
 
 static int bad_ioapic(unsigned long address)
@@ -227,13 +188,13 @@ static void __init MP_lintsrc_info(struct mpc_config_lintsrc *m)
 static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
 {
        char str[16];
+       char oem[10];
        int count = sizeof(*mpc);
        unsigned char *mpt = ((unsigned char *)mpc) + count;
 
        if (memcmp(mpc->mpc_signature, MPC_SIGNATURE, 4)) {
                printk(KERN_ERR "MPTABLE: bad signature [%c%c%c%c]!\n",
-                      mpc->mpc_signature[0],
-                      mpc->mpc_signature[1],
+                      mpc->mpc_signature[0], mpc->mpc_signature[1],
                       mpc->mpc_signature[2], mpc->mpc_signature[3]);
                return 0;
        }
@@ -250,12 +211,17 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
                printk(KERN_ERR "MPTABLE: null local APIC address!\n");
                return 0;
        }
-       memcpy(str, mpc->mpc_oem, 8);
-       str[8] = 0;
-       printk(KERN_INFO "MPTABLE: OEM ID: %s ", str);
+       memcpy(oem, mpc->mpc_oem, 8);
+       oem[8] = 0;
+       printk(KERN_INFO "MPTABLE: OEM ID: %s ", oem);
 
        memcpy(str, mpc->mpc_productid, 12);
        str[12] = 0;
+       printk("Product ID: %s ", str);
+
+#ifdef CONFIG_X86_32
+       mps_oem_check(mpc, oem, str);
+#endif
        printk(KERN_INFO "MPTABLE: Product ID: %s ", str);
 
        printk(KERN_INFO "MPTABLE: APIC at: 0x%X\n", mpc->mpc_lapic);
@@ -270,12 +236,16 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
        /*
         *      Now process the configuration blocks.
         */
+#ifdef CONFIG_X86_NUMAQ
+       mpc_record = 0;
+#endif
        while (count < mpc->mpc_length) {
                switch (*mpt) {
                case MP_PROCESSOR:
                        {
                                struct mpc_config_processor *m =
                                    (struct mpc_config_processor *)mpt;
+                               /* ACPI may have already provided this data */
                                if (!acpi_lapic)
                                        MP_processor_info(m);
                                mpt += sizeof(*m);
@@ -319,7 +289,15 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
                                count += sizeof(*m);
                                break;
                        }
+               default:
+                       {
+                               count = mpc->mpc_length;
+                               break;
+                       }
                }
+#ifdef CONFIG_X86_NUMAQ
+               ++mpc_record;
+#endif
        }
        setup_apic_routing();
        if (!num_processors)
@@ -423,10 +401,12 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
         * 2 CPUs, numbered 0 & 1.
         */
        processor.mpc_type = MP_PROCESSOR;
-       processor.mpc_apicver = 0;
+       /* Either an integrated APIC or a discrete 82489DX. */
+       processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
        processor.mpc_cpuflag = CPU_ENABLED;
-       processor.mpc_cpufeature = 0;
-       processor.mpc_featureflag = 0;
+       processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) |
+           (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask;
+       processor.mpc_featureflag = boot_cpu_data.x86_capability[0];
        processor.mpc_reserved[0] = 0;
        processor.mpc_reserved[1] = 0;
        for (i = 0; i < 2; i++) {
@@ -445,6 +425,14 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
        case 5:
                memcpy(bus.mpc_bustype, "ISA   ", 6);
                break;
+       case 2:
+       case 6:
+       case 3:
+               memcpy(bus.mpc_bustype, "EISA  ", 6);
+               break;
+       case 4:
+       case 7:
+               memcpy(bus.mpc_bustype, "MCA   ", 6);
        }
        MP_bus_info(&bus);
        if (mpc_default_type > 4) {
@@ -455,7 +443,7 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
 
        ioapic.mpc_type = MP_IOAPIC;
        ioapic.mpc_apicid = 2;
-       ioapic.mpc_apicver = 0;
+       ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
        ioapic.mpc_flags = MPC_APIC_USABLE;
        ioapic.mpc_apicaddr = 0xFEC00000;
        MP_ioapic_info(&ioapic);
@@ -502,7 +490,15 @@ static void __init __get_smp_config(unsigned early)
 
        printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n",
               mpf->mpf_specification);
-
+#ifdef CONFIG_X86_32
+       if (mpf->mpf_feature2 & (1 << 7)) {
+               printk(KERN_INFO "    IMCR and PIC compatibility mode.\n");
+               pic_mode = 1;
+       } else {
+               printk(KERN_INFO "    Virtual Wire compatibility mode.\n");
+               pic_mode = 0;
+       }
+#endif
        /*
         * Now see if we need to read further.
         */
@@ -597,7 +593,30 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
 
                        smp_found_config = 1;
                        mpf_found = mpf;
+#ifdef CONFIG_X86_32
+                       printk(KERN_INFO "found SMP MP-table at [%p] %08lx\n",
+                              mpf, virt_to_phys(mpf));
+                       reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE,
+                                       BOOTMEM_DEFAULT);
+                       if (mpf->mpf_physptr) {
+                               /*
+                                * We cannot access to MPC table to compute
+                                * table size yet, as only few megabytes from
+                                * the bottom is mapped now.
+                                * PC-9800's MPC table places on the very last
+                                * of physical memory; so that simply reserving
+                                * PAGE_SIZE from mpg->mpf_physptr yields BUG()
+                                * in reserve_bootmem.
+                                */
+                               unsigned long size = PAGE_SIZE;
+                               unsigned long end = max_low_pfn * PAGE_SIZE;
+                               if (mpf->mpf_physptr + size > end)
+                                       size = end - mpf->mpf_physptr;
+                               reserve_bootmem(mpf->mpf_physptr, size,
+                                               BOOTMEM_DEFAULT);
+                       }
 
+#else
                        if (!reserve)
                                return 1;
 
@@ -605,7 +624,8 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
                        if (mpf->mpf_physptr)
                                reserve_bootmem_generic(mpf->mpf_physptr,
                                                        PAGE_SIZE);
-                       return 1;
+#endif
+               return 1;
                }
                bp += 4;
                length -= 16;
@@ -665,44 +685,10 @@ void __init find_smp_config(void)
 
 #ifdef CONFIG_ACPI
 
-void __init mp_register_lapic_address(u64 address)
-{
-       mp_lapic_addr = (unsigned long)address;
-       set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
-       if (boot_cpu_physical_apicid == -1U)
-               boot_cpu_physical_apicid  = GET_APIC_ID(apic_read(APIC_ID));
-}
-
-void __cpuinit mp_register_lapic(u8 id, u8 enabled)
-{
-       struct mpc_config_processor processor;
-       int boot_cpu = 0;
-
-       if (id == boot_cpu_physical_apicid)
-               boot_cpu = 1;
-
-       processor.mpc_type = MP_PROCESSOR;
-       processor.mpc_apicid = id;
-       processor.mpc_apicver = 0;
-       processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0);
-       processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0);
-       processor.mpc_cpufeature = 0;
-       processor.mpc_featureflag = 0;
-       processor.mpc_reserved[0] = 0;
-       processor.mpc_reserved[1] = 0;
-
-       MP_processor_info(&processor);
-}
-
 #define MP_ISA_BUS             0
 #define MP_MAX_IOAPIC_PIN      127
 
-static struct mp_ioapic_routing {
-       int apic_id;
-       int gsi_base;
-       int gsi_end;
-       u32 pin_programmed[4];
-} mp_ioapic_routing[MAX_IO_APICS];
+extern struct mp_ioapic_routing mp_ioapic_routing[MAX_IO_APICS];
 
 static int mp_find_ioapic(int gsi)
 {
@@ -721,6 +707,13 @@ static int mp_find_ioapic(int gsi)
 
 static u8 uniq_ioapic_id(u8 id)
 {
+#ifdef CONFIG_X86_32
+       if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
+           !APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
+               return io_apic_get_unique_id(nr_ioapics, id);
+       else
+               return id;
+#else
        int i;
        DECLARE_BITMAP(used, 256);
        bitmap_zero(used, 256);
@@ -731,9 +724,10 @@ static u8 uniq_ioapic_id(u8 id)
        if (!test_bit(id, used))
                return id;
        return find_first_zero_bit(used, 256);
+#endif
 }
 
-void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base)
+void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 {
        int idx = 0;