Copyright clean-up (part 1):
[AROS.git] / arch / i386-pc / cpu / smp.c
blob74ee3e331bcfe0719396b56f3ca28c32be32085e
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /* AROS Multi Processor Support Functions by NicJA. */
7 #ifndef _SMP_C
8 #define _SMP_C
10 #ifndef _CPU_INTERN_H
11 # include "cpu_intern.h"
12 #endif
14 /**********************************************************************/
15 void parse_MP_Processor (struct mpc_config_processor *mc, struct SMP_Definition *SMP_Group )
17 struct CPU_Definition *ThisCPU, *CPUList;
18 struct i386_compat_intern *ThisCPU_intern = NULL;
19 int cpuapicver, apicid = 0;
20 //physid_mask_t tmp;
22 CPUList = CPUBase->CPUB_Processors;
24 //apicid = mpc_apic_id(mc, translation_table[SMP_Group->SMP_RecordCount]);
26 kprintf(DEBUG_NAME_STR ": Parsing MP Processor Features :-\n");
28 if (mc->mpc_featureflag&(1<<0)) kprintf(DEBUG_NAME_STR ": *Floating point unit present.\n");
29 if (mc->mpc_featureflag&(1<<7)) kprintf(DEBUG_NAME_STR ": *Machine Exception supported.\n");
30 if (mc->mpc_featureflag&(1<<8)) kprintf(DEBUG_NAME_STR ": *64 bit compare & exchange supported.\n");
31 if (mc->mpc_featureflag&(1<<9)) kprintf(DEBUG_NAME_STR ": *Internal APIC present.\n");
32 if (mc->mpc_featureflag&(1<<11)) kprintf(DEBUG_NAME_STR ": *SEP present.\n");
33 if (mc->mpc_featureflag&(1<<12)) kprintf(DEBUG_NAME_STR ": *MTRR present.\n");
34 if (mc->mpc_featureflag&(1<<13)) kprintf(DEBUG_NAME_STR ": *PGE present.\n");
35 if (mc->mpc_featureflag&(1<<14)) kprintf(DEBUG_NAME_STR ": *MCA present.\n");
36 if (mc->mpc_featureflag&(1<<15)) kprintf(DEBUG_NAME_STR ": *CMOV present.\n");
37 if (mc->mpc_featureflag&(1<<16)) kprintf(DEBUG_NAME_STR ": *PAT present.\n");
38 if (mc->mpc_featureflag&(1<<17)) kprintf(DEBUG_NAME_STR ": *PSE present.\n");
39 if (mc->mpc_featureflag&(1<<18)) kprintf(DEBUG_NAME_STR ": *PSN present.\n");
40 if (mc->mpc_featureflag&(1<<19)) kprintf(DEBUG_NAME_STR ": *Cache Line Flush Instruction present.\n");
41 /* 20 Reserved */
42 if (mc->mpc_featureflag&(1<<21)) kprintf(DEBUG_NAME_STR ": *Debug Trace and EMON Store present.\n");
43 if (mc->mpc_featureflag&(1<<22)) kprintf(DEBUG_NAME_STR ": *ACPI Thermal Throttle Registers present.\n");
44 if (mc->mpc_featureflag&(1<<23)) kprintf(DEBUG_NAME_STR ": *MMX present.\n");
45 if (mc->mpc_featureflag&(1<<24)) kprintf(DEBUG_NAME_STR ": *FXSR present.\n");
46 if (mc->mpc_featureflag&(1<<25)) kprintf(DEBUG_NAME_STR ": *XMM present.\n");
47 if (mc->mpc_featureflag&(1<<26)) kprintf(DEBUG_NAME_STR ": *Willamette New Instructions present.\n");
48 if (mc->mpc_featureflag&(1<<27)) kprintf(DEBUG_NAME_STR ": *Self Snoop present.\n");
49 if (mc->mpc_featureflag&(1<<28)) kprintf(DEBUG_NAME_STR ": *HT present.\n");
50 if (mc->mpc_featureflag&(1<<29)) kprintf(DEBUG_NAME_STR ": *Thermal Monitor present.\n");
51 /* 30, 31 Reserved */
53 /*if (SMP_Group->SMP_CPUCount >= MAX_CPU)
55 kprintf(DEBUG_NAME_STR ": WARNING - Reached MAX_CPU count [%i]. CPU(apicid 0x%x) not booted.\n", MAX_CPU, mc->mpc_apicid);
56 return;
57 }*/
59 if (MAX_APICS - mc->mpc_apicid <= 0)
61 kprintf(DEBUG_NAME_STR ": WARNING - INVALID Processor [#%d - Max ID: %d].\n", mc->mpc_apicid, MAX_APICS);
62 return;
65 if (mc->mpc_cpuflag & CPU_BOOTPROCESSOR)
67 kprintf(DEBUG_NAME_STR ": Bootup CPU\n"); /* CPU booted system.. */
68 CPUBase->CPUB_BOOT_Physical = mc->mpc_apicid;
69 CPUBase->CPUB_BOOT_Logical = apicid;
70 ThisCPU = (struct CPU_Definition *)CPUList->CPU_CPUList.mlh_Head;
71 ThisCPU->CPU_Physical = mc->mpc_apicid;
72 ThisCPU->CPU_Enabled = TRUE; /* got to be enabled or we wouldnt be here.. */
73 ThisCPU->CPU_IsOnline = TRUE; /* CPU is online .. */
74 ThisCPU->CPU_BootCPU = TRUE;
75 ThisCPU->CPU_SMPGroup = (ULONG *)SMP_Group;
76 kprintf(DEBUG_NAME_STR ": CPU List item for BOOT CPU updated..[PhysicalID=%d]!\n", ThisCPU->CPU_Physical);
78 else
80 ThisCPU = AllocMem( sizeof(struct CPU_Definition), MEMF_CLEAR | MEMF_PUBLIC ); /* Add this CPU to the CPU List */
82 if( ThisCPU == NULL )
84 kprintf(DEBUG_NAME_STR ":ERROR - Couldnt allocate CPU list item memory!\n");
86 else
88 CPUList->CPU_Physical += 1; /* Increment the System Processor count */
90 ThisCPU->CPU_Family = CPU_Family_i386; /* we are i386 compatable.. */
91 ThisCPU->CPU_Model = CPU_i386_386; /* will probe more later .. */
92 ThisCPU->CPU_Physical = mc->mpc_apicid;
93 ThisCPU->CPU_Enabled = (mc->mpc_cpuflag & CPU_ENABLED);
94 ThisCPU->CPU_ID = CPUList->CPU_Physical; /* we are the only CPU at this time .. */
95 ThisCPU->CPU_IsOnline = FALSE; /* CPU is online .. */
96 ThisCPU->CPU_BootCPU = FALSE; /* CPU bootd system.. */
97 ThisCPU->CPU_SMPGroup = (ULONG *)SMP_Group;
99 kprintf(DEBUG_NAME_STR ": New CPU List item created @ %p, for [PhysicalID=%d]\n", ThisCPU_intern, ThisCPU->CPU_Physical);
101 ThisCPU_intern = AllocMem(sizeof(struct i386_compat_intern), MEMF_CLEAR | MEMF_PUBLIC ); /* Create its per CPU internal struct */
103 if( ThisCPU_intern == NULL )
105 kprintf(DEBUG_NAME_STR ":ERROR - Couldnt allocate CPU private struct!\n");
107 else
109 kprintf(DEBUG_NAME_STR ": i386 private structure allocated @ %p\n",ThisCPU_intern);
110 ThisCPU->CPU_Private1 = ThisCPU_intern; /* We dont fill it in yet - probed l8r */
112 AddTail((struct List *)&CPUList->CPU_CPUList,(struct Node *)&ThisCPU->CPU_CPUList); /* Add the CPU to the system List */
116 SMP_Group->SMP_CPUCount += 1; /* Increment the groups CPU count */
118 cpuapicver = mc->mpc_apicver;
120 //tmp = apicid_to_cpu_present(apicid);
121 //physids_or(phys_cpu_present_map, phys_cpu_present_map, tmp);
123 /* Validate version */
124 if ( cpuapicver == 0x0 )
126 kprintf(DEBUG_NAME_STR ": WARNING - BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", mc->mpc_apicid);
127 cpuapicver = 0x10;
130 //apic_version[m->mpc_apicid] = ver;
131 //bios_cpu_apicid[num_processors - 1] = m->mpc_apicid;
134 void parse_MP_IOAPIC (struct mpc_config_ioapic *mc, struct SMP_Definition *SMP_Group )
136 if (!(mc->mpc_flags & MPC_APIC_USABLE)) return;
138 kprintf(DEBUG_NAME_STR ": I/O APIC #%d Version %d at 0x%lX.\n", mc->mpc_apicid, mc->mpc_apicver, mc->mpc_apicaddr);
140 //if (nr_ioapics >= MAX_IO_APICS)
142 // kprintf(DEBUG_NAME_STR ": CRITICAL - Max # of I/O APICs (%d) exceeded (found %d).\n",MAX_IO_APICS, nr_ioapics);
145 if (!mc->mpc_apicaddr)
147 kprintf(DEBUG_NAME_STR ":ERROR - bogus zero I/O APIC address found in MP table, skipping!\n");
148 return;
151 //mp_ioapics[nr_ioapics] = *mc;
152 //nr_ioapics++;
155 void parse_MP_IntSrc (struct mpc_config_intsrc *mc, struct SMP_Definition *SMP_Group )
157 //mp_irqs [mp_irq_entries] = *mc;
158 kprintf(DEBUG_NAME_STR ": Int: type %d, pol %d, trig %d, bus %d, IRQ %02x, APIC ID %x, APIC INT %02x\n", mc->mpc_irqtype, mc->mpc_irqflag & 3, (mc->mpc_irqflag >> 2) & 3, mc->mpc_srcbus, mc->mpc_srcbusirq, mc->mpc_dstapic, mc->mpc_dstirq);
160 /* TODO: Replace the following print with ALERT */
161 //if (++mp_irq_entries == MAX_IRQ_SOURCES) kprintf(DEBUG_NAME_STR ": DIE HERE!!! (BUG) ");
164 void parse_MP_LIntSrc (struct mpc_config_lintsrc *mc, struct SMP_Definition *SMP_Group )
166 kprintf(DEBUG_NAME_STR ": Lint: type %d, pol %d, trig %d, bus %d, IRQ %02x, APIC ID %x, APIC LINT %02x\n", mc->mpc_irqtype, mc->mpc_irqflag & 3, (mc->mpc_irqflag >> 2) &3, mc->mpc_srcbusid, mc->mpc_srcbusirq, mc->mpc_destapic, mc->mpc_destapiclint);
168 Apparently all exisitng SMP boards use ExtINT/LVT1 == LINT0 and NMI/LVT2 == LINT1
169 The following check will show us if this assumptions is false. Until then we do not have to add baggage.
171 /* TODO: Replace the following prints with ALERTS */
173 if ((mc->mpc_irqtype == mp_ExtINT) && (mc->mpc_destapiclint != 0)) kprintf(DEBUG_NAME_STR ": DIE HERE!!! (BUG) ");//BUG();
175 if ((mc->mpc_irqtype == mp_NMI) && (mc->mpc_destapiclint != 1)) kprintf(DEBUG_NAME_STR ": DIE HERE!!! (BUG) ");//BUG();
178 void parse_MP_Bus (struct mpc_config_bus *mc, struct SMP_Definition *SMP_Group )
180 char str[7];
182 memcpy(str, mc->mpc_bustype, 6);
183 str[6] = 0;
185 /* TODO: Implemenet parse_MP_Bus */
186 //mpc_oem_bus_info(mc, str, translation_table[SMP_Group->SMP_RecordCount]);
188 //if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0)
190 // mp_bus_id_to_type[mc->mpc_busid] = MP_BUS_ISA;
192 //else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) mp_bus_id_to_type[mc->mpc_busid] = MP_BUS_EISA;
193 //else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0)
195 // mpc_oem_pci_bus(mc, translation_table[SMP_Group->SMP_RecordCount]);
196 // mp_bus_id_to_type[mc->mpc_busid] = MP_BUS_PCI;
197 // mp_bus_id_to_pci_bus[mc->mpc_busid] = mp_current_pci_id;
198 // mp_current_pci_id++;
200 //else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) mp_bus_id_to_type[mc->mpc_busid] = MP_BUS_MCA;
201 //else if (strncmp(str, BUSTYPE_NEC98, sizeof(BUSTYPE_NEC98)-1) == 0) mp_bus_id_to_type[mc->mpc_busid] = MP_BUS_NEC98;
202 //else kprintf(DEBUG_NAME_STR ": WARNING - Unknown bustype %s - ignoring\n", str);
205 void parse_MP_Translation (struct mpc_config_translation *mc, struct SMP_Definition *SMP_Group)
207 kprintf(DEBUG_NAME_STR ": Translation: record %d, type %d, quad %d, global %d, local %d\n", SMP_Group->SMP_RecordCount, mc->trans_type, mc->trans_quad, mc->trans_global, mc->trans_local);
209 if (SMP_Group->SMP_RecordCount >= MAX_MPC_ENTRY) kprintf(DEBUG_NAME_STR ": ERROR - MAX_MPC_ENTRY exceeded!\n");
210 //else translation_table[SMP_Group->SMP_RecordCount] = mc; /* stash this for later */
212 //if (mc->trans_quad+1 > numnodes) numnodes = mc->trans_quad+1;
215 /**************************************************************************/
217 int mpfcb_checksum(unsigned char *mpcb, int len)
219 int sum = 0; /* Quickly grab the checksum of the config block */
221 while (len--) sum += *mpcb++;
223 return sum & 0xFF;
226 /**************************************************************************/
228 void smp_read_mpc_oem(struct mp_config_oemtable *oemtable, unsigned short oemsize, struct SMP_Definition *SMP_Group )
230 int count = sizeof (*oemtable); /* the header size */
231 unsigned char *oemptr = ((unsigned char *)oemtable)+count;
233 SMP_Group->SMP_RecordCount = 0;
234 kprintf(DEBUG_NAME_STR ": Found an OEM MPC table at %8p - parsing it ... \n", oemtable);
236 if (memcmp(oemtable->oem_signature,MPC_OEM_SIGNATURE,4))
238 kprintf(DEBUG_NAME_STR ": WARNING - SMP mpc oemtable: bad signature [%c%c%c%c]!\n", oemtable->oem_signature[0], oemtable->oem_signature[1], oemtable->oem_signature[2], oemtable->oem_signature[3]);
239 return;
242 if (mpfcb_checksum((unsigned char *)oemtable,oemtable->oem_length))
244 kprintf(DEBUG_NAME_STR ": WARNING - SMP oem mptable: checksum error\n");
245 return;
248 while (count < oemtable->oem_length)
250 switch (*oemptr) {
251 case MP_TRANSLATION:
253 struct mpc_config_translation *mc=(struct mpc_config_translation *)oemptr;
254 parse_MP_Translation( mc, SMP_Group );
255 oemptr += sizeof(*mc);
256 count += sizeof(*mc);
257 ++SMP_Group->SMP_RecordCount;
258 break;
260 default:
262 kprintf(DEBUG_NAME_STR ": WARNING - Unrecognised OEM table entry type - %d\n", (int) *oemptr);
263 return;
269 void mps_oem_check(struct mp_config_table *mpcf, char *oem, char *productid, struct SMP_Definition *SMP_Group )
271 if (strncmp(oem, "IBM NUMA", 8)) kprintf( DEBUG_NAME_STR ": WARNING - May not be a NUMA-Q system.\n");
272 if (mpcf->mpc_oemptr) smp_read_mpc_oem((struct mp_config_oemtable *) mpcf->mpc_oemptr, mpcf->mpc_oemsize, SMP_Group);
275 /****************************************************************************************/
276 /* We are called very early to get the low memory for the SMP bootup trampoline page. */
278 int smp_alloc_memory(void)
280 ULONG trampoline_base;
281 /* TODO: properly allocate SMP memory */
282 //if ( ( trampoline_base = (void *) alloc_bootmem_low_pages(PAGE_SIZE)) >= 0x0009F000) /* Has to be in very low memory so we can execute real-mode AP code. */
284 trampoline_base = 0x0009E000;
287 return trampoline_base;
290 /**************************************************************************/
292 APTR scan_for_smpconfig (APTR base, unsigned long length)
294 ULONG *basepointer = base;
295 struct intel_mp_confblock *mpcfb;
297 kprintf(DEBUG_NAME_STR ": Scan for SMP = %p for %ld bytes.\n", basepointer,length);
299 while (length > 0)
301 mpcfb = (struct intel_mp_confblock *)basepointer;
303 if ((*basepointer == SMP_MAGIC_IDENT))
305 if ( (mpcfb->mpcf_length == 1) && !mpfcb_checksum( (unsigned char *)basepointer, 16) )
307 if ( ( ( mpcfb->mpcf_specification == 1 ) || ( mpcfb->mpcf_specification == 4 ) ) )
309 return basepointer;
314 basepointer += 4;
315 length -= 16;
317 return NULL;
320 APTR find_smp_config (void)
322 APTR confAddr;
324 if ((confAddr = scan_for_smpconfig((APTR)0x00000000,0x400))) return confAddr; /* Scan the bottom 1K for a signature */
325 if ((confAddr = scan_for_smpconfig((APTR)0x0009FC00,0x400))) return confAddr; /* Scan the top 1K of base RAM (639*0x400) */
326 if ((confAddr = scan_for_smpconfig((APTR)0x000F0000,0x10000))) return confAddr; /* Scan the 64K of bios */
328 /* If it is an SMP machine we should know now, unless the
329 configuration is in an EISA/MCA bus machine with an
330 extended bios data area.
332 there is a real-mode segmented pointer pointing to the
333 4K EBDA area at 0x0000040E, calculate and scan it here.
335 Some Linux loaders corrupt the EBDA area, so this kind
336 of SMP config may be less reliable, because the SMP
337 table may have been corrupted during early boot. These
338 loaders are buggy and should be fixed. */
340 confAddr = (APTR)(((IPTR)*(UWORD *)(0x0000040E)) << 4);
341 return scan_for_smpconfig(confAddr, 0x1000);
344 void get_smp_config ( struct intel_mp_confblock *mpcfb, struct CPUBase *CPUBase)
346 struct SMP_Definition *SMP_Group;
347 BOOL SMPERROR = FALSE;
348 ULONG pic_mode;
350 kprintf(DEBUG_NAME_STR ": Processing SMP config...\n");
353 ACPI may be used to obtain the entire SMP configuration or just to
354 enumerate/configure processors (CONFIG_ACPI_HT).
356 Note that ACPI supports both logical (e.g. Hyper-Threading) and physical
357 processors, where MPS only supports physical. */
359 if (ACPICABase)
362 kprintf(DEBUG_NAME_STR ": FIXME: Use ACPI (MADT) for SMP configuration information\n");
363 return;
365 kprintf(DEBUG_NAME_STR ": Intel MultiProcessor Specification v1.%d\n", mpcfb->mpcf_specification);
367 if (mpcfb->mpcf_feature2 & (1<<7)) /* test bit 7 (IMCR|PIC) */
369 kprintf(DEBUG_NAME_STR ": IMCR and PIC compatibility mode.\n");
370 pic_mode = 1;
372 else
374 kprintf(DEBUG_NAME_STR ": Virtual Wire compatibility mode.\n");
375 pic_mode = 0;
378 /* Now see if we need to read further. */
379 if (mpcfb->mpcf_feature1 != 0)
381 kprintf(DEBUG_NAME_STR ": Default MP configuration #%d\n", mpcfb->mpcf_feature1);
382 //construct_default_ISA_mptable(mpf->mpf_feature1);
384 else if (mpcfb->mpcf_physptr)
387 /* Read the physical hardware table. Anything here will override the defaults. */
388 if (!(SMP_Group = smp_read_mpcfb((void *)mpcfb->mpcf_physptr, CPUBase)) )
390 SMPERROR = TRUE;
391 kprintf(DEBUG_NAME_STR ": ERROR - BIOS bug, MP table errors detected!...\n");
394 SMP_Group->SMP_PIC_Mode = pic_mode;
397 If there are no explicit MP IRQ entries, then we are
398 broken. We set up most of the low 16 IO-APIC pins to
399 ISA defaults and hope it will work. */
401 /*if (!mp_irq_entries)
403 struct mpc_config_bus bus;
405 kprintf(DEBUG_NAME_STR ": BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");
407 bus.mpc_type = MP_BUS;
408 bus.mpc_busid = 0;
409 memcpy(bus.mpc_bustype, "ISA ", 6);
410 parse_MP_Bus(&bus);
412 construct_default_ioirq_mptable(0);
413 } */
416 else SMPERROR = TRUE;
418 if ( SMPERROR == TRUE )
420 mpcfb = NULL;
421 kprintf(DEBUG_NAME_STR ": ERROR - disabling SMP support. (tell your hw vendor)\n");
423 else kprintf(DEBUG_NAME_STR ": Processors: %d\n", SMP_Group->SMP_CPUCount);
424 /* Only use the first configuration found. */
427 struct SMP_Definition *smp_read_mpcfb(struct mp_config_table *mpcf, struct CPUBase *CPUBase)
429 char str[16];
430 char oem[10];
431 int count = sizeof(*mpcf);
432 unsigned char *mpt = ((unsigned char *)mpcf) + count;
433 struct SMP_Definition *SMP_Group;
435 if (ACPICABase)
436 return NULL;
438 if (memcmp(mpcf->mpc_signature,MPC_SIGNATURE,4))
440 kprintf(DEBUG_NAME_STR ": ERROR - SMP mptable: bad signature [0x%x]!\n", *(ULONG *)mpcf->mpc_signature);
441 return NULL;
444 if (mpfcb_checksum((unsigned char *)mpcf,mpcf->mpc_length))
446 kprintf(DEBUG_NAME_STR ": ERROR - SMP mptable: checksum error!\n");
447 return NULL;
450 if (mpcf->mpc_spec != 0x01 && mpcf->mpc_spec != 0x04)
452 kprintf(DEBUG_NAME_STR ": ERROR - SMP mptable: bad table version (%d)!!\n",mpcf->mpc_spec);
453 return NULL;
456 if (!mpcf->mpc_lapic)
458 kprintf(DEBUG_NAME_STR ": ERROR - SMP mptable: null local APIC address!\n");
459 return NULL;
462 /* Create the SMP group block */
463 SMP_Group = AllocMem( sizeof(struct SMP_Definition), MEMF_CLEAR | MEMF_PUBLIC );
464 if (CPUBase->CPUB_SMP_Groups)
466 AddTail((struct List *)CPUBase->CPUB_SMP_Groups,(struct Node *)&SMP_Group->SMP_SMPList); /* Add this SMP group to the list */
467 kprintf(DEBUG_NAME_STR ": SMP Group Item @ 0x%p, Inserted into List @ 0x%p\n",&SMP_Group->SMP_SMPList,CPUBase->CPUB_SMP_Groups);
469 InitSemaphore( &SMP_Group->SMP_GrpLock);
470 kprintf(DEBUG_NAME_STR ": Initialised SMP Group Semaphore\n");
472 else
474 NEWLIST((struct List *)&(SMP_Group->SMP_SMPList)); /* Create This SMP group list */
475 kprintf(DEBUG_NAME_STR ": First SMP List & Group created @ 0x%p\n",&SMP_Group->SMP_SMPList);
477 InitSemaphore( &SMP_Group->SMP_GrpLock);
478 kprintf(DEBUG_NAME_STR ": Initialised SMP Group Semaphore\n");
480 CPUBase->CPUB_SMP_Groups = SMP_Group;
483 memcpy(oem,mpcf->mpc_oem,8);
484 oem[8]=0;
486 memcpy(str,mpcf->mpc_productid,12);
487 str[12]=0;
489 kprintf(DEBUG_NAME_STR ": OEM ID: %s Product ID: %s \n",oem,str);
491 mps_oem_check( mpcf, oem, str, SMP_Group );
493 kprintf(DEBUG_NAME_STR ": APIC at: 0x%lX\n",mpcf->mpc_lapic);
495 /* Save the local APIC address (it might be non-default) - though only if we're not using ACPI. */
496 SMP_Group->SMP_APIC = (APTR)mpcf->mpc_lapic;
498 /* Now process the configuration blocks. */
500 SMP_Group->SMP_RecordCount = 0;
501 while (count < mpcf->mpc_length)
503 switch(*mpt)
505 case MP_PROCESSOR:
507 struct mpc_config_processor *mc= (struct mpc_config_processor *)mpt;
509 parse_MP_Processor( mc, SMP_Group ); /* ACPI may have already provided this data */
511 mpt += sizeof( *mc );
512 count += sizeof( *mc );
513 break;
515 case MP_IOAPIC:
517 struct mpc_config_ioapic *mc= (struct mpc_config_ioapic *)mpt;
519 parse_MP_IOAPIC( mc, SMP_Group );
520 mpt += sizeof( *mc );
521 count += sizeof( *mc );
522 break;
524 case MP_INTSRC:
526 struct mpc_config_intsrc *mc= (struct mpc_config_intsrc *)mpt;
528 parse_MP_IntSrc( mc, SMP_Group );
529 mpt += sizeof( *mc );
530 count += sizeof( *mc );
531 break;
533 case MP_LINTSRC:
535 struct mpc_config_lintsrc *mc= (struct mpc_config_lintsrc *)mpt;
537 parse_MP_LIntSrc( mc, SMP_Group );
538 mpt += sizeof( *mc );
539 count += sizeof( *mc );
540 break;
542 case MP_BUS:
544 struct mpc_config_bus *mc= (struct mpc_config_bus *)mpt;
546 parse_MP_Bus( mc, SMP_Group );
547 mpt += sizeof( *mc );
548 count += sizeof( *mc );
549 break;
551 default:
553 count = mpcf->mpc_length;
554 break;
557 ++SMP_Group->SMP_RecordCount;
560 //clustered_apic_check();
561 if (!SMP_Group->SMP_CPUCount) kprintf(DEBUG_NAME_STR ": SMP mptable - NO Processors Registered!\n");
562 return SMP_Group;
565 /**************************************************************************/
567 #endif /* _SMP_C */