1 |
30 |
unneback |
/* timer.c
|
2 |
|
|
*
|
3 |
|
|
* This file manages the benchmark timer used by the RTEMS Timing Test Suite.
|
4 |
|
|
* Each measured time period is demarcated by calls to Timer_initialize() and
|
5 |
|
|
* Read_timer(). Read_timer() usually returns the number of microseconds
|
6 |
|
|
* since Timer_initialize() exitted.
|
7 |
|
|
*
|
8 |
|
|
* These functions are prototyped in rtems/c/src/lib/include/timerdrv.h and
|
9 |
|
|
* must be implemented as part of the BSP.
|
10 |
|
|
*
|
11 |
|
|
* This port does not allow the application to select which timer on the
|
12 |
|
|
* MVME167 to use for the timer, nor does it allow the application to
|
13 |
|
|
* configure the timer. The timer uses the VMEchip2 Tick Timer #1. This timer
|
14 |
|
|
* is distinct from the clock, which uses Tick Timer #2 in the VMEchip2.
|
15 |
|
|
*
|
16 |
|
|
* All page references are to the MVME166/MVME167/MVME187 Single Board
|
17 |
|
|
* Computer Programmer's Reference Guide (MVME187PG/D2) with the April 1993
|
18 |
|
|
* supplements/addenda (MVME187PG/D2A1).
|
19 |
|
|
*
|
20 |
|
|
* COPYRIGHT (c) 1989-1999.
|
21 |
|
|
* On-Line Applications Research Corporation (OAR).
|
22 |
|
|
*
|
23 |
|
|
* The license and distribution terms for this file may be
|
24 |
|
|
* found in the file LICENSE in this distribution or at
|
25 |
|
|
* http://www.OARcorp.com/rtems/license.html.
|
26 |
|
|
*
|
27 |
|
|
* Modifications of respective RTEMS file:
|
28 |
|
|
* Copyright (c) 1998, National Research Council of Canada
|
29 |
|
|
*
|
30 |
|
|
* $Id: timer.c,v 1.2 2001-09-27 12:00:20 chris Exp $
|
31 |
|
|
*/
|
32 |
|
|
|
33 |
|
|
#include <rtems.h>
|
34 |
|
|
#include <bsp.h>
|
35 |
|
|
|
36 |
|
|
/* Periodic tick interval */
|
37 |
|
|
#define TICK_INTERVAL 10000UL /* T1's countdown constant (10 ms) */
|
38 |
|
|
#define TIMER_INT_LEVEL 6 /* T1's interrupt level */
|
39 |
|
|
#define TIMER_VECTOR (VBR0 * 0x10 + 0x8) /* T1 is vector $X8 (p. 2-71)*/
|
40 |
|
|
|
41 |
|
|
/* Number of interrupts since timer was re-initialized */
|
42 |
|
|
rtems_unsigned32 Ttimer_val;
|
43 |
|
|
|
44 |
|
|
/*
|
45 |
|
|
* Set to TRUE to return raw value. Normally zero. Depends on being allocated
|
46 |
|
|
* in the .bss section and on that section being explicitly zeroed at boot
|
47 |
|
|
* time.
|
48 |
|
|
*/
|
49 |
|
|
rtems_boolean Timer_driver_Find_average_overhead;
|
50 |
|
|
|
51 |
|
|
rtems_isr timerisr();
|
52 |
|
|
|
53 |
|
|
/*
|
54 |
|
|
* This routine initializes the Tick Timer 1 on the MVME167 board.
|
55 |
|
|
*
|
56 |
|
|
* Input parameters: NONE
|
57 |
|
|
*
|
58 |
|
|
* Output parameters: NONE
|
59 |
|
|
*
|
60 |
|
|
* NOTE: This routine may not work if the optimizer is enabled for some
|
61 |
|
|
* compilers. The multiple writes may be optimized away.
|
62 |
|
|
*
|
63 |
|
|
* It is important that the timer start/stop overhead be
|
64 |
|
|
* determined when porting or modifying this code.
|
65 |
|
|
*
|
66 |
|
|
* THE VMECHIP2 PRESCALER REGISTER IS ASSUMED TO BE SET!
|
67 |
|
|
* The prescaler is used by all VMEchip2 timers, including the VMEbus grant
|
68 |
|
|
* timeout counter, the DMAC time off timer, the DMAC timer on timer, and the
|
69 |
|
|
* VMEbus global timeout timer. The prescaler value is normally set by the
|
70 |
|
|
* boot ROM to provide a 1 MHz clock to the timers. For a 25 MHz MVME167, the
|
71 |
|
|
* prescaler value should be 0xE7 (page 2-63).
|
72 |
|
|
*/
|
73 |
|
|
void Timer_initialize()
|
74 |
|
|
{
|
75 |
|
|
(void) set_vector( timerisr, TIMER_VECTOR, 0 );
|
76 |
|
|
|
77 |
|
|
Ttimer_val = 0; /* clear timer ISR count */
|
78 |
|
|
lcsr->intr_ena &= 0xFEFFFFFF; /* disable tick timer 1 interrupt */
|
79 |
|
|
lcsr->intr_clear |= 0x01000000; /* clear tick timer 1 interrupt */
|
80 |
|
|
lcsr->intr_level[0] = /* set int level */
|
81 |
|
|
(lcsr->intr_level[0] & 0xFFFFFFF0) | TIMER_INT_LEVEL;
|
82 |
|
|
lcsr->timer_cmp_1 = TICK_INTERVAL; /* period in compare register */
|
83 |
|
|
lcsr->timer_cnt_1 = 0; /* clear tick timer 1 counter */
|
84 |
|
|
lcsr->board_ctl |= 7; /* start tick timer 1, reset-on-compare, */
|
85 |
|
|
/* and clear overflow counter */
|
86 |
|
|
|
87 |
|
|
lcsr->intr_ena |= 0x01000000; /* enable tick timer 1 interrupt */
|
88 |
|
|
lcsr->vector_base |= MASK_INT; /* unmask VMEchip2 interrupts */
|
89 |
|
|
}
|
90 |
|
|
|
91 |
|
|
#define AVG_OVERHEAD 3UL /* It typically takes 3.0 microseconds */
|
92 |
|
|
/* (3 countdowns) to start/stop the timer. */
|
93 |
|
|
#define LEAST_VALID 3UL /* Don't trust a value lower than this */
|
94 |
|
|
|
95 |
|
|
|
96 |
|
|
/*
|
97 |
|
|
* This routine reads the Tick Timer 1 on the MVME167 board.
|
98 |
|
|
*
|
99 |
|
|
* Input parameters: NONE
|
100 |
|
|
*
|
101 |
|
|
* Output parameters: time in microseconds
|
102 |
|
|
*
|
103 |
|
|
* AVG_OVEREHAD is the overhead for starting and stopping the timer. It
|
104 |
|
|
* is usually deducted from the number returned.
|
105 |
|
|
*
|
106 |
|
|
* LEAST_VALID is the lowest number this routine should trust. Numbers
|
107 |
|
|
* below this are "noise" and zero is returned.
|
108 |
|
|
*/
|
109 |
|
|
int Read_timer()
|
110 |
|
|
{
|
111 |
|
|
rtems_unsigned32 total;
|
112 |
|
|
|
113 |
|
|
total = (Ttimer_val * TICK_INTERVAL) + lcsr->timer_cnt_1;
|
114 |
|
|
|
115 |
|
|
if ( Timer_driver_Find_average_overhead )
|
116 |
|
|
return total; /* in one microsecond units */
|
117 |
|
|
|
118 |
|
|
if ( total < LEAST_VALID )
|
119 |
|
|
return 0; /* below timer resolution */
|
120 |
|
|
|
121 |
|
|
return total - AVG_OVERHEAD;
|
122 |
|
|
}
|
123 |
|
|
|
124 |
|
|
|
125 |
|
|
/*
|
126 |
|
|
* Empty function call used in loops to measure basic cost of looping
|
127 |
|
|
* in Timing Test Suite.
|
128 |
|
|
*
|
129 |
|
|
* Input parameters: NONE
|
130 |
|
|
*
|
131 |
|
|
* Output parameters: time in microseconds
|
132 |
|
|
*/
|
133 |
|
|
rtems_status_code Empty_function( void )
|
134 |
|
|
{
|
135 |
|
|
return RTEMS_SUCCESSFUL;
|
136 |
|
|
}
|
137 |
|
|
|
138 |
|
|
|
139 |
|
|
/*
|
140 |
|
|
* This routine sets the Timer_driver_Find_average_overhead flag in this
|
141 |
|
|
* module.
|
142 |
|
|
*
|
143 |
|
|
* Input parameters: NONE
|
144 |
|
|
*
|
145 |
|
|
* Output parameters: time in microseconds
|
146 |
|
|
*/
|
147 |
|
|
void Set_find_average_overhead(
|
148 |
|
|
rtems_boolean find_flag
|
149 |
|
|
)
|
150 |
|
|
{
|
151 |
|
|
Timer_driver_Find_average_overhead = find_flag;
|
152 |
|
|
}
|