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