source: rtems/c/src/lib/libcpu/sh/sh7032/timer/timer.c @ 4a238002

4.104.114.84.95
Last change on this file since 4a238002 was 4a238002, checked in by Joel Sherrill <joel.sherrill@…>, on 11/18/99 at 21:22:58

Patch from "John M. Mills" <jmills@…> with subsequent cleanup from
Ralf Corsepius <corsepiu@…> that adds initial Hitachi SH-2
support to RTEMS. Ralf's comments are:

Changes:
------

  1. SH-Port:
  • Many files renamed.
  • CONSOLE_DEVNAME and MHZ defines removed from libcpu.
  • console.c moved to libbsp/sh/shared, build in libbsp/sh/<BSP>/console applying VPATH.
  • CONSOLE_DEVNAME made BSP-specific, replacement is defined in bsp.h
  • MHZ define replaced with HZ (extendent resolution) in custom/*.cfg
  • -DHZ=HZ used in bspstart.c, only
  • Makefile variable HZ used in bsp-dependent directories only.
  1. SH1-Port
  • clock-driver rewritten to provide better resolution for odd CPU frequencies. This driver is only partially tested on hardware, ie. sightly experimental, but I don't expect severe problems with it.
  • Polling SCI-driver added. This driver is experimental and completly untested yet. Therefore it is not yet used for the console (/dev/console is still pointing to /dev/null, cf. gensh1/bsp.h).
  • minor changes to the timer driver
  • SH1 specific delay()/CPU_delay() now is implemented as a function
  1. SH2-Port
  • Merged
  • IMO, the code is still in its infancy. Therefore I have interspersed comments (FIXME) it for items which I think John should look after.
  • sci and console drivers partially rewritten and extended (John, I hope you don't mind).
  • Copyright notices are not yet adapted
  • Property mode set to 100644
File size: 5.3 KB
RevLine 
[f8b27df9]1/*
2 *  timer for the Hitachi SH 703X
3 *
4 *  This file manages the benchmark timer used by the RTEMS Timing Test
5 *  Suite.  Each measured time period is demarcated by calls to
6 *  Timer_initialize() and Read_timer().  Read_timer() usually returns
7 *  the number of microseconds since Timer_initialize() exitted.
8 *
9 *  NOTE: It is important that the timer start/stop overhead be
10 *        determined when porting or modifying this code.
11 *
12 *  Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
13 *           Bernd Becker (becker@faw.uni-ulm.de)
14 *
15 *  COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
16 *
17 *  This program is distributed in the hope that it will be useful,
18 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 *  COPYRIGHT (c) 1998.
22 *  On-Line Applications Research Corporation (OAR).
23 *  Copyright assigned to U.S. Government, 1994.
24 *
25 *  The license and distribution terms for this file may be
26 *  found in the file LICENSE in this distribution or at
27 *  http://www.OARcorp.com/rtems/license.html.
28 *
29 *  $Id$
30 */
31
[f817b02]32#include <rtems.h>
[f8b27df9]33
34#include <rtems/score/sh_io.h>
[4a238002]35#include <rtems/score/ispsh7032.h>
36#include <rtems/score/iosh7032.h>
37
38#define I_CLK_PHI_1     0
39#define I_CLK_PHI_2     1
40#define I_CLK_PHI_4     2
41#define I_CLK_PHI_8     3
[f8b27df9]42
43/*
[4a238002]44 * Set I_CLK_PHI to one of the I_CLK_PHI_X values from above to choose
45 * a PHI/X clock rate. 
[f8b27df9]46 */
[4a238002]47   
48#define I_CLK_PHI       I_CLK_PHI_4
49#define CLOCK_SCALE     (1<<I_CLK_PHI)
[f8b27df9]50
51#define ITU1_STARTMASK  0xfd
52#define ITU1_SYNCMASK   0xfd
53#define ITU1_MODEMASK   0xfd
[4a238002]54#define ITU1_TCRMASK    (0x00 | I_CLK_PHI)
[f8b27df9]55#define ITU1_TIORMASK   0x88
56#define ITU1_STAT_MASK  0xf8
57#define ITU1_TIERMASK   0xfc
58#define IPRC_ITU1_MASK  0xfff0
59
60#ifndef ITU1_PRIO
61#define ITU1_PRIO 15
62#endif
63
[4a238002]64#define ITU1_VECTOR OVI1_ISP_V
[f8b27df9]65
66rtems_isr timerisr();
67
68static rtems_unsigned32 Timer_interrupts;
69
70rtems_boolean Timer_driver_Find_average_overhead;
71
[4a238002]72static rtems_unsigned32 Timer_HZ ;
73
[f8b27df9]74void Timer_initialize( void )
75{
[21bfd93]76  rtems_unsigned8  temp8;
[f8b27df9]77  rtems_unsigned16 temp16;
78  rtems_unsigned32 level;
[21bfd93]79  rtems_isr        *ignored;
[f8b27df9]80
[4a238002]81  Timer_HZ = rtems_cpu_configuration_get_clicks_per_second() / CLOCK_SCALE ;
82
[f8b27df9]83  /*
84   *  Timer has never overflowed.  This may not be necessary on some
85   *  implemenations of timer but ....
86   */
87
88  Timer_interrupts /* .i */ = 0;
89  _CPU_ISR_Disable( level);
90
91  /*
92   *  Somehow start the timer
93   */
94  /* stop Timer 1  */
95  temp8 = read8( ITU_TSTR) & ITU1_STARTMASK;
96  write8( temp8, ITU_TSTR);
97
98  /* initialize counter 1 */
99  write16( 0, ITU_TCNT1);
100
101  /* Timer 1 is independent of other timers */
102  temp8 = read8( ITU_TSNC) & ITU1_SYNCMASK;
103  write8( temp8, ITU_TSNC);
104
105  /* Timer 1, normal mode */
106  temp8 = read8( ITU_TMDR) & ITU1_MODEMASK;
107  write8( temp8, ITU_TMDR);
108
[4a238002]109  /* Use a Phi/X counter */
[f8b27df9]110  write8( ITU1_TCRMASK, ITU_TCR1);
111
112  /* gra and grb are not used */
113  write8( ITU1_TIORMASK, ITU_TIOR1);
114
115  /* reset all status flags */
116  temp8 = read8( ITU_TSR1) & ITU1_STAT_MASK;
117  write8( temp8, ITU_TSR1);
118
119  /* enable overflow interrupt */
120  write8( ITU1_TIERMASK, ITU_TIER1);
121
122  /* set interrupt priority */
123  temp16 = read16( INTC_IPRC) & IPRC_ITU1_MASK;
124  temp16 |= ITU1_PRIO;
125  write16( temp16, INTC_IPRC);
126
127  /* initialize ISR */
[21bfd93]128  _CPU_ISR_install_raw_handler( ITU1_VECTOR, timerisr, &ignored );
[f8b27df9]129  _CPU_ISR_Enable( level);
130
131  /* start timer 1 */
132  temp8 = read8( ITU_TSTR) | ~ITU1_STARTMASK;
133  write8( temp8, ITU_TSTR);
134}
135
136/*
137 *  The following controls the behavior of Read_timer().
138 *
139 *  AVG_OVERHEAD is the overhead for starting and stopping the timer.  It
140 *  is usually deducted from the number returned.
141 *
142 *  LEAST_VALID is the lowest number this routine should trust.  Numbers
143 *  below this are "noise" and zero is returned.
144 */
145
146#define AVG_OVERHEAD      1  /* It typically takes X.X microseconds */
147                             /* (Y countdowns) to start/stop the timer. */
148                             /* This value is in microseconds. */
149#define LEAST_VALID       0 /* 20 */ /* Don't trust a clicks value lower than this */
150
151int Read_timer( void )
152{
[4a238002]153  rtems_unsigned32 cclicks;
[f8b27df9]154  rtems_unsigned32 total ;
155  /*
156   *  Read the timer and see how many clicks it has been since we started.
157   */
158 
159
[4a238002]160  cclicks = read16( ITU_TCNT1);   /* XXX: read some HW here */
[f8b27df9]161 
162  /*
163   *  Total is calculated by taking into account the number of timer overflow
164   *  interrupts since the timer was initialized and clicks since the last
165   *  interrupts.
166   */
167
[4a238002]168  total = cclicks + Timer_interrupts * 65536 ;
[f8b27df9]169
170  if ( Timer_driver_Find_average_overhead )
[4a238002]171    return total / CLOCK_SCALE;          /* in XXX microsecond units */
[f8b27df9]172  else
173  {
174    if ( total < LEAST_VALID )
175      return 0;            /* below timer resolution */
176  /*
177   *  Somehow convert total into microseconds
178   */
[4a238002]179    return (total / CLOCK_SCALE - AVG_OVERHEAD) ;
[f8b27df9]180  }
181}
182
183/*
184 *  Empty function call used in loops to measure basic cost of looping
185 *  in Timing Test Suite.
186 */
187
188rtems_status_code Empty_function( void )
189{
190  return RTEMS_SUCCESSFUL;
191}
192
193void Set_find_average_overhead(
194  rtems_boolean find_flag
195)
196{
197  Timer_driver_Find_average_overhead = find_flag;
198}
199
200/* Timer 1 is used */
201
202#pragma interrupt
203void timerisr( void )
204{
205  unsigned8 temp8;
206
207  /* reset the flags of the status register */
208  temp8 = read8( ITU_TSR1) & ITU1_STAT_MASK;
209  write8( temp8, ITU_TSR1);
210
211  Timer_interrupts += 1;
212}
Note: See TracBrowser for help on using the repository browser.