/* $NetBSD: clock_hb.c,v 1.7 2000/10/05 19:04:59 tsutsui Exp $ */ /*- * Copyright (c) 1996 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Jason R. Thorpe. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the NetBSD * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include /* * interrupt level for clock */ #define CLOCK_LEVEL 6 int clock_hb_match __P((struct device *, struct cfdata *, void *)); void clock_hb_attach __P((struct device *, struct device *, void *)); void clock_hb_initclocks __P((int, int)); void clock_intr __P((struct clockframe *)); static __inline void leds_intr __P((void)); extern void _isr_clock __P((void)); /* locore.s */ struct cfattach clock_hb_ca = { sizeof(struct device), clock_hb_match, clock_hb_attach }; extern volatile u_char *ctrl_timer, *ctrl_led; extern struct cfdriver clock_cd; int clock_hb_match(parent, cf, aux) struct device *parent; struct cfdata *cf; void *aux; { struct hb_attach_args *ha = aux; static int clock_hb_matched; /* Only one clock, please. */ if (clock_hb_matched) return (0); if (strcmp(ha->ha_name, clock_cd.cd_name)) return (0); if (ha->ha_ipl == -1) ha->ha_ipl = CLOCK_LEVEL; ha->ha_size = MK48T02_CLKSZ; clock_hb_matched = 1; return 1; } void clock_hb_attach(parent, self, aux) struct device *parent, *self; void *aux; { struct hb_attach_args *ha = aux; bus_space_tag_t bst = ha->ha_bust; bus_space_handle_t bsh; todr_chip_handle_t handle; extern int delay_divisor; /* from machdep.c */ if (ha->ha_ipl != CLOCK_LEVEL) panic("clock_hb_attach: wrong interrupt level"); if (bus_space_map(bst, (bus_addr_t)ha->ha_address, ha->ha_size, 0, &bsh) != 0) printf("can't map device space\n"); if ((handle = mk48txx_attach(bst, bsh, "mk48t02", 1900)) == NULL) panic("can't attach tod clock"); printf("\n%s: delay_divisor %d\n", self->dv_xname, delay_divisor); handle->bus_cookie = NULL; handle->todr_setwen = NULL; clock_config(handle, clock_hb_initclocks); #if 0 /* XXX this will be done in clock_hb_initclocks() */ isrlink_custom(ha->ha_ipl, (void *)_isr_clock); #endif } /* * Set up the real-time clock (enable clock interrupts). * Leave stathz 0 since there is no secondary clock available. * Note that clock interrupts MUST STAY DISABLED until here. */ void clock_hb_initclocks(tick, statint) int tick, statint; { int s; s = splhigh(); /* Install isr (in locore.s) that calls clock_intr(). */ isrlink_custom(CLOCK_LEVEL, (void *)_isr_clock); /* enable the clock */ *ctrl_timer = 1; splx(s); } /* * Clock interrupt handler for Mostek. * This is is called by the "custom" interrupt handler. * * from sun3/sun3x/clock.c -tsutsui */ void clock_intr(cf) struct clockframe *cf; { #ifdef LED_IDLE_CHECK extern char _Idle[]; /* locore.s */ #endif /* Pulse the clock intr. enable low. */ *ctrl_timer = 0; *ctrl_timer = 1; intrcnt[CLOCK_LEVEL]++; /* Entertainment! */ #ifdef LED_IDLE_CHECK if (cf.cf_pc == (long)_Idle) #endif leds_intr(); /* Call common clock interrupt handler. */ hardclock(cf); uvmexp.intrs++; } /* heartbeat LED */ #define LED0 0x01 #define LED1 0x02 static __inline void leds_intr() { static u_char led_countdown, led_stat; u_char i; if (led_countdown) { led_countdown--; return; } i = led_stat ^ LED0; *ctrl_led = i; led_stat = i; led_countdown = hz; }