Index: trunk/i386/libsaio/acpi_patcher.c =================================================================== --- trunk/i386/libsaio/acpi_patcher.c (revision 826) +++ trunk/i386/libsaio/acpi_patcher.c (revision 827) @@ -494,6 +494,7 @@ case CPU_MODEL_NEHALEM_EX: case CPU_MODEL_WESTMERE: case CPU_MODEL_WESTMERE_EX: + case CPU_MODEL_SANDY: { 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; Index: trunk/i386/libsaio/cpu.c =================================================================== --- trunk/i386/libsaio/cpu.c (revision 826) +++ trunk/i386/libsaio/cpu.c (revision 827) @@ -6,6 +6,8 @@ #include "libsaio.h" #include "platform.h" #include "cpu.h" +#include "bootstruct.h" +#include "boot.h" #ifndef DEBUG_CPU #define DEBUG_CPU 0 @@ -94,9 +96,14 @@ { uint64_t tscFrequency, fsbFrequency, cpuFrequency; uint64_t msr, flex_ratio; - uint8_t maxcoef, maxdiv, currcoef, currdiv; + uint8_t maxcoef, maxdiv, currcoef, bus_ratio_max, currdiv; + const char *newratio; + int len, myfsb; + uint8_t bus_ratio_min; + uint32_t max_ratio, min_ratio; - maxcoef = maxdiv = currcoef = currdiv = 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]); @@ -196,26 +203,75 @@ cpuFrequency = 0; if ((p->CPU.Vendor == 0x756E6547 /* Intel */) && ((p->CPU.Family == 0x06) || (p->CPU.Family == 0x0f))) { + int intelCPU = p->CPU.Model; if ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0c) || (p->CPU.Family == 0x0f && p->CPU.Model >= 0x03)) { /* Nehalem CPU model */ if (p->CPU.Family == 0x06 && (p->CPU.Model == 0x1a || p->CPU.Model == 0x1e - || p->CPU.Model == 0x1f || p->CPU.Model == 0x25 || p->CPU.Model == 0x2c)) { + || p->CPU.Model == 0x1f || p->CPU.Model == 0x25 || p->CPU.Model == 0x2c || p->CPU.Model == CPU_MODEL_SANDY)) { msr = rdmsr64(MSR_PLATFORM_INFO); DBG("msr(%d): platform_info %08x\n", __LINE__, msr & 0xffffffff); - currcoef = (msr >> 8) & 0xff; + bus_ratio_max = (msr >> 8) & 0xff; + bus_ratio_min = (msr >> 40) & 0xff; //valv: not sure about this one (Remarq.1) msr = rdmsr64(MSR_FLEX_RATIO); DBG("msr(%d): flex_ratio %08x\n", __LINE__, msr & 0xffffffff); if ((msr >> 16) & 0x01) { flex_ratio = (msr >> 8) & 0xff; - if (currcoef > flex_ratio) { - currcoef = flex_ratio; + /* 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. + */ + 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", msr & 0xffffffff); + } else { + if (bus_ratio_max > flex_ratio) { + bus_ratio_max = flex_ratio; + } } } - if (currcoef) { - fsbFrequency = (tscFrequency / currcoef); + if (bus_ratio_max) { + fsbFrequency = (tscFrequency / bus_ratio_max); } - cpuFrequency = tscFrequency; + //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; + } + if ((getValueForKey(kbusratio, &newratio, &len, &bootInfo->bootConfig)) && (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); + + // extreme overclockers may love 320 ;) + if ((max_ratio >= min_ratio) && (max_ratio <= 320)) { + cpuFrequency = (fsbFrequency * max_ratio) / 10; + if (len >= 3) maxdiv = 1; + else maxdiv = 0; + } else { + 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; + + 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__, msr & 0xffffffff); Index: trunk/i386/libsaio/platform.h =================================================================== --- trunk/i386/libsaio/platform.h (revision 826) +++ trunk/i386/libsaio/platform.h (revision 827) @@ -31,6 +31,7 @@ #define CPU_MODEL_FIELDS 0x1E /* Lynnfield, Clarksfield, Jasper */ #define CPU_MODEL_DALES 0x1F /* Havendale, Auburndale */ #define CPU_MODEL_DALES_32NM 0x25 /* Clarkdale, Arrandale */ +#define CPU_MODEL_SANDY 0x2a /* Sandy bridge */ #define CPU_MODEL_WESTMERE 0x2C /* Gulftown, Westmere-EP, Westmere-WS */ #define CPU_MODEL_NEHALEM_EX 0x2E #define CPU_MODEL_WESTMERE_EX 0x2F @@ -120,6 +121,8 @@ uint64_t TSCFrequency; // TSC Frequency Hz uint64_t FSBFrequency; // FSB Frequency Hz uint64_t CPUFrequency; // CPU Frequency Hz + uint32_t MaxRatio; // Max Bus Ratio + uint32_t MinRatio; // Min Bus Ratio char BrandString[48]; // 48 Byte Branding String uint32_t CPUID[CPUID_MAX][4]; // CPUID 0..4, 80..81 Raw Values } CPU; Index: trunk/i386/libsaio/cpu.h =================================================================== --- trunk/i386/libsaio/cpu.h (revision 826) +++ trunk/i386/libsaio/cpu.h (revision 827) @@ -20,6 +20,7 @@ #define MSR_IA32_PERF_CONTROL 0x199 #define MSR_IA32_EXT_CONFIG 0x00EE #define MSR_FLEX_RATIO 0x194 +#define MSR_TURBO_RATIO_LIMIT 0x1AD #define MSR_PLATFORM_INFO 0xCE #define K8_FIDVID_STATUS 0xC0010042 #define K10_COFVID_STATUS 0xC0010071 Index: trunk/i386/libsaio/smbios.c =================================================================== --- trunk/i386/libsaio/smbios.c (revision 826) +++ trunk/i386/libsaio/smbios.c (revision 827) @@ -94,6 +94,9 @@ // defaults for an iMac11,1 core i3/i5/i7 #define kDefaultiMacNehalem "iMac11,1" #define kDefaultiMacNehalemBIOSVersion " IM111.88Z.0034.B00.0903051113" +// defaults for an iMac12,1 +#define kDefaultiMacSandy "iMac12,1" +#define kDefaultiMacSandyBIOSVersion " IM121.88Z.0047.B00.1102091756" // defaults for a Mac Pro #define kDefaultMacProFamily "MacPro" @@ -331,6 +334,11 @@ defaultSystemInfo.family = kDefaultiMacFamily; break; + case CPU_MODEL_SANDY: + defaultBIOSInfo.version = kDefaultiMacSandyBIOSVersion; + defaultSystemInfo.productName = kDefaultiMacSandy; + defaultSystemInfo.family = kDefaultiMacFamily; + break; case CPU_MODEL_NEHALEM: case CPU_MODEL_NEHALEM_EX: defaultBIOSInfo.version = kDefaultMacProNehalemBIOSVersion; Index: trunk/i386/libsaio/smbios_getters.c =================================================================== --- trunk/i386/libsaio/smbios_getters.c (revision 826) +++ trunk/i386/libsaio/smbios_getters.c (revision 827) @@ -48,6 +48,7 @@ return false; case 0x19: // Intel Core i5 650 @3.20 Ghz + case CPU_MODEL_SANDY: // Intel Core i5, i7 LGA1155 sandy bridge case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm) case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm) case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ??? @@ -156,6 +157,7 @@ value->word = 0x0701; // Core i7 return true; + case CPU_MODEL_SANDY: // Intel Core i3, i5, i7 LGA1155 sandy bridge case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm) (Clarkdale, Arrandale) if (strstr(Platform.CPU.BrandString, "Core(TM) i3")) value->word = 0x901; // Core i3 Index: trunk/i386/boot2/boot.h =================================================================== --- trunk/i386/boot2/boot.h (revision 826) +++ trunk/i386/boot2/boot.h (revision 827) @@ -109,6 +109,7 @@ #define kDefaultPartition "Default Partition" /* sys.c */ #define kMD0Image "md0" /* ramdisk.h */ +#define kbusratio "busratio" /* cpu.c */ /* * Flags to the booter or kernel