ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mpconfig.c
Go to the documentation of this file.
00001 /* $Id$
00002  *
00003  * COPYRIGHT:             See COPYING in the top level directory
00004  * PROJECT:               ReactOS kernel
00005  * FILE:                  hal/halx86/mp/mpconfig.c
00006  * PURPOSE:               
00007  * PROGRAMMER:            
00008  */
00009 
00010 /* INCLUDES *****************************************************************/
00011 
00012 #include <hal.h>
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 /* GLOBALS ******************************************************************/
00017 
00018 MP_FLOATING_POINTER* Mpf = NULL;
00019 
00020 /* FUNCTIONS ****************************************************************/
00021 
00022 static UCHAR 
00023 MPChecksum(PUCHAR Base,
00024        ULONG Size)
00025 /*
00026  * Checksum an MP configuration block
00027  */
00028 {
00029    UCHAR Sum = 0;
00030 
00031    while (Size--)
00032       Sum += *Base++;
00033 
00034    return Sum;
00035 }
00036 
00037 static VOID 
00038 HaliMPIntSrcInfo(PMP_CONFIGURATION_INTSRC m)
00039 {
00040   DPRINT("Int: type %d, pol %d, trig %d, bus %d,"
00041          " IRQ %02x, APIC ID %x, APIC INT %02x\n",
00042          m->IrqType, m->IrqFlag & 3,
00043          (m->IrqFlag >> 2) & 3, m->SrcBusId,
00044          m->SrcBusIrq, m->DstApicId, m->DstApicInt);
00045   if (IRQCount > MAX_IRQ_SOURCE) 
00046   {
00047     DPRINT1("Max # of irq sources exceeded!!\n");
00048     ASSERT(FALSE);
00049   }
00050 
00051   IRQMap[IRQCount] = *m;
00052   IRQCount++;
00053 }
00054 
00055 PCHAR 
00056 HaliMPFamily(ULONG Family,
00057          ULONG Model)
00058 {
00059    static CHAR str[64];
00060    static PCHAR CPUs[] =
00061    {
00062       "80486DX", "80486DX",
00063       "80486SX", "80486DX/2 or 80487",
00064       "80486SL", "Intel5X2(tm)",
00065       "Unknown", "Unknown",
00066       "80486DX/4"
00067    };
00068    if (Family == 0x6)
00069       return ("Pentium(tm) Pro");
00070    if (Family == 0x5)
00071       return ("Pentium(tm)");
00072    if (Family == 0x0F && Model == 0x0F)
00073       return("Special controller");
00074    if (Family == 0x0F && Model == 0x00)
00075       return("Pentium 4(tm)");
00076    if (Family == 0x04 && Model < 9)
00077       return CPUs[Model];
00078    sprintf(str, "Unknown CPU with family ID %ld and model ID %ld", Family, Model);
00079    return str;
00080 }
00081 
00082 
00083 static VOID 
00084 HaliMPProcessorInfo(PMP_CONFIGURATION_PROCESSOR m)
00085 {
00086   UCHAR ver;
00087 
00088   if (!(m->CpuFlags & CPU_FLAG_ENABLED))
00089     return;
00090 
00091   DPRINT("Processor #%d %s APIC version %d\n",
00092          m->ApicId,
00093          HaliMPFamily((m->FeatureFlags & CPU_FAMILY_MASK) >> 8,
00094                       (m->FeatureFlags & CPU_MODEL_MASK) >> 4),
00095          m->ApicVersion);
00096 
00097   if (m->FeatureFlags & (1 << 0))
00098     DPRINT("    Floating point unit present.\n");
00099   if (m->FeatureFlags & (1 << 7))
00100     DPRINT("    Machine Exception supported.\n");
00101   if (m->FeatureFlags & (1 << 8))
00102     DPRINT("    64 bit compare & exchange supported.\n");
00103   if (m->FeatureFlags & (1 << 9))
00104     DPRINT("    Internal APIC present.\n");
00105   if (m->FeatureFlags & (1 << 11))
00106     DPRINT("    SEP present.\n");
00107   if (m->FeatureFlags & (1 << 12))
00108     DPRINT("    MTRR present.\n");
00109   if (m->FeatureFlags & (1 << 13))
00110     DPRINT("    PGE  present.\n");
00111   if (m->FeatureFlags & (1 << 14))
00112     DPRINT("    MCA  present.\n");
00113   if (m->FeatureFlags & (1 << 15))
00114     DPRINT("    CMOV  present.\n");
00115   if (m->FeatureFlags & (1 << 16))
00116     DPRINT("    PAT  present.\n");
00117   if (m->FeatureFlags & (1 << 17))
00118     DPRINT("    PSE  present.\n");
00119   if (m->FeatureFlags & (1 << 18))
00120     DPRINT("    PSN  present.\n");
00121   if (m->FeatureFlags & (1 << 19))
00122     DPRINT("    Cache Line Flush Instruction present.\n");
00123   /* 20 Reserved */
00124   if (m->FeatureFlags & (1 << 21))
00125     DPRINT("    Debug Trace and EMON Store present.\n");
00126   if (m->FeatureFlags & (1 << 22))
00127     DPRINT("    ACPI Thermal Throttle Registers present.\n");
00128   if (m->FeatureFlags & (1 << 23))
00129     DPRINT("    MMX  present.\n");
00130   if (m->FeatureFlags & (1 << 24))
00131     DPRINT("    FXSR  present.\n");
00132   if (m->FeatureFlags & (1 << 25))
00133     DPRINT("    XMM  present.\n");
00134   if (m->FeatureFlags & (1 << 26))
00135     DPRINT("    Willamette New Instructions present.\n");
00136   if (m->FeatureFlags & (1 << 27))
00137     DPRINT("    Self Snoop present.\n");
00138   /* 28 Reserved */
00139   if (m->FeatureFlags & (1 << 29))
00140     DPRINT("    Thermal Monitor present.\n");
00141   /* 30, 31 Reserved */
00142 
00143   CPUMap[CPUCount].APICId = m->ApicId;
00144 
00145   CPUMap[CPUCount].Flags = CPU_USABLE;
00146 
00147   if (m->CpuFlags & CPU_FLAG_BSP) 
00148   {
00149     DPRINT("    Bootup CPU\n");
00150     CPUMap[CPUCount].Flags |= CPU_BSP;
00151     BootCPU = m->ApicId;
00152   }
00153 
00154   if (m->ApicId > MAX_CPU) 
00155   {
00156     DPRINT("Processor #%d INVALID. (Max ID: %d).\n", m->ApicId, MAX_CPU);
00157     return;
00158   }
00159   ver = m->ApicVersion;
00160 
00161   /*
00162    * Validate version
00163    */
00164   if (ver == 0x0) 
00165   {
00166      DPRINT("BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->ApicId);
00167      ver = 0x10;
00168   }
00169 //  ApicVersion[m->ApicId] = Ver;
00170 //  BiosCpuApicId[CPUCount] = m->ApicId;
00171   CPUMap[CPUCount].APICVersion = ver;
00172   
00173   CPUCount++;
00174 }
00175 
00176 static VOID 
00177 HaliMPBusInfo(PMP_CONFIGURATION_BUS m)
00178 {
00179   static UCHAR CurrentPCIBusId = 0;
00180 
00181   DPRINT("Bus #%d is %.*s\n", m->BusId, 6, m->BusType);
00182 
00183   if (strncmp(m->BusType, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) 
00184   {
00185      BUSMap[m->BusId] = MP_BUS_ISA;
00186   } 
00187   else if (strncmp(m->BusType, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) 
00188   {
00189      BUSMap[m->BusId] = MP_BUS_EISA;
00190   } 
00191   else if (strncmp(m->BusType, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) 
00192   {
00193      BUSMap[m->BusId] = MP_BUS_PCI;
00194      PCIBUSMap[m->BusId] = CurrentPCIBusId;
00195      CurrentPCIBusId++;
00196   } 
00197   else if (strncmp(m->BusType, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) 
00198   {
00199      BUSMap[m->BusId] = MP_BUS_MCA;
00200   } 
00201   else 
00202   {
00203      DPRINT("Unknown bustype %.*s - ignoring\n", 6, m->BusType);
00204   }
00205 }
00206 
00207 static VOID 
00208 HaliMPIOApicInfo(PMP_CONFIGURATION_IOAPIC m)
00209 {
00210   if (!(m->ApicFlags & CPU_FLAG_ENABLED))
00211     return;
00212 
00213   DPRINT("I/O APIC #%d Version %d at 0x%lX.\n",
00214          m->ApicId, m->ApicVersion, m->ApicAddress);
00215   if (IOAPICCount > MAX_IOAPIC) 
00216   {
00217     DPRINT("Max # of I/O APICs (%d) exceeded (found %d).\n",
00218            MAX_IOAPIC, IOAPICCount);
00219     DPRINT1("Recompile with bigger MAX_IOAPIC!.\n");
00220     ASSERT(FALSE);
00221   }
00222 
00223   IOAPICMap[IOAPICCount].ApicId = m->ApicId;
00224   IOAPICMap[IOAPICCount].ApicVersion = m->ApicVersion;
00225   IOAPICMap[IOAPICCount].ApicAddress = m->ApicAddress;
00226   IOAPICCount++;
00227 }
00228 
00229 
00230 static VOID 
00231 HaliMPIntLocalInfo(PMP_CONFIGURATION_INTLOCAL m)
00232 {
00233   DPRINT("Lint: type %d, pol %d, trig %d, bus %d,"
00234          " IRQ %02x, APIC ID %x, APIC LINT %02x\n",
00235          m->IrqType, m->SrcBusIrq & 3,
00236          (m->SrcBusIrq >> 2) & 3, m->SrcBusId,
00237           m->SrcBusIrq, m->DstApicId, m->DstApicLInt);
00238   /*
00239    * Well it seems all SMP boards in existence
00240    * use ExtINT/LVT1 == LINT0 and
00241    * NMI/LVT2 == LINT1 - the following check
00242    * will show us if this assumptions is false.
00243    * Until then we do not have to add baggage.
00244    */
00245   if ((m->IrqType == INT_EXTINT) && (m->DstApicLInt != 0)) 
00246   {
00247     DPRINT1("Invalid MP table!\n");
00248     ASSERT(FALSE);
00249   }
00250   if ((m->IrqType == INT_NMI) && (m->DstApicLInt != 1)) 
00251   {
00252     DPRINT1("Invalid MP table!\n");
00253     ASSERT(FALSE);
00254   }
00255 }
00256 
00257 
00258 static BOOLEAN
00259 HaliReadMPConfigTable(PMP_CONFIGURATION_TABLE Table)
00260 /*
00261    PARAMETERS:
00262       Table = Pointer to MP configuration table
00263  */
00264 {
00265    PUCHAR Entry;
00266    ULONG Count;
00267 
00268    if (Table->Signature != MPC_SIGNATURE)
00269      {
00270        PUCHAR pc = (PUCHAR)&Table->Signature;
00271        
00272        DPRINT1("Bad MP configuration block signature: %c%c%c%c\n",
00273         pc[0], pc[1], pc[2], pc[3]);
00274        KeBugCheckEx(HAL_INITIALIZATION_FAILED, pc[0], pc[1], pc[2], pc[3]);
00275        return FALSE;
00276      }
00277 
00278    if (MPChecksum((PUCHAR)Table, Table->Length))
00279      {
00280        DPRINT1("Bad MP configuration block checksum\n");
00281        ASSERT(FALSE);
00282        return FALSE;
00283      }
00284 
00285    if (Table->Specification != 0x01 && Table->Specification != 0x04)
00286      {
00287        DPRINT1("Bad MP configuration table version (%d)\n",
00288            Table->Specification);
00289        ASSERT(FALSE);
00290        return FALSE;
00291      }
00292 
00293    if (Table->LocalAPICAddress != APIC_DEFAULT_BASE)
00294      {
00295        DPRINT1("APIC base address is at 0x%X. I cannot handle non-standard adresses\n", 
00296            Table->LocalAPICAddress);
00297        ASSERT(FALSE);
00298        return FALSE;
00299      }
00300 
00301    DPRINT("Oem: %.*s, ProductId: %.*s\n", 8, Table->Oem, 12, Table->ProductId);
00302    DPRINT("APIC at: %08x\n", Table->LocalAPICAddress);
00303 
00304 
00305    Entry = (PUCHAR)((ULONG_PTR)Table + sizeof(MP_CONFIGURATION_TABLE));
00306    Count = 0;
00307    while (Count < (Table->Length - sizeof(MP_CONFIGURATION_TABLE)))
00308    {
00309      /* Switch on type */
00310      switch (*Entry)
00311        {
00312        case MPCTE_PROCESSOR:
00313          {
00314        HaliMPProcessorInfo((PMP_CONFIGURATION_PROCESSOR)Entry);
00315        Entry += sizeof(MP_CONFIGURATION_PROCESSOR);
00316        Count += sizeof(MP_CONFIGURATION_PROCESSOR);
00317        break;
00318      }
00319        case MPCTE_BUS:
00320      {
00321        HaliMPBusInfo((PMP_CONFIGURATION_BUS)Entry);
00322        Entry += sizeof(MP_CONFIGURATION_BUS);
00323        Count += sizeof(MP_CONFIGURATION_BUS);
00324        break;
00325      }
00326        case MPCTE_IOAPIC:
00327      {
00328        HaliMPIOApicInfo((PMP_CONFIGURATION_IOAPIC)Entry);
00329        Entry += sizeof(MP_CONFIGURATION_IOAPIC);
00330        Count += sizeof(MP_CONFIGURATION_IOAPIC);
00331        break;
00332      }
00333        case MPCTE_INTSRC:
00334      {
00335        HaliMPIntSrcInfo((PMP_CONFIGURATION_INTSRC)Entry);
00336        Entry += sizeof(MP_CONFIGURATION_INTSRC);
00337        Count += sizeof(MP_CONFIGURATION_INTSRC);
00338        break;
00339      }
00340        case MPCTE_LINTSRC:
00341      {
00342        HaliMPIntLocalInfo((PMP_CONFIGURATION_INTLOCAL)Entry);
00343        Entry += sizeof(MP_CONFIGURATION_INTLOCAL);
00344        Count += sizeof(MP_CONFIGURATION_INTLOCAL);
00345        break;
00346      }
00347        default:
00348      DPRINT1("Unknown entry in MPC table\n");
00349      ASSERT(FALSE);
00350      return FALSE;
00351        }
00352    }
00353    return TRUE;
00354 }
00355 
00356 static VOID 
00357 HaliConstructDefaultIOIrqMPTable(ULONG Type)
00358 {
00359     MP_CONFIGURATION_INTSRC intsrc;
00360     UCHAR i;
00361 
00362     intsrc.Type = MPCTE_INTSRC;
00363     intsrc.IrqFlag = 0;         /* conforming */
00364     intsrc.SrcBusId = 0;
00365     intsrc.DstApicId = IOAPICMap[0].ApicId;
00366 
00367     intsrc.IrqType = INT_VECTORED;
00368     for (i = 0; i < 16; i++) {
00369         switch (Type) {
00370         case 2:
00371             if (i == 0 || i == 13)
00372                 continue;   /* IRQ0 & IRQ13 not connected */
00373             /* Fall through */
00374         default:
00375             if (i == 2)
00376                 continue;   /* IRQ2 is never connected */
00377         }
00378 
00379         intsrc.SrcBusIrq = i;
00380         intsrc.DstApicInt = i ? i : 2; /* IRQ0 to INTIN2 */
00381         HaliMPIntSrcInfo(&intsrc);
00382     }
00383 
00384     intsrc.IrqType = INT_EXTINT;
00385     intsrc.SrcBusIrq = 0;
00386     intsrc.DstApicInt = 0; /* 8259A to INTIN0 */
00387     HaliMPIntSrcInfo(&intsrc);
00388 }
00389 
00390 static VOID 
00391 HaliConstructDefaultISAMPTable(ULONG Type)
00392 {
00393   MP_CONFIGURATION_PROCESSOR processor;
00394   MP_CONFIGURATION_BUS bus;
00395   MP_CONFIGURATION_IOAPIC ioapic;
00396   MP_CONFIGURATION_INTLOCAL lintsrc;
00397   UCHAR linttypes[2] = { INT_EXTINT, INT_NMI };
00398   UCHAR i;
00399 
00400   /*
00401    * 2 CPUs, numbered 0 & 1.
00402    */
00403   processor.Type = MPCTE_PROCESSOR;
00404   /* Either an integrated APIC or a discrete 82489DX. */
00405   processor.ApicVersion = Type > 4 ? 0x10 : 0x01;
00406   processor.CpuFlags = CPU_FLAG_ENABLED | CPU_FLAG_BSP;
00407   /* FIXME: Get this from the bootstrap processor */
00408   processor.CpuSignature = 0;
00409   processor.FeatureFlags = 0;
00410   processor.Reserved[0] = 0;
00411   processor.Reserved[1] = 0;
00412   for (i = 0; i < 2; i++) 
00413   {
00414     processor.ApicId = i;
00415     HaliMPProcessorInfo(&processor);
00416     processor.CpuFlags &= ~CPU_FLAG_BSP;
00417   }
00418 
00419   bus.Type = MPCTE_BUS;
00420   bus.BusId = 0;
00421   switch (Type) 
00422   {
00423     default:
00424     DPRINT("Unknown standard configuration %d\n", Type);
00425       /* Fall through */
00426     case 1:
00427     case 5:
00428       memcpy(bus.BusType, "ISA   ", 6);
00429       break;
00430     case 2:
00431     case 6:
00432     case 3:
00433       memcpy(bus.BusType, "EISA  ", 6);
00434       break;
00435     case 4:
00436     case 7:
00437       memcpy(bus.BusType, "MCA   ", 6);
00438   }
00439   HaliMPBusInfo(&bus);
00440   if (Type > 4) 
00441   {
00442     bus.Type = MPCTE_BUS;
00443     bus.BusId = 1;
00444     memcpy(bus.BusType, "PCI   ", 6);
00445     HaliMPBusInfo(&bus);
00446   }
00447 
00448   ioapic.Type = MPCTE_IOAPIC;
00449   ioapic.ApicId = 2;
00450   ioapic.ApicVersion = Type > 4 ? 0x10 : 0x01;
00451   ioapic.ApicFlags = MP_IOAPIC_USABLE;
00452   ioapic.ApicAddress = IOAPIC_DEFAULT_BASE;
00453   HaliMPIOApicInfo(&ioapic);
00454 
00455   /*
00456    * We set up most of the low 16 IO-APIC pins according to MPS rules.
00457    */
00458   HaliConstructDefaultIOIrqMPTable(Type);
00459 
00460   lintsrc.Type = MPCTE_LINTSRC;
00461   lintsrc.IrqType = 0;
00462   lintsrc.IrqFlag = 0;  /* conforming */
00463   lintsrc.SrcBusId = 0;
00464   lintsrc.SrcBusIrq = 0;
00465   lintsrc.DstApicId = MP_APIC_ALL;
00466   for (i = 0; i < 2; i++) 
00467   {
00468     lintsrc.IrqType = linttypes[i];
00469     lintsrc.DstApicLInt = i;
00470     HaliMPIntLocalInfo(&lintsrc);
00471   }
00472 }
00473 
00474 
00475 static BOOLEAN
00476 HaliScanForMPConfigTable(ULONG Base,
00477              ULONG Size)
00478 {
00479 /*
00480    PARAMETERS:
00481       Base = Base address of region
00482       Size = Length of region to check
00483    RETURNS:
00484       TRUE if a valid MP configuration table was found
00485  */
00486 
00487    PULONG bp = (PULONG)Base;
00488    MP_FLOATING_POINTER* mpf;
00489    UCHAR Checksum;
00490 
00491    while (Size > 0)
00492    {
00493       mpf = (MP_FLOATING_POINTER*)bp;
00494       if (mpf->Signature == MPF_SIGNATURE)
00495       {
00496      Checksum = MPChecksum((PUCHAR)bp, 16);
00497      DPRINT("Found MPF signature at %x, checksum %x\n", bp, Checksum);
00498          if (Checksum == 0 &&
00499          mpf->Length == 1)
00500          {
00501             DPRINT("Intel MultiProcessor Specification v1.%d compliant system.\n",
00502                    mpf->Specification);
00503 
00504             if (mpf->Feature2 & FEATURE2_IMCRP) 
00505         {
00506                DPRINT("Running in IMCR and PIC compatibility mode.\n");
00507             } 
00508         else 
00509         {
00510                DPRINT("Running in Virtual Wire compatibility mode.\n");
00511         }
00512     
00513 
00514             switch (mpf->Feature1)
00515             {
00516                case 0:
00517                   /* Non standard configuration */
00518                   break;
00519                case 1:
00520                   DPRINT("ISA\n");
00521                   break;
00522                case 2:
00523                   DPRINT("EISA with no IRQ8 chaining\n");
00524                   break;
00525                case 3:
00526                   DPRINT("EISA\n");
00527                   break;
00528                case 4:
00529                   DPRINT("MCA\n");
00530                   break;
00531                case 5:
00532                   DPRINT("ISA and PCI\n");
00533                   break;
00534                case 6:
00535                   DPRINT("EISA and PCI\n");
00536                   break;
00537                case 7:
00538                   DPRINT("MCA and PCI\n");
00539                   break;
00540                default:
00541                   DPRINT("Unknown standard configuration %d\n", mpf->Feature1);
00542                   return FALSE;
00543             }
00544             Mpf = mpf; 
00545             return TRUE;
00546          }
00547       }
00548       bp += 4;
00549       Size -= 16;
00550    }
00551    return FALSE;
00552 }
00553 
00554 static BOOLEAN
00555 HaliGetSmpConfig(VOID)
00556 {
00557    if (Mpf == NULL)
00558    {
00559       return FALSE;
00560    }
00561 
00562    if (Mpf->Feature2 & FEATURE2_IMCRP)
00563    {
00564       DPRINT("Running in IMCR and PIC compatibility mode.\n");
00565       APICMode = amPIC;
00566    }
00567    else
00568    {
00569       DPRINT("Running in Virtual Wire compatibility mode.\n");
00570       APICMode = amVWIRE;
00571    }
00572 
00573    if (Mpf->Feature1 == 0 && Mpf->Address)
00574    {
00575       if(!HaliReadMPConfigTable((PMP_CONFIGURATION_TABLE)Mpf->Address))
00576       {
00577          DPRINT("BIOS bug, MP table errors detected!...\n");
00578      DPRINT("... disabling SMP support. (tell your hw vendor)\n");
00579      return FALSE;
00580       }
00581       if (IRQCount == 0)
00582       {
00583          MP_CONFIGURATION_BUS bus;
00584 
00585          DPRINT("BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");
00586 
00587          bus.BusId = 1;
00588      memcpy(bus.BusType, "ISA   ", 6);
00589          HaliMPBusInfo(&bus);
00590      HaliConstructDefaultIOIrqMPTable(bus.BusId);
00591       }
00592 
00593    } 
00594    else if(Mpf->Feature1 != 0)
00595    {
00596       HaliConstructDefaultISAMPTable(Mpf->Feature1);
00597    }
00598    else
00599    {
00600       ASSERT(FALSE);
00601    }
00602    return TRUE;
00603 }    
00604 
00605 BOOLEAN 
00606 HaliFindSmpConfig(VOID)
00607 {
00608    /*
00609      Scan the system memory for an MP configuration table
00610        1) Scan the first KB of system base memory
00611        2) Scan the last KB of system base memory
00612        3) Scan the BIOS ROM address space between 0F0000h and 0FFFFFh
00613        4) Scan the first KB from the Extended BIOS Data Area
00614    */
00615 
00616    if (!HaliScanForMPConfigTable(0x0, 0x400)) 
00617    {
00618       if (!HaliScanForMPConfigTable(0x9FC00, 0x400)) 
00619       {
00620          if (!HaliScanForMPConfigTable(0xF0000, 0x10000)) 
00621          {
00622             if (!HaliScanForMPConfigTable(*((PUSHORT)0x040E) << 4, 0x400)) 
00623         {
00624                DPRINT("No multiprocessor compliant system found.\n");
00625                return FALSE;
00626             }
00627          }
00628       }
00629    }
00630 
00631    if (HaliGetSmpConfig())
00632    {
00633       return TRUE;
00634    }
00635    else
00636    {
00637       DPRINT("No MP config table found\n");
00638       return FALSE;
00639    }
00640 
00641 }
00642 
00643 /* EOF */

Generated on Sun May 27 2012 04:28:44 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.