From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47058) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XXRCa-000634-I4 for qemu-devel@nongnu.org; Fri, 26 Sep 2014 04:48:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XXRCR-0005Qx-Dj for qemu-devel@nongnu.org; Fri, 26 Sep 2014 04:48:32 -0400 Received: from mail-la0-x22e.google.com ([2a00:1450:4010:c03::22e]:56954) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XXRCR-0005Pj-18 for qemu-devel@nongnu.org; Fri, 26 Sep 2014 04:48:23 -0400 Received: by mail-la0-f46.google.com with SMTP id gi9so3763664lab.19 for ; Fri, 26 Sep 2014 01:48:16 -0700 (PDT) From: Max Filippov Date: Fri, 26 Sep 2014 12:47:44 +0400 Message-Id: <1411721264-20356-1-git-send-email-jcmvbkbc@gmail.com> Subject: [Qemu-devel] [PATCH] target-xtensa: avoid duplicate timer interrupt delivery List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Max Filippov 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 --- hw/xtensa/pic_cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/xtensa/pic_cpu.c b/hw/xtensa/pic_cpu.c index e2005bd..18825d1 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); } } -- 1.8.1.4