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

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