Mac OS X as is has a condition to only run on family 13 Intel CPUs, so this adds a definition for a CoreDuo CPU. Furthermore it adds the MSR Mac OS X uses to read the CPU multiplier and the CPUID used to read the cache information.
Index: qemu-snapshot-2008-01-08_05/target-i386/cpu.h =================================================================== --- qemu-snapshot-2008-01-08_05.orig/target-i386/cpu.h +++ qemu-snapshot-2008-01-08_05/target-i386/cpu.h @@ -232,6 +232,8 @@ #define MSR_MCG_STATUS 0x17a #define MSR_MCG_CTL 0x17b +#define MSR_IA32_PERF_STS 0x198 + #define MSR_PAT 0x277 #define MSR_EFER 0xc0000080 Index: qemu-snapshot-2008-01-08_05/target-i386/helper.c =================================================================== --- qemu-snapshot-2008-01-08_05.orig/target-i386/helper.c +++ qemu-snapshot-2008-01-08_05/target-i386/helper.c @@ -1710,6 +1710,79 @@ void helper_cpuid(void) ECX = 0; EDX = 0x2c307d; break; + case 4: + /* cache info: needed for Core Duo compatibility */ +/* From the Intel documentation: +EAX: + Bits 4-0: Cache Type** + Bits 7-5: Cache Level (starts at 1) + Bits 8: Self Initializing cache level (does not need SW initialization) + Bits 9: Fully Associative cache Bits + 13-10: Reserved Bits + 25-14: Number of threads sharing this cache* Bits + 31-26: Number of processor cores on this die (Multicore)* +EBX: + Bits 11-0: L = System Coherency Line Size* + Bits 21-12: P = Physical Line partitions* + Bits 31-22: W = Ways of associativity* +ECX: + Bits 31-0: S = Number of Sets* +EDX: Reserved + * Add one to the value in the register file to get the number. For example, the number + of processor cores is EAX[31:26]+1. +** Cache Types fields + 0 = Null - No more caches + 1 = Data Cache + 2 = Instruction Cache + 3 = Unified Cache + 31-4 = Reserved +*/ + + switch (ECX) { + case 0: // L1 cache info +/* EAX = 3 // Unified Cache + | (1 << 5) // L1 Cache + | (1 << 8); // Self Initializing + EBX = 63 // Line size = 64 bytes + | (1022 << 12) // Partitions = 1024 bytes + | (0 << 22); // Ways = 2 + ECX = 0x3f; // One L1 Cache + EDX = 0;*/ + EAX = 0x0000123; + EBX = 0x1c0003f; + ECX = 0x000003f; + EDX = 0x0000001; + break; + case 1: // L2 cache info +/* EAX = 3 // Unified Cache + | (2 << 5) // L2 Cache + | (1 << 8); // Self Initializing + EBX = 63 // Line size = 64 bytes + | (1023 << 12) // Partitions = 1024 bytes + | (0 << 22); // Ways = 512 + ECX = 0; // One L2 Cache + EDX = 0; +*/ + EAX = 0x0000122; + EBX = 0x1c0003f; + ECX = 0x000003f; + EDX = 0x0000001; + break; + case 2: + EAX = 0x0004143; + EBX = 0x3c0003f; + ECX = 0x0000fff; + EDX = 0x0000001; + break; + default: // end of info + EAX = 0; + EBX = 0; + ECX = 0; + EDX = 0; + break; + } + + break; case 0x80000000: EAX = env->cpuid_xlevel; EBX = env->cpuid_vendor1; @@ -2844,6 +2917,10 @@ void helper_rdmsr(void) { uint64_t val; switch((uint32_t)ECX) { + case MSR_IA32_PERF_STS: + val = 1000ULL /* tsc_increment_by_tick */ + | (((uint64_t)(4ULL /* granularity */ & 0x7)) << 40); + break; case MSR_IA32_SYSENTER_CS: val = env->sysenter_cs; break; Index: qemu-snapshot-2008-01-08_05/target-i386/helper2.c =================================================================== --- qemu-snapshot-2008-01-08_05.orig/target-i386/helper2.c +++ qemu-snapshot-2008-01-08_05/target-i386/helper2.c @@ -156,6 +156,23 @@ static x86_def_t x86_defs[] = { }, #endif { + .name = "coreduo", + .level = 3, + .vendor1 = 0x756e6547, /* "Genu" */ + .vendor2 = 0x49656e69, /* "ineI" */ + .vendor3 = 0x6c65746e, /* "ntel" */ + .family = 6, + .model = 13, + .stepping = 1, + .features = PPRO_FEATURES | + CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | + CPUID_PSE36, + .ext_features = CPUID_EXT_SSE3, + .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | + CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, + .xlevel = 0x8000000A, + }, + { .name = "qemu32", .level = 2, .family = 6,