* [Qemu-devel] [PATCH] Sun4m : Timer RUN/STOP bit.
@ 2014-02-16 23:14 Olivier Danet
2014-02-23 17:34 ` Mark Cave-Ayland
0 siblings, 1 reply; 2+ messages in thread
From: Olivier Danet @ 2014-02-16 23:14 UTC (permalink / raw)
To: qemu-devel, Blue Swirl, Mark Cave-Ayland, Artyom Tarasenko
The Sun4m architecture has one 'system' timer and one timer per CPU.
The CPU timers can be configured in two modes :
* 22bits Counter/Timer. Periodic interrupts.
* 54bits 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 <odanet@caramail.com>
---
hw/timer/slavio_timer.c | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/hw/timer/slavio_timer.c b/hw/timer/slavio_timer.c
index f75b914..e4dccea 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;
--
1.8.1.5
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [Qemu-devel] [PATCH] Sun4m : Timer RUN/STOP bit.
2014-02-16 23:14 [Qemu-devel] [PATCH] Sun4m : Timer RUN/STOP bit Olivier Danet
@ 2014-02-23 17:34 ` Mark Cave-Ayland
0 siblings, 0 replies; 2+ messages in thread
From: Mark Cave-Ayland @ 2014-02-23 17:34 UTC (permalink / raw)
To: Olivier Danet; +Cc: Blue Swirl, qemu-devel, Artyom Tarasenko
On 16/02/14 23:14, Olivier Danet wrote:
> The Sun4m architecture has one 'system' timer and one timer per CPU.
> The CPU timers can be configured in two modes :
> * 22bits Counter/Timer. Periodic interrupts.
> * 54bits 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 <odanet@caramail.com>
> ---
> hw/timer/slavio_timer.c | 25 ++++++++++---------------
> 1 file changed, 10 insertions(+), 15 deletions(-)
>
> diff --git a/hw/timer/slavio_timer.c b/hw/timer/slavio_timer.c
> index f75b914..e4dccea 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;
This appears to pass my tests, and does seem to agree with my reading of
the NCR89C105.txt specification mentioned in the file header.
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
I've applied this to my qemu-sparc branch.
ATB,
Mark.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2014-02-23 17:36 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-16 23:14 [Qemu-devel] [PATCH] Sun4m : Timer RUN/STOP bit Olivier Danet
2014-02-23 17:34 ` Mark Cave-Ayland
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.