source: rtems/c/src/lib/libbsp/sparc/erc32/clock/ckinit.c @ f7fa7d7

4.104.114.84.95
Last change on this file since f7fa7d7 was 98e4ebf5, checked in by Joel Sherrill <joel.sherrill@…>, on 10/08/97 at 15:45:54

Fixed typo in the pointer to the license terms.

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