source: rtems/c/src/lib/libbsp/powerpc/psim/clock/clock.c @ 0dd1d44

4.104.114.84.95
Last change on this file since 0dd1d44 was 0dd1d44, checked in by Joel Sherrill <joel.sherrill@…>, on 01/11/00 at 17:34:20

Removed old hack of using Configuration Table entry ticks_per_timeslice
being set to 0 to indicate that there should be no Clock Tick. This
was used by the Timing Tests to avoid clock tick overhead perturbing
execution times. Now the Timing Tests simply leave the Clock Tick
Driver out of the Device Driver Table.

  • Property mode set to 100644
File size: 4.7 KB
Line 
1/*
2 *  Clock Tick Device Driver
3 *
4 *  This routine utilizes the Decrementer Register common to the PPC family.
5 *
6 *  The tick frequency is directly programmed to the configured number of
7 *  microseconds per tick.
8 *
9 *  COPYRIGHT (c) 1989-1999.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in found in the file LICENSE in this distribution or at
14 *  http://www.OARcorp.com/rtems/license.html.
15 *
16 *  $Id$
17 */
18
19#include <stdlib.h>
20
21#include <bsp.h>
22#include <rtems/libio.h>
23
24/*
25 *  The Real Time Clock Counter Timer uses this trap type.
26 */
27
28#define CLOCK_VECTOR PPC_IRQ_DECREMENTER
29
30/*
31 *  Clock ticks since initialization
32 */
33
34volatile rtems_unsigned32 Clock_driver_ticks;
35
36/*
37 *  This is the value programmed into the count down timer.  It
38 *  is artificially lowered when PSIM_FAST_IDLE is defined to
39 *  cut down how long we spend in the idle task while executing on
40 *  the simulator.
41 */
42
43extern rtems_unsigned32 CPU_PPC_CLICKS_PER_TICK;
44
45rtems_isr_entry  Old_ticker;
46
47void Clock_exit( void );
48 
49/*
50 * These are set by clock driver during its init
51 */
52 
53rtems_device_major_number rtems_clock_major = ~0;
54rtems_device_minor_number rtems_clock_minor;
55
56/*
57 *  Clock_isr
58 *
59 *  This is the clock tick interrupt handler.
60 *
61 *  Input parameters:
62 *    vector - vector number
63 *
64 *  Output parameters:  NONE
65 *
66 *  Return values:      NONE
67 *
68 */
69
70#define PPC_Set_decrementer( _clicks ) \
71  do { \
72    asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \
73  } while (0)
74
75rtems_isr Clock_isr(
76  rtems_vector_number vector
77)
78{
79  /*
80   *  Whether or not we we are in "fast idle" mode, the value for clicks
81   *  per tick must be programmed.  If we are using "fast idle" mode for
82   *  a simulator, then the clicks per tick value is lowered to decrease
83   *  the amount of time spent executing the idle task while using the
84   *  an instruction simulator like psim.
85   */
86
87
88  PPC_Set_decrementer( CPU_PPC_CLICKS_PER_TICK );
89
90  /*
91   *  The driver has seen another tick.
92   */
93
94  Clock_driver_ticks += 1;
95
96  /*
97   *  Real Time Clock counter/timer is set to automatically reload.
98   */
99
100  rtems_clock_tick();
101}
102
103/*
104 *  Install_clock
105 *
106 *  This routine actually performs the hardware initialization for the clock.
107 *
108 *  Input parameters:
109 *    clock_isr - clock interrupt service routine entry point
110 *
111 *  Output parameters:  NONE
112 *
113 *  Return values:      NONE
114 *
115 */
116
117extern int CLOCK_SPEED;
118
119void Install_clock(
120  rtems_isr_entry clock_isr
121)
122{
123  Clock_driver_ticks = 0;
124
125  Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 );
126
127  PPC_Set_decrementer( CPU_PPC_CLICKS_PER_TICK );
128
129  atexit( Clock_exit );
130}
131
132/*
133 *  Clock_exit
134 *
135 *  This routine allows the clock driver to exit by masking the interrupt and
136 *  disabling the clock's counter.
137 *
138 *  Input parameters:   NONE
139 *
140 *  Output parameters:  NONE
141 *
142 *  Return values:      NONE
143 *
144 */
145
146void Clock_exit( void )
147{
148  /* nothing to do */;
149
150  /* do not restore old vector */
151}
152 
153/*
154 *  Clock_initialize
155 *
156 *  This routine initializes the clock driver.
157 *
158 *  Input parameters:
159 *    major - clock device major number
160 *    minor - clock device minor number
161 *    parg  - pointer to optional device driver arguments
162 *
163 *  Output parameters:  NONE
164 *
165 *  Return values:
166 *    rtems_device_driver status code
167 */
168
169rtems_device_driver Clock_initialize(
170  rtems_device_major_number major,
171  rtems_device_minor_number minor,
172  void *pargp
173)
174{
175  Install_clock( Clock_isr );
176 
177  /*
178   * make major/minor avail to others such as shared memory driver
179   */
180 
181  rtems_clock_major = major;
182  rtems_clock_minor = minor;
183 
184  return RTEMS_SUCCESSFUL;
185}
186 
187/*
188 *  Clock_control
189 *
190 *  This routine is the clock device driver control entry point.
191 *
192 *  Input parameters:
193 *    major - clock device major number
194 *    minor - clock device minor number
195 *    parg  - pointer to optional device driver arguments
196 *
197 *  Output parameters:  NONE
198 *
199 *  Return values:
200 *    rtems_device_driver status code
201 */
202
203rtems_device_driver Clock_control(
204  rtems_device_major_number major,
205  rtems_device_minor_number minor,
206  void *pargp
207)
208{
209    rtems_unsigned32 isrlevel;
210    rtems_libio_ioctl_args_t *args = pargp;
211 
212    if (args == 0)
213        goto done;
214 
215    /*
216     * This is hokey, but until we get a defined interface
217     * to do this, it will just be this simple...
218     */
219 
220    if (args->command == rtems_build_name('I', 'S', 'R', ' '))
221    {
222        Clock_isr(CLOCK_VECTOR);
223    }
224    else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
225    {
226      rtems_interrupt_disable( isrlevel );
227       (void) set_vector( args->buffer, CLOCK_VECTOR, 1 );
228      rtems_interrupt_enable( isrlevel );
229    }
230 
231done:
232    return RTEMS_SUCCESSFUL;
233}
Note: See TracBrowser for help on using the repository browser.