0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/mm.h>
0012 #include <linux/init.h>
0013 #include <linux/delay.h>
0014 #include <linux/memblock.h>
0015 #include <linux/kernel_stat.h>
0016 #include <linux/mc146818rtc.h>
0017 #include <linux/bitops.h>
0018 #include <linux/acpi.h>
0019 #include <linux/smp.h>
0020 #include <linux/pci.h>
0021
0022 #include <asm/i8259.h>
0023 #include <asm/io_apic.h>
0024 #include <asm/acpi.h>
0025 #include <asm/irqdomain.h>
0026 #include <asm/mtrr.h>
0027 #include <asm/mpspec.h>
0028 #include <asm/proto.h>
0029 #include <asm/bios_ebda.h>
0030 #include <asm/e820/api.h>
0031 #include <asm/setup.h>
0032 #include <asm/smp.h>
0033
0034 #include <asm/apic.h>
0035
0036
0037
0038
0039 static int __init mpf_checksum(unsigned char *mp, int len)
0040 {
0041 int sum = 0;
0042
0043 while (len--)
0044 sum += *mp++;
0045
0046 return sum & 0xFF;
0047 }
0048
0049 static void __init MP_processor_info(struct mpc_cpu *m)
0050 {
0051 int apicid;
0052 char *bootup_cpu = "";
0053
0054 if (!(m->cpuflag & CPU_ENABLED)) {
0055 disabled_cpus++;
0056 return;
0057 }
0058
0059 apicid = m->apicid;
0060
0061 if (m->cpuflag & CPU_BOOTPROCESSOR) {
0062 bootup_cpu = " (Bootup-CPU)";
0063 boot_cpu_physical_apicid = m->apicid;
0064 }
0065
0066 pr_info("Processor #%d%s\n", m->apicid, bootup_cpu);
0067 generic_processor_info(apicid, m->apicver);
0068 }
0069
0070 #ifdef CONFIG_X86_IO_APIC
0071 static void __init mpc_oem_bus_info(struct mpc_bus *m, char *str)
0072 {
0073 memcpy(str, m->bustype, 6);
0074 str[6] = 0;
0075 apic_printk(APIC_VERBOSE, "Bus #%d is %s\n", m->busid, str);
0076 }
0077
0078 static void __init MP_bus_info(struct mpc_bus *m)
0079 {
0080 char str[7];
0081
0082 mpc_oem_bus_info(m, str);
0083
0084 #if MAX_MP_BUSSES < 256
0085 if (m->busid >= MAX_MP_BUSSES) {
0086 pr_warn("MP table busid value (%d) for bustype %s is too large, max. supported is %d\n",
0087 m->busid, str, MAX_MP_BUSSES - 1);
0088 return;
0089 }
0090 #endif
0091
0092 set_bit(m->busid, mp_bus_not_pci);
0093 if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA) - 1) == 0) {
0094 #ifdef CONFIG_EISA
0095 mp_bus_id_to_type[m->busid] = MP_BUS_ISA;
0096 #endif
0097 } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI) - 1) == 0) {
0098 clear_bit(m->busid, mp_bus_not_pci);
0099 #ifdef CONFIG_EISA
0100 mp_bus_id_to_type[m->busid] = MP_BUS_PCI;
0101 } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA) - 1) == 0) {
0102 mp_bus_id_to_type[m->busid] = MP_BUS_EISA;
0103 #endif
0104 } else
0105 pr_warn("Unknown bustype %s - ignoring\n", str);
0106 }
0107
0108 static void __init MP_ioapic_info(struct mpc_ioapic *m)
0109 {
0110 struct ioapic_domain_cfg cfg = {
0111 .type = IOAPIC_DOMAIN_LEGACY,
0112 .ops = &mp_ioapic_irqdomain_ops,
0113 };
0114
0115 if (m->flags & MPC_APIC_USABLE)
0116 mp_register_ioapic(m->apicid, m->apicaddr, gsi_top, &cfg);
0117 }
0118
0119 static void __init print_mp_irq_info(struct mpc_intsrc *mp_irq)
0120 {
0121 apic_printk(APIC_VERBOSE,
0122 "Int: type %d, pol %d, trig %d, bus %02x, IRQ %02x, APIC ID %x, APIC INT %02x\n",
0123 mp_irq->irqtype, mp_irq->irqflag & 3,
0124 (mp_irq->irqflag >> 2) & 3, mp_irq->srcbus,
0125 mp_irq->srcbusirq, mp_irq->dstapic, mp_irq->dstirq);
0126 }
0127
0128 #else
0129 static inline void __init MP_bus_info(struct mpc_bus *m) {}
0130 static inline void __init MP_ioapic_info(struct mpc_ioapic *m) {}
0131 #endif
0132
0133 static void __init MP_lintsrc_info(struct mpc_lintsrc *m)
0134 {
0135 apic_printk(APIC_VERBOSE,
0136 "Lint: type %d, pol %d, trig %d, bus %02x, IRQ %02x, APIC ID %x, APIC LINT %02x\n",
0137 m->irqtype, m->irqflag & 3, (m->irqflag >> 2) & 3, m->srcbusid,
0138 m->srcbusirq, m->destapic, m->destapiclint);
0139 }
0140
0141
0142
0143
0144 static int __init smp_check_mpc(struct mpc_table *mpc, char *oem, char *str)
0145 {
0146
0147 if (memcmp(mpc->signature, MPC_SIGNATURE, 4)) {
0148 pr_err("MPTABLE: bad signature [%c%c%c%c]!\n",
0149 mpc->signature[0], mpc->signature[1],
0150 mpc->signature[2], mpc->signature[3]);
0151 return 0;
0152 }
0153 if (mpf_checksum((unsigned char *)mpc, mpc->length)) {
0154 pr_err("MPTABLE: checksum error!\n");
0155 return 0;
0156 }
0157 if (mpc->spec != 0x01 && mpc->spec != 0x04) {
0158 pr_err("MPTABLE: bad table version (%d)!!\n", mpc->spec);
0159 return 0;
0160 }
0161 if (!mpc->lapic) {
0162 pr_err("MPTABLE: null local APIC address!\n");
0163 return 0;
0164 }
0165 memcpy(oem, mpc->oem, 8);
0166 oem[8] = 0;
0167 pr_info("MPTABLE: OEM ID: %s\n", oem);
0168
0169 memcpy(str, mpc->productid, 12);
0170 str[12] = 0;
0171
0172 pr_info("MPTABLE: Product ID: %s\n", str);
0173
0174 pr_info("MPTABLE: APIC at: 0x%X\n", mpc->lapic);
0175
0176 return 1;
0177 }
0178
0179 static void skip_entry(unsigned char **ptr, int *count, int size)
0180 {
0181 *ptr += size;
0182 *count += size;
0183 }
0184
0185 static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt)
0186 {
0187 pr_err("Your mptable is wrong, contact your HW vendor!\n");
0188 pr_cont("type %x\n", *mpt);
0189 print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_ADDRESS, 16,
0190 1, mpc, mpc->length, 1);
0191 }
0192
0193 static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
0194 {
0195 char str[16];
0196 char oem[10];
0197
0198 int count = sizeof(*mpc);
0199 unsigned char *mpt = ((unsigned char *)mpc) + count;
0200
0201 if (!smp_check_mpc(mpc, oem, str))
0202 return 0;
0203
0204
0205 if (!acpi_lapic)
0206 register_lapic_address(mpc->lapic);
0207
0208 if (early)
0209 return 1;
0210
0211
0212 while (count < mpc->length) {
0213 switch (*mpt) {
0214 case MP_PROCESSOR:
0215
0216 if (!acpi_lapic)
0217 MP_processor_info((struct mpc_cpu *)mpt);
0218 skip_entry(&mpt, &count, sizeof(struct mpc_cpu));
0219 break;
0220 case MP_BUS:
0221 MP_bus_info((struct mpc_bus *)mpt);
0222 skip_entry(&mpt, &count, sizeof(struct mpc_bus));
0223 break;
0224 case MP_IOAPIC:
0225 MP_ioapic_info((struct mpc_ioapic *)mpt);
0226 skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));
0227 break;
0228 case MP_INTSRC:
0229 mp_save_irq((struct mpc_intsrc *)mpt);
0230 skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));
0231 break;
0232 case MP_LINTSRC:
0233 MP_lintsrc_info((struct mpc_lintsrc *)mpt);
0234 skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc));
0235 break;
0236 default:
0237
0238 smp_dump_mptable(mpc, mpt);
0239 count = mpc->length;
0240 break;
0241 }
0242 }
0243
0244 if (!num_processors)
0245 pr_err("MPTABLE: no processors registered!\n");
0246 return num_processors;
0247 }
0248
0249 #ifdef CONFIG_X86_IO_APIC
0250
0251 static int __init ELCR_trigger(unsigned int irq)
0252 {
0253 unsigned int port;
0254
0255 port = PIC_ELCR1 + (irq >> 3);
0256 return (inb(port) >> (irq & 7)) & 1;
0257 }
0258
0259 static void __init construct_default_ioirq_mptable(int mpc_default_type)
0260 {
0261 struct mpc_intsrc intsrc;
0262 int i;
0263 int ELCR_fallback = 0;
0264
0265 intsrc.type = MP_INTSRC;
0266 intsrc.irqflag = MP_IRQTRIG_DEFAULT | MP_IRQPOL_DEFAULT;
0267 intsrc.srcbus = 0;
0268 intsrc.dstapic = mpc_ioapic_id(0);
0269
0270 intsrc.irqtype = mp_INT;
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280 if (mpc_default_type == 5) {
0281 pr_info("ISA/PCI bus type with no IRQ information... falling back to ELCR\n");
0282
0283 if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) ||
0284 ELCR_trigger(13))
0285 pr_err("ELCR contains invalid data... not using ELCR\n");
0286 else {
0287 pr_info("Using ELCR to identify PCI interrupts\n");
0288 ELCR_fallback = 1;
0289 }
0290 }
0291
0292 for (i = 0; i < 16; i++) {
0293 switch (mpc_default_type) {
0294 case 2:
0295 if (i == 0 || i == 13)
0296 continue;
0297 fallthrough;
0298 default:
0299 if (i == 2)
0300 continue;
0301 }
0302
0303 if (ELCR_fallback) {
0304
0305
0306
0307
0308
0309 if (ELCR_trigger(i)) {
0310 intsrc.irqflag = MP_IRQTRIG_LEVEL |
0311 MP_IRQPOL_ACTIVE_HIGH;
0312 } else {
0313 intsrc.irqflag = MP_IRQTRIG_DEFAULT |
0314 MP_IRQPOL_DEFAULT;
0315 }
0316 }
0317
0318 intsrc.srcbusirq = i;
0319 intsrc.dstirq = i ? i : 2;
0320 mp_save_irq(&intsrc);
0321 }
0322
0323 intsrc.irqtype = mp_ExtINT;
0324 intsrc.srcbusirq = 0;
0325 intsrc.dstirq = 0;
0326 mp_save_irq(&intsrc);
0327 }
0328
0329
0330 static void __init construct_ioapic_table(int mpc_default_type)
0331 {
0332 struct mpc_ioapic ioapic;
0333 struct mpc_bus bus;
0334
0335 bus.type = MP_BUS;
0336 bus.busid = 0;
0337 switch (mpc_default_type) {
0338 default:
0339 pr_err("???\nUnknown standard configuration %d\n",
0340 mpc_default_type);
0341 fallthrough;
0342 case 1:
0343 case 5:
0344 memcpy(bus.bustype, "ISA ", 6);
0345 break;
0346 case 2:
0347 case 6:
0348 case 3:
0349 memcpy(bus.bustype, "EISA ", 6);
0350 break;
0351 }
0352 MP_bus_info(&bus);
0353 if (mpc_default_type > 4) {
0354 bus.busid = 1;
0355 memcpy(bus.bustype, "PCI ", 6);
0356 MP_bus_info(&bus);
0357 }
0358
0359 ioapic.type = MP_IOAPIC;
0360 ioapic.apicid = 2;
0361 ioapic.apicver = mpc_default_type > 4 ? 0x10 : 0x01;
0362 ioapic.flags = MPC_APIC_USABLE;
0363 ioapic.apicaddr = IO_APIC_DEFAULT_PHYS_BASE;
0364 MP_ioapic_info(&ioapic);
0365
0366
0367
0368
0369 construct_default_ioirq_mptable(mpc_default_type);
0370 }
0371 #else
0372 static inline void __init construct_ioapic_table(int mpc_default_type) { }
0373 #endif
0374
0375 static inline void __init construct_default_ISA_mptable(int mpc_default_type)
0376 {
0377 struct mpc_cpu processor;
0378 struct mpc_lintsrc lintsrc;
0379 int linttypes[2] = { mp_ExtINT, mp_NMI };
0380 int i;
0381
0382
0383
0384
0385 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
0386
0387
0388
0389
0390 processor.type = MP_PROCESSOR;
0391
0392 processor.apicver = mpc_default_type > 4 ? 0x10 : 0x01;
0393 processor.cpuflag = CPU_ENABLED;
0394 processor.cpufeature = (boot_cpu_data.x86 << 8) |
0395 (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_stepping;
0396 processor.featureflag = boot_cpu_data.x86_capability[CPUID_1_EDX];
0397 processor.reserved[0] = 0;
0398 processor.reserved[1] = 0;
0399 for (i = 0; i < 2; i++) {
0400 processor.apicid = i;
0401 MP_processor_info(&processor);
0402 }
0403
0404 construct_ioapic_table(mpc_default_type);
0405
0406 lintsrc.type = MP_LINTSRC;
0407 lintsrc.irqflag = MP_IRQTRIG_DEFAULT | MP_IRQPOL_DEFAULT;
0408 lintsrc.srcbusid = 0;
0409 lintsrc.srcbusirq = 0;
0410 lintsrc.destapic = MP_APIC_ALL;
0411 for (i = 0; i < 2; i++) {
0412 lintsrc.irqtype = linttypes[i];
0413 lintsrc.destapiclint = i;
0414 MP_lintsrc_info(&lintsrc);
0415 }
0416 }
0417
0418 static unsigned long mpf_base;
0419 static bool mpf_found;
0420
0421 static unsigned long __init get_mpc_size(unsigned long physptr)
0422 {
0423 struct mpc_table *mpc;
0424 unsigned long size;
0425
0426 mpc = early_memremap(physptr, PAGE_SIZE);
0427 size = mpc->length;
0428 early_memunmap(mpc, PAGE_SIZE);
0429 apic_printk(APIC_VERBOSE, " mpc: %lx-%lx\n", physptr, physptr + size);
0430
0431 return size;
0432 }
0433
0434 static int __init check_physptr(struct mpf_intel *mpf, unsigned int early)
0435 {
0436 struct mpc_table *mpc;
0437 unsigned long size;
0438
0439 size = get_mpc_size(mpf->physptr);
0440 mpc = early_memremap(mpf->physptr, size);
0441
0442
0443
0444
0445
0446 if (!smp_read_mpc(mpc, early)) {
0447 #ifdef CONFIG_X86_LOCAL_APIC
0448 smp_found_config = 0;
0449 #endif
0450 pr_err("BIOS bug, MP table errors detected!...\n");
0451 pr_cont("... disabling SMP support. (tell your hw vendor)\n");
0452 early_memunmap(mpc, size);
0453 return -1;
0454 }
0455 early_memunmap(mpc, size);
0456
0457 if (early)
0458 return -1;
0459
0460 #ifdef CONFIG_X86_IO_APIC
0461
0462
0463
0464
0465
0466 if (!mp_irq_entries) {
0467 struct mpc_bus bus;
0468
0469 pr_err("BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");
0470
0471 bus.type = MP_BUS;
0472 bus.busid = 0;
0473 memcpy(bus.bustype, "ISA ", 6);
0474 MP_bus_info(&bus);
0475
0476 construct_default_ioirq_mptable(0);
0477 }
0478 #endif
0479
0480 return 0;
0481 }
0482
0483
0484
0485
0486 void __init default_get_smp_config(unsigned int early)
0487 {
0488 struct mpf_intel *mpf;
0489
0490 if (!smp_found_config)
0491 return;
0492
0493 if (!mpf_found)
0494 return;
0495
0496 if (acpi_lapic && early)
0497 return;
0498
0499
0500
0501
0502
0503 if (acpi_lapic && acpi_ioapic)
0504 return;
0505
0506 mpf = early_memremap(mpf_base, sizeof(*mpf));
0507 if (!mpf) {
0508 pr_err("MPTABLE: error mapping MP table\n");
0509 return;
0510 }
0511
0512 pr_info("Intel MultiProcessor Specification v1.%d\n",
0513 mpf->specification);
0514 #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32)
0515 if (mpf->feature2 & (1 << 7)) {
0516 pr_info(" IMCR and PIC compatibility mode.\n");
0517 pic_mode = 1;
0518 } else {
0519 pr_info(" Virtual Wire compatibility mode.\n");
0520 pic_mode = 0;
0521 }
0522 #endif
0523
0524
0525
0526 if (mpf->feature1) {
0527 if (early) {
0528
0529
0530
0531 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
0532 goto out;
0533 }
0534
0535 pr_info("Default MP configuration #%d\n", mpf->feature1);
0536 construct_default_ISA_mptable(mpf->feature1);
0537
0538 } else if (mpf->physptr) {
0539 if (check_physptr(mpf, early))
0540 goto out;
0541 } else
0542 BUG();
0543
0544 if (!early)
0545 pr_info("Processors: %d\n", num_processors);
0546
0547
0548
0549 out:
0550 early_memunmap(mpf, sizeof(*mpf));
0551 }
0552
0553 static void __init smp_reserve_memory(struct mpf_intel *mpf)
0554 {
0555 memblock_reserve(mpf->physptr, get_mpc_size(mpf->physptr));
0556 }
0557
0558 static int __init smp_scan_config(unsigned long base, unsigned long length)
0559 {
0560 unsigned int *bp;
0561 struct mpf_intel *mpf;
0562 int ret = 0;
0563
0564 apic_printk(APIC_VERBOSE, "Scan for SMP in [mem %#010lx-%#010lx]\n",
0565 base, base + length - 1);
0566 BUILD_BUG_ON(sizeof(*mpf) != 16);
0567
0568 while (length > 0) {
0569 bp = early_memremap(base, length);
0570 mpf = (struct mpf_intel *)bp;
0571 if ((*bp == SMP_MAGIC_IDENT) &&
0572 (mpf->length == 1) &&
0573 !mpf_checksum((unsigned char *)bp, 16) &&
0574 ((mpf->specification == 1)
0575 || (mpf->specification == 4))) {
0576 #ifdef CONFIG_X86_LOCAL_APIC
0577 smp_found_config = 1;
0578 #endif
0579 mpf_base = base;
0580 mpf_found = true;
0581
0582 pr_info("found SMP MP-table at [mem %#010lx-%#010lx]\n",
0583 base, base + sizeof(*mpf) - 1);
0584
0585 memblock_reserve(base, sizeof(*mpf));
0586 if (mpf->physptr)
0587 smp_reserve_memory(mpf);
0588
0589 ret = 1;
0590 }
0591 early_memunmap(bp, length);
0592
0593 if (ret)
0594 break;
0595
0596 base += 16;
0597 length -= 16;
0598 }
0599 return ret;
0600 }
0601
0602 void __init default_find_smp_config(void)
0603 {
0604 unsigned int address;
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614 if (smp_scan_config(0x0, 0x400) ||
0615 smp_scan_config(639 * 0x400, 0x400) ||
0616 smp_scan_config(0xF0000, 0x10000))
0617 return;
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635 address = get_bios_ebda();
0636 if (address)
0637 smp_scan_config(address, 0x400);
0638 }
0639
0640 #ifdef CONFIG_X86_IO_APIC
0641 static u8 __initdata irq_used[MAX_IRQ_SOURCES];
0642
0643 static int __init get_MP_intsrc_index(struct mpc_intsrc *m)
0644 {
0645 int i;
0646
0647 if (m->irqtype != mp_INT)
0648 return 0;
0649
0650 if (m->irqflag != (MP_IRQTRIG_LEVEL | MP_IRQPOL_ACTIVE_LOW))
0651 return 0;
0652
0653
0654
0655 for (i = 0; i < mp_irq_entries; i++) {
0656 if (mp_irqs[i].irqtype != mp_INT)
0657 continue;
0658
0659 if (mp_irqs[i].irqflag != (MP_IRQTRIG_LEVEL |
0660 MP_IRQPOL_ACTIVE_LOW))
0661 continue;
0662
0663 if (mp_irqs[i].srcbus != m->srcbus)
0664 continue;
0665 if (mp_irqs[i].srcbusirq != m->srcbusirq)
0666 continue;
0667 if (irq_used[i]) {
0668
0669 return -2;
0670 }
0671 irq_used[i] = 1;
0672 return i;
0673 }
0674
0675
0676 return -1;
0677 }
0678
0679 #define SPARE_SLOT_NUM 20
0680
0681 static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM];
0682
0683 static void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare)
0684 {
0685 int i;
0686
0687 apic_printk(APIC_VERBOSE, "OLD ");
0688 print_mp_irq_info(m);
0689
0690 i = get_MP_intsrc_index(m);
0691 if (i > 0) {
0692 memcpy(m, &mp_irqs[i], sizeof(*m));
0693 apic_printk(APIC_VERBOSE, "NEW ");
0694 print_mp_irq_info(&mp_irqs[i]);
0695 return;
0696 }
0697 if (!i) {
0698
0699 return;
0700 }
0701 if (*nr_m_spare < SPARE_SLOT_NUM) {
0702
0703
0704
0705
0706 m_spare[*nr_m_spare] = m;
0707 *nr_m_spare += 1;
0708 }
0709 }
0710
0711 static int __init
0712 check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, int count)
0713 {
0714 if (!mpc_new_phys || count <= mpc_new_length) {
0715 WARN(1, "update_mptable: No spare slots (length: %x)\n", count);
0716 return -1;
0717 }
0718
0719 return 0;
0720 }
0721 #else
0722 static
0723 inline void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {}
0724 #endif
0725
0726 static int __init replace_intsrc_all(struct mpc_table *mpc,
0727 unsigned long mpc_new_phys,
0728 unsigned long mpc_new_length)
0729 {
0730 #ifdef CONFIG_X86_IO_APIC
0731 int i;
0732 #endif
0733 int count = sizeof(*mpc);
0734 int nr_m_spare = 0;
0735 unsigned char *mpt = ((unsigned char *)mpc) + count;
0736
0737 pr_info("mpc_length %x\n", mpc->length);
0738 while (count < mpc->length) {
0739 switch (*mpt) {
0740 case MP_PROCESSOR:
0741 skip_entry(&mpt, &count, sizeof(struct mpc_cpu));
0742 break;
0743 case MP_BUS:
0744 skip_entry(&mpt, &count, sizeof(struct mpc_bus));
0745 break;
0746 case MP_IOAPIC:
0747 skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));
0748 break;
0749 case MP_INTSRC:
0750 check_irq_src((struct mpc_intsrc *)mpt, &nr_m_spare);
0751 skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));
0752 break;
0753 case MP_LINTSRC:
0754 skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc));
0755 break;
0756 default:
0757
0758 smp_dump_mptable(mpc, mpt);
0759 goto out;
0760 }
0761 }
0762
0763 #ifdef CONFIG_X86_IO_APIC
0764 for (i = 0; i < mp_irq_entries; i++) {
0765 if (irq_used[i])
0766 continue;
0767
0768 if (mp_irqs[i].irqtype != mp_INT)
0769 continue;
0770
0771 if (mp_irqs[i].irqflag != (MP_IRQTRIG_LEVEL |
0772 MP_IRQPOL_ACTIVE_LOW))
0773 continue;
0774
0775 if (nr_m_spare > 0) {
0776 apic_printk(APIC_VERBOSE, "*NEW* found\n");
0777 nr_m_spare--;
0778 memcpy(m_spare[nr_m_spare], &mp_irqs[i], sizeof(mp_irqs[i]));
0779 m_spare[nr_m_spare] = NULL;
0780 } else {
0781 struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
0782 count += sizeof(struct mpc_intsrc);
0783 if (check_slot(mpc_new_phys, mpc_new_length, count) < 0)
0784 goto out;
0785 memcpy(m, &mp_irqs[i], sizeof(*m));
0786 mpc->length = count;
0787 mpt += sizeof(struct mpc_intsrc);
0788 }
0789 print_mp_irq_info(&mp_irqs[i]);
0790 }
0791 #endif
0792 out:
0793
0794 mpc->checksum = 0;
0795 mpc->checksum -= mpf_checksum((unsigned char *)mpc, mpc->length);
0796
0797 return 0;
0798 }
0799
0800 int enable_update_mptable;
0801
0802 static int __init update_mptable_setup(char *str)
0803 {
0804 enable_update_mptable = 1;
0805 #ifdef CONFIG_PCI
0806 pci_routeirq = 1;
0807 #endif
0808 return 0;
0809 }
0810 early_param("update_mptable", update_mptable_setup);
0811
0812 static unsigned long __initdata mpc_new_phys;
0813 static unsigned long mpc_new_length __initdata = 4096;
0814
0815
0816 static int __initdata alloc_mptable;
0817 static int __init parse_alloc_mptable_opt(char *p)
0818 {
0819 enable_update_mptable = 1;
0820 #ifdef CONFIG_PCI
0821 pci_routeirq = 1;
0822 #endif
0823 alloc_mptable = 1;
0824 if (!p)
0825 return 0;
0826 mpc_new_length = memparse(p, &p);
0827 return 0;
0828 }
0829 early_param("alloc_mptable", parse_alloc_mptable_opt);
0830
0831 void __init e820__memblock_alloc_reserved_mpc_new(void)
0832 {
0833 if (enable_update_mptable && alloc_mptable)
0834 mpc_new_phys = e820__memblock_alloc_reserved(mpc_new_length, 4);
0835 }
0836
0837 static int __init update_mp_table(void)
0838 {
0839 char str[16];
0840 char oem[10];
0841 struct mpf_intel *mpf;
0842 struct mpc_table *mpc, *mpc_new;
0843 unsigned long size;
0844
0845 if (!enable_update_mptable)
0846 return 0;
0847
0848 if (!mpf_found)
0849 return 0;
0850
0851 mpf = early_memremap(mpf_base, sizeof(*mpf));
0852 if (!mpf) {
0853 pr_err("MPTABLE: mpf early_memremap() failed\n");
0854 return 0;
0855 }
0856
0857
0858
0859
0860 if (mpf->feature1)
0861 goto do_unmap_mpf;
0862
0863 if (!mpf->physptr)
0864 goto do_unmap_mpf;
0865
0866 size = get_mpc_size(mpf->physptr);
0867 mpc = early_memremap(mpf->physptr, size);
0868 if (!mpc) {
0869 pr_err("MPTABLE: mpc early_memremap() failed\n");
0870 goto do_unmap_mpf;
0871 }
0872
0873 if (!smp_check_mpc(mpc, oem, str))
0874 goto do_unmap_mpc;
0875
0876 pr_info("mpf: %llx\n", (u64)mpf_base);
0877 pr_info("physptr: %x\n", mpf->physptr);
0878
0879 if (mpc_new_phys && mpc->length > mpc_new_length) {
0880 mpc_new_phys = 0;
0881 pr_info("mpc_new_length is %ld, please use alloc_mptable=8k\n",
0882 mpc_new_length);
0883 }
0884
0885 if (!mpc_new_phys) {
0886 unsigned char old, new;
0887
0888 mpc->checksum = 0;
0889 old = mpf_checksum((unsigned char *)mpc, mpc->length);
0890 mpc->checksum = 0xff;
0891 new = mpf_checksum((unsigned char *)mpc, mpc->length);
0892 if (old == new) {
0893 pr_info("mpc is readonly, please try alloc_mptable instead\n");
0894 goto do_unmap_mpc;
0895 }
0896 pr_info("use in-position replacing\n");
0897 } else {
0898 mpc_new = early_memremap(mpc_new_phys, mpc_new_length);
0899 if (!mpc_new) {
0900 pr_err("MPTABLE: new mpc early_memremap() failed\n");
0901 goto do_unmap_mpc;
0902 }
0903 mpf->physptr = mpc_new_phys;
0904 memcpy(mpc_new, mpc, mpc->length);
0905 early_memunmap(mpc, size);
0906 mpc = mpc_new;
0907 size = mpc_new_length;
0908
0909 if (mpc_new_phys - mpf->physptr) {
0910 struct mpf_intel *mpf_new;
0911
0912 mpf_new = early_memremap(0x400 - 16, sizeof(*mpf_new));
0913 if (!mpf_new) {
0914 pr_err("MPTABLE: new mpf early_memremap() failed\n");
0915 goto do_unmap_mpc;
0916 }
0917 pr_info("mpf new: %x\n", 0x400 - 16);
0918 memcpy(mpf_new, mpf, 16);
0919 early_memunmap(mpf, sizeof(*mpf));
0920 mpf = mpf_new;
0921 mpf->physptr = mpc_new_phys;
0922 }
0923 mpf->checksum = 0;
0924 mpf->checksum -= mpf_checksum((unsigned char *)mpf, 16);
0925 pr_info("physptr new: %x\n", mpf->physptr);
0926 }
0927
0928
0929
0930
0931
0932
0933
0934 replace_intsrc_all(mpc, mpc_new_phys, mpc_new_length);
0935
0936 do_unmap_mpc:
0937 early_memunmap(mpc, size);
0938
0939 do_unmap_mpf:
0940 early_memunmap(mpf, sizeof(*mpf));
0941
0942 return 0;
0943 }
0944
0945 late_initcall(update_mp_table);