From ead4cf04f855575c24e795d7179d93b1601575b7 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Sat, 22 Feb 2014 22:54:53 +0000 Subject: sun4m: fix slavio timer RUN/STOP bit The sun4m architecture has one 'system' timer and one timer per CPU. The CPU timers can be configured in two modes: * 22 bits Counter/Timer. Periodic interrupts. * 54 bits User timer. For profiling. In this mode, the Run/Stop bit controls the timer. The run/stop bit controls the timer only when it is in "User" mode, but its state shall be persistent. Signed-off-by: Olivier Danet Signed-off-by: Mark Cave-Ayland --- hw/timer/slavio_timer.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'hw/timer') diff --git a/hw/timer/slavio_timer.c b/hw/timer/slavio_timer.c index f75b914951..e4dcceaf23 100644 --- a/hw/timer/slavio_timer.c +++ b/hw/timer/slavio_timer.c @@ -51,7 +51,7 @@ typedef struct CPUTimerState { ptimer_state *timer; uint32_t count, counthigh, reached; /* processor only */ - uint32_t running; + uint32_t run; uint64_t limit; } CPUTimerState; @@ -177,7 +177,7 @@ static uint64_t slavio_timer_mem_readl(void *opaque, hwaddr addr, // only available in processor counter/timer // read start/stop status if (timer_index > 0) { - ret = t->running; + ret = t->run; } else { ret = 0; } @@ -260,16 +260,15 @@ static void slavio_timer_mem_writel(void *opaque, hwaddr addr, case TIMER_STATUS: if (slavio_timer_is_user(tc)) { // start/stop user counter - if ((val & 1) && !t->running) { + if (val & 1) { trace_slavio_timer_mem_writel_status_start(timer_index); ptimer_run(t->timer, 0); - t->running = 1; - } else if (!(val & 1) && t->running) { + } else { trace_slavio_timer_mem_writel_status_stop(timer_index); ptimer_stop(t->timer); - t->running = 0; } } + t->run = val & 1; break; case TIMER_MODE: if (timer_index == 0) { @@ -284,8 +283,9 @@ static void slavio_timer_mem_writel(void *opaque, hwaddr addr, if (val & processor) { // counter -> user timer qemu_irq_lower(curr_timer->irq); // counters are always running - ptimer_stop(curr_timer->timer); - curr_timer->running = 0; + if (!curr_timer->run) { + ptimer_stop(curr_timer->timer); + } // user timer limit is always the same curr_timer->limit = TIMER_MAX_COUNT64; ptimer_set_limit(curr_timer->timer, @@ -296,13 +296,8 @@ static void slavio_timer_mem_writel(void *opaque, hwaddr addr, s->cputimer_mode |= processor; trace_slavio_timer_mem_writel_mode_user(timer_index); } else { // user timer -> counter - // stop the user timer if it is running - if (curr_timer->running) { - ptimer_stop(curr_timer->timer); - } // start the counter ptimer_run(curr_timer->timer, 0); - curr_timer->running = 1; // clear this processors user timer bit in config // register s->cputimer_mode &= ~processor; @@ -340,7 +335,7 @@ static const VMStateDescription vmstate_timer = { VMSTATE_UINT32(count, CPUTimerState), VMSTATE_UINT32(counthigh, CPUTimerState), VMSTATE_UINT32(reached, CPUTimerState), - VMSTATE_UINT32(running, CPUTimerState), + VMSTATE_UINT32(run , CPUTimerState), VMSTATE_PTIMER(timer, CPUTimerState), VMSTATE_END_OF_LIST() } @@ -373,7 +368,7 @@ static void slavio_timer_reset(DeviceState *d) ptimer_set_limit(curr_timer->timer, LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1); ptimer_run(curr_timer->timer, 0); - curr_timer->running = 1; + curr_timer->run = 1; } } s->cputimer_mode = 0; -- cgit v1.2.1