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

4.104.114.84.95
Last change on this file since f05b2ac was f05b2ac, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/21/04 at 16:01:48

Remove duplicate white lines.

  • 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 *  Clock_isr
61 *
62 *  This is the clock tick interrupt handler.
63 *
64 *  Input parameters:
65 *    vector - vector number
66 *
67 *  Output parameters:  NONE
68 *
69 *  Return values:      NONE
70 *
71 */
72rtems_isr Clock_isr(
73  rtems_vector_number  vector,
74  CPU_Interrupt_frame *frame
75)
76{
77  /*
78   *  Set the decrementer.
79   */
80
81  PPC_Set_decrementer( Clock_Decrementer_value );
82
83  /*
84   *  The driver has seen another tick.
85   */
86
87  Clock_driver_ticks += 1;
88
89  /*
90   *  Real Time Clock counter/timer is set to automatically reload.
91   */
92
93  rtems_clock_tick();
94}
95
96/*
97 *  Install_clock
98 *
99 *  This routine actually performs the hardware initialization for the clock.
100 *
101 *  Input parameters:
102 *    clock_isr - clock interrupt service routine entry point
103 *
104 *  Output parameters:  NONE
105 *
106 *  Return values:      NONE
107 *
108 */
109
110extern int CLOCK_SPEED;
111
112void Install_clock(
113  rtems_isr_entry clock_isr
114)
115{
116  Clock_driver_ticks = 0;
117
118  Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 );
119
120  PPC_Set_decrementer( Clock_Decrementer_value );
121
122  atexit( Clock_exit );
123}
124
125/*
126 *  Clock_exit
127 *
128 *  This routine allows the clock driver to exit by masking the interrupt and
129 *  disabling the clock's counter.
130 *
131 *  Input parameters:   NONE
132 *
133 *  Output parameters:  NONE
134 *
135 *  Return values:      NONE
136 *
137 */
138
139void Clock_exit( void )
140{
141  /* nothing to do */;
142
143  /* do not restore old vector */
144}
145
146/*
147 *  Clock_initialize
148 *
149 *  This routine initializes the clock driver.
150 *
151 *  Input parameters:
152 *    major - clock device major number
153 *    minor - clock device minor number
154 *    parg  - pointer to optional device driver arguments
155 *
156 *  Output parameters:  NONE
157 *
158 *  Return values:
159 *    rtems_device_driver status code
160 */
161
162rtems_device_driver Clock_initialize(
163  rtems_device_major_number major,
164  rtems_device_minor_number minor,
165  void *pargp
166)
167{
168  Clock_Decrementer_value = (int) &CPU_PPC_CLICKS_PER_MS *
169                       (BSP_Configuration.microseconds_per_tick / 1000);
170
171  Install_clock( (rtems_isr_entry) Clock_isr );
172
173  /*
174   * make major/minor avail to others such as shared memory driver
175   */
176
177  rtems_clock_major = major;
178  rtems_clock_minor = minor;
179
180  return RTEMS_SUCCESSFUL;
181}
182
183/*
184 *  Clock_control
185 *
186 *  This routine is the clock device driver control entry point.
187 *
188 *  Input parameters:
189 *    major - clock device major number
190 *    minor - clock device minor number
191 *    parg  - pointer to optional device driver arguments
192 *
193 *  Output parameters:  NONE
194 *
195 *  Return values:
196 *    rtems_device_driver status code
197 */
198
199rtems_device_driver Clock_control(
200  rtems_device_major_number major,
201  rtems_device_minor_number minor,
202  void *pargp
203)
204{
205    uint32_t         isrlevel;
206    rtems_libio_ioctl_args_t *args = pargp;
207
208    if (args == 0)
209        goto done;
210
211    /*
212     * This is hokey, but until we get a defined interface
213     * to do this, it will just be this simple...
214     */
215
216    if (args->command == rtems_build_name('I', 'S', 'R', ' '))
217    {
218        Clock_isr( CLOCK_VECTOR, pargp );
219    }
220    else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
221    {
222      rtems_interrupt_disable( isrlevel );
223       (void) set_vector( args->buffer, CLOCK_VECTOR, 1 );
224      rtems_interrupt_enable( isrlevel );
225    }
226
227done:
228    return RTEMS_SUCCESSFUL;
229}
Note: See TracBrowser for help on using the repository browser.