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

Subversion Repositories or1k

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

powered by: WebSVN 2.1.0

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