Skip to content

Commit

Permalink
target-arm: Add trace events for the generic timers
Browse files Browse the repository at this point in the history
Add some useful trace events for the ARM generic timers (notably
the various register writes and the resulting IRQ line state).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1476294876-12340-3-git-send-email-peter.maydell@linaro.org
  • Loading branch information
pm215 committed Oct 17, 2016
1 parent 5dbdc43 commit 194cbc4
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
1 change: 1 addition & 0 deletions Makefile.objs
Expand Up @@ -155,6 +155,7 @@ trace-events-y += hw/alpha/trace-events
trace-events-y += ui/trace-events
trace-events-y += audio/trace-events
trace-events-y += net/trace-events
trace-events-y += target-arm/trace-events
trace-events-y += target-i386/trace-events
trace-events-y += target-sparc/trace-events
trace-events-y += target-s390x/trace-events
Expand Down
20 changes: 16 additions & 4 deletions target-arm/helper.c
@@ -1,4 +1,5 @@
#include "qemu/osdep.h"
#include "trace.h"
#include "cpu.h"
#include "internals.h"
#include "exec/gdbstub.h"
Expand Down Expand Up @@ -1560,10 +1561,13 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
/* Note that this must be unsigned 64 bit arithmetic: */
int istatus = count - offset >= gt->cval;
uint64_t nexttick;
int irqstate;

gt->ctl = deposit32(gt->ctl, 2, 1, istatus);
qemu_set_irq(cpu->gt_timer_outputs[timeridx],
(istatus && !(gt->ctl & 2)));

irqstate = (istatus && !(gt->ctl & 2));
qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);

if (istatus) {
/* Next transition is when count rolls back over to zero */
nexttick = UINT64_MAX;
Expand All @@ -1580,11 +1584,13 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
nexttick = INT64_MAX / GTIMER_SCALE;
}
timer_mod(cpu->gt_timer[timeridx], nexttick);
trace_arm_gt_recalc(timeridx, irqstate, nexttick);
} else {
/* Timer disabled: ISTATUS and timer output always clear */
gt->ctl &= ~4;
qemu_set_irq(cpu->gt_timer_outputs[timeridx], 0);
timer_del(cpu->gt_timer[timeridx]);
trace_arm_gt_recalc_disabled(timeridx);
}
}

Expand All @@ -1610,6 +1616,7 @@ static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
int timeridx,
uint64_t value)
{
trace_arm_gt_cval_write(timeridx, value);
env->cp15.c14_timer[timeridx].cval = value;
gt_recalc_timer(arm_env_get_cpu(env), timeridx);
}
Expand All @@ -1629,6 +1636,7 @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
{
uint64_t offset = timeridx == GTIMER_VIRT ? env->cp15.cntvoff_el2 : 0;

trace_arm_gt_tval_write(timeridx, value);
env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) - offset +
sextract64(value, 0, 32);
gt_recalc_timer(arm_env_get_cpu(env), timeridx);
Expand All @@ -1641,6 +1649,7 @@ static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
ARMCPU *cpu = arm_env_get_cpu(env);
uint32_t oldval = env->cp15.c14_timer[timeridx].ctl;

trace_arm_gt_ctl_write(timeridx, value);
env->cp15.c14_timer[timeridx].ctl = deposit64(oldval, 0, 2, value);
if ((oldval ^ value) & 1) {
/* Enable toggled */
Expand All @@ -1649,8 +1658,10 @@ static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
/* IMASK toggled: don't need to recalculate,
* just set the interrupt line based on ISTATUS
*/
qemu_set_irq(cpu->gt_timer_outputs[timeridx],
(oldval & 4) && !(value & 2));
int irqstate = (oldval & 4) && !(value & 2);

trace_arm_gt_imask_toggle(timeridx, irqstate);
qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
}
}

Expand Down Expand Up @@ -1715,6 +1726,7 @@ static void gt_cntvoff_write(CPUARMState *env, const ARMCPRegInfo *ri,
{
ARMCPU *cpu = arm_env_get_cpu(env);

trace_arm_gt_cntvoff_write(value);
raw_write(env, ri, value);
gt_recalc_timer(cpu, GTIMER_VIRT);
}
Expand Down
10 changes: 10 additions & 0 deletions target-arm/trace-events
@@ -0,0 +1,10 @@
# See docs/tracing.txt for syntax documentation.

# target-arm/helper.c
arm_gt_recalc(int timer, int irqstate, uint64_t nexttick) "gt recalc: timer %d irqstate %d next tick %" PRIx64
arm_gt_recalc_disabled(int timer) "gt recalc: timer %d irqstate 0 timer disabled"
arm_gt_cval_write(int timer, uint64_t value) "gt_cval_write: timer %d value %" PRIx64
arm_gt_tval_write(int timer, uint64_t value) "gt_tval_write: timer %d value %" PRIx64
arm_gt_ctl_write(int timer, uint64_t value) "gt_ctl_write: timer %d value %" PRIx64
arm_gt_imask_toggle(int timer, int irqstate) "gt_ctl_write: timer %d IMASK toggle, new irqstate %d"
arm_gt_cntvoff_write(uint64_t value) "gt_cntvoff_write: value %" PRIx64

0 comments on commit 194cbc4

Please sign in to comment.