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) {
226continue;
227}
228/* The TSC must increment at LEAST once every millisecond.
229 * We should have waited exactly 30 msec so the APERF delta should
230 * be >= 30. Anything less and the processor is way too slow.
231 */
232if ((aperfEnd - aperfStart) <= CALIBRATE_TIME_MSEC) {
233continue;
234}
235// tscDelta = MIN(tscDelta, (tscEnd - tscStart))
236if ( (aperfEnd - aperfStart) < aperfDelta ) {
237aperfDelta = aperfEnd - aperfStart;
238}
239}
240/* mperfDelta is now the least number of MPERF ticks the processor made in
241 * a timespan of 0.03 s (e.g. 30 milliseconds)
242 */
243
244if (aperfDelta > (1ULL<<32)) {
245retval = 0;
246} else {
247retval = aperfDelta * 1000 / 30;
248}
249disable_PIT2();
250return retval;
251}
252
253/*
254 * Calculates the FSB and CPU frequencies using specific MSRs for each CPU
255 * - multi. is read from a specific MSR. In the case of Intel, there is:
256 * a max multi. (used to calculate the FSB freq.),
257 * and a current multi. (used to calculate the CPU freq.)
258 * - fsbFrequency = tscFrequency / multi
259 * - cpuFrequency = fsbFrequency * multi
260 */
261void scan_cpu(PlatformInfo_t *p)
262{
263uint64_ttscFrequency = 0;
264uint64_tfsbFrequency = 0;
265uint64_tcpuFrequency = 0;
266uint64_tmsr = 0;
267uint64_tflex_ratio = 0;
268
269uint32_tmax_ratio = 0;
270uint32_tmin_ratio = 0;
271uint32_treg[4];
272 uint32_tcores_per_package = 0;
273 uint32_t logical_per_package = 1;
274 uint32_t threads_per_core = 1;;
275
276uint8_tbus_ratio_max = 0;
277uint8_tbus_ratio_min = 0;
278uint8_tcurrdiv = 0;
279uint8_tcurrcoef = 0;
280uint8_tmaxdiv = 0;
281uint8_tmaxcoef = 0;
282
283const char*newratio;
284charstr[128];
285 char *s = 0;
286
287int len = 0;
288int myfsb = 0;
289 int i = 0;
290
291/* get cpuid values */
292do_cpuid(0x00000000, p->CPU.CPUID[CPUID_0]); // MaxFn, Vendor
293 p->CPU.Vendor = p->CPU.CPUID[CPUID_0][ebx];
294
295do_cpuid(0x00000001, p->CPU.CPUID[CPUID_1]); // Signature, stepping, features
296 if ((p->CPU.Vendor == CPUID_VENDOR_INTEL) && ((bit(28) & p->CPU.CPUID[CPUID_1][edx]) != 0)) { // Intel && HTT/Multicore
297 logical_per_package = bitfield(p->CPU.CPUID[CPUID_1][ebx], 23, 16);
298 }
299
300do_cpuid(0x00000002, p->CPU.CPUID[CPUID_2]); // TLB/Cache/Prefetch
301
302do_cpuid(0x00000003, p->CPU.CPUID[CPUID_3]); // S/N
303
304 /* Based on Apple's XNU cpuid.c - Deterministic cache parameters */
305 if ((p->CPU.CPUID[CPUID_0][eax] > 3) && (p->CPU.CPUID[CPUID_0][eax] < 0x80000000)) {
306 for (i = 0; i < 0xFF; i++) { // safe loop
307 do_cpuid2(0x00000004, i, reg); // AX=4: Fn, CX=i: cache index
308 if (bitfield(reg[eax], 4, 0) == 0) break;
309 //cores_per_package = bitfield(reg[eax], 31, 26) + 1;
310 }
311 }
312 do_cpuid2(0x00000004, 0, p->CPU.CPUID[CPUID_4]);
313 if (i > 0) {
314 cores_per_package = bitfield(p->CPU.CPUID[CPUID_4][eax], 31, 26) + 1; // i = cache index
315 threads_per_core = bitfield(p->CPU.CPUID[CPUID_4][eax], 25, 14) + 1;
316 }
317 if (cores_per_package == 0) cores_per_package = 1;
318
319if (p->CPU.CPUID[CPUID_0][0] >= 0x5) { // Monitor/Mwait
320do_cpuid(5, p->CPU.CPUID[CPUID_5]);
321}
322if (p->CPU.CPUID[CPUID_0][0] >= 6) { // Thermal/Power
323do_cpuid(6, p->CPU.CPUID[CPUID_6]);
324}
325
326 do_cpuid(0x80000000, p->CPU.CPUID[CPUID_80]);
327if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 8) {
328do_cpuid(0x80000008, p->CPU.CPUID[CPUID_88]);
329do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]);
330} else if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 1) {
331do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]);
332}
333
334/*
335 EAX (Intel):
336 31 28 27 20 19 16 1514 1312 11 8 7 4 3 0
337 +--------+----------------+--------+----+----+--------+--------+--------+
338 |########|Extended family |Extmodel|####|type|familyid| model |stepping|
339 +--------+----------------+--------+----+----+--------+--------+--------+
340
341 EAX (AMD):
342 31 28 27 20 19 16 1514 1312 11 8 7 4 3 0
343 +--------+----------------+--------+----+----+--------+--------+--------+
344 |########|Extended family |Extmodel|####|####|familyid| model |stepping|
345 +--------+----------------+--------+----+----+--------+--------+--------+
346*/
347p->CPU.Signature= p->CPU.CPUID[CPUID_1][0];
348// stepping = cpu_feat_eax & 0xF;
349p->CPU.Stepping= bitfield(p->CPU.CPUID[CPUID_1][0], 3, 0);
350// model = (cpu_feat_eax >> 4) & 0xF;
351p->CPU.Model= bitfield(p->CPU.CPUID[CPUID_1][0], 7, 4);
352// family = (cpu_feat_eax >> 8) & 0xF;
353p->CPU.Family= bitfield(p->CPU.CPUID[CPUID_1][0], 11, 8);
354// type = (cpu_feat_eax >> 12) & 0x3;
355//p->CPU.Type= bitfield(p->CPU.CPUID[CPUID_1][0], 13, 12);
356// ext_model = (cpu_feat_eax >> 16) & 0xF;
357p->CPU.ExtModel= bitfield(p->CPU.CPUID[CPUID_1][0], 19, 16);
358// ext_family = (cpu_feat_eax >> 20) & 0xFF;
359p->CPU.ExtFamily= bitfield(p->CPU.CPUID[CPUID_1][0], 27, 20);
360/*
361if (p->CPU.Family == 0x0f)
362 p->CPU.Family += p->CPU.ExtFamily;
363 if (p->CPU.Family == 0x0f || p->CPU.Family == 0x06) */
364 p->CPU.Model += (p->CPU.ExtModel << 4);
365
366 /* get BrandString (if supported) */
367/* Copyright: from Apple's XNU cpuid.c */
368if (p->CPU.CPUID[CPUID_80][0] > 0x80000004)
369{
370bzero(str, 128);
371/*
372 * The brand string 48 bytes (max), guaranteed to
373 * be NULL terminated.
374 */
375do_cpuid(0x80000002, reg);
376memcpy(&str[0], (char *)reg, 16);
377do_cpuid(0x80000003, reg);
378memcpy(&str[16], (char *)reg, 16);
379do_cpuid(0x80000004, reg);
380memcpy(&str[32], (char *)reg, 16);
381for (s = str; *s != '\0'; s++)
382{
383if (*s != ' ')
384{
385break;
386}
387}
388strlcpy(p->CPU.BrandString, s, 48);
389
390if (!strncmp(p->CPU.BrandString, CPU_STRING_UNKNOWN, MIN(sizeof(p->CPU.BrandString), (unsigned)strlen(CPU_STRING_UNKNOWN) + 1)))
391{
392/*
393 * This string means we have a firmware-programmable brand string,
394 * and the firmware couldn't figure out what sort of CPU we have.
395 */
396p->CPU.BrandString[0] = '\0';
397}
398p->CPU.BrandString[47] = '\0';
399 //verbose("Brandstring = %s\n", p->CPU.BrandString);
400}
401
402 /*
403 * Find the number of enabled cores and threads
404 * (which determines whether SMT/Hyperthreading is active).
405 */
406 switch (p->CPU.Vendor) {
407 case CPUID_VENDOR_INTEL:
408 switch (p->CPU.Model) {
409 case CPUID_MODEL_NEHALEM:
410 case CPUID_MODEL_FIELDS:
411 case CPUID_MODEL_DALES:
412 case CPUID_MODEL_NEHALEM_EX:
413 case CPUID_MODEL_JAKETOWN:
414 case CPUID_MODEL_SANDYBRIDGE:
415 case CPUID_MODEL_IVYBRIDGE:
416 case CPUID_MODEL_IVYBRIDGE_EP:
417 case CPUID_MODEL_HASWELL:
418 case CPUID_MODEL_HASWELL_SVR:
419 //case CPUID_MODEL_HASWELL_H:
420 case CPUID_MODEL_HASWELL_ULT:
421 case CPUID_MODEL_CRYSTALWELL:
422 msr = rdmsr64(MSR_CORE_THREAD_COUNT);
423 p->CPU.NoCores= (uint32_t)bitfield((uint32_t)msr, 31, 16);
424 p->CPU.NoThreads= (uint32_t)bitfield((uint32_t)msr, 15, 0);
425 break;
426
427 case CPUID_MODEL_DALES_32NM:
428 case CPUID_MODEL_WESTMERE:
429 case CPUID_MODEL_WESTMERE_EX:
430 msr = rdmsr64(MSR_CORE_THREAD_COUNT);
431 p->CPU.NoCores= (uint32_t)bitfield((uint32_t)msr, 19, 16);
432 p->CPU.NoThreads= (uint32_t)bitfield((uint32_t)msr, 15, 0);
433 break;
434 }
435 if (p->CPU.NoCores == 0) {
436 p->CPU.NoCores = cores_per_package;
437 p->CPU.NoThreads = logical_per_package;
438 }
439 break;
440
441 case CPUID_VENDOR_AMD:
442 p->CPU.NoCores= (uint32_t)bitfield(p->CPU.CPUID[CPUID_88][2], 7, 0) + 1;
443 p->CPU.NoThreads= (uint32_t)bitfield(p->CPU.CPUID[CPUID_1][1], 23, 16);
444 if (p->CPU.NoCores == 0) p->CPU.NoCores = 1;
445 if (p->CPU.NoThreads < p->CPU.NoCores) p->CPU.NoThreads = p->CPU.NoCores;
446 break;
447
448 default:
449 stop("Unsupported CPU detected! System halted.");
450}
451
452 //workaround for N270. I don't know why it detected wrong
453 // MSR is *NOT* available on the Intel Atom CPU
454 if ((p->CPU.Model == CPUID_MODEL_ATOM) && (strstr(p->CPU.BrandString, "270"))) {
455 p->CPU.NoCores= 1;
456 p->CPU.NoThreads= 2;
457 }
458
459 /* setup features */
460if ((bit(23) & p->CPU.CPUID[CPUID_1][3]) != 0) {
461p->CPU.Features |= CPU_FEATURE_MMX;
462}
463if ((bit(25) & p->CPU.CPUID[CPUID_1][3]) != 0) {
464p->CPU.Features |= CPU_FEATURE_SSE;
465}
466if ((bit(26) & p->CPU.CPUID[CPUID_1][3]) != 0) {
467p->CPU.Features |= CPU_FEATURE_SSE2;
468}
469if ((bit(0) & p->CPU.CPUID[CPUID_1][2]) != 0) {
470p->CPU.Features |= CPU_FEATURE_SSE3;
471}
472if ((bit(19) & p->CPU.CPUID[CPUID_1][2]) != 0) {
473p->CPU.Features |= CPU_FEATURE_SSE41;
474}
475if ((bit(20) & p->CPU.CPUID[CPUID_1][2]) != 0) {
476p->CPU.Features |= CPU_FEATURE_SSE42;
477}
478if ((bit(29) & p->CPU.CPUID[CPUID_81][3]) != 0) {
479p->CPU.Features |= CPU_FEATURE_EM64T;
480}
481if ((bit(5) & p->CPU.CPUID[CPUID_1][3]) != 0) {
482p->CPU.Features |= CPU_FEATURE_MSR;
483}
484
485 if ((p->CPU.Vendor == CPUID_VENDOR_INTEL) && (p->CPU.NoThreads > p->CPU.NoCores)) {
486p->CPU.Features |= CPU_FEATURE_HTT;
487 }
488
489tscFrequency = measure_tsc_frequency();
490//verbose("cpu freq classic = 0x%016llx\n", tscFrequency);
491
492/* if usual method failed */
493if ( tscFrequency < 1000 )//TEST
494{
495tscFrequency = timeRDTSC() * 20;//measure_tsc_frequency();
496//verbose("cpu freq timeRDTSC = 0x%016llx\n", tscFrequency);
497}
498else
499{
500// verbose("cpu freq timeRDTSC = 0x%016llxn", timeRDTSC() * 20);
501}
502
503fsbFrequency = 0;
504cpuFrequency = 0;
505
506if (p->CPU.Vendor == CPUID_VENDOR_INTEL && ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0c) || (p->CPU.Family == 0x0f && p->CPU.Model >= 0x03)))
507{
508int intelCPU = p->CPU.Model;
509if (p->CPU.Family == 0x06)
510{
511/* Nehalem CPU model */
512switch (p->CPU.Model)
513{
514case CPUID_MODEL_NEHALEM:
515case CPUID_MODEL_FIELDS:
516case CPUID_MODEL_DALES:
517case CPUID_MODEL_DALES_32NM:
518case CPUID_MODEL_WESTMERE:
519case CPUID_MODEL_NEHALEM_EX:
520case CPUID_MODEL_WESTMERE_EX:
521/* --------------------------------------------------------- */
522case CPUID_MODEL_SANDYBRIDGE:
523case CPUID_MODEL_JAKETOWN:
524case CPUID_MODEL_IVYBRIDGE_EP:
525case CPUID_MODEL_IVYBRIDGE:
526case CPUID_MODEL_HASWELL:
527case CPUID_MODEL_HASWELL_SVR:
528
529case CPUID_MODEL_HASWELL_ULT:
530case CPUID_MODEL_CRYSTALWELL:
531/* --------------------------------------------------------- */
532msr = rdmsr64(MSR_PLATFORM_INFO);
533//verbose("msr(%d): platform_info %08x\n", __LINE__, bitfield(msr, 31, 0));
534bus_ratio_max = bitfield(msr, 15, 8);
535bus_ratio_min = bitfield(msr, 47, 40); //valv: not sure about this one (Remarq.1)
536msr = rdmsr64(MSR_FLEX_RATIO);
537//verbose("msr(%d): flex_ratio %08x\n", __LINE__, bitfield(msr, 31, 0));
538if (bitfield(msr, 16, 16)) {
539flex_ratio = bitfield(msr, 15, 8);
540
541// bcc9: at least on the gigabyte h67ma-ud2h,
542// where the cpu multipler can't be changed to
543// allow overclocking, the flex_ratio msr has unexpected (to OSX)
544// contents.These contents cause mach_kernel to
545// fail to compute the bus ratio correctly, instead
546// causing the system to crash since tscGranularity
547// is inadvertently set to 0.
548if (flex_ratio == 0) {
549// Clear bit 16 (evidently the presence bit)
550wrmsr64(MSR_FLEX_RATIO, (msr & 0xFFFFFFFFFFFEFFFFULL));
551msr = rdmsr64(MSR_FLEX_RATIO);
552verbose("CPU: Unusable flex ratio detected. Patched MSR now %08x\n", bitfield(msr, 31, 0));
553} else {
554if (bus_ratio_max > flex_ratio) {
555bus_ratio_max = flex_ratio;
556}
557}
558}
559
560if (bus_ratio_max) {
561fsbFrequency = (tscFrequency / bus_ratio_max);
562}
563
564//valv: Turbo Ratio Limit
565if ((intelCPU != 0x2e) && (intelCPU != 0x2f)) {
566msr = rdmsr64(MSR_TURBO_RATIO_LIMIT);
567cpuFrequency = bus_ratio_max * fsbFrequency;
568max_ratio = bus_ratio_max * 10;
569} else {
570cpuFrequency = tscFrequency;
571}
572if ((getValueForKey(kbusratio, &newratio, &len, &bootInfo->chameleonConfig)) && (len <= 4)) {
573max_ratio = atoi(newratio);
574max_ratio = (max_ratio * 10);
575if (len >= 3) {
576max_ratio = (max_ratio + 5);
577}
578
579//verbose("Bus-Ratio: min=%d, max=%s\n", bus_ratio_min, newratio);
580
581// extreme overclockers may love 320 ;)
582if ((max_ratio >= min_ratio) && (max_ratio <= 320)) {
583cpuFrequency = (fsbFrequency * max_ratio) / 10;
584if (len >= 3) {
585maxdiv = 1;
586} else {
587maxdiv = 0;
588}
589} else {
590max_ratio = (bus_ratio_max * 10);
591}
592}
593//valv: to be uncommented if Remarq.1 didn't stick
594//if (bus_ratio_max > 0) bus_ratio = flex_ratio;
595p->CPU.MaxRatio = max_ratio;
596p->CPU.MinRatio = min_ratio;
597
598myfsb = fsbFrequency / 1000000;
599//verbose("Sticking with [BCLK: %dMhz, Bus-Ratio: %d]\n", myfsb, max_ratio/10); // Bungo: fixed wrong Bus-Ratio readout
600currcoef = bus_ratio_max;
601
602break;
603
604default:
605msr = rdmsr64(MSR_IA32_PERF_STATUS);
606//verbose("msr(%d): ia32_perf_stat 0x%08x\n", __LINE__, bitfield(msr, 31, 0));
607currcoef = bitfield(msr, 12, 8); // Bungo: reverted to 2263 state because of wrong old CPUs freq. calculating
608// Non-integer bus ratio for the max-multi
609maxdiv = bitfield(msr, 46, 46);
610// Non-integer bus ratio for the current-multi (undocumented)
611currdiv = bitfield(msr, 14, 14);
612
613// This will always be model >= 3
614if ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0e) || (p->CPU.Family == 0x0f)) {
615/* On these models, maxcoef defines TSC freq */
616maxcoef = bitfield(msr, 44, 40);
617} else {
618// On lower models, currcoef defines TSC freq
619// XXX
620maxcoef = currcoef;
621}
622
623if (!currcoef)
624{
625currcoef = maxcoef;
626}
627
628if (maxcoef)
629{
630if (maxdiv)
631{
632fsbFrequency = ((tscFrequency * 2) / ((maxcoef * 2) + 1));
633} else {
634fsbFrequency = (tscFrequency / maxcoef);
635}
636if (currdiv) {
637cpuFrequency = (fsbFrequency * ((currcoef * 2) + 1) / 2);
638} else {
639cpuFrequency = (fsbFrequency * currcoef);
640}
641//verbose("max: %d%s current: %d%s\n", maxcoef, maxdiv ? ".5" : "",currcoef, currdiv ? ".5" : "");
642}
643break;
644}
645}
646// Mobile CPU
647if (rdmsr64(MSR_IA32_PLATFORM_ID) & (1<<28)) {
648p->CPU.Features |= CPU_FEATURE_MOBILE;
649}
650} else if ((p->CPU.Vendor == CPUID_VENDOR_AMD) && (p->CPU.Family == 0x0f)) {
651switch(p->CPU.ExtFamily) {
652case 0x00: //* K8 *//
653msr = rdmsr64(K8_FIDVID_STATUS);
654maxcoef = bitfield(msr, 21, 16) / 2 + 4;
655currcoef = bitfield(msr, 5, 0) / 2 + 4;
656break;
657
658case 0x01: //* K10 *//
659msr = rdmsr64(K10_COFVID_STATUS);
660do_cpuid2(0x00000006, 0, p->CPU.CPUID[CPUID_6]);
661// EffFreq: effective frequency interface
662if (bitfield(p->CPU.CPUID[CPUID_6][2], 0, 0) == 1) {
663//uint64_t mperf = measure_mperf_frequency();
664uint64_t aperf = measure_aperf_frequency();
665cpuFrequency = aperf;
666}
667// NOTE: tsc runs at the maccoeff (non turbo)
668//*not* at the turbo frequency.
669maxcoef = bitfield(msr, 54, 49) / 2 + 4;
670currcoef = bitfield(msr, 5, 0) + 0x10;
671currdiv = 2 << bitfield(msr, 8, 6);
672
673break;
674
675case 0x05: //* K14 *//
676msr = rdmsr64(K10_COFVID_STATUS);
677currcoef = (bitfield(msr, 54, 49) + 0x10) << 2;
678currdiv = (bitfield(msr, 8, 4) + 1) << 2;
679currdiv += bitfield(msr, 3, 0);
680
681break;
682
683case 0x02: //* K11 *//
684// not implimented
685break;
686}
687
688if (maxcoef) {
689if (currdiv) {
690if (!currcoef) {
691currcoef = maxcoef;
692}
693
694if (!cpuFrequency) {
695fsbFrequency = ((tscFrequency * currdiv) / currcoef);
696} else {
697fsbFrequency = ((cpuFrequency * currdiv) / currcoef);
698}
699//verbose("%d.%d\n", currcoef / currdiv, ((currcoef % currdiv) * 100) / currdiv);
700} else {
701if (!cpuFrequency) {
702fsbFrequency = (tscFrequency / maxcoef);
703} else {
704fsbFrequency = (cpuFrequency / maxcoef);
705}
706//verbose("%d\n", currcoef);
707}
708} else if (currcoef) {
709if (currdiv) {
710fsbFrequency = ((tscFrequency * currdiv) / currcoef);
711//verbose("%d.%d\n", currcoef / currdiv, ((currcoef % currdiv) * 100) / currdiv);
712} else {
713fsbFrequency = (tscFrequency / currcoef);
714//verbose("%d\n", currcoef);
715}
716}
717if (!cpuFrequency) cpuFrequency = tscFrequency;
718}
719
720#if 0
721if (!fsbFrequency) {
722fsbFrequency = (DEFAULT_FSB * 1000);
723 verbose("CPU: fsbFrequency=0! using the default value for FSB!\n");
724cpuFrequency = tscFrequency;
725}
726
727//verbose("cpu freq = 0x%016llxn", timeRDTSC() * 20);
728
729#endif
730
731p->CPU.MaxCoef = maxcoef;
732p->CPU.MaxDiv = maxdiv;
733p->CPU.CurrCoef = currcoef;
734p->CPU.CurrDiv = currdiv;
735p->CPU.TSCFrequency = tscFrequency;
736p->CPU.FSBFrequency = fsbFrequency;
737p->CPU.CPUFrequency = cpuFrequency;
738
739// keep formatted with spaces instead of tabs
740//verbose("\n---------------------------------------------\n");
741 verbose("\n------------------ CPU INFO -----------------\n");
742//verbose("---------------------------------------------\n");
743 verbose("\nCPUID Raw Values:\n");
744 for (i = 0; i < CPUID_MAX; i++) {
745 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]);
746 }
747 verbose("\n");
748verbose("Brand String: %s\n",p->CPU.BrandString); // Processor name (BIOS)
749verbose("Vendor: 0x%X\n",p->CPU.Vendor); // Vendor ex: GenuineIntel
750verbose("Family: 0x%X\n",p->CPU.Family); // Family ex: 6 (06h)
751verbose("ExtFamily: 0x%X\n",p->CPU.ExtFamily);
752verbose("Signature: 0x%08X\n",p->CPU.Signature); // CPUID signature
753verbose("Model: 0x%X\n",p->CPU.Model); // Model ex: 37 (025h)
754verbose("ExtModel: 0x%X\n",p->CPU.ExtModel);
755verbose("Stepping: 0x%X\n",p->CPU.Stepping); // Stepping ex: 5 (05h)
756verbose("MaxCoef: %d\n",p->CPU.MaxCoef);
757verbose("CurrCoef: %d\n",p->CPU.CurrCoef);
758verbose("MaxDiv: %d\n",p->CPU.MaxDiv);
759verbose("CurrDiv: %d\n",p->CPU.CurrDiv);
760verbose("TSCFreq: %dMHz\n",p->CPU.TSCFrequency / 1000000);
761verbose("FSBFreq: %dMHz\n",p->CPU.FSBFrequency / 1000000);
762verbose("CPUFreq: %dMHz\n",p->CPU.CPUFrequency / 1000000);
763verbose("Cores: %d\n",p->CPU.NoCores); // Cores
764 verbose("Logical procesors: %d\n",p->CPU.NoThreads); // Threads
765verbose("Features: 0x%08x\n",p->CPU.Features);
766verbose("---------------------------------------------\n\n");
767#if DEBUG_CPU
768 pause("\n[DEBUG CPU] ");
769#endif
770}
771

Archive Download this file

Revision: 2531