]> git.proxmox.com Git - mirror_qemu.git/commitdiff
target/xtensa: implement RUNSTALL
authorMax Filippov <jcmvbkbc@gmail.com>
Wed, 14 Dec 2016 02:52:08 +0000 (18:52 -0800)
committerMax Filippov <jcmvbkbc@gmail.com>
Sun, 15 Jan 2017 21:01:55 +0000 (13:01 -0800)
RUNSTALL signal stalls core execution while it's applied. It is widely
used in multicore configurations to control activity of additional
cores.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
target/xtensa/cpu.c
target/xtensa/cpu.h
target/xtensa/helper.c

index 09b53c76d432f8ec7aee737f0cf3f5559f727086..1c18892fca25236ec3568e2c8afd8455df380a0f 100644 (file)
@@ -47,7 +47,7 @@ static bool xtensa_cpu_has_work(CPUState *cs)
 {
     XtensaCPU *cpu = XTENSA_CPU(cs);
 
-    return cpu->env.pending_irq_level;
+    return !cpu->env.runstall && cpu->env.pending_irq_level;
 }
 
 /* CPUClass::reset() */
@@ -74,6 +74,7 @@ static void xtensa_cpu_reset(CPUState *s)
 
     env->pending_irq_level = 0;
     reset_mmu(env);
+    s->halted = env->runstall;
 }
 
 static ObjectClass *xtensa_cpu_class_by_name(const char *cpu_model)
index 6b044d32f656466520f5d8854a1545bba7e14700..77bd9d2a7f616d869876e172814d50735779eab0 100644 (file)
@@ -366,7 +366,7 @@ typedef struct CPUXtensaState {
     xtensa_tlb_entry itlb[7][MAX_TLB_WAY_SIZE];
     xtensa_tlb_entry dtlb[10][MAX_TLB_WAY_SIZE];
     unsigned autorefill_idx;
-
+    bool runstall;
     int pending_irq_level; /* level of last raised IRQ */
     void **irq_inputs;
     QEMUTimer *ccompare_timer;
@@ -469,6 +469,7 @@ static inline void xtensa_select_static_vectors(CPUXtensaState *env,
     assert(n < 2);
     env->static_vectors = n;
 }
+void xtensa_runstall(CPUXtensaState *env, bool runstall);
 
 #define XTENSA_OPTION_BIT(opt) (((uint64_t)1) << (opt))
 #define XTENSA_OPTION_ALL (~(uint64_t)0)
index 768b32c4172400ccdf61180e90e0139b6e8d4373..c67d715c4b9c692ea2f4332830871b9b5f425b80 100644 (file)
@@ -728,3 +728,16 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUXtensaState *env)
         cpu_fprintf(f, "No TLB for this CPU core\n");
     }
 }
+
+void xtensa_runstall(CPUXtensaState *env, bool runstall)
+{
+    CPUState *cpu = CPU(xtensa_env_get_cpu(env));
+
+    env->runstall = runstall;
+    cpu->halted = runstall;
+    if (runstall) {
+        cpu_interrupt(cpu, CPU_INTERRUPT_HALT);
+    } else {
+        cpu_reset_interrupt(cpu, CPU_INTERRUPT_HALT);
+    }
+}