diff options
author | Richard Henderson <rth@twiddle.net> | 2014-09-13 09:45:22 -0700 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-09-25 18:54:21 +0100 |
commit | dde7c241e3259f5a752e4fb7a638ee377ed0cad0 (patch) | |
tree | a669f557ef79fa422ac0f6c81cc51f30a38c4afa /target-alpha | |
parent | 5a1f7f44cf7a55b696859d09af1b18c8e40c8339 (diff) |
target-alpha: Use cpu_exec_interrupt qom hook
Signed-off-by: Richard Henderson <rth@twiddle.net>
Message-id: 1410626734-3804-12-git-send-email-rth@twiddle.net
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-alpha')
-rw-r--r-- | target-alpha/cpu-qom.h | 1 | ||||
-rw-r--r-- | target-alpha/cpu.c | 1 | ||||
-rw-r--r-- | target-alpha/helper.c | 44 |
3 files changed, 46 insertions, 0 deletions
diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h index 0caa362f5b..b01c6c82eb 100644 --- a/target-alpha/cpu-qom.h +++ b/target-alpha/cpu-qom.h @@ -79,6 +79,7 @@ extern const struct VMStateDescription vmstate_alpha_cpu; #endif void alpha_cpu_do_interrupt(CPUState *cpu); +bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req); void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags); hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c index 2491f0a301..a98b7d8d72 100644 --- a/target-alpha/cpu.c +++ b/target-alpha/cpu.c @@ -284,6 +284,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = alpha_cpu_class_by_name; cc->has_work = alpha_cpu_has_work; cc->do_interrupt = alpha_cpu_do_interrupt; + cc->cpu_exec_interrupt = alpha_cpu_exec_interrupt; cc->dump_state = alpha_cpu_dump_state; cc->set_pc = alpha_cpu_set_pc; cc->gdb_read_register = alpha_cpu_gdb_read_register; diff --git a/target-alpha/helper.c b/target-alpha/helper.c index 7c053a3eae..a8aa782a2a 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -470,6 +470,50 @@ void alpha_cpu_do_interrupt(CPUState *cs) #endif /* !USER_ONLY */ } +bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request) +{ + AlphaCPU *cpu = ALPHA_CPU(cs); + CPUAlphaState *env = &cpu->env; + int idx = -1; + + /* We never take interrupts while in PALmode. */ + if (env->pal_mode) { + return false; + } + + /* Fall through the switch, collecting the highest priority + interrupt that isn't masked by the processor status IPL. */ + /* ??? This hard-codes the OSF/1 interrupt levels. */ + switch (env->ps & PS_INT_MASK) { + case 0 ... 3: + if (interrupt_request & CPU_INTERRUPT_HARD) { + idx = EXCP_DEV_INTERRUPT; + } + /* FALLTHRU */ + case 4: + if (interrupt_request & CPU_INTERRUPT_TIMER) { + idx = EXCP_CLK_INTERRUPT; + } + /* FALLTHRU */ + case 5: + if (interrupt_request & CPU_INTERRUPT_SMP) { + idx = EXCP_SMP_INTERRUPT; + } + /* FALLTHRU */ + case 6: + if (interrupt_request & CPU_INTERRUPT_MCHK) { + idx = EXCP_MCHK; + } + } + if (idx >= 0) { + cs->exception_index = idx; + env->error_code = 0; + alpha_cpu_do_interrupt(cs); + return true; + } + return false; +} + void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags) { |