xref: /netbsd-src/sys/arch/usermode/dev/clock.c (revision b5677b36047b601b9addaaa494a58ceae82c2a6c)
1 /* $NetBSD: clock.c,v 1.2 2008/01/07 17:27:12 joerg Exp $ */
2 
3 /*-
4  * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *        This product includes software developed by Jared D. McNeill.
18  * 4. Neither the name of The NetBSD Foundation nor the names of its
19  *    contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include <sys/cdefs.h>
36 __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.2 2008/01/07 17:27:12 joerg Exp $");
37 
38 #include <sys/param.h>
39 #include <sys/proc.h>
40 #include <sys/user.h>
41 #include <sys/systm.h>
42 #include <sys/device.h>
43 #include <sys/timetc.h>
44 
45 #include <machine/mainbus.h>
46 
47 static int	clock_match(device_t, cfdata_t, void *);
48 static void	clock_attach(device_t, device_t, void *);
49 
50 static void 	clock_intr(int);
51 static u_int	clock_getcounter(struct timecounter *);
52 
53 typedef struct clock_softc {
54 	device_t	sc_dev;
55 } clock_softc_t;
56 
57 extern int	setitimer(int, const struct itimerval *, struct itimerval *);
58 
59 static struct timecounter clock_timecounter = {
60 	clock_getcounter,	/* get_timecount */
61 	0,			/* no poll_pps */
62 	~0u,			/* counter_mask */
63 	1000000,		/* frequency */
64 	"gettimeofday",		/* name */
65 	100,			/* quality */
66 	NULL,			/* prev */
67 	NULL,			/* next */
68 };
69 
70 CFATTACH_DECL_NEW(clock, sizeof(clock_softc_t),
71     clock_match, clock_attach, NULL, NULL);
72 
73 static int
74 clock_match(device_t parent, cfdata_t match, void *opaque)
75 {
76 	struct thunkbus_attach_args *taa = opaque;
77 
78 	if (taa->taa_type != THUNKBUS_TYPE_CLOCK)
79 		return 0;
80 
81 	return 1;
82 }
83 
84 static void
85 clock_attach(device_t parent, device_t self, void *opaque)
86 {
87 	clock_softc_t *sc = device_private(self);
88 	struct itimerval itimer;
89 
90 	aprint_naive("\n");
91 	aprint_normal("\n");
92 
93 	sc->sc_dev = self;
94 
95 	(void)signal(SIGALRM, clock_intr);
96 
97 	itimer.it_interval.tv_sec = 0;
98 	itimer.it_interval.tv_usec = 10000;
99 	itimer.it_value = itimer.it_interval;
100 	(void)setitimer(ITIMER_REAL, &itimer, NULL);
101 
102 	tc_init(&clock_timecounter);
103 }
104 
105 static void
106 clock_intr(int notused)
107 {
108 	extern int usermode_x;
109 	struct clockframe cf;
110 
111 #if notyet
112 	/* XXXJDM */
113 	if (usermode_x > IPL_SOFTCLOCK)
114 		return;
115 #endif
116 
117 	hardclock(&cf);
118 }
119 
120 static u_int
121 clock_getcounter(struct timecounter *tc)
122 {
123 	extern int gettimeofday(struct timeval *, void *);
124 	struct timeval tv;
125 
126 	gettimeofday(&tv, NULL);
127 	return tv.tv_sec * 1000000 + tv.tv_usec;
128 }
129