source: rtems/c/src/lib/libbsp/powerpc/score603e/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 Jan 11, 2000 at 5:34:20 PM

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