Chameleon

Chameleon Commit Details

Date:2012-05-03 17:39:07 (11 years 11 months ago)
Author:MacMan
Commit:1930
Parents: 1929
Message:Chimera 1.9.2 changes: Fixed CPU processor speed detection on SandyBridge family CPUs. Fixed invalid FSB speed reported on SandyBridge family CPUs. Fixed reporting of P-States: minimum and maximum on SandyBridge family CPUs. Improved bdmesg output. Added 7 Series and X79 SMbus controller device ids.
Changes:
M/branches/Chimera/i386/libsaio/cpu.c
M/branches/Chimera/i386/libsaio/platform.h
M/branches/Chimera/i386/libsaio/smbios_getters.c
M/branches/Chimera/version
M/branches/Chimera/i386/libsaio/cpu.h
M/branches/Chimera/i386/libsaio/smbios.c
M/branches/Chimera/i386/libsaio/acpi_patcher.c
M/branches/Chimera/i386/libsaio/spd.c

File differences

branches/Chimera/version
1
1
1.9.1
1.9.2
branches/Chimera/i386/libsaio/acpi_patcher.c
426426
427427
428428
429
429
430
430431
431432
432433
......
563564
564565
565566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
566595
567596
568597
569598
570
599
600
601
602
571603
572604
573
605
574606
575607
576608
......
591623
592624
593625
594
626
595627
596628
597629
......
781813
782814
783815
816
817
818
784819
785820
786821
if (acpi_cpu_count > 0)
{
struct p_state initial, maximum, minimum, p_states[32];
uint8_t p_states_count = 0;
uint8_t p_states_count = 0;
uint64_t msr = 0;
// Retrieving P-States, ported from code by superhai (c)
switch (Platform.CPU.Family) {
case CPU_MODEL_NEHALEM_EX:// Intel Xeon X75xx, Xeon X65xx, Xeon E75xx, Xeon E65xx
case CPU_MODEL_WESTMERE:// Intel Core i7, Xeon X56xx, Xeon E56xx, Xeon W36xx LGA1366 (32nm) 6 Core
case CPU_MODEL_WESTMERE_EX:// Intel Xeon E7
{
maximum.Control = rdmsr64(MSR_IA32_PERF_STATUS) & 0xff; // Seems it always contains maximum multiplier value (with turbo, that's we need)...
minimum.Control = (rdmsr64(MSR_PLATFORM_INFO) >> 40) & 0xff;
verbose("P-States: min %d, max %d\n", minimum.Control, maximum.Control);
// Sanity check
if (maximum.Control < minimum.Control)
{
DBG("Insane control values!");
p_states_count = 0;
}
else
{
uint8_t i;
p_states_count = 0;
for (i = maximum.Control; i >= minimum.Control; i--)
{
p_states[p_states_count].Control = i;
p_states[p_states_count].CID = p_states[p_states_count].Control << 1;
p_states[p_states_count].Frequency = (Platform.CPU.FSBFrequency / 1000000) * i;
p_states_count++;
}
}
verbose("Number of P-States Generated: %d\n", p_states_count);
break;
}
case CPU_MODEL_SANDYBRIDGE:// Intel Core i3, i5, i7 LGA1155 (32nm)
case CPU_MODEL_IVYBRIDGE:// Intel Core i3, i5, i7 LGA1155 (22nm)
case CPU_MODEL_JAKETOWN:// Intel Core i7, Xeon E5 LGA2011 (32nm)
{
maximum.Control = rdmsr64(MSR_IA32_PERF_STATUS) & 0xff; // Seems it always contains maximum multiplier value (with turbo, that's we need)...
msr = rdmsr64(MSR_IA32_PERF_STATUS);
initial.Control = bitfield(msr, 15, 8);
msr = rdmsr64(MSR_IA32_PERF_STATUS);
maximum.Control = bitfield(msr, 15, 8);
minimum.Control = (rdmsr64(MSR_PLATFORM_INFO) >> 40) & 0xff;
verbose("P-States: min 0x%x, max 0x%x\n", minimum.Control, maximum.Control);
verbose("P-States: min %d, max %d\n", minimum.Control, maximum.Control);
// Sanity check
if (maximum.Control < minimum.Control)
p_states_count++;
}
}
verbose("Number of P-States Generated: %d\n", p_states_count);
break;
}
default:
const char *filename;
char dirSpec[128];
int len = 0;
// always reset cpu count to 0 when injecting new acpi
acpi_cpu_count = 0;
// Try using the file specified with the DSDT option
if (getValueForKey(kDSDT, &filename, &len, &bootInfo->chameleonConfig))
branches/Chimera/i386/libsaio/spd.c
373373
374374
375375
376
377
376378
377379
378380
{0x8086, 0x3A60, "ICH10B",read_smb_intel },
{0x8086, 0x3B30, "5 Series",read_smb_intel },
{0x8086, 0x1C22, "6 Series",read_smb_intel },
{0x8086, 0x1E22, "7 Series",read_smb_intel },
{0x8086, 0x1D70, "X79",read_smb_intel },
{0x8086, 0x5032, "EP80579",read_smb_intel }
};
branches/Chimera/i386/libsaio/cpu.c
150150
151151
152152
153
154
155
153
154
155
156
157
158
159
160
161
162
163
164
165
166
156167
157
158
159
168
160169
161
162
163
164170
165171
166172
......
281287
282288
283289
284
285
286290
287291
288292
......
299303
300304
301305
302
303
304
306
307
308
305309
306
310
307311
308
309
310
311
312
313
314
315
316
312
317313
318314
319315
320316
321
317
322318
323319
324320
......
329325
330326
331327
332
333
334
335
336
337
338
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
339357
358
340359
341360
342361
343362
344363
345
364
346365
347366
348367
......
353372
354373
355374
356
357
358
359
375
376
377
360378
361
362
363
364379
365380
366
381
367382
368383
369384
......
484499
485500
486501
487
502
503
504
505
506
507
488508
489
509
510
511
512
513
514
490515
491516
492517
493518
494519
495
496
497
498
499
500
501
502
503
504
505
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
506537
507538
508539
*/
void scan_cpu(PlatformInfo_t *p)
{
uint64_ttscFrequency, fsbFrequency, cpuFrequency;
uint64_tmsr, flex_ratio;
uint8_tmaxcoef, maxdiv, currcoef, bus_ratio_max, currdiv;
uint64_ttscFrequency = 0;
uint64_tfsbFrequency = 0;
uint64_tcpuFrequency =0;
uint64_tmsr = 0;
uint64_tflex_ratio = 0;
uint32_tmax_ratio = 0;
uint32_tmin_ratio = 0;
uint8_tbus_ratio_max = 0;
uint8_tbus_ratio_min = 0;
uint8_tcurrdiv = 0;
uint8_tcurrcoef = 0;
uint8_tmaxdiv = 0;
uint8_tmaxcoef = 0;
const char*newratio;
intlen, myfsb;
uint8_tbus_ratio_min;
uint32_tmax_ratio, min_ratio;
intlen = 0;
max_ratio = min_ratio = myfsb = bus_ratio_min = 0;
maxcoef = maxdiv = bus_ratio_max = currcoef = currdiv = 0;
/* get cpuid values */
do_cpuid(0x00000000, p->CPU.CPUID[CPUID_0]);
do_cpuid(0x00000001, p->CPU.CPUID[CPUID_1]);
}
tscFrequency = measure_tsc_frequency();
fsbFrequency = 0;
cpuFrequency = 0;
if ((p->CPU.Vendor == CPUID_VENDOR_INTEL) && ((p->CPU.Family == 0x06) || (p->CPU.Family == 0x0f))) {
int intelCPU = p->CPU.Model;
p->CPU.Model == CPU_MODEL_JAKETOWN||
p->CPU.Model == CPU_MODEL_IVYBRIDGE)) {
msr = rdmsr64(MSR_PLATFORM_INFO);
DBG("msr(%d): platform_info %08x\n", __LINE__, bitfield(msr, 31, 0));
bus_ratio_max = bitfield(msr, 14, 8);
bus_ratio_min = bitfield(msr, 46, 40); //valv: not sure about this one (Remarq.1)
//DBG("MSR_PLATFORM_INFO: 0x%x\n", bitfield(msr, 63, 0));
bus_ratio_max = bitfield(msr, 15, 8);//MacMan: Changed bitfield to match Apple tsc.c
bus_ratio_min = bitfield(msr, 47, 40);//MacMan: Changed bitfield to match Apple tsc.c
msr = rdmsr64(MSR_FLEX_RATIO);
DBG("msr(%d): flex_ratio %08x\n", __LINE__, bitfield(msr, 31, 0));
//DBG("MSR_FLEX_RATIO: 0x%x\n", bitfield(msr, 31, 0));
if (bitfield(msr, 16, 16)) {
flex_ratio = bitfield(msr, 14, 8);
/* bcc9: at least on the gigabyte h67ma-ud2h,
where the cpu multipler can't be changed to
allow overclocking, the flex_ratio msr has unexpected (to OSX)
contents.These contents cause mach_kernel to
fail to compute the bus ratio correctly, instead
causing the system to crash since tscGranularity
is inadvertently set to 0.
*/
flex_ratio = bitfield(msr, 15, 8);//MacMan: Changed bitfield to match Apple tsc.c
if (flex_ratio == 0) {
/* Clear bit 16 (evidently the presence bit) */
wrmsr64(MSR_FLEX_RATIO, (msr & 0xFFFFFFFFFFFEFFFFULL));
msr = rdmsr64(MSR_FLEX_RATIO);
verbose("Unusable flex ratio detected. Patched MSR now %08x\n", bitfield(msr, 31, 0));
//DBG("Null flex ratio detected. MSR_FLEX_RATIO now: %08x\n", bitfield(msr, 31, 0));
} else {
if (bus_ratio_max > flex_ratio) {
bus_ratio_max = flex_ratio;
if (bus_ratio_max) {
fsbFrequency = (tscFrequency / bus_ratio_max);
}
//valv: Turbo Ratio Limit
if ((intelCPU != 0x2e) && (intelCPU != 0x2f)) {
msr = rdmsr64(MSR_TURBO_RATIO_LIMIT);
cpuFrequency = bus_ratio_max * fsbFrequency;
max_ratio = bus_ratio_max * 10;
} else {
cpuFrequency = tscFrequency;
//MacMan: Turbo Ratio Limit
switch (intelCPU)
{
case CPU_MODEL_WESTMERE_EX:// Intel Xeon E7
case CPU_MODEL_NEHALEM_EX:// Intel Xeon X75xx, Xeon X65xx, Xeon E75xx, Xeon E65xx
{
cpuFrequency = tscFrequency;
DBG("cpu.c (%d)CPU_MODEL_NEHALEM_EX or CPU_MODEL_WESTMERE_EX Found\n", __LINE__);
break;
}
case CPU_MODEL_SANDYBRIDGE:// Intel Core i3, i5, i7 LGA1155 (32nm)
case CPU_MODEL_IVYBRIDGE:// Intel Core i3, i5, i7 LGA1155 (22nm)
case CPU_MODEL_JAKETOWN:// Intel Core i7, Xeon E5 LGA2011 (32nm)
{
msr = rdmsr64(MSR_IA32_PERF_STATUS);
currcoef = bitfield(msr, 15, 8);
cpuFrequency = currcoef * fsbFrequency;
maxcoef = bus_ratio_max;
break;
}
default:
{
msr = rdmsr64(MSR_IA32_PERF_STATUS);
currcoef = bitfield(msr, 7, 0);
cpuFrequency = currcoef * fsbFrequency;
maxcoef = bus_ratio_max;
break;
}
}
if ((getValueForKey(kbusratio, &newratio, &len, &bootInfo->chameleonConfig)) && (len <= 4)) {
max_ratio = atoi(newratio);
max_ratio = (max_ratio * 10);
if (len >= 3) max_ratio = (max_ratio + 5);
verbose("Bus-Ratio: min=%d, max=%s\n", bus_ratio_min, newratio);
DBG("Bus-Ratio: min=%d, max=%s\n", bus_ratio_min, newratio);
// extreme overclockers may love 320 ;)
if ((max_ratio >= min_ratio) && (max_ratio <= 320)) {
max_ratio = (bus_ratio_max * 10);
}
}
//valv: to be uncommented if Remarq.1 didn't stick
/*if (bus_ratio_max > 0) bus_ratio = flex_ratio;*/
p->CPU.MaxRatio = max_ratio;
p->CPU.MinRatio = min_ratio;
p->CPU.MaxRatio = bus_ratio_max;
p->CPU.MinRatio = bus_ratio_min;
myfsb = fsbFrequency / 1000000;
verbose("Sticking with [BCLK: %dMhz, Bus-Ratio: %d]\n", myfsb, max_ratio);
currcoef = bus_ratio_max;
} else {
msr = rdmsr64(MSR_IA32_PERF_STATUS);
DBG("msr(%d): ia32_perf_stat 0x%08x\n", __LINE__, bitfield(msr, 31, 0));
DBG("MSR_IA32_PERF_STATUS: 0x%08x\n", bitfield(msr, 31, 0));
currcoef = bitfield(msr, 12, 8);
/* Non-integer bus ratio for the max-multi*/
maxdiv = bitfield(msr, 46, 46);
#endif
p->CPU.MaxCoef = maxcoef;
p->CPU.MaxDiv = maxdiv;
if (maxdiv == 0){
p->CPU.MaxDiv = bus_ratio_max;
}
else {
p->CPU.MaxDiv = maxdiv;
}
p->CPU.CurrCoef = currcoef;
p->CPU.CurrDiv = currdiv;
if (currdiv == 0){
p->CPU.CurrDiv = currcoef;
}
else {
p->CPU.CurrDiv = currdiv;
}
p->CPU.TSCFrequency = tscFrequency;
p->CPU.FSBFrequency = fsbFrequency;
p->CPU.CPUFrequency = cpuFrequency;
// keep formatted with spaces instead of tabs
DBG("CPU: Brand String: %s\n", p->CPU.BrandString);
DBG("CPU: Vendor/Family/ExtFamily: 0x%x/0x%x/0x%x\n", p->CPU.Vendor, p->CPU.Family, p->CPU.ExtFamily);
DBG("CPU: Model/ExtModel/Stepping: 0x%x/0x%x/0x%x\n", p->CPU.Model, p->CPU.ExtModel, p->CPU.Stepping);
DBG("CPU: MaxCoef/CurrCoef: 0x%x/0x%x\n", p->CPU.MaxCoef, p->CPU.CurrCoef);
DBG("CPU: MaxDiv/CurrDiv: 0x%x/0x%x\n", p->CPU.MaxDiv, p->CPU.CurrDiv);
DBG("CPU: TSCFreq: %dMHz\n", p->CPU.TSCFrequency / 1000000);
DBG("CPU: FSBFreq: %dMHz\n", p->CPU.FSBFrequency / 1000000);
DBG("CPU: CPUFreq: %dMHz\n", p->CPU.CPUFrequency / 1000000);
DBG("CPU: NoCores/NoThreads: %d/%d\n", p->CPU.NoCores, p->CPU.NoThreads);
DBG("CPU: Features: 0x%08x\n", p->CPU.Features);
#if DEBUG_CPU
DBG("CPU: Brand String: %s\n", p->CPU.BrandString);
DBG("CPU: Vendor: 0x%x\n", p->CPU.Vendor);
DBG("CPU: Family / ExtFamily: 0x%x / 0x%x\n", p->CPU.Family, p->CPU.ExtFamily);
DBG("CPU: Model / ExtModel / Stepping: 0x%x / 0x%x / 0x%x\n", p->CPU.Model, p->CPU.ExtModel, p->CPU.Stepping);
DBG("CPU: Number of Cores / Threads: %d / %d\n", p->CPU.NoCores, p->CPU.NoThreads);
DBG("CPU: Features: 0x%08x\n", p->CPU.Features);
DBG("CPU: TSC Frequency: %d MHz\n", p->CPU.TSCFrequency / 1000000);
DBG("CPU: FSB Frequency: %d MHz\n", p->CPU.FSBFrequency / 1000000);
DBG("CPU: CPU Frequency: %d MHz\n", p->CPU.CPUFrequency / 1000000);
DBG("CPU: Minimum Bus Ratio: %d\n", p->CPU.MinRatio);
DBG("CPU: Maximum Bus Ratio: %d\n", p->CPU.MaxRatio);
DBG("CPU: Current Bus Ratio: %d\n", p->CPU.CurrCoef);
//DBG("CPU: Maximum Multiplier: %d\n", p->CPU.MaxCoef);
// DBG("CPU: Maximum Divider: %d\n", p->CPU.MaxDiv);
//DBG("CPU: Current Divider: %d\n", p->CPU.CurrDiv);
#if DEBUG_CPU
pause();
#endif
}
branches/Chimera/i386/libsaio/platform.h
4040
4141
4242
43
43
4444
45
45
4646
4747
4848
#define CPU_MODEL_DALES_32NM0x25// Clarkdale, Arrandale
#define CPU_MODEL_SANDYBRIDGE0x2A// Sandy Bridge
#define CPU_MODEL_WESTMERE0x2C// Gulftown, Westmere-EP, Westmere-WS
#define CPU_MODEL_JAKETOWN0x2D// Sandy Bridge-E, Sandy Bridge-EP
#define CPU_MODEL_JAKETOWN0x2D// Sandy Bridge-E, Sandy Bridge-EP
#define CPU_MODEL_NEHALEM_EX0x2E// Beckton
#define CPU_MODEL_WESTMERE_EX0x2F
#define CPU_MODEL_WESTMERE_EX0x2F// Westmere-EX
#define CPU_MODEL_IVYBRIDGE0x3A// Ivy Bridge
/* CPU Features */
branches/Chimera/i386/libsaio/cpu.h
1616
1717
1818
19
19
20
21
22
23
2024
21
22
25
26
2327
24
25
26
2728
29
2830
2931
3032
#define CPU_STRING_UNKNOWN"Unknown CPU Type"
#defineMSR_IA32_PERF_STATUS0x00000198
#define MSR_CORE_THREAD_COUNT0x35// Undocumented. Nehalem and newer only
#define MSR_FLEX_RATIO0x194// Undocumented.
#define MSR_IA32_EXT_CONFIG0xEE// Undocumented. Core Solo and Core Duo only
#define MSR_PKG_CST_CONFIG_CTL0xE2
#defineMSR_IA32_PERF_STATUS0x198
#define MSR_IA32_PERF_CONTROL0x199
#define MSR_IA32_EXT_CONFIG0x00EE
#define MSR_FLEX_RATIO0x194
#define MSR_IA32_PLATFORM_ID0x17
#defineMSR_PLATFORM_INFO0xCE
#define MSR_TURBO_RATIO_LIMIT0x1AD
#defineMSR_PLATFORM_INFO0xCE
#define MSR_CORE_THREAD_COUNT0x35// Undocumented
#define MSR_IA32_PLATFORM_ID0x17
#define K8_FIDVID_STATUS0xC0010042
#define K10_COFVID_STATUS0xC0010071
branches/Chimera/i386/libsaio/smbios.c
557557
558558
559559
560
560
561561
562562
563563
......
571571
572572
573573
574
575
576
574577
575578
576
579
577580
578581
579582
void addSMBOemProcessorBusSpeed(SMBStructPtrs *structPtr)
{
SMBOemProcessorBusSpeed *p = (SMBOemProcessorBusSpeed *)structPtr->new;
switch (Platform.CPU.Family)
{
case 0x06:
case CPU_MODEL_NEHALEM_EX:// Intel Xeon X75xx, Xeon X65xx, Xeon E75xx, Xeon E65x
case CPU_MODEL_WESTMERE:// Intel Core i7, Xeon X56xx, Xeon E56xx, Xeon W36xx LGA1366 (32nm) 6 Core
case CPU_MODEL_WESTMERE_EX:// Intel Xeon E7
case CPU_MODEL_SANDYBRIDGE:// Intel Core i3, i5, i7 LGA1155 (32nm)
case CPU_MODEL_IVYBRIDGE:// Intel Core i3, i5, i7 LGA1155 (22nm)
case CPU_MODEL_JAKETOWN:// Intel Core i7, Xeon E5 LGA2011 (32nm)
break;
default:
default:
return;
}
}
branches/Chimera/i386/libsaio/smbios_getters.c
8686
8787
8888
89
90
91
92
93
94
95
96
97
8998
9099
91100
......
109118
110119
111120
112
113
114121
115122
116123
117124
118
119
120
121
122
123
124125
125126
126127
......
137138
138139
139140
140
141
141142
142143
143144
......
161162
162163
163164
164
165
165166
166167
167
168
168
169
169170
171
172
173
170174
171175
172176
value->word = qpibusspeed;
return true;
}
case CPU_MODEL_SANDYBRIDGE:// Intel Core i3, i5, i7 LGA1155 (32nm)
case CPU_MODEL_IVYBRIDGE:// Intel Core i3, i5, i7 LGA1155 (22nm)
case CPU_MODEL_JAKETOWN:// Intel Core i7, Xeon E5 LGA2011 (32nm)
{
int busspeed;
busspeed = 100;
value->word = busspeed;
return true;
}
}
}
}
bool getSMBOemProcessorType(returnType *value)
{
static bool done = false;
value->word = simpleGetSMBOemProcessorType();
if (Platform.CPU.Vendor == 0x756E6547) // Intel
{
if (!done)
{
verbose("CPU is %s, family 0x%x, model 0x%x\n", Platform.CPU.BrandString, Platform.CPU.Family, Platform.CPU.Model);
done = true;
}
switch (Platform.CPU.Family)
{
case 0x06:
case CPU_MODEL_NEHALEM:// Intel Core i7, Xeon W35xx, Xeon X55xx, Xeon E55xx LGA1366 (45nm)
case CPU_MODEL_WESTMERE:// Intel Core i7, Xeon X56xx, Xeon E56xx, Xeon W36xx LGA1366 (32nm) 6 Core
case CPU_MODEL_WESTMERE_EX:// Intel Xeon E7
case CPU_MODEL_JAKETOWN:// Intel Core i7, Xeon E5 LGA2011 (32nm)
case CPU_MODEL_JAKETOWN:// Intel Core i7, Xeon E5-xxxx LGA2011 (32nm)
if (strstr(Platform.CPU.BrandString, "Xeon(R)"))
value->word = 0x0501;// Xeon
else
value->word = 0x0701;// Core i7
return true;
case CPU_MODEL_SANDYBRIDGE:// Intel Core i3, i5, i7 LGA1155 (32nm)
case CPU_MODEL_SANDYBRIDGE:// Intel Core i3, i5, i7, Xeon E3-12xx LGA1155 (32nm)
case CPU_MODEL_IVYBRIDGE:// Intel Core i3, i5, i7 LGA1155 (22nm)
case CPU_MODEL_DALES_32NM:// Intel Core i3, i5 LGA1156 (32nm)
if (strstr(Platform.CPU.BrandString, "Core(TM) i3"))
value->word = 0x0901;// Core i3
if (strstr(Platform.CPU.BrandString, "Xeon(R)"))
value->word = 0x0501;// Xeon
else
if (strstr(Platform.CPU.BrandString, "Core(TM) i3"))
value->word = 0x0901;// Core i3
else
if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))
value->word = 0x0601;// Core i5
else

Archive Download the corresponding diff file

Revision: 1930