summaryrefslogtreecommitdiff
path: root/target/xtensa
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2016-12-13 18:52:08 -0800
committerMax Filippov <jcmvbkbc@gmail.com>2017-01-15 13:01:55 -0800
commitbd527a83232ce8b48dac4b8c86607ad8a7e28d98 (patch)
tree6650120264bc9b01d6034e5ae017de2809d8ee99 /target/xtensa
parent17ab14acd488289d2f85ad6212b212c21f050b3d (diff)
downloadqemu-bd527a83232ce8b48dac4b8c86607ad8a7e28d98.tar.gz
target/xtensa: implement RUNSTALL
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>
Diffstat (limited to 'target/xtensa')
-rw-r--r--target/xtensa/cpu.c3
-rw-r--r--target/xtensa/cpu.h3
-rw-r--r--target/xtensa/helper.c13
3 files changed, 17 insertions, 2 deletions
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 09b53c76d4..1c18892fca 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -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)
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 6b044d32f6..77bd9d2a7f 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -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)
diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c
index 768b32c417..c67d715c4b 100644
--- a/target/xtensa/helper.c
+++ b/target/xtensa/helper.c
@@ -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);
+ }
+}