diff options
author | Blue Swirl <blauwirbel@gmail.com> | 2010-04-03 06:17:35 +0000 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2010-04-03 06:17:35 +0000 |
commit | 68fb89a2c07b6ad1e69a9a45f664d533f2662ec6 (patch) | |
tree | fda0fe64363a15cf360a440b52d46605b0bf4e26 | |
parent | 25da2f343cba4f854f19b2b52817f2e5c851ee17 (diff) | |
download | qemu-68fb89a2c07b6ad1e69a9a45f664d533f2662ec6.zip qemu-68fb89a2c07b6ad1e69a9a45f664d533f2662ec6.tar.gz qemu-68fb89a2c07b6ad1e69a9a45f664d533f2662ec6.tar.bz2 |
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>
-rw-r--r-- | 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); |