aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/mpparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/mpparse.c')
-rw-r--r--arch/x86/kernel/mpparse.c541
1 files changed, 271 insertions, 270 deletions
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index a649a4ccad43..dce99dca6cf8 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -3,7 +3,7 @@
3 * compliant MP-table parsing routines. 3 * compliant MP-table parsing routines.
4 * 4 *
5 * (c) 1995 Alan Cox, Building #3 <alan@lxorguk.ukuu.org.uk> 5 * (c) 1995 Alan Cox, Building #3 <alan@lxorguk.ukuu.org.uk>
6 * (c) 1998, 1999, 2000 Ingo Molnar <mingo@redhat.com> 6 * (c) 1998, 1999, 2000, 2009 Ingo Molnar <mingo@redhat.com>
7 * (c) 2008 Alexey Starikovskiy <astarikovskiy@suse.de> 7 * (c) 2008 Alexey Starikovskiy <astarikovskiy@suse.de>
8 */ 8 */
9 9
@@ -29,12 +29,7 @@
29#include <asm/setup.h> 29#include <asm/setup.h>
30#include <asm/smp.h> 30#include <asm/smp.h>
31 31
32#include <mach_apic.h> 32#include <asm/apic.h>
33#ifdef CONFIG_X86_32
34#include <mach_apicdef.h>
35#include <mach_mpparse.h>
36#endif
37
38/* 33/*
39 * Checksum an MP configuration block. 34 * Checksum an MP configuration block.
40 */ 35 */
@@ -114,9 +109,6 @@ static void __init MP_bus_info(struct mpc_bus *m)
114 } else 109 } else
115 printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str); 110 printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
116} 111}
117#endif
118
119#ifdef CONFIG_X86_IO_APIC
120 112
121static int bad_ioapic(unsigned long address) 113static int bad_ioapic(unsigned long address)
122{ 114{
@@ -144,11 +136,11 @@ static void __init MP_ioapic_info(struct mpc_ioapic *m)
144 if (bad_ioapic(m->apicaddr)) 136 if (bad_ioapic(m->apicaddr))
145 return; 137 return;
146 138
147 mp_ioapics[nr_ioapics].mp_apicaddr = m->apicaddr; 139 mp_ioapics[nr_ioapics].apicaddr = m->apicaddr;
148 mp_ioapics[nr_ioapics].mp_apicid = m->apicid; 140 mp_ioapics[nr_ioapics].apicid = m->apicid;
149 mp_ioapics[nr_ioapics].mp_type = m->type; 141 mp_ioapics[nr_ioapics].type = m->type;
150 mp_ioapics[nr_ioapics].mp_apicver = m->apicver; 142 mp_ioapics[nr_ioapics].apicver = m->apicver;
151 mp_ioapics[nr_ioapics].mp_flags = m->flags; 143 mp_ioapics[nr_ioapics].flags = m->flags;
152 nr_ioapics++; 144 nr_ioapics++;
153} 145}
154 146
@@ -160,55 +152,55 @@ static void print_MP_intsrc_info(struct mpc_intsrc *m)
160 m->srcbusirq, m->dstapic, m->dstirq); 152 m->srcbusirq, m->dstapic, m->dstirq);
161} 153}
162 154
163static void __init print_mp_irq_info(struct mp_config_intsrc *mp_irq) 155static void __init print_mp_irq_info(struct mpc_intsrc *mp_irq)
164{ 156{
165 apic_printk(APIC_VERBOSE, "Int: type %d, pol %d, trig %d, bus %02x," 157 apic_printk(APIC_VERBOSE, "Int: type %d, pol %d, trig %d, bus %02x,"
166 " IRQ %02x, APIC ID %x, APIC INT %02x\n", 158 " IRQ %02x, APIC ID %x, APIC INT %02x\n",
167 mp_irq->mp_irqtype, mp_irq->mp_irqflag & 3, 159 mp_irq->irqtype, mp_irq->irqflag & 3,
168 (mp_irq->mp_irqflag >> 2) & 3, mp_irq->mp_srcbus, 160 (mp_irq->irqflag >> 2) & 3, mp_irq->srcbus,
169 mp_irq->mp_srcbusirq, mp_irq->mp_dstapic, mp_irq->mp_dstirq); 161 mp_irq->srcbusirq, mp_irq->dstapic, mp_irq->dstirq);
170} 162}
171 163
172static void __init assign_to_mp_irq(struct mpc_intsrc *m, 164static void __init assign_to_mp_irq(struct mpc_intsrc *m,
173 struct mp_config_intsrc *mp_irq) 165 struct mpc_intsrc *mp_irq)
174{ 166{
175 mp_irq->mp_dstapic = m->dstapic; 167 mp_irq->dstapic = m->dstapic;
176 mp_irq->mp_type = m->type; 168 mp_irq->type = m->type;
177 mp_irq->mp_irqtype = m->irqtype; 169 mp_irq->irqtype = m->irqtype;
178 mp_irq->mp_irqflag = m->irqflag; 170 mp_irq->irqflag = m->irqflag;
179 mp_irq->mp_srcbus = m->srcbus; 171 mp_irq->srcbus = m->srcbus;
180 mp_irq->mp_srcbusirq = m->srcbusirq; 172 mp_irq->srcbusirq = m->srcbusirq;
181 mp_irq->mp_dstirq = m->dstirq; 173 mp_irq->dstirq = m->dstirq;
182} 174}
183 175
184static void __init assign_to_mpc_intsrc(struct mp_config_intsrc *mp_irq, 176static void __init assign_to_mpc_intsrc(struct mpc_intsrc *mp_irq,
185 struct mpc_intsrc *m) 177 struct mpc_intsrc *m)
186{ 178{
187 m->dstapic = mp_irq->mp_dstapic; 179 m->dstapic = mp_irq->dstapic;
188 m->type = mp_irq->mp_type; 180 m->type = mp_irq->type;
189 m->irqtype = mp_irq->mp_irqtype; 181 m->irqtype = mp_irq->irqtype;
190 m->irqflag = mp_irq->mp_irqflag; 182 m->irqflag = mp_irq->irqflag;
191 m->srcbus = mp_irq->mp_srcbus; 183 m->srcbus = mp_irq->srcbus;
192 m->srcbusirq = mp_irq->mp_srcbusirq; 184 m->srcbusirq = mp_irq->srcbusirq;
193 m->dstirq = mp_irq->mp_dstirq; 185 m->dstirq = mp_irq->dstirq;
194} 186}
195 187
196static int __init mp_irq_mpc_intsrc_cmp(struct mp_config_intsrc *mp_irq, 188static int __init mp_irq_mpc_intsrc_cmp(struct mpc_intsrc *mp_irq,
197 struct mpc_intsrc *m) 189 struct mpc_intsrc *m)
198{ 190{
199 if (mp_irq->mp_dstapic != m->dstapic) 191 if (mp_irq->dstapic != m->dstapic)
200 return 1; 192 return 1;
201 if (mp_irq->mp_type != m->type) 193 if (mp_irq->type != m->type)
202 return 2; 194 return 2;
203 if (mp_irq->mp_irqtype != m->irqtype) 195 if (mp_irq->irqtype != m->irqtype)
204 return 3; 196 return 3;
205 if (mp_irq->mp_irqflag != m->irqflag) 197 if (mp_irq->irqflag != m->irqflag)
206 return 4; 198 return 4;
207 if (mp_irq->mp_srcbus != m->srcbus) 199 if (mp_irq->srcbus != m->srcbus)
208 return 5; 200 return 5;
209 if (mp_irq->mp_srcbusirq != m->srcbusirq) 201 if (mp_irq->srcbusirq != m->srcbusirq)
210 return 6; 202 return 6;
211 if (mp_irq->mp_dstirq != m->dstirq) 203 if (mp_irq->dstirq != m->dstirq)
212 return 7; 204 return 7;
213 205
214 return 0; 206 return 0;
@@ -229,8 +221,12 @@ static void __init MP_intsrc_info(struct mpc_intsrc *m)
229 if (++mp_irq_entries == MAX_IRQ_SOURCES) 221 if (++mp_irq_entries == MAX_IRQ_SOURCES)
230 panic("Max # of irq sources exceeded!!\n"); 222 panic("Max # of irq sources exceeded!!\n");
231} 223}
224#else /* CONFIG_X86_IO_APIC */
225static inline void __init MP_bus_info(struct mpc_bus *m) {}
226static inline void __init MP_ioapic_info(struct mpc_ioapic *m) {}
227static inline void __init MP_intsrc_info(struct mpc_intsrc *m) {}
228#endif /* CONFIG_X86_IO_APIC */
232 229
233#endif
234 230
235static void __init MP_lintsrc_info(struct mpc_lintsrc *m) 231static void __init MP_lintsrc_info(struct mpc_lintsrc *m)
236{ 232{
@@ -280,6 +276,20 @@ static int __init smp_check_mpc(struct mpc_table *mpc, char *oem, char *str)
280 return 1; 276 return 1;
281} 277}
282 278
279static void skip_entry(unsigned char **ptr, int *count, int size)
280{
281 *ptr += size;
282 *count += size;
283}
284
285static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt)
286{
287 printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n"
288 "type %x\n", *mpt);
289 print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_ADDRESS, 16,
290 1, mpc, mpc->length, 1);
291}
292
283static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) 293static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
284{ 294{
285 char str[16]; 295 char str[16];
@@ -292,16 +302,7 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
292 return 0; 302 return 0;
293 303
294#ifdef CONFIG_X86_32 304#ifdef CONFIG_X86_32
295 /* 305 generic_mps_oem_check(mpc, oem, str);
296 * need to make sure summit and es7000's mps_oem_check is safe to be
297 * called early via genericarch 's mps_oem_check
298 */
299 if (early) {
300#ifdef CONFIG_X86_NUMAQ
301 numaq_mps_oem_check(mpc, oem, str);
302#endif
303 } else
304 mps_oem_check(mpc, oem, str);
305#endif 306#endif
306 /* save the local APIC address, it might be non-default */ 307 /* save the local APIC address, it might be non-default */
307 if (!acpi_lapic) 308 if (!acpi_lapic)
@@ -324,61 +325,30 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
324 while (count < mpc->length) { 325 while (count < mpc->length) {
325 switch (*mpt) { 326 switch (*mpt) {
326 case MP_PROCESSOR: 327 case MP_PROCESSOR:
327 { 328 /* ACPI may have already provided this data */
328 struct mpc_cpu *m = (struct mpc_cpu *)mpt; 329 if (!acpi_lapic)
329 /* ACPI may have already provided this data */ 330 MP_processor_info((struct mpc_cpu *)mpt);
330 if (!acpi_lapic) 331 skip_entry(&mpt, &count, sizeof(struct mpc_cpu));
331 MP_processor_info(m); 332 break;
332 mpt += sizeof(*m);
333 count += sizeof(*m);
334 break;
335 }
336 case MP_BUS: 333 case MP_BUS:
337 { 334 MP_bus_info((struct mpc_bus *)mpt);
338 struct mpc_bus *m = (struct mpc_bus *)mpt; 335 skip_entry(&mpt, &count, sizeof(struct mpc_bus));
339#ifdef CONFIG_X86_IO_APIC 336 break;
340 MP_bus_info(m);
341#endif
342 mpt += sizeof(*m);
343 count += sizeof(*m);
344 break;
345 }
346 case MP_IOAPIC: 337 case MP_IOAPIC:
347 { 338 MP_ioapic_info((struct mpc_ioapic *)mpt);
348#ifdef CONFIG_X86_IO_APIC 339 skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));
349 struct mpc_ioapic *m = (struct mpc_ioapic *)mpt; 340 break;
350 MP_ioapic_info(m);
351#endif
352 mpt += sizeof(struct mpc_ioapic);
353 count += sizeof(struct mpc_ioapic);
354 break;
355 }
356 case MP_INTSRC: 341 case MP_INTSRC:
357 { 342 MP_intsrc_info((struct mpc_intsrc *)mpt);
358#ifdef CONFIG_X86_IO_APIC 343 skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));
359 struct mpc_intsrc *m = (struct mpc_intsrc *)mpt; 344 break;
360
361 MP_intsrc_info(m);
362#endif
363 mpt += sizeof(struct mpc_intsrc);
364 count += sizeof(struct mpc_intsrc);
365 break;
366 }
367 case MP_LINTSRC: 345 case MP_LINTSRC:
368 { 346 MP_lintsrc_info((struct mpc_lintsrc *)mpt);
369 struct mpc_lintsrc *m = 347 skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc));
370 (struct mpc_lintsrc *)mpt; 348 break;
371 MP_lintsrc_info(m);
372 mpt += sizeof(*m);
373 count += sizeof(*m);
374 break;
375 }
376 default: 349 default:
377 /* wrong mptable */ 350 /* wrong mptable */
378 printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n"); 351 smp_dump_mptable(mpc, mpt);
379 printk(KERN_ERR "type %x\n", *mpt);
380 print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_ADDRESS, 16,
381 1, mpc, mpc->length, 1);
382 count = mpc->length; 352 count = mpc->length;
383 break; 353 break;
384 } 354 }
@@ -386,13 +356,13 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
386 (*x86_quirks->mpc_record)++; 356 (*x86_quirks->mpc_record)++;
387 } 357 }
388 358
389#ifdef CONFIG_X86_GENERICARCH 359#ifdef CONFIG_X86_BIGSMP
390 generic_bigsmp_probe(); 360 generic_bigsmp_probe();
391#endif 361#endif
392 362
393#ifdef CONFIG_X86_32 363 if (apic->setup_apic_routing)
394 setup_apic_routing(); 364 apic->setup_apic_routing();
395#endif 365
396 if (!num_processors) 366 if (!num_processors)
397 printk(KERN_ERR "MPTABLE: no processors registered!\n"); 367 printk(KERN_ERR "MPTABLE: no processors registered!\n");
398 return num_processors; 368 return num_processors;
@@ -417,7 +387,7 @@ static void __init construct_default_ioirq_mptable(int mpc_default_type)
417 intsrc.type = MP_INTSRC; 387 intsrc.type = MP_INTSRC;
418 intsrc.irqflag = 0; /* conforming */ 388 intsrc.irqflag = 0; /* conforming */
419 intsrc.srcbus = 0; 389 intsrc.srcbus = 0;
420 intsrc.dstapic = mp_ioapics[0].mp_apicid; 390 intsrc.dstapic = mp_ioapics[0].apicid;
421 391
422 intsrc.irqtype = mp_INT; 392 intsrc.irqtype = mp_INT;
423 393
@@ -570,14 +540,76 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
570 } 540 }
571} 541}
572 542
573static struct intel_mp_floating *mpf_found; 543static struct mpf_intel *mpf_found;
544
545static unsigned long __init get_mpc_size(unsigned long physptr)
546{
547 struct mpc_table *mpc;
548 unsigned long size;
549
550 mpc = early_ioremap(physptr, PAGE_SIZE);
551 size = mpc->length;
552 early_iounmap(mpc, PAGE_SIZE);
553 apic_printk(APIC_VERBOSE, " mpc: %lx-%lx\n", physptr, physptr + size);
554
555 return size;
556}
557
558static int __init check_physptr(struct mpf_intel *mpf, unsigned int early)
559{
560 struct mpc_table *mpc;
561 unsigned long size;
562
563 size = get_mpc_size(mpf->physptr);
564 mpc = early_ioremap(mpf->physptr, size);
565 /*
566 * Read the physical hardware table. Anything here will
567 * override the defaults.
568 */
569 if (!smp_read_mpc(mpc, early)) {
570#ifdef CONFIG_X86_LOCAL_APIC
571 smp_found_config = 0;
572#endif
573 printk(KERN_ERR "BIOS bug, MP table errors detected!...\n"
574 "... disabling SMP support. (tell your hw vendor)\n");
575 early_iounmap(mpc, size);
576 return -1;
577 }
578 early_iounmap(mpc, size);
579
580 if (early)
581 return -1;
582
583#ifdef CONFIG_X86_IO_APIC
584 /*
585 * If there are no explicit MP IRQ entries, then we are
586 * broken. We set up most of the low 16 IO-APIC pins to
587 * ISA defaults and hope it will work.
588 */
589 if (!mp_irq_entries) {
590 struct mpc_bus bus;
591
592 printk(KERN_ERR "BIOS bug, no explicit IRQ entries, "
593 "using default mptable. (tell your hw vendor)\n");
594
595 bus.type = MP_BUS;
596 bus.busid = 0;
597 memcpy(bus.bustype, "ISA ", 6);
598 MP_bus_info(&bus);
599
600 construct_default_ioirq_mptable(0);
601 }
602#endif
603
604 return 0;
605}
574 606
575/* 607/*
576 * Scan the memory blocks for an SMP configuration block. 608 * Scan the memory blocks for an SMP configuration block.
577 */ 609 */
578static void __init __get_smp_config(unsigned int early) 610static void __init __get_smp_config(unsigned int early)
579{ 611{
580 struct intel_mp_floating *mpf = mpf_found; 612 struct mpf_intel *mpf = mpf_found;
581 613
582 if (!mpf) 614 if (!mpf)
583 return; 615 return;
@@ -598,9 +630,9 @@ static void __init __get_smp_config(unsigned int early)
598 } 630 }
599 631
600 printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n", 632 printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n",
601 mpf->mpf_specification); 633 mpf->specification);
602#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32) 634#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32)
603 if (mpf->mpf_feature2 & (1 << 7)) { 635 if (mpf->feature2 & (1 << 7)) {
604 printk(KERN_INFO " IMCR and PIC compatibility mode.\n"); 636 printk(KERN_INFO " IMCR and PIC compatibility mode.\n");
605 pic_mode = 1; 637 pic_mode = 1;
606 } else { 638 } else {
@@ -611,7 +643,7 @@ static void __init __get_smp_config(unsigned int early)
611 /* 643 /*
612 * Now see if we need to read further. 644 * Now see if we need to read further.
613 */ 645 */
614 if (mpf->mpf_feature1 != 0) { 646 if (mpf->feature1 != 0) {
615 if (early) { 647 if (early) {
616 /* 648 /*
617 * local APIC has default address 649 * local APIC has default address
@@ -621,49 +653,12 @@ static void __init __get_smp_config(unsigned int early)
621 } 653 }
622 654
623 printk(KERN_INFO "Default MP configuration #%d\n", 655 printk(KERN_INFO "Default MP configuration #%d\n",
624 mpf->mpf_feature1); 656 mpf->feature1);
625 construct_default_ISA_mptable(mpf->mpf_feature1); 657 construct_default_ISA_mptable(mpf->feature1);
626
627 } else if (mpf->mpf_physptr) {
628 658
629 /* 659 } else if (mpf->physptr) {
630 * Read the physical hardware table. Anything here will 660 if (check_physptr(mpf, early))
631 * override the defaults.
632 */
633 if (!smp_read_mpc(phys_to_virt(mpf->mpf_physptr), early)) {
634#ifdef CONFIG_X86_LOCAL_APIC
635 smp_found_config = 0;
636#endif
637 printk(KERN_ERR
638 "BIOS bug, MP table errors detected!...\n");
639 printk(KERN_ERR "... disabling SMP support. "
640 "(tell your hw vendor)\n");
641 return;
642 }
643
644 if (early)
645 return; 661 return;
646#ifdef CONFIG_X86_IO_APIC
647 /*
648 * If there are no explicit MP IRQ entries, then we are
649 * broken. We set up most of the low 16 IO-APIC pins to
650 * ISA defaults and hope it will work.
651 */
652 if (!mp_irq_entries) {
653 struct mpc_bus bus;
654
655 printk(KERN_ERR "BIOS bug, no explicit IRQ entries, "
656 "using default mptable. "
657 "(tell your hw vendor)\n");
658
659 bus.type = MP_BUS;
660 bus.busid = 0;
661 memcpy(bus.bustype, "ISA ", 6);
662 MP_bus_info(&bus);
663
664 construct_default_ioirq_mptable(0);
665 }
666#endif
667 } else 662 } else
668 BUG(); 663 BUG();
669 664
@@ -684,54 +679,62 @@ void __init get_smp_config(void)
684 __get_smp_config(0); 679 __get_smp_config(0);
685} 680}
686 681
682static void smp_reserve_bootmem(struct mpf_intel *mpf)
683{
684 unsigned long size = get_mpc_size(mpf->physptr);
685#ifdef CONFIG_X86_32
686 /*
687 * We cannot access to MPC table to compute table size yet,
688 * as only few megabytes from the bottom is mapped now.
689 * PC-9800's MPC table places on the very last of physical
690 * memory; so that simply reserving PAGE_SIZE from mpf->physptr
691 * yields BUG() in reserve_bootmem.
692 * also need to make sure physptr is below than max_low_pfn
693 * we don't need reserve the area above max_low_pfn
694 */
695 unsigned long end = max_low_pfn * PAGE_SIZE;
696
697 if (mpf->physptr < end) {
698 if (mpf->physptr + size > end)
699 size = end - mpf->physptr;
700 reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT);
701 }
702#else
703 reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT);
704#endif
705}
706
687static int __init smp_scan_config(unsigned long base, unsigned long length, 707static int __init smp_scan_config(unsigned long base, unsigned long length,
688 unsigned reserve) 708 unsigned reserve)
689{ 709{
690 unsigned int *bp = phys_to_virt(base); 710 unsigned int *bp = phys_to_virt(base);
691 struct intel_mp_floating *mpf; 711 struct mpf_intel *mpf;
692 712
693 apic_printk(APIC_VERBOSE, "Scan SMP from %p for %ld bytes.\n", 713 apic_printk(APIC_VERBOSE, "Scan SMP from %p for %ld bytes.\n",
694 bp, length); 714 bp, length);
695 BUILD_BUG_ON(sizeof(*mpf) != 16); 715 BUILD_BUG_ON(sizeof(*mpf) != 16);
696 716
697 while (length > 0) { 717 while (length > 0) {
698 mpf = (struct intel_mp_floating *)bp; 718 mpf = (struct mpf_intel *)bp;
699 if ((*bp == SMP_MAGIC_IDENT) && 719 if ((*bp == SMP_MAGIC_IDENT) &&
700 (mpf->mpf_length == 1) && 720 (mpf->length == 1) &&
701 !mpf_checksum((unsigned char *)bp, 16) && 721 !mpf_checksum((unsigned char *)bp, 16) &&
702 ((mpf->mpf_specification == 1) 722 ((mpf->specification == 1)
703 || (mpf->mpf_specification == 4))) { 723 || (mpf->specification == 4))) {
704#ifdef CONFIG_X86_LOCAL_APIC 724#ifdef CONFIG_X86_LOCAL_APIC
705 smp_found_config = 1; 725 smp_found_config = 1;
706#endif 726#endif
707 mpf_found = mpf; 727 mpf_found = mpf;
708 728
709 printk(KERN_INFO "found SMP MP-table at [%p] %08lx\n", 729 printk(KERN_INFO "found SMP MP-table at [%p] %llx\n",
710 mpf, virt_to_phys(mpf)); 730 mpf, (u64)virt_to_phys(mpf));
711 731
712 if (!reserve) 732 if (!reserve)
713 return 1; 733 return 1;
714 reserve_bootmem_generic(virt_to_phys(mpf), PAGE_SIZE, 734 reserve_bootmem_generic(virt_to_phys(mpf), sizeof(*mpf),
715 BOOTMEM_DEFAULT);
716 if (mpf->mpf_physptr) {
717 unsigned long size = PAGE_SIZE;
718#ifdef CONFIG_X86_32
719 /*
720 * We cannot access to MPC table to compute
721 * table size yet, as only few megabytes from
722 * the bottom is mapped now.
723 * PC-9800's MPC table places on the very last
724 * of physical memory; so that simply reserving
725 * PAGE_SIZE from mpg->mpf_physptr yields BUG()
726 * in reserve_bootmem.
727 */
728 unsigned long end = max_low_pfn * PAGE_SIZE;
729 if (mpf->mpf_physptr + size > end)
730 size = end - mpf->mpf_physptr;
731#endif
732 reserve_bootmem_generic(mpf->mpf_physptr, size,
733 BOOTMEM_DEFAULT); 735 BOOTMEM_DEFAULT);
734 } 736 if (mpf->physptr)
737 smp_reserve_bootmem(mpf);
735 738
736 return 1; 739 return 1;
737 } 740 }
@@ -809,15 +812,15 @@ static int __init get_MP_intsrc_index(struct mpc_intsrc *m)
809 /* not legacy */ 812 /* not legacy */
810 813
811 for (i = 0; i < mp_irq_entries; i++) { 814 for (i = 0; i < mp_irq_entries; i++) {
812 if (mp_irqs[i].mp_irqtype != mp_INT) 815 if (mp_irqs[i].irqtype != mp_INT)
813 continue; 816 continue;
814 817
815 if (mp_irqs[i].mp_irqflag != 0x0f) 818 if (mp_irqs[i].irqflag != 0x0f)
816 continue; 819 continue;
817 820
818 if (mp_irqs[i].mp_srcbus != m->srcbus) 821 if (mp_irqs[i].srcbus != m->srcbus)
819 continue; 822 continue;
820 if (mp_irqs[i].mp_srcbusirq != m->srcbusirq) 823 if (mp_irqs[i].srcbusirq != m->srcbusirq)
821 continue; 824 continue;
822 if (irq_used[i]) { 825 if (irq_used[i]) {
823 /* already claimed */ 826 /* already claimed */
@@ -834,7 +837,57 @@ static int __init get_MP_intsrc_index(struct mpc_intsrc *m)
834#define SPARE_SLOT_NUM 20 837#define SPARE_SLOT_NUM 20
835 838
836static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM]; 839static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM];
837#endif 840
841static void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare)
842{
843 int i;
844
845 apic_printk(APIC_VERBOSE, "OLD ");
846 print_MP_intsrc_info(m);
847
848 i = get_MP_intsrc_index(m);
849 if (i > 0) {
850 assign_to_mpc_intsrc(&mp_irqs[i], m);
851 apic_printk(APIC_VERBOSE, "NEW ");
852 print_mp_irq_info(&mp_irqs[i]);
853 return;
854 }
855 if (!i) {
856 /* legacy, do nothing */
857 return;
858 }
859 if (*nr_m_spare < SPARE_SLOT_NUM) {
860 /*
861 * not found (-1), or duplicated (-2) are invalid entries,
862 * we need to use the slot later
863 */
864 m_spare[*nr_m_spare] = m;
865 *nr_m_spare += 1;
866 }
867}
868#else /* CONFIG_X86_IO_APIC */
869static inline void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {}
870#endif /* CONFIG_X86_IO_APIC */
871
872static int check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length,
873 int count)
874{
875 if (!mpc_new_phys) {
876 pr_info("No spare slots, try to append...take your risk, "
877 "new mpc_length %x\n", count);
878 } else {
879 if (count <= mpc_new_length)
880 pr_info("No spare slots, try to append..., "
881 "new mpc_length %x\n", count);
882 else {
883 pr_err("mpc_new_length %lx is too small\n",
884 mpc_new_length);
885 return -1;
886 }
887 }
888
889 return 0;
890}
838 891
839static int __init replace_intsrc_all(struct mpc_table *mpc, 892static int __init replace_intsrc_all(struct mpc_table *mpc,
840 unsigned long mpc_new_phys, 893 unsigned long mpc_new_phys,
@@ -842,77 +895,33 @@ static int __init replace_intsrc_all(struct mpc_table *mpc,
842{ 895{
843#ifdef CONFIG_X86_IO_APIC 896#ifdef CONFIG_X86_IO_APIC
844 int i; 897 int i;
845 int nr_m_spare = 0;
846#endif 898#endif
847
848 int count = sizeof(*mpc); 899 int count = sizeof(*mpc);
900 int nr_m_spare = 0;
849 unsigned char *mpt = ((unsigned char *)mpc) + count; 901 unsigned char *mpt = ((unsigned char *)mpc) + count;
850 902
851 printk(KERN_INFO "mpc_length %x\n", mpc->length); 903 printk(KERN_INFO "mpc_length %x\n", mpc->length);
852 while (count < mpc->length) { 904 while (count < mpc->length) {
853 switch (*mpt) { 905 switch (*mpt) {
854 case MP_PROCESSOR: 906 case MP_PROCESSOR:
855 { 907 skip_entry(&mpt, &count, sizeof(struct mpc_cpu));
856 struct mpc_cpu *m = (struct mpc_cpu *)mpt; 908 break;
857 mpt += sizeof(*m);
858 count += sizeof(*m);
859 break;
860 }
861 case MP_BUS: 909 case MP_BUS:
862 { 910 skip_entry(&mpt, &count, sizeof(struct mpc_bus));
863 struct mpc_bus *m = (struct mpc_bus *)mpt; 911 break;
864 mpt += sizeof(*m);
865 count += sizeof(*m);
866 break;
867 }
868 case MP_IOAPIC: 912 case MP_IOAPIC:
869 { 913 skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));
870 mpt += sizeof(struct mpc_ioapic); 914 break;
871 count += sizeof(struct mpc_ioapic);
872 break;
873 }
874 case MP_INTSRC: 915 case MP_INTSRC:
875 { 916 check_irq_src((struct mpc_intsrc *)mpt, &nr_m_spare);
876#ifdef CONFIG_X86_IO_APIC 917 skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));
877 struct mpc_intsrc *m = (struct mpc_intsrc *)mpt; 918 break;
878
879 printk(KERN_INFO "OLD ");
880 print_MP_intsrc_info(m);
881 i = get_MP_intsrc_index(m);
882 if (i > 0) {
883 assign_to_mpc_intsrc(&mp_irqs[i], m);
884 printk(KERN_INFO "NEW ");
885 print_mp_irq_info(&mp_irqs[i]);
886 } else if (!i) {
887 /* legacy, do nothing */
888 } else if (nr_m_spare < SPARE_SLOT_NUM) {
889 /*
890 * not found (-1), or duplicated (-2)
891 * are invalid entries,
892 * we need to use the slot later
893 */
894 m_spare[nr_m_spare] = m;
895 nr_m_spare++;
896 }
897#endif
898 mpt += sizeof(struct mpc_intsrc);
899 count += sizeof(struct mpc_intsrc);
900 break;
901 }
902 case MP_LINTSRC: 919 case MP_LINTSRC:
903 { 920 skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc));
904 struct mpc_lintsrc *m = 921 break;
905 (struct mpc_lintsrc *)mpt;
906 mpt += sizeof(*m);
907 count += sizeof(*m);
908 break;
909 }
910 default: 922 default:
911 /* wrong mptable */ 923 /* wrong mptable */
912 printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n"); 924 smp_dump_mptable(mpc, mpt);
913 printk(KERN_ERR "type %x\n", *mpt);
914 print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_ADDRESS, 16,
915 1, mpc, mpc->length, 1);
916 goto out; 925 goto out;
917 } 926 }
918 } 927 }
@@ -922,30 +931,22 @@ static int __init replace_intsrc_all(struct mpc_table *mpc,
922 if (irq_used[i]) 931 if (irq_used[i])
923 continue; 932 continue;
924 933
925 if (mp_irqs[i].mp_irqtype != mp_INT) 934 if (mp_irqs[i].irqtype != mp_INT)
926 continue; 935 continue;
927 936
928 if (mp_irqs[i].mp_irqflag != 0x0f) 937 if (mp_irqs[i].irqflag != 0x0f)
929 continue; 938 continue;
930 939
931 if (nr_m_spare > 0) { 940 if (nr_m_spare > 0) {
932 printk(KERN_INFO "*NEW* found "); 941 apic_printk(APIC_VERBOSE, "*NEW* found\n");
933 nr_m_spare--; 942 nr_m_spare--;
934 assign_to_mpc_intsrc(&mp_irqs[i], m_spare[nr_m_spare]); 943 assign_to_mpc_intsrc(&mp_irqs[i], m_spare[nr_m_spare]);
935 m_spare[nr_m_spare] = NULL; 944 m_spare[nr_m_spare] = NULL;
936 } else { 945 } else {
937 struct mpc_intsrc *m = (struct mpc_intsrc *)mpt; 946 struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
938 count += sizeof(struct mpc_intsrc); 947 count += sizeof(struct mpc_intsrc);
939 if (!mpc_new_phys) { 948 if (!check_slot(mpc_new_phys, mpc_new_length, count))
940 printk(KERN_INFO "No spare slots, try to append...take your risk, new mpc_length %x\n", count); 949 goto out;
941 } else {
942 if (count <= mpc_new_length)
943 printk(KERN_INFO "No spare slots, try to append..., new mpc_length %x\n", count);
944 else {
945 printk(KERN_ERR "mpc_new_length %lx is too small\n", mpc_new_length);
946 goto out;
947 }
948 }
949 assign_to_mpc_intsrc(&mp_irqs[i], m); 950 assign_to_mpc_intsrc(&mp_irqs[i], m);
950 mpc->length = count; 951 mpc->length = count;
951 mpt += sizeof(struct mpc_intsrc); 952 mpt += sizeof(struct mpc_intsrc);
@@ -1001,7 +1002,7 @@ static int __init update_mp_table(void)
1001{ 1002{
1002 char str[16]; 1003 char str[16];
1003 char oem[10]; 1004 char oem[10];
1004 struct intel_mp_floating *mpf; 1005 struct mpf_intel *mpf;
1005 struct mpc_table *mpc, *mpc_new; 1006 struct mpc_table *mpc, *mpc_new;
1006 1007
1007 if (!enable_update_mptable) 1008 if (!enable_update_mptable)
@@ -1014,19 +1015,19 @@ static int __init update_mp_table(void)
1014 /* 1015 /*
1015 * Now see if we need to go further. 1016 * Now see if we need to go further.
1016 */ 1017 */
1017 if (mpf->mpf_feature1 != 0) 1018 if (mpf->feature1 != 0)
1018 return 0; 1019 return 0;
1019 1020
1020 if (!mpf->mpf_physptr) 1021 if (!mpf->physptr)
1021 return 0; 1022 return 0;
1022 1023
1023 mpc = phys_to_virt(mpf->mpf_physptr); 1024 mpc = phys_to_virt(mpf->physptr);
1024 1025
1025 if (!smp_check_mpc(mpc, oem, str)) 1026 if (!smp_check_mpc(mpc, oem, str))
1026 return 0; 1027 return 0;
1027 1028
1028 printk(KERN_INFO "mpf: %lx\n", virt_to_phys(mpf)); 1029 printk(KERN_INFO "mpf: %llx\n", (u64)virt_to_phys(mpf));
1029 printk(KERN_INFO "mpf_physptr: %x\n", mpf->mpf_physptr); 1030 printk(KERN_INFO "physptr: %x\n", mpf->physptr);
1030 1031
1031 if (mpc_new_phys && mpc->length > mpc_new_length) { 1032 if (mpc_new_phys && mpc->length > mpc_new_length) {
1032 mpc_new_phys = 0; 1033 mpc_new_phys = 0;
@@ -1047,23 +1048,23 @@ static int __init update_mp_table(void)
1047 } 1048 }
1048 printk(KERN_INFO "use in-positon replacing\n"); 1049 printk(KERN_INFO "use in-positon replacing\n");
1049 } else { 1050 } else {
1050 mpf->mpf_physptr = mpc_new_phys; 1051 mpf->physptr = mpc_new_phys;
1051 mpc_new = phys_to_virt(mpc_new_phys); 1052 mpc_new = phys_to_virt(mpc_new_phys);
1052 memcpy(mpc_new, mpc, mpc->length); 1053 memcpy(mpc_new, mpc, mpc->length);
1053 mpc = mpc_new; 1054 mpc = mpc_new;
1054 /* check if we can modify that */ 1055 /* check if we can modify that */
1055 if (mpc_new_phys - mpf->mpf_physptr) { 1056 if (mpc_new_phys - mpf->physptr) {
1056 struct intel_mp_floating *mpf_new; 1057 struct mpf_intel *mpf_new;
1057 /* steal 16 bytes from [0, 1k) */ 1058 /* steal 16 bytes from [0, 1k) */
1058 printk(KERN_INFO "mpf new: %x\n", 0x400 - 16); 1059 printk(KERN_INFO "mpf new: %x\n", 0x400 - 16);
1059 mpf_new = phys_to_virt(0x400 - 16); 1060 mpf_new = phys_to_virt(0x400 - 16);
1060 memcpy(mpf_new, mpf, 16); 1061 memcpy(mpf_new, mpf, 16);
1061 mpf = mpf_new; 1062 mpf = mpf_new;
1062 mpf->mpf_physptr = mpc_new_phys; 1063 mpf->physptr = mpc_new_phys;
1063 } 1064 }
1064 mpf->mpf_checksum = 0; 1065 mpf->checksum = 0;
1065 mpf->mpf_checksum -= mpf_checksum((unsigned char *)mpf, 16); 1066 mpf->checksum -= mpf_checksum((unsigned char *)mpf, 16);
1066 printk(KERN_INFO "mpf_physptr new: %x\n", mpf->mpf_physptr); 1067 printk(KERN_INFO "physptr new: %x\n", mpf->physptr);
1067 } 1068 }
1068 1069
1069 /* 1070 /*