clock.c revision 209639
1127915Skientzle/*-
2265420Simp * Copyright (C) 1995, 1996 Wolfgang Solfrank.
3127915Skientzle * Copyright (C) 1995, 1996 TooLs GmbH.
4319186Sngie * All rights reserved.
5228797Smm *
6127915Skientzle * Redistribution and use in source and binary forms, with or without
7368984Smm * modification, are permitted provided that the following conditions
8368984Smm * are met:
9228797Smm * 1. Redistributions of source code must retain the above copyright
10291620Sbdrewery *    notice, this list of conditions and the following disclaimer.
11203559Skientzle * 2. Redistributions in binary form must reproduce the above copyright
12203559Skientzle *    notice, this list of conditions and the following disclaimer in the
13248616Smm *    documentation and/or other materials provided with the distribution.
14203559Skientzle * 3. All advertising materials mentioning features or use of this software
15203559Skientzle *    must display the following acknowledgement:
16203559Skientzle *	This product includes software developed by TooLs GmbH.
17203559Skientzle * 4. The name of TooLs GmbH may not be used to endorse or promote products
18224153Smm *    derived from this software without specific prior written permission.
19291620Sbdrewery *
20224153Smm * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
21299529Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22299529Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23224153Smm * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24275042Sbapt * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25224566Smm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26232153Smm * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27232153Smm * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28232153Smm * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29232153Smm * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30175051Skientzle *
31319186Sngie *	$NetBSD: clock.c,v 1.9 2000/01/19 02:52:19 msaitoh Exp $
32291620Sbdrewery */
33291620Sbdrewery/*
34137616Sru * Copyright (C) 2001 Benno Rice.
35128446Skientzle * All rights reserved.
36128446Skientzle *
37289195Sngie * Redistribution and use in source and binary forms, with or without
38289195Sngie * modification, are permitted provided that the following conditions
39289195Sngie * are met:
40175051Skientzle * 1. Redistributions of source code must retain the above copyright
41127915Skientzle *    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: head/sys/powerpc/aim/clock.c 209639 2010-07-02 02:17:39Z marcel $");
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 */
80u_long			ns_per_tick = 80;
81static u_long		ticks_per_sec = 12500000;
82static long		ticks_per_intr;
83
84static timecounter_get_t	decr_get_timecount;
85
86static 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
94void
95decr_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
126void
127decr_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
155void
156decr_ap_init(void)
157{
158
159}
160#endif
161
162void
163decr_tc_init(void)
164{
165	decr_timecounter.tc_frequency = ticks_per_sec;
166	tc_init(&decr_timecounter);
167}
168
169static unsigned
170decr_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 */
181void
182DELAY(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 */
195void
196cpu_startprofclock(void)
197{
198
199	/* Do nothing */
200}
201
202void
203cpu_stopprofclock(void)
204{
205}
206