about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core.c85
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c3
-rw-r--r--src/emu/x64run0f.c2
-rw-r--r--src/include/debug.h1
-rw-r--r--src/include/my_cpuid.h1
-rw-r--r--src/tools/my_cpuid.c7
-rw-r--r--src/tools/rcfile.c4
7 files changed, 66 insertions, 37 deletions
diff --git a/src/core.c b/src/core.c
index 2c583226..9d6b4042 100644
--- a/src/core.c
+++ b/src/core.c
@@ -65,6 +65,7 @@ int box64_mmap32 = 0;
 #endif
 int box64_ignoreint3 = 0;
 int box64_rdtsc = 0;
+int box64_rdtsc_1ghz = 0;
 uint8_t box64_rdtsc_shift = 0;
 #ifdef DYNAREC
 int box64_dynarec = 1;
@@ -504,6 +505,45 @@ HWCAP2_ECV
 }
 #endif
 
+void computeRDTSC()
+{
+    int hardware  = 0;
+    box64_rdtsc_shift = 0;
+    #if defined(ARM64) || defined(RV64)
+    hardware = 1;
+    box64_rdtsc = 0;    // allow hardxare counter
+    #else
+    box64_rdtsc = 1;
+    printf_log(LOG_INFO, "Will use time-based emulation for rdtsc, even if hardware counter are available\n");
+    #endif
+    uint64_t freq = ReadTSCFrequency(NULL);
+    if(freq<(box64_rdtsc_1ghz)?1000000000LL:1000000) {
+        box64_rdtsc = 1;
+        if(hardware) printf_log(LOG_INFO, "Hardware counter to slow (%d kHz), not using it\n", freq/1000);
+        hardware = 0;
+        freq = ReadTSCFrequency(NULL);
+    }
+    uint64_t efreq = freq;
+    while(efreq<2000000000) {    // minium 2GHz
+        ++box64_rdtsc_shift;
+        efreq = freq<<box64_rdtsc_shift;
+    }
+    printf_log(LOG_INFO, "Will use %s counter measured at ", box64_rdtsc?"Software":"Hardware");
+    int ghz = freq>=1000000000LL;
+    if(ghz) freq/=100000000LL; else freq/=100000;
+    if(ghz) printf_log(LOG_INFO, "%d.%d GHz", freq/10, freq%10);
+    if(!ghz && (freq>=1000)) printf_log(LOG_INFO, "%d MHz", freq/10);
+    if(!ghz && (freq<1000)) printf_log(LOG_INFO, "%d.%d MHz", freq/10, freq%10);
+    if(box64_rdtsc_shift) {
+        printf_log(LOG_INFO, " emulating ");
+        ghz = efreq>=1000000000LL;
+        if(ghz) efreq/=100000000LL; else efreq/=100000;
+        if(ghz) printf_log(LOG_INFO, "%d.%d GHz", efreq/10, efreq%10);
+        if(!ghz && (efreq>=1000)) printf_log(LOG_INFO, "%d MHz", efreq/10);
+        if(!ghz && (efreq<1000)) printf_log(LOG_INFO, "%d.%d MHz", efreq/10, efreq%10);
+    }
+    printf_log(LOG_INFO, "\n");
+}
 
 EXPORTDYN
 void LoadLogEnv()
@@ -1005,6 +1045,15 @@ void LoadLogEnv()
             printf_log(LOG_INFO, "Will expose AVX2 capabilities\n");
         }
     }
+    p = getenv("BOX64_RDTSC_1GHZ");
+    if(p) {
+        if(strlen(p)==1) {
+            if(p[0]>='0' && p[0]<='0'+1)
+                box64_rdtsc_1ghz = p[0]-'0';
+        }
+        if(!box64_rdtsc_1ghz)
+            printf_log(LOG_INFO, "Will require a hardware counter of 1GHz minimum or will fallback to software\n");
+    }
     p = getenv("BOX64_FIX_64BIT_INODES");
     if(p) {
         if(strlen(p)==1) {
@@ -1087,41 +1136,7 @@ void LoadLogEnv()
     const char* cpuname = getCpuName();
     printf_log(LOG_INFO, " PageSize:%zd Running on %s with %d Cores\n", box64_pagesize, cpuname, ncpu);
     // grab and calibrate hardware counter
-    int hardware  = 0;
-    #if defined(ARM64) || defined(RV64)
-    hardware = 1;
-    box64_rdtsc = 0;    // allow hardxare counter
-    #else
-    box64_rdtsc = 1;
-    printf_log(LOG_INFO, "Will use time-based emulation for rdtsc, even if hardware counter are available\n");
-    #endif
-    uint64_t freq = ReadTSCFrequency(NULL);
-    if(freq<1000000) {
-        box64_rdtsc = 1;
-        if(hardware) printf_log(LOG_INFO, "Hardware counter to slow (%d kHz), not using it\n", freq/1000);
-        hardware = 0;
-        freq = ReadTSCFrequency(NULL);
-    }
-    uint64_t efreq = freq;
-    while(efreq<2000000000) {    // minium 2GHz
-        ++box64_rdtsc_shift;
-        efreq = freq<<box64_rdtsc_shift;
-    }
-    printf_log(LOG_INFO, "Will use %s counter measured at ", box64_rdtsc?"Software":"Hardware");
-    int ghz = freq>=1000000000LL;
-    if(ghz) freq/=100000000LL; else freq/=100000;
-    if(ghz) printf_log(LOG_INFO, "%d.%d GHz", freq/10, freq%10);
-    if(!ghz && (freq>=1000)) printf_log(LOG_INFO, "%d MHz", freq/10);
-    if(!ghz && (freq<1000)) printf_log(LOG_INFO, "%d.%d MHz", freq/10, freq%10);
-    if(box64_rdtsc_shift) {
-        printf_log(LOG_INFO, " emulating ");
-        ghz = efreq>=1000000000LL;
-        if(ghz) efreq/=100000000LL; else efreq/=100000;
-        if(ghz) printf_log(LOG_INFO, "%d.%d GHz", efreq/10, efreq%10);
-        if(!ghz && (efreq>=1000)) printf_log(LOG_INFO, "%d MHz", efreq/10);
-        if(!ghz && (efreq<1000)) printf_log(LOG_INFO, "%d.%d MHz", efreq/10, efreq%10);
-    }
-    printf_log(LOG_INFO, "\n");
+    computeRDTSC();
 }
 
 EXPORTDYN
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index 596c9fd1..3fe4d540 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -101,7 +101,8 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }

                     LSRx(xRDX, x1, 32);

                     MOVw_REG(xRAX, x1);   // wipe upper part

-                    MOVw_REG(xRCX, xZR);    // IA32_TSC, 0 for now

+                    CALL_(helper_getcpu, x1, x3);

+                    MOVw_REG(xRCX, x1);    // IA32_TSC, 0 for now

                     break;

                 default:

                     DEFAULT;

diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c
index 8fc5e645..2a2c78cb 100644
--- a/src/emu/x64run0f.c
+++ b/src/emu/x64run0f.c
@@ -118,7 +118,7 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
                         tmp64u<<=box64_rdtsc_shift;

                     R_RAX = tmp64u & 0xffffffff;

                     R_RDX = tmp64u >> 32;

-                    R_RCX = 0;  // should be low of IA32_TSC

+                    R_RCX = helper_getcpu(emu);

                     #ifdef TEST_INTERPRETER

                     test->notest = 1;

                     #endif

diff --git a/src/include/debug.h b/src/include/debug.h
index be48b59e..4af3b0cb 100644
--- a/src/include/debug.h
+++ b/src/include/debug.h
@@ -14,6 +14,7 @@ extern int box64_maxcpu;
 extern int box64_mmap32;
 extern int box64_ignoreint3;
 extern int box64_rdtsc;
+extern int box64_rdtsc_1ghz;
 extern uint8_t box64_rdtsc_shift;
 #ifdef DYNAREC
 extern int box64_dynarec_dump;
diff --git a/src/include/my_cpuid.h b/src/include/my_cpuid.h
index 53792ea0..a8c4dcec 100644
--- a/src/include/my_cpuid.h
+++ b/src/include/my_cpuid.h
@@ -4,5 +4,6 @@
 typedef struct x64emu_s x64emu_t;
 
 void my_cpuid(x64emu_t* emu, uint32_t tmp32u);
+uint32_t helper_getcpu(x64emu_t* emu);  // get the numa/cpu id actually running
 
 #endif //__MY_CPUID_H__
\ No newline at end of file
diff --git a/src/tools/my_cpuid.c b/src/tools/my_cpuid.c
index 06d810aa..00859cc8 100644
--- a/src/tools/my_cpuid.c
+++ b/src/tools/my_cpuid.c
@@ -468,3 +468,10 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u)
             R_EDX = 0;
     }   
 }
+
+uint32_t helper_getcpu(x64emu_t* emu) {
+    uint32_t cpu, node;
+    if(!getcpu(&cpu, &node))
+        return (node&0xff)<<12 | (cpu&0xff);
+    return 0;
+}
\ No newline at end of file
diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c
index 2b45dd06..cd1316f4 100644
--- a/src/tools/rcfile.c
+++ b/src/tools/rcfile.c
@@ -99,6 +99,7 @@ ENTRYBOOL(BOX64_CRASHHANDLER, box64_dummy_crashhandler) \
 ENTRYBOOL(BOX64_NOPULSE, box64_nopulse)                 \
 ENTRYBOOL(BOX64_NOGTK, box64_nogtk)                     \
 ENTRYBOOL(BOX64_NOVULKAN, box64_novulkan)               \
+ENTRYBOOL(BOX64_RDTSC_1GHZ, box64_rdtsc_1ghz)           \
 ENTRYBOOL(BOX64_SSE42, box64_sse42)                     \
 ENTRYINT(BOX64_AVX, new_avx, 0, 2, 2)                   \
 ENTRYBOOL(BOX64_FUTEX_WAITV, box64_futex_waitv)         \
@@ -489,6 +490,7 @@ extern char* ftrace_name;
 void openFTrace(const char* newtrace);
 void addNewEnvVar(const char* s);
 void AddNewLibs(const char* libs);
+void computeRDTSC();
 #ifdef DYNAREC
 void GatherDynarecExtensions();
 #endif
@@ -568,6 +570,8 @@ void ApplyParams(const char* name)
             box64_avx = 1; box64_avx2 = 1;
         }
     }
+    if(param->is_box64_rdtsc_1ghz_present)
+        computeRDTSC();
     #ifdef DYNAREC
     if(param->is_box64_dynarec_jvm_present && !param->is_box64_jvm_present)
         box64_jvm = box64_dynarec_jvm;