]> git.proxmox.com Git - mirror_qemu.git/commitdiff
target-xtensa: implement RER/WER instructions
authorMax Filippov <jcmvbkbc@gmail.com>
Sat, 26 Nov 2011 11:48:41 +0000 (15:48 +0400)
committerMax Filippov <jcmvbkbc@gmail.com>
Tue, 17 Jan 2017 03:19:03 +0000 (19:19 -0800)
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>
target/xtensa/cpu.c
target/xtensa/cpu.h
target/xtensa/helper.h
target/xtensa/op_helper.c
target/xtensa/overlay_tool.h
target/xtensa/translate.c

index 811d8780d6bb1959b0aaf413cb916cbe07c6e053..cd7f95823f769624571eaabc1cb78c1f60f9bd5f 100644 (file)
@@ -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();
index 9a130bdabf4eda841128f46b3b17a3ebedb07f00..7e7131a596d4092c0af93e306b9641a2fe018fee 100644 (file)
@@ -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)
index 7e1474147b766d17aa624fec3823fc90e1f8d860..db3c9c5f216061921d8eaf2a609ff0fcb5987488 100644 (file)
@@ -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)
index 989578a8112bae2edde412c5e48b891c641c5ae1..b456c2ec3febb22030e6be3c0da5a715cc14a8eb 100644 (file)
@@ -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);
+}
index bf36b5cdf6c2c572df955f3d27d36623e1b36e7f..38e9be9ff56357c15621be455bc412797689bf0d 100644 (file)
 #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 ( \
     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
index c541b59747c1f474cd9bf1bc3cb5a6a0d134f1c2..c0408a01c7075b5d7073c85b86e9a698b2078611 100644 (file)
@@ -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*/