target-xtensa: avoid duplicate timer interrupt delivery
authorMax Filippov <jcmvbkbc@gmail.com>
Thu, 25 Sep 2014 12:12:31 +0000 (16:12 +0400)
committerMax Filippov <jcmvbkbc@gmail.com>
Sun, 2 Nov 2014 21:51:44 +0000 (00:51 +0300)
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>
hw/xtensa/pic_cpu.c

index e2005bd981ab39ab77e39015543748705257d790..18825d19f047b88b9fe3e24842ed382fa7304030 100644 (file)
 
 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);
             }
         }