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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [powerpc/] [score603e/] [clock/] [clock.c] - Blame information for rev 30

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
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
 *  Copyright assigned to U.S. Government, 1994.
12
 *
13
 *  The license and distribution terms for this file may in
14
 *  the file LICENSE in this distribution or at
15
 *  http://www.OARcorp.com/rtems/license.html.
16
 *
17
 *  $Id: clock.c,v 1.2 2001-09-27 12:01:03 chris Exp $
18
 */
19
 
20
#include <stdlib.h>
21
 
22
#include <bsp.h>
23
#include <rtems/libio.h>
24
#include <assert.h>
25
 
26
/*
27
 *  The Real Time Clock Counter Timer uses this trap type.
28
 */
29
 
30
#define CLOCK_VECTOR PPC_IRQ_DECREMENTER
31
 
32
/*
33
 *  Clock ticks since initialization
34
 */
35
 
36
volatile rtems_unsigned32 Clock_driver_ticks;
37
 
38
/*
39
 *  This is the value programmed into the count down timer.
40
 */
41
 
42
rtems_unsigned32 Clock_Decrementer_value;
43
 
44
rtems_isr_entry  Old_ticker;
45
 
46
void Clock_exit( void );
47
 
48
/*
49
 * These are set by clock driver during its init
50
 */
51
 
52
rtems_device_major_number rtems_clock_major = ~0;
53
rtems_device_minor_number rtems_clock_minor;
54
 
55
#define PPC_Set_decrementer( _clicks ) \
56
  do { \
57
    asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \
58
  } while (0)
59
 
60
 
61
/*
62
 *  Clock_isr
63
 *
64
 *  This is the clock tick interrupt handler.
65
 *
66
 *  Input parameters:
67
 *    vector - vector number
68
 *
69
 *  Output parameters:  NONE
70
 *
71
 *  Return values:      NONE
72
 *
73
 */
74
rtems_isr Clock_isr(
75
  rtems_vector_number  vector,
76
  CPU_Interrupt_frame *frame
77
)
78
{
79
  /*
80
   *  Set the decrementer.
81
   */
82
 
83
  PPC_Set_decrementer( Clock_Decrementer_value );
84
 
85
  /*
86
   *  The driver has seen another tick.
87
   */
88
 
89
  Clock_driver_ticks += 1;
90
 
91
  /*
92
   *  Real Time Clock counter/timer is set to automatically reload.
93
   */
94
 
95
  rtems_clock_tick();
96
}
97
 
98
/*
99
 *  Install_clock
100
 *
101
 *  This routine actually performs the hardware initialization for the clock.
102
 *
103
 *  Input parameters:
104
 *    clock_isr - clock interrupt service routine entry point
105
 *
106
 *  Output parameters:  NONE
107
 *
108
 *  Return values:      NONE
109
 *
110
 */
111
 
112
extern int CLOCK_SPEED;
113
 
114
void Install_clock(
115
  rtems_isr_entry clock_isr
116
)
117
{
118
  Clock_driver_ticks = 0;
119
 
120
  Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 );
121
 
122
  PPC_Set_decrementer( Clock_Decrementer_value );
123
 
124
  atexit( Clock_exit );
125
}
126
 
127
/*
128
 *  Clock_exit
129
 *
130
 *  This routine allows the clock driver to exit by masking the interrupt and
131
 *  disabling the clock's counter.
132
 *
133
 *  Input parameters:   NONE
134
 *
135
 *  Output parameters:  NONE
136
 *
137
 *  Return values:      NONE
138
 *
139
 */
140
 
141
void Clock_exit( void )
142
{
143
  /* nothing to do */;
144
 
145
  /* do not restore old vector */
146
}
147
 
148
/*
149
 *  Clock_initialize
150
 *
151
 *  This routine initializes the clock driver.
152
 *
153
 *  Input parameters:
154
 *    major - clock device major number
155
 *    minor - clock device minor number
156
 *    parg  - pointer to optional device driver arguments
157
 *
158
 *  Output parameters:  NONE
159
 *
160
 *  Return values:
161
 *    rtems_device_driver status code
162
 */
163
 
164
rtems_device_driver Clock_initialize(
165
  rtems_device_major_number major,
166
  rtems_device_minor_number minor,
167
  void *pargp
168
)
169
{
170
  Clock_Decrementer_value = (int) &CPU_PPC_CLICKS_PER_MS *
171
                       (BSP_Configuration.microseconds_per_tick / 1000);
172
 
173
  Install_clock( (rtems_isr_entry) Clock_isr );
174
 
175
  /*
176
   * make major/minor avail to others such as shared memory driver
177
   */
178
 
179
  rtems_clock_major = major;
180
  rtems_clock_minor = minor;
181
 
182
  return RTEMS_SUCCESSFUL;
183
}
184
 
185
/*
186
 *  Clock_control
187
 *
188
 *  This routine is the clock device driver control entry point.
189
 *
190
 *  Input parameters:
191
 *    major - clock device major number
192
 *    minor - clock device minor number
193
 *    parg  - pointer to optional device driver arguments
194
 *
195
 *  Output parameters:  NONE
196
 *
197
 *  Return values:
198
 *    rtems_device_driver status code
199
 */
200
 
201
rtems_device_driver Clock_control(
202
  rtems_device_major_number major,
203
  rtems_device_minor_number minor,
204
  void *pargp
205
)
206
{
207
    rtems_unsigned32 isrlevel;
208
    rtems_libio_ioctl_args_t *args = pargp;
209
 
210
    if (args == 0)
211
        goto done;
212
 
213
    /*
214
     * This is hokey, but until we get a defined interface
215
     * to do this, it will just be this simple...
216
     */
217
 
218
    if (args->command == rtems_build_name('I', 'S', 'R', ' '))
219
    {
220
        Clock_isr( CLOCK_VECTOR, pargp );
221
    }
222
    else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
223
    {
224
      rtems_interrupt_disable( isrlevel );
225
       (void) set_vector( args->buffer, CLOCK_VECTOR, 1 );
226
      rtems_interrupt_enable( isrlevel );
227
    }
228
 
229
done:
230
    return RTEMS_SUCCESSFUL;
231
}
232
 
233
 
234
 
235
 
236
 

powered by: WebSVN 2.1.0

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