From patchwork Sun Jun 13 12:15:42 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 55423 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 98DBCB7D84 for ; Sun, 13 Jun 2010 22:28:29 +1000 (EST) Received: from localhost ([127.0.0.1]:42585 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1ONmIF-0000kR-VP for incoming@patchwork.ozlabs.org; Sun, 13 Jun 2010 08:28:04 -0400 Received: from [140.186.70.92] (port=44636 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1ONm6Y-0001jM-Qo for qemu-devel@nongnu.org; Sun, 13 Jun 2010 08:16:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1ONm6W-000335-8a for qemu-devel@nongnu.org; Sun, 13 Jun 2010 08:15:58 -0400 Received: from fmmailgate01.web.de ([217.72.192.221]:54928) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1ONm6V-00032Z-UI for qemu-devel@nongnu.org; Sun, 13 Jun 2010 08:15:56 -0400 Received: from smtp01.web.de ( [172.20.0.243]) by fmmailgate01.web.de (Postfix) with ESMTP id 67E8515EFE504; Sun, 13 Jun 2010 14:15:55 +0200 (CEST) Received: from [92.74.52.35] (helo=localhost.localdomain) by smtp01.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #4) id 1ONm6V-0004oR-00; Sun, 13 Jun 2010 14:15:55 +0200 From: Jan Kiszka To: Anthony Liguori , qemu-devel@nongnu.org Date: Sun, 13 Jun 2010 14:15:42 +0200 Message-Id: X-Mailer: git-send-email 1.6.0.2 In-Reply-To: References: In-Reply-To: References: X-Sender: jan.kiszka@web.de X-Provags-ID: V01U2FsdGVkX1/RYSmNt2aRY+cInOvCfKHsuS3EDb3+dH2vW0Kk +gApRgKSBjD7hP4aIP+HAzkJD575yxhniqBnl6fSqhJpkLBA5X RAXl6zrmA= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 Cc: blue Swirl , Jan Kiszka , Paul Brook , Gleb Natapov , Juan Quintela Subject: [Qemu-devel] [PATCH v4 09/13] hpet: Add support for level-triggered interrupts X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Jan Kiszka By implementing this feature we can also remove a nasty way to kill qemu (by trying to enable level-triggered hpet interrupts). Signed-off-by: Jan Kiszka --- hw/hpet.c | 32 ++++++++++++++++++++++---------- 1 files changed, 22 insertions(+), 10 deletions(-) diff --git a/hw/hpet.c b/hw/hpet.c index 59a06f6..f24b227 100644 --- a/hw/hpet.c +++ b/hw/hpet.c @@ -159,8 +159,10 @@ static inline uint64_t hpet_calculate_diff(HPETTimer *t, uint64_t current) } } -static void update_irq(struct HPETTimer *timer) +static void update_irq(struct HPETTimer *timer, int set) { + uint64_t mask; + HPETState *s; int route; if (timer->tn <= 1 && hpet_in_legacy_mode(timer->state)) { @@ -172,10 +174,18 @@ static void update_irq(struct HPETTimer *timer) } else { route = timer_int_route(timer); } - if (!timer_enabled(timer) || !hpet_enabled(timer->state)) { - return; + s = timer->state; + mask = 1 << timer->tn; + if (!set || !timer_enabled(timer) || !hpet_enabled(timer->state)) { + s->isr &= ~mask; + qemu_irq_lower(s->irqs[route]); + } else if (timer->config & HPET_TN_TYPE_LEVEL) { + s->isr |= mask; + qemu_irq_raise(s->irqs[route]); + } else { + s->isr &= ~mask; + qemu_irq_pulse(s->irqs[route]); } - qemu_irq_pulse(timer->state->irqs[route]); } static void hpet_pre_save(void *opaque) @@ -261,7 +271,7 @@ static void hpet_timer(void *opaque) t->wrap_flag = 0; } } - update_irq(t); + update_irq(t, 1); } static void hpet_set_timer(HPETTimer *t) @@ -291,6 +301,7 @@ static void hpet_set_timer(HPETTimer *t) static void hpet_del_timer(HPETTimer *t) { qemu_del_timer(t->qemu_timer); + update_irq(t, 0); } #ifdef HPET_DEBUG @@ -423,10 +434,6 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr, timer->cmp = (uint32_t)timer->cmp; timer->period = (uint32_t)timer->period; } - if (new_val & HPET_TN_TYPE_LEVEL) { - printf("qemu: level-triggered hpet not supported\n"); - exit (-1); - } if (activating_bit(old_val, new_val, HPET_TN_ENABLE)) { hpet_set_timer(timer); } else if (deactivating_bit(old_val, new_val, HPET_TN_ENABLE)) { @@ -522,7 +529,12 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr, DPRINTF("qemu: invalid HPET_CFG+4 write \n"); break; case HPET_STATUS: - /* FIXME: need to handle level-triggered interrupts */ + val = new_val & s->isr; + for (i = 0; i < HPET_NUM_TIMERS; i++) { + if (val & (1 << i)) { + update_irq(&s->timer[i], 0); + } + } break; case HPET_COUNTER: if (hpet_enabled(s)) {