2
[_Anarchy_(alan@lightning.swansea.uk.linux.org)] you should do one check
3
though - if the board seems to be SMP and the CPU in /proc/cpuinfo is non
4
intel dont install an SMP kernel - thats a dual pentium board with a cyrix
5
or similar single cpu in it
18
#define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_')
20
struct intel_mp_floating
22
char mpf_signature[4]; /* "_MP_" */
23
unsigned long mpf_physptr; /* Configuration table address */
24
unsigned char mpf_length; /* Our length (paragraphs) */
25
unsigned char mpf_specification;/* Specification version */
26
unsigned char mpf_checksum; /* Checksum (makes sum 0) */
27
unsigned char mpf_feature1; /* Standard or configuration ? */
28
unsigned char mpf_feature2; /* Bit7 set for IMCR|PIC */
29
unsigned char mpf_feature3; /* Unused (0) */
30
unsigned char mpf_feature4; /* Unused (0) */
31
unsigned char mpf_feature5; /* Unused (0) */
34
struct mp_config_table
36
char mpc_signature[4];
37
#define MPC_SIGNATURE "PCMP"
38
unsigned short mpc_length; /* Size of table */
39
char mpc_spec; /* 0x01 */
42
char mpc_productid[12];
43
unsigned long mpc_oemptr; /* 0 if not present */
44
unsigned short mpc_oemsize; /* 0 if not present */
45
unsigned short mpc_oemcount;
46
unsigned long mpc_lapic; /* APIC address */
47
unsigned long reserved;
50
/* Followed by entries */
52
#define MP_PROCESSOR 0
58
struct mpc_config_processor
60
unsigned char mpc_type;
61
unsigned char mpc_apicid; /* Local APIC number */
62
unsigned char mpc_apicver; /* Its versions */
63
unsigned char mpc_cpuflag;
64
#define CPU_ENABLED 1 /* Processor is available */
65
#define CPU_BOOTPROCESSOR 2 /* Processor is the BP */
66
unsigned long mpc_cpufeature;
67
#define CPU_STEPPING_MASK 0x0F
68
#define CPU_MODEL_MASK 0xF0
69
#define CPU_FAMILY_MASK 0xF00
70
unsigned long mpc_featureflag; /* CPUID feature value */
71
unsigned long mpc_reserved[2];
76
unsigned char mpc_type;
77
unsigned char mpc_busid;
78
unsigned char mpc_bustype[6] __attribute((packed));
81
#define BUSTYPE_EISA "EISA"
82
#define BUSTYPE_ISA "ISA"
83
#define BUSTYPE_INTERN "INTERN" /* Internal BUS */
84
#define BUSTYPE_MCA "MCA"
85
#define BUSTYPE_VL "VL" /* Local bus */
86
#define BUSTYPE_PCI "PCI"
87
#define BUSTYPE_PCMCIA "PCMCIA"
89
/* We don't understand the others */
91
struct mpc_config_ioapic
93
unsigned char mpc_type;
94
unsigned char mpc_apicid;
95
unsigned char mpc_apicver;
96
unsigned char mpc_flags;
97
#define MPC_APIC_USABLE 0x01
98
unsigned long mpc_apicaddr;
101
struct mpc_config_intsrc
103
unsigned char mpc_type;
104
unsigned char mpc_irqtype;
105
unsigned short mpc_irqflag;
106
unsigned char mpc_srcbus;
107
unsigned char mpc_srcbusirq;
108
unsigned char mpc_dstapic;
109
unsigned char mpc_dstirq;
112
#define MP_INT_VECTORED 0
115
#define MP_INT_EXTINT 3
117
#define MP_IRQDIR_DEFAULT 0
118
#define MP_IRQDIR_HIGH 1
119
#define MP_IRQDIR_LOW 3
122
struct mpc_config_intlocal
124
unsigned char mpc_type;
125
unsigned char mpc_irqtype;
126
unsigned short mpc_irqflag;
127
unsigned char mpc_srcbusid;
128
unsigned char mpc_srcbusirq;
129
unsigned char mpc_destapic;
130
#define MP_APIC_ALL 0xFF
131
unsigned char mpc_destapiclint;
136
* Default configurations
138
* 1 2 CPU ISA 82489DX
139
* 2 2 CPU EISA 82489DX no IRQ 8 or timer chaining
140
* 3 2 CPU EISA 82489DX
141
* 4 2 CPU MCA 82489DX
148
static int smp_found_config=0;
151
* Checksum an MP configuration block.
154
static int mpf_checksum(unsigned char *mp, int len)
162
static int do_smp_scan_config(unsigned long *bp, unsigned long length)
164
struct intel_mp_floating *mpf;
167
if (sizeof(*mpf)!=16)
168
logMessage("Error: MPF size\n");
173
if (*bp==SMP_MAGIC_IDENT)
175
mpf=(struct intel_mp_floating *)bp;
176
if (mpf->mpf_length==1 &&
177
!mpf_checksum((unsigned char *)bp,16) &&
178
(mpf->mpf_specification == 1
179
|| mpf->mpf_specification == 4) )
181
/*logMessage("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
182
if (mpf->mpf_feature2&(1<<7))
183
logMessage(" IMCR and PIC compatibility mode.\n");
185
logMessage(" Virtual Wire compatibility mode.\n");
198
static int smp_scan_config(int mem_fd, unsigned long base,
199
unsigned long length)
208
p=mmap(0, (length+4095)&0xFFFFF000, PROT_READ, MAP_SHARED,
209
mem_fd, (base&0xFFFF0000));
212
/*logMessage("SMP Probe error: mmap: %s", strerror(errno));*/
215
do_smp_scan_config(p+o, length-o);
216
munmap(p, (length+4095)&0xFFFFF000);
220
static int intelDetectSMP(void)
224
mem_fd=open("/dev/mem", O_RDONLY);
228
/*logMessage("Error detecting SMP: /dev/mem: %s", strerror(errno));*/
232
* FIXME: Linux assumes you have 640K of base ram..
233
* this continues the error...
235
* 1) Scan the bottom 1K for a signature
236
* 2) Scan the top 1K of base RAM
237
* 3) Scan the 64K of bios
239
if (!smp_scan_config(mem_fd, 0x0, 0x400) &&
240
!smp_scan_config(mem_fd, 639*0x400,0x400) &&
241
!smp_scan_config(mem_fd, 0xF0000,0x10000)) {
245
* If it is an SMP machine we should know now, unless the
246
* configuration is in an EISA/MCA bus machine with an
247
* extended bios data area.
249
* there is a real-mode segmented pointer pointing to the
250
* 4K EBDA area at 0x40E, calculate and scan it here.
252
* NOTE! There are Linux loaders that will corrupt the EBDA
253
* area, and as such this kind of SMP config may be less
254
* trustworthy, simply because the SMP table may have been
255
* stomped on during early boot. These loaders are buggy and
258
unsigned int address;
260
address = *(unsigned short *)phys_to_virt(0x40E);
262
smp_scan_config(mem_fd, address, 0x1000);
263
if (smp_found_config)
264
/*logMessage("WARNING: MP table in the EBDA can be UNSAFE, contact linux-smp@vger.rutgers.edu if you experience SMP problems!\n");*/
269
logMessage("Detected SMP capable motherboard\n");
271
logMessage("Detected non SMP capable motherboard\n");
273
return smp_found_config;
278
static int isSMP = -1;
283
return isSMP = intelDetectSMP();
286
#endif /* __i386__ */