Patchwork Re: 452efb didn't show up in the list

login
register
mail settings
Submitter Blue Swirl
Date April 2, 2010, 4:18 p.m.
Message ID <m2tf43fc5581004020918l989a9cbavc4cabd6234c6ff74@mail.gmail.com>
Download mbox | patch
Permalink /patch/49313/
State New
Headers show

Comments

Blue Swirl - April 2, 2010, 4:18 p.m.
On 4/1/10, Artyom Tarasenko <atar4qemu@googlemail.com> wrote:
> 2010/4/1 Blue Swirl <blauwirbel@gmail.com>:
>  > Which list?
>
>  This mailing list?
>
>
>  > On 4/1/10, Artyom Tarasenko <atar4qemu@googlemail.com> wrote:
>  >> and looks wrong or incomplete to me:
>  >>
>  >>  >According to Sun4M System Architecture Manual chapter 5.3.2, a limit
>  >>  >of 0 will not generate interrupts.
>  >>
>  >>  This is indeed correct, but the chapter 5.3.2 also explains why:
>  >>
>  >>  "Setting the limit register to  0  allows the counter to free run. Since the
>  >>  timer always resets to a value of 500 nS after reaching maximum count,
>  >>  there is no match and no interrupts are generated."
>  >>
>  >>  The part about 500 nS (0x00000200 in the counter register) and
>  >>  no match seems to be not addressed.
>  >
>  > The 500ns offset part could be addressed by making the timer period
>  > shorter by 1 tick. I doubt such a change would have any visible
>  > difference with QEMU, except that tick count of 0 should never appear
>  > in the counter but it may now.
>
>
> as well as all the other values between 0 and 0x200. But it's less
>  important I guess.
>
>
>  > For the no match part, t->reached should not be set if t->limit == 0.

I think this patch would do what is expected.
Artyom Tarasenko - April 2, 2010, 8:32 p.m.
2010/4/2 Blue Swirl <blauwirbel@gmail.com>:
> On 4/1/10, Artyom Tarasenko <atar4qemu@googlemail.com> wrote:
>> 2010/4/1 Blue Swirl <blauwirbel@gmail.com>:
>>  > Which list?
>>
>>  This mailing list?
>>
>>
>>  > On 4/1/10, Artyom Tarasenko <atar4qemu@googlemail.com> wrote:
>>  >> and looks wrong or incomplete to me:
>>  >>
>>  >>  >According to Sun4M System Architecture Manual chapter 5.3.2, a limit
>>  >>  >of 0 will not generate interrupts.
>>  >>
>>  >>  This is indeed correct, but the chapter 5.3.2 also explains why:
>>  >>
>>  >>  "Setting the limit register to  0  allows the counter to free run. Since the
>>  >>  timer always resets to a value of 500 nS after reaching maximum count,
>>  >>  there is no match and no interrupts are generated."
>>  >>
>>  >>  The part about 500 nS (0x00000200 in the counter register) and
>>  >>  no match seems to be not addressed.
>>  >
>>  > The 500ns offset part could be addressed by making the timer period
>>  > shorter by 1 tick. I doubt such a change would have any visible
>>  > difference with QEMU, except that tick count of 0 should never appear
>>  > in the counter but it may now.
>>
>>
>> as well as all the other values between 0 and 0x200. But it's less
>>  important I guess.
>>
>>
>>  > For the no match part, t->reached should not be set if t->limit == 0.
>
> I think this patch would do what is expected.

Looks good and passes my tests, thanks.

Redefining LIMIT_TO_PERIODS is a really nice solution.

Patch

From 7ef9679874d24f3062bf64525d9dd13d45dc2f27 Mon Sep 17 00:00:00 2001
From: Blue Swirl <blauwirbel@gmail.com>
Date: Fri, 2 Apr 2010 15:54:26 +0000
Subject: [PATCH] sparc32: improve timer implementation

Timer with zero period (free-run) will never match.

Timer counting starts with tick value of 0x200, not from 0,
so the period must calculated from one tick less than the limit.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 hw/slavio_timer.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c
index ef36fe4..d787553 100644
--- a/hw/slavio_timer.c
+++ b/hw/slavio_timer.c
@@ -88,8 +88,8 @@  typedef struct TimerContext {
 #define TIMER_MAX_COUNT32  0x7ffffe00ULL
 #define TIMER_REACHED      0x80000000
 #define TIMER_PERIOD       500ULL // 500ns
-#define LIMIT_TO_PERIODS(l) ((l) >> 9)
-#define PERIODS_TO_LIMIT(l) ((l) << 9)
+#define LIMIT_TO_PERIODS(l) (((l) >> 9) - 1)
+#define PERIODS_TO_LIMIT(l) (((l) + 1) << 9)
 
 static int slavio_timer_is_user(TimerContext *tc)
 {
@@ -127,7 +127,10 @@  static void slavio_timer_irq(void *opaque)
 
     slavio_timer_get_out(t);
     DPRINTF("callback: count %x%08x\n", t->counthigh, t->count);
-    t->reached = TIMER_REACHED;
+    /* if limit is 0 (free-run), there will be no match */
+    if (t->limit != 0) {
+        t->reached = TIMER_REACHED;
+    }
     /* there is no interrupt if user timer or free-run */
     if (!slavio_timer_is_user(tc) && t->limit != 0) {
         qemu_irq_raise(t->irq);
-- 
1.5.6.5