X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=arch%2Fx86%2Fkernel%2Fmpparse_32.c;h=15dd87110298371e2c7e033776874fc0f502ccfd;hb=864205062f1c752c80077be8ec2b15c81f4a6525;hp=b2aded3fbfec6ae6bf330e5924a3525a67d8ce93;hpb=7b1292e2371e3ae2ac69fbb899d539ddc7b53a27;p=linux-2.6 diff --git a/arch/x86/kernel/mpparse_32.c b/arch/x86/kernel/mpparse_32.c index b2aded3fbf..15dd871102 100644 --- a/arch/x86/kernel/mpparse_32.c +++ b/arch/x86/kernel/mpparse_32.c @@ -27,11 +27,11 @@ #include #include #include +#include #include #include #include -#include /* Have we found an MP table */ int smp_found_config; @@ -42,10 +42,10 @@ unsigned int __cpuinitdata maxcpus = NR_CPUS; * MP-table. */ int apic_version [MAX_APICS]; +#if defined (CONFIG_MCA) || defined (CONFIG_EISA) int mp_bus_id_to_type [MAX_MP_BUSSES]; -int mp_bus_id_to_node [MAX_MP_BUSSES]; -int mp_bus_id_to_local [MAX_MP_BUSSES]; -int quad_local_to_mp_bus_id [NR_CPUS/4][4]; +#endif +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; @@ -75,7 +75,9 @@ unsigned disabled_cpus __cpuinitdata; /* Bitmask of physically existing CPUs */ physid_mask_t phys_cpu_present_map; -u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; +#ifndef CONFIG_SMP +DEFINE_PER_CPU(u16, x86_bios_cpu_apicid) = BAD_APICID; +#endif /* * Intel MP BIOS table parsing routines: @@ -96,6 +98,7 @@ static int __init mpf_checksum(unsigned char *mp, int len) return sum & 0xFF; } +#ifdef CONFIG_X86_NUMAQ /* * Have to match translation table entries to main table entries by counter * hence the mpc_record variable .... can't see a less disgusting way of @@ -104,10 +107,12 @@ static int __init mpf_checksum(unsigned char *mp, int len) static int mpc_record; static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __cpuinitdata; +#endif static void __cpuinit MP_processor_info (struct mpc_config_processor *m) { - int ver, apicid; + int ver, apicid, cpu; + cpumask_t tmp_map; physid_mask_t phys_cpu; if (!(m->mpc_cpuflag & CPU_ENABLED)) { @@ -115,7 +120,16 @@ static void __cpuinit MP_processor_info (struct mpc_config_processor *m) return; } +#ifdef CONFIG_X86_NUMAQ apicid = mpc_apic_id(m, translation_table[mpc_record]); +#else + Dprintk("Processor #%d %u:%u APIC version %d\n", + m->mpc_apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, + (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, + m->mpc_apicver); + apicid = m->mpc_apicid; +#endif if (m->mpc_featureflag&(1<<0)) Dprintk(" Floating point unit present.\n"); @@ -200,6 +214,16 @@ static void __cpuinit MP_processor_info (struct mpc_config_processor *m) cpu_set(num_processors, cpu_possible_map); num_processors++; + cpus_complement(tmp_map, cpu_present_map); + cpu = first_cpu(tmp_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; /* * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y @@ -220,7 +244,20 @@ static void __cpuinit MP_processor_info (struct mpc_config_processor *m) def_to_bigsmp = 1; } } - bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; +#ifdef CONFIG_SMP + /* 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[num_processors - 1] = m->mpc_apicid; + } else { + per_cpu(x86_cpu_to_apicid, cpu) = m->mpc_apicid; + per_cpu(x86_bios_cpu_apicid, cpu) = m->mpc_apicid; + } +#endif + cpu_set(cpu, cpu_present_map); } static void __init MP_bus_info (struct mpc_config_bus *m) @@ -230,7 +267,11 @@ 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 MAX_MP_BUSSES < 256 if (m->mpc_busid >= MAX_MP_BUSSES) { @@ -241,20 +282,41 @@ static void __init MP_bus_info (struct mpc_config_bus *m) } #endif - if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { - mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; - } 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_PCI, sizeof(BUSTYPE_PCI)-1) == 0) { + set_bit(m->mpc_busid, mp_bus_not_pci); + if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) { +#ifdef CONFIG_X86_NUMAQ mpc_oem_pci_bus(m, translation_table[mpc_record]); - mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI; +#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++; +#if defined(CONFIG_EISA) || defined (CONFIG_MCA) + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI; + } else if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; + } 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; } else { printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str); +#endif + } +} + +static int bad_ioapic(unsigned long address) +{ + if (nr_ioapics >= MAX_IO_APICS) { + printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " + "(found %d)\n", MAX_IO_APICS, nr_ioapics); + panic("Recompile kernel with bigger MAX_IO_APICS!\n"); + } + if (!address) { + printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" + " found in table, skipping!\n"); + return 1; } + return 0; } static void __init MP_ioapic_info (struct mpc_config_ioapic *m) @@ -264,16 +326,10 @@ static void __init MP_ioapic_info (struct mpc_config_ioapic *m) printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n", m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr); - if (nr_ioapics >= MAX_IO_APICS) { - printk(KERN_CRIT "Max # of I/O APICs (%d) exceeded (found %d).\n", - MAX_IO_APICS, nr_ioapics); - panic("Recompile kernel with bigger MAX_IO_APICS!.\n"); - } - if (!m->mpc_apicaddr) { - printk(KERN_ERR "WARNING: bogus zero I/O APIC address" - " found in MP table, skipping!\n"); + + if (bad_ioapic(m->mpc_apicaddr)) return; - } + mp_ioapics[nr_ioapics] = *m; nr_ioapics++; } @@ -421,7 +477,9 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) /* * Now process the configuration blocks. */ +#ifdef CONFIG_X86_NUMAQ mpc_record = 0; +#endif while (count < mpc->mpc_length) { switch(*mpt) { case MP_PROCESSOR: @@ -478,7 +536,9 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) break; } } +#ifdef CONFIG_X86_NUMAQ ++mpc_record; +#endif } setup_apic_routing(); if (!num_processors) @@ -883,39 +943,30 @@ static int mp_find_ioapic (int gsi) return -1; } +static u8 uniq_ioapic_id(u8 id) +{ + 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; +} + void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) { int idx = 0; - int tmpid; - if (nr_ioapics >= MAX_IO_APICS) { - printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " - "(found %d)\n", MAX_IO_APICS, nr_ioapics); - panic("Recompile kernel with bigger MAX_IO_APICS!\n"); - } - if (!address) { - printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" - " found in MADT table, skipping!\n"); + if (bad_ioapic(address)) return; - } - idx = nr_ioapics++; + idx = nr_ioapics; mp_ioapics[idx].mpc_type = MP_IOAPIC; mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE; mp_ioapics[idx].mpc_apicaddr = address; set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); - if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) - && !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) - tmpid = io_apic_get_unique_id(idx, id); - else - tmpid = id; - if (tmpid == -1) { - nr_ioapics--; - return; - } - mp_ioapics[idx].mpc_apicid = tmpid; + mp_ioapics[idx].mpc_apicid = uniq_ioapic_id(id); mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); /* @@ -929,9 +980,12 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, - mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr, + mp_ioapics[idx].mpc_apicver, + mp_ioapics[idx].mpc_apicaddr, mp_ioapic_routing[idx].gsi_base, mp_ioapic_routing[idx].gsi_end); + + nr_ioapics++; } void __init @@ -981,10 +1035,13 @@ void __init mp_config_acpi_legacy_irqs (void) int i = 0; int ioapic = -1; +#if defined (CONFIG_MCA) || defined (CONFIG_EISA) /* * Fabricate the legacy ISA bus (bus #31). */ mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA; +#endif + set_bit(MP_ISA_BUS, mp_bus_not_pci); Dprintk("Bus #%d is ISA\n", MP_ISA_BUS); /*