Home | History | Annotate | Line # | Download | only in dev
int.c revision 1.10
      1  1.10  tsutsui /*	$NetBSD: int.c,v 1.10 2005/10/18 11:31:12 tsutsui Exp $	*/
      2   1.1   sekiya 
      3   1.1   sekiya /*
      4   1.1   sekiya  * Copyright (c) 2004 Christopher SEKIYA
      5   1.1   sekiya  * All rights reserved.
      6   1.1   sekiya  *
      7   1.1   sekiya  * Redistribution and use in source and binary forms, with or without
      8   1.1   sekiya  * modification, are permitted provided that the following conditions
      9   1.1   sekiya  * are met:
     10   1.1   sekiya  * 1. Redistributions of source code must retain the above copyright
     11   1.1   sekiya  *    notice, this list of conditions and the following disclaimer.
     12   1.1   sekiya  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.1   sekiya  *    notice, this list of conditions and the following disclaimer in the
     14   1.1   sekiya  *    documentation and/or other materials provided with the distribution.
     15   1.1   sekiya  * 3. The name of the author may not be used to endorse or promote products
     16   1.1   sekiya  *    derived from this software without specific prior written permission.
     17   1.1   sekiya  *
     18   1.1   sekiya  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19   1.1   sekiya  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20   1.1   sekiya  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21   1.1   sekiya  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22   1.1   sekiya  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23   1.1   sekiya  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24   1.1   sekiya  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25   1.1   sekiya  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26   1.1   sekiya  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27   1.1   sekiya  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28   1.1   sekiya  */
     29   1.1   sekiya 
     30   1.1   sekiya /*
     31   1.5    pooka  * INT/INT2/INT3 interrupt controller (used in Indy's, Indigo's, etc..)
     32   1.1   sekiya  */
     33   1.1   sekiya 
     34   1.1   sekiya #include <sys/cdefs.h>
     35  1.10  tsutsui __KERNEL_RCSID(0, "$NetBSD: int.c,v 1.10 2005/10/18 11:31:12 tsutsui Exp $");
     36   1.1   sekiya 
     37   1.1   sekiya #include "opt_cputype.h"
     38   1.1   sekiya 
     39   1.1   sekiya #include <sys/param.h>
     40   1.1   sekiya #include <sys/proc.h>
     41   1.1   sekiya #include <sys/systm.h>
     42   1.1   sekiya #include <sys/kernel.h>
     43   1.1   sekiya #include <sys/device.h>
     44   1.8   sekiya #include <sys/malloc.h>
     45   1.1   sekiya 
     46   1.1   sekiya #include <dev/ic/i8253reg.h>
     47   1.1   sekiya #include <machine/sysconf.h>
     48   1.1   sekiya #include <machine/machtype.h>
     49   1.1   sekiya #include <machine/bus.h>
     50   1.1   sekiya #include <mips/locore.h>
     51   1.1   sekiya 
     52   1.1   sekiya #include <mips/cache.h>
     53   1.1   sekiya 
     54   1.1   sekiya #include <sgimips/dev/int2reg.h>
     55   1.3   sekiya #include <sgimips/dev/int2var.h>
     56   1.1   sekiya 
     57   1.1   sekiya static bus_space_handle_t ioh;
     58   1.1   sekiya static bus_space_tag_t iot;
     59   1.1   sekiya 
     60   1.1   sekiya struct int_softc {
     61   1.1   sekiya 	struct device sc_dev;
     62   1.1   sekiya };
     63   1.1   sekiya 
     64   1.1   sekiya 
     65   1.1   sekiya static int	int_match(struct device *, struct cfdata *, void *);
     66   1.1   sekiya static void	int_attach(struct device *, struct device *, void *);
     67   1.1   sekiya void 		int_local0_intr(u_int32_t, u_int32_t, u_int32_t, u_int32_t);
     68   1.1   sekiya void		int_local1_intr(u_int32_t, u_int32_t, u_int32_t, u_int32_t);
     69   1.1   sekiya int 		int_mappable_intr(void *);
     70   1.1   sekiya void		*int_intr_establish(int, int, int (*)(void *), void *);
     71   1.1   sekiya unsigned long	int_cal_timer(void);
     72   1.1   sekiya void		int_8254_cal(void);
     73   1.1   sekiya 
     74   1.1   sekiya CFATTACH_DECL(int, sizeof(struct int_softc),
     75   1.1   sekiya 	int_match, int_attach, NULL, NULL);
     76   1.1   sekiya 
     77   1.1   sekiya static int
     78   1.1   sekiya int_match(struct device *parent, struct cfdata *match, void *aux)
     79   1.1   sekiya {
     80   1.6    pooka 
     81   1.6    pooka 	if ((mach_type == MACH_SGI_IP12) || (mach_type == MACH_SGI_IP20) ||
     82   1.6    pooka 	    (mach_type == MACH_SGI_IP22) )
     83   1.1   sekiya 		return 1;
     84   1.1   sekiya 
     85   1.1   sekiya 	return 0;
     86   1.1   sekiya }
     87   1.1   sekiya 
     88   1.1   sekiya static void
     89   1.1   sekiya int_attach(struct device *parent, struct device *self, void *aux)
     90   1.1   sekiya {
     91   1.1   sekiya 	u_int32_t address;
     92   1.1   sekiya 
     93   1.1   sekiya 	if (mach_type == MACH_SGI_IP12)
     94   1.1   sekiya 		address = INT_IP12;
     95   1.1   sekiya 	else if (mach_type == MACH_SGI_IP20)
     96   1.1   sekiya 		address = INT_IP20;
     97   1.1   sekiya 	else if (mach_type == MACH_SGI_IP22) {
     98   1.1   sekiya 		if (mach_subtype == MACH_SGI_IP22_FULLHOUSE)
     99   1.1   sekiya 			address = INT_IP22;
    100   1.1   sekiya 		else
    101   1.1   sekiya 			address = INT_IP24;
    102   1.7    pooka 	} else
    103   1.1   sekiya 		panic("\nint0: passed match, but failed attach?");
    104   1.1   sekiya 
    105   1.1   sekiya 	printf(" addr 0x%x", address);
    106  1.10  tsutsui 
    107   1.1   sekiya 	bus_space_map(iot, address, 0, 0, &ioh);
    108   1.1   sekiya 	iot = SGIMIPS_BUS_SPACE_NORMAL;
    109   1.1   sekiya 
    110   1.1   sekiya 	/* Clean out interrupt masks */
    111   1.1   sekiya 	bus_space_write_4(iot, ioh, INT2_LOCAL0_MASK, 0);
    112   1.1   sekiya 	bus_space_write_4(iot, ioh, INT2_LOCAL1_MASK, 0);
    113   1.1   sekiya 	bus_space_write_4(iot, ioh, INT2_MAP_MASK0, 0);
    114   1.1   sekiya 	bus_space_write_4(iot, ioh, INT2_MAP_MASK1, 0);
    115   1.1   sekiya 
    116   1.1   sekiya 	/* Reset timer interrupts */
    117   1.1   sekiya 	bus_space_write_4(iot, ioh, INT2_TIMER_CLEAR, 0x03);
    118   1.1   sekiya 
    119   1.1   sekiya 	switch (mach_type) {
    120   1.1   sekiya 		case MACH_SGI_IP12:
    121   1.1   sekiya 			platform.intr1 = int_local0_intr;
    122   1.1   sekiya 			platform.intr2 = int_local1_intr;
    123   1.1   sekiya 			int_8254_cal();
    124   1.1   sekiya 			break;
    125   1.4    pooka #ifdef MIPS3
    126   1.1   sekiya 		case MACH_SGI_IP20:
    127   1.1   sekiya 		case MACH_SGI_IP22:
    128   1.4    pooka 		{
    129   1.4    pooka 			int i;
    130   1.4    pooka 			unsigned long cps;
    131   1.4    pooka 			unsigned long ctrdiff[3];
    132   1.4    pooka 
    133   1.1   sekiya 			platform.intr0 = int_local0_intr;
    134   1.1   sekiya 			platform.intr1 = int_local1_intr;
    135   1.1   sekiya 
    136   1.1   sekiya 			/* calibrate timer */
    137   1.1   sekiya 			int_cal_timer();
    138   1.1   sekiya 
    139   1.1   sekiya 			cps = 0;
    140   1.6    pooka 			for (i = 0;
    141   1.6    pooka 			    i < sizeof(ctrdiff) / sizeof(ctrdiff[0]); i++) {
    142   1.1   sekiya 				do {
    143   1.1   sekiya 					ctrdiff[i] = int_cal_timer();
    144   1.1   sekiya 				} while (ctrdiff[i] == 0);
    145   1.1   sekiya 
    146   1.1   sekiya 				cps += ctrdiff[i];
    147   1.1   sekiya 			}
    148   1.1   sekiya 
    149   1.1   sekiya 			cps = cps / (sizeof(ctrdiff) / sizeof(ctrdiff[0]));
    150   1.1   sekiya 
    151   1.6    pooka 			printf(": bus %luMHz, CPU %luMHz",
    152   1.6    pooka 			    cps / 10000, cps / 5000);
    153   1.1   sekiya 
    154   1.1   sekiya 			/* R4k/R4400/R4600/R5k count at half CPU frequency */
    155   1.1   sekiya 			curcpu()->ci_cpu_freq = 2 * cps * hz;
    156   1.4    pooka 		}
    157   1.4    pooka #endif /* MIPS3 */
    158   1.1   sekiya 
    159   1.1   sekiya 			break;
    160   1.1   sekiya 		default:
    161   1.1   sekiya 			panic("int0: unsupported machine type %i\n", mach_type);
    162   1.1   sekiya 			break;
    163   1.1   sekiya 	}
    164   1.1   sekiya 
    165   1.1   sekiya 	printf("\n");
    166   1.1   sekiya 
    167   1.1   sekiya 	curcpu()->ci_cycles_per_hz = curcpu()->ci_cpu_freq / (2 * hz);
    168   1.1   sekiya 	curcpu()->ci_divisor_delay = curcpu()->ci_cpu_freq / (2 * 1000000);
    169   1.1   sekiya 	MIPS_SET_CI_RECIPRICAL(curcpu());
    170   1.1   sekiya 
    171   1.1   sekiya 	if (mach_type == MACH_SGI_IP22) {
    172   1.1   sekiya 		/* Wire interrupts 7, 11 to mappable interrupt 0,1 handlers */
    173   1.1   sekiya 		intrtab[7].ih_fun = int_mappable_intr;
    174   1.1   sekiya 		intrtab[7].ih_arg = (void*) 0;
    175   1.1   sekiya 
    176   1.1   sekiya 		intrtab[11].ih_fun = int_mappable_intr;
    177   1.1   sekiya 		intrtab[11].ih_arg = (void*) 1;
    178   1.1   sekiya 	}
    179   1.1   sekiya 
    180   1.1   sekiya 	platform.intr_establish = int_intr_establish;
    181   1.1   sekiya }
    182   1.1   sekiya 
    183   1.1   sekiya int
    184   1.1   sekiya int_mappable_intr(void *arg)
    185   1.1   sekiya {
    186   1.1   sekiya 	int i;
    187   1.1   sekiya 	int ret;
    188   1.1   sekiya 	int intnum;
    189   1.1   sekiya 	u_int32_t mstat;
    190   1.1   sekiya 	u_int32_t mmask;
    191   1.1   sekiya 	int which = (int)arg;
    192   1.8   sekiya 	struct sgimips_intrhand *ih;
    193   1.1   sekiya 
    194   1.1   sekiya 	ret = 0;
    195   1.1   sekiya 	mstat = bus_space_read_4(iot, ioh, INT2_MAP_STATUS);
    196   1.1   sekiya 	mmask = bus_space_read_4(iot, ioh, INT2_MAP_MASK0 + (which << 2));
    197   1.1   sekiya 
    198   1.1   sekiya 	mstat &= mmask;
    199   1.1   sekiya 
    200   1.1   sekiya 	for (i = 0; i < 8; i++) {
    201   1.1   sekiya 		intnum = i + 16 + (which << 3);
    202   1.1   sekiya 		if (mstat & (1 << i)) {
    203   1.8   sekiya 			for (ih = &intrtab[intnum]; ih != NULL;
    204   1.8   sekiya 							ih = ih->ih_next) {
    205   1.8   sekiya 				if (ih->ih_fun != NULL)
    206   1.8   sekiya 					ret |= (ih->ih_fun)(ih->ih_arg);
    207   1.8   sekiya 				else
    208   1.8   sekiya 					printf("int0: unexpected mapped "
    209   1.8   sekiya 					       "interrupt %d\n", intnum);
    210   1.8   sekiya 			}
    211   1.1   sekiya 		}
    212   1.1   sekiya 	}
    213   1.1   sekiya 
    214   1.1   sekiya 	return ret;
    215   1.1   sekiya }
    216   1.1   sekiya 
    217   1.1   sekiya void
    218   1.6    pooka int_local0_intr(u_int32_t status, u_int32_t cause, u_int32_t pc,
    219   1.6    pooka 		u_int32_t ipending)
    220   1.1   sekiya {
    221   1.1   sekiya 	int i;
    222   1.1   sekiya 	u_int32_t l0stat;
    223   1.1   sekiya 	u_int32_t l0mask;
    224   1.8   sekiya 	struct sgimips_intrhand *ih;
    225   1.1   sekiya 
    226   1.1   sekiya 	l0stat = bus_space_read_4(iot, ioh, INT2_LOCAL0_STATUS);
    227   1.1   sekiya 	l0mask = bus_space_read_4(iot, ioh, INT2_LOCAL0_MASK);
    228   1.1   sekiya 
    229   1.8   sekiya 	/* The "FIFO full" bit is apparently not latched in the ISR, which
    230   1.8   sekiya 	   means that it won't be present in l0stat unless we're very lucky.
    231   1.8   sekiya 	   If no interrupts are pending, assume that it was caused by a full
    232   1.8   sekiya 	   FIFO and dispatch.
    233   1.8   sekiya 	 */
    234   1.8   sekiya 	bus_space_write_4(iot, ioh, INT2_LOCAL0_MASK, l0mask & (0xfe));
    235   1.9   sekiya 	if ( (l0mask & 0x01) && ((l0stat & l0mask) == 0) )
    236   1.8   sekiya 	  l0stat = 0x01;
    237   1.1   sekiya 
    238   1.1   sekiya 	for (i = 0; i < 8; i++) {
    239   1.8   sekiya 		if ( (l0stat & l0mask) & (1 << i)) {
    240   1.8   sekiya 			for (ih = &intrtab[i]; ih != NULL; ih = ih->ih_next) {
    241   1.8   sekiya 				if (ih->ih_fun != NULL)
    242   1.8   sekiya 					(ih->ih_fun)(ih->ih_arg);
    243   1.8   sekiya 				else
    244   1.8   sekiya 					printf("int0: unexpected local0 "
    245   1.8   sekiya 					       "interrupt %d\n", i);
    246   1.8   sekiya 			}
    247   1.1   sekiya 		}
    248   1.1   sekiya 	}
    249   1.8   sekiya 
    250   1.8   sekiya 	/* Unmask FIFO */
    251   1.8   sekiya 	bus_space_write_4(iot, ioh, INT2_LOCAL0_MASK, l0mask | 0x01);
    252   1.1   sekiya }
    253   1.1   sekiya 
    254   1.1   sekiya void
    255   1.6    pooka int_local1_intr(u_int32_t status, u_int32_t cause, u_int32_t pc,
    256   1.6    pooka 		u_int32_t ipending)
    257   1.1   sekiya {
    258   1.1   sekiya 	int i;
    259   1.1   sekiya 	u_int32_t l1stat;
    260   1.1   sekiya 	u_int32_t l1mask;
    261   1.8   sekiya 	struct sgimips_intrhand *ih;
    262   1.1   sekiya 
    263   1.1   sekiya 	l1stat = bus_space_read_4(iot, ioh, INT2_LOCAL1_STATUS);
    264   1.1   sekiya 	l1mask = bus_space_read_4(iot, ioh, INT2_LOCAL1_MASK);
    265   1.1   sekiya 
    266   1.1   sekiya 	l1stat &= l1mask;
    267   1.1   sekiya 
    268   1.1   sekiya 	for (i = 0; i < 8; i++) {
    269   1.1   sekiya 		if (l1stat & (1 << i)) {
    270   1.8   sekiya 			for (ih = &intrtab[8+i]; ih != NULL; ih = ih->ih_next) {
    271   1.8   sekiya 				if (ih->ih_fun != NULL)
    272   1.8   sekiya 					(ih->ih_fun)(ih->ih_arg);
    273   1.8   sekiya 				else
    274   1.8   sekiya 					printf("int0: unexpected local1 "
    275   1.8   sekiya 					       " interrupt %x\n", 8 + i);
    276   1.8   sekiya 			}
    277   1.1   sekiya 		}
    278   1.1   sekiya 	}
    279   1.1   sekiya }
    280   1.1   sekiya 
    281   1.1   sekiya void *
    282   1.1   sekiya int_intr_establish(int level, int ipl, int (*handler) (void *), void *arg)
    283   1.1   sekiya {
    284   1.1   sekiya 	u_int32_t mask;
    285   1.1   sekiya 
    286   1.1   sekiya 	if (level < 0 || level >= NINTR)
    287   1.1   sekiya 		panic("invalid interrupt level");
    288   1.1   sekiya 
    289   1.8   sekiya 	if (intrtab[level].ih_fun == NULL) {
    290   1.8   sekiya 		intrtab[level].ih_fun = handler;
    291   1.8   sekiya 		intrtab[level].ih_arg = arg;
    292   1.8   sekiya 		intrtab[level].ih_next = NULL;
    293   1.8   sekiya 	} else {
    294   1.8   sekiya 		struct sgimips_intrhand *n, *ih = malloc(sizeof *ih,
    295   1.8   sekiya 							 M_DEVBUF, M_NOWAIT);
    296   1.8   sekiya 
    297   1.8   sekiya 		if (ih == NULL) {
    298  1.10  tsutsui 			printf("int_intr_establish: can't allocate handler\n");
    299   1.8   sekiya 			return (void *)NULL;
    300   1.8   sekiya 		}
    301   1.8   sekiya 
    302   1.8   sekiya 		ih->ih_fun = handler;
    303   1.8   sekiya 		ih->ih_arg = arg;
    304   1.8   sekiya 		ih->ih_next = NULL;
    305   1.8   sekiya 
    306   1.8   sekiya 		for (n = &intrtab[level]; n->ih_next != NULL; n = n->ih_next)
    307  1.10  tsutsui 			;
    308  1.10  tsutsui 
    309   1.8   sekiya 		n->ih_next = ih;
    310   1.8   sekiya 
    311   1.8   sekiya 		return (void *)NULL;	/* vector already set */
    312   1.1   sekiya 	}
    313   1.1   sekiya 
    314   1.1   sekiya 
    315   1.1   sekiya 	if (level < 8) {
    316   1.1   sekiya 		mask = bus_space_read_4(iot, ioh, INT2_LOCAL0_MASK);
    317   1.1   sekiya 		mask |= (1 << level);
    318   1.1   sekiya 		bus_space_write_4(iot, ioh, INT2_LOCAL0_MASK, mask);
    319   1.1   sekiya 	} else if (level < 16) {
    320   1.1   sekiya 		mask = bus_space_read_4(iot, ioh, INT2_LOCAL1_MASK);
    321   1.1   sekiya 		mask |= (1 << (level - 8));
    322   1.1   sekiya 		bus_space_write_4(iot, ioh, INT2_LOCAL1_MASK, mask);
    323   1.1   sekiya 	} else if (level < 24) {
    324   1.1   sekiya 		/* Map0 interrupt maps to l0 bit 7, so turn that on too */
    325   1.1   sekiya 		mask = bus_space_read_4(iot, ioh, INT2_LOCAL0_MASK);
    326   1.1   sekiya 		mask |= (1 << 7);
    327   1.1   sekiya 		bus_space_write_4(iot, ioh, INT2_LOCAL0_MASK, mask);
    328   1.1   sekiya 
    329   1.1   sekiya 		mask = bus_space_read_4(iot, ioh, INT2_MAP_MASK0);
    330   1.1   sekiya 		mask |= (1 << (level - 16));
    331   1.1   sekiya 		bus_space_write_4(iot, ioh, INT2_MAP_MASK0, mask);
    332   1.1   sekiya 	} else {
    333   1.1   sekiya 		/* Map1 interrupt maps to l1 bit 3, so turn that on too */
    334   1.1   sekiya 		mask = bus_space_read_4(iot, ioh, INT2_LOCAL1_MASK);
    335   1.1   sekiya 		mask |= (1 << 3);
    336   1.1   sekiya 		bus_space_write_4(iot, ioh, INT2_LOCAL1_MASK, mask);
    337   1.1   sekiya 
    338   1.1   sekiya 		mask = bus_space_read_4(iot, ioh, INT2_MAP_MASK1);
    339   1.1   sekiya 		mask |= (1 << (level - 24));
    340   1.1   sekiya 		bus_space_write_4(iot, ioh, INT2_MAP_MASK1, mask);
    341   1.1   sekiya 	}
    342   1.1   sekiya 
    343   1.1   sekiya 	return (void *)NULL;
    344   1.1   sekiya }
    345   1.1   sekiya 
    346   1.4    pooka #ifdef MIPS3
    347   1.1   sekiya unsigned long
    348   1.1   sekiya int_cal_timer(void)
    349   1.1   sekiya {
    350   1.1   sekiya 	int s;
    351   1.1   sekiya 	int roundtime;
    352   1.1   sekiya 	int sampletime;
    353   1.1   sekiya 	int startmsb, lsb, msb;
    354   1.1   sekiya 	unsigned long startctr, endctr;
    355   1.1   sekiya 
    356   1.1   sekiya 	/*
    357   1.1   sekiya 	 * NOTE: HZ must be greater than 15 for this to work, as otherwise
    358   1.1   sekiya 	 * we'll overflow the counter.  We round the answer to hearest 1
    359   1.1   sekiya 	 * MHz of the master (2x) clock.
    360   1.1   sekiya 	 */
    361   1.1   sekiya 	roundtime = (1000000 / hz) / 2;
    362   1.1   sekiya 	sampletime = (1000000 / hz) + 0xff;
    363   1.1   sekiya 	startmsb = (sampletime >> 8);
    364   1.1   sekiya 
    365   1.1   sekiya 	s = splhigh();
    366   1.1   sekiya 
    367   1.1   sekiya 	bus_space_write_4(iot, ioh, INT2_TIMER_CONTROL,
    368   1.1   sekiya 		( TIMER_SEL2 | TIMER_16BIT | TIMER_RATEGEN) );
    369   1.1   sekiya 	bus_space_write_4(iot, ioh, INT2_TIMER_2, (sampletime & 0xff));
    370   1.1   sekiya 	bus_space_write_4(iot, ioh, INT2_TIMER_2, (sampletime >> 8));
    371   1.1   sekiya 
    372   1.1   sekiya 	startctr = mips3_cp0_count_read();
    373   1.1   sekiya 
    374   1.1   sekiya 	/* Wait for the MSB to count down to zero */
    375   1.1   sekiya 	do {
    376   1.1   sekiya 		bus_space_write_4(iot, ioh, INT2_TIMER_CONTROL, TIMER_SEL2 );
    377   1.1   sekiya 		lsb = bus_space_read_4(iot, ioh, INT2_TIMER_2) & 0xff;
    378   1.1   sekiya 		msb = bus_space_read_4(iot, ioh, INT2_TIMER_2) & 0xff;
    379   1.1   sekiya 
    380   1.1   sekiya 		endctr = mips3_cp0_count_read();
    381   1.1   sekiya 	} while (msb);
    382   1.1   sekiya 
    383   1.1   sekiya 	/* Turn off timer */
    384   1.1   sekiya 	bus_space_write_4(iot, ioh, INT2_TIMER_CONTROL,
    385   1.1   sekiya 		( TIMER_SEL2 | TIMER_16BIT | TIMER_SWSTROBE) );
    386   1.1   sekiya 
    387   1.1   sekiya 	splx(s);
    388   1.1   sekiya 
    389   1.1   sekiya 	return (endctr - startctr) / roundtime * roundtime;
    390   1.1   sekiya }
    391   1.4    pooka #endif /* MIPS3 */
    392   1.1   sekiya 
    393   1.1   sekiya void
    394   1.1   sekiya int_8254_cal(void)
    395   1.1   sekiya {
    396   1.1   sekiya 	int s;
    397   1.1   sekiya 
    398   1.1   sekiya 	s = splhigh();
    399   1.1   sekiya 
    400   1.7    pooka 	bus_space_write_1(iot, ioh, INT2_TIMER_0 + 15,
    401  1.10  tsutsui 	    TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
    402   1.7    pooka 	bus_space_write_1(iot, ioh, INT2_TIMER_0 + 3, (20000 / hz) % 256);
    403   1.1   sekiya 	wbflush();
    404   1.1   sekiya 	delay(4);
    405   1.7    pooka 	bus_space_write_1(iot, ioh, INT2_TIMER_0 + 3, (20000 / hz) / 256);
    406   1.1   sekiya 
    407   1.7    pooka 	bus_space_write_1(iot, ioh, INT2_TIMER_0 + 15,
    408  1.10  tsutsui 	    TIMER_SEL2|TIMER_RATEGEN|TIMER_16BIT);
    409   1.7    pooka 	bus_space_write_1(iot, ioh, INT2_TIMER_0 + 11, 50);
    410   1.1   sekiya 	wbflush();
    411   1.1   sekiya 	delay(4);
    412   1.7    pooka 	bus_space_write_1(iot, ioh, INT2_TIMER_0 + 11, 0);
    413   1.1   sekiya 	splx(s);
    414   1.1   sekiya }
    415   1.3   sekiya 
    416   1.3   sekiya void
    417   1.3   sekiya int2_wait_fifo(u_int32_t flag)
    418   1.3   sekiya {
    419   1.8   sekiya 	if (ioh == 0)
    420   1.8   sekiya 		delay(5000);
    421   1.8   sekiya 	else
    422   1.8   sekiya 		while (bus_space_read_4(iot, ioh, INT2_LOCAL0_STATUS) & flag)
    423   1.8   sekiya 			;
    424   1.3   sekiya }
    425