diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2011-10-10 06:25:04 +0400 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2011-10-15 21:03:03 +0000 |
commit | 890c6333b28a4dcbf2a26a5a17b0e71304d5a851 (patch) | |
tree | d9243ab3e1a3eab793184eb49134b9c1d9c6fa87 /target-xtensa/op_helper.c | |
parent | 9870a5e6cd3df584328728b3d822b23cee28c561 (diff) |
target-xtensa: fix guest hang on masked CCOMPARE interrupt
QEMU timer is used to post CCOMPARE interrupt when the core is halted.
If that CCOMPARE interrupt is masked off then the timer must be rearmed
in the callback, otherwise it will be rearmed next time the core goes to
halt by the waiti instruction.
Add test case into timer testsuite.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-xtensa/op_helper.c')
-rw-r--r-- | target-xtensa/op_helper.c | 18 |
1 files changed, 3 insertions, 15 deletions
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c index 64847fc8e6..0605611031 100644 --- a/target-xtensa/op_helper.c +++ b/target-xtensa/op_helper.c @@ -370,23 +370,11 @@ void HELPER(waiti)(uint32_t pc, uint32_t intlevel) return; } - if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT)) { - int i; - uint32_t wake_ccount = env->sregs[CCOUNT] - 1; - - for (i = 0; i < env->config->nccompare; ++i) { - if (env->sregs[CCOMPARE + i] - env->sregs[CCOUNT] < - wake_ccount - env->sregs[CCOUNT]) { - wake_ccount = env->sregs[CCOMPARE + i]; - } - } - env->wake_ccount = wake_ccount; - qemu_mod_timer(env->ccompare_timer, qemu_get_clock_ns(vm_clock) + - muldiv64(wake_ccount - env->sregs[CCOUNT], - 1000000, env->config->clock_freq_khz)); - } env->halt_clock = qemu_get_clock_ns(vm_clock); env->halted = 1; + if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT)) { + xtensa_rearm_ccompare_timer(env); + } HELPER(exception)(EXCP_HLT); } |