diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2003-10-11 22:06:51 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2003-10-11 22:06:51 +0000 |
commit | a8fd6865bd65719e98f10462c68fc1b437ca6974 (patch) | |
tree | 2c51f4b74d68e67c5c2180dd1ccc5c2960445534 /sys/arch/mvme88k | |
parent | 54222586fc769389928f40caffdc7538103085d7 (diff) |
Merge sclock and clock pseudo-devices.
Diffstat (limited to 'sys/arch/mvme88k')
-rw-r--r-- | sys/arch/mvme88k/conf/GENERIC | 33 | ||||
-rw-r--r-- | sys/arch/mvme88k/conf/M187 | 5 | ||||
-rw-r--r-- | sys/arch/mvme88k/conf/M188 | 5 | ||||
-rw-r--r-- | sys/arch/mvme88k/conf/M197 | 5 | ||||
-rw-r--r-- | sys/arch/mvme88k/conf/RAMDISK | 8 | ||||
-rw-r--r-- | sys/arch/mvme88k/conf/files.mvme88k | 8 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/clock.c | 348 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/sclock.c | 427 |
8 files changed, 321 insertions, 518 deletions
diff --git a/sys/arch/mvme88k/conf/GENERIC b/sys/arch/mvme88k/conf/GENERIC index 6e6232becd4..32e99c48c29 100644 --- a/sys/arch/mvme88k/conf/GENERIC +++ b/sys/arch/mvme88k/conf/GENERIC @@ -1,6 +1,6 @@ -# $OpenBSD: GENERIC,v 1.33 2003/08/01 07:43:01 miod Exp $ +# $OpenBSD: GENERIC,v 1.34 2003/10/11 22:06:48 miod Exp $ -machine mvme88k +machine mvme88k include "../../../conf/GENERIC" @@ -10,10 +10,9 @@ option MVME197 # support for 197 option "NCPUS=1" # number of CPUs supported (max 4) option BUGMAP # use the Bug ROM VME mappings #option DEBUG # print debugging statements -#option EH_DEBUG # debugging code for exception handlers # Define this if your processor has the xxx.usr bug (mask C82N) -option ERRATA__XXX_USR +option ERRATA__XXX_USR maxusers 64 @@ -25,18 +24,13 @@ config bsd swap generic mainbus0 at root -# ------------------------------ mainbus devices ------------------------ bugtty0 at mainbus0 -pcctwo0 at mainbus0 addr 0xfff00000 -syscon0 at mainbus0 addr 0xfff00000 -bussw0 at mainbus0 addr 0xfff00000 -# ------------------------------ bussw devices -------------------------- -pcctwo0 at bussw0 offset 0x42000 - -# ------------------------------ pcctwo devices ------------------------- +# MVME1x7 devices +pcctwo0 at mainbus0 addr 0xfff00000 # MVME187 +bussw0 at mainbus0 addr 0xfff00000 # MVME197 +pcctwo0 at bussw0 offset 0x42000 # MVME197 clock0 at pcctwo0 ipl 5 -sclock0 at pcctwo0 ipl 5 nvram0 at pcctwo0 offset 0xc0000 vme0 at pcctwo0 offset 0x40000 ie0 at pcctwo0 offset 0x46000 ipl 1 @@ -46,18 +40,16 @@ cl0 at pcctwo0 offset 0x45000 ipl 3 memc0 at pcctwo0 offset 0x43000 memc1 at pcctwo0 offset 0x43100 -# ------------------------------ syscon0 devices ------------------------ +# MVME188 devices +syscon0 at mainbus0 addr 0xfff00000 # MVME188 clock0 at syscon0 ipl 5 -sclock0 at syscon0 ipl 5 nvram0 at syscon0 offset 0x80000 dart0 at syscon0 offset 0x82000 ipl 3 vme0 at syscon0 offset 0x85000 -# ------------------------------ vme0 devices -------------------------- vmes0 at vme0 vmel0 at vme0 -# ------------------------------ vmes0 devices ------------------------- vx0 at vmes0 addr 0xff780000 ipl 3 len 0x10000 vx1 at vmes0 addr 0xff790000 ipl 3 len 0x10000 vx2 at vmes0 addr 0xff7a0000 ipl 3 len 0x10000 @@ -72,13 +64,12 @@ vs3 at vmes0 addr 0xffff5800 ipl 2 len 0x800 vs4 at vmes0 addr 0xffff7000 ipl 2 len 0x800 vs5 at vmes0 addr 0xffff7800 ipl 2 len 0x800 -# ------------------------------- vs0 devices -------------------------- scsibus* at vs? - -# ------------------------------ ssh0 devices -------------------------- scsibus* at ssh? -# ------------------------------ scsibus0 devices ---------------------- sd* at scsibus? target ? lun ? st* at scsibus? target ? lun ? cd* at scsibus? target ? lun ? +ch* at scsibus? target ? lun ? +ss* at scsibus? target ? lun ? +uk* at scsibus? target ? lun ? diff --git a/sys/arch/mvme88k/conf/M187 b/sys/arch/mvme88k/conf/M187 index f6e02dce277..6668dffde27 100644 --- a/sys/arch/mvme88k/conf/M187 +++ b/sys/arch/mvme88k/conf/M187 @@ -1,4 +1,4 @@ -# $OpenBSD: M187,v 1.21 2003/08/01 07:43:01 miod Exp $ +# $OpenBSD: M187,v 1.22 2003/10/11 22:06:48 miod Exp $ machine mvme88k @@ -10,7 +10,7 @@ option BUGMAP # use Bug Rom VME Mappings #option EH_DEBUG # debugging code for exception handlers # Define this if your processor has the xxx.usr bug (mask C82N) -option ERRATA__XXX_USR +option ERRATA__XXX_USR maxusers 64 @@ -25,7 +25,6 @@ pcctwo0 at mainbus0 addr 0xfff00000 # ------------------------------ pcctwo devices ------------------------- clock0 at pcctwo0 ipl 5 -sclock0 at pcctwo0 ipl 5 vme0 at pcctwo0 offset 0x40000 nvram0 at pcctwo0 offset 0xc0000 ie0 at pcctwo0 offset 0x46000 ipl 1 diff --git a/sys/arch/mvme88k/conf/M188 b/sys/arch/mvme88k/conf/M188 index f34d4c34f73..602d1192e17 100644 --- a/sys/arch/mvme88k/conf/M188 +++ b/sys/arch/mvme88k/conf/M188 @@ -1,4 +1,4 @@ -# $OpenBSD: M188,v 1.16 2001/12/22 18:22:38 smurph Exp $ +# $OpenBSD: M188,v 1.17 2003/10/11 22:06:48 miod Exp $ machine mvme88k @@ -11,7 +11,7 @@ option BUGMAP # use Bug Rom VME Mappings #option EH_DEBUG # debugging code for exception handlers # Define this if your processor has the xxx.usr bug (mask C82N) -option ERRATA__XXX_USR +option ERRATA__XXX_USR maxusers 64 @@ -26,7 +26,6 @@ syscon0 at mainbus0 addr 0xfff00000 # ------------------------------ syscon0 devices ------------------------ clock0 at syscon0 ipl 5 -sclock0 at syscon0 ipl 5 nvram0 at syscon0 offset 0x80000 dart0 at syscon0 offset 0x82000 ipl 3 vme0 at syscon0 offset 0x85000 diff --git a/sys/arch/mvme88k/conf/M197 b/sys/arch/mvme88k/conf/M197 index 2f4e633d1f1..ec4f05be27a 100644 --- a/sys/arch/mvme88k/conf/M197 +++ b/sys/arch/mvme88k/conf/M197 @@ -1,4 +1,4 @@ -# $OpenBSD: M197,v 1.17 2003/01/04 16:20:30 miod Exp $ +# $OpenBSD: M197,v 1.18 2003/10/11 22:06:48 miod Exp $ machine mvme88k @@ -11,7 +11,7 @@ option BUGMAP # use Bug Rom VME Mappings #option EH_DEBUG # debugging code for exception handlers # Define this if your processor has the xxx.usr bug (mask C82N) -option ERRATA__XXX_USR +option ERRATA__XXX_USR maxusers 64 @@ -29,7 +29,6 @@ pcctwo0 at bussw0 offset 0x42000 # ------------------------------ pcctwo devices ------------------------- clock0 at pcctwo0 ipl 5 -sclock0 at pcctwo0 ipl 5 vme0 at pcctwo0 offset 0x40000 nvram0 at pcctwo0 offset 0xc0000 ie0 at pcctwo0 offset 0x46000 ipl 1 diff --git a/sys/arch/mvme88k/conf/RAMDISK b/sys/arch/mvme88k/conf/RAMDISK index d86d5d48b30..879562f39a6 100644 --- a/sys/arch/mvme88k/conf/RAMDISK +++ b/sys/arch/mvme88k/conf/RAMDISK @@ -1,6 +1,6 @@ -# $OpenBSD: RAMDISK,v 1.13 2003/08/09 21:19:58 miod Exp $ +# $OpenBSD: RAMDISK,v 1.14 2003/10/11 22:06:48 miod Exp $ -machine mvme88k +machine mvme88k # 2 meg ramdisk option MINIROOTSIZE=4096 @@ -14,7 +14,7 @@ option "NCPUS=1" # number of CPUs supported (max 4) option BUGMAP # use the Bug ROM VME mappings # Define this if your processor has the xxx.usr bug (mask C82N) -option ERRATA__XXX_USR +option ERRATA__XXX_USR maxusers 32 @@ -42,7 +42,6 @@ syscon0 at mainbus0 addr 0xfff00000 pcctwo0 at bussw0 offset 0x42000 clock0 at pcctwo0 ipl 5 -sclock0 at pcctwo0 ipl 5 vme0 at pcctwo0 offset 0x40000 nvram0 at pcctwo0 offset 0xc0000 ie0 at pcctwo0 offset 0x46000 ipl 1 @@ -50,7 +49,6 @@ ssh0 at pcctwo0 offset 0x47000 ipl 2 cl0 at pcctwo0 offset 0x45000 ipl 3 clock0 at syscon0 ipl 5 -sclock0 at syscon0 ipl 5 nvram0 at syscon0 offset 0x80000 dart0 at syscon0 offset 0x82000 ipl 3 vme0 at syscon0 offset 0x85000 diff --git a/sys/arch/mvme88k/conf/files.mvme88k b/sys/arch/mvme88k/conf/files.mvme88k index 5140a9b6329..5e6deec8a94 100644 --- a/sys/arch/mvme88k/conf/files.mvme88k +++ b/sys/arch/mvme88k/conf/files.mvme88k @@ -1,5 +1,5 @@ -# $OpenBSD: files.mvme88k,v 1.20 2003/01/14 03:20:12 miod Exp $ -# +# $OpenBSD: files.mvme88k,v 1.21 2003/10/11 22:06:48 miod Exp $ +# maxpartitions 16 device mainbus { [addr = -1 ] } @@ -30,10 +30,6 @@ device clock attach clock at pcctwo, syscon file arch/mvme88k/dev/clock.c clock -device sclock -attach sclock at pcctwo, syscon -file arch/mvme88k/dev/sclock.c sclock - device memc attach memc at pcctwo file arch/mvme88k/dev/memc.c memc diff --git a/sys/arch/mvme88k/dev/clock.c b/sys/arch/mvme88k/dev/clock.c index 03b2fa8f1ad..3fcc2a61db9 100644 --- a/sys/arch/mvme88k/dev/clock.c +++ b/sys/arch/mvme88k/dev/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.25 2003/10/08 22:36:11 miod Exp $ */ +/* $OpenBSD: clock.c,v 1.26 2003/10/11 22:06:50 miod Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. * Copyright (c) 1995 Theo de Raadt @@ -67,7 +67,7 @@ */ /* - * interval clock driver. + * Interval and statistic clocks driver. */ #include <sys/param.h> @@ -75,12 +75,8 @@ #include <sys/kernel.h> #include <sys/device.h> #include <sys/systm.h> -#ifdef GPROF -#include <sys/gmon.h> -#endif #include <machine/asm.h> -#include <machine/asm_macro.h> /* for stack_pointer() */ #include <machine/board.h> /* for register defines */ #include <machine/psl.h> #include <machine/autoconf.h> @@ -111,8 +107,13 @@ int clockmatch(struct device *, void *, void *); void clockattach(struct device *, struct device *, void *); void sbc_initclock(void); +void sbc_initstatclock(void); void m188_initclock(void); +void m188_initstatclock(void); void m188_timer_init(unsigned); +void m188_cio_init(unsigned); +u_int8_t read_cio(int); +void write_cio(int, u_int8_t); struct clocksoftc { struct device sc_dev; @@ -129,18 +130,35 @@ struct cfdriver clock_cd = { }; int sbc_clockintr(void *); +int sbc_statintr(void *); int m188_clockintr(void *); +int m188_statintr(void *); + +u_int8_t prof_reset; +u_int8_t stat_reset; + +struct simplelock cio_lock; + +#define CIO_LOCK simple_lock(&cio_lock) +#define CIO_UNLOCK simple_unlock(&cio_lock) -u_char prof_reset; +/* + * Statistics clock interval and variance, in usec. Variance must be a + * power of two. Since this gives us an even number, not an odd number, + * we discard one case and compensate. That is, a variance of 4096 would + * give us offsets in [0..4095]. Instead, we take offsets in [1..4095]. + * This is symmetric about the point 2048, or statvar/2, and thus averages + * to that value (assuming uniform random numbers). + */ +int statvar = 8192; +int statmin; /* statclock interval - 1/2*variance */ /* * Every machine must have a clock tick device of some sort; for this * platform this file manages it, no matter what form it takes. */ int -clockmatch(parent, vcf, args) - struct device *parent; - void *vcf, *args; +clockmatch(struct device *parent, void *vcf, void *args) { struct confargs *ca = args; struct cfdata *cf = vcf; @@ -161,9 +179,7 @@ clockmatch(parent, vcf, args) } void -clockattach(parent, self, args) - struct device *parent, *self; - void *args; +clockattach(struct device *parent, struct device *self, void *args) { struct confargs *ca = args; struct clocksoftc *sc = (struct clocksoftc *)self; @@ -178,6 +194,13 @@ clockattach(parent, self, args) prof_reset = ca->ca_ipl | PCC2_IRQ_IEN | PCC2_IRQ_ICLR; pcctwointr_establish(PCC2V_TIMER1, &sc->sc_profih); md.clock_init_func = sbc_initclock; + sc->sc_statih.ih_fn = sbc_statintr; + sc->sc_statih.ih_arg = 0; + sc->sc_statih.ih_wantframe = 1; + sc->sc_statih.ih_ipl = ca->ca_ipl; + stat_reset = ca->ca_ipl | PCC2_IRQ_IEN | PCC2_IRQ_ICLR; + pcctwointr_establish(PCC2V_TIMER2, &sc->sc_statih); + md.statclock_init_func = sbc_initstatclock; break; #endif /* NPCCTWO */ #if NSYSCON > 0 @@ -188,6 +211,12 @@ clockattach(parent, self, args) sc->sc_profih.ih_ipl = ca->ca_ipl; sysconintr_establish(SYSCV_TIMER1, &sc->sc_profih); md.clock_init_func = m188_initclock; + sc->sc_statih.ih_fn = m188_statintr; + sc->sc_statih.ih_arg = 0; + sc->sc_statih.ih_wantframe = 1; + sc->sc_statih.ih_ipl = ca->ca_ipl; + sysconintr_establish(SYSCV_TIMER2, &sc->sc_statih); + md.statclock_init_func = m188_initstatclock; break; #endif /* NSYSCON */ } @@ -195,6 +224,7 @@ clockattach(parent, self, args) } #if NPCCTWO > 0 + void sbc_initclock(void) { @@ -220,8 +250,7 @@ sbc_initclock(void) * clockintr: ack intr and call hardclock */ int -sbc_clockintr(eframe) - void *eframe; +sbc_clockintr(void *eframe) { sys_pcc2->pcc2_t1irq = prof_reset; @@ -233,42 +262,74 @@ sbc_clockintr(eframe) return (1); } -#endif /* NPCCTWO */ void -delay(us) - int us; +sbc_initstatclock(void) { - volatile int c; + int statint, minint; + +#ifdef CLOCK_DEBUG + printf("SBC statclock init\n"); +#endif + if (stathz == 0) + stathz = hz; + if (1000000 % stathz) { + printf("cannot get %d Hz statclock; using 100 Hz\n", stathz); + stathz = 100; + } + profhz = stathz; /* always */ + + statint = 1000000 / stathz; + minint = statint / 2 + 100; + while (statvar > minint) + statvar >>= 1; + + /* statclock */ + sys_pcc2->pcc2_t2ctl = 0; + sys_pcc2->pcc2_t2cmp = pcc2_timer_us2lim(statint); + sys_pcc2->pcc2_t2count = 0; + sys_pcc2->pcc2_t2ctl = PCC2_TCTL_CEN | PCC2_TCTL_COC | PCC2_TCTL_COVF; + sys_pcc2->pcc2_t2irq = stat_reset; + + statmin = statint - (statvar >> 1); +} + +int +sbc_statintr(void *eframe) +{ + u_long newint, r, var; + + sys_pcc2->pcc2_t2irq = stat_reset; + + /* increment intr counter */ + intrcnt[M88K_SCLK_IRQ]++; + + statclock((struct clockframe *)eframe); -#if NPCCTWO > 0 /* - * We use the vme system controller for the delay clock. - * Do not go to the real timer until vme device is present. - * Or, in the case of MVME188, not at all. + * Compute new randomized interval. The intervals are uniformly + * distributed on [statint - statvar / 2, statint + statvar / 2], + * and therefore have mean statint, giving a stathz frequency clock. */ - if (sys_vme2 != NULL) { - sys_vme2->vme2_t1cmp = 0xffffffff; - sys_vme2->vme2_t1count = 0; - sys_vme2->vme2_tctl |= VME2_TCTL1_CEN; - - while (sys_vme2->vme2_t1count < us) - ; - sys_vme2->vme2_tctl &= ~VME2_TCTL1_CEN; - return; - } -#endif - c = 3 * us; /* XXX not accurate! */ - while (--c > 0) - ; + var = statvar; + do { + r = random() & (var - 1); + } while (r == 0); + newint = statmin + r; + + sys_pcc2->pcc2_t2ctl = 0; + sys_pcc2->pcc2_t2cmp = pcc2_timer_us2lim(newint); + sys_pcc2->pcc2_t2count = 0; /* should I? */ + sys_pcc2->pcc2_t2irq = stat_reset; + sys_pcc2->pcc2_t2ctl = PCC2_TCTL_CEN | PCC2_TCTL_COC; + return (1); } -#if NSYSCON > 0 -int counter; +#endif /* NPCCTWO */ +#if NSYSCON > 0 int -m188_clockintr(eframe) - void *eframe; +m188_clockintr(void *eframe) { volatile int tmp; @@ -313,7 +374,7 @@ void m188_timer_init(unsigned period) { volatile int imr; - dma_cachectl(0xFFF82000, 0x1000, DMA_CACHE_SYNC_INVAL); + int counter; /* make sure the counter range is proper. */ if ( period < 9 ) @@ -327,24 +388,211 @@ m188_timer_init(unsigned period) printf("timer will interrupt every %d usec\n", (int) (counter * 4.34)); #endif /* clear the counter/timer output OP3 while we program the DART */ - *((int *volatile) DART_OPCR) = 0x00; + *((int *volatile)DART_OPCR) = 0x00; /* do the stop counter/timer command */ - imr = *((int *volatile) DART_STOPC); + imr = *((int *volatile)DART_STOPC); /* set counter/timer to counter mode, clock/16 */ - *((int *volatile) DART_ACR) = 0x30; + *((int *volatile)DART_ACR) = 0x30; - *((int *volatile) DART_CTUR) = counter / 256; /* set counter MSB */ - *((int *volatile) DART_CTLR) = counter % 256; /* set counter LSB */ - *((int *volatile) DART_IVR) = SYSCV_TIMER1; /* set interrupt vec */ + *((int *volatile)DART_CTUR) = counter / 256; /* set counter MSB */ + *((int *volatile)DART_CTLR) = counter % 256; /* set counter LSB */ + *((int *volatile)DART_IVR) = SYSCV_TIMER1; /* set interrupt vec */ /* give the start counter/timer command */ /* (yes, this is supposed to be a read) */ - imr = *((int *volatile) DART_STARTC); + imr = *((int *volatile)DART_STARTC); /* set the counter/timer output OP3 */ - *((int *volatile) DART_OPCR) = 0x04; + *((int *volatile)DART_OPCR) = 0x04; +} + +int +m188_statintr(void *eframe) +{ + u_long newint, r, var; + + CIO_LOCK; + + /* increment intr counter */ + intrcnt[M88K_SCLK_IRQ]++; + + statclock((struct clockframe *)eframe); + write_cio(CIO_CSR1, CIO_GCB|CIO_CIP); /* Ack the interrupt */ + + /* + * Compute new randomized interval. The intervals are uniformly + * distributed on [statint - statvar / 2, statint + statvar / 2], + * and therefore have mean statint, giving a stathz frequency clock. + */ + var = statvar; + do { + r = random() & (var - 1); + } while (r == 0); + newint = statmin + r; + + /* Load time constant CTC #1 */ + write_cio(CIO_CT1MSB, (newint & 0xff00) >> 8); + write_cio(CIO_CT1LSB, newint & 0xff); + + /* Start CTC #1 running */ + write_cio(CIO_CSR1, CIO_GCB|CIO_CIP); + + CIO_UNLOCK; + return (1); +} + +void +m188_initstatclock(void) +{ + int statint, minint; + +#ifdef CLOCK_DEBUG + printf("VME188 clock init\n"); +#endif + simple_lock_init(&cio_lock); + if (stathz == 0) + stathz = hz; + if (1000000 % stathz) { + printf("cannot get %d Hz statclock; using 100 Hz\n", stathz); + stathz = 100; + } + profhz = stathz; /* always */ + + statint = 1000000 / stathz; + minint = statint / 2 + 100; + while (statvar > minint) + statvar >>= 1; + m188_cio_init(statint); + statmin = statint - (statvar >> 1); +} + +#define CIO_CNTRL 0xfff8300c + +/* Write CIO register */ +void +write_cio(int reg, u_int8_t val) +{ + int s, i; + int *volatile cio_ctrl = (int *volatile)CIO_CNTRL; + + s = splclock(); + CIO_LOCK; + + i = *cio_ctrl; /* goto state 1 */ + *cio_ctrl = 0; /* take CIO out of RESET */ + i = *cio_ctrl; /* reset CIO state machine */ + + *cio_ctrl = (reg & 0xff); /* Select register */ + *cio_ctrl = (val & 0xff); /* Write the value */ + + CIO_UNLOCK; + splx(s); +} + +/* Read CIO register */ +u_int8_t +read_cio(int reg) +{ + int c; + int s, i; + int *volatile cio_ctrl = (int *volatile)CIO_CNTRL; + + s = splclock(); + CIO_LOCK; + + /* Select register */ + *cio_ctrl = (char)(reg & 0xff); + /* Delay for a short time to allow 8536 to settle */ + for (i = 0; i < 100; i++) + ; + /* read the value */ + c = *cio_ctrl; + CIO_UNLOCK; + splx(s); + return (c & 0xff); +} + +/* + * Initialize the CTC (8536) + * Only the counter/timers are used - the IO ports are un-comitted. + * Channels 1 and 2 are linked to provide a /32 counter. + */ + +void +m188_cio_init(unsigned p) +{ + long i; + short period; + + CIO_LOCK; + + period = p & 0xffff; + + /* Initialize 8536 CTC */ + + /* Start by forcing chip into known state */ + read_cio(CIO_MICR); + write_cio(CIO_MICR, CIO_MICR_RESET); /* Reset the CTC */ + for (i = 0; i < 1000; i++) /* Loop to delay */ + ; + + /* Clear reset and start init seq. */ + write_cio(CIO_MICR, 0x00); + + /* Wait for chip to come ready */ + while ((read_cio(CIO_MICR) & CIO_MICR_RJA) == 0) + ; + + /* Initialize the 8536 */ + write_cio(CIO_MICR, + CIO_MICR_MIE | CIO_MICR_NV | CIO_MICR_RJA | CIO_MICR_DLC); + write_cio(CIO_CTMS1, CIO_CTMS_CSC); /* Continuous count */ + write_cio(CIO_PDCB, 0xff); /* set port B to input */ + + /* Load time constant CTC #1 */ + write_cio(CIO_CT1MSB, (period & 0xff00) >> 8); + write_cio(CIO_CT1LSB, period & 0xff); + + /* enable counter 1 */ + write_cio(CIO_MCCR, CIO_MCCR_CT1E | CIO_MCCR_PBE); + + /* Start CTC #1 running */ + write_cio(CIO_CSR1, CIO_GCB | CIO_TCB | CIO_IE); + + CIO_UNLOCK; } #endif /* NSYSCON */ +void +delay(int us) +{ + +#if NPCCTWO > 0 + /* + * On MVME187 and MVME197, we use the vme system controller for + * the delay clock. + * Do not go to the real timer until the vme device is attached. + * We could directly access the chip, but oh well, who cares. + */ + if (sys_vme2 != NULL) { + sys_vme2->vme2_t1cmp = 0xffffffff; + sys_vme2->vme2_t1count = 0; + sys_vme2->vme2_tctl |= VME2_TCTL1_CEN; + + while (sys_vme2->vme2_t1count < us) + ; + sys_vme2->vme2_tctl &= ~VME2_TCTL1_CEN; + } else +#endif + + /* + * If we can't use a real timer, use a tight loop. + */ + { + volatile int c = 3 * us; /* XXX not accurate! */ + while (--c > 0) + ; + } +} diff --git a/sys/arch/mvme88k/dev/sclock.c b/sys/arch/mvme88k/dev/sclock.c deleted file mode 100644 index e389a17da59..00000000000 --- a/sys/arch/mvme88k/dev/sclock.c +++ /dev/null @@ -1,427 +0,0 @@ -/* $OpenBSD: sclock.c,v 1.16 2003/10/08 22:36:11 miod Exp $ */ -/* - * Copyright (c) 1999 Steve Murphree, Jr. - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - * - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * Copyright (c) 1995 Nivas Madhur - * Copyright (c) 1994 Gordon W. Ross - * Copyright (c) 1993 Adam Glass - * - * This software was developed by the Computer Systems Engineering group - * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and - * contributed to Berkeley. - * - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Lawrence Berkeley Laboratory. - * - * 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. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - */ - -/* - * Statistics clock driver. - */ - -#include <sys/param.h> -#include <sys/simplelock.h> -#include <sys/kernel.h> -#include <sys/device.h> -#include <sys/systm.h> -#ifdef GPROF -#include <sys/gmon.h> -#endif - -#include <machine/board.h> -#include <machine/psl.h> -#include <machine/autoconf.h> -#include <machine/cpu.h> - -#include "pcctwo.h" -#if NPCCTWO > 0 -#include <mvme88k/dev/pcctwofunc.h> -#include <mvme88k/dev/pcctworeg.h> -#endif - -#include "syscon.h" -#if NSYSCON > 0 -#include <mvme88k/dev/sysconfunc.h> -#include <mvme88k/dev/sysconreg.h> -#endif - -struct simplelock cio_lock; -/* - * Statistics clock interval and variance, in usec. Variance must be a - * power of two. Since this gives us an even number, not an odd number, - * we discard one case and compensate. That is, a variance of 4096 would - * give us offsets in [0..4095]. Instead, we take offsets in [1..4095]. - * This is symmetric about the point 2048, or statvar/2, and thus averages - * to that value (assuming uniform random numbers). - */ -int statvar = 8192; -int statmin; /* statclock interval - 1/2*variance */ - -int sclockmatch(struct device *, void *, void *); -void sclockattach(struct device *, struct device *, void *); - -void sbc_initstatclock(void); -void m188_initstatclock(void); -void m188_cio_init(unsigned); -u_char read_cio(unsigned); -void write_cio(unsigned, unsigned); - -struct sclocksoftc { - struct device sc_dev; - struct intrhand sc_statih; -}; - -struct cfattach sclock_ca = { - sizeof(struct sclocksoftc), sclockmatch, sclockattach -}; - -struct cfdriver sclock_cd = { - NULL, "sclock", DV_DULL, 0 -}; - -int sbc_statintr(void *); -int m188_statintr(void *); - -u_char stat_reset; - -/* - * Every machine needs, but doesn't have to have, a statistics clock. - * For this platform, this file manages it, no matter what form it takes. - */ -int -sclockmatch(parent, vcf, args) - struct device *parent; - void *vcf, *args; -{ - struct confargs *ca = args; - struct cfdata *cf = vcf; - - if (strcmp(cf->cf_driver->cd_name, "sclock")) { - return (0); - } - - /* - * clock has to be at ipl 5 - * We return the ipl here so that the parent can print - * a message if it is different from what ioconf.c says. - */ - ca->ca_ipl = IPL_CLOCK; - /* set size to 0 - see pcctwo.c:match for details */ - ca->ca_len = 0; - return (1); -} - -void -sclockattach(parent, self, args) - struct device *parent, *self; - void *args; -{ - struct confargs *ca = args; - struct sclocksoftc *sc = (struct sclocksoftc *)self; - - switch (ca->ca_bustype) { -#if NPCCTWO > 0 - case BUS_PCCTWO: - sc->sc_statih.ih_fn = sbc_statintr; - sc->sc_statih.ih_arg = 0; - sc->sc_statih.ih_wantframe = 1; - sc->sc_statih.ih_ipl = ca->ca_ipl; - stat_reset = ca->ca_ipl | PCC2_IRQ_IEN | PCC2_IRQ_ICLR; - pcctwointr_establish(PCC2V_TIMER2, &sc->sc_statih); - md.statclock_init_func = sbc_initstatclock; - break; -#endif /* NPCCTWO */ -#if NSYSCON > 0 - case BUS_SYSCON: - sc->sc_statih.ih_fn = m188_statintr; - sc->sc_statih.ih_arg = 0; - sc->sc_statih.ih_wantframe = 1; - sc->sc_statih.ih_ipl = ca->ca_ipl; - sysconintr_establish(SYSCV_TIMER2, &sc->sc_statih); - md.statclock_init_func = m188_initstatclock; - break; -#endif /* NSYSCON */ - } - printf("\n"); -} - -#if NPCCTWO > 0 -void -sbc_initstatclock(void) -{ - int statint, minint; - -#ifdef CLOCK_DEBUG - printf("SBC statclock init\n"); -#endif - if (stathz == 0) - stathz = hz; - if (1000000 % stathz) { - printf("cannot get %d Hz statclock; using 100 Hz\n", stathz); - stathz = 100; - } - profhz = stathz; /* always */ - - statint = 1000000 / stathz; - minint = statint / 2 + 100; - while (statvar > minint) - statvar >>= 1; - - /* statclock */ - sys_pcc2->pcc2_t2ctl = 0; - sys_pcc2->pcc2_t2cmp = pcc2_timer_us2lim(statint); - sys_pcc2->pcc2_t2count = 0; - sys_pcc2->pcc2_t2ctl = PCC2_TCTL_CEN | PCC2_TCTL_COC | - PCC2_TCTL_COVF; - sys_pcc2->pcc2_t2irq = stat_reset; - - statmin = statint - (statvar >> 1); -} - -int -sbc_statintr(eframe) - void *eframe; -{ - u_long newint, r, var; - - sys_pcc2->pcc2_t2irq = stat_reset; - - /* increment intr counter */ - intrcnt[M88K_SCLK_IRQ]++; - - statclock((struct clockframe *)eframe); - - /* - * Compute new randomized interval. The intervals are uniformly - * distributed on [statint - statvar / 2, statint + statvar / 2], - * and therefore have mean statint, giving a stathz frequency clock. - */ - var = statvar; - do { - r = random() & (var - 1); - } while (r == 0); - newint = statmin + r; - - sys_pcc2->pcc2_t2ctl = 0; - sys_pcc2->pcc2_t2cmp = pcc2_timer_us2lim(newint); - sys_pcc2->pcc2_t2count = 0; /* should I? */ - sys_pcc2->pcc2_t2irq = stat_reset; - sys_pcc2->pcc2_t2ctl = PCC2_TCTL_CEN | PCC2_TCTL_COC; - return (1); -} -#endif /* NPCCTWO */ - -#if NSYSCON > 0 -#define CIO_LOCK simple_lock(&cio_lock) -#define CIO_UNLOCK simple_unlock(&cio_lock) - -int -m188_statintr(eframe) - void *eframe; -{ - u_long newint, r, var; - - CIO_LOCK; - - /* increment intr counter */ - intrcnt[M88K_SCLK_IRQ]++; - - statclock((struct clockframe *)eframe); - write_cio(CIO_CSR1, CIO_GCB|CIO_CIP); /* Ack the interrupt */ - - /* - * Compute new randomized interval. The intervals are uniformly - * distributed on [statint - statvar / 2, statint + statvar / 2], - * and therefore have mean statint, giving a stathz frequency clock. - */ - var = statvar; - do { - r = random() & (var - 1); - } while (r == 0); - newint = statmin + r; - /* - printf("newint = %d, 0x%x\n", newint, newint); - */ - write_cio(CIO_CT1MSB, (newint & 0xFF00) >> 8); /* Load time constant CTC #1 */ - write_cio(CIO_CT1LSB, newint & 0xFF); - - write_cio(CIO_CSR1, CIO_GCB|CIO_CIP); /* Start CTC #1 running */ -#if 0 - if (*ist & CIOI_BIT) { - printf("CIOI not clearing!\n"); - } -#endif - CIO_UNLOCK; - return (1); -} - -void -m188_initstatclock(void) -{ - int statint, minint; - -#ifdef CLOCK_DEBUG - printf("VME188 clock init\n"); -#endif - simple_lock_init(&cio_lock); - if (stathz == 0) - stathz = hz; - if (1000000 % stathz) { - printf("cannot get %d Hz statclock; using 100 Hz\n", stathz); - stathz = 100; - } - profhz = stathz; /* always */ - - statint = 1000000 / stathz; - minint = statint / 2 + 100; - while (statvar > minint) - statvar >>= 1; - m188_cio_init(statint); - statmin = statint - (statvar >> 1); -} - -#define CIO_CNTRL 0xFFF8300C - -/* Write CIO register */ -void -write_cio(reg, val) - unsigned reg,val; -{ - int s, i; - int *volatile cio_ctrl = (int *volatile)CIO_CNTRL; - - s = splclock(); - CIO_LOCK; - - i = *cio_ctrl; /* goto state 1 */ - *cio_ctrl = 0; /* take CIO out of RESET */ - i = *cio_ctrl; /* reset CIO state machine */ - - *cio_ctrl = (reg & 0xFF); /* Select register */ - *cio_ctrl = (val & 0xFF); /* Write the value */ - - CIO_UNLOCK; - splx(s); -} - -/* Read CIO register */ -u_char -read_cio(reg) - unsigned reg; -{ - int c; - int s, i; - int *volatile cio_ctrl = (int *volatile)CIO_CNTRL; - - s = splclock(); - CIO_LOCK; - - /* Select register */ - *cio_ctrl = (char)(reg&0xFF); - /* Delay for a short time to allow 8536 to settle */ - for (i=0;i<100;i++); - /* read the value */ - c = *cio_ctrl; - CIO_UNLOCK; - splx(s); - return ((u_char)c&0xFF); -} - -/* - * Initialize the CTC (8536) - * Only the counter/timers are used - the IO ports are un-comitted. - * Channels 1 and 2 are linked to provide a /32 counter. - */ - -void -m188_cio_init(p) - unsigned p; -{ - long i; - short period; - - CIO_LOCK; - - period = p & 0xFFFF; - - /* Initialize 8536 CTC */ - /* Start by forcing chip into known state */ - (void) read_cio(CIO_MICR); - - write_cio(CIO_MICR, CIO_MICR_RESET); /* Reset the CTC */ - for (i=0;i < 1000L; i++) /* Loop to delay */ - ; - /* Clear reset and start init seq. */ - write_cio(CIO_MICR, 0x00); - - /* Wait for chip to come ready */ - while ((read_cio(CIO_MICR)) != (char) CIO_MICR_RJA) - ; - /* init Z8036 */ - write_cio(CIO_MICR, CIO_MICR_MIE | CIO_MICR_NV | CIO_MICR_RJA | CIO_MICR_DLC); - write_cio(CIO_CTMS1, CIO_CTMS_CSC); /* Continuous count */ - write_cio(CIO_PDCB, 0xFF); /* set port B to input */ - - /* Load time constant CTC #1 */ - write_cio(CIO_CT1MSB, (period & 0xFF00) >> 8); - write_cio(CIO_CT1LSB, period & 0xFF); - - /* enable counter 1 */ - write_cio(CIO_MCCR, CIO_MCCR_CT1E | CIO_MCCR_PBE); - - /* enable interrupts and start */ - /*write_cio(CIO_IVR, SYSCV_TIMER2);*/ - write_cio(CIO_CSR1, CIO_GCB|CIO_TCB|CIO_IE); /* Start CTC #1 running */ - - CIO_UNLOCK; -} -#endif /* NSYSCON */ |