Chameleon

Chameleon Svn Source Tree

Root/branches/Bungo/i386/libsaio/cpu.c

1/*
2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*
29 * @OSF_COPYRIGHT@
30 */
31/*
32 * Copyright 2008 Islam Ahmed Zaid. All rights reserved. <azismed@gmail.com>
33 * AsereBLN: 2009: cleanup and bugfix
34 */
35
36#include "libsaio.h"
37#include "platform.h"
38#include "cpu.h"
39#include "bootstruct.h"
40#include "boot.h"
41
42#ifndef DEBUG_CPU
43#define DEBUG_CPU 0
44#endif
45
46#if DEBUG_CPU
47#define DBG(x...)printf(x)
48#else
49#define DBG(x...)msglog(x)
50#endif
51
52/*
53 * timeRDTSC()
54 * This routine sets up PIT counter 2 to count down 1/20 of a second.
55 * It pauses until the value is latched in the counter
56 * and then reads the time stamp counter to return to the caller.
57 */
58uint64_t timeRDTSC(void)
59{
60intattempts = 0;
61uint64_t latchTime;
62uint64_tsaveTime,intermediate;
63unsigned int timerValue, lastValue;
64//boolean_tint_enabled;
65/*
66 * Table of correction factors to account for
67 * - timer counter quantization errors, and
68 * - undercounts 0..5
69 */
70#define SAMPLE_CLKS_EXACT(((double) CLKNUM) / 20.0)
71#define SAMPLE_CLKS_INT((int) CLKNUM / 20)
72#define SAMPLE_NSECS(2000000000LL)
73#define SAMPLE_MULTIPLIER(((double)SAMPLE_NSECS)*SAMPLE_CLKS_EXACT)
74#define ROUND64(x)((uint64_t)((x) + 0.5))
75uint64_tscale[6] = {
76ROUND64(SAMPLE_MULTIPLIER/(double)(SAMPLE_CLKS_INT-0)),
77ROUND64(SAMPLE_MULTIPLIER/(double)(SAMPLE_CLKS_INT-1)),
78ROUND64(SAMPLE_MULTIPLIER/(double)(SAMPLE_CLKS_INT-2)),
79ROUND64(SAMPLE_MULTIPLIER/(double)(SAMPLE_CLKS_INT-3)),
80ROUND64(SAMPLE_MULTIPLIER/(double)(SAMPLE_CLKS_INT-4)),
81ROUND64(SAMPLE_MULTIPLIER/(double)(SAMPLE_CLKS_INT-5))
82};
83
84//int_enabled = ml_set_interrupts_enabled(FALSE);
85
86restart:
87if (attempts >= 9) // increase to up to 9 attempts.
88{
89 // This will flash-reboot. TODO: Use tscPanic instead.
90printf("Timestamp counter calibation failed with %d attempts\n", attempts);
91}
92attempts++;
93enable_PIT2();// turn on PIT2
94set_PIT2(0);// reset timer 2 to be zero
95latchTime = rdtsc64();// get the time stamp to time
96latchTime = get_PIT2(&timerValue) - latchTime; // time how long this takes
97set_PIT2(SAMPLE_CLKS_INT);// set up the timer for (almost) 1/20th a second
98saveTime = rdtsc64();// now time how long a 20th a second is...
99get_PIT2(&lastValue);
100get_PIT2(&lastValue);// read twice, first value may be unreliable
101do {
102intermediate = get_PIT2(&timerValue);
103if (timerValue > lastValue)
104{
105// Timer wrapped
106set_PIT2(0);
107disable_PIT2();
108goto restart;
109}
110lastValue = timerValue;
111} while (timerValue > 5);
112printf("timerValue %d\n",timerValue);
113printf("intermediate 0x%016llX\n",intermediate);
114printf("saveTime 0x%016llX\n",saveTime);
115
116intermediate -= saveTime;// raw count for about 1/20 second
117intermediate *= scale[timerValue];// rescale measured time spent
118intermediate /= SAMPLE_NSECS;// so its exactly 1/20 a second
119intermediate += latchTime;// add on our save fudge
120
121set_PIT2(0);// reset timer 2 to be zero
122disable_PIT2();// turn off PIT 2
123
124//ml_set_interrupts_enabled(int_enabled);
125return intermediate;
126}
127
128/*
129 * DFE: Measures the TSC frequency in Hz (64-bit) using the ACPI PM timer
130 */
131static uint64_t measure_tsc_frequency(void)
132{
133uint64_t tscStart;
134uint64_t tscEnd;
135uint64_t tscDelta = 0xffffffffffffffffULL;
136unsigned long pollCount;
137uint64_t retval = 0;
138int i;
139
140/* Time how many TSC ticks elapse in 30 msec using the 8254 PIT
141 * counter 2. We run this loop 3 times to make sure the cache
142 * is hot and we take the minimum delta from all of the runs.
143 * That is to say that we're biased towards measuring the minimum
144 * number of TSC ticks that occur while waiting for the timer to
145 * expire. That theoretically helps avoid inconsistencies when
146 * running under a VM if the TSC is not virtualized and the host
147 * steals time. The TSC is normally virtualized for VMware.
148 */
149for(i = 0; i < 10; ++i)
150{
151enable_PIT2();
152set_PIT2_mode0(CALIBRATE_LATCH);
153tscStart = rdtsc64();
154pollCount = poll_PIT2_gate();
155tscEnd = rdtsc64();
156/* The poll loop must have run at least a few times for accuracy */
157if (pollCount <= 1) {
158continue;
159}
160/* The TSC must increment at LEAST once every millisecond.
161 * We should have waited exactly 30 msec so the TSC delta should
162 * be >= 30. Anything less and the processor is way too slow.
163 */
164if ((tscEnd - tscStart) <= CALIBRATE_TIME_MSEC) {
165continue;
166}
167// tscDelta = MIN(tscDelta, (tscEnd - tscStart))
168if ( (tscEnd - tscStart) < tscDelta ) {
169tscDelta = tscEnd - tscStart;
170}
171}
172/* tscDelta is now the least number of TSC ticks the processor made in
173 * a timespan of 0.03 s (e.g. 30 milliseconds)
174 * Linux thus divides by 30 which gives the answer in kiloHertz because
175 * 1 / ms = kHz. But we're xnu and most of the rest of the code uses
176 * Hz so we need to convert our milliseconds to seconds. Since we're
177 * dividing by the milliseconds, we simply multiply by 1000.
178 */
179
180/* Unlike linux, we're not limited to 32-bit, but we do need to take care
181 * that we're going to multiply by 1000 first so we do need at least some
182 * arithmetic headroom. For now, 32-bit should be enough.
183 * Also unlike Linux, our compiler can do 64-bit integer arithmetic.
184 */
185if (tscDelta > (1ULL<<32)) {
186retval = 0;
187} else {
188retval = tscDelta * 1000 / 30;
189}
190disable_PIT2();
191return retval;
192}
193
194/*
195 * Original comment/code:
196 * "DFE: Measures the Max Performance Frequency in Hz (64-bit)"
197 *
198 * Measures the Actual Performance Frequency in Hz (64-bit)
199 * (just a naming change, mperf --> aperf )
200 */
201static uint64_t measure_aperf_frequency(void)
202{
203uint64_t aperfStart;
204uint64_t aperfEnd;
205uint64_t aperfDelta = 0xffffffffffffffffULL;
206unsigned long pollCount;
207uint64_t retval = 0;
208int i;
209
210/* Time how many APERF ticks elapse in 30 msec using the 8254 PIT
211 * counter 2. We run this loop 3 times to make sure the cache
212 * is hot and we take the minimum delta from all of the runs.
213 * That is to say that we're biased towards measuring the minimum
214 * number of APERF ticks that occur while waiting for the timer to
215 * expire.
216 */
217for(i = 0; i < 10; ++i)
218{
219enable_PIT2();
220set_PIT2_mode0(CALIBRATE_LATCH);
221aperfStart = rdmsr64(MSR_AMD_APERF);
222pollCount = poll_PIT2_gate();
223aperfEnd = rdmsr64(MSR_AMD_APERF);
224/* The poll loop must have run at least a few times for accuracy */
225if (pollCount <= 1)
226{
227continue;
228}
229/* The TSC must increment at LEAST once every millisecond.
230 * We should have waited exactly 30 msec so the APERF delta should
231 * be >= 30. Anything less and the processor is way too slow.
232 */
233if ((aperfEnd - aperfStart) <= CALIBRATE_TIME_MSEC)
234{
235continue;
236}
237// tscDelta = MIN(tscDelta, (tscEnd - tscStart))
238if ( (aperfEnd - aperfStart) < aperfDelta )
239{
240aperfDelta = aperfEnd - aperfStart;
241}
242}
243/* mperfDelta is now the least number of MPERF ticks the processor made in
244 * a timespan of 0.03 s (e.g. 30 milliseconds)
245 */
246
247if (aperfDelta > (1ULL<<32))
248{
249retval = 0;
250}
251else
252{
253retval = aperfDelta * 1000 / 30;
254}
255disable_PIT2();
256return retval;
257}
258
259/*
260 * Calculates the FSB and CPU frequencies using specific MSRs for each CPU
261 * - multi. is read from a specific MSR. In the case of Intel, there is:
262 * a max multi. (used to calculate the FSB freq.),
263 * and a current multi. (used to calculate the CPU freq.)
264 * - fsbFrequency = tscFrequency / multi
265 * - cpuFrequency = fsbFrequency * multi
266 */
267void scan_cpu(PlatformInfo_t *p)
268{
269uint64_ttscFrequency = 0;
270uint64_tfsbFrequency = 0;
271uint64_tcpuFrequency = 0;
272uint64_tmsr = 0;
273uint64_tflex_ratio = 0;
274
275uint32_tmax_ratio = 0;
276uint32_tmin_ratio = 0;
277uint32_treg[4];
278 uint32_tcores_per_package = 0;
279 uint32_t logical_per_package = 1;
280 uint32_t threads_per_core = 1;;
281
282uint8_tbus_ratio_max = 0;
283uint8_tbus_ratio_min = 0;
284uint8_tcurrdiv = 0;
285uint8_tcurrcoef = 0;
286uint8_tmaxdiv = 0;
287uint8_tmaxcoef = 0;
288
289const char*newratio;
290charstr[128];
291 char *s = 0;
292
293int len = 0;
294int myfsb = 0;
295 int i = 0;
296
297/* get cpuid values */
298do_cpuid(0x00000000, p->CPU.CPUID[CPUID_0]); // MaxFn, Vendor
299 p->CPU.Vendor = p->CPU.CPUID[CPUID_0][ebx];
300
301do_cpuid(0x00000001, p->CPU.CPUID[CPUID_1]); // Signature, stepping, features
302 if ((p->CPU.Vendor == CPUID_VENDOR_INTEL) && ((bit(28) & p->CPU.CPUID[CPUID_1][edx]) != 0)) { // Intel && HTT/Multicore
303 logical_per_package = bitfield(p->CPU.CPUID[CPUID_1][ebx], 23, 16);
304 }
305
306do_cpuid(0x00000002, p->CPU.CPUID[CPUID_2]); // TLB/Cache/Prefetch
307
308do_cpuid(0x00000003, p->CPU.CPUID[CPUID_3]); // S/N
309
310 /* Based on Apple's XNU cpuid.c - Deterministic cache parameters */
311 if ((p->CPU.CPUID[CPUID_0][eax] > 3) && (p->CPU.CPUID[CPUID_0][eax] < 0x80000000)) {
312 for (i = 0; i < 0xFF; i++) { // safe loop
313 do_cpuid2(0x00000004, i, reg); // AX=4: Fn, CX=i: cache index
314 if (bitfield(reg[eax], 4, 0) == 0) break;
315 //cores_per_package = bitfield(reg[eax], 31, 26) + 1;
316 }
317 }
318 do_cpuid2(0x00000004, 0, p->CPU.CPUID[CPUID_4]);
319 if (i > 0) {
320 cores_per_package = bitfield(p->CPU.CPUID[CPUID_4][eax], 31, 26) + 1; // i = cache index
321 threads_per_core = bitfield(p->CPU.CPUID[CPUID_4][eax], 25, 14) + 1;
322 }
323 if (cores_per_package == 0) cores_per_package = 1;
324
325if (p->CPU.CPUID[CPUID_0][0] >= 0x5) { // Monitor/Mwait
326do_cpuid(5, p->CPU.CPUID[CPUID_5]);
327}
328if (p->CPU.CPUID[CPUID_0][0] >= 6) { // Thermal/Power
329do_cpuid(6, p->CPU.CPUID[CPUID_6]);
330}
331
332 do_cpuid(0x80000000, p->CPU.CPUID[CPUID_80]);
333if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 8) {
334do_cpuid(0x80000008, p->CPU.CPUID[CPUID_88]);
335do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]);
336} else if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 1) {
337do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]);
338}
339
340/*
341 EAX (Intel):
342 31 28 27 20 19 16 1514 1312 11 8 7 4 3 0
343 +--------+----------------+--------+----+----+--------+--------+--------+
344 |########|Extended family |Extmodel|####|type|familyid| model |stepping|
345 +--------+----------------+--------+----+----+--------+--------+--------+
346
347 EAX (AMD):
348 31 28 27 20 19 16 1514 1312 11 8 7 4 3 0
349 +--------+----------------+--------+----+----+--------+--------+--------+
350 |########|Extended family |Extmodel|####|####|familyid| model |stepping|
351 +--------+----------------+--------+----+----+--------+--------+--------+
352*/
353p->CPU.Signature= p->CPU.CPUID[CPUID_1][0];
354// stepping = cpu_feat_eax & 0xF;
355p->CPU.Stepping= bitfield(p->CPU.CPUID[CPUID_1][0], 3, 0);
356// model = (cpu_feat_eax >> 4) & 0xF;
357p->CPU.Model= bitfield(p->CPU.CPUID[CPUID_1][0], 7, 4);
358// family = (cpu_feat_eax >> 8) & 0xF;
359p->CPU.Family= bitfield(p->CPU.CPUID[CPUID_1][0], 11, 8);
360// type = (cpu_feat_eax >> 12) & 0x3;
361//p->CPU.Type= bitfield(p->CPU.CPUID[CPUID_1][0], 13, 12);
362// ext_model = (cpu_feat_eax >> 16) & 0xF;
363p->CPU.ExtModel= bitfield(p->CPU.CPUID[CPUID_1][0], 19, 16);
364// ext_family = (cpu_feat_eax >> 20) & 0xFF;
365p->CPU.ExtFamily= bitfield(p->CPU.CPUID[CPUID_1][0], 27, 20);
366/*
367if (p->CPU.Family == 0x0f)
368 p->CPU.Family += p->CPU.ExtFamily;
369 if (p->CPU.Family == 0x0f || p->CPU.Family == 0x06) */
370 p->CPU.Model += (p->CPU.ExtModel << 4);
371
372 /* get BrandString (if supported) */
373/* Copyright: from Apple's XNU cpuid.c */
374if (p->CPU.CPUID[CPUID_80][0] > 0x80000004)
375{
376bzero(str, 128);
377/*
378 * The brand string 48 bytes (max), guaranteed to
379 * be NULL terminated.
380 */
381do_cpuid(0x80000002, reg);
382memcpy(&str[0], (char *)reg, 16);
383do_cpuid(0x80000003, reg);
384memcpy(&str[16], (char *)reg, 16);
385do_cpuid(0x80000004, reg);
386memcpy(&str[32], (char *)reg, 16);
387for (s = str; *s != '\0'; s++)
388{
389if (*s != ' ')
390{
391break;
392}
393}
394strlcpy(p->CPU.BrandString, s, 48);
395
396if (!strncmp(p->CPU.BrandString, CPU_STRING_UNKNOWN, MIN(sizeof(p->CPU.BrandString), (unsigned)strlen(CPU_STRING_UNKNOWN) + 1)))
397{
398/*
399 * This string means we have a firmware-programmable brand string,
400 * and the firmware couldn't figure out what sort of CPU we have.
401 */
402p->CPU.BrandString[0] = '\0';
403}
404p->CPU.BrandString[47] = '\0';
405 //verbose("Brandstring = %s\n", p->CPU.BrandString);
406}
407
408 /*
409 * Find the number of enabled cores and threads
410 * (which determines whether SMT/Hyperthreading is active).
411 */
412 switch (p->CPU.Vendor) {
413 case CPUID_VENDOR_INTEL:
414 switch (p->CPU.Model) {
415 case CPUID_MODEL_NEHALEM:
416 case CPUID_MODEL_FIELDS:
417 case CPUID_MODEL_DALES:
418 case CPUID_MODEL_NEHALEM_EX:
419 case CPUID_MODEL_JAKETOWN:
420 case CPUID_MODEL_SANDYBRIDGE:
421 case CPUID_MODEL_IVYBRIDGE:
422 case CPUID_MODEL_IVYBRIDGE_EP:
423 case CPUID_MODEL_HASWELL:
424 case CPUID_MODEL_HASWELL_SVR:
425 //case CPUID_MODEL_HASWELL_H:
426 case CPUID_MODEL_HASWELL_ULT:
427 case CPUID_MODEL_CRYSTALWELL:
428 msr = rdmsr64(MSR_CORE_THREAD_COUNT);
429 p->CPU.NoCores= (uint32_t)bitfield((uint32_t)msr, 31, 16);
430 p->CPU.NoThreads= (uint32_t)bitfield((uint32_t)msr, 15, 0);
431 break;
432
433 case CPUID_MODEL_DALES_32NM:
434 case CPUID_MODEL_WESTMERE:
435 case CPUID_MODEL_WESTMERE_EX:
436 msr = rdmsr64(MSR_CORE_THREAD_COUNT);
437 p->CPU.NoCores= (uint32_t)bitfield((uint32_t)msr, 19, 16);
438 p->CPU.NoThreads= (uint32_t)bitfield((uint32_t)msr, 15, 0);
439 break;
440 }
441 if (p->CPU.NoCores == 0) {
442 p->CPU.NoCores = cores_per_package;
443 p->CPU.NoThreads = logical_per_package;
444 }
445 break;
446
447 case CPUID_VENDOR_AMD:
448 p->CPU.NoCores= (uint32_t)bitfield(p->CPU.CPUID[CPUID_88][2], 7, 0) + 1;
449 p->CPU.NoThreads= (uint32_t)bitfield(p->CPU.CPUID[CPUID_1][1], 23, 16);
450 if (p->CPU.NoCores == 0) p->CPU.NoCores = 1;
451 if (p->CPU.NoThreads < p->CPU.NoCores) p->CPU.NoThreads = p->CPU.NoCores;
452 break;
453
454 default:
455 stop("Unsupported CPU detected! System halted.");
456}
457
458 //workaround for N270. I don't know why it detected wrong
459 // MSR is *NOT* available on the Intel Atom CPU
460 if ((p->CPU.Model == CPUID_MODEL_ATOM) && (strstr(p->CPU.BrandString, "270"))) {
461 p->CPU.NoCores= 1;
462 p->CPU.NoThreads= 2;
463 }
464
465 /* setup features */
466if ((bit(23) & p->CPU.CPUID[CPUID_1][3]) != 0)
467{
468p->CPU.Features |= CPU_FEATURE_MMX;
469}
470
471if ((bit(25) & p->CPU.CPUID[CPUID_1][3]) != 0)
472{
473p->CPU.Features |= CPU_FEATURE_SSE;
474}
475
476if ((bit(26) & p->CPU.CPUID[CPUID_1][3]) != 0)
477{
478p->CPU.Features |= CPU_FEATURE_SSE2;
479}
480
481if ((bit(0) & p->CPU.CPUID[CPUID_1][2]) != 0)
482{
483p->CPU.Features |= CPU_FEATURE_SSE3;
484}
485
486if ((bit(19) & p->CPU.CPUID[CPUID_1][2]) != 0)
487{
488p->CPU.Features |= CPU_FEATURE_SSE41;
489}
490
491if ((bit(20) & p->CPU.CPUID[CPUID_1][2]) != 0)
492{
493p->CPU.Features |= CPU_FEATURE_SSE42;
494}
495
496if ((bit(29) & p->CPU.CPUID[CPUID_81][3]) != 0)
497{
498p->CPU.Features |= CPU_FEATURE_EM64T;
499}
500
501if ((bit(5) & p->CPU.CPUID[CPUID_1][3]) != 0)
502{
503p->CPU.Features |= CPU_FEATURE_MSR;
504}
505
506 if ((p->CPU.Vendor == CPUID_VENDOR_INTEL) && (p->CPU.NoThreads > p->CPU.NoCores)) {
507p->CPU.Features |= CPU_FEATURE_HTT;
508 }
509
510tscFrequency = measure_tsc_frequency();
511//verbose("cpu freq classic = 0x%016llx\n", tscFrequency);
512
513/* if usual method failed */
514if ( tscFrequency < 1000 )//TEST
515{
516tscFrequency = timeRDTSC() * 20;//measure_tsc_frequency();
517//verbose("cpu freq timeRDTSC = 0x%016llx\n", tscFrequency);
518}
519else
520{
521// verbose("cpu freq timeRDTSC = 0x%016llxn", timeRDTSC() * 20);
522}
523
524fsbFrequency = 0;
525cpuFrequency = 0;
526
527if (p->CPU.Vendor == CPUID_VENDOR_INTEL && ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0c) || (p->CPU.Family == 0x0f && p->CPU.Model >= 0x03)))
528{
529int intelCPU = p->CPU.Model;
530if (p->CPU.Family == 0x06)
531{
532/* Nehalem CPU model */
533switch (p->CPU.Model)
534{
535case CPUID_MODEL_NEHALEM:
536case CPUID_MODEL_FIELDS:
537case CPUID_MODEL_DALES:
538case CPUID_MODEL_DALES_32NM:
539case CPUID_MODEL_WESTMERE:
540case CPUID_MODEL_NEHALEM_EX:
541case CPUID_MODEL_WESTMERE_EX:
542/* --------------------------------------------------------- */
543case CPUID_MODEL_SANDYBRIDGE:
544case CPUID_MODEL_JAKETOWN:
545case CPUID_MODEL_IVYBRIDGE_EP:
546case CPUID_MODEL_IVYBRIDGE:
547case CPUID_MODEL_HASWELL:
548case CPUID_MODEL_HASWELL_SVR:
549
550case CPUID_MODEL_HASWELL_ULT:
551case CPUID_MODEL_CRYSTALWELL:
552/* --------------------------------------------------------- */
553msr = rdmsr64(MSR_PLATFORM_INFO);
554//verbose("msr(%d): platform_info %08x\n", __LINE__, bitfield(msr, 31, 0));
555bus_ratio_max = bitfield(msr, 15, 8);
556bus_ratio_min = bitfield(msr, 47, 40); //valv: not sure about this one (Remarq.1)
557msr = rdmsr64(MSR_FLEX_RATIO);
558//verbose("msr(%d): flex_ratio %08x\n", __LINE__, bitfield(msr, 31, 0));
559if (bitfield(msr, 16, 16)) {
560flex_ratio = bitfield(msr, 15, 8);
561
562// bcc9: at least on the gigabyte h67ma-ud2h,
563// where the cpu multipler can't be changed to
564// allow overclocking, the flex_ratio msr has unexpected (to OSX)
565// contents.These contents cause mach_kernel to
566// fail to compute the bus ratio correctly, instead
567// causing the system to crash since tscGranularity
568// is inadvertently set to 0.
569if (flex_ratio == 0) {
570// Clear bit 16 (evidently the presence bit)
571wrmsr64(MSR_FLEX_RATIO, (msr & 0xFFFFFFFFFFFEFFFFULL));
572msr = rdmsr64(MSR_FLEX_RATIO);
573verbose("CPU: Unusable flex ratio detected. Patched MSR now %08x\n", bitfield(msr, 31, 0));
574} else {
575if (bus_ratio_max > flex_ratio) {
576bus_ratio_max = flex_ratio;
577}
578}
579}
580
581if (bus_ratio_max)
582{
583fsbFrequency = (tscFrequency / bus_ratio_max);
584}
585
586//valv: Turbo Ratio Limit
587if ((intelCPU != 0x2e) && (intelCPU != 0x2f))
588{
589msr = rdmsr64(MSR_TURBO_RATIO_LIMIT);
590cpuFrequency = bus_ratio_max * fsbFrequency;
591max_ratio = bus_ratio_max * 10;
592}
593else
594{
595cpuFrequency = tscFrequency;
596}
597if ((getValueForKey(kbusratio, &newratio, &len, &bootInfo->chameleonConfig)) && (len <= 4))
598{
599max_ratio = atoi(newratio);
600max_ratio = (max_ratio * 10);
601if (len >= 3)
602{
603max_ratio = (max_ratio + 5);
604}
605
606//verbose("Bus-Ratio: min=%d, max=%s\n", bus_ratio_min, newratio);
607
608// extreme overclockers may love 320 ;)
609if ((max_ratio >= min_ratio) && (max_ratio <= 320))
610{
611cpuFrequency = (fsbFrequency * max_ratio) / 10;
612if (len >= 3)
613{
614maxdiv = 1;
615}
616else
617{
618maxdiv = 0;
619}
620}
621else
622{
623max_ratio = (bus_ratio_max * 10);
624}
625}
626//valv: to be uncommented if Remarq.1 didn't stick
627//if (bus_ratio_max > 0) bus_ratio = flex_ratio;
628p->CPU.MaxRatio = max_ratio;
629p->CPU.MinRatio = min_ratio;
630
631myfsb = fsbFrequency / 1000000;
632//verbose("Sticking with [BCLK: %dMhz, Bus-Ratio: %d]\n", myfsb, max_ratio/10); // Bungo: fixed wrong Bus-Ratio readout
633currcoef = bus_ratio_max;
634
635break;
636
637default:
638msr = rdmsr64(MSR_IA32_PERF_STATUS);
639//verbose("msr(%d): ia32_perf_stat 0x%08x\n", __LINE__, bitfield(msr, 31, 0));
640currcoef = bitfield(msr, 12, 8); // Bungo: reverted to 2263 state because of wrong old CPUs freq. calculating
641// Non-integer bus ratio for the max-multi
642maxdiv = bitfield(msr, 46, 46);
643// Non-integer bus ratio for the current-multi (undocumented)
644currdiv = bitfield(msr, 14, 14);
645
646// This will always be model >= 3
647if ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0e) || (p->CPU.Family == 0x0f))
648{
649/* On these models, maxcoef defines TSC freq */
650maxcoef = bitfield(msr, 44, 40);
651}
652else
653{
654/* On lower models, currcoef defines TSC freq */
655/* XXX */
656maxcoef = currcoef;
657}
658
659if (!currcoef)
660{
661currcoef = maxcoef;
662}
663
664if (maxcoef)
665{
666if (maxdiv)
667{
668fsbFrequency = ((tscFrequency * 2) / ((maxcoef * 2) + 1));
669}
670else
671{
672fsbFrequency = (tscFrequency / maxcoef);
673}
674
675if (currdiv)
676{
677cpuFrequency = (fsbFrequency * ((currcoef * 2) + 1) / 2);
678}
679else
680{
681cpuFrequency = (fsbFrequency * currcoef);
682}
683//verbose("max: %d%s current: %d%s\n", maxcoef, maxdiv ? ".5" : "",currcoef, currdiv ? ".5" : "");
684}
685break;
686}
687}
688/* Mobile CPU */
689if (rdmsr64(MSR_IA32_PLATFORM_ID) & (1<<28))
690{
691p->CPU.Features |= CPU_FEATURE_MOBILE;
692}
693}
694else if ((p->CPU.Vendor == CPUID_VENDOR_AMD) && (p->CPU.Family == 0x0f))
695{
696switch(p->CPU.ExtFamily)
697{
698case 0x00: /* K8 */
699msr = rdmsr64(K8_FIDVID_STATUS);
700maxcoef = bitfield(msr, 21, 16) / 2 + 4;
701currcoef = bitfield(msr, 5, 0) / 2 + 4;
702break;
703
704case 0x01: /* K10 */
705msr = rdmsr64(K10_COFVID_STATUS);
706do_cpuid2(0x00000006, 0, p->CPU.CPUID[CPUID_6]);
707// EffFreq: effective frequency interface
708if (bitfield(p->CPU.CPUID[CPUID_6][2], 0, 0) == 1)
709{
710//uint64_t mperf = measure_mperf_frequency();
711uint64_t aperf = measure_aperf_frequency();
712cpuFrequency = aperf;
713}
714// NOTE: tsc runs at the maccoeff (non turbo)
715//*not* at the turbo frequency.
716maxcoef = bitfield(msr, 54, 49) / 2 + 4;
717currcoef = bitfield(msr, 5, 0) + 0x10;
718currdiv = 2 << bitfield(msr, 8, 6);
719
720break;
721
722case 0x05: /* K14 */
723msr = rdmsr64(K10_COFVID_STATUS);
724currcoef = (bitfield(msr, 54, 49) + 0x10) << 2;
725currdiv = (bitfield(msr, 8, 4) + 1) << 2;
726currdiv += bitfield(msr, 3, 0);
727
728break;
729
730case 0x02: /* K11 */
731// not implimented
732break;
733}
734
735if (maxcoef)
736{
737if (currdiv)
738{
739if (!currcoef)
740{
741currcoef = maxcoef;
742}
743
744if (!cpuFrequency)
745{
746fsbFrequency = ((tscFrequency * currdiv) / currcoef);
747}
748else
749{
750fsbFrequency = ((cpuFrequency * currdiv) / currcoef);
751}
752//verbose("%d.%d\n", currcoef / currdiv, ((currcoef % currdiv) * 100) / currdiv);
753} else {
754if (!cpuFrequency) {
755fsbFrequency = (tscFrequency / maxcoef);
756}
757else
758{
759fsbFrequency = (cpuFrequency / maxcoef);
760}
761//verbose("%d\n", currcoef);
762}
763}
764else if (currcoef)
765{
766if (currdiv)
767{
768fsbFrequency = ((tscFrequency * currdiv) / currcoef);
769//verbose("%d.%d\n", currcoef / currdiv, ((currcoef % currdiv) * 100) / currdiv);
770} else {
771fsbFrequency = (tscFrequency / currcoef);
772//verbose("%d\n", currcoef);
773}
774}
775if (!cpuFrequency) cpuFrequency = tscFrequency;
776}
777
778#if 0
779if (!fsbFrequency)
780{
781fsbFrequency = (DEFAULT_FSB * 1000);
782 verbose("CPU: fsbFrequency=0! using the default value for FSB!\n");
783cpuFrequency = tscFrequency;
784}
785
786//verbose("cpu freq = 0x%016llxn", timeRDTSC() * 20);
787
788#endif
789
790p->CPU.MaxCoef = maxcoef;
791p->CPU.MaxDiv = maxdiv;
792p->CPU.CurrCoef = currcoef;
793p->CPU.CurrDiv = currdiv;
794p->CPU.TSCFrequency = tscFrequency;
795p->CPU.FSBFrequency = fsbFrequency;
796p->CPU.CPUFrequency = cpuFrequency;
797
798// keep formatted with spaces instead of tabs
799//verbose("\n---------------------------------------------\n");
800 verbose("\n------------------ CPU INFO -----------------\n");
801//verbose("---------------------------------------------\n");
802 verbose("\nCPUID Raw Values:\n");
803 for (i = 0; i < CPUID_MAX; i++) {
804 verbose("%02d: %08X-%08X-%08X-%08X\n", i, p->CPU.CPUID[i][eax], p->CPU.CPUID[i][ebx], p->CPU.CPUID[i][ecx], p->CPU.CPUID[i][edx]);
805 }
806 verbose("\n");
807verbose("Brand String: %s\n",p->CPU.BrandString); // Processor name (BIOS)
808verbose("Vendor: 0x%X\n",p->CPU.Vendor); // Vendor ex: GenuineIntel
809verbose("Family: 0x%X\n",p->CPU.Family); // Family ex: 6 (06h)
810verbose("ExtFamily: 0x%X\n",p->CPU.ExtFamily);
811verbose("Signature: 0x%08X\n",p->CPU.Signature); // CPUID signature
812verbose("Model: 0x%X\n",p->CPU.Model); // Model ex: 37 (025h)
813verbose("ExtModel: 0x%X\n",p->CPU.ExtModel);
814verbose("Stepping: 0x%X\n",p->CPU.Stepping); // Stepping ex: 5 (05h)
815verbose("MaxCoef: %d\n",p->CPU.MaxCoef);
816verbose("CurrCoef: %d\n",p->CPU.CurrCoef);
817verbose("MaxDiv: %d\n",p->CPU.MaxDiv);
818verbose("CurrDiv: %d\n",p->CPU.CurrDiv);
819verbose("TSCFreq: %dMHz\n",p->CPU.TSCFrequency / 1000000);
820verbose("FSBFreq: %dMHz\n",p->CPU.FSBFrequency / 1000000);
821verbose("CPUFreq: %dMHz\n",p->CPU.CPUFrequency / 1000000);
822verbose("Cores: %d\n",p->CPU.NoCores); // Cores
823 verbose("Logical procesors: %d\n",p->CPU.NoThreads); // Threads
824verbose("Features: 0x%08x\n",p->CPU.Features);
825verbose("---------------------------------------------\n\n");
826#if DEBUG_CPU
827 pause("\n[DEBUG CPU] ");
828#endif
829}
830

Archive Download this file

Revision: 2537