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;
-
-#ifdef CONFIG_SMP
-u16 x86_bios_cpu_apicid_init[NR_CPUS] __initdata
- = {[0 ... NR_CPUS - 1] = BAD_APICID };
-void *x86_bios_cpu_apicid_early_ptr;
-#endif
-
-/* Make it easy to share the UP and SMP code: */
-#ifndef CONFIG_X86_SMP
-unsigned int num_processors;
-unsigned disabled_cpus __cpuinitdata;
-#ifndef CONFIG_X86_LOCAL_APIC
-unsigned int boot_cpu_physical_apicid = -1U;
-#endif
-#endif
/*
* Intel MP BIOS table parsing routines:
static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
{
+ 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);
- generic_processor_info(m->mpc_apicid, 0);
+ generic_processor_info(apicid, m->mpc_apicver);
}
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) {
+ 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, "ISA", 3) == 0) {
- set_bit(m->mpc_busid, mp_bus_not_pci);
- } else if (strncmp(str, "PCI", 3) == 0) {
+ 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)
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;
}
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);
/*
* 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);
count += sizeof(*m);
break;
}
+ default:
+ {
+ count = mpc->mpc_length;
+ break;
+ }
}
+#ifdef CONFIG_X86_NUMAQ
+ ++mpc_record;
+#endif
}
setup_apic_routing();
if (!num_processors)
* 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++) {
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) {
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);
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.
*/
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;
if (mpf->mpf_physptr)
reserve_bootmem_generic(mpf->mpf_physptr,
PAGE_SIZE);
- return 1;
+#endif
+ return 1;
}
bp += 4;
length -= 16;
#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(read_apic_id());
-}
-void __cpuinit mp_register_lapic(int id, u8 enabled)
-{
- if (!enabled) {
- ++disabled_cpus;
- return;
- }
-
- generic_processor_info(id, 0);
-}
-
-
#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)
{
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);
if (!test_bit(id, used))
return id;
return find_first_zero_bit(used, 256);
+#endif
}
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)