]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/powerpc/aim/clock.c
Copy stable/8 to releng/8.2 in preparation for FreeBSD-8.2 release.
[FreeBSD/releng/8.2.git] / sys / powerpc / aim / clock.c
1 /*-
2  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
3  * Copyright (C) 1995, 1996 TooLs GmbH.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *      This product includes software developed by TooLs GmbH.
17  * 4. The name of TooLs GmbH may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  *      $NetBSD: clock.c,v 1.9 2000/01/19 02:52:19 msaitoh Exp $
32  */
33 /*
34  * Copyright (C) 2001 Benno Rice.
35  * All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  *
46  * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
47  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
48  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
49  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
51  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
52  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
53  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
54  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
55  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56  */
57
58 #include <sys/cdefs.h>
59 __FBSDID("$FreeBSD$");
60
61 #include <sys/param.h>
62 #include <sys/systm.h>
63 #include <sys/kernel.h>
64 #include <sys/bus.h>
65 #include <sys/interrupt.h>
66 #include <sys/pcpu.h>
67 #include <sys/sysctl.h>
68 #include <sys/timetc.h>
69
70 #include <dev/ofw/openfirm.h>
71
72 #include <machine/clock.h>
73 #include <machine/cpu.h>
74 #include <machine/md_var.h>
75 #include <machine/smp.h>
76
77 /*
78  * Initially we assume a processor with a bus frequency of 12.5 MHz.
79  */
80 u_long                  ns_per_tick = 80;
81 static u_long           ticks_per_sec = 12500000;
82 static long             ticks_per_intr;
83
84 static timecounter_get_t        decr_get_timecount;
85
86 static struct timecounter       decr_timecounter = {
87         decr_get_timecount,     /* get_timecount */
88         0,                      /* no poll_pps */
89         ~0u,                    /* counter_mask */
90         0,                      /* frequency */
91         "decrementer"           /* name */
92 };
93
94 void
95 decr_intr(struct trapframe *frame)
96 {
97         int32_t         tick, nticks;
98
99         /*
100          * Check whether we are initialized.
101          */
102         if (!ticks_per_intr)
103                 return;
104
105         /*
106          * Based on the actual time delay since the last decrementer reload,
107          * we arrange for earlier interrupt next time.
108          */
109         __asm ("mfdec %0" : "=r"(tick));
110         for (nticks = 0; tick < 0; nticks++)
111                 tick += ticks_per_intr;
112         mtdec(tick);
113
114         while (nticks-- > 0) {
115                 if (PCPU_GET(cpuid) == 0)
116                         hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
117                 else
118                         hardclock_cpu(TRAPF_USERMODE(frame));
119
120                 statclock(TRAPF_USERMODE(frame));
121                 if (profprocs != 0)
122                         profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
123         }
124 }
125
126 void
127 decr_init(void)
128 {
129         struct cpuref cpu;
130         register_t msr;
131
132         /*
133          * Check the BSP's timebase frequency. Sometimes we can't find the BSP, so fall
134          * back to the first CPU in this case.
135          */
136
137         if (platform_smp_get_bsp(&cpu) != 0)
138                 platform_smp_first_cpu(&cpu);
139
140         ticks_per_sec = platform_timebase_freq(&cpu);
141
142         msr = mfmsr();
143         mtmsr(msr & ~PSL_EE);
144
145         ns_per_tick = 1000000000 / ticks_per_sec;
146         ticks_per_intr = ticks_per_sec / hz;
147         mtdec(ticks_per_intr);
148
149         set_cputicker(mftb, ticks_per_sec, 0);
150
151         mtmsr(msr);
152 }
153
154 #ifdef SMP
155 void
156 decr_ap_init(void)
157 {
158
159 }
160 #endif
161
162 void
163 decr_tc_init(void)
164 {
165         decr_timecounter.tc_frequency = ticks_per_sec;
166         tc_init(&decr_timecounter);
167 }
168
169 static unsigned
170 decr_get_timecount(struct timecounter *tc)
171 {
172         register_t tb;
173
174         __asm __volatile("mftb %0" : "=r"(tb));
175         return (tb);
176 }
177
178 /*
179  * Wait for about n microseconds (at least!).
180  */
181 void
182 DELAY(int n)
183 {
184         u_quad_t        tb, ttb;
185
186         tb = mftb();
187         ttb = tb + (n * 1000 + ns_per_tick - 1) / ns_per_tick;
188         while (tb < ttb)
189                 tb = mftb();
190 }
191
192 /*
193  * Nothing to do.
194  */
195 void
196 cpu_startprofclock(void)
197 {
198
199         /* Do nothing */
200 }
201
202 void
203 cpu_stopprofclock(void)
204 {
205 }