From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43718) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d1F92-0008PM-C8 for qemu-devel@nongnu.org; Thu, 20 Apr 2017 12:41:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d1F90-00087i-Tx for qemu-devel@nongnu.org; Thu, 20 Apr 2017 12:41:24 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:36887) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1d1F90-00085i-Ln for qemu-devel@nongnu.org; Thu, 20 Apr 2017 12:41:22 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.84_2) (envelope-from ) id 1d1F8v-0006wm-LT for qemu-devel@nongnu.org; Thu, 20 Apr 2017 17:41:17 +0100 From: Peter Maydell Date: Thu, 20 Apr 2017 17:40:59 +0100 Message-Id: <1492706470-10921-14-git-send-email-peter.maydell@linaro.org> In-Reply-To: <1492706470-10921-1-git-send-email-peter.maydell@linaro.org> References: <1492706470-10921-1-git-send-email-peter.maydell@linaro.org> Subject: [Qemu-devel] [PULL 13/24] cadence_gem: Correct the interupt logic List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org From: Alistair Francis This patch fixes two mistakes in the interrupt logic. First we only trigger single-queue or multi-queue interrupts if the status register is set. This logic was already used for non multi-queue interrupts but it also applies to multi-queue interrupts. Secondly we need to lower the interrupts if the ISR isn't set. As part of this we can remove the other interrupt lowering logic and consolidate it inside gem_update_int_status(). Signed-off-by: Alistair Francis Message-id: 438bcc014f8f8a2f8f68f322cb6a53f4c04688c2.1491947224.git.alistair.francis@xilinx.com Signed-off-by: Peter Maydell Reviewed-by: Peter Maydell --- hw/net/cadence_gem.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c index a66a9cc..e1962e1 100644 --- a/hw/net/cadence_gem.c +++ b/hw/net/cadence_gem.c @@ -509,7 +509,18 @@ static void gem_update_int_status(CadenceGEMState *s) { int i; - if ((s->num_priority_queues == 1) && s->regs[GEM_ISR]) { + if (!s->regs[GEM_ISR]) { + /* ISR isn't set, clear all the interrupts */ + for (i = 0; i < s->num_priority_queues; ++i) { + qemu_set_irq(s->irq[i], 0); + } + return; + } + + /* If we get here we know s->regs[GEM_ISR] is set, so we don't need to + * check it again. + */ + if (s->num_priority_queues == 1) { /* No priority queues, just trigger the interrupt */ DB_PRINT("asserting int.\n"); qemu_set_irq(s->irq[0], 1); @@ -1274,7 +1285,6 @@ static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size) { CadenceGEMState *s; uint32_t retval; - int i; s = (CadenceGEMState *)opaque; offset >>= 2; @@ -1285,9 +1295,7 @@ static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size) switch (offset) { case GEM_ISR: DB_PRINT("lowering irqs on ISR read\n"); - for (i = 0; i < s->num_priority_queues; ++i) { - qemu_set_irq(s->irq[i], 0); - } + /* The interrupts get updated at the end of the function. */ break; case GEM_PHYMNTNC: if (retval & GEM_PHYMNTNC_OP_R) { -- 2.7.4