Skip to content

Commit

Permalink
drc: another try to fix thread cache stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
notaz committed Dec 17, 2024
1 parent a7a6db3 commit d8f2909
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 14 deletions.
24 changes: 18 additions & 6 deletions libpcsxcore/new_dynarec/emu_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "../gte_arm.h"
#include "../gte_neon.h"
#include "compiler_features.h"
#include "arm_features.h"
#define FLAGLESS
#include "../gte.h"
#ifdef NDRC_THREAD
Expand Down Expand Up @@ -317,13 +318,24 @@ static void ari64_apply_config()
#ifdef NDRC_THREAD
static void clear_local_cache(void)
{
#ifdef _3DS
if (ndrc_g.thread.cache_dirty) {
ndrc_g.thread.cache_dirty = 0;
ctr_invalidate_icache();
}
#if defined(__arm__) || defined(__aarch64__)
if (ndrc_g.thread.dirty_start) {
// see "Ensuring the visibility of updates to instructions"
// in v7/v8 reference manuals (DDI0406, DDI0487 etc.)
#if defined(__aarch64__) || defined(HAVE_ARMV8)
// the actual clean/invalidate is broadcast to all cores,
// the manual only prescribes an isb
__asm__ volatile("isb");
//#elif defined(_3DS)
// ctr_invalidate_icache();
#else
// hopefully nothing is needed, as tested on r-pi4 and switch
// while on v6 this is always required, on v7 it depends on
// "Multiprocessing Extensions" being present, but that is difficult
// to detect so do it always for now
new_dyna_clear_cache(ndrc_g.thread.dirty_start, ndrc_g.thread.dirty_end);
#endif
ndrc_g.thread.dirty_start = ndrc_g.thread.dirty_end = 0;
}
#endif
}

Expand Down
24 changes: 17 additions & 7 deletions libpcsxcore/new_dynarec/new_dynarec.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,12 +474,7 @@ static void mprotect_w_x(void *start, void *end, int is_x)
#endif
}

static void start_tcache_write(void *start, void *end)
{
mprotect_w_x(start, end, 0);
}

static void end_tcache_write(void *start, void *end)
void new_dyna_clear_cache(void *start, void *end)
{
#if defined(__arm__) || defined(__aarch64__)
size_t len = (char *)end - (char *)start;
Expand All @@ -495,7 +490,6 @@ static void end_tcache_write(void *start, void *end)
ctr_clear_cache_range(start, end);
else
ctr_clear_cache();
ndrc_g.thread.cache_dirty = 1;
#elif defined(HAVE_LIBNX)
if (g_jit.type == JitType_CodeMemory) {
armDCacheClean(start, len);
Expand All @@ -512,6 +506,22 @@ static void end_tcache_write(void *start, void *end)
#endif
(void)len;
#endif
}

static void start_tcache_write(void *start, void *end)
{
mprotect_w_x(start, end, 0);
}

static void end_tcache_write(void *start, void *end)
{
#ifdef NDRC_THREAD
if (!ndrc_g.thread.dirty_start || (size_t)ndrc_g.thread.dirty_start > (size_t)start)
ndrc_g.thread.dirty_start = start;
if ((size_t)ndrc_g.thread.dirty_end < (size_t)end)
ndrc_g.thread.dirty_end = end;
#endif
new_dyna_clear_cache(start, end);

mprotect_w_x(start, end, 1);
}
Expand Down
4 changes: 3 additions & 1 deletion libpcsxcore/new_dynarec/new_dynarec.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ struct ndrc_globals
void *handle;
void *lock;
void *cond;
void *dirty_start;
void *dirty_end;
unsigned int addr;
int busy;
int exit;
int cache_dirty; // 3ds only
} thread;
};
extern struct ndrc_globals ndrc_g;
Expand All @@ -40,6 +41,7 @@ void new_dynarec_print_stats(void);
int new_dynarec_quick_check_range(unsigned int start, unsigned int end);
void new_dynarec_invalidate_range(unsigned int start, unsigned int end);
void new_dynarec_invalidate_all_pages(void);
void new_dyna_clear_cache(void *start, void *end);

void new_dyna_start(void *context);
void new_dyna_start_at(void *context, void *compiled_code);
Expand Down

0 comments on commit d8f2909

Please sign in to comment.