e2k: add probe access cache
This commit is contained in:
parent
120943216e
commit
02455c9eb5
|
@ -89,7 +89,24 @@ 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) {
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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, cpu_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, cpu_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, cpu_env, addr, t0);
|
||||
}
|
||||
|
||||
static AlopResult gen_ld_raw_i64(Alop *alop, TCGv_i32 tag, TCGv addr,
|
||||
|
|
Loading…
Reference in New Issue