#include <asm/mtrr.h>
#include <asm/mpspec.h>
#include <asm/io_apic.h>
+#include <asm/bios_ebda.h>
#include <mach_apic.h>
#include <mach_apicdef.h>
#include <mach_mpparse.h>
-#include <bios_ebda.h>
/* Have we found an MP table */
int smp_found_config;
/* Bitmask of physically existing CPUs */
physid_mask_t phys_cpu_present_map;
+#ifndef CONFIG_SMP
+DEFINE_PER_CPU(u16, x86_bios_cpu_apicid) = BAD_APICID;
+#endif
+
/*
* Intel MP BIOS table parsing routines:
*/
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
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)
{
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");
return;
}
- cpu_set(num_processors, cpu_possible_map);
num_processors++;
cpus_complement(tmp_map, cpu_present_map);
cpu = first_cpu(tmp_map);
def_to_bigsmp = 1;
}
}
+#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;
+ 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;
}
+#endif
+ cpu_set(cpu, cpu_possible_map);
cpu_set(cpu, cpu_present_map);
}
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) {
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]);
+#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++;
}
}
+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)
{
if (!(m->mpc_flags & MPC_APIC_USABLE))
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++;
}
/*
* Now process the configuration blocks.
*/
+#ifdef CONFIG_X86_NUMAQ
mpc_record = 0;
+#endif
while (count < mpc->mpc_length) {
switch(*mpt) {
case MP_PROCESSOR:
break;
}
}
+#ifdef CONFIG_X86_NUMAQ
++mpc_record;
+#endif
}
setup_apic_routing();
if (!num_processors)
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);
/*
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
* 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++;
+ gsi = pci_irq++;
/*
* Don't assign IRQ used by ACPI SCI
*/