source: rtems/c/src/lib/libbsp/powerpc/psim/clock/clock.c @ 08311cc3

4.104.114.84.95
Last change on this file since 08311cc3 was 08311cc3, checked in by Joel Sherrill <joel.sherrill@…>, on 11/17/99 at 17:51:34

Updated copyright notice.

  • Property mode set to 100644
File size: 4.8 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  if ( BSP_Configuration.ticks_per_timeslice ) {
126    Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 );
127
128    PPC_Set_decrementer( CPU_PPC_CLICKS_PER_TICK );
129
130    atexit( Clock_exit );
131  }
132
133}
134
135/*
136 *  Clock_exit
137 *
138 *  This routine allows the clock driver to exit by masking the interrupt and
139 *  disabling the clock's counter.
140 *
141 *  Input parameters:   NONE
142 *
143 *  Output parameters:  NONE
144 *
145 *  Return values:      NONE
146 *
147 */
148
149void Clock_exit( void )
150{
151  if ( BSP_Configuration.ticks_per_timeslice ) {
152
153    /* nothing to do */;
154
155    /* do not restore old vector */
156  }
157}
158 
159/*
160 *  Clock_initialize
161 *
162 *  This routine initializes the clock driver.
163 *
164 *  Input parameters:
165 *    major - clock device major number
166 *    minor - clock device minor number
167 *    parg  - pointer to optional device driver arguments
168 *
169 *  Output parameters:  NONE
170 *
171 *  Return values:
172 *    rtems_device_driver status code
173 */
174
175rtems_device_driver Clock_initialize(
176  rtems_device_major_number major,
177  rtems_device_minor_number minor,
178  void *pargp
179)
180{
181  Install_clock( Clock_isr );
182 
183  /*
184   * make major/minor avail to others such as shared memory driver
185   */
186 
187  rtems_clock_major = major;
188  rtems_clock_minor = minor;
189 
190  return RTEMS_SUCCESSFUL;
191}
192 
193/*
194 *  Clock_control
195 *
196 *  This routine is the clock device driver control entry point.
197 *
198 *  Input parameters:
199 *    major - clock device major number
200 *    minor - clock device minor number
201 *    parg  - pointer to optional device driver arguments
202 *
203 *  Output parameters:  NONE
204 *
205 *  Return values:
206 *    rtems_device_driver status code
207 */
208
209rtems_device_driver Clock_control(
210  rtems_device_major_number major,
211  rtems_device_minor_number minor,
212  void *pargp
213)
214{
215    rtems_unsigned32 isrlevel;
216    rtems_libio_ioctl_args_t *args = pargp;
217 
218    if (args == 0)
219        goto done;
220 
221    /*
222     * This is hokey, but until we get a defined interface
223     * to do this, it will just be this simple...
224     */
225 
226    if (args->command == rtems_build_name('I', 'S', 'R', ' '))
227    {
228        Clock_isr(CLOCK_VECTOR);
229    }
230    else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
231    {
232      rtems_interrupt_disable( isrlevel );
233       (void) set_vector( args->buffer, CLOCK_VECTOR, 1 );
234      rtems_interrupt_enable( isrlevel );
235    }
236 
237done:
238    return RTEMS_SUCCESSFUL;
239}
Note: See TracBrowser for help on using the repository browser.