e2k: add probe access cache

This commit is contained in:
Denis Drakhnia 2024-01-13 17:32:31 +02:00
parent 0ff495b4d3
commit c116f9e4bd
5 changed files with 66 additions and 16 deletions

View File

@ -60,6 +60,21 @@ static void stack_expand(CPUE2KState *env, E2KPsp *s)
s->size = new_size;
}
static void e2k_clear_probe_page_cache(void)
{
CPUState *other_cpu;
start_exclusive();
CPU_FOREACH(other_cpu) {
E2KCPU *cpu = E2K_CPU(other_cpu);
CPUE2KState *env = &cpu->env;
memset(env->probe_cache_page, 0, sizeof(env->probe_cache_page));
memset(env->probe_cache_flags, 0, sizeof(env->probe_cache_flags));
}
end_exclusive();
}
void cpu_loop(CPUE2KState *env)
{
CPUState *cs = env_cpu(env);
@ -89,7 +104,14 @@ void cpu_loop(CPUE2KState *env)
}
if (!env->enable_tags || (env->wtag[0] & E2K_TAG_MASK_32) == E2K_TAG_NUMBER32) {
ret = do_syscall(env, (uint32_t) args[0], args[1], args[2], args[3],
args[0] = (uint32_t) args[0];
if (args[0] == TARGET_NR_brk || args[0] == TARGET_NR_mmap ||
args[0] == TARGET_NR_munmap) {
e2k_clear_probe_page_cache();
}
ret = do_syscall(env, args[0], args[1], args[2], args[3],
args[4], args[5], args[6], args[7], args[8]);
} else {
ret = TARGET_ENOSYS;

View File

@ -44,6 +44,8 @@ void e2k_tcg_initialize(void);
#define E2K_PR_COUNT 32 /* %predN [0, 32) */
#define TARGET_PROBE_CACHE_SIZE 64
typedef enum {
E2K_TAG_NUMBER32 = 0,
E2K_TAG_NUMBER64 = 0,
@ -804,6 +806,11 @@ typedef struct CPUArchState {
/* Next Instruction Address */
target_ulong nip;
#if defined(CONFIG_USER_ONLY)
target_ulong probe_cache_page[TARGET_PROBE_CACHE_SIZE];
uint8_t probe_cache_flags[TARGET_PROBE_CACHE_SIZE];
#endif
/* Procedure Chain Stack Pointer (control registers) */
E2KPsp pcsp;
/* Procedure Stack Pointer (window registers) */

View File

@ -13,9 +13,9 @@ DEF_HELPER_1(return, void, env)
DEF_HELPER_4(setwd, void, env, int, int, int)
DEF_HELPER_FLAGS_2(probe_read_access, TCG_CALL_NO_RWG_SE, int, tl, int)
DEF_HELPER_FLAGS_2(probe_write_access, TCG_CALL_NO_RWG_SE, int, tl, int)
DEF_HELPER_FLAGS_2(probe_rw_access, TCG_CALL_NO_RWG_SE, int, tl, int)
DEF_HELPER_FLAGS_3(probe_read_access, TCG_CALL_NO_RWG_SE, int, env, tl, int)
DEF_HELPER_FLAGS_3(probe_write_access, TCG_CALL_NO_RWG_SE, int, env, tl, int)
DEF_HELPER_FLAGS_3(probe_rw_access, TCG_CALL_NO_RWG_SE, int, env, tl, int)
DEF_HELPER_FLAGS_2(aau_load_program, TCG_CALL_NO_RWG, void, env, i64)
DEF_HELPER_FLAGS_6(mova_ptr, TCG_CALL_NO_RWG, tl, env, int, int, int, int, int)

View File

@ -5,31 +5,52 @@
#include "qemu/host-utils.h"
#include "exec/helper-proto.h"
static bool e2k_probe_access(target_ulong addr, int size, int flags)
#if defined(CONFIG_USER_ONLY)
#if PAGE_READ > 0xff || PAGE_WRITE_ORG > 0xff
# error
#endif
static bool e2k_probe_access_cached(CPUE2KState *env, target_ulong page, int flags)
{
int index = (page >> TARGET_PAGE_BITS) & (TARGET_PROBE_CACHE_SIZE - 1);
if (env->probe_cache_page[index] == page) {
return (env->probe_cache_flags[index] & flags) == flags;
}
env->probe_cache_page[index] = page;
env->probe_cache_flags[index] = page_get_flags(page);
return (env->probe_cache_flags[index] & flags) == flags;
}
static bool e2k_probe_access(CPUE2KState *env, target_ulong addr, int size, int flags)
{
target_ulong start = addr & TARGET_PAGE_MASK;
target_ulong last = (addr + size - 1) & TARGET_PAGE_MASK;
if (start == last) {
return guest_addr_valid_untagged(addr) &&
(page_get_flags(start) & flags) == flags;
e2k_probe_access_cached(env, start, flags);
} else {
return guest_range_valid_untagged(addr, size) &&
page_check_range(addr, size, flags);
e2k_probe_access_cached(env, start, flags) &&
e2k_probe_access_cached(env, last, flags);
}
}
int HELPER(probe_read_access)(target_ulong addr, int size)
int HELPER(probe_read_access)(CPUE2KState *env, target_ulong addr, int size)
{
return e2k_probe_access(addr, size, PAGE_READ);
return e2k_probe_access(env, addr, size, PAGE_READ);
}
int HELPER(probe_write_access)(target_ulong addr, int size)
int HELPER(probe_write_access)(CPUE2KState *env, target_ulong addr, int size)
{
return e2k_probe_access(addr, size, PAGE_WRITE_ORG);
return e2k_probe_access(env, addr, size, PAGE_WRITE_ORG);
}
int HELPER(probe_rw_access)(target_ulong addr, int size)
int HELPER(probe_rw_access)(CPUE2KState *env, target_ulong addr, int size)
{
return e2k_probe_access(addr, size, PAGE_READ | PAGE_WRITE_ORG);
return e2k_probe_access(env, addr, size, PAGE_READ | PAGE_WRITE_ORG);
}
#endif /* CONFIG_USER_ONLY */

View File

@ -3960,21 +3960,21 @@ static void gen_probe_read_access(TCGv_i32 ret, TCGv addr, int size,
int mmu_idx)
{
TCGv_i32 t0 = tcg_constant_i32(size);
gen_helper_probe_read_access(ret, addr, t0);
gen_helper_probe_read_access(ret, tcg_env, addr, t0);
}
static void gen_probe_write_access(TCGv_i32 ret, TCGv addr, int size,
int mmu_idx)
{
TCGv_i32 t0 = tcg_constant_i32(size);
gen_helper_probe_write_access(ret, addr, t0);
gen_helper_probe_write_access(ret, tcg_env, addr, t0);
}
static void gen_probe_rw_access(TCGv_i32 ret, TCGv addr, int size,
int mmu_idx)
{
TCGv_i32 t0 = tcg_constant_i32(size);
gen_helper_probe_rw_access(ret, addr, t0);
gen_helper_probe_rw_access(ret, tcg_env, addr, t0);
}
static AlopResult gen_ld_raw_i64(Alop *alop, TCGv_i32 tag, TCGv addr,