1 /* $OpenBSD: clock.c,v 1.19 2023/09/17 14:50:51 cheloha Exp $ */
2 /* $NetBSD: clock.c,v 1.2 2000/01/11 10:29:35 nisimura Exp $ */
3
4 /*
5 * Copyright (c) 1988 University of Utah.
6 * Copyright (c) 1992, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * This code is derived from software contributed to Berkeley by
10 * the Systems Programming Group of the University of Utah Computer
11 * Science Department and Ralph Campbell.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgement:
23 * This product includes software developed by the University of
24 * California, Berkeley and its contributors.
25 * 4. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * SUCH DAMAGE.
40 *
41 * from: Utah Hdr: clock.c 1.18 91/01/21
42 *
43 * @(#)clock.c 8.1 (Berkeley) 6/10/93
44 */
45
46 /* from NetBSD/luna68k sys/arch/luna68k/luna68k/clock.c */
47
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/clockintr.h>
51 #include <sys/device.h>
52 #include <sys/kernel.h>
53 #include <sys/evcount.h>
54 #include <sys/timetc.h>
55
56 #include <machine/board.h>
57 #include <machine/cpu.h>
58
59 #include <dev/clock_subr.h>
60 #include <luna88k/luna88k/clockvar.h>
61
62 struct device *clockdev;
63 const struct clockfns *clockfns;
64 struct evcount *clockevc;
65 int clockinitted;
66
67 extern todr_chip_handle_t todr_handle;
68 struct todr_chip_handle rtc_todr;
69
70 int
rtc_gettime(struct todr_chip_handle * handle,struct timeval * tv)71 rtc_gettime(struct todr_chip_handle *handle, struct timeval *tv)
72 {
73 struct clock_ymdhms dt;
74
75 (*clockfns->cf_get)(clockdev, tv->tv_sec, &dt);
76 tv->tv_sec = clock_ymdhms_to_secs(&dt);
77 tv->tv_usec = 0;
78 return 0;
79 }
80
81 int
rtc_settime(struct todr_chip_handle * handle,struct timeval * tv)82 rtc_settime(struct todr_chip_handle *handle, struct timeval *tv)
83 {
84 struct clock_ymdhms dt;
85
86 clock_secs_to_ymdhms(tv->tv_sec, &dt);
87 (*clockfns->cf_set)(clockdev, &dt);
88 return 0;
89 }
90
91 void
clockattach(struct device * dev,const struct clockfns * fns,struct evcount * evc)92 clockattach(struct device *dev, const struct clockfns *fns,
93 struct evcount *evc)
94 {
95 /*
96 * Just bookkeeping.
97 */
98 if (clockfns != NULL)
99 panic("clockattach: multiple clocks");
100 clockdev = dev;
101 clockfns = fns;
102 clockevc = evc;
103 }
104
105 /*
106 * Machine-dependent clock routines.
107 */
108
109 u_int clock_get_tc(struct timecounter *);
110
111 struct timecounter clock_tc = {
112 .tc_get_timecount = clock_get_tc,
113 .tc_counter_mask = 0xffffffff,
114 .tc_frequency = 0, /* will be filled in */
115 .tc_name = "clock",
116 .tc_quality = 0,
117 .tc_priv = NULL,
118 .tc_user = 0,
119 };
120
121 /*
122 * Start the real-time and statistics clocks.
123 */
124 void
cpu_initclocks()125 cpu_initclocks()
126 {
127
128 #ifdef DIAGNOSTIC
129 if (clockfns == NULL)
130 panic("cpu_initclocks: no clock attached");
131 #endif
132
133 tick = 1000000 / hz; /* number of microseconds between interrupts */
134 tick_nsec = 1000000000 / hz;
135
136 clock_tc.tc_frequency = hz;
137 tc_init(&clock_tc);
138
139 stathz = hz;
140 profhz = stathz;
141 }
142
143 void
cpu_startclock(void)144 cpu_startclock(void)
145 {
146 clockintr_cpu_init(NULL);
147
148 clockinitted = 1;
149
150 rtc_todr.todr_gettime = rtc_gettime;
151 rtc_todr.todr_settime = rtc_settime;
152 todr_handle = &rtc_todr;
153 }
154
155 void
setstatclockrate(int newhz)156 setstatclockrate(int newhz)
157 {
158 }
159
160 /*
161 * Clock interrupt routine
162 */
163 int
clockintr(void * eframe)164 clockintr(void *eframe)
165 {
166 struct cpu_info *ci = curcpu();
167
168 #ifdef MULTIPROCESSOR
169 if (CPU_IS_PRIMARY(ci))
170 #endif
171 clockevc->ec_count++;
172
173 *(volatile uint32_t *)(ci->ci_clock_ack) = ~0;
174 if (clockinitted)
175 clockintr_dispatch(eframe);
176 return 1;
177 }
178
179 u_int
clock_get_tc(struct timecounter * tc)180 clock_get_tc(struct timecounter *tc)
181 {
182 return (u_int)clockevc->ec_count;
183 }
184