Skip to content

Commit

Permalink
target-xtensa: implement RER/WER instructions
Browse files Browse the repository at this point in the history
RER and WER are privileged instructions for accessing external
registers. External register address space is local to processor core.
There's no alignment requirements, addressable units are 32-bit wide
registers.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
  • Loading branch information
jcmvbkbc committed Jan 17, 2017
1 parent 8b912ff commit 3a3c9dc
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 3 deletions.
6 changes: 6 additions & 0 deletions target/xtensa/cpu.c
Expand Up @@ -127,6 +127,12 @@ static void xtensa_cpu_initfn(Object *obj)
cs->env_ptr = env;
env->config = xcc->config;

env->address_space_er = g_malloc(sizeof(*env->address_space_er));
env->system_er = g_malloc(sizeof(*env->system_er));
memory_region_init_io(env->system_er, NULL, NULL, env, "er",
UINT64_C(0x100000000));
address_space_init(env->address_space_er, env->system_er, "ER");

if (tcg_enabled() && !tcg_inited) {
tcg_inited = true;
xtensa_translate_init();
Expand Down
7 changes: 7 additions & 0 deletions target/xtensa/cpu.h
Expand Up @@ -103,6 +103,7 @@ enum {
XTENSA_OPTION_PROCESSOR_ID,
XTENSA_OPTION_DEBUG,
XTENSA_OPTION_TRACE_PORT,
XTENSA_OPTION_EXTERN_REGS,
};

enum {
Expand Down Expand Up @@ -393,6 +394,8 @@ typedef struct CPUXtensaState {
xtensa_tlb_entry dtlb[10][MAX_TLB_WAY_SIZE];
unsigned autorefill_idx;
bool runstall;
AddressSpace *address_space_er;
MemoryRegion *system_er;
int pending_irq_level; /* level of last raised IRQ */
void **irq_inputs;
XtensaCcompareTimer ccompare[MAX_NCCOMPARE];
Expand Down Expand Up @@ -488,6 +491,10 @@ int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,
void reset_mmu(CPUXtensaState *env);
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUXtensaState *env);
void debug_exception_env(CPUXtensaState *new_env, uint32_t cause);
static inline MemoryRegion *xtensa_get_er_region(CPUXtensaState *env)
{
return env->system_er;
}

static inline void xtensa_select_static_vectors(CPUXtensaState *env,
unsigned n)
Expand Down
3 changes: 3 additions & 0 deletions target/xtensa/helper.h
Expand Up @@ -58,3 +58,6 @@ DEF_HELPER_4(olt_s, void, env, i32, f32, f32)
DEF_HELPER_4(ult_s, void, env, i32, f32, f32)
DEF_HELPER_4(ole_s, void, env, i32, f32, f32)
DEF_HELPER_4(ule_s, void, env, i32, f32, f32)

DEF_HELPER_2(rer, i32, env, i32)
DEF_HELPER_3(wer, void, env, i32, i32)
12 changes: 12 additions & 0 deletions target/xtensa/op_helper.c
Expand Up @@ -1027,3 +1027,15 @@ void HELPER(ule_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
int v = float32_compare_quiet(a, b, &env->fp_status);
set_br(env, v != float_relation_greater, br);
}

uint32_t HELPER(rer)(CPUXtensaState *env, uint32_t addr)
{
return address_space_ldl(env->address_space_er, addr,
(MemTxAttrs){0}, NULL);
}

void HELPER(wer)(CPUXtensaState *env, uint32_t data, uint32_t addr)
{
address_space_stl(env->address_space_er, addr, data,
(MemTxAttrs){0}, NULL);
}
7 changes: 6 additions & 1 deletion target/xtensa/overlay_tool.h
Expand Up @@ -63,6 +63,10 @@
#define XCHAL_LOOP_BUFFER_SIZE 0
#endif

#ifndef XCHAL_HAVE_EXTERN_REGS
#define XCHAL_HAVE_EXTERN_REGS 0
#endif

#define XCHAL_OPTION(xchal, qemu) ((xchal) ? XTENSA_OPTION_BIT(qemu) : 0)

#define XTENSA_OPTIONS ( \
Expand Down Expand Up @@ -115,7 +119,8 @@
XCHAL_OPTION(XCHAL_HAVE_DEBUG, XTENSA_OPTION_DEBUG) |\
XCHAL_OPTION(XCHAL_NUM_MISC_REGS > 0, XTENSA_OPTION_MISC_SR) | \
XCHAL_OPTION(XCHAL_HAVE_THREADPTR, XTENSA_OPTION_THREAD_POINTER) | \
XCHAL_OPTION(XCHAL_HAVE_PRID, XTENSA_OPTION_PROCESSOR_ID))
XCHAL_OPTION(XCHAL_HAVE_PRID, XTENSA_OPTION_PROCESSOR_ID) | \
XCHAL_OPTION(XCHAL_HAVE_EXTERN_REGS, XTENSA_OPTION_EXTERN_REGS))

#ifndef XCHAL_WINDOW_OF4_VECOFS
#define XCHAL_WINDOW_OF4_VECOFS 0x00000000
Expand Down
12 changes: 10 additions & 2 deletions target/xtensa/translate.c
Expand Up @@ -1420,11 +1420,19 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
break;

case 6: /*RER*/
TBD();
HAS_OPTION(XTENSA_OPTION_EXTERN_REGS);
if (gen_check_privilege(dc) &&
gen_window_check2(dc, RRR_S, RRR_T)) {
gen_helper_rer(cpu_R[RRR_T], cpu_env, cpu_R[RRR_S]);
}
break;

case 7: /*WER*/
TBD();
HAS_OPTION(XTENSA_OPTION_EXTERN_REGS);
if (gen_check_privilege(dc) &&
gen_window_check2(dc, RRR_S, RRR_T)) {
gen_helper_wer(cpu_env, cpu_R[RRR_T], cpu_R[RRR_S]);
}
break;

case 8: /*ROTWw*/
Expand Down

0 comments on commit 3a3c9dc

Please sign in to comment.