blob: da5291a48ac588201bfef37eb7c0990de4ecaf47 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
/**
* @file
* @brief IDT 4650 Timer Driver.
*
* This file manages the benchmark timer used by the RTEMS Timing Test
* Suite.
*/
/*
* Author: Craig Lebakken <craigl@transition.com>
*
* COPYRIGHT (c) 1996 by Transition Networks Inc.
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of Transition Networks not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* Transition Networks makes no representations about the suitability
* of this software for any purpose.
*
* derived from src/lib/libbsp/no_cpu/no_bsp/timer/timer.c
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems.h>
#include <rtems/btimer.h>
#define CLOCKS_PER_MICROSECOND ( CPU_CLOCK_RATE_MHZ )
#define TIMER_MAX_VALUE 0xffffffff
extern uint32_t mips_read_timer( void );
static bool benchmark_timer_find_average_overhead;
static uint32_t benchmark_timer_initial_value = 0;
void benchmark_timer_initialize( void )
{
benchmark_timer_initial_value = mips_read_timer();
/*
* Somehow start the timer
*/
/* Timer on 4650 is always running */
}
/*
* The following controls the behavior of benchmark_timer_read().
*
* AVG_OVEREHAD is the overhead for starting and stopping the timer. It
* is usually deducted from the number returned.
*
* LEAST_VALID is the lowest number this routine should trust. Numbers
* below this are "noise" and zero is returned.
*/
#define AVG_OVERHEAD 8 /* It typically takes X.X microseconds */
/* (Y countdowns) to start/stop the timer. */
/* This value is in cycles. */
#define LEAST_VALID 1 /* Don't trust a clicks value lower than this */
benchmark_timer_t benchmark_timer_read( void )
{
uint64_t clicks;
uint32_t total;
/*
* Read the timer and see how many clicks it has been since we started.
*/
clicks = mips_read_timer(); /* XXX: read some HW here */
if (clicks < benchmark_timer_initial_value)
{
clicks += TIMER_MAX_VALUE;
}
clicks -= benchmark_timer_initial_value;
/*
* Total is calculated by taking into account the number of timer overflow
* interrupts since the timer was initialized and clicks since the last
* interrupts.
*/
#if 0 /* leave total in number of cycles */
total = clicks / CLOCKS_PER_MICROSECOND;
#else
total = clicks;
#endif
if ( benchmark_timer_find_average_overhead == 1 )
return total; /* in # cycles units */
else {
if ( total < LEAST_VALID )
return 0; /* below timer resolution */
/*
* leave total in cycles
*/
return (total - AVG_OVERHEAD);
}
}
void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
{
benchmark_timer_find_average_overhead = find_flag;
}
|