diff options
Diffstat (limited to 'src/tools')
| -rw-r--r-- | src/tools/my_cpuid.c | 440 | ||||
| -rw-r--r-- | src/tools/rcfile.c | 1 |
2 files changed, 318 insertions, 123 deletions
diff --git a/src/tools/my_cpuid.c b/src/tools/my_cpuid.c index b201bd71..e10aaca9 100644 --- a/src/tools/my_cpuid.c +++ b/src/tools/my_cpuid.c @@ -200,12 +200,22 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) int ncpu = getNCpu(); if(!ncpu) ncpu = 1; int ncluster = 1; - while(ncpu>64) { - ncluster++; // do cluster of 64 cpus... - if(ncpu>=128) - ncpu-=64; - else - ncpu=64; + if(box64_cputype) { + while(ncpu>256) { + ncluster++; // do cluster of 256 cpus... + if(ncpu>=256) + ncpu-=256; + else + ncpu=256; + } + } else { + while(ncpu>64) { + ncluster++; // do cluster of 64 cpus... + if(ncpu>=128) + ncpu-=64; + else + ncpu=64; + } } static char branding[3*4*4+1] = ""; if(!branding[0]) { @@ -218,23 +228,40 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) switch(tmp32u) { case 0x0: // emulate a P4. TODO: Emulate a Core2? - R_EAX = 0x0000000f;//was 0x15 before, but something seems wrong for leaf 0x15, and cpu-z take that as pure cpu speed... - // return GenuineIntel - R_EBX = 0x756E6547; - R_EDX = 0x49656E69; - R_ECX = 0x6C65746E; + R_EAX = box64_cputype?0x0000000f:0x0000000f;//was 0x15 before, but something seems wrong for leaf 0x15, and cpu-z take that as pure cpu speed... + if(box64_cputype) { + // return AuthenticAMD + R_EBX = 0x68747541; + R_ECX = 0x444d4163; + R_EDX = 0x69746E65; + } else { + // return GenuineIntel + R_EBX = 0x756E6547; + R_ECX = 0x6C65746E; + R_EDX = 0x49656E69; + } break; case 0x1: - R_EAX = (0x1<<0) | // stepping - (0x6<<4) | // model - (0x6<<8) | // familly - (0x0<<12)| // Processor type - (0x0<<14)| // reserved - (0x4<<16)| // extended model - (0x0<<20)| // extended familly - - 0 ; // family and all, simulating Haswell type of cpu - R_EBX = 0 | (8<<0x8) | (ncluster<<16); // Brand index, CLFlush (8), Max APIC ID (16-23), Local APIC ID (24-31) + if(box64_cputype) { + R_EAX = (0xc<<0) | // stepping 0-3 + (0x1<<4) | // base model 4-7 + (0xf<<8) | // base familly 8-11 + (0x0<<12)| // reserved 12-15 + (0x7<<16)| // Extented model 16-19 + (0x8<<20)| // extended familly 20-27 + (0x0<<28)| // reserved 28-31 + 0 ; // family and all, simulating a Ryzen 5 type of cpu + } else { + R_EAX = (0x1<<0) | // stepping + (0x6<<4) | // model + (0x6<<8) | // familly + (0x0<<12)| // Processor type + (0x0<<14)| // reserved + (0x4<<16)| // extended model + (0x0<<20)| // extended familly + 0 ; // family and all, simulating Haswell type of cpu + } + R_EBX = 0 | (8<<0x8) | ((box64_cputype?0:ncluster)<<16); // Brand index, CLFlush (8), Max APIC ID (16-23), Local APIC ID (24-31) /*{ int cpu = sched_getcpu(); if(cpu<0) cpu=0; @@ -257,7 +284,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) | 1<<24 // fxsr (fxsave, fxrestore) | 1<<25 // SSE | 1<<26 // SSE2 - | 1<<28 // HT / Multi-core + | (box64_cputype?0:1)<<28 // HT / Multi-core ; R_ECX = 1<<0 // SSE3 | 1<<1 // PCLMULQDQ @@ -277,40 +304,52 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) | box64_avx2<<30 // RDRAND ; break; - case 0x2: // TLB and Cache info. Sending 1st gen P4 info... - R_EAX = 0x665B5001; - R_EBX = 0x00000000; - R_ECX = 0x00000000; - R_EDX = 0x007A7000; + case 0x2: + if(box64_cputype) { + // reserved + R_EAX = R_EBX = R_ECX = R_EDX = 0 ; + } else { + // TLB and Cache info. Sending 1st gen P4 info... + R_EAX = 0x665B5001; + R_EBX = 0x00000000; + R_ECX = 0x00000000; + R_EDX = 0x007A7000; + } break; - case 0x4: // Cache info - switch (R_ECX) { - case 0: // L1 data cache - R_EAX = (1 | (1<<5) | (1<<8) | ((ncpu-1)<<26)); //type + (26-31):max cores per packages-1 - R_EBX = (63 | (7<<22)); // size - R_ECX = 63; - R_EDX = 1; - break; - case 1: // L1 inst cache - R_EAX = (2 | (1<<5) | (1<<8)); //type - R_EBX = (63 | (7<<22)); // size - R_ECX = 63; - R_EDX = 1; - break; - case 2: // L2 cache - R_EAX = (3 | (2<<5) | (1<<8)); //type - R_EBX = (63 | (15<<22)); // size - R_ECX = 4095; - R_EDX = 1; - break; + case 0x4: + if(box64_cputype) { + // reserved + R_EAX = R_EBX = R_ECX = R_EDX = 0 ; + } else { + // Cache info + switch (R_ECX) { + case 0: // L1 data cache + R_EAX = (1 | (1<<5) | (1<<8) | ((ncpu-1)<<26)); //type + (26-31):max cores per packages-1 + R_EBX = (63 | (7<<22)); // size + R_ECX = 63; + R_EDX = 1; + break; + case 1: // L1 inst cache + R_EAX = (2 | (1<<5) | (1<<8)); //type + R_EBX = (63 | (7<<22)); // size + R_ECX = 63; + R_EDX = 1; + break; + case 2: // L2 cache + R_EAX = (3 | (2<<5) | (1<<8)); //type + R_EBX = (63 | (15<<22)); // size + R_ECX = 4095; + R_EDX = 1; + break; - default: - R_EAX = 0x00000000; - R_EBX = 0x00000000; - R_ECX = 0x00000000; - R_EDX = 0x00000000; - break; + default: + R_EAX = 0x00000000; + R_EBX = 0x00000000; + R_ECX = 0x00000000; + R_EDX = 0x00000000; + break; + } } break; case 0x5: //mwait info @@ -329,7 +368,8 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) R_ECX = 0; R_EDX = 0; break; - case 0x7: // extended bits... + case 0x7: + // extended bits... if(R_ECX==0) { R_EAX = 0; R_EBX = @@ -347,15 +387,28 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) } else {R_EAX = R_ECX = R_EBX = R_EDX = 0;} break; - case 0xB: // Extended Topology Enumeration Leaf - //TODO! - R_EAX = 0; - R_EBX = 0; + case 0xB: + if(box64_cputype) { + // reserved + R_EAX = R_EBX = R_ECX = R_EDX = 0 ; + } else { + // Extended Topology Enumeration Leaf + //TODO! + R_EAX = 0; + R_EBX = 0; + } break; - case 0xC: //? - R_EAX = 0; + case 0xC: + if(box64_cputype) { + // reserved + R_EAX = R_EBX = R_ECX = R_EDX = 0 ; + } else { + //? + R_EAX = 0; + } break; - case 0xD: // Processor Extended State Enumeration Main Leaf / Sub Leaf + case 0xD: + // Processor Extended State Enumeration Main Leaf / Sub Leaf switch(R_CX) { case 0: R_EAX = 0b111; // x87 SSE AVX saved @@ -382,66 +435,136 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) case 0xE: //? R_EAX = 0; break; - case 0xF: //L3 Cache - switch(R_ECX) { - case 0: - R_EAX = 0; - R_EBX = 0; // maximum range of RMID of physical processor - R_ECX = 0; - R_EDX = 0; // bit 1 support L3 RDT Cache monitoring - break; - case 1: - R_EAX = 0; - R_EBX = 0; // Conversion factor - R_EDX = 0; // bit 0 = occupency monitoring - break; - default: R_EAX = 0; + case 0xF: + if(box64_cputype) { + // reserved + R_EAX = R_EBX = R_ECX = R_EDX = 0 ; + } else { + //L3 Cache + switch(R_ECX) { + case 0: + R_EAX = 0; + R_EBX = 0; // maximum range of RMID of physical processor + R_ECX = 0; + R_EDX = 0; // bit 1 support L3 RDT Cache monitoring + break; + case 1: + R_EAX = 0; + R_EBX = 0; // Conversion factor + R_EDX = 0; // bit 0 = occupency monitoring + break; + default: R_EAX = 0; + } } break; - case 0x14: // Processor Trace Enumeration Main Leaf - switch(R_ECX) { - case 0: // main leaf - R_EAX = 0; // max sub-leaf - R_EBX = 0; - R_ECX = 0; - R_EDX = 0; - break; - default: R_EAX = 0; + case 0x14: + if(box64_cputype) { + // reserved + R_EAX = R_EBX = R_ECX = R_EDX = 0 ; + } else { + // Processor Trace Enumeration Main Leaf + switch(R_ECX) { + case 0: // main leaf + R_EAX = 0; // max sub-leaf + R_EBX = 0; + R_ECX = 0; + R_EDX = 0; + break; + default: R_EAX = 0; + } } break; - case 0x15: // TSC core frenquency - R_EAX = 1; // denominator - R_EBX = 1; // numerator - { - uint64_t freq = ReadTSCFrequency(emu); - while(freq>100000000) { - freq/=10; - R_EAX *= 10; + case 0x15: + if(box64_cputype) { + // reserved + R_EAX = R_EBX = R_ECX = R_EDX = 0 ; + } else { + // TSC core frenquency + R_EAX = 1; // denominator + R_EBX = 1; // numerator + { + uint64_t freq = ReadTSCFrequency(emu); + while(freq>100000000) { + freq/=10; + R_EAX *= 10; + } + R_ECX = freq; // nominal frequency in Hz } - R_ECX = freq; // nominal frequency in Hz + R_EDX = 0; } - R_EDX = 0; break; case 0x80000000: // max extended - R_EAX = 0x80000005; // was 0x80000007 before, but L2 cache description 0x80000006 is not correct and make some AC games to assert about l2 cache value coherency... + if(box64_cputype) { + R_EAX = 0x8000001a; + R_EBX = 0x68747541; + R_ECX = 0x444d4163; + R_EDX = 0x69746E65; + } else { + R_EAX = 0x80000005; // was 0x80000007 before, but L2 cache description 0x80000006 is not correct and make some AC games to assert about l2 cache value coherency... + } break; case 0x80000001: //Extended Processor Signature and Feature Bits - R_EAX = 0; // reserved - R_EBX = 0; // reserved - R_ECX = (1<<0) // LAHF_LM - | (1<<5) // LZCNT - | (1<<8) // PREFETCHW - ; - R_EDX = 1 // x87 FPU - | (1<<8) // cx8: cmpxchg8b opcode - | (1<<11) // syscall - | (1<<15) // cmov: FCMOV opcodes - | (1<<20) // NX - | (1<<23) // mmx: MMX available - | (1<<24) // fxsave - | (1<<27) // rdtscp - | (1<<29); // long mode 64bits available + if(box64_cputype) { + R_EAX = (0xc<<0) | // stepping 0-3 + (0x1<<4) | // base model 4-7 + (0xf<<8) | // base familly 8-11 + (0x0<<12)| // reserved 12-15 + (0x7<<16)| // Extented model 16-19 + (0x8<<20)| // extended familly 20-27 + (0x0<<28)| // reserved 28-31 + 0 ; // family and all, simulating a Ryzen 5 type of cpu + R_EBX = 0; //0-15 brandID, 16-27 reserved, 28-31 PkgType + R_ECX = 1<<0 // LAHF/SAHF + | 1<<1 // cmplegacy? + | 1<<2 // securevm + | 1<<5 // ABM (LZCNT) + //| 1<<6 // SSE4a (extrq, instrq, movntss, movntsd) + //| 1<<7 // misaligned SSE + | 1<<8 // 3DNowPrefetch + //| 1<<10 // IBS + //| 1<<11 // SSE5 + ; + R_EDX = 1 // fpu + | 1<<2 // debugging extension + | 1<<3 // pse + | 1<<4 // rdtsc + | 1<<5 // msr + | 1<<6 // pae + | 1<<8 // cmpxchg8 + | 1<<11 // sep (sysenter & sysexit) + | 1<<12 // mtrr + | 1<<15 // cmov + | 1<<16 // pat + | 1<<19 // clflush (seems to be with SSE2) + | 1<<21 // DS, used with VMX, is that usefull? + //| 1<<22 // MMXext + | 1<<23 // mmx + | 1<<24 // fxsr (fxsave, fxrestore) + //| 1<<25 // FFXSR + //| 1<<26 // Page1GB + | 1<<27 // RDTSCP + | 1<<29 //LM + //| 1<<30 //3DNowExt + //| 1<<31 //3DNow! + ; + } else { + R_EAX = 0; // reserved + R_EBX = 0; // reserved + R_ECX = (1<<0) // LAHF_LM + | (1<<5) // LZCNT + | (1<<8) // PREFETCHW + ; + R_EDX = 1 // x87 FPU + | (1<<8) // cx8: cmpxchg8b opcode + | (1<<11) // syscall + | (1<<15) // cmov: FCMOV opcodes + | (1<<20) // NX + | (1<<23) // mmx: MMX available + | (1<<24) // fxsave + | (1<<27) // rdtscp + | (1<<29); // long mode 64bits available + } break; case 0x80000002: // Brand part 1 (branding signature) R_EAX = ((uint32_t*)branding)[0]; @@ -462,22 +585,93 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) R_EDX = ((uint32_t*)branding)[11]; break; case 0x80000005: - R_EAX = 0; - R_EBX = 0; - R_ECX = 0; - R_EDX = 0; + if(box64_cputype) { + //L1 cache and TLB + R_EAX = 0; + R_EBX = 0; + R_ECX = 0; + R_EDX = 0; + } else { + R_EAX = 0; + R_EBX = 0; + R_ECX = 0; + R_EDX = 0; + } break; case 0x80000006: // L2 cache line size and associativity - R_EAX = 0; - R_EBX = 0; - R_ECX = 64 | (0x6<<12) | (256<<16); // bits: 0-7 line size, 15-12: assoc (using special encoding), 31-16: size in K //TODO: read info from /sys/devices/system/cpu/cpuX/cache/index2 - R_EDX = 0; + if(box64_cputype) { + R_EAX = 0; + R_EBX = 0; + R_ECX = 64 | (0x6<<12) | (256<<16); // bits: 0-7 line size, 15-12: assoc (using special encoding), 31-16: size in K //TODO: read info from /sys/devices/system/cpu/cpuX/cache/index2 + R_EDX = 0; + } else { + R_EAX = 0; + R_EBX = 0; + R_ECX = 64 | (0x6<<12) | (256<<16); // bits: 0-7 line size, 15-12: assoc (using special encoding), 31-16: size in K //TODO: read info from /sys/devices/system/cpu/cpuX/cache/index2 + R_EDX = 0; + } break; - case 0x80000007: // Invariant TSC - R_EAX = 0; - R_EBX = 0; - R_ECX = 0; - R_EDX = 0 | (1<<8); // Invariant TSC + case 0x80000007: + if(box64_cputype) { + // Advanced Power Management Information + R_EAX = 0; + R_EBX = 0; + R_ECX = 0; + R_EDX = 0 | (1<<8); // Invariant TSC + } else { + // Invariant TSC + R_EAX = 0; + R_EBX = 0; + R_ECX = 0; + R_EDX = 0 | (1<<8); // Invariant TSC + } + break; + case 0x80000008: + if(box64_cputype) { + // Address Size And Physical Core Count Information + R_EAX = 0; // 23-16 guest / 15-8 linear / 7-0 phys + R_EBX = 0; // reserved + R_ECX = ncpu-1; + R_EDX = 0; + } else { + // ? + R_EAX = 0; + R_EBX = 0; + R_ECX = 0; + R_EDX = 0; + } + break; + case 0x8000000a: + if(box64_cputype) { + // SVM Revision and Feature Identification + R_EAX = 0; + R_EBX = 0; + R_ECX = 0; + R_EDX = 0; + } else { + // ? + R_EAX = 0; + R_EBX = 0; + R_ECX = 0; + R_EDX = 0; + } + break; + case 0x8000001a: + if(box64_cputype) { + // Performance Optimization Identifiers + R_EAX = 1<<0 // FP128 + | 1<<1 // MOVU + | 0; + R_EBX = 0; + R_ECX = 0; + R_EDX = 0; + } else { + // ? + R_EAX = 0; + R_EBX = 0; + R_ECX = 0; + R_EDX = 0; + } break; default: printf_log(LOG_INFO, "Warning, CPUID command %X unsupported (ECX=%08x)\n", tmp32u, R_ECX); diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c index 5cbd421c..109133d3 100644 --- a/src/tools/rcfile.c +++ b/src/tools/rcfile.c @@ -127,6 +127,7 @@ ENTRYSTRING_(BOX64_ENV4, new_env4) \ ENTRYSTRING_(BOX64_ARGS, new_args) \ ENTRYSTRING_(BOX64_INSERT_ARGS, insert_args) \ ENTRYBOOL(BOX64_RESERVE_HIGH, new_reserve_high) \ +ENTRYINT(BOX64_CPUTYPE, box64_cputype, 0, 1, 1) \ #ifdef HAVE_TRACE #define SUPER2() \ |