aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2014-09-25 16:12:31 +0400
committerMax Filippov <jcmvbkbc@gmail.com>2014-11-03 00:51:44 +0300
commitc9e9521fcb840b14ec0ae9117b224ff8a71418da (patch)
tree74a60acef2ad9cf1a62ee8bb5122036d3e78f8a7 /hw
parent20303e42d4726018ee64798b4d3051cbe6eea9f8 (diff)
target-xtensa: avoid duplicate timer interrupt delivery
Timer interrupt should be raised at the same cycle when CCOUNT equals CCOMPARE. As cycles are counted in batches, timer interrupt is sent every time CCOMPARE lies in the interval [old CCOUNT, new CCOUNT]. This is wrong, because when new CCOUNT equals CCOMPARE interrupt is sent twice, once for the upper interval boundary and once for the lower. Fix that by excluding lower interval boundary from the condition. This doesn't have user-visible effect, because CCOMPARE reload always causes CCOUNT increment followed by current timer interrupt reset. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/xtensa/pic_cpu.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/hw/xtensa/pic_cpu.c b/hw/xtensa/pic_cpu.c
index e2005bd981..18825d19f0 100644
--- a/hw/xtensa/pic_cpu.c
+++ b/hw/xtensa/pic_cpu.c
@@ -31,14 +31,14 @@
void xtensa_advance_ccount(CPUXtensaState *env, uint32_t d)
{
- uint32_t old_ccount = env->sregs[CCOUNT];
+ uint32_t old_ccount = env->sregs[CCOUNT] + 1;
env->sregs[CCOUNT] += d;
if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT)) {
int i;
for (i = 0; i < env->config->nccompare; ++i) {
- if (env->sregs[CCOMPARE + i] - old_ccount <= d) {
+ if (env->sregs[CCOMPARE + i] - old_ccount < d) {
xtensa_timer_irq(env, i, 1);
}
}