source: rtems/c/src/lib/libcpu/powerpc/ppc403/clock/clock.c @ 3a4ae6c

4.104.114.84.95
Last change on this file since 3a4ae6c was 3a4ae6c, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 11, 1995 at 7:35:39 PM

The word "RTEMS" almost completely removed from the core.

Configuration Table Template file added and all tests
modified to use this. All gvar.h and conftbl.h files
removed from test directories.

Configuration parameter maximum_devices added.

Core semaphore and mutex handlers added and RTEMS API Semaphore
Manager updated to reflect this.

Initialization sequence changed to invoke API specific initialization
routines. Initialization tasks table now owned by RTEMS Tasks Manager.

Added user extension for post-switch.

Utilized user extensions to implement API specific functionality
like signal dispatching.

Added extensions to the System Initialization Thread so that an
API can register a function to be invoked while the system
is being initialized. These are largely equivalent to the
pre-driver and post-driver hooks.

Added the Modules file oar-go32_p5, modified oar-go32, and modified
the file make/custom/go32.cfg to look at an environment varable which
determines what CPU model is being used.

All BSPs updated to reflect named devices and clock driver's IOCTL
used by the Shared Memory Driver. Also merged clock isr into
main file and removed ckisr.c where possible.

Updated spsize to reflect new and moved variables.

Makefiles for the executive source and include files updated to show
break down of files into Core, RTEMS API, and Neither.

Header and inline files installed into subdirectory based on whether
logically in the Core or a part of the RTEMS API.

  • Property mode set to 100644
File size: 6.5 KB
Line 
1/*  clock.c
2 *
3 *  This routine initializes the interval timer on the
4 *  PowerPC 403 CPU.  The tick frequency is specified by the bsp.
5 *
6 *  Author:     Andrew Bray <andy@i-cubed.demon.co.uk>
7 *
8 *  COPYRIGHT (c) 1995 by i-cubed ltd.
9 *
10 *  To anyone who acknowledges that this file is provided "AS IS"
11 *  without any express or implied warranty:
12 *      permission to use, copy, modify, and distribute this file
13 *      for any purpose is hereby granted without fee, provided that
14 *      the above copyright notice and this notice appears in all
15 *      copies, and that the name of i-cubed limited not be used in
16 *      advertising or publicity pertaining to distribution of the
17 *      software without specific, written prior permission.
18 *      i-cubed limited makes no representations about the suitability
19 *      of this software for any purpose.
20 *
21 *  Derived from c/src/lib/libcpu/hppa1_1/clock/clock.c:
22 *
23 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
24 *  On-Line Applications Research Corporation (OAR).
25 *  All rights assigned to U.S. Government, 1994.
26 *
27 *  This material may be reproduced by or for the U.S. Government pursuant
28 *  to the copyright license under the clause at DFARS 252.227-7013.  This
29 *  notice must appear in all copies of this file and its derivatives.
30 *
31 *  clock.c,v 1.2 1995/05/31 16:59:06 joel Exp
32 */
33
34#include <bsp.h>
35#include <clockdrv.h>
36#include <rtems/libio.h>
37
38#include <stdlib.h>                     /* for atexit() */
39
40extern rtems_cpu_table           Cpu_table;             /* owned by BSP */
41
42volatile rtems_unsigned32 Clock_driver_ticks;
43static rtems_unsigned32 pit_value, tick_time;
44static rtems_boolean auto_restart;
45
46void Clock_exit( void );
47 
48/*
49 * These are set by clock driver during its init
50 */
51 
52rtems_device_major_number rtems_clock_major = ~0;
53rtems_device_minor_number rtems_clock_minor;
54 
55static INLINE rtems_unsigned32 get_itimer(void)
56{
57    register rtems_unsigned32 rc;
58
59    asm volatile ("mftblo %0" : "=r" ((rc)));
60
61    return rc;
62}
63
64/*
65 *  ISR Handler
66 */
67 
68rtems_isr
69Clock_isr(rtems_vector_number vector)
70{
71    if (!auto_restart)
72        {
73            rtems_unsigned32 clicks_til_next_interrupt;
74            rtems_unsigned32 itimer_value;
75
76            /*
77             * setup for next interrupt; making sure the new value is reasonably
78             * in the future.... in case we lost out on an interrupt somehow
79             */
80
81            itimer_value = get_itimer();
82            tick_time += pit_value;
83
84            /*
85             * how far away is next interrupt *really*
86             * It may be a long time; this subtraction works even if
87             * Clock_clicks_interrupt < Clock_clicks_low_order via
88             * the miracle of unsigned math.
89             */
90            clicks_til_next_interrupt = tick_time - itimer_value;
91
92            /*
93             * If it is too soon then bump it up.
94             * This should only happen if CPU_HPPA_CLICKS_PER_TICK is too small.
95             * But setting it low is useful for debug, so...
96             */
97
98            if (clicks_til_next_interrupt < 400)
99                {
100                    tick_time = itimer_value + 1000;
101                    clicks_til_next_interrupt = 1000;
102                    /* XXX: count these! this should be rare */
103                }
104
105            /*
106             * If it is too late, that means we missed the interrupt somehow.
107             * Rather than wait 35-50s for a wrap, we just fudge it here.
108             */
109           
110            if (clicks_til_next_interrupt > pit_value)
111                {
112                    tick_time = itimer_value + 1000;
113                    clicks_til_next_interrupt = 1000;
114                    /* XXX: count these! this should never happen :-) */
115                }
116
117            asm volatile ("mtpit %0" :: "r" (clicks_til_next_interrupt));
118        }
119
120    asm volatile ( "mttsr %0" :: "r" (0x08000000));
121
122    Clock_driver_ticks++;
123
124    rtems_clock_tick();
125}
126
127void Install_clock(rtems_isr_entry clock_isr)
128{
129    rtems_isr_entry previous_isr;
130    rtems_unsigned32 pvr, iocr;
131
132    Clock_driver_ticks = 0;
133
134    asm volatile ("mfiocr %0" : "=r" (iocr));
135    iocr &= ~4;
136    iocr |= 4;  /* Select external timer clock */
137    asm volatile ("mtiocr %0" : "=r" (iocr) : "0" (iocr));
138
139    asm volatile ("mfpvr %0" : "=r" ((pvr)));
140
141    if (((pvr & 0xffff0000) >> 16) != 0x0020)
142        return; /* Not a ppc403 */
143
144    if ((pvr & 0xff00) == 0x0000) /* 403GA */
145        auto_restart = (pvr & 0x00f0) > 0x0000 ? 1 : 0;
146    else if ((pvr & 0xff00) == 0x0100) /* 403GB */
147        auto_restart = 1;
148
149    pit_value = BSP_Configuration.microseconds_per_tick *
150        Cpu_table.clicks_per_usec;
151
152    if (BSP_Configuration.ticks_per_timeslice)
153    {
154        register rtems_unsigned32 tcr;
155        /*
156         * initialize the interval here
157         * First tick is set to right amount of time in the future
158         * Future ticks will be incremented over last value set
159         * in order to provide consistent clicks in the face of
160         * interrupt overhead
161         */
162
163        rtems_interrupt_catch(clock_isr, PPC_IRQ_PIT,
164                              &previous_isr);
165
166        asm volatile ("mtpit %0" : : "r" (pit_value));
167
168        asm volatile ("mftcr %0" : "=r" ((tcr)));
169
170        tcr &= ~ 0x04400000;
171
172        tcr |= (auto_restart ? 0x04400000 : 0x04000000);
173
174        tick_time = get_itimer() + pit_value;
175
176        asm volatile ("mttcr %0" : "=r" ((tcr)) : "0" ((tcr)));
177    }
178    atexit(Clock_exit);
179}
180
181void
182ReInstall_clock(rtems_isr_entry new_clock_isr)
183{
184    rtems_isr_entry previous_isr;
185    rtems_unsigned32 isrlevel = 0;
186
187    rtems_interrupt_disable(isrlevel);
188   
189    rtems_interrupt_catch(new_clock_isr, PPC_IRQ_PIT,
190                          &previous_isr);
191
192    rtems_interrupt_enable(isrlevel);
193}
194
195
196/*
197 * Called via atexit()
198 * Remove the clock interrupt handler by setting handler to NULL
199 */
200
201void
202Clock_exit(void)
203{
204    if ( BSP_Configuration.ticks_per_timeslice )
205    {
206        register rtems_unsigned32 tcr;
207
208        asm volatile ("mftcr %0" : "=r" ((tcr)));
209
210        tcr &= ~ 0x04400000;
211
212        asm volatile ("mttcr %0" : "=r" ((tcr)) : "0" ((tcr)));
213
214        (void) set_vector(0, PPC_IRQ_PIT, 1);
215    }
216}
217
218rtems_device_driver Clock_initialize(
219  rtems_device_major_number major,
220  rtems_device_minor_number minor,
221  void *pargp
222)
223{
224  Install_clock( Clock_isr );
225 
226  /*
227   * make major/minor avail to others such as shared memory driver
228   */
229 
230  rtems_clock_major = major;
231  rtems_clock_minor = minor;
232 
233  return RTEMS_SUCCESSFUL;
234}
235 
236rtems_device_driver Clock_control(
237  rtems_device_major_number major,
238  rtems_device_minor_number minor,
239  void *pargp
240)
241{
242    rtems_libio_ioctl_args_t *args = pargp;
243 
244    if (args == 0)
245        goto done;
246 
247    /*
248     * This is hokey, but until we get a defined interface
249     * to do this, it will just be this simple...
250     */
251 
252    if (args->command == rtems_build_name('I', 'S', 'R', ' '))
253    {
254        Clock_isr(PPC_IRQ_PIT);
255    }
256    else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
257    {
258        ReInstall_clock(args->buffer);
259    }
260 
261done:
262    return RTEMS_SUCCESSFUL;
263}
264
Note: See TracBrowser for help on using the repository browser.