From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55028) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wu113-00051r-Ts for qemu-devel@nongnu.org; Mon, 09 Jun 2014 10:57:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Wu112-0005du-A7 for qemu-devel@nongnu.org; Mon, 09 Jun 2014 10:57:41 -0400 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:48572) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wu112-0005dP-3J for qemu-devel@nongnu.org; Mon, 09 Jun 2014 10:57:40 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1Wu111-0006As-4c for qemu-devel@nongnu.org; Mon, 09 Jun 2014 15:57:39 +0100 From: Peter Maydell Date: Mon, 9 Jun 2014 15:57:37 +0100 Message-Id: <1402325858-23615-20-git-send-email-peter.maydell@linaro.org> In-Reply-To: <1402325858-23615-1-git-send-email-peter.maydell@linaro.org> References: <1402325858-23615-1-git-send-email-peter.maydell@linaro.org> Subject: [Qemu-devel] [PULL 19/20] target-arm: Fix errors in writes to generic timer control registers List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org The code for handling writes to the generic timer control registers had several bugs: * ISTATUS (bit 2) is read-only but we forced it to zero on any write * the check for "was IMASK (bit 1) toggled?" incorrectly used '&' where it should be '^' * the handling of IMASK was inverted: we should set the IRQ if ISTATUS is set and IMASK is clear, not if both are set The combination of these bugs meant that when running a Linux guest that uses the generic timers we would fairly quickly end up either forgetting that the timer output should be asserted, or failing to set the IRQ when the timer was unmasked. The result is that the guest never gets any more timer interrupts. Signed-off-by: Peter Maydell Message-id: 1401803208-1281-1-git-send-email-peter.maydell@linaro.org Cc: qemu-stable@nongnu.org --- target-arm/helper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 2b7a904..562545f 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1040,16 +1040,16 @@ static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri, int timeridx = ri->crm & 1; uint32_t oldval = env->cp15.c14_timer[timeridx].ctl; - env->cp15.c14_timer[timeridx].ctl = value & 3; + env->cp15.c14_timer[timeridx].ctl = deposit64(oldval, 0, 2, value); if ((oldval ^ value) & 1) { /* Enable toggled */ gt_recalc_timer(cpu, timeridx); - } else if ((oldval & value) & 2) { + } else if ((oldval ^ value) & 2) { /* IMASK toggled: don't need to recalculate, * just set the interrupt line based on ISTATUS */ qemu_set_irq(cpu->gt_timer_outputs[timeridx], - (oldval & 4) && (value & 2)); + (oldval & 4) && !(value & 2)); } } -- 1.9.2