From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JHVlA-0004r7-Fg for qemu-devel@nongnu.org; Tue, 22 Jan 2008 21:54:40 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JHVl7-0004pp-MY for qemu-devel@nongnu.org; Tue, 22 Jan 2008 21:54:38 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JHVl7-0004pl-DO for qemu-devel@nongnu.org; Tue, 22 Jan 2008 21:54:37 -0500 Received: from pop-gadwall.atl.sa.earthlink.net ([207.69.195.61]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1JHVl7-0006Er-1l for qemu-devel@nongnu.org; Tue, 22 Jan 2008 21:54:37 -0500 Received: from user-142h2k8.cable.mindspring.com ([72.40.138.136] helo=earthlink.net) by pop-gadwall.atl.sa.earthlink.net with esmtp (Exim 3.36 #1) id 1JHVl5-0004Hs-00 for qemu-devel@nongnu.org; Tue, 22 Jan 2008 21:54:35 -0500 Message-ID: <4796AC6C.5030408@earthlink.net> Date: Tue, 22 Jan 2008 21:54:36 -0500 From: Robert Reif MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------060606010100020200020707" Subject: [Qemu-devel] [PATCH] hw/slavio_timer.c user timer limit bit fix Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. --------------060606010100020200020707 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Set limit bit when user timer expires. Clear limit bit when user timer count set. Set ptimer count when user timer count set. --------------060606010100020200020707 Content-Type: text/plain; name="timer1.diff.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="timer1.diff.txt" Index: hw/slavio_timer.c =================================================================== RCS file: /sources/qemu/qemu/hw/slavio_timer.c,v retrieving revision 1.28 diff -p -u -r1.28 slavio_timer.c --- hw/slavio_timer.c 1 Jan 2008 17:06:38 -0000 1.28 +++ hw/slavio_timer.c 23 Jan 2008 02:33:57 -0000 @@ -122,10 +122,9 @@ static void slavio_timer_irq(void *opaqu slavio_timer_get_out(s); DPRINTF("callback: count %x%08x\n", s->counthigh, s->count); - if (!slavio_timer_is_user(s)) { - s->reached = TIMER_REACHED; + s->reached = TIMER_REACHED; + if (!slavio_timer_is_user(s)) qemu_irq_raise(s->irq); - } } static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr) @@ -141,7 +140,7 @@ static uint32_t slavio_timer_mem_readl(v if (slavio_timer_is_user(s)) { // read user timer MSW slavio_timer_get_out(s); - ret = s->counthigh; + ret = s->counthigh | s->reached; } else { // read limit // clear irq @@ -155,7 +154,7 @@ static uint32_t slavio_timer_mem_readl(v // of counter (user mode) slavio_timer_get_out(s); if (slavio_timer_is_user(s)) // read user timer LSW - ret = s->count & TIMER_COUNT_MASK32; + ret = s->count & TIMER_MAX_COUNT64; else // read limit ret = (s->count & TIMER_MAX_COUNT32) | s->reached; break; @@ -190,12 +189,19 @@ static void slavio_timer_mem_writel(void switch (saddr) { case TIMER_LIMIT: if (slavio_timer_is_user(s)) { + uint64_t count; // set user counter MSW, reset counter qemu_irq_lower(s->irq); s->limit = TIMER_MAX_COUNT64; - DPRINTF("processor %d user timer reset\n", s->slave_index); - if (s->timer) - ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(s->limit), 1); + s->counthigh = val & (TIMER_MAX_COUNT64 >> 32); + s->reached = 0; + count = ((uint64_t)s->counthigh << 32) | s->count; + DPRINTF("processor %d user timer set to %016llx\n", s->slave_index, + count); + if (s->timer) { + ptimer_set_count(s->timer, LIMIT_TO_PERIODS(s->limit - count)); + ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(s->limit), 0); + } } else { // set limit, reset counter qemu_irq_lower(s->irq); @@ -210,12 +216,19 @@ static void slavio_timer_mem_writel(void break; case TIMER_COUNTER: if (slavio_timer_is_user(s)) { + uint64_t count; // set user counter LSW, reset counter qemu_irq_lower(s->irq); s->limit = TIMER_MAX_COUNT64; - DPRINTF("processor %d user timer reset\n", s->slave_index); - if (s->timer) - ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(s->limit), 1); + s->count = val & TIMER_MAX_COUNT64; + s->reached = 0; + count = ((uint64_t)s->counthigh) << 32 | s->count; + DPRINTF("processor %d user timer set to %016llx\n", s->slave_index, + count); + if (s->timer) { + ptimer_set_count(s->timer, LIMIT_TO_PERIODS(s->limit - count)); + ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(s->limit), 0); + } } else DPRINTF("not user timer\n"); break; --------------060606010100020200020707--