source: rtems/c/src/lib/libbsp/arm/tms570/misc/cpucounterread.c @ dc95663e

5
Last change on this file since dc95663e was dc95663e, checked in by Sebastian Huber <sebastian.huber@…>, on 03/09/17 at 13:14:42

bsp/tms570: Fix CPU counter frequency

The CPU counter runs with the processor frequency. Use
RTEMS_SYSINIT_ITEM() to initialize the CPU counter.

  • Property mode set to 100644
File size: 2.7 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup tms570_clocks
5 *
6 * @brief Cortex-R performace counters
7 *
8 * The counters setup functions are these which has been suggested
9 * on StackOverflow
10 *
11 * Code is probably for use on Cortex-A without modifications as well.
12 *
13 * http://stackoverflow.com/questions/3247373/how-to-measure-program-execution-time-in-arm-cortex-a8-processor
14 */
15
16/*
17 * Copyright (c) 2014 Pavel Pisa <pisa@cmp.felk.cvut.cz>
18 *
19 * Czech Technical University in Prague
20 * Zikova 1903/4
21 * 166 36 Praha 6
22 * Czech Republic
23 *
24 * The license and distribution terms for this file may be
25 * found in the file LICENSE in this distribution or at
26 * http://www.rtems.org/license/LICENSE.
27 */
28
29#include <rtems/counter.h>
30#include <rtems/sysinit.h>
31
32#include <bsp.h>
33
34/**
35 * @brief set mode of Cortex-R performance counters
36 *
37 * Based on example found on http://stackoverflow.com
38 *
39 * @param[in] do_reset if set, values of the counters are reset
40 * @param[in] enable_divider if set, CCNT counts clocks divided by 64
41 * @retval Void
42 */
43static inline void tms570_init_perfcounters(
44    int32_t do_reset,
45    int32_t enable_divider
46)
47{
48  /* in general enable all counters (including cycle counter) */
49  int32_t value = 1;
50
51  /* peform reset */
52  if (do_reset)
53  {
54    value |= 2;     /* reset all counters to zero */
55    value |= 4;     /* reset cycle counter to zero */
56  }
57
58  if (enable_divider)
59    value |= 8;     /* enable "by 64" divider for CCNT */
60
61  value |= 16;
62
63  /* program the performance-counter control-register */
64  asm volatile ("mcr p15, 0, %0, c9, c12, 0\t\n" :: "r"(value));
65
66  /* enable all counters */
67  asm volatile ("mcr p15, 0, %0, c9, c12, 1\t\n" :: "r"(0x8000000f));
68
69  /* clear overflows */
70  asm volatile ("mcr p15, 0, %0, c9, c12, 3\t\n" :: "r"(0x8000000f));
71}
72
73/**
74 * @brief initialize Cortex-R performance counters subsystem
75 *
76 * Based on example found on http://stackoverflow.com
77 *
78 * @retval Void
79 *
80 */
81static void tms570_cpu_counter_initialize(void)
82{
83  /* enable user-mode access to the performance counter */
84  asm volatile ("mcr p15, 0, %0, c9, c14, 0\n\t" :: "r"(1));
85
86  /* disable counter overflow interrupts (just in case) */
87  asm volatile ("mcr p15, 0, %0, c9, c14, 2\n\t" :: "r"(0x8000000f));
88
89  tms570_init_perfcounters(false, false);
90  rtems_counter_initialize_converter(2 * BSP_PLL_OUT_CLOCK);
91}
92
93/**
94 * @brief returns the actual value of Cortex-R cycle counter register
95 *
96 * The register is incremented at each core clock period
97 *
98 * @retval x actual core clock counter value
99 *
100 */
101CPU_Counter_ticks _CPU_Counter_read(void)
102{
103  uint32_t ticks;
104  asm volatile ("mrc p15, 0, %0, c9, c13, 0\n": "=r" (ticks));
105  return ticks;
106}
107
108RTEMS_SYSINIT_ITEM(
109  tms570_cpu_counter_initialize,
110  RTEMS_SYSINIT_BSP_START,
111  RTEMS_SYSINIT_ORDER_FIRST
112);
Note: See TracBrowser for help on using the repository browser.