Index: branches/azimutz/CleanCut/CHANGES =================================================================== --- branches/azimutz/CleanCut/CHANGES (revision 297) +++ branches/azimutz/CleanCut/CHANGES (revision 298) @@ -1,3 +1,5 @@ +- Added automatic SMBusspeed detection for lga1156 core i5/7 cpus +- Added new iMac11,1 sbios default model for lga1156 core i5/17 mobos - md0 code. Notified xnu when an md ramdisk is specified - Added rollover image support for selected device icons. Use device__o.png in theme folder. Credits goes to Blackosx. Index: branches/azimutz/CleanCut/i386/libsaio/acpi_patcher.c =================================================================== --- branches/azimutz/CleanCut/i386/libsaio/acpi_patcher.c (revision 297) +++ branches/azimutz/CleanCut/i386/libsaio/acpi_patcher.c (revision 298) @@ -387,9 +387,9 @@ if (acpi_cpu_count > 0) { - bool cpu_dynamic_fsb = false, cpu_noninteger_bus_ratio = (rdmsr64(MSR_IA32_PERF_STATUS) & (1ULL << 46)); + struct p_state initial, maximum, minimum, p_states[32]; - uint8_t p_states_count; + uint8_t p_states_count = 0; // Retrieving P-States, ported from code by superhai (c) switch (Platform.CPU.Family) { @@ -400,128 +400,134 @@ case 0x0F: // Intel Core (65nm) case 0x17: // Intel Core (45nm) case 0x1C: // Intel Atom (45nm) + { + bool cpu_dynamic_fsb = false; + if (rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 27)) { wrmsr64(MSR_IA32_EXT_CONFIG, (rdmsr64(MSR_IA32_EXT_CONFIG) | (1 << 28))); delay(1); cpu_dynamic_fsb = rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 28); } - break; + + bool cpu_noninteger_bus_ratio = (rdmsr64(MSR_IA32_PERF_STATUS) & (1ULL << 46)); + + initial.Control = rdmsr64(MSR_IA32_PERF_STATUS); + + maximum.Control = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 32) & 0x1F3F) | (0x4000 * cpu_noninteger_bus_ratio); + maximum.CID = ((maximum.FID & 0x1F) << 1) | cpu_noninteger_bus_ratio; + + minimum.FID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 24) & 0x1F) | (0x80 * cpu_dynamic_fsb); + minimum.VID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 48) & 0x3F); + + if (minimum.FID == 0) + { + uint64_t msr; + uint8_t i; + // Probe for lowest fid + for (i = maximum.FID; i >= 0x6; i--) + { + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (i << 8) | minimum.VID); + intel_waitforsts(); + minimum.FID = (rdmsr64(MSR_IA32_PERF_STATUS) >> 8) & 0x1F; + delay(1); + } + + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID); + intel_waitforsts(); + } + + if (minimum.VID == maximum.VID) + { + uint64_t msr; + uint8_t i; + // Probe for lowest vid + for (i = maximum.VID; i > 0xA; i--) + { + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (minimum.FID << 8) | i); + intel_waitforsts(); + minimum.VID = rdmsr64(MSR_IA32_PERF_STATUS) & 0x3F; + delay(1); + } + + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID); + intel_waitforsts(); + } + + minimum.CID = ((minimum.FID & 0x1F) << 1) >> cpu_dynamic_fsb; + + // Sanity check + if (maximum.CID < minimum.CID) + { + DBG("Insane FID values!"); + p_states_count = 1; + } + else + { + // Finalize P-States + // Find how many P-States machine supports + p_states_count = maximum.CID - minimum.CID + 1; + + if (p_states_count > 32) + p_states_count = 32; + + uint8_t vidstep; + uint8_t i = 0, u, invalid = 0; + + vidstep = ((maximum.VID << 2) - (minimum.VID << 2)) / (p_states_count - 1); + + for (u = 0; u < p_states_count; u++) + { + i = u - invalid; + + p_states[i].CID = maximum.CID - u; + p_states[i].FID = (p_states[i].CID >> 1); + + if (p_states[i].FID < 0x6) + { + if (cpu_dynamic_fsb) + p_states[i].FID = (p_states[i].FID << 1) | 0x80; + } + else if (cpu_noninteger_bus_ratio) + { + p_states[i].FID = p_states[i].FID | (0x40 * (p_states[i].CID & 0x1)); + } + + if (i && p_states[i].FID == p_states[i-1].FID) + invalid++; + + p_states[i].VID = ((maximum.VID << 2) - (vidstep * u)) >> 2; + + uint32_t multiplier = p_states[i].FID & 0x1f; // = 0x08 + bool half = p_states[i].FID & 0x40; // = 0x01 + bool dfsb = p_states[i].FID & 0x80; // = 0x00 + uint32_t fsb = Platform.CPU.FSBFrequency / 1000000; // = 400 + uint32_t halffsb = (fsb + 1) >> 1; // = 200 + uint32_t frequency = (multiplier * fsb); // = 3200 + + p_states[i].Frequency = (frequency + (half * halffsb)) >> dfsb; // = 3200 + 200 = 3400 + } + + p_states_count -= invalid; + } + } break; case 0x1A: // Intel Core i7 LGA1366 (45nm) case 0x1E: // Intel Core i5, i7 LGA1156 (45nm) case 0x1F: case 0x25: // Intel Core i3, i5, i7 LGA1156 (32nm) case 0x2C: // Intel Core i7 LGA1366 (32nm) 6 Core case 0x2F: - cpu_dynamic_fsb = rdmsr64(MSR_IA32_PERF_STATUS) & (1 << 15); + default: + verbose ("Unsupported CPU: P-States not generated !!!\n"); break; } } } - initial.Control = rdmsr64(MSR_IA32_PERF_STATUS); - - maximum.Control = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 32) & 0x1F3F) | (0x4000 * cpu_noninteger_bus_ratio); - maximum.CID = ((maximum.FID & 0x1F) << 1) | cpu_noninteger_bus_ratio; - - minimum.FID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 24) & 0x1F) | (0x80 * cpu_dynamic_fsb); - minimum.VID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 48) & 0x3F); - - if (minimum.FID == 0) - { - uint64_t msr; - uint8_t i; - // Probe for lowest fid - for (i = maximum.FID; i >= 0x6; i--) - { - msr = rdmsr64(MSR_IA32_PERF_CONTROL); - wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (i << 8) | minimum.VID); - intel_waitforsts(); - minimum.FID = (rdmsr64(MSR_IA32_PERF_STATUS) >> 8) & 0x1F; - delay(1); - } - - msr = rdmsr64(MSR_IA32_PERF_CONTROL); - wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID); - intel_waitforsts(); - } - - if (minimum.VID == maximum.VID) - { - uint64_t msr; - uint8_t i; - // Probe for lowest vid - for (i = maximum.VID; i > 0xA; i--) - { - msr = rdmsr64(MSR_IA32_PERF_CONTROL); - wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (minimum.FID << 8) | i); - intel_waitforsts(); - minimum.VID = rdmsr64(MSR_IA32_PERF_STATUS) & 0x3F; - delay(1); - } - - msr = rdmsr64(MSR_IA32_PERF_CONTROL); - wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID); - intel_waitforsts(); - } - - minimum.CID = ((minimum.FID & 0x1F) << 1) >> cpu_dynamic_fsb; - - // Sanity check - if (maximum.CID < minimum.CID) - { - DBG("Insane FID values!"); - p_states_count = 1; - } - else - { - // Finalize P-States - // Find how many P-States machine supports - p_states_count = maximum.CID - minimum.CID + 1; - - if (p_states_count > 32) - p_states_count = 32; - - uint8_t vidstep; - uint8_t i = 0, u, invalid = 0; - - vidstep = ((maximum.VID << 2) - (minimum.VID << 2)) / (p_states_count - 1); - - for (u = 0; u < p_states_count; u++) - { - i = u - invalid; - - p_states[i].CID = maximum.CID - u; - p_states[i].FID = (p_states[i].CID >> 1); - - if (p_states[i].FID < 0x6) - { - if (cpu_dynamic_fsb) - p_states[i].FID = (p_states[i].FID << 1) | 0x80; - } - else if (cpu_noninteger_bus_ratio) - { - p_states[i].FID = p_states[i].FID | (0x40 * (p_states[i].CID & 0x1)); - } - - if (i && p_states[i].FID == p_states[i-1].FID) - invalid++; - - p_states[i].VID = ((maximum.VID << 2) - (vidstep * u)) >> 2; - - uint32_t multiplier = p_states[i].FID & 0x1f; // = 0x08 - bool half = p_states[i].FID & 0x40; // = 0x01 - bool dfsb = p_states[i].FID & 0x80; // = 0x00 - uint32_t fsb = Platform.CPU.FSBFrequency / 1000000; // = 400 - uint32_t halffsb = (fsb + 1) >> 1; // = 200 - uint32_t frequency = (multiplier * fsb); // = 3200 - - p_states[i].Frequency = (frequency + (half * halffsb)) >> dfsb; // = 3200 + 200 = 3400 - } - - p_states_count -= invalid; - } - // Generating SSDT if (p_states_count > 0) @@ -575,7 +581,8 @@ return ssdt; } } - else { + else + { verbose ("ACPI CPUs not found: P-States not generated !!!\n"); } Index: branches/azimutz/CleanCut/i386/libsaio/smbios_patcher.c =================================================================== --- branches/azimutz/CleanCut/i386/libsaio/smbios_patcher.c (revision 297) +++ branches/azimutz/CleanCut/i386/libsaio/smbios_patcher.c (revision 298) @@ -101,6 +101,21 @@ { "","" } }; +// defaults for an iMac11,1 core i5/i7 +static const SMStrEntryPair const sm_imacCore_i5_i7_defaults[]={ + {"SMbiosvendor", "Apple Inc." }, + {"SMbiosversion", "IM111.0034.B00" }, + {"SMbiosdate", "06/01/2009" }, + {"SMmanufacter", "Apple Inc." }, + {"SMproductname", "iMac11,1" }, + {"SMsystemversion", "1.0" }, + {"SMserial", "SOMESRLNMBR" }, + {"SMfamily", "iMac" }, + {"SMboardmanufacter","Apple Computer, Inc." }, + {"SMboardproduct", "Mac-F2268DAE" }, + { "","" } +}; + static const char* sm_get_defstr(const char * key, int table_num) { int i; @@ -113,13 +128,42 @@ sm_defaults=sm_macbook_defaults; } } else { - switch (Platform.CPU.NoCores) { - case 1: sm_defaults=sm_macmini_defaults; break; - case 2: sm_defaults=sm_imac_defaults; break; - default: sm_defaults=sm_macpro_defaults; break; + switch (Platform.CPU.NoCores) + { + case 1: + sm_defaults=sm_macmini_defaults; + break; + case 2: + sm_defaults=sm_imac_defaults; + break; + default: + { + switch (Platform.CPU.Family) + { + case 0x06: + { + switch (Platform.CPU.Model) + { + case 0x19: // Intel Core i5 650 + case 0x1E: // Intel Core i7 LGA1156 (45nm) + case 0x1F: // Intel Core i5 LGA1156 (45nm) + sm_defaults=sm_imacCore_i5_i7_defaults; + break; + default: + sm_defaults=sm_macpro_defaults; + break; + } + break; + } + default: + sm_defaults=sm_macpro_defaults; + break; + } + break; + } } } - + for (i=0; sm_defaults[i].key[0]; i++) { if (!strcmp (sm_defaults[i].key, key)) { return sm_defaults[i].value; @@ -156,11 +200,48 @@ return 0x0301; // Core 2 Duo } +static int sm_get_bus_speed (const char *name, int table_num) +{ + if (Platform.CPU.Vendor == 0x756E6547) // Intel + { + switch (Platform.CPU.Family) + { + case 0x06: + { + switch (Platform.CPU.Model) + { + case 0x0F: // Intel Core (65nm) + case 0x17: // Intel Core (45nm) + case 0x1C: // Intel Atom (45nm) + return 0; // TODO: populate bus speed for these processors + case 0x19: // Intel Core i5 650 @3.20 Ghz + return 3600; // GT/s / 1000 + case 0x1A: // Intel Core i7 LGA1366 (45nm) + case 0x1E: // Intel Core i5, i7 LGA1156 (45nm) + case 0x1F: // Intel Core i5, i7 LGA1156 (45nm) ??? + return 4800; // GT/s / 1000 + case 0x25: // Intel Core i3, i5, i7 LGA1156 (32nm) + return 0; // TODO: populate bus speed for these processors + case 0x2C: // Intel Core i7 LGA1366 (32nm) 6 Core + case 0x2E: // Intel Core i7 LGA1366 (45nm) 6 Core ??? + return 0; // TODO: populate bus speed for these processors + } + } + } + } + return 0; +} + static int sm_get_cputype (const char *name, int table_num) { + static bool done = false; + if (Platform.CPU.Vendor == 0x756E6547) // Intel { - verbose("CPU is Intel, family 0x%x, model 0x%x, ext.model 0x%x\n", Platform.CPU.Family, Platform.CPU.Model, Platform.CPU.ExtModel); + if (!done) { + verbose("CPU is Intel, family 0x%x, model 0x%x, ext.model 0x%x\n", Platform.CPU.Family, Platform.CPU.Model, Platform.CPU.ExtModel); + done = true; + } switch (Platform.CPU.Family) { @@ -175,6 +256,9 @@ case 0x1A: // Intel Core i7 LGA1366 (45nm) return 0x0701; case 0x1E: // Intel Core i5, i7 LGA1156 (45nm) + // get this opportunity to fill the known processor interconnect speed for cor i5/i7 in GT/s + return 0x0701; + case 0x19: // Intel Core i5 650 @3.20 Ghz case 0x1F: // Intel Core i5, i7 LGA1156 (45nm) ??? return 0x0601; case 0x25: // Intel Core i3, i5, i7 LGA1156 (32nm) @@ -291,7 +375,7 @@ {.name="SMmemserial", .table_type=17, .value_type=SMSTRING, .offset=0x18, .auto_str=sm_get_memserial}, {.name="SMmempart", .table_type=17, .value_type=SMSTRING, .offset=0x1A, .auto_str=sm_get_mempartno}, {.name="SMcputype", .table_type=131,.value_type=SMWORD, .offset=0x04, .auto_int=sm_get_cputype}, - {.name="SMbusspeed", .table_type=132,.value_type=SMWORD, .offset=0x04, .auto_str=0 } + {.name="SMbusspeed", .table_type=132,.value_type=SMWORD, .offset=0x04, .auto_int=sm_get_bus_speed} }; struct smbios_table_description smbios_table_descriptions[]= @@ -493,9 +577,11 @@ int i, j; int tablespresent[256]; bool do_auto=true; - - extern void dumpPhysAddr(const char * title, void * a, int len); + + static bool done = false; // IMPROVEME: called twice via getSmbios(), but only the second call can get all necessary info ! + extern void dumpPhysAddr(const char * title, void * a, int len); + bzero(tablespresent, sizeof(tablespresent)); bzero(handles, sizeof(handles)); @@ -765,7 +851,11 @@ newsmbios->dmi.checksum = 256 - checksum8(&newsmbios->dmi, sizeof(newsmbios->dmi)); newsmbios->checksum = 0; newsmbios->checksum = 256 - checksum8(newsmbios, sizeof(*newsmbios)); - verbose("Patched DMI Table\n"); + + if (!done) { + verbose("Patched DMI Table\n"); + done=true; + } } #define MAX_DMI_TABLES 96 Index: branches/azimutz/CleanCut/i386/libsaio/memvendors.h =================================================================== --- branches/azimutz/CleanCut/i386/libsaio/memvendors.h (revision 297) +++ branches/azimutz/CleanCut/i386/libsaio/memvendors.h (revision 298) @@ -410,7 +410,7 @@ { 3, 0x10, "Agere Systems"}, { 3, 0x91, "NeoMagic"}, { 3, 0x92, "AuroraNetics"}, - { 3, 0x13, "Golden Empire"}, + { 3, 0x13, "Geil"}, { 3, 0x94, "Mushkin"}, { 3, 0x15, "Tioga Technologies"}, { 3, 0x16, "Netlist"}, Index: branches/azimutz/CleanCut/i386/libsaio/dram_controllers.c =================================================================== --- branches/azimutz/CleanCut/i386/libsaio/dram_controllers.c (revision 297) +++ branches/azimutz/CleanCut/i386/libsaio/dram_controllers.c (revision 298) @@ -518,6 +518,10 @@ { 0x8086, 0x3401, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, { 0x8086, 0x3402, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, { 0x8086, 0x3403, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, + { 0x8086, 0x3404, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, + { 0x8086, 0x3405, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, + { 0x8086, 0x3406, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, + { 0x8086, 0x3407, "NHM IMC", setup_nhm, get_fsb_nhm, get_timings_nhm }, }; Index: branches/azimutz/CleanCut/i386/libsaio/cache.c =================================================================== --- branches/azimutz/CleanCut/i386/libsaio/cache.c (revision 297) +++ branches/azimutz/CleanCut/i386/libsaio/cache.c (revision 298) @@ -39,7 +39,7 @@ #define kCacheSize (0x100000) #define kCacheMinBlockSize (0x200) -#define kCacheMaxBlockSize (0x4000) +#define kCacheMaxBlockSize (0x8000) #define kCacheMaxEntries (kCacheSize / kCacheMinBlockSize) static CICell gCacheIH; @@ -74,7 +74,7 @@ #endif if ((blockSize < kCacheMinBlockSize) || - (blockSize >= kCacheMaxBlockSize)) + (blockSize > kCacheMaxBlockSize)) return; gCacheBlockSize = blockSize; Index: branches/azimutz/CleanCut/i386/libsaio/msdos.c =================================================================== --- branches/azimutz/CleanCut/i386/libsaio/msdos.c (revision 297) +++ branches/azimutz/CleanCut/i386/libsaio/msdos.c (revision 298) @@ -55,6 +55,7 @@ #define LABEL_LENGTH 11 #define MAX_DOS_BLOCKSIZE 2048 +#define MAX_CACHE_BLOCKSIZE 32768 #define CLUST_FIRST 2/* reserved cluster range */ #define CLUST_RSRVD32 0x0ffffff8 /* reserved cluster range */ @@ -74,6 +75,7 @@ static CICell msdoscurrent = 0; static int msdosrootcluster = 0; static int msdosfatbits = 0; +static int msdosCacheBlockSize = 0; #if UNUSED /* @@ -151,7 +153,7 @@ if (msdoscurrent == ih) { - CacheInit(ih, msdosclustersize); + CacheInit(ih, msdosCacheBlockSize); return 0; } @@ -220,14 +222,30 @@ } msdosclustersize = msdosbps * spc; - msdoscurrent = ih; - CacheInit(ih, msdosclustersize); + + msdosCacheBlockSize = (msdosclustersize > MAX_CACHE_BLOCKSIZE) ? msdosclustersize : MAX_CACHE_BLOCKSIZE; + CacheInit(ih, msdosCacheBlockSize); free (buf); return 0; } static int +readSectorAligned(CICell ih, off_t readOffset, char *buf, int size) +{ + long long sectorOffset = (uint64_t)readOffset / msdosCacheBlockSize * msdosCacheBlockSize; + long relOffset = readOffset % msdosCacheBlockSize; + char *cacheBuffer; + + cacheBuffer = malloc(msdosCacheBlockSize); + CacheRead(ih, cacheBuffer, sectorOffset, msdosCacheBlockSize, true); + bcopy(cacheBuffer + relOffset, buf, size); + free(cacheBuffer); + + return 0; +} + +static int msdosreadcluster (CICell ih, uint8_t *buf, int size, off_t *cluster) { off_t readOffset; @@ -263,18 +281,17 @@ /* Read in "cluster" */ if (buf) { - Seek(ih, readOffset); - Read(ih, (long)buf, size); + readSectorAligned(ih, readOffset, (char *)buf, size); } - + /* Find first sector of FAT */ - readOffset = msdosressector*msdosbps; + readOffset = msdosressector * msdosbps; + /* Find sector containing "cluster" entry in FAT */ - readOffset += ((uint64_t)*cluster * (uint64_t)msdosfatbits)/8; + readOffset += ((uint64_t)*cluster * (uint64_t)msdosfatbits) / 8; /* Read one sector of the FAT */ - Seek(ih, readOffset); - Read(ih, (long)tmpbuf, 4); + readSectorAligned(ih, readOffset, tmpbuf, 4); switch (msdosfatbits) { case 32: Index: branches/azimutz/CleanCut/i386/libsa/memory.h =================================================================== --- branches/azimutz/CleanCut/i386/libsa/memory.h (revision 297) +++ branches/azimutz/CleanCut/i386/libsa/memory.h (revision 298) @@ -57,7 +57,7 @@ #define BOOT2_SEG 0x2000 #define BOOT2_OFS 0x0200 // 512 byte disk sector offset -#define BIOS_ADDR 0x9000 // BIOS disk I/O buffer +#define BIOS_ADDR 0x8000 // BIOS disk I/O buffer #define BIOS_LEN 0x8000 // 32K - divisible by 512 and 2048 #define BOOT0_ADDR 0x7E00 // boot0 gets loaded here