From e14d8abb6197c8e9ae5f0ee523c539b52c26d712 Mon Sep 17 00:00:00 2001 From: rajdakin Date: Tue, 16 Jul 2024 11:15:33 +0200 Subject: [PATCH] [MAXCPU] Added support for maxcpu (backport from box64) (#982) * [MAXCPU] Added support for maxcpu (backport from box64) * [MAXCPU] Added documentation for maxcpu * [ARM PRINTER] Fixed ADR decoder * [WRAPPED] Fixed wrapped libc --- docs/USAGE.md | 5 +++++ rebuild_printer.py | 2 +- src/dynarec/arm_instructions.txt | 2 ++ src/dynarec/arm_printer.c | 24 ++++++++++++------------ src/dynarec/last_run.txt | 2 ++ src/include/debug.h | 2 ++ src/main.c | 18 ++++++++++++++++++ src/tools/my_cpuid.c | 4 ++-- src/tools/rcfile.c | 9 +++++++++ src/wrapped/wrappedlibc.c | 26 ++++++++++++++++++++++---- 10 files changed, 75 insertions(+), 19 deletions(-) diff --git a/docs/USAGE.md b/docs/USAGE.md index 106c59682..7b8bbe1b9 100755 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -206,6 +206,11 @@ Handling of x87 80bits long double * 0 : Try to handle 80bits long double as precise as possible (Default) * 1 : Handle them as double +#### BOX64_MAXCPU +Maximum CPU Core exposed +* 0 : Don't cap the number of cpu core exposed (Default) +* XXX : Cap the maximum CPU Core exposed to XXX (usefull with wine64 or GridAutosport for example) + #### BOX86_LIBCEF * Detect libcef and apply malloc_hack settings * 0 : Don't detect libcef diff --git a/rebuild_printer.py b/rebuild_printer.py index d9f1788b4..a08b9aff4 100755 --- a/rebuild_printer.py +++ b/rebuild_printer.py @@ -72,7 +72,7 @@ def append(strg): # Get all actual instructions # Ignore white lines and lines beginning with either !, ; or # - insts = list(filter(lambda l: not re.match("^\s*$", l) and not re.match("^([!;#])", l), insts.split('\n'))) + insts = list(filter(lambda l: not re.match("^\\s*$", l) and not re.match("^([!;#])", l), insts.split('\n'))) try: # Do not open with `with` to be able to open it in writing mode diff --git a/src/dynarec/arm_instructions.txt b/src/dynarec/arm_instructions.txt index 14793f951..eb4bec7b3 100644 --- a/src/dynarec/arm_instructions.txt +++ b/src/dynarec/arm_instructions.txt @@ -471,8 +471,10 @@ ARM_ cond 0 0 0 1 1 1 1 0 Rn Rd (1) (1) (1) (1) 1 0 0 1 Rt STREXH , , ARM_ cond 0 0 0 1 1 1 1 1 Rn Rt (1) (1) (1) (1) 1 0 0 1 (1) (1) (1) (1) LDREXH , [] ARM_ cond 0 0 1 0 0 0 0 S Rn Rd imm12 AND{S} , , # ARM_ cond 0 0 1 0 0 0 1 S Rn Rd imm12 EOR{S} , , # +ARM_ cond 0 0 1 0 0 1 0 0 1 1 1 1 Rd imm12 ADR , #- ARM_ cond 0 0 1 0 0 1 0 S Rn Rd imm12 SUB{S} , , # ARM_ cond 0 0 1 0 0 1 1 S Rn Rd imm12 RSB{S} , , # +ARM_ cond 0 0 1 0 1 0 0 0 1 1 1 1 Rd imm12 ADR , # ARM_ cond 0 0 1 0 1 0 0 S Rn Rd imm12 ADD{S} , , # ARM_ cond 0 0 1 0 1 0 1 S Rn Rd imm12 ADC{S} , , # ARM_ cond 0 0 1 0 1 1 0 S Rn Rd imm12 SBC{S} , , # diff --git a/src/dynarec/arm_printer.c b/src/dynarec/arm_printer.c index 0b678333c..6041a6cf1 100644 --- a/src/dynarec/arm_printer.c +++ b/src/dynarec/arm_printer.c @@ -3944,18 +3944,6 @@ const char* arm_print(uint32_t opcode) { uint8_t shift = ((opcode >> 4) & 0xFF); sprintf(ret, "TEQ%s %s, %s%s", cond, regname[rn], regname[rm], print_shift(shift, 1)); - } else if ((opcode&0b00001111111111110000000000000000) == 0b00000010100011110000000000000000) { - const char* cond = conds[(opcode >> 28) & 0xF]; - int rd = (opcode >> 16) & 0xF; - uint32_t imm12 = opcode&0b111111111111; - - sprintf(ret, "ADR %s, #0x%x", regname[rd], imm12); - } else if ((opcode&0b00001111111111110000000000000000) == 0b00000010010011110000000000000000) { - const char* cond = conds[(opcode >> 28) & 0xF]; - int rd = (opcode >> 16) & 0xF; - uint32_t imm12 = opcode&0b111111111111; - - sprintf(ret, "ADR %s, #-0x%x", regname[rd], imm12); } else if ((opcode & 0x0FF000F0) == 0x01400090) { const char* cond = conds[(opcode >> 28) & 0xF]; int rt = (opcode >> 12) & 0xF; @@ -4209,6 +4197,12 @@ const char* arm_print(uint32_t opcode) { uint16_t imm12 = ((opcode >> 0) & 0xFFF); sprintf(ret, "EOR%s%s %s, %s, #0x%x", (s ? "S" : ""), cond, regname[rd], regname[rn], print_modified_imm_ARM(imm12)); + } else if ((opcode & 0x0FFF0000) == 0x024F0000) { + const char* cond = conds[(opcode >> 28) & 0xF]; + int rd = (opcode >> 12) & 0xF; + uint16_t imm12 = ((opcode >> 0) & 0xFFF); + + sprintf(ret, "ADR%s %s, #-0x%x", cond, regname[rd], print_modified_imm_ARM(imm12)); } else if ((opcode & 0x0FE00000) == 0x02400000) { int s = (opcode >> 20) & 1; const char* cond = conds[(opcode >> 28) & 0xF]; @@ -4225,6 +4219,12 @@ const char* arm_print(uint32_t opcode) { uint16_t imm12 = ((opcode >> 0) & 0xFFF); sprintf(ret, "RSB%s%s %s, %s, #0x%x", (s ? "S" : ""), cond, regname[rd], regname[rn], print_modified_imm_ARM(imm12)); + } else if ((opcode & 0x0FFF0000) == 0x028F0000) { + const char* cond = conds[(opcode >> 28) & 0xF]; + int rd = (opcode >> 12) & 0xF; + uint16_t imm12 = ((opcode >> 0) & 0xFFF); + + sprintf(ret, "ADR%s %s, #0x%x", cond, regname[rd], print_modified_imm_ARM(imm12)); } else if ((opcode & 0x0FE00000) == 0x02800000) { int s = (opcode >> 20) & 1; const char* cond = conds[(opcode >> 28) & 0xF]; diff --git a/src/dynarec/last_run.txt b/src/dynarec/last_run.txt index 5fb119172..e4ab7d2b3 100644 --- a/src/dynarec/last_run.txt +++ b/src/dynarec/last_run.txt @@ -353,8 +353,10 @@ ARM_ cond 0 0 0 1 1 1 1 0 Rn Rd (1) (1) (1) (1) 1 0 0 1 Rt STREXH , , ARM_ cond 0 0 0 1 1 1 1 1 Rn Rt (1) (1) (1) (1) 1 0 0 1 (1) (1) (1) (1) LDREXH , [] ARM_ cond 0 0 1 0 0 0 0 S Rn Rd imm12 AND{S} , , # ARM_ cond 0 0 1 0 0 0 1 S Rn Rd imm12 EOR{S} , , # +ARM_ cond 0 0 1 0 0 1 0 0 1 1 1 1 Rd imm12 ADR , #- ARM_ cond 0 0 1 0 0 1 0 S Rn Rd imm12 SUB{S} , , # ARM_ cond 0 0 1 0 0 1 1 S Rn Rd imm12 RSB{S} , , # +ARM_ cond 0 0 1 0 1 0 0 0 1 1 1 1 Rd imm12 ADR , # ARM_ cond 0 0 1 0 1 0 0 S Rn Rd imm12 ADD{S} , , # ARM_ cond 0 0 1 0 1 0 1 S Rn Rd imm12 ADC{S} , , # ARM_ cond 0 0 1 0 1 1 0 S Rn Rd imm12 SBC{S} , , # diff --git a/src/include/debug.h b/src/include/debug.h index afff0ab43..50a179cbc 100755 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -10,6 +10,8 @@ extern int box86_dynarec; extern uintptr_t box86_pagesize; extern uintptr_t box86_load_addr; extern int box86_showbt; +extern int box86_maxcpu; +extern int box86_maxcpu_immutable; #ifdef DYNAREC extern int box86_dynarec_dump; extern int box86_dynarec_trace; diff --git a/src/main.c b/src/main.c index 8009c4776..d9025f237 100644 --- a/src/main.c +++ b/src/main.c @@ -51,6 +51,8 @@ int box86_dynarec_log = LOG_NONE; uintptr_t box86_pagesize; uintptr_t box86_load_addr = 0; int box86_showbt = 0; +int box86_maxcpu = 0; +int box86_maxcpu_immutable = 0; int box86_isglibc234 = 0; int box86_nosandbox = 0; int box86_malloc_hack = 0; @@ -759,6 +761,19 @@ void LoadLogEnv() if(box86_showbt) printf_log(LOG_INFO, "Show Backtrace for signals\n"); } + p = getenv("BOX64_MAXCPU"); + if(p) { + int maxcpu = 0; + if(sscanf(p, "%d", &maxcpu)==1) + box86_maxcpu = maxcpu; + if(box86_maxcpu<0) + box86_maxcpu = 0; + if(box86_maxcpu) { + printf_log(LOG_INFO, "Will not expose more than %d cpu cores\n", box86_maxcpu); + } else { + printf_log(LOG_INFO, "Will not limit the number of cpu cores exposed\n"); + } + } box86_pagesize = sysconf(_SC_PAGESIZE); if(!box86_pagesize) box86_pagesize = 4096; @@ -1569,6 +1584,9 @@ int main(int argc, const char **argv, char **env) my_context->argv[i] = box_strdup(argv[i+nextarg]); printf_log(LOG_INFO, "argv[%i]=\"%s\"\n", i, my_context->argv[i]); } + if(box86_wine) { + box86_maxcpu_immutable = 1; // cannot change once wine is loaded + } if(box86_nosandbox) { add_argv("--no-sandbox"); diff --git a/src/tools/my_cpuid.c b/src/tools/my_cpuid.c index 56368b77c..76c3ccc57 100644 --- a/src/tools/my_cpuid.c +++ b/src/tools/my_cpuid.c @@ -93,8 +93,8 @@ int getNCpu() { if(!nCPU) grabNCpu(); - if(box86_wine && nCPU>32) - return 32; + if(box86_maxcpu && nCPU>box86_maxcpu) + return box86_maxcpu; return nCPU; } diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c index b1cfad5b0..5c7eaced7 100644 --- a/src/tools/rcfile.c +++ b/src/tools/rcfile.c @@ -55,6 +55,7 @@ ENTRYBOOL(BOX86_LIBCEF, box86_libcef) \ ENTRYBOOL(BOX86_SDL2_JGUID, box86_sdl2_jguid) \ ENTRYBOOL(BOX86_MUTEX_ALIGNED, box86_mutex_aligned) \ ENTRYINT(BOX86_MALLOC_HACK, box86_malloc_hack, 0, 2, 2) \ +ENTRYINTPOS(BOX86_MAXCPU, new_maxcpu) \ #ifdef HAVE_TRACE #define SUPER2() \ @@ -399,6 +400,7 @@ void ApplyParams(const char* name, path_collection_t* preload) return; static const char* old_name = NULL; int new_cycle_log = cycle_log; + int new_maxcpu = box86_maxcpu; if(old_name && !strcmp(name, old_name)) return; old_name = name; @@ -442,6 +444,13 @@ void ApplyParams(const char* name, path_collection_t* preload) cycle_log = new_cycle_log; initCycleLog(my_context); } + if(!box86_maxcpu_immutable) { + if(new_maxcpu!=box86_maxcpu && box86_maxcpu && box86_maxcpuis_ld_library_path_present) AppendList(&my_context->box86_ld_lib, param->ld_library_path, 1); if(param->is_box86_path_present) AppendList(&my_context->box86_path, param->box86_path, 1); if(param->is_trace_file_present) { diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index ebc68b9ef..9618cd03f 100755 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -1892,6 +1892,15 @@ EXPORT int32_t my_open(x86emu_t* emu, void* pathname, int32_t flags, uint32_t mo lseek(tmp, 0, SEEK_SET); return tmp; } + if(box86_maxcpu && (!strcmp(pathname, "/sys/devices/system/cpu/present") || !strcmp(pathname, "/sys/devices/system/cpu/online")) && (getNCpu()>=box86_maxcpu)) { + // special case for cpu present (to limit to box86_maxcpu cores) + int tmp = shm_open(TMP_CPUPRESENT, O_RDWR | O_CREAT, S_IRWXU); + if(tmp<0) return open(pathname, flags, mode); // error fallback + shm_unlink(TMP_CPUPRESENT); // remove the shm file, but it will still exist because it's currently in use + CreateCPUPresentFile(tmp); + lseek(tmp, 0, SEEK_SET); + return tmp; + } if(isCpuTopology((const char*)pathname)!=-1) { int n = isCpuTopology((const char*)pathname); char buf[512]; @@ -2009,6 +2018,15 @@ EXPORT int32_t my_open64(x86emu_t* emu, void* pathname, int32_t flags, uint32_t lseek(tmp, 0, SEEK_SET); return tmp; } + if(box86_maxcpu && (!strcmp(pathname, "/sys/devices/system/cpu/present") || !strcmp(pathname, "/sys/devices/system/cpu/online")) && (getNCpu()>=box86_maxcpu)) { + // special case for cpu present (to limit to box86_maxcpu cores) + int tmp = shm_open(TMP_CPUPRESENT, O_RDWR | O_CREAT, S_IRWXU); + if(tmp<0) return open64(pathname, flags, mode); // error fallback + shm_unlink(TMP_CPUPRESENT); // remove the shm file, but it will still exist because it's currently in use + CreateCPUPresentFile(tmp); + lseek(tmp, 0, SEEK_SET); + return fdopen(tmp, mode); + } if(isCpuTopology((const char*)pathname)!=-1) { int n = isCpuTopology((const char*)pathname); char buf[512]; @@ -2084,8 +2102,8 @@ EXPORT FILE* my_fopen(x86emu_t* emu, const char* path, const char* mode) lseek(tmp, 0, SEEK_SET); return fdopen(tmp, mode);; } - if(box86_wine && (!strcmp(path, "/sys/devices/system/cpu/present") || !strcmp(path, "/sys/devices/system/cpu/online")) && (getNCpu()>=32)) { - // special case for cpu present (to limit to 64 cores) + if(box86_maxcpu && (!strcmp(path, "/sys/devices/system/cpu/present") || !strcmp(path, "/sys/devices/system/cpu/online")) && (getNCpu()>=box86_maxcpu)) { + // special case for cpu present (to limit to box86_maxcpu cores) int tmp = shm_open(TMP_CPUPRESENT, O_RDWR | O_CREAT, S_IRWXU); if(tmp<0) return fopen(path, mode); // error fallback shm_unlink(TMP_CPUPRESENT); // remove the shm file, but it will still exist because it's currently in use @@ -2160,8 +2178,8 @@ EXPORT FILE* my_fopen64(x86emu_t* emu, const char* path, const char* mode) lseek(tmp, 0, SEEK_SET); return fdopen(tmp, mode);; } - if(box86_wine && (!strcmp(path, "/sys/devices/system/cpu/present") || !strcmp(path, "/sys/devices/system/cpu/online")) && (getNCpu()>=32)) { - // special case for cpu present (to limit to 64 cores) + if(box86_maxcpu && (!strcmp(path, "/sys/devices/system/cpu/present") || !strcmp(path, "/sys/devices/system/cpu/online")) && (getNCpu()>=box86_maxcpu)) { + // special case for cpu present (to limit to box86_maxcpu cores) int tmp = shm_open(TMP_CPUPRESENT, O_RDWR | O_CREAT, S_IRWXU); if(tmp<0) return fopen64(path, mode); // error fallback shm_unlink(TMP_CPUPRESENT); // remove the shm file, but it will still exist because it's currently in use