Index: trunk/i386/libsaio/efi.h =================================================================== --- trunk/i386/libsaio/efi.h (revision 2646) +++ trunk/i386/libsaio/efi.h (revision 2647) @@ -230,11 +230,10 @@ // physical memory protection on range -#define EFI_MEMORY_WP 0x0000000000001000ULL -#define EFI_MEMORY_RP 0x0000000000002000ULL -#define EFI_MEMORY_XP 0x0000000000004000ULL +#define EFI_MEMORY_WP 0x0000000000001000ULL /* write-protect */ +#define EFI_MEMORY_RP 0x0000000000002000ULL /* read-protect */ +#define EFI_MEMORY_XP 0x0000000000004000ULL /* execute-protect */ - // range requires a runtime mapping #define EFI_MEMORY_RUNTIME 0x8000000000000000ULL @@ -498,9 +497,12 @@ #define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249ULL #define EFI_SYSTEM_TABLE_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION << 16) | (EFI_SPECIFICATION_MINOR_REVISION)) -#define EFI_2_00_SYSTEM_TABLE_REVISION ((2 << 16) | 00) -#define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | 02) -#define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | 10) +#define EFI_2_30_SYSTEM_TABLE_REVISION ((2 << 16) | (30)) +#define EFI_2_20_SYSTEM_TABLE_REVISION ((2 << 16) | (20)) +#define EFI_2_10_SYSTEM_TABLE_REVISION ((2 << 16) | (10)) +#define EFI_2_00_SYSTEM_TABLE_REVISION ((2 << 16) | (00)) +#define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | (10)) +#define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | (02)) typedef struct EFI_SYSTEM_TABLE_32 { EFI_TABLE_HEADER Hdr; Index: trunk/i386/libsaio/cpu.c =================================================================== --- trunk/i386/libsaio/cpu.c (revision 2646) +++ trunk/i386/libsaio/cpu.c (revision 2647) @@ -19,6 +19,71 @@ #define DBG(x...) #endif + +boolean_t ForceAmdCpu = false; + +/* For AMD CPU's */ +boolean_t IsAmdCPU(void) +{ + if (ForceAmdCpu) + { + return true; + } + + uint32_t ourcpuid[4]; + do_cpuid(0, ourcpuid); + if ( + /* This spells out "AuthenticAMD". */ + ourcpuid[ebx] == 0x68747541 && // Auth + ourcpuid[ecx] == 0x444D4163 && // cAMD + ourcpuid[edx] == 0x69746E65) // enti + { + return true; + } + + return false; +}; + +/* For Intel CPU's */ +boolean_t IsIntelCPU(void) +{ + uint32_t ourcpuid[4]; + do_cpuid(0, ourcpuid); + if ( + /* This spells out "GenuineIntel". */ + ourcpuid[ebx] == 0x756E6547 && // Genu + ourcpuid[ecx] == 0x6C65746E && // ntel + ourcpuid[edx] == 0x49656E69) // ineI + { + return true; + } + + if (!IsAmdCPU()) + { + return true; + } + + return false; +} + +#define UI_CPUFREQ_ROUNDING_FACTOR 10000000 + +clock_frequency_info_t gPEClockFrequencyInfo; + +static inline uint32_t __unused clockspeed_rdtsc(void) +{ + uint32_t out; + __asm__ volatile ( + "rdtsc\n" + "shl $32,%%edx\n" + "or %%edx,%%eax\n" + : "=a" (out) + : + : "%edx" + ); + return out; +} + /* * timeRDTSC() * This routine sets up PIT counter 2 to count down 1/20 of a second. @@ -54,10 +119,10 @@ //int_enabled = ml_set_interrupts_enabled(false); restart: - if (attempts >= 9) // increase to up to 9 attempts. + if (attempts >= 3) // increase to up to 9 attempts. { // This will flash-reboot. TODO: Use tscPanic instead. - printf("Timestamp counter calibation failed with %d attempts\n", attempts); + //printf("Timestamp counter calibation failed with %d attempts\n", attempts); } attempts++; enable_PIT2(); // turn on PIT2 @@ -79,9 +144,9 @@ } lastValue = timerValue; } while (timerValue > 5); - printf("timerValue %d\n",timerValue); - printf("intermediate 0x%016llX\n",intermediate); - printf("saveTime 0x%016llX\n",saveTime); + //printf("timerValue %d\n",timerValue); + //printf("intermediate 0x%016llX\n",intermediate); + //printf("saveTime 0x%016llX\n",saveTime); intermediate -= saveTime; // raw count for about 1/20 second intermediate *= scale[timerValue]; // rescale measured time spent @@ -98,7 +163,7 @@ /* * DFE: Measures the TSC frequency in Hz (64-bit) using the ACPI PM timer */ -static uint64_t measure_tsc_frequency(void) +static uint64_t __unused measure_tsc_frequency(void) { uint64_t tscStart; uint64_t tscEnd; @@ -167,69 +232,75 @@ return retval; } -/* - * Original comment/code: - * "DFE: Measures the Max Performance Frequency in Hz (64-bit)" - * - * Measures the Actual Performance Frequency in Hz (64-bit) - * (just a naming change, mperf --> aperf ) - */ -static uint64_t measure_aperf_frequency(void) +static uint64_t rtc_set_cyc_per_sec(uint64_t cycles); +#define RTC_FAST_DENOM 0xFFFFFFFF + +inline static uint32_t +create_mul_quant_GHZ(int shift, uint32_t quant) { - uint64_t aperfStart; - uint64_t aperfEnd; - uint64_t aperfDelta = 0xffffffffffffffffULL; - unsigned long pollCount; - uint64_t retval = 0; - int i; + return (uint32_t)((((uint64_t)NSEC_PER_SEC/20) << shift) / quant); +} - /* Time how many APERF ticks elapse in 30 msec using the 8254 PIT - * counter 2. We run this loop 3 times to make sure the cache - * is hot and we take the minimum delta from all of the runs. - * That is to say that we're biased towards measuring the minimum - * number of APERF ticks that occur while waiting for the timer to - * expire. - */ - for(i = 0; i < 10; ++i) +struct { + mach_timespec_t calend_offset; + boolean_t calend_is_set; + + int64_t calend_adjtotal; + int32_t calend_adjdelta; + + uint32_t boottime; + + mach_timebase_info_data_t timebase_const; + + decl_simple_lock_data(,lock) /* real-time clock device lock */ +} rtclock; + +uint32_t rtc_quant_shift; /* clock to nanos right shift */ +uint32_t rtc_quant_scale; /* clock to nanos multiplier */ +uint64_t rtc_cyc_per_sec; /* processor cycles per sec */ +uint64_t rtc_cycle_count; /* clocks in 1/20th second */ +//uint64_t cpuFreq; + +static uint64_t rtc_set_cyc_per_sec(uint64_t cycles) +{ + + if (cycles > (NSEC_PER_SEC/20)) { - enable_PIT2(); - set_PIT2_mode0(CALIBRATE_LATCH); - aperfStart = rdmsr64(MSR_AMD_APERF); - pollCount = poll_PIT2_gate(); - aperfEnd = rdmsr64(MSR_AMD_APERF); - /* The poll loop must have run at least a few times for accuracy */ - if (pollCount <= 1) - { - continue; - } - /* The TSC must increment at LEAST once every millisecond. - * We should have waited exactly 30 msec so the APERF delta should - * be >= 30. Anything less and the processor is way too slow. - */ - if ((aperfEnd - aperfStart) <= CALIBRATE_TIME_MSEC) - { - continue; - } - // tscDelta = MIN(tscDelta, (tscEnd - tscStart)) - if ( (aperfEnd - aperfStart) < aperfDelta ) - { - aperfDelta = aperfEnd - aperfStart; - } + // we can use just a "fast" multiply to get nanos + rtc_quant_shift = 32; + rtc_quant_scale = create_mul_quant_GHZ(rtc_quant_shift, (uint32_t)cycles); + rtclock.timebase_const.numer = rtc_quant_scale; // timeRDTSC is 1/20 + rtclock.timebase_const.denom = (uint32_t)RTC_FAST_DENOM; } - /* mperfDelta is now the least number of MPERF ticks the processor made in - * a timespan of 0.03 s (e.g. 30 milliseconds) + else + { + rtc_quant_shift = 26; + rtc_quant_scale = create_mul_quant_GHZ(rtc_quant_shift, (uint32_t)cycles); + rtclock.timebase_const.numer = NSEC_PER_SEC/20; // timeRDTSC is 1/20 + rtclock.timebase_const.denom = (uint32_t)cycles; + } + rtc_cyc_per_sec = cycles*20; // multiply it by 20 and we are done.. + // BUT we also want to calculate... + + cycles = ((rtc_cyc_per_sec + (UI_CPUFREQ_ROUNDING_FACTOR/2)) + / UI_CPUFREQ_ROUNDING_FACTOR) + * UI_CPUFREQ_ROUNDING_FACTOR; + + /* + * Set current measured speed. */ - - if (aperfDelta > (1ULL<<32)) + if (cycles >= 0x100000000ULL) { - retval = 0; + gPEClockFrequencyInfo.cpu_clock_rate_hz = 0xFFFFFFFFUL; } else { - retval = aperfDelta * 1000 / 30; + gPEClockFrequencyInfo.cpu_clock_rate_hz = (unsigned long)cycles; } - disable_PIT2(); - return retval; + gPEClockFrequencyInfo.cpu_frequency_hz = cycles; + + //printf("[RTCLOCK_1] frequency %llu (%llu) %llu\n", cycles, rtc_cyc_per_sec,timeRDTSC() * 20); + return(rtc_cyc_per_sec); } /* @@ -237,20 +308,33 @@ * - multi. is read from a specific MSR. In the case of Intel, there is: * a max multi. (used to calculate the FSB freq.), * and a current multi. (used to calculate the CPU freq.) - * - fsbFrequency = tscFrequency / multi - * - cpuFrequency = fsbFrequency * multi + * - busFrequency = tscFrequency / multi + * - cpuFrequency = busFrequency * multi */ + +/* Decimal powers: */ +#define kilo (1000ULL) +#define Mega (kilo * kilo) +#define Giga (kilo * Mega) +#define Tera (kilo * Giga) +#define Peta (kilo * Tera) + +#define quad(hi,lo) (((uint64_t)(hi)) << 32 | (lo)) + void scan_cpu(PlatformInfo_t *p) { - uint64_t tscFrequency = 0; - uint64_t fsbFrequency = 0; + uint64_t busFCvtt2n; + uint64_t tscFCvtt2n; + uint64_t tscFreq = 0; + uint64_t busFrequency = 0; uint64_t cpuFrequency = 0; uint64_t msr = 0; uint64_t flex_ratio = 0; + uint64_t cpuid_features; uint32_t max_ratio = 0; uint32_t min_ratio = 0; - uint32_t reg[4]; // = {0, 0, 0, 0}; + uint32_t reg[4]; uint32_t cores_per_package = 0; uint32_t logical_per_package = 1; uint32_t threads_per_core = 1; @@ -261,7 +345,7 @@ uint8_t currcoef = 0; uint8_t maxdiv = 0; uint8_t maxcoef = 0; - uint8_t pic0_mask; + uint8_t cpuMultN2 = 0; const char *newratio; char str[128]; @@ -271,68 +355,101 @@ int myfsb = 0; int i = 0; - /* get cpuid values */ - do_cpuid(0x00000000, p->CPU.CPUID[CPUID_0]); // MaxFn, Vendor - p->CPU.Vendor = p->CPU.CPUID[CPUID_0][ebx]; - - do_cpuid(0x00000001, p->CPU.CPUID[CPUID_1]); // Signature, stepping, features - - if ((p->CPU.Vendor == CPUID_VENDOR_INTEL) && ((bit(28) & p->CPU.CPUID[CPUID_1][edx]) != 0)) // Intel && HTT/Multicore + if(IsIntelCPU()) { - logical_per_package = bitfield(p->CPU.CPUID[CPUID_1][ebx], 23, 16); - } - do_cpuid(0x00000002, p->CPU.CPUID[CPUID_2]); // TLB/Cache/Prefetch + do_cpuid(0x00000002, p->CPU.CPUID[CPUID_2]); // TLB/Cache/Prefetch - do_cpuid(0x00000003, p->CPU.CPUID[CPUID_3]); // S/N + do_cpuid(0x00000003, p->CPU.CPUID[CPUID_3]); // S/N - /* Based on Apple's XNU cpuid.c - Deterministic cache parameters */ - if ((p->CPU.CPUID[CPUID_0][eax] > 3) && (p->CPU.CPUID[CPUID_0][eax] < 0x80000000)) - { - for (i = 0; i < 0xFF; i++) // safe loop + /* Based on Apple's XNU cpuid.c - Deterministic cache parameters */ + if ((p->CPU.CPUID[CPUID_0][eax] > 3) && (p->CPU.CPUID[CPUID_0][eax] < 0x80000000)) { - do_cpuid2(0x00000004, i, reg); // AX=4: Fn, CX=i: cache index - if (bitfield(reg[eax], 4, 0) == 0) + for (i = 0; i < 0xFF; i++) // safe loop { - break; + do_cpuid2(0x00000004, i, reg); // AX=4: Fn, CX=i: cache index + if (bitfield(reg[eax], 4, 0) == 0) + { + break; + } + cores_per_package = bitfield(reg[eax], 31, 26) + 1; } - //cores_per_package = bitfield(reg[eax], 31, 26) + 1; + } + + do_cpuid2(0x00000004, 0, p->CPU.CPUID[CPUID_4]); + + if (i > 0) + { + cores_per_package = bitfield(p->CPU.CPUID[CPUID_4][eax], 31, 26) + 1; // i = cache index + threads_per_core = bitfield(p->CPU.CPUID[CPUID_4][eax], 25, 14) + 1; } - } - do_cpuid2(0x00000004, 0, p->CPU.CPUID[CPUID_4]); + if (cores_per_package == 0) + { + cores_per_package = 1; + } - if (i > 0) - { - cores_per_package = bitfield(p->CPU.CPUID[CPUID_4][eax], 31, 26) + 1; // i = cache index - threads_per_core = bitfield(p->CPU.CPUID[CPUID_4][eax], 25, 14) + 1; - } + if (p->CPU.CPUID[CPUID_0][0] >= 0x5) // Monitor/Mwait + { + do_cpuid(5, p->CPU.CPUID[CPUID_5]); + } - if (cores_per_package == 0) - { - cores_per_package = 1; - } + if (p->CPU.CPUID[CPUID_0][0] >= 6) // Thermal/Power + { + do_cpuid(6, p->CPU.CPUID[CPUID_6]); + } - if (p->CPU.CPUID[CPUID_0][0] >= 0x5) // Monitor/Mwait - { - do_cpuid(5, p->CPU.CPUID[CPUID_5]); + do_cpuid(0x80000000, p->CPU.CPUID[CPUID_80]); + + if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 8) + { + do_cpuid(0x80000008, p->CPU.CPUID[CPUID_88]); + do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]); + } + else if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 1) + { + do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]); + } } - - if (p->CPU.CPUID[CPUID_0][0] >= 6) // Thermal/Power + else if(IsAmdCPU()) { - do_cpuid(6, p->CPU.CPUID[CPUID_6]); - } + do_cpuid(5, p->CPU.CPUID[CPUID_5]); // Monitor/Mwait - do_cpuid(0x80000000, p->CPU.CPUID[CPUID_80]); + do_cpuid(0x80000000, p->CPU.CPUID[CPUID_80]); + if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 8) + { + do_cpuid(0x80000008, p->CPU.CPUID[CPUID_88]); + } - if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 8) - { + if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 1) + { + do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]); + } + + do_cpuid(0x80000005, p->CPU.CPUID[CPUID_85]); // TLB/Cache/Prefetch + do_cpuid(0x80000006, p->CPU.CPUID[CPUID_86]); // TLB/Cache/Prefetch do_cpuid(0x80000008, p->CPU.CPUID[CPUID_88]); - do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]); + + cores_per_package = bitfield(p->CPU.CPUID[CPUID_88][ecx], 7, 0) + 1; + threads_per_core = cores_per_package; + + if (cores_per_package == 0) + { + cores_per_package = 1; + } + + p->CPU.NoThreads = logical_per_package; + p->CPU.NoCores = cores_per_package; + + if (p->CPU.NoCores == 0) + { + p->CPU.NoCores = 1; + p->CPU.NoThreads = 1; + } } - else if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 1) + else { - do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]); + stop("Unsupported CPU detected! System halted."); } /* http://www.flounder.com/cpuid_explorer2.htm @@ -348,7 +465,20 @@ |########|Extended family |Extmodel|####|####|familyid| model |stepping| +--------+----------------+--------+----+----+--------+--------+--------+ */ + do_cpuid(0x00000001, p->CPU.CPUID[CPUID_1]); // Signature, stepping, features + cpuid_features = quad(p->CPU.CPUID[CPUID_1][ecx],p->CPU.CPUID[CPUID_1][edx]); + if (bit(28) & cpuid_features) // HTT/Multicore + { + logical_per_package = bitfield(p->CPU.CPUID[CPUID_1][ebx], 23, 16); + } + else + { + logical_per_package = 1; + } + + do_cpuid(0x00000000, p->CPU.CPUID[CPUID_0]); // MaxFn, Vendor + p->CPU.Vendor = p->CPU.CPUID[CPUID_0][1]; p->CPU.Signature = p->CPU.CPUID[CPUID_1][0]; p->CPU.Stepping = (uint8_t)bitfield(p->CPU.CPUID[CPUID_1][0], 3, 0); // stepping = cpu_feat_eax & 0xF; @@ -358,8 +488,16 @@ p->CPU.ExtModel = (uint8_t)bitfield(p->CPU.CPUID[CPUID_1][0], 19, 16); // ext_model = (cpu_feat_eax >> 16) & 0xF; p->CPU.ExtFamily = (uint8_t)bitfield(p->CPU.CPUID[CPUID_1][0], 27, 20); // ext_family = (cpu_feat_eax >> 20) & 0xFF; - p->CPU.Model += (p->CPU.ExtModel << 4); + if (p->CPU.Family == 0x0f) + { + p->CPU.Family += p->CPU.ExtFamily; + } + if (p->CPU.Family == 0x0f || p->CPU.Family == 0x06) + { + p->CPU.Model += (p->CPU.ExtModel << 4); + } + /* get BrandString (if supported) */ /* Copyright: from Apple's XNU cpuid.c */ if (p->CPU.CPUID[CPUID_80][0] > 0x80000004) @@ -400,73 +538,61 @@ * Find the number of enabled cores and threads * (which determines whether SMT/Hyperthreading is active). */ - switch (p->CPU.Vendor) + + if(IsIntelCPU()) { - case CPUID_VENDOR_INTEL: - switch (p->CPU.Model) - { - case CPUID_MODEL_NEHALEM: - case CPUID_MODEL_FIELDS: - case CPUID_MODEL_DALES: - case CPUID_MODEL_NEHALEM_EX: - case CPUID_MODEL_JAKETOWN: - case CPUID_MODEL_SANDYBRIDGE: - case CPUID_MODEL_IVYBRIDGE: + switch (p->CPU.Model) + { + case CPUID_MODEL_NEHALEM: + case CPUID_MODEL_FIELDS: + case CPUID_MODEL_DALES: + case CPUID_MODEL_NEHALEM_EX: + case CPUID_MODEL_JAKETOWN: + case CPUID_MODEL_SANDYBRIDGE: + case CPUID_MODEL_IVYBRIDGE: - case CPUID_MODEL_HASWELL: - case CPUID_MODEL_HASWELL_SVR: - //case CPUID_MODEL_HASWELL_H: - case CPUID_MODEL_HASWELL_ULT: - case CPUID_MODEL_CRYSTALWELL: - //case CPUID_MODEL_: - msr = rdmsr64(MSR_CORE_THREAD_COUNT); - p->CPU.NoCores = (uint32_t)bitfield((uint32_t)msr, 31, 16); - p->CPU.NoThreads = (uint32_t)bitfield((uint32_t)msr, 15, 0); - break; + case CPUID_MODEL_HASWELL: + case CPUID_MODEL_HASWELL_SVR: + //case CPUID_MODEL_HASWELL_H: + case CPUID_MODEL_HASWELL_ULT: + case CPUID_MODEL_CRYSTALWELL: + //case CPUID_MODEL_: + msr = rdmsr64(MSR_CORE_THREAD_COUNT); + p->CPU.NoCores = (uint32_t)bitfield((uint32_t)msr, 31, 16); + p->CPU.NoThreads = (uint32_t)bitfield((uint32_t)msr, 15, 0); + break; - case CPUID_MODEL_DALES_32NM: - case CPUID_MODEL_WESTMERE: - case CPUID_MODEL_WESTMERE_EX: - msr = rdmsr64(MSR_CORE_THREAD_COUNT); - p->CPU.NoCores = (uint32_t)bitfield((uint32_t)msr, 19, 16); - p->CPU.NoThreads = (uint32_t)bitfield((uint32_t)msr, 15, 0); - break; - } + case CPUID_MODEL_DALES_32NM: + case CPUID_MODEL_WESTMERE: + case CPUID_MODEL_WESTMERE_EX: + msr = rdmsr64(MSR_CORE_THREAD_COUNT); + p->CPU.NoCores = (uint32_t)bitfield((uint32_t)msr, 19, 16); + p->CPU.NoThreads = (uint32_t)bitfield((uint32_t)msr, 15, 0); + break; + } - if (p->CPU.NoCores == 0) - { - p->CPU.NoCores = cores_per_package; - p->CPU.NoThreads = logical_per_package; - } - break; + if (p->CPU.NoCores == 0) + { + p->CPU.NoCores = cores_per_package; + p->CPU.NoThreads = logical_per_package; + } - case CPUID_VENDOR_AMD: - p->CPU.NoCores = (uint32_t)bitfield(p->CPU.CPUID[CPUID_88][2], 7, 0) + 1; - p->CPU.NoThreads = (uint32_t)bitfield(p->CPU.CPUID[CPUID_1][1], 23, 16); - if (p->CPU.NoCores == 0) - { - p->CPU.NoCores = 1; - } + // MSR is *NOT* available on the Intel Atom CPU + //workaround for N270. I don't know why it detected wrong + if ((p->CPU.Model == CPUID_MODEL_ATOM) && (strstr(p->CPU.BrandString, "270"))) + { + p->CPU.NoCores = 1; + p->CPU.NoThreads = 2; + } - if (p->CPU.NoThreads < p->CPU.NoCores) - { - p->CPU.NoThreads = p->CPU.NoCores; - } - - break; - - default: - stop("Unsupported CPU detected! System halted."); + //workaround for Quad + if ( strstr(p->CPU.BrandString, "Quad") ) + { + p->CPU.NoCores = 4; + p->CPU.NoThreads = 4; + } } - //workaround for N270. I don't know why it detected wrong - // MSR is *NOT* available on the Intel Atom CPU - if ((p->CPU.Model == CPUID_MODEL_ATOM) && (strstr(p->CPU.BrandString, "270"))) - { - p->CPU.NoCores = 1; - p->CPU.NoThreads = 2; - } - /* setup features */ if ((bit(23) & p->CPU.CPUID[CPUID_1][3]) != 0) { @@ -508,31 +634,23 @@ p->CPU.Features |= CPU_FEATURE_MSR; } - if ((p->CPU.Vendor == CPUID_VENDOR_INTEL) && (p->CPU.NoThreads > p->CPU.NoCores)) + if ((p->CPU.NoThreads > p->CPU.NoCores)) { p->CPU.Features |= CPU_FEATURE_HTT; } - pic0_mask = inb(0x21U); - outb(0x21U, 0xFFU); // mask PIC0 interrupts for duration of timing tests - - tscFrequency = measure_tsc_frequency(); - DBG("cpu freq classic = 0x%016llx\n", tscFrequency); + uint64_t cycles; + cycles = timeRDTSC(); + tscFreq = rtc_set_cyc_per_sec(cycles); + DBG("cpu freq classic = 0x%016llx\n", tscFreq); // if usual method failed - if ( tscFrequency < 1000 ) //TEST + if ( tscFreq < 1000 ) //TEST { - tscFrequency = timeRDTSC() * 20;//measure_tsc_frequency(); + tscFreq = timeRDTSC() * 20;//measure_tsc_frequency(); // DBG("cpu freq timeRDTSC = 0x%016llx\n", tscFrequency); } - else - { - // DBG("cpu freq timeRDTSC = 0x%016llxn", timeRDTSC() * 20); - } - fsbFrequency = 0; - cpuFrequency = 0; - - if (p->CPU.Vendor == CPUID_VENDOR_INTEL && ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0c) || (p->CPU.Family == 0x0f && p->CPU.Model >= 0x03))) + if (IsIntelCPU() && ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0c) || (p->CPU.Family == 0x0f && p->CPU.Model >= 0x03))) { int intelCPU = p->CPU.Model; if (p->CPU.Family == 0x06) @@ -593,7 +711,7 @@ if (bus_ratio_max) { - fsbFrequency = (tscFrequency / bus_ratio_max); + busFrequency = (tscFreq / bus_ratio_max); } //valv: Turbo Ratio Limit @@ -601,12 +719,12 @@ { msr = rdmsr64(MSR_TURBO_RATIO_LIMIT); - cpuFrequency = bus_ratio_max * fsbFrequency; + cpuFrequency = bus_ratio_max * busFrequency; max_ratio = bus_ratio_max * 10; } else { - cpuFrequency = tscFrequency; + cpuFrequency = tscFreq; } if ((getValueForKey(kbusratio, &newratio, &len, &bootInfo->chameleonConfig)) && (len <= 4)) { @@ -622,7 +740,7 @@ // extreme overclockers may love 320 ;) if ((max_ratio >= min_ratio) && (max_ratio <= 320)) { - cpuFrequency = (fsbFrequency * max_ratio) / 10; + cpuFrequency = (busFrequency * max_ratio) / 10; if (len >= 3) { maxdiv = 1; @@ -642,7 +760,7 @@ p->CPU.MaxRatio = max_ratio; p->CPU.MinRatio = min_ratio; - myfsb = fsbFrequency / 1000000; + myfsb = busFrequency / 1000000; verbose("Sticking with [BCLK: %dMhz, Bus-Ratio: %d]\n", myfsb, max_ratio/10); // Bungo: fixed wrong Bus-Ratio readout currcoef = bus_ratio_max; @@ -679,20 +797,20 @@ { if (maxdiv) { - fsbFrequency = ((tscFrequency * 2) / ((maxcoef * 2) + 1)); + busFrequency = ((tscFreq * 2) / ((maxcoef * 2) + 1)); } else { - fsbFrequency = (tscFrequency / maxcoef); + busFrequency = (tscFreq / maxcoef); } if (currdiv) { - cpuFrequency = (fsbFrequency * ((currcoef * 2) + 1) / 2); + cpuFrequency = (busFrequency * ((currcoef * 2) + 1) / 2); } else { - cpuFrequency = (fsbFrequency * currcoef); + cpuFrequency = (busFrequency * currcoef); } DBG("max: %d%s current: %d%s\n", maxcoef, maxdiv ? ".5" : "",currcoef, currdiv ? ".5" : ""); @@ -706,118 +824,251 @@ p->CPU.Features |= CPU_FEATURE_MOBILE; } } - else if ((p->CPU.Vendor == CPUID_VENDOR_AMD) && (p->CPU.Family == 0x0f)) + + else if (IsAmdCPU()) { - switch(p->CPU.ExtFamily) + switch(p->CPU.Family) { - case 0x00: //* K8 *// - msr = rdmsr64(K8_FIDVID_STATUS); - maxcoef = bitfield(msr, 21, 16) / 2 + 4; - currcoef = bitfield(msr, 5, 0) / 2 + 4; + case 0xF: /* K8 */ + { + uint64_t fidvid = 0; + uint64_t cpuMult; + uint64_t fid; + + fidvid = rdmsr64(K8_FIDVID_STATUS); + fid = bitfield(fidvid, 5, 0); + + cpuMult = (fid + 8) / 2; + currcoef = cpuMult; + + cpuMultN2 = (fidvid & (uint64_t)bit(0)); + currdiv = cpuMultN2; + /****** Addon END ******/ + } break; - case 0x01: //* K10 *// - msr = rdmsr64(K10_COFVID_STATUS); - do_cpuid2(0x00000006, 0, p->CPU.CPUID[CPUID_6]); - // EffFreq: effective frequency interface - if (bitfield(p->CPU.CPUID[CPUID_6][2], 0, 0) == 1) + case 0x10: /*** AMD Family 10h ***/ + { + uint64_t cofvid = 0; + uint64_t cpuMult; + uint64_t divisor = 0; + uint64_t did; + uint64_t fid; + + cofvid = rdmsr64(K10_COFVID_STATUS); + did = bitfield(cofvid, 8, 6); + fid = bitfield(cofvid, 5, 0); + if (did == 0) divisor = 2; + else if (did == 1) divisor = 4; + else if (did == 2) divisor = 8; + else if (did == 3) divisor = 16; + else if (did == 4) divisor = 32; + + cpuMult = (fid + 16) / divisor; + currcoef = cpuMult; + + cpuMultN2 = (cofvid & (uint64_t)bit(0)); + currdiv = cpuMultN2; + + /****** Addon END ******/ + } + break; + + case 0x11: /*** AMD Family 11h ***/ + { + uint64_t cofvid = 0; + uint64_t cpuMult; + uint64_t divisor = 0; + uint64_t did; + uint64_t fid; + + cofvid = rdmsr64(K10_COFVID_STATUS); + did = bitfield(cofvid, 8, 6); + fid = bitfield(cofvid, 5, 0); + if (did == 0) divisor = 2; + else if (did == 1) divisor = 4; + else if (did == 2) divisor = 8; + else if (did == 3) divisor = 16; + else if (did == 4) divisor = 32; + + cpuMult = (fid + 8) / divisor; + currcoef = cpuMult; + + cpuMultN2 = (cofvid & (uint64_t)bit(0)); + currdiv = cpuMultN2; + + /****** Addon END ******/ + } + break; + + case 0x12: /*** AMD Family 12h ***/ + { + // 8:4 CpuFid: current CPU core frequency ID + // 3:0 CpuDid: current CPU core divisor ID + uint64_t prfsts,CpuFid,CpuDid; + prfsts = rdmsr64(K10_COFVID_STATUS); + + CpuDid = bitfield(prfsts, 3, 0) ; + CpuFid = bitfield(prfsts, 8, 4) ; + uint64_t divisor; + switch (CpuDid) { - //uint64_t mperf = measure_mperf_frequency(); - uint64_t aperf = measure_aperf_frequency(); - cpuFrequency = aperf; + case 0: divisor = 1; break; + case 1: divisor = (3/2); break; + case 2: divisor = 2; break; + case 3: divisor = 3; break; + case 4: divisor = 4; break; + case 5: divisor = 6; break; + case 6: divisor = 8; break; + case 7: divisor = 12; break; + case 8: divisor = 16; break; + default: divisor = 1; break; } - // NOTE: tsc runs at the maccoeff (non turbo) - // *not* at the turbo frequency. - maxcoef = bitfield(msr, 54, 49) / 2 + 4; - currcoef = bitfield(msr, 5, 0) + 0x10; - currdiv = 2 << bitfield(msr, 8, 6); + currcoef = (CpuFid + 0x10) / divisor; + cpuMultN2 = (prfsts & (uint64_t)bit(0)); + currdiv = cpuMultN2; + + } break; - case 0x05: //* K14 *// - msr = rdmsr64(K10_COFVID_STATUS); - currcoef = (bitfield(msr, 54, 49) + 0x10) << 2; - currdiv = (bitfield(msr, 8, 4) + 1) << 2; + case 0x14: /* K14 */ + + { + // 8:4: current CPU core divisor ID most significant digit + // 3:0: current CPU core divisor ID least significant digit + uint64_t prfsts; + prfsts = rdmsr64(K10_COFVID_STATUS); + + uint64_t CpuDidMSD,CpuDidLSD; + CpuDidMSD = bitfield(prfsts, 8, 4) ; + CpuDidLSD = bitfield(prfsts, 3, 0) ; + + uint64_t frequencyId = 0x10; + currcoef = (frequencyId + 0x10) / + (CpuDidMSD + (CpuDidLSD * 0.25) + 1); + currdiv = ((CpuDidMSD) + 1) << 2; currdiv += bitfield(msr, 3, 0); + cpuMultN2 = (prfsts & (uint64_t)bit(0)); + currdiv = cpuMultN2; + } + break; - case 0x02: //* K11 *// - // not implimented + case 0x15: /*** AMD Family 15h ***/ + case 0x06: /*** AMD Family 06h ***/ + { + + uint64_t cofvid = 0; + uint64_t cpuMult; + uint64_t divisor = 0; + uint64_t did; + uint64_t fid; + + cofvid = rdmsr64(K10_COFVID_STATUS); + did = bitfield(cofvid, 8, 6); + fid = bitfield(cofvid, 5, 0); + if (did == 0) divisor = 2; + else if (did == 1) divisor = 4; + else if (did == 2) divisor = 8; + else if (did == 3) divisor = 16; + else if (did == 4) divisor = 32; + + cpuMult = (fid + 16) / divisor; + currcoef = cpuMult; + + cpuMultN2 = (cofvid & (uint64_t)bit(0)); + currdiv = cpuMultN2; + } break; - } - if (maxcoef) - { - if (currdiv) + case 0x16: /*** AMD Family 16h kabini ***/ { - if (!currcoef) - { - currcoef = maxcoef; - } + uint64_t cofvid = 0; + uint64_t cpuMult; + uint64_t divisor = 0; + uint64_t did; + uint64_t fid; - if (!cpuFrequency) - { - fsbFrequency = ((tscFrequency * currdiv) / currcoef); - } - else - { - fsbFrequency = ((cpuFrequency * currdiv) / currcoef); - } - DBG("%d.%d\n", currcoef / currdiv, ((currcoef % currdiv) * 100) / currdiv); + cofvid = rdmsr64(K10_COFVID_STATUS); + did = bitfield(cofvid, 8, 6); + fid = bitfield(cofvid, 5, 0); + if (did == 0) divisor = 1; + else if (did == 1) divisor = 2; + else if (did == 2) divisor = 4; + else if (did == 3) divisor = 8; + else if (did == 4) divisor = 16; + + cpuMult = (fid + 16) / divisor; + currcoef = cpuMult; + + cpuMultN2 = (cofvid & (uint64_t)bit(0)); + currdiv = cpuMultN2; + /****** Addon END ******/ } - else + break; + + default: { - if (!cpuFrequency) - { - fsbFrequency = (tscFrequency / maxcoef); - } - else - { - fsbFrequency = (cpuFrequency / maxcoef); - } - DBG("%d\n", currcoef); + typedef unsigned long long vlong; + uint64_t prfsts; + prfsts = rdmsr64(K10_COFVID_STATUS); + uint64_t r; + vlong hz; + r = (prfsts>>6) & 0x07; + hz = (((prfsts & 0x3f)+0x10)*100000000ll)/(1<CPU.MaxCoef = maxcoef; - p->CPU.MaxDiv = maxdiv; + p->CPU.MaxCoef = maxcoef = currcoef; + p->CPU.MaxDiv = maxdiv = currdiv; p->CPU.CurrCoef = currcoef; p->CPU.CurrDiv = currdiv; - p->CPU.TSCFrequency = tscFrequency; - p->CPU.FSBFrequency = fsbFrequency; + p->CPU.TSCFrequency = tscFreq; + p->CPU.FSBFrequency = busFrequency; p->CPU.CPUFrequency = cpuFrequency; // keep formatted with spaces instead of tabs Index: trunk/i386/libsaio/platform.h =================================================================== --- trunk/i386/libsaio/platform.h (revision 2646) +++ trunk/i386/libsaio/platform.h (revision 2647) @@ -23,8 +23,11 @@ #define CPUID_6 6 #define CPUID_80 7 #define CPUID_81 8 -#define CPUID_88 9 -#define CPUID_MAX 10 +#define CPUID_85 9 +#define CPUID_86 10 +#define CPUID_87 11 +#define CPUID_88 12 +#define CPUID_MAX 13 #define CPUID_MODEL_ANY 0x00 #define CPUID_MODEL_UNKNOWN 0x01 @@ -77,6 +80,14 @@ #define CPUID_VENDOR_INTEL 0x756E6547 #define CPUID_VENDOR_AMD 0x68747541 + +/* This spells out "GenuineIntel". */ +//#define is_intel \ +// ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69 + /* This spells out "AuthenticAMD". */ +//#define is_amd \ +// ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65 + /* Unknown CPU */ #define CPU_STRING_UNKNOWN "Unknown CPU Type" Index: trunk/i386/libsaio/cpu.h =================================================================== --- trunk/i386/libsaio/cpu.h (revision 2646) +++ trunk/i386/libsaio/cpu.h (revision 2647) @@ -10,6 +10,85 @@ extern void scan_cpu(PlatformInfo_t *); +struct clock_frequency_info_t +{ + unsigned long bus_clock_rate_hz; + unsigned long cpu_clock_rate_hz; + unsigned long dec_clock_rate_hz; + unsigned long bus_clock_rate_num; + unsigned long bus_clock_rate_den; + unsigned long bus_to_cpu_rate_num; + unsigned long bus_to_cpu_rate_den; + unsigned long bus_to_dec_rate_num; + unsigned long bus_to_dec_rate_den; + unsigned long timebase_frequency_hz; + unsigned long timebase_frequency_num; + unsigned long timebase_frequency_den; + unsigned long long bus_frequency_hz; + unsigned long long bus_frequency_min_hz; + unsigned long long bus_frequency_max_hz; + unsigned long long cpu_frequency_hz; + unsigned long long cpu_frequency_min_hz; + unsigned long long cpu_frequency_max_hz; + unsigned long long prf_frequency_hz; + unsigned long long prf_frequency_min_hz; + unsigned long long prf_frequency_max_hz; + unsigned long long mem_frequency_hz; + unsigned long long mem_frequency_min_hz; + unsigned long long mem_frequency_max_hz; + unsigned long long fix_frequency_hz; +}; + +typedef struct clock_frequency_info_t clock_frequency_info_t; + +extern clock_frequency_info_t gPEClockFrequencyInfo; + + +struct mach_timebase_info +{ + uint32_t numer; + uint32_t denom; +}; + +struct hslock +{ + int lock_data; +}; +typedef struct hslock hw_lock_data_t, *hw_lock_t; + +#define hw_lock_addr(hwl) (&((hwl).lock_data)) + +typedef struct uslock_debug +{ + void *lock_pc; /* pc where lock operation began */ + void *lock_thread; /* thread that acquired lock */ + unsigned long duration[2]; + unsigned short state; + unsigned char lock_cpu; + void *unlock_thread; /* last thread to release lock */ + unsigned char unlock_cpu; + void *unlock_pc; /* pc where lock operation ended */ +} uslock_debug; + +typedef struct slock +{ + hw_lock_data_t interlock; /* must be first... see lock.c */ + unsigned short lock_type; /* must be second... see lock.c */ +#define USLOCK_TAG 0x5353 + uslock_debug debug; +} usimple_lock_data_t, *usimple_lock_t; + +#if !defined(decl_simple_lock_data) +typedef usimple_lock_data_t *simple_lock_t; +typedef usimple_lock_data_t simple_lock_data_t; + +#define decl_simple_lock_data(class,name) \ +class simple_lock_data_t name; +#endif /* !defined(decl_simple_lock_data) */ + +typedef struct mach_timebase_info *mach_timebase_info_t; +typedef struct mach_timebase_info mach_timebase_info_data_t; + // DFE: These two constants come from Linux except CLOCK_TICK_RATE replaced with CLKNUM #define CALIBRATE_TIME_MSEC 30 /* 30 msecs */ #define CALIBRATE_LATCH ((CLKNUM * CALIBRATE_TIME_MSEC + 1000/2)/1000) Index: trunk/i386/libsaio/fake_efi.c =================================================================== --- trunk/i386/libsaio/fake_efi.c (revision 2646) +++ trunk/i386/libsaio/fake_efi.c (revision 2647) @@ -79,13 +79,19 @@ } // ========================================================================== -// ErmaC -static inline uint64_t getCPUTick(void) + +EFI_UINT32 getCPUTick(void) { - uint32_t lowest; - uint32_t highest; - __asm__ volatile ("rdtsc" : "=a" (lowest), "=d" (highest)); - return (uint64_t) highest << 32 | lowest; + uint32_t out; + __asm__ volatile ( + "rdtsc\n" + "shl $32,%%edx\n" + "or %%edx,%%eax\n" + : "=a" (out) + : + : "%edx" + ); + return out; } /*========================================================================== Index: trunk/i386/modules/AcpiCodec/acpi_codec.c =================================================================== --- trunk/i386/modules/AcpiCodec/acpi_codec.c (revision 2646) +++ trunk/i386/modules/AcpiCodec/acpi_codec.c (revision 2647) @@ -52,6 +52,52 @@ #include "pci.h" #include "pci_root.h" +boolean_t ForceAmdCpu = false; + +/* For AMD CPU's */ +boolean_t IsAmdCPU(void) +{ + if (ForceAmdCpu) + { + return true; + } + + uint32_t ourcpuid[4]; + do_cpuid(0, ourcpuid); + if ( + /* This spells out "AuthenticAMD". */ + ourcpuid[ebx] == 0x68747541 && // Auth + ourcpuid[ecx] == 0x444D4163 && // cAMD + ourcpuid[edx] == 0x69746E65) // enti + { + return true; + } + + return false; +}; + +/* For Intel CPU's */ +boolean_t IsIntelCPU(void) +{ + uint32_t ourcpuid[4]; + do_cpuid(0, ourcpuid); + if ( + /* This spells out "GenuineIntel". */ + ourcpuid[ebx] == 0x756E6547 && // Genu + ourcpuid[ecx] == 0x6C65746E && // ntel + ourcpuid[edx] == 0x49656E69) // ineI + { + return true; + } + + if (!IsAmdCPU()) + { + return true; + } + + return false; +} + U64 rsd_p; ACPI_TABLES acpi_tables; U32 uuid32; @@ -1005,169 +1051,171 @@ boolean_t fine_grain_clock_mod = 0; #if BUILD_ACPI_TSS || pstate_power_support - if (Platform.CPU.CPUID[CPUID_0][0] >= 0x5) { - /* - * Extract the Monitor/Mwait Leaf info: - */ - sub_Cstates = Platform.CPU.CPUID[CPUID_5][3]; - extensions = Platform.CPU.CPUID[CPUID_5][2]; - } - - if (Platform.CPU.CPUID[CPUID_0][0] >= 6) + if(IsIntelCPU()) { - dynamic_acceleration = bitfield(Platform.CPU.CPUID[CPUID_6][0], 1, 1); // "Dynamic Acceleration Technology (Turbo Mode)" - invariant_APIC_timer = bitfield(Platform.CPU.CPUID[CPUID_6][0], 2, 2); // "Invariant APIC Timer" - fine_grain_clock_mod = bitfield(Platform.CPU.CPUID[CPUID_6][0], 4, 4); - } - cpu->turbo_available = (U32)dynamic_acceleration; + if (Platform.CPU.CPUID[CPUID_0][0] >= 0x5) + { + /* + * Extract the Monitor/Mwait Leaf info: + */ + sub_Cstates = Platform.CPU.CPUID[CPUID_5][3]; + extensions = Platform.CPU.CPUID[CPUID_5][2]; + } - { - U32 temp32 = 0; - U64 temp64= 0; - int tdp; - if (getIntForKey("TDP", &tdp, &bootInfo->chameleonConfig)) + if (Platform.CPU.CPUID[CPUID_0][0] >= 6) { - temp32 = (U32) (tdp*8) ; + dynamic_acceleration = bitfield(Platform.CPU.CPUID[CPUID_6][0], 1, 1); // "Dynamic Acceleration Technology (Turbo Mode)" + invariant_APIC_timer = bitfield(Platform.CPU.CPUID[CPUID_6][0], 2, 2); // "Invariant APIC Timer" + fine_grain_clock_mod = bitfield(Platform.CPU.CPUID[CPUID_6][0], 4, 4); + } + cpu->turbo_available = (U32)dynamic_acceleration; - int tdc; - if (getIntForKey("TDC", &tdc, &bootInfo->chameleonConfig)) + { + U32 temp32 = 0; + U64 temp64= 0; + int tdp; + if (getIntForKey("TDP", &tdp, &bootInfo->chameleonConfig)) { - temp32 = (U32) (temp32) | tdc<<16 ; - + temp32 = (U32) (tdp*8) ; + + int tdc; + if (getIntForKey("TDC", &tdc, &bootInfo->chameleonConfig)) + { + temp32 = (U32) (temp32) | tdc<<16 ; + } + else if (tdp) + { + temp32 = (U32) (temp32) | ((tdp)*8)<<16 ; + } } - else if (tdp) + else if (!is_sandybridge() && !is_jaketown()) { - temp32 = (U32) (temp32) | ((tdp)*8)<<16 ; + if (turbo_enabled && cpu->turbo_available) + { + temp64 = rdmsr64(MSR_TURBO_POWER_CURRENT_LIMIT); + temp32 = (U32)temp64; + } + else + { + // Unfortunately, Intel don't provide a better method for non turbo processors + // and it will give a TDP of 95w (for ex. mine is 65w) , to fix this issue, + // you can set this value by simply adding the option TDP = XX (XX is an integer) + // in your boot.plist + temp32 = (U32)0x02a802f8; + } + } - - } - else if (!is_sandybridge() && !is_jaketown()) - { - if (turbo_enabled && cpu->turbo_available) + if (temp32) { - temp64 = rdmsr64(MSR_TURBO_POWER_CURRENT_LIMIT); - temp32 = (U32)temp64; - } - else - { - // Unfortunately, Intel don't provide a better method for non turbo processors - // and it will give a TDP of 95w (for ex. mine is 65w) , to fix this issue, - // you can set this value by simply adding the option TDP = XX (XX is an integer) - // in your boot.plist - temp32 = (U32)0x02a802f8; + cpu->tdp_limit = ( temp32 & 0x7fff ); + cpu->tdc_limit = ( (temp32 >> 16) & 0x7fff ); } + } - } - if (temp32) - { - cpu->tdp_limit = ( temp32 & 0x7fff ); - cpu->tdc_limit = ( (temp32 >> 16) & 0x7fff ); - } - } - #endif - switch (Platform.CPU.Family) - { - case 0x06: + switch (Platform.CPU.Family) { - switch (Platform.CPU.Model) + case 0x06: { - case CPUID_MODEL_DOTHAN: - case CPUID_MODEL_YONAH: // Yonah - case CPUID_MODEL_MEROM: // Merom - case CPUID_MODEL_PENRYN: // Penryn - case CPUID_MODEL_ATOM: // Intel Atom (45nm) + switch (Platform.CPU.Model) { + case CPUID_MODEL_DOTHAN: + case CPUID_MODEL_YONAH: // Yonah + case CPUID_MODEL_MEROM: // Merom + case CPUID_MODEL_PENRYN: // Penryn + case CPUID_MODEL_ATOM: // Intel Atom (45nm) + { - cpu->core_c1_supported = ((sub_Cstates >> 4) & 0xf) ? 1 : 0; - cpu->core_c4_supported = ((sub_Cstates >> 16) & 0xf) ? 1 : 0; + cpu->core_c1_supported = ((sub_Cstates >> 4) & 0xf) ? 1 : 0; + cpu->core_c4_supported = ((sub_Cstates >> 16) & 0xf) ? 1 : 0; - if (Platform.CPU.Model == CPUID_MODEL_ATOM) - { - cpu->core_c2_supported = cpu->core_c3_supported = ((sub_Cstates >> 8) & 0xf) ? 1 : 0; - cpu->core_c6_supported = ((sub_Cstates >> 12) & 0xf) ? 1 : 0; + if (Platform.CPU.Model == CPUID_MODEL_ATOM) + { + cpu->core_c2_supported = cpu->core_c3_supported = ((sub_Cstates >> 8) & 0xf) ? 1 : 0; + cpu->core_c6_supported = ((sub_Cstates >> 12) & 0xf) ? 1 : 0; - } - else - { - cpu->core_c3_supported = ((sub_Cstates >> 12) & 0xf) ? 1 : 0; - cpu->core_c2_supported = ((sub_Cstates >> 8) & 0xf) ? 1 : 0; - cpu->core_c6_supported = 0; + } + else + { + cpu->core_c3_supported = ((sub_Cstates >> 12) & 0xf) ? 1 : 0; + cpu->core_c2_supported = ((sub_Cstates >> 8) & 0xf) ? 1 : 0; + cpu->core_c6_supported = 0; - } + } - cpu->core_c7_supported = 0; + cpu->core_c7_supported = 0; #if BETA - GetMaxRatio(&cpu->max_ratio_as_mfg); - U64 msr = rdmsr64(MSR_IA32_PERF_STATUS); - U16 idlo = (msr >> 48) & 0xffff; - U16 idhi = (msr >> 32) & 0xffff; - cpu->min_ratio = (U32) (idlo >> 8) & 0xff; - cpu->max_ratio_as_cfg = (U32) (idhi >> 8) & 0xff; + GetMaxRatio(&cpu->max_ratio_as_mfg); + U64 msr = rdmsr64(MSR_IA32_PERF_STATUS); + U16 idlo = (msr >> 48) & 0xffff; + U16 idhi = (msr >> 32) & 0xffff; + cpu->min_ratio = (U32) (idlo >> 8) & 0xff; + cpu->max_ratio_as_cfg = (U32) (idhi >> 8) & 0xff; #else - if (Platform.CPU.MaxCoef) - { - if (Platform.CPU.MaxDiv) + if (Platform.CPU.MaxCoef) { - cpu->max_ratio_as_cfg = cpu->max_ratio_as_mfg = (U32) (Platform.CPU.MaxCoef * 10) + 5; + if (Platform.CPU.MaxDiv) + { + cpu->max_ratio_as_cfg = cpu->max_ratio_as_mfg = (U32) (Platform.CPU.MaxCoef * 10) + 5; + } + else + { + cpu->max_ratio_as_cfg = cpu->max_ratio_as_mfg = (U32) Platform.CPU.MaxCoef * 10; + } } - else - { - cpu->max_ratio_as_cfg = cpu->max_ratio_as_mfg = (U32) Platform.CPU.MaxCoef * 10; - } - } #endif + break; + } + case CPUID_MODEL_FIELDS: + case CPUID_MODEL_DALES: + case CPUID_MODEL_DALES_32NM: + case CPUID_MODEL_NEHALEM: + case CPUID_MODEL_NEHALEM_EX: + case CPUID_MODEL_WESTMERE: + case CPUID_MODEL_WESTMERE_EX: + case CPUID_MODEL_SANDYBRIDGE: + case CPUID_MODEL_JAKETOWN: + { + cpu->core_c1_supported = ((sub_Cstates >> 4) & 0xf) ? 1 : 0; + cpu->core_c3_supported = ((sub_Cstates >> 8) & 0xf) ? 1 : 0; + cpu->core_c6_supported = ((sub_Cstates >> 12) & 0xf) ? 1 : 0; + cpu->core_c7_supported = ((sub_Cstates >> 16) & 0xf) ? 1 : 0; + cpu->core_c2_supported = 0; + cpu->core_c4_supported = 0; - break; - } - case CPUID_MODEL_FIELDS: - case CPUID_MODEL_DALES: - case CPUID_MODEL_DALES_32NM: - case CPUID_MODEL_NEHALEM: - case CPUID_MODEL_NEHALEM_EX: - case CPUID_MODEL_WESTMERE: - case CPUID_MODEL_WESTMERE_EX: - case CPUID_MODEL_SANDYBRIDGE: - case CPUID_MODEL_JAKETOWN: - { + GetMaxRatio(&cpu->max_ratio_as_mfg); + U64 platform_info = rdmsr64(MSR_PLATFORM_INFO); + cpu->max_ratio_as_cfg = (U32) ((U32)platform_info >> 8) & 0xff; + cpu->min_ratio = (U32) ((platform_info >> 40) & 0xff); - cpu->core_c1_supported = ((sub_Cstates >> 4) & 0xf) ? 1 : 0; - cpu->core_c3_supported = ((sub_Cstates >> 8) & 0xf) ? 1 : 0; - cpu->core_c6_supported = ((sub_Cstates >> 12) & 0xf) ? 1 : 0; - cpu->core_c7_supported = ((sub_Cstates >> 16) & 0xf) ? 1 : 0; - cpu->core_c2_supported = 0; - cpu->core_c4_supported = 0; + cpu->tdc_tdp_limits_for_turbo_flag = (platform_info & (1ULL << 29)) ? 1 : 0; + cpu->ratio_limits_for_turbo_flag = (platform_info & (1ULL << 28)) ? 1 : 0; + cpu->xe_available = cpu->tdc_tdp_limits_for_turbo_flag | cpu->ratio_limits_for_turbo_flag; - GetMaxRatio(&cpu->max_ratio_as_mfg); - U64 platform_info = rdmsr64(MSR_PLATFORM_INFO); - cpu->max_ratio_as_cfg = (U32) ((U32)platform_info >> 8) & 0xff; - cpu->min_ratio = (U32) ((platform_info >> 40) & 0xff); - - cpu->tdc_tdp_limits_for_turbo_flag = (platform_info & (1ULL << 29)) ? 1 : 0; - cpu->ratio_limits_for_turbo_flag = (platform_info & (1ULL << 28)) ? 1 : 0; - cpu->xe_available = cpu->tdc_tdp_limits_for_turbo_flag | cpu->ratio_limits_for_turbo_flag; - - - - if (is_sandybridge() || is_jaketown()) - { - cpu->package_power_limit = rdmsr64(MSR_PKG_RAPL_POWER_LIMIT); - cpu->package_power_sku_unit = rdmsr64(MSR_RAPL_POWER_UNIT); + if (is_sandybridge() || is_jaketown()) + { + cpu->package_power_limit = rdmsr64(MSR_PKG_RAPL_POWER_LIMIT); + cpu->package_power_sku_unit = rdmsr64(MSR_RAPL_POWER_UNIT); + } + break; } - break; + default: + verbose ("Unsupported CPU\n"); + return /*(0)*/; + break; } - default: - verbose ("Unsupported CPU\n"); - return /*(0)*/; - break; } + default: + break; } - default: - break; } + else + { + extensions = Platform.CPU.CPUID[CPUID_5][2]; + } cpu->mwait_supported = (extensions & (1UL << 0)) ? 1 : 0; @@ -1193,13 +1241,10 @@ #if BUILD_ACPI_TSS || pstate_power_support if (is_sandybridge() || is_jaketown()) { - printf("package_power_limit : %d\n",cpu->package_power_limit); printf("package_power_sku_unit : %d\n",cpu->package_power_sku_unit); - } #endif - DBG("invariant_apic_timer_flag : %d\n",cpu->invariant_apic_timer_flag); #endif @@ -1325,6 +1370,7 @@ return (0); } + if(IsIntelCPU()) { #if UNUSED struct p_state initial;