diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-06 10:24:33 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-06 10:24:33 +0100 |
| commit | aed9ebd7d66fb3c4e9954c5d0759c2446b820ed3 (patch) | |
| tree | 7a89f8fbcb4222bf80d631fe208fe00d1c4ae930 | |
| parent | f335df23ec5276ebf67c0a9d59fb504da60839aa (diff) | |
| download | box64-aed9ebd7d66fb3c4e9954c5d0759c2446b820ed3.tar.gz box64-aed9ebd7d66fb3c4e9954c5d0759c2446b820ed3.zip | |
Added 0F A2 cpuid opcode
| -rwxr-xr-x | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/emu/x64run0f.c | 8 | ||||
| -rwxr-xr-x | src/include/cpu_info.h | 94 | ||||
| -rw-r--r-- | src/include/my_cpuid.h | 8 | ||||
| -rw-r--r-- | src/tools/my_cpuid.c | 188 |
5 files changed, 298 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index eff6854b..4934e0da 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,6 +127,7 @@ set(ELFLOADER_SRC "${BOX64_ROOT}/src/tools/box64stack.c" "${BOX64_ROOT}/src/tools/bridge.c" "${BOX64_ROOT}/src/tools/callback.c" + "${BOX64_ROOT}/src/tools/my_cpuid.c" "${BOX64_ROOT}/src/tools/pathcoll.c" "${BOX64_ROOT}/src/tools/fileutils.c" "${BOX64_ROOT}/src/tools/wine_tools.c" diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c index 51496f55..2544580f 100644 --- a/src/emu/x64run0f.c +++ b/src/emu/x64run0f.c @@ -18,7 +18,7 @@ #include "x64trace.h" #include "x87emu_private.h" #include "box64context.h" -//#include "my_cpuid.h" +#include "my_cpuid.h" #include "bridge.h" //#include "signals.h" #ifdef DYNAREC @@ -32,6 +32,7 @@ int Run0F(x64emu_t *emu, rex_t rex) uint8_t opcode; uint8_t nextop; int32_t tmp32s; + uint32_t tmp32u; reg64_t *oped, *opgd; opcode = F8; @@ -61,6 +62,11 @@ int Run0F(x64emu_t *emu, rex_t rex) , R_RIP += tmp32s; ) /* 0x80 -> 0x8F Jxx */ + case 0xA2: /* CPUID */ + tmp32u = R_EAX; + my_cpuid(emu, tmp32u); + break; + case 0xAF: /* IMUL Gd,Ed */ nextop = F8; GETED; diff --git a/src/include/cpu_info.h b/src/include/cpu_info.h new file mode 100755 index 00000000..18c4a1b9 --- /dev/null +++ b/src/include/cpu_info.h @@ -0,0 +1,94 @@ +#ifndef __CPU_INFO__H_ +#define __CPU_INFO__H_ +enum ProcessorVendors { + VENDOR_INTEL = 1, + VENDOR_AMD, + VENDOR_OTHER, + VENDOR_MAX +}; + +enum ProcessorTypes { + INTEL_ATOM = 1, + INTEL_CORE2, + INTEL_COREI7, + AMDFAM10H, + AMDFAM15H, + INTEL_i386, + INTEL_i486, + INTEL_PENTIUM, + INTEL_PENTIUM_PRO, + INTEL_PENTIUM_II, + INTEL_PENTIUM_III, + INTEL_PENTIUM_IV, + INTEL_PENTIUM_M, + INTEL_CORE_DUO, + INTEL_XEONPHI, + INTEL_X86_64, + INTEL_NOCONA, + INTEL_PRESCOTT, + AMD_i486, + AMDPENTIUM, + AMDATHLON, + AMDFAM14H, + AMDFAM16H, + CPU_TYPE_MAX +}; + +enum ProcessorSubtypes { + INTEL_COREI7_NEHALEM = 1, + INTEL_COREI7_WESTMERE, + INTEL_COREI7_SANDYBRIDGE, + AMDFAM10H_BARCELONA, + AMDFAM10H_SHANGHAI, + AMDFAM10H_ISTANBUL, + AMDFAM15H_BDVER1, + AMDFAM15H_BDVER2, + INTEL_PENTIUM_MMX, + INTEL_CORE2_65, + INTEL_CORE2_45, + INTEL_COREI7_IVYBRIDGE, + INTEL_COREI7_HASWELL, + INTEL_COREI7_BROADWELL, + INTEL_COREI7_SKYLAKE, + INTEL_COREI7_SKYLAKE_AVX512, + INTEL_ATOM_BONNELL, + INTEL_ATOM_SILVERMONT, + INTEL_KNIGHTS_LANDING, + AMDPENTIUM_K6, + AMDPENTIUM_K62, + AMDPENTIUM_K63, + AMDPENTIUM_GEODE, + AMDATHLON_TBIRD, + AMDATHLON_MP, + AMDATHLON_XP, + AMDATHLON_K8SSE3, + AMDATHLON_OPTERON, + AMDATHLON_FX, + AMDATHLON_64, + AMD_BTVER1, + AMD_BTVER2, + AMDFAM15H_BDVER3, + AMDFAM15H_BDVER4, + CPU_SUBTYPE_MAX +}; + +enum ProcessorFeatures { + FEATURE_CMOV = 0, + FEATURE_MMX, + FEATURE_POPCNT, + FEATURE_SSE, + FEATURE_SSE2, + FEATURE_SSE3, + FEATURE_SSSE3, + FEATURE_SSE4_1, + FEATURE_SSE4_2, + FEATURE_AVX, + FEATURE_AVX2, + FEATURE_AVX512, + FEATURE_AVX512SAVE, + FEATURE_MOVBE, + FEATURE_ADX, + FEATURE_EM64T +}; + +#endif \ No newline at end of file diff --git a/src/include/my_cpuid.h b/src/include/my_cpuid.h new file mode 100644 index 00000000..53792ea0 --- /dev/null +++ b/src/include/my_cpuid.h @@ -0,0 +1,8 @@ +#ifndef __MY_CPUID_H__ +#define __MY_CPUID_H__ +#include <stdint.h> +typedef struct x64emu_s x64emu_t; + +void my_cpuid(x64emu_t* emu, uint32_t tmp32u); + +#endif //__MY_CPUID_H__ \ No newline at end of file diff --git a/src/tools/my_cpuid.c b/src/tools/my_cpuid.c new file mode 100644 index 00000000..3aaf9d51 --- /dev/null +++ b/src/tools/my_cpuid.c @@ -0,0 +1,188 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "my_cpuid.h" +#include "../emu/x64emu_private.h" +#include "debug.h" + +int get_cpuMhz() +{ + int MHz = 0; +#ifdef __arm__ + FILE *f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", "r"); + if(f) { + int r; + if(1==fscanf(f, "%d", &r)) + MHz = r/1000; + fclose(f); + } +#endif + if(!MHz) + MHz = 1000; // default to 1Ghz... + return MHz; +} + +void my_cpuid(x64emu_t* emu, uint32_t tmp32u) +{ + emu->regs[_AX].dword[1] = emu->regs[_DX].dword[1] = emu->regs[_CX].dword[1] = emu->regs[_BX].dword[1] = 0; + switch(tmp32u) { + case 0x0: + // emulate a P4. TODO: Emulate a Core2? + R_EAX = 0x0000000D;//0x80000004; + // return GenuineIntel + R_EBX = 0x756E6547; + R_EDX = 0x49656E69; + R_ECX = 0x6C65746E; + break; + case 0x1: + R_EAX = 0x00000601; // familly and all + R_EBX = 0; // Brand indexe, CLFlush, Max APIC ID, Local APIC ID + R_EDX = 1 // fpu + | 1<<4 // rdtsc + | 1<<8 // cmpxchg8 + | 1<<11 // sep (sysenter & sysexit) + | 1<<15 // cmov + | 1<<19 // clflush (seems to be with SSE2) + | 1<<23 // mmx + | 1<<24 // fxsr (fxsave, fxrestore) + | 1<<25 // SSE + | 1<<26 // SSE2 + ; + R_ECX = 1<<0 // SSE3 + | 1<<9 // SSSE3 + | 1<<12 // fma + | 1<<13 // cx16 (cmpxchg16) + ; + break; + case 0x2: // 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)); //type + 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; + } + break; + case 0x5: //mwait info + R_EAX = 0; + R_EBX = 0; + R_ECX = 1 | 2; + R_EDX = 0; + break; + case 0x3: // PSN + case 0x6: // thermal + case 0x8: // more extended capabilities + case 0x9: // direct cache access + case 0xA: // Architecture performance monitor + R_EAX = 0; + R_EBX = 0; + R_ECX = 0; + R_EDX = 0; + break; + case 0x7: // extended bits... + /*if(R_ECX==0) R_EAX = 0; + else*/ R_EAX = R_ECX = R_EBX = R_EDX = 0; + break; + case 0xB: // Extended Topology Enumaretion Leaf + //TODO! + R_EAX = 0; + break; + case 0xC: //? + R_EAX = 0; + break; + case 0xD: // Processor Extended State Enumeration Main Leaf / Sub Leaf + if(R_CX==0) { + R_EAX = 1 | 2; // x87 SSE saved + R_EBX = 512; // size of xsave/xrstor + R_ECX = 512; // same + R_EDX = 0; // more bits + } else if(R_CX==1){ + R_EAX = R_ECX = R_EBX = R_EDX = 0; // XSAVEOPT and co are not available + } else { + R_EAX = R_ECX = R_EBX = R_EDX = 0; + } + break; + + case 0x80000000: // max extended + R_EAX = 0x80000005; + break; + case 0x80000001: //Extended Processor Signature and Feature Bits + R_EAX = 0; // reserved + R_EBX = 0; // reserved + R_ECX = (1<<5) | (1<<8); // LZCNT | PREFETCHW + R_EDX = 0; + break; + case 0x80000002: // Brand part 1 (P4 signature) + R_EAX = 0x20202020; + R_EBX = 0x20202020; + R_ECX = 0x20202020; + R_EDX = 0x6E492020; + break; + case 0x80000003: // Brand part 2 + R_EAX = 0x286C6574; + R_EBX = 0x50202952; + R_ECX = 0x69746E65; + R_EDX = 0x52286D75; + break; + case 0x80000004: // Brand part 3, with frequency + R_EAX = 0x20342029; + R_EBX = 0x20555043; + { + static int MHz = 0; + if(!MHz) + MHz = get_cpuMhz(); + if(MHz>15000) { // swiches to GHz display... + char tmp[11]; + sprintf(tmp, "%1.2f", MHz/1000.); + R_ECX = *(uint32_t*)tmp; + R_EDX = 0x007A4847; // GHz + } else { + char tmp[11]; + sprintf(tmp, "%04d", MHz); + R_ECX = *(uint32_t*)tmp; + R_EDX = 0x007A484D; // MHz + } + } + break; + case 0x80000005: + 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); + R_EAX = 0; + R_EBX = 0; + R_ECX = 0; + R_EDX = 0; + } +} |