source: rtems/c/src/lib/libbsp/powerpc/score603e/clock/clock.c @ 6128a4a

4.104.114.84.95
Last change on this file since 6128a4a was 6128a4a, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/21/04 at 10:43:04

Remove stray white spaces.

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