OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [c/] [src/] [lib/] [libbsp/] [sparc/] [erc32/] [clock/] [ckinit.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
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
 *  ckinit.c,v 1.6 2000/01/11 17:34:20 joel Exp
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
 
42
volatile 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
 
51
extern rtems_unsigned32 CPU_SPARC_CLICKS_PER_TICK;
52
 
53
rtems_isr_entry  Old_ticker;
54
 
55
void Clock_exit( void );
56
 
57
/*
58
 * These are set by clock driver during its init
59
 */
60
 
61
rtems_device_major_number rtems_clock_major = ~0;
62
rtems_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
 
78
rtems_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
 
123
extern int CLOCK_SPEED;
124
 
125
void 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
 
165
void 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
 
192
rtems_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
 
226
rtems_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
 
254
done:
255
    return RTEMS_SUCCESSFUL;
256
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.