1 /* $NetBSD: timer_sun4.c,v 1.17 2010/01/04 03:54:42 mrg Exp $ */ 2 3 /* 4 * Copyright (c) 1992, 1993 5 * The Regents of the University of California. All rights reserved. 6 * Copyright (c) 1994 Gordon W. Ross 7 * Copyright (c) 1993 Adam Glass 8 * Copyright (c) 1996 Paul Kranenburg 9 * Copyright (c) 1996 10 * The President and Fellows of Harvard College. All rights reserved. 11 * 12 * This software was developed by the Computer Systems Engineering group 13 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 14 * contributed to Berkeley. 15 * 16 * All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Harvard University. 19 * This product includes software developed by the University of 20 * California, Lawrence Berkeley Laboratory. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 26 * 1. Redistributions of source code must retain the above copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * This product includes software developed by the University of 34 * California, Berkeley and its contributors. 35 * This product includes software developed by Paul Kranenburg. 36 * This product includes software developed by Harvard University. 37 * 4. Neither the name of the University nor the names of its contributors 38 * may be used to endorse or promote products derived from this software 39 * without specific prior written permission. 40 * 41 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * @(#)clock.c 8.1 (Berkeley) 6/11/93 54 */ 55 56 /* 57 * Sun4/Sun4c timer support. 58 */ 59 60 #include <sys/cdefs.h> 61 __KERNEL_RCSID(0, "$NetBSD: timer_sun4.c,v 1.17 2010/01/04 03:54:42 mrg Exp $"); 62 63 #include <sys/param.h> 64 #include <sys/kernel.h> 65 #include <sys/device.h> 66 #include <sys/systm.h> 67 68 #include <machine/autoconf.h> 69 #include <machine/bus.h> 70 71 #include <sparc/sparc/vaddrs.h> 72 #include <sparc/sparc/timerreg.h> 73 #include <sparc/sparc/timervar.h> 74 75 #define timerreg4 ((struct timerreg_4 *)TIMERREG_VA) 76 77 /* 78 * Set up the real-time and statistics clocks. 79 * Leave stathz 0 only if no alternative timer is available. 80 * 81 * The frequencies of these clocks must be an even number of microseconds. 82 */ 83 void 84 timer_init_4(void) 85 { 86 87 timerreg4->t_c10.t_limit = tmr_ustolim(tick); 88 timerreg4->t_c14.t_limit = tmr_ustolim(statint); 89 ienab_bis(IE_L14 | IE_L10); 90 } 91 92 /* 93 * Level 10 (clock) interrupts from system counter. 94 */ 95 int 96 clockintr_4(void *cap) 97 { 98 99 /* read the limit register to clear the interrupt */ 100 *((volatile int *)&timerreg4->t_c10.t_limit); 101 tickle_tc(); 102 hardclock((struct clockframe *)cap); 103 return (1); 104 } 105 106 /* 107 * Level 14 (stat clock) interrupts from processor counter. 108 */ 109 int 110 statintr_4(void *cap) 111 { 112 struct clockframe *frame = cap; 113 u_long newint; 114 115 /* read the limit register to clear the interrupt */ 116 *((volatile int *)&timerreg4->t_c14.t_limit); 117 118 statclock(frame); 119 120 /* 121 * Compute new randomized interval. 122 */ 123 newint = new_interval(); 124 125 /* 126 * The sun4/4c timer has no `non-resetting' register; 127 * use the current counter value to compensate the new 128 * limit value for the number of counter ticks elapsed. 129 */ 130 newint -= tmr_cnttous(timerreg4->t_c14.t_counter); 131 timerreg4->t_c14.t_limit = tmr_ustolim(newint); 132 133 /* 134 * The factor 8 is only valid for stathz==100. 135 * See also clock.c 136 */ 137 if ((++cpuinfo.ci_schedstate.spc_schedticks & 7) == 0) { 138 if (CLKF_LOPRI(frame, IPL_SCHED)) { 139 /* No need to schedule a soft interrupt */ 140 spllowerschedclock(); 141 schedintr(cap); 142 } else { 143 /* 144 * We're interrupting a thread that may have the 145 * scheduler lock; run schedintr() later. 146 */ 147 sparc_softintr_schedule(sched_cookie); 148 } 149 } 150 151 return (1); 152 } 153 154 #if defined(SUN4) 155 void 156 timerattach_obio_4(struct device *parent, struct device *self, void *aux) 157 { 158 union obio_attach_args *uoba = aux; 159 struct obio4_attach_args *oba = &uoba->uoba_oba4; 160 bus_space_handle_t bh; 161 162 if (bus_space_map2(oba->oba_bustag, 163 oba->oba_paddr, 164 sizeof(struct timerreg_4), 165 BUS_SPACE_MAP_LINEAR, 166 TIMERREG_VA, 167 &bh) != 0) { 168 printf(": can't map registers\n"); 169 return; 170 } 171 172 timerattach(&timerreg4->t_c10.t_counter, &timerreg4->t_c10.t_limit); 173 } 174 #endif /* SUN4 */ 175 176 #if defined(SUN4C) 177 void 178 timerattach_mainbus_4c(struct device *parent, struct device *self, void *aux) 179 { 180 struct mainbus_attach_args *ma = aux; 181 bus_space_handle_t bh; 182 183 /* 184 * This time we ignore any existing virtual address because 185 * we have a fixed virtual address for the timer, to make 186 * microtime() faster. 187 */ 188 if (bus_space_map2(ma->ma_bustag, 189 ma->ma_paddr, 190 sizeof(struct timerreg_4), 191 BUS_SPACE_MAP_LINEAR, 192 TIMERREG_VA, &bh) != 0) { 193 printf(": can't map registers\n"); 194 return; 195 } 196 197 timerattach(&timerreg4->t_c10.t_counter, &timerreg4->t_c10.t_limit); 198 } 199 #endif /* SUN4C */ 200