File: /usr/src/linux/arch/i386/kernel/mpparse.c
1 /*
2 * Intel Multiprocessor Specificiation 1.1 and 1.4
3 * compliant MP-table parsing routines.
4 *
5 * (c) 1995 Alan Cox, Building #3 <alan@redhat.com>
6 * (c) 1998, 1999, 2000 Ingo Molnar <mingo@redhat.com>
7 *
8 * Fixes
9 * Erich Boleyn : MP v1.4 and additional changes.
10 * Alan Cox : Added EBDA scanning
11 * Ingo Molnar : various cleanups and rewrites
12 * Maciej W. Rozycki : Bits for default MP configurations
13 */
14
15 #include <linux/mm.h>
16 #include <linux/irq.h>
17 #include <linux/init.h>
18 #include <linux/delay.h>
19 #include <linux/config.h>
20 #include <linux/bootmem.h>
21 #include <linux/smp_lock.h>
22 #include <linux/kernel_stat.h>
23 #include <linux/mc146818rtc.h>
24
25 #include <asm/smp.h>
26 #include <asm/mtrr.h>
27 #include <asm/mpspec.h>
28 #include <asm/pgalloc.h>
29
30 /* Have we found an MP table */
31 int smp_found_config;
32
33 /*
34 * Various Linux-internal data structures created from the
35 * MP-table.
36 */
37 int apic_version [MAX_APICS];
38 int mp_bus_id_to_type [MAX_MP_BUSSES];
39 int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
40 int mp_current_pci_id;
41
42 /* I/O APIC entries */
43 struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
44
45 /* # of MP IRQ source entries */
46 struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
47
48 /* MP IRQ source entries */
49 int mp_irq_entries;
50
51 int nr_ioapics;
52
53 int pic_mode;
54 unsigned long mp_lapic_addr;
55
56 /* Processor that is doing the boot up */
57 unsigned int boot_cpu_id = -1U;
58 /* Internal processor count */
59 static unsigned int num_processors;
60
61 /* Bitmask of physically existing CPUs */
62 unsigned long phys_cpu_present_map;
63
64 /*
65 * Intel MP BIOS table parsing routines:
66 */
67
68 #ifndef CONFIG_X86_VISWS_APIC
69 /*
70 * Checksum an MP configuration block.
71 */
72
73 static int __init mpf_checksum(unsigned char *mp, int len)
74 {
75 int sum = 0;
76
77 while (len--)
78 sum += *mp++;
79
80 return sum & 0xFF;
81 }
82
83 /*
84 * Processor encoding in an MP configuration block
85 */
86
87 static char __init *mpc_family(int family,int model)
88 {
89 static char n[32];
90 static char *model_defs[]=
91 {
92 "80486DX","80486DX",
93 "80486SX","80486DX/2 or 80487",
94 "80486SL","80486SX/2",
95 "Unknown","80486DX/2-WB",
96 "80486DX/4","80486DX/4-WB"
97 };
98
99 switch (family) {
100 case 0x04:
101 if (model < 10)
102 return model_defs[model];
103 break;
104
105 case 0x05:
106 return("Pentium(tm)");
107
108 case 0x06:
109 return("Pentium(tm) Pro");
110
111 case 0x0F:
112 if (model == 0x00)
113 return("Pentium 4(tm)");
114 if (model == 0x0F)
115 return("Special controller");
116 }
117 sprintf(n,"Unknown CPU [%d:%d]",family, model);
118 return n;
119 }
120
121 static void __init MP_processor_info (struct mpc_config_processor *m)
122 {
123 int ver;
124
125 if (!(m->mpc_cpuflag & CPU_ENABLED))
126 return;
127
128 printk("Processor #%d %s APIC version %d\n",
129 m->mpc_apicid,
130 mpc_family( (m->mpc_cpufeature & CPU_FAMILY_MASK)>>8 ,
131 (m->mpc_cpufeature & CPU_MODEL_MASK)>>4),
132 m->mpc_apicver);
133
134 if (m->mpc_featureflag&(1<<0))
135 Dprintk(" Floating point unit present.\n");
136 if (m->mpc_featureflag&(1<<7))
137 Dprintk(" Machine Exception supported.\n");
138 if (m->mpc_featureflag&(1<<8))
139 Dprintk(" 64 bit compare & exchange supported.\n");
140 if (m->mpc_featureflag&(1<<9))
141 Dprintk(" Internal APIC present.\n");
142 if (m->mpc_featureflag&(1<<11))
143 Dprintk(" SEP present.\n");
144 if (m->mpc_featureflag&(1<<12))
145 Dprintk(" MTRR present.\n");
146 if (m->mpc_featureflag&(1<<13))
147 Dprintk(" PGE present.\n");
148 if (m->mpc_featureflag&(1<<14))
149 Dprintk(" MCA present.\n");
150 if (m->mpc_featureflag&(1<<15))
151 Dprintk(" CMOV present.\n");
152 if (m->mpc_featureflag&(1<<16))
153 Dprintk(" PAT present.\n");
154 if (m->mpc_featureflag&(1<<17))
155 Dprintk(" PSE present.\n");
156 if (m->mpc_featureflag&(1<<18))
157 Dprintk(" PSN present.\n");
158 if (m->mpc_featureflag&(1<<19))
159 Dprintk(" Cache Line Flush Instruction present.\n");
160 /* 20 Reserved */
161 if (m->mpc_featureflag&(1<<21))
162 Dprintk(" Debug Trace and EMON Store present.\n");
163 if (m->mpc_featureflag&(1<<22))
164 Dprintk(" ACPI Thermal Throttle Registers present.\n");
165 if (m->mpc_featureflag&(1<<23))
166 Dprintk(" MMX present.\n");
167 if (m->mpc_featureflag&(1<<24))
168 Dprintk(" FXSR present.\n");
169 if (m->mpc_featureflag&(1<<25))
170 Dprintk(" XMM present.\n");
171 if (m->mpc_featureflag&(1<<26))
172 Dprintk(" Willamette New Instructions present.\n");
173 if (m->mpc_featureflag&(1<<27))
174 Dprintk(" Self Snoop present.\n");
175 /* 28 Reserved */
176 if (m->mpc_featureflag&(1<<29))
177 Dprintk(" Thermal Monitor present.\n");
178 /* 30, 31 Reserved */
179
180
181 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
182 Dprintk(" Bootup CPU\n");
183 boot_cpu_id = m->mpc_apicid;
184 }
185 num_processors++;
186
187 if (m->mpc_apicid > MAX_APICS) {
188 printk("Processor #%d INVALID. (Max ID: %d).\n",
189 m->mpc_apicid, MAX_APICS);
190 return;
191 }
192 ver = m->mpc_apicver;
193
194 phys_cpu_present_map |= 1 << m->mpc_apicid;
195 /*
196 * Validate version
197 */
198 if (ver == 0x0) {
199 printk("BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid);
200 ver = 0x10;
201 }
202 apic_version[m->mpc_apicid] = ver;
203 }
204
205 static void __init MP_bus_info (struct mpc_config_bus *m)
206 {
207 char str[7];
208
209 memcpy(str, m->mpc_bustype, 6);
210 str[6] = 0;
211 Dprintk("Bus #%d is %s\n", m->mpc_busid, str);
212
213 if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) {
214 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
215 } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) {
216 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
217 } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) {
218 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
219 mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id;
220 mp_current_pci_id++;
221 } else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) {
222 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA;
223 } else {
224 printk("Unknown bustype %s - ignoring\n", str);
225 }
226 }
227
228 static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
229 {
230 if (!(m->mpc_flags & MPC_APIC_USABLE))
231 return;
232
233 printk("I/O APIC #%d Version %d at 0x%lX.\n",
234 m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr);
235 if (nr_ioapics >= MAX_IO_APICS) {
236 printk("Max # of I/O APICs (%d) exceeded (found %d).\n",
237 MAX_IO_APICS, nr_ioapics);
238 panic("Recompile kernel with bigger MAX_IO_APICS!.\n");
239 }
240 if (!m->mpc_apicaddr) {
241 printk(KERN_ERR "WARNING: bogus zero I/O APIC address"
242 " found in MP table, skipping!\n");
243 return;
244 }
245 mp_ioapics[nr_ioapics] = *m;
246 nr_ioapics++;
247 }
248
249 static void __init MP_intsrc_info (struct mpc_config_intsrc *m)
250 {
251 mp_irqs [mp_irq_entries] = *m;
252 Dprintk("Int: type %d, pol %d, trig %d, bus %d,"
253 " IRQ %02x, APIC ID %x, APIC INT %02x\n",
254 m->mpc_irqtype, m->mpc_irqflag & 3,
255 (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus,
256 m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq);
257 if (++mp_irq_entries == MAX_IRQ_SOURCES)
258 panic("Max # of irq sources exceeded!!\n");
259 }
260
261 static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m)
262 {
263 Dprintk("Lint: type %d, pol %d, trig %d, bus %d,"
264 " IRQ %02x, APIC ID %x, APIC LINT %02x\n",
265 m->mpc_irqtype, m->mpc_irqflag & 3,
266 (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid,
267 m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint);
268 /*
269 * Well it seems all SMP boards in existence
270 * use ExtINT/LVT1 == LINT0 and
271 * NMI/LVT2 == LINT1 - the following check
272 * will show us if this assumptions is false.
273 * Until then we do not have to add baggage.
274 */
275 if ((m->mpc_irqtype == mp_ExtINT) &&
276 (m->mpc_destapiclint != 0))
277 BUG();
278 if ((m->mpc_irqtype == mp_NMI) &&
279 (m->mpc_destapiclint != 1))
280 BUG();
281 }
282
283 /*
284 * Read/parse the MPC
285 */
286
287 static int __init smp_read_mpc(struct mp_config_table *mpc)
288 {
289 char str[16];
290 int count=sizeof(*mpc);
291 unsigned char *mpt=((unsigned char *)mpc)+count;
292
293 if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) {
294 panic("SMP mptable: bad signature [%c%c%c%c]!\n",
295 mpc->mpc_signature[0],
296 mpc->mpc_signature[1],
297 mpc->mpc_signature[2],
298 mpc->mpc_signature[3]);
299 return 0;
300 }
301 if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) {
302 panic("SMP mptable: checksum error!\n");
303 return 0;
304 }
305 if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) {
306 printk(KERN_ERR "SMP mptable: bad table version (%d)!!\n",
307 mpc->mpc_spec);
308 return 0;
309 }
310 if (!mpc->mpc_lapic) {
311 printk(KERN_ERR "SMP mptable: null local APIC address!\n");
312 return 0;
313 }
314 memcpy(str,mpc->mpc_oem,8);
315 str[8]=0;
316 printk("OEM ID: %s ",str);
317
318 memcpy(str,mpc->mpc_productid,12);
319 str[12]=0;
320 printk("Product ID: %s ",str);
321
322 printk("APIC at: 0x%lX\n",mpc->mpc_lapic);
323
324 /* save the local APIC address, it might be non-default */
325 mp_lapic_addr = mpc->mpc_lapic;
326
327 /*
328 * Now process the configuration blocks.
329 */
330 while (count < mpc->mpc_length) {
331 switch(*mpt) {
332 case MP_PROCESSOR:
333 {
334 struct mpc_config_processor *m=
335 (struct mpc_config_processor *)mpt;
336 MP_processor_info(m);
337 mpt += sizeof(*m);
338 count += sizeof(*m);
339 break;
340 }
341 case MP_BUS:
342 {
343 struct mpc_config_bus *m=
344 (struct mpc_config_bus *)mpt;
345 MP_bus_info(m);
346 mpt += sizeof(*m);
347 count += sizeof(*m);
348 break;
349 }
350 case MP_IOAPIC:
351 {
352 struct mpc_config_ioapic *m=
353 (struct mpc_config_ioapic *)mpt;
354 MP_ioapic_info(m);
355 mpt+=sizeof(*m);
356 count+=sizeof(*m);
357 break;
358 }
359 case MP_INTSRC:
360 {
361 struct mpc_config_intsrc *m=
362 (struct mpc_config_intsrc *)mpt;
363
364 MP_intsrc_info(m);
365 mpt+=sizeof(*m);
366 count+=sizeof(*m);
367 break;
368 }
369 case MP_LINTSRC:
370 {
371 struct mpc_config_lintsrc *m=
372 (struct mpc_config_lintsrc *)mpt;
373 MP_lintsrc_info(m);
374 mpt+=sizeof(*m);
375 count+=sizeof(*m);
376 break;
377 }
378 }
379 }
380 if (!num_processors)
381 printk(KERN_ERR "SMP mptable: no processors registered!\n");
382 return num_processors;
383 }
384
385 static int __init ELCR_trigger(unsigned int irq)
386 {
387 unsigned int port;
388
389 port = 0x4d0 + (irq >> 3);
390 return (inb(port) >> (irq & 7)) & 1;
391 }
392
393 static void __init construct_default_ioirq_mptable(int mpc_default_type)
394 {
395 struct mpc_config_intsrc intsrc;
396 int i;
397 int ELCR_fallback = 0;
398
399 intsrc.mpc_type = MP_INTSRC;
400 intsrc.mpc_irqflag = 0; /* conforming */
401 intsrc.mpc_srcbus = 0;
402 intsrc.mpc_dstapic = mp_ioapics[0].mpc_apicid;
403
404 intsrc.mpc_irqtype = mp_INT;
405
406 /*
407 * If true, we have an ISA/PCI system with no IRQ entries
408 * in the MP table. To prevent the PCI interrupts from being set up
409 * incorrectly, we try to use the ELCR. The sanity check to see if
410 * there is good ELCR data is very simple - IRQ0, 1, 2 and 13 can
411 * never be level sensitive, so we simply see if the ELCR agrees.
412 * If it does, we assume it's valid.
413 */
414 if (mpc_default_type == 5) {
415 printk("ISA/PCI bus type with no IRQ information... falling back to ELCR\n");
416
417 if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) || ELCR_trigger(13))
418 printk("ELCR contains invalid data... not using ELCR\n");
419 else {
420 printk("Using ELCR to identify PCI interrupts\n");
421 ELCR_fallback = 1;
422 }
423 }
424
425 for (i = 0; i < 16; i++) {
426 switch (mpc_default_type) {
427 case 2:
428 if (i == 0 || i == 13)
429 continue; /* IRQ0 & IRQ13 not connected */
430 /* fall through */
431 default:
432 if (i == 2)
433 continue; /* IRQ2 is never connected */
434 }
435
436 if (ELCR_fallback) {
437 /*
438 * If the ELCR indicates a level-sensitive interrupt, we
439 * copy that information over to the MP table in the
440 * irqflag field (level sensitive, active high polarity).
441 */
442 if (ELCR_trigger(i))
443 intsrc.mpc_irqflag = 13;
444 else
445 intsrc.mpc_irqflag = 0;
446 }
447
448 intsrc.mpc_srcbusirq = i;
449 intsrc.mpc_dstirq = i ? i : 2; /* IRQ0 to INTIN2 */
450 MP_intsrc_info(&intsrc);
451 }
452
453 intsrc.mpc_irqtype = mp_ExtINT;
454 intsrc.mpc_srcbusirq = 0;
455 intsrc.mpc_dstirq = 0; /* 8259A to INTIN0 */
456 MP_intsrc_info(&intsrc);
457 }
458
459 static inline void __init construct_default_ISA_mptable(int mpc_default_type)
460 {
461 struct mpc_config_processor processor;
462 struct mpc_config_bus bus;
463 struct mpc_config_ioapic ioapic;
464 struct mpc_config_lintsrc lintsrc;
465 int linttypes[2] = { mp_ExtINT, mp_NMI };
466 int i;
467
468 /*
469 * local APIC has default address
470 */
471 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
472
473 /*
474 * 2 CPUs, numbered 0 & 1.
475 */
476 processor.mpc_type = MP_PROCESSOR;
477 /* Either an integrated APIC or a discrete 82489DX. */
478 processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
479 processor.mpc_cpuflag = CPU_ENABLED;
480 processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) |
481 (boot_cpu_data.x86_model << 4) |
482 boot_cpu_data.x86_mask;
483 processor.mpc_featureflag = boot_cpu_data.x86_capability[0];
484 processor.mpc_reserved[0] = 0;
485 processor.mpc_reserved[1] = 0;
486 for (i = 0; i < 2; i++) {
487 processor.mpc_apicid = i;
488 MP_processor_info(&processor);
489 }
490
491 bus.mpc_type = MP_BUS;
492 bus.mpc_busid = 0;
493 switch (mpc_default_type) {
494 default:
495 printk("???\nUnknown standard configuration %d\n",
496 mpc_default_type);
497 /* fall through */
498 case 1:
499 case 5:
500 memcpy(bus.mpc_bustype, "ISA ", 6);
501 break;
502 case 2:
503 case 6:
504 case 3:
505 memcpy(bus.mpc_bustype, "EISA ", 6);
506 break;
507 case 4:
508 case 7:
509 memcpy(bus.mpc_bustype, "MCA ", 6);
510 }
511 MP_bus_info(&bus);
512 if (mpc_default_type > 4) {
513 bus.mpc_busid = 1;
514 memcpy(bus.mpc_bustype, "PCI ", 6);
515 MP_bus_info(&bus);
516 }
517
518 ioapic.mpc_type = MP_IOAPIC;
519 ioapic.mpc_apicid = 2;
520 ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
521 ioapic.mpc_flags = MPC_APIC_USABLE;
522 ioapic.mpc_apicaddr = 0xFEC00000;
523 MP_ioapic_info(&ioapic);
524
525 /*
526 * We set up most of the low 16 IO-APIC pins according to MPS rules.
527 */
528 construct_default_ioirq_mptable(mpc_default_type);
529
530 lintsrc.mpc_type = MP_LINTSRC;
531 lintsrc.mpc_irqflag = 0; /* conforming */
532 lintsrc.mpc_srcbusid = 0;
533 lintsrc.mpc_srcbusirq = 0;
534 lintsrc.mpc_destapic = MP_APIC_ALL;
535 for (i = 0; i < 2; i++) {
536 lintsrc.mpc_irqtype = linttypes[i];
537 lintsrc.mpc_destapiclint = i;
538 MP_lintsrc_info(&lintsrc);
539 }
540 }
541
542 static struct intel_mp_floating *mpf_found;
543
544 /*
545 * Scan the memory blocks for an SMP configuration block.
546 */
547 void __init get_smp_config (void)
548 {
549 struct intel_mp_floating *mpf = mpf_found;
550 printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
551 if (mpf->mpf_feature2 & (1<<7)) {
552 printk(" IMCR and PIC compatibility mode.\n");
553 pic_mode = 1;
554 } else {
555 printk(" Virtual Wire compatibility mode.\n");
556 pic_mode = 0;
557 }
558
559 /*
560 * Now see if we need to read further.
561 */
562 if (mpf->mpf_feature1 != 0) {
563
564 printk("Default MP configuration #%d\n", mpf->mpf_feature1);
565 construct_default_ISA_mptable(mpf->mpf_feature1);
566
567 } else if (mpf->mpf_physptr) {
568
569 /*
570 * Read the physical hardware table. Anything here will
571 * override the defaults.
572 */
573 if (!smp_read_mpc((void *)mpf->mpf_physptr)) {
574 smp_found_config = 0;
575 printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
576 printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
577 return;
578 }
579 /*
580 * If there are no explicit MP IRQ entries, then we are
581 * broken. We set up most of the low 16 IO-APIC pins to
582 * ISA defaults and hope it will work.
583 */
584 if (!mp_irq_entries) {
585 struct mpc_config_bus bus;
586
587 printk("BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");
588
589 bus.mpc_type = MP_BUS;
590 bus.mpc_busid = 0;
591 memcpy(bus.mpc_bustype, "ISA ", 6);
592 MP_bus_info(&bus);
593
594 construct_default_ioirq_mptable(0);
595 }
596
597 } else
598 BUG();
599
600 printk("Processors: %d\n", num_processors);
601 /*
602 * Only use the first configuration found.
603 */
604 }
605
606 static int __init smp_scan_config (unsigned long base, unsigned long length)
607 {
608 unsigned long *bp = phys_to_virt(base);
609 struct intel_mp_floating *mpf;
610
611 Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
612 if (sizeof(*mpf) != 16)
613 printk("Error: MPF size\n");
614
615 while (length > 0) {
616 mpf = (struct intel_mp_floating *)bp;
617 if ((*bp == SMP_MAGIC_IDENT) &&
618 (mpf->mpf_length == 1) &&
619 !mpf_checksum((unsigned char *)bp, 16) &&
620 ((mpf->mpf_specification == 1)
621 || (mpf->mpf_specification == 4)) ) {
622
623 smp_found_config = 1;
624 printk("found SMP MP-table at %08lx\n",
625 virt_to_phys(mpf));
626 reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE);
627 if (mpf->mpf_physptr)
628 reserve_bootmem(mpf->mpf_physptr, PAGE_SIZE);
629 mpf_found = mpf;
630 return 1;
631 }
632 bp += 4;
633 length -= 16;
634 }
635 return 0;
636 }
637
638 void __init find_intel_smp (void)
639 {
640 unsigned int address;
641
642 /*
643 * FIXME: Linux assumes you have 640K of base ram..
644 * this continues the error...
645 *
646 * 1) Scan the bottom 1K for a signature
647 * 2) Scan the top 1K of base RAM
648 * 3) Scan the 64K of bios
649 */
650 if (smp_scan_config(0x0,0x400) ||
651 smp_scan_config(639*0x400,0x400) ||
652 smp_scan_config(0xF0000,0x10000))
653 return;
654 /*
655 * If it is an SMP machine we should know now, unless the
656 * configuration is in an EISA/MCA bus machine with an
657 * extended bios data area.
658 *
659 * there is a real-mode segmented pointer pointing to the
660 * 4K EBDA area at 0x40E, calculate and scan it here.
661 *
662 * NOTE! There are Linux loaders that will corrupt the EBDA
663 * area, and as such this kind of SMP config may be less
664 * trustworthy, simply because the SMP table may have been
665 * stomped on during early boot. These loaders are buggy and
666 * should be fixed.
667 */
668
669 address = *(unsigned short *)phys_to_virt(0x40E);
670 address <<= 4;
671 smp_scan_config(address, 0x1000);
672 if (smp_found_config)
673 printk(KERN_WARNING "WARNING: MP table in the EBDA can be UNSAFE, contact linux-smp@vger.kernel.org if you experience SMP problems!\n");
674 }
675
676 #else
677
678 /*
679 * The Visual Workstation is Intel MP compliant in the hardware
680 * sense, but it doesnt have a BIOS(-configuration table).
681 * No problem for Linux.
682 */
683 void __init find_visws_smp(void)
684 {
685 smp_found_config = 1;
686
687 phys_cpu_present_map |= 2; /* or in id 1 */
688 apic_version[1] |= 0x10; /* integrated APIC */
689 apic_version[0] |= 0x10;
690
691 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
692 }
693
694 #endif
695
696 /*
697 * - Intel MP Configuration Table
698 * - or SGI Visual Workstation configuration
699 */
700 void __init find_smp_config (void)
701 {
702 #ifdef CONFIG_X86_LOCAL_APIC
703 find_intel_smp();
704 #endif
705 #ifdef CONFIG_VISWS
706 find_visws_smp();
707 #endif
708 }
709
710