about summary refs log tree commit diff stats
path: root/src/tools
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-02-23 16:41:44 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-02-23 16:41:44 +0100
commitffda782c3d88d977acc12a3c2c2738719f9304ed (patch)
treea0e1893fb28090c4f0f2a26c7a67bb40ae71f6b5 /src/tools
parent3a6df996dc85257a5496ecb28a72579df225a176 (diff)
downloadbox64-ffda782c3d88d977acc12a3c2c2738719f9304ed.tar.gz
box64-ffda782c3d88d977acc12a3c2c2738719f9304ed.zip
Better handling of Hardware counter for rdtsc emulation (ARM64 only for now), more cpuid leafs, and introduce BOX64_RDTSC env.var. with a profile that use it
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/my_cpuid.c29
-rw-r--r--src/tools/rcfile.c18
2 files changed, 45 insertions, 2 deletions
diff --git a/src/tools/my_cpuid.c b/src/tools/my_cpuid.c
index 7ee95ff0..bc584851 100644
--- a/src/tools/my_cpuid.c
+++ b/src/tools/my_cpuid.c
@@ -182,7 +182,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u)
     switch(tmp32u) {
         case 0x0:
             // emulate a P4. TODO: Emulate a Core2?
-            R_EAX = 0x0000000F;//0x80000004;
+            R_EAX = 0x00000015;//0x80000004;
             // return GenuineIntel
             R_EBX = 0x756E6547;
             R_EDX = 0x49656E69;
@@ -321,9 +321,22 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u)
                 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;
+                }
+                R_ECX = freq;  // nominal frequency in Hz
+            }
+            R_EDX = 0;
+            break;
 
         case 0x80000000:        // max extended
-            R_EAX = 0x80000005;
+            R_EAX = 0x80000007;
             break;
         case 0x80000001:        //Extended Processor Signature and Feature Bits
             R_EAX = 0;  // reserved
@@ -362,6 +375,18 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u)
             R_ECX = 0;
             R_EDX = 0;
             break;
+        case 0x80000006:    // L2 cache line size and associativity
+            R_EAX = 0;
+            R_EBX = 0;
+            R_ECX = 0;
+            R_EDX = 0;
+            break;
+        case 0x80000007:    // Invariant TSC
+            R_EAX = 0;
+            R_EBX = 0;
+            R_ECX = 0;
+            R_EDX = 0 | (1<<8); // Invariant TSC
+            break;
         default:
             printf_log(LOG_INFO, "Warning, CPUID command %X unsupported (ECX=%08x)\n", tmp32u, R_ECX);
             R_EAX = 0;
diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c
index b628fb6b..9c44336c 100644
--- a/src/tools/rcfile.c
+++ b/src/tools/rcfile.c
@@ -10,6 +10,7 @@
 #include "box64context.h"
 #include "fileutils.h"
 #include "pathcoll.h"
+#include "x64emu.h"
 #ifdef HAVE_TRACE
 #include "x64trace.h"
 #endif
@@ -88,6 +89,7 @@ ENTRYBOOL(BOX64_SHOWSEGV, box64_showsegv)               \
 ENTRYBOOL(BOX64_SHOWBT, box64_showbt)                   \
 ENTRYBOOL(BOX64_MMAP32, box64_mmap32)                   \
 ENTRYBOOL(BOX64_IGNOREINT3, box64_ignoreint3)           \
+ENTRYINT(BOX64_RDTSC, box64_rdtsc, 0, 2, 2)             \
 ENTRYBOOL(BOX64_X11THREADS, box64_x11threads)           \
 ENTRYBOOL(BOX64_X11GLX, box64_x11glx)                   \
 ENTRYDSTRING(BOX64_LIBGL, box64_libGL)                  \
@@ -574,6 +576,22 @@ void ApplyParams(const char* name)
         my_context->bashpath = strdup(param->bash);
         printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_BASH", param->bash);
     }
+    if(param->is_box64_rdtsc_present && (box64_rdtsc==2)) {
+        #if defined(ARM64)
+        box64_rdtsc = 0;    // allow hardxware counter
+        uint64_t freq = ReadTSCFrequency(NULL);
+        printf_log(LOG_INFO, "Applying RDTSC: Hardware counter measured at %d Mhz, ", freq/1000);
+        if(freq>1000000000) {
+            printf_log(LOG_INFO, "keeping it\n");
+        } else {
+            box64_rdtsc = 1;
+            printf_log(LOG_INFO, "not using it\n");
+        }
+        #else
+        box64_rdtsc = 1;
+        printf_log(LOG_INFO, "Applying RDTSC: Will use time-based emulation for rdtsc, even if hardware counter are available\n");
+        #endif
+    }
     #ifdef HAVE_TRACE
     int old_x64trace = my_context->x64trace;
     if(param->is_trace_present) {