mirror of https://github.com/xqemu/xqemu.git
target/xtensa: implement MEMCTL SR
MEMCTL SR controls zero overhead loop buffer and number of ways enabled in L1 caches. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
parent
4b37aaa879
commit
9e03ade441
|
@ -66,6 +66,7 @@ static void xtensa_cpu_reset(CPUState *s)
|
||||||
XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10;
|
XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10;
|
||||||
env->sregs[VECBASE] = env->config->vecbase;
|
env->sregs[VECBASE] = env->config->vecbase;
|
||||||
env->sregs[IBREAKENABLE] = 0;
|
env->sregs[IBREAKENABLE] = 0;
|
||||||
|
env->sregs[MEMCTL] = MEMCTL_IL0EN & env->config->memctl_mask;
|
||||||
env->sregs[CACHEATTR] = 0x22222222;
|
env->sregs[CACHEATTR] = 0x22222222;
|
||||||
env->sregs[ATOMCTL] = xtensa_option_enabled(env->config,
|
env->sregs[ATOMCTL] = xtensa_option_enabled(env->config,
|
||||||
XTENSA_OPTION_ATOMCTL) ? 0x28 : 0x15;
|
XTENSA_OPTION_ATOMCTL) ? 0x28 : 0x15;
|
||||||
|
|
|
@ -129,6 +129,7 @@ enum {
|
||||||
ITLBCFG = 91,
|
ITLBCFG = 91,
|
||||||
DTLBCFG = 92,
|
DTLBCFG = 92,
|
||||||
IBREAKENABLE = 96,
|
IBREAKENABLE = 96,
|
||||||
|
MEMCTL = 97,
|
||||||
CACHEATTR = 98,
|
CACHEATTR = 98,
|
||||||
ATOMCTL = 99,
|
ATOMCTL = 99,
|
||||||
IBREAKA = 128,
|
IBREAKA = 128,
|
||||||
|
@ -189,6 +190,20 @@ enum {
|
||||||
#define DBREAKC_SB_LB (DBREAKC_SB | DBREAKC_LB)
|
#define DBREAKC_SB_LB (DBREAKC_SB | DBREAKC_LB)
|
||||||
#define DBREAKC_MASK 0x3f
|
#define DBREAKC_MASK 0x3f
|
||||||
|
|
||||||
|
#define MEMCTL_INIT 0x00800000
|
||||||
|
#define MEMCTL_IUSEWAYS_SHIFT 18
|
||||||
|
#define MEMCTL_IUSEWAYS_LEN 5
|
||||||
|
#define MEMCTL_IUSEWAYS_MASK 0x007c0000
|
||||||
|
#define MEMCTL_DALLOCWAYS_SHIFT 13
|
||||||
|
#define MEMCTL_DALLOCWAYS_LEN 5
|
||||||
|
#define MEMCTL_DALLOCWAYS_MASK 0x0003e000
|
||||||
|
#define MEMCTL_DUSEWAYS_SHIFT 8
|
||||||
|
#define MEMCTL_DUSEWAYS_LEN 5
|
||||||
|
#define MEMCTL_DUSEWAYS_MASK 0x00001f00
|
||||||
|
#define MEMCTL_ISNP 0x4
|
||||||
|
#define MEMCTL_DSNP 0x2
|
||||||
|
#define MEMCTL_IL0EN 0x1
|
||||||
|
|
||||||
#define MAX_NAREG 64
|
#define MAX_NAREG 64
|
||||||
#define MAX_NINTERRUPT 32
|
#define MAX_NINTERRUPT 32
|
||||||
#define MAX_NLEVEL 6
|
#define MAX_NLEVEL 6
|
||||||
|
@ -332,6 +347,10 @@ struct XtensaConfig {
|
||||||
unsigned nibreak;
|
unsigned nibreak;
|
||||||
unsigned ndbreak;
|
unsigned ndbreak;
|
||||||
|
|
||||||
|
unsigned icache_ways;
|
||||||
|
unsigned dcache_ways;
|
||||||
|
uint32_t memctl_mask;
|
||||||
|
|
||||||
uint32_t configid[2];
|
uint32_t configid[2];
|
||||||
|
|
||||||
uint32_t clock_freq_khz;
|
uint32_t clock_freq_khz;
|
||||||
|
|
|
@ -23,6 +23,7 @@ DEF_HELPER_2(wsr_ccount, void, env, i32)
|
||||||
DEF_HELPER_2(update_ccompare, void, env, i32)
|
DEF_HELPER_2(update_ccompare, void, env, i32)
|
||||||
DEF_HELPER_1(check_interrupts, void, env)
|
DEF_HELPER_1(check_interrupts, void, env)
|
||||||
DEF_HELPER_3(check_atomctl, void, env, i32, i32)
|
DEF_HELPER_3(check_atomctl, void, env, i32, i32)
|
||||||
|
DEF_HELPER_2(wsr_memctl, void, env, i32)
|
||||||
|
|
||||||
DEF_HELPER_2(itlb_hit_test, void, env, i32)
|
DEF_HELPER_2(itlb_hit_test, void, env, i32)
|
||||||
DEF_HELPER_2(wsr_rasid, void, env, i32)
|
DEF_HELPER_2(wsr_rasid, void, env, i32)
|
||||||
|
|
|
@ -506,6 +506,30 @@ void HELPER(check_atomctl)(CPUXtensaState *env, uint32_t pc, uint32_t vaddr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HELPER(wsr_memctl)(CPUXtensaState *env, uint32_t v)
|
||||||
|
{
|
||||||
|
if (xtensa_option_enabled(env->config, XTENSA_OPTION_ICACHE)) {
|
||||||
|
if (extract32(v, MEMCTL_IUSEWAYS_SHIFT, MEMCTL_IUSEWAYS_LEN) >
|
||||||
|
env->config->icache_ways) {
|
||||||
|
deposit32(v, MEMCTL_IUSEWAYS_SHIFT, MEMCTL_IUSEWAYS_LEN,
|
||||||
|
env->config->icache_ways);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (xtensa_option_enabled(env->config, XTENSA_OPTION_DCACHE)) {
|
||||||
|
if (extract32(v, MEMCTL_DUSEWAYS_SHIFT, MEMCTL_DUSEWAYS_LEN) >
|
||||||
|
env->config->dcache_ways) {
|
||||||
|
deposit32(v, MEMCTL_DUSEWAYS_SHIFT, MEMCTL_DUSEWAYS_LEN,
|
||||||
|
env->config->dcache_ways);
|
||||||
|
}
|
||||||
|
if (extract32(v, MEMCTL_DALLOCWAYS_SHIFT, MEMCTL_DALLOCWAYS_LEN) >
|
||||||
|
env->config->dcache_ways) {
|
||||||
|
deposit32(v, MEMCTL_DALLOCWAYS_SHIFT, MEMCTL_DALLOCWAYS_LEN,
|
||||||
|
env->config->dcache_ways);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
env->sregs[MEMCTL] = v & env->config->memctl_mask;
|
||||||
|
}
|
||||||
|
|
||||||
void HELPER(wsr_rasid)(CPUXtensaState *env, uint32_t v)
|
void HELPER(wsr_rasid)(CPUXtensaState *env, uint32_t v)
|
||||||
{
|
{
|
||||||
XtensaCPU *cpu = xtensa_env_get_cpu(env);
|
XtensaCPU *cpu = xtensa_env_get_cpu(env);
|
||||||
|
|
|
@ -59,6 +59,10 @@
|
||||||
#define XCHAL_HW_MIN_VERSION 0
|
#define XCHAL_HW_MIN_VERSION 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef XCHAL_LOOP_BUFFER_SIZE
|
||||||
|
#define XCHAL_LOOP_BUFFER_SIZE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define XCHAL_OPTION(xchal, qemu) ((xchal) ? XTENSA_OPTION_BIT(qemu) : 0)
|
#define XCHAL_OPTION(xchal, qemu) ((xchal) ? XTENSA_OPTION_BIT(qemu) : 0)
|
||||||
|
|
||||||
#define XTENSA_OPTIONS ( \
|
#define XTENSA_OPTIONS ( \
|
||||||
|
@ -343,6 +347,16 @@
|
||||||
.nibreak = XCHAL_NUM_IBREAK, \
|
.nibreak = XCHAL_NUM_IBREAK, \
|
||||||
.ndbreak = XCHAL_NUM_DBREAK
|
.ndbreak = XCHAL_NUM_DBREAK
|
||||||
|
|
||||||
|
#define CACHE_SECTION \
|
||||||
|
.icache_ways = XCHAL_ICACHE_WAYS, \
|
||||||
|
.dcache_ways = XCHAL_DCACHE_WAYS, \
|
||||||
|
.memctl_mask = \
|
||||||
|
(XCHAL_ICACHE_SIZE ? MEMCTL_IUSEWAYS_MASK : 0) | \
|
||||||
|
(XCHAL_DCACHE_SIZE ? \
|
||||||
|
MEMCTL_DALLOCWAYS_MASK | MEMCTL_DUSEWAYS_MASK : 0) | \
|
||||||
|
MEMCTL_ISNP | MEMCTL_DSNP | \
|
||||||
|
(XCHAL_HAVE_LOOPS && XCHAL_LOOP_BUFFER_SIZE ? MEMCTL_IL0EN : 0)
|
||||||
|
|
||||||
#define CONFIG_SECTION \
|
#define CONFIG_SECTION \
|
||||||
.configid = { \
|
.configid = { \
|
||||||
XCHAL_HW_CONFIGID0, \
|
XCHAL_HW_CONFIGID0, \
|
||||||
|
@ -357,6 +371,7 @@
|
||||||
INTERRUPTS_SECTION, \
|
INTERRUPTS_SECTION, \
|
||||||
TLB_SECTION, \
|
TLB_SECTION, \
|
||||||
DEBUG_SECTION, \
|
DEBUG_SECTION, \
|
||||||
|
CACHE_SECTION, \
|
||||||
CONFIG_SECTION
|
CONFIG_SECTION
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,7 @@ static const XtensaReg sregnames[256] = {
|
||||||
[ITLBCFG] = XTENSA_REG("ITLBCFG", XTENSA_OPTION_MMU),
|
[ITLBCFG] = XTENSA_REG("ITLBCFG", XTENSA_OPTION_MMU),
|
||||||
[DTLBCFG] = XTENSA_REG("DTLBCFG", XTENSA_OPTION_MMU),
|
[DTLBCFG] = XTENSA_REG("DTLBCFG", XTENSA_OPTION_MMU),
|
||||||
[IBREAKENABLE] = XTENSA_REG("IBREAKENABLE", XTENSA_OPTION_DEBUG),
|
[IBREAKENABLE] = XTENSA_REG("IBREAKENABLE", XTENSA_OPTION_DEBUG),
|
||||||
|
[MEMCTL] = XTENSA_REG_BITS("MEMCTL", XTENSA_OPTION_ALL),
|
||||||
[CACHEATTR] = XTENSA_REG("CACHEATTR", XTENSA_OPTION_CACHEATTR),
|
[CACHEATTR] = XTENSA_REG("CACHEATTR", XTENSA_OPTION_CACHEATTR),
|
||||||
[ATOMCTL] = XTENSA_REG("ATOMCTL", XTENSA_OPTION_ATOMCTL),
|
[ATOMCTL] = XTENSA_REG("ATOMCTL", XTENSA_OPTION_ATOMCTL),
|
||||||
[IBREAKA] = XTENSA_REG("IBREAKA0", XTENSA_OPTION_DEBUG),
|
[IBREAKA] = XTENSA_REG("IBREAKA0", XTENSA_OPTION_DEBUG),
|
||||||
|
@ -637,6 +638,12 @@ static bool gen_wsr_ibreakenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool gen_wsr_memctl(DisasContext *dc, uint32_t sr, TCGv_i32 v)
|
||||||
|
{
|
||||||
|
gen_helper_wsr_memctl(cpu_env, v);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool gen_wsr_atomctl(DisasContext *dc, uint32_t sr, TCGv_i32 v)
|
static bool gen_wsr_atomctl(DisasContext *dc, uint32_t sr, TCGv_i32 v)
|
||||||
{
|
{
|
||||||
tcg_gen_andi_i32(cpu_SR[sr], v, 0x3f);
|
tcg_gen_andi_i32(cpu_SR[sr], v, 0x3f);
|
||||||
|
@ -821,6 +828,7 @@ static bool gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
|
||||||
[ITLBCFG] = gen_wsr_tlbcfg,
|
[ITLBCFG] = gen_wsr_tlbcfg,
|
||||||
[DTLBCFG] = gen_wsr_tlbcfg,
|
[DTLBCFG] = gen_wsr_tlbcfg,
|
||||||
[IBREAKENABLE] = gen_wsr_ibreakenable,
|
[IBREAKENABLE] = gen_wsr_ibreakenable,
|
||||||
|
[MEMCTL] = gen_wsr_memctl,
|
||||||
[ATOMCTL] = gen_wsr_atomctl,
|
[ATOMCTL] = gen_wsr_atomctl,
|
||||||
[IBREAKA] = gen_wsr_ibreaka,
|
[IBREAKA] = gen_wsr_ibreaka,
|
||||||
[IBREAKA + 1] = gen_wsr_ibreaka,
|
[IBREAKA + 1] = gen_wsr_ibreaka,
|
||||||
|
|
Loading…
Reference in New Issue