target-xtensa: implement RER/WER instructions
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>
This commit is contained in:
parent
8b912ff033
commit
3a3c9dc4ca
@ -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();
|
||||
|
@ -103,6 +103,7 @@ enum {
|
||||
XTENSA_OPTION_PROCESSOR_ID,
|
||||
XTENSA_OPTION_DEBUG,
|
||||
XTENSA_OPTION_TRACE_PORT,
|
||||
XTENSA_OPTION_EXTERN_REGS,
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -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];
|
||||
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 ( \
|
||||
@ -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
|
||||
|
@ -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*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user