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

Definition at line 258 of file cpu.c.

{
    PKPRCB Prcb = KeGetCurrentPrcb();
    ULONG Vendor;
    ULONG FeatureBits = KF_WORKING_PTE;
    ULONG Reg[4], Dummy;
    UCHAR Ccr1;
    BOOLEAN ExtendedCPUID = TRUE;
    ULONG CpuFeatures = 0;

    /* Get the Vendor ID */
    Vendor = KiGetCpuVendor();

    /* Make sure we got a valid vendor ID at least. */
    if (!Vendor) return FeatureBits;

    /* Get the CPUID Info. Features are in Reg[3]. */
    CPUID(1, &Reg[0], &Reg[1], &Dummy, &Reg[3]);

    /* Set the initial APIC ID */
    Prcb->InitialApicId = (UCHAR)(Reg[1] >> 24);

    switch (Vendor)
    {
        /* Intel CPUs */
        case CPU_INTEL:

            /* Check if it's a P6 */
            if (Prcb->CpuType == 6)
            {
                /* Perform the special sequence to get the MicroCode Signature */
                WRMSR(0x8B, 0);
                CPUID(1, &Dummy, &Dummy, &Dummy, &Dummy);
                Prcb->UpdateSignature.QuadPart = RDMSR(0x8B);
            }
            else if (Prcb->CpuType == 5)
            {
                /* On P5, enable workaround for the LOCK errata. */
                KiI386PentiumLockErrataPresent = TRUE;
            }

            /* Check for broken P6 with bad SMP PTE implementation */
            if (((Reg[0] & 0x0FF0) == 0x0610 && (Reg[0] & 0x000F) <= 0x9) ||
                ((Reg[0] & 0x0FF0) == 0x0630 && (Reg[0] & 0x000F) <= 0x4))
            {
                /* Remove support for correct PTE support. */
                FeatureBits &= ~KF_WORKING_PTE;
            }

            /* Check if the CPU is too old to support SYSENTER */
            if ((Prcb->CpuType < 6) ||
                ((Prcb->CpuType == 6) && (Prcb->CpuStep < 0x0303)))
            {
                /* Disable it */
                Reg[3] &= ~0x800;
            }

            break;

        /* AMD CPUs */
        case CPU_AMD:

            /* Check if this is a K5 or K6. (family 5) */
            if ((Reg[0] & 0x0F00) == 0x0500)
            {
                /* Get the Model Number */
                switch (Reg[0] & 0x00F0)
                {
                    /* Model 1: K5 - 5k86 (initial models) */
                    case 0x0010:

                        /* Check if this is Step 0 or 1. They don't support PGE */
                        if ((Reg[0] & 0x000F) > 0x03) break;

                    /* Model 0: K5 - SSA5 */
                    case 0x0000:

                        /* Model 0 doesn't support PGE at all. */
                        Reg[3] &= ~0x2000;
                        break;

                    /* Model 8: K6-2 */
                    case 0x0080:

                        /* K6-2, Step 8 and over have support for MTRR. */
                        if ((Reg[0] & 0x000F) >= 0x8) FeatureBits |= KF_AMDK6MTRR;
                        break;

                    /* Model 9: K6-III
                       Model D: K6-2+, K6-III+ */
                    case 0x0090:
                    case 0x00D0:

                        FeatureBits |= KF_AMDK6MTRR;
                        break;
                }
            }
            else if((Reg[0] & 0x0F00) < 0x0500)
            {
                /* Families below 5 don't support PGE, PSE or CMOV at all */
                Reg[3] &= ~(0x08 | 0x2000 | 0x8000);

                /* They also don't support advanced CPUID functions. */
                ExtendedCPUID = FALSE;
            }

            break;

        /* Cyrix CPUs */
        case CPU_CYRIX:

            /* Workaround the "COMA" bug on 6x family of Cyrix CPUs */
            if (Prcb->CpuType == 6 &&
                Prcb->CpuStep <= 1)
            {
                /* Get CCR1 value */
                Ccr1 = getCx86(CX86_CCR1);

                /* Enable the NO_LOCK bit */
                Ccr1 |= 0x10;

                /* Set the new CCR1 value */
                setCx86(CX86_CCR1, Ccr1);
            }

            break;

        /* Transmeta CPUs */
        case CPU_TRANSMETA:

            /* Enable CMPXCHG8B if the family (>= 5), model and stepping (>= 4.2) support it */
            if ((Reg[0] & 0x0FFF) >= 0x0542)
            {
                WRMSR(0x80860004, RDMSR(0x80860004) | 0x0100);
                FeatureBits |= KF_CMPXCHG8B;
            }

            break;

        /* Centaur, IDT, Rise and VIA CPUs */
        case CPU_CENTAUR:
        case CPU_RISE:

            /* These CPUs don't report the presence of CMPXCHG8B through CPUID.
               However, this feature exists and operates properly without any additional steps. */
            FeatureBits |= KF_CMPXCHG8B;

            break;
    }

    /* Set the current features */
    CpuFeatures = Reg[3];

    /* Convert all CPUID Feature bits into our format */
    if (CpuFeatures & 0x00000002) FeatureBits |= KF_V86_VIS | KF_CR4;
    if (CpuFeatures & 0x00000008) FeatureBits |= KF_LARGE_PAGE | KF_CR4;
    if (CpuFeatures & 0x00000010) FeatureBits |= KF_RDTSC;
    if (CpuFeatures & 0x00000100) FeatureBits |= KF_CMPXCHG8B;
    if (CpuFeatures & 0x00000800) FeatureBits |= KF_FAST_SYSCALL;
    if (CpuFeatures & 0x00001000) FeatureBits |= KF_MTRR;
    if (CpuFeatures & 0x00002000) FeatureBits |= KF_GLOBAL_PAGE | KF_CR4;
    if (CpuFeatures & 0x00008000) FeatureBits |= KF_CMOV;
    if (CpuFeatures & 0x00010000) FeatureBits |= KF_PAT;
    if (CpuFeatures & 0x00200000) FeatureBits |= KF_DTS;
    if (CpuFeatures & 0x00800000) FeatureBits |= KF_MMX;
    if (CpuFeatures & 0x01000000) FeatureBits |= KF_FXSR;
    if (CpuFeatures & 0x02000000) FeatureBits |= KF_XMMI;
    if (CpuFeatures & 0x04000000) FeatureBits |= KF_XMMI64;

    /* Check if the CPU has hyper-threading */
    if (CpuFeatures & 0x10000000)
    {
        /* Set the number of logical CPUs */
        Prcb->LogicalProcessorsPerPhysicalProcessor = (UCHAR)(Reg[1] >> 16);
        if (Prcb->LogicalProcessorsPerPhysicalProcessor > 1)
        {
            /* We're on dual-core */
            KiSMTProcessorsPresent = TRUE;
        }
    }
    else
    {
        /* We only have a single CPU */
        Prcb->LogicalProcessorsPerPhysicalProcessor = 1;
    }

    /* Check if CPUID 0x80000000 is supported */
    if (ExtendedCPUID)
    {
        /* Do the call */
        CPUID(0x80000000, &Reg[0], &Dummy, &Dummy, &Dummy);
        if ((Reg[0] & 0xffffff00) == 0x80000000)
        {
            /* Check if CPUID 0x80000001 is supported */
            if (Reg[0] >= 0x80000001)
            {
                /* Check which extended features are available. */
                CPUID(0x80000001, &Dummy, &Dummy, &Dummy, &Reg[3]);

                /* Check if NX-bit is supported */
                if (Reg[3] & 0x00100000) FeatureBits |= KF_NX_BIT;

                /* Now handle each features for each CPU Vendor */
                switch (Vendor)
                {
                    case CPU_AMD:
                    case CPU_CENTAUR:
                        if (Reg[3] & 0x80000000) FeatureBits |= KF_3DNOW;
                        break;
                }
            }
        }
    }

#define print_supported(kf_value) ((FeatureBits & kf_value) ? #kf_value : "")
    DPRINT1("Supported CPU features : %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n",
    print_supported(KF_V86_VIS),
    print_supported(KF_RDTSC),
    print_supported(KF_CR4),
    print_supported(KF_CMOV),
    print_supported(KF_GLOBAL_PAGE),
    print_supported(KF_LARGE_PAGE),
    print_supported(KF_MTRR),
    print_supported(KF_CMPXCHG8B),
    print_supported(KF_MMX),
    print_supported(KF_WORKING_PTE),
    print_supported(KF_PAT),
    print_supported(KF_FXSR),
    print_supported(KF_FAST_SYSCALL),
    print_supported(KF_XMMI),
    print_supported(KF_3DNOW),
    print_supported(KF_AMDK6MTRR),
    print_supported(KF_XMMI64),
    print_supported(KF_DTS),
    print_supported(KF_NX_BIT),
    print_supported(KF_NX_DISABLED),
    print_supported(KF_NX_ENABLED));
#undef print_supported

    /* Return the Feature Bits */
    return FeatureBits;
}

Generated on Sat May 26 2012 06:07:03 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.