summaryrefslogtreecommitdiff
path: root/sys/arch/mvme88k/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/mvme88k/dev')
-rw-r--r--sys/arch/mvme88k/dev/bugtty.c490
-rw-r--r--sys/arch/mvme88k/dev/clock.c109
-rw-r--r--sys/arch/mvme88k/dev/m88k/bugio.c108
-rw-r--r--sys/arch/mvme88k/dev/mb.c87
-rw-r--r--sys/arch/mvme88k/dev/pcc2.c253
-rw-r--r--sys/arch/mvme88k/dev/pcctwo.c252
6 files changed, 1299 insertions, 0 deletions
diff --git a/sys/arch/mvme88k/dev/bugtty.c b/sys/arch/mvme88k/dev/bugtty.c
new file mode 100644
index 00000000000..48f668a3102
--- /dev/null
+++ b/sys/arch/mvme88k/dev/bugtty.c
@@ -0,0 +1,490 @@
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 1995 Dale Rahn.
+ * All rights reserved.
+ *
+ * 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 Dale Rahn.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/ioctl.h>
+#include <sys/device.h>
+#include <sys/tty.h>
+#include <sys/proc.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/queue.h>
+#include <dev/cons.h>
+
+#include <machine/autoconf.h>
+#include <machine/cpu.h>
+
+#include "bugtty.h"
+
+int bugttymatch __P((struct device *parent, void *self, void *aux));
+void bugttyattach __P((struct device *parent, struct device *self, void *aux));
+
+struct cfdriver bugttycd = {
+ NULL, "bugtty", bugttymatch, bugttyattach,
+ DV_TTY, sizeof(struct device)
+};
+
+/* prototypes */
+int bugttycnprobe __P((struct consdev *cp));
+int bugttycninit __P((struct consdev *cp));
+int bugttycngetc __P((dev_t dev));
+int bugttycnputc __P((dev_t dev, char c));
+
+int bugttyopen __P((dev_t dev, int flag, int mode, struct proc *p));
+int bugttyclose __P((dev_t dev, int flag, int mode, struct proc *p));
+int bugttyread __P((dev_t dev, struct uio *uio, int flag));
+int bugttywrite __P((dev_t dev, struct uio *uio, int flag));
+int bugttyioctl __P((dev_t dev, int cmd, caddr_t data, int flag, struct proc *p));
+int bugttystop __P((struct tty *tp, int flag));
+
+#define DIALOUT(x) ((x) & 0x80)
+#define SWFLAGS(dev) (bugttyswflags | (DIALOUT(dev) ? TIOCFLAG_SOFTCAR : 0))
+
+#define BUGBUF 80
+char bugtty_ibuffer[BUGBUF+1];
+volatile char *pinchar = bugtty_ibuffer;
+char bug_obuffer[BUGBUF+1];
+
+#define bugtty_tty bugttytty
+struct tty *bugtty_tty[NBUGTTY];
+int needprom = 1;
+
+int
+bugttymatch(parent, self, aux)
+ struct device *parent;
+ void *self;
+ void *aux;
+{
+ extern int needprom;
+
+ if (needprom == 0)
+ return (0);
+ return (1);
+}
+
+void
+bugttyattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ printf("\n");
+}
+
+#define BUGTTYUNIT(x) ((x) & (0x7f))
+void bugttyoutput __P((struct tty *tp));
+
+int bugttydefaultrate = TTYDEF_SPEED;
+int bugttyswflags;
+
+int
+bugttymctl(dev, bits, how)
+ dev_t dev;
+ int bits, how;
+{
+ static int settings = TIOCM_DTR | TIOCM_RTS |
+ TIOCM_CTS | TIOCM_CD | TIOCM_DSR;
+ int s;
+
+ /*printf("mctl: dev %x, bits %x, how %x,",dev, bits, how);*/
+
+ /* settings are currently ignored */
+ s = spltty();
+ switch (how) {
+ case DMSET:
+ break;
+ case DMBIC:
+ break;
+ case DMBIS:
+ break;
+ case DMGET:
+ break;
+ }
+ (void)splx(s);
+
+ bits = 0;
+ /* proper defaults? */
+ bits |= TIOCM_DTR;
+ bits |= TIOCM_RTS;
+ bits |= TIOCM_CTS;
+ bits |= TIOCM_CD;
+ /* bits |= TIOCM_RI; */
+ bits |= TIOCM_DSR;
+
+ /* printf("retbits %x\n", bits); */
+ return (bits);
+}
+
+int
+bugttyopen(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ int s, unit = BUGTTYUNIT(dev);
+ struct tty *tp;
+ extern int needprom;
+
+ if (needprom == 0)
+ return (ENODEV);
+
+ s = spltty();
+ if (bugtty_tty[unit]) {
+ tp = bugtty_tty[unit];
+ } else {
+ tp = bugtty_tty[unit] = ttymalloc();
+ }
+ tp->t_oproc = bugttyoutput;
+ tp->t_param = NULL;
+ tp->t_dev = dev;
+
+ if ((tp->t_state & TS_ISOPEN) == 0) {
+ tp->t_state |= TS_WOPEN;
+ ttychars(tp);
+ if (tp->t_ispeed == 0) {
+ /*
+ * only when cleared do we reset to defaults.
+ */
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_cflag = TTYDEF_CFLAG;
+ tp->t_lflag = TTYDEF_LFLAG;
+ tp->t_ispeed = tp->t_ospeed = bugttydefaultrate;
+ }
+ /* bugtty does not have carrier */
+ tp->t_cflag |= CLOCAL;
+ /*
+ * do these all the time
+ */
+ if (bugttyswflags & TIOCFLAG_CLOCAL)
+ tp->t_cflag |= CLOCAL;
+ if (bugttyswflags & TIOCFLAG_CRTSCTS)
+ tp->t_cflag |= CRTSCTS;
+ if (bugttyswflags & TIOCFLAG_MDMBUF)
+ tp->t_cflag |= MDMBUF;
+ bugttyparam(tp, &tp->t_termios);
+ ttsetwater(tp);
+
+ (void)bugttymctl(dev, TIOCM_DTR | TIOCM_RTS, DMSET);
+ /*
+ if ((SWFLAGS(dev) & TIOCFLAG_SOFTCAR) ||
+ (bugttymctl(dev, 0, DMGET) & TIOCM_CD))
+ tp->t_state |= TS_CARR_ON;
+ else
+ tp->t_state &= ~TS_CARR_ON;
+ */
+ tp->t_state |= TS_CARR_ON;
+ } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
+ splx(s);
+ return (EBUSY);
+ }
+
+ /*
+ * if NONBLOCK requested, ignore carrier
+ */
+/*
+ if (flag & O_NONBLOCK)
+ goto done;
+*/
+
+ splx(s);
+ /*
+ * Reset the tty pointer, as there could have been a dialout
+ * use of the tty with a dialin open waiting.
+ */
+ tp->t_dev = dev;
+ return ((*linesw[tp->t_line].l_open)(dev, tp));
+}
+
+int
+bugttyparam()
+{
+ return (0);
+}
+
+void
+bugttyoutput(tp)
+ struct tty *tp;
+{
+ int cc, s, unit, cnt ;
+
+ /* only supports one unit */
+
+ if ((tp->t_state & TS_ISOPEN) == 0)
+ return;
+
+ s = spltty();
+ cc = tp->t_outq.c_cc;
+ while (cc > 0) {
+ cnt = min(BUGBUF, cc);
+ cnt = q_to_b(&tp->t_outq, bug_obuffer, cnt);
+ bugoutstr(bug_obuffer, &bug_obuffer[cnt]);
+ cc -= cnt;
+ }
+ splx(s);
+}
+
+int
+bugttyclose(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ int unit = BUGTTYUNIT(dev);
+ struct tty *tp = bugtty_tty[unit];
+
+ (*linesw[tp->t_line].l_close)(tp, flag);
+
+ ttyclose(tp);
+#if 0
+ bugtty_tty[unit] = NULL;
+#endif
+ return (0);
+}
+
+int
+bugttyread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ struct tty *tp;
+
+ if ((tp = bugtty_tty[BUGTTYUNIT(dev)]) == NULL)
+ return (ENXIO);
+ return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
+}
+
+#if 1
+/* only to be called at splclk() */
+bugtty_chkinput()
+{
+ struct tty *tp;
+
+ tp = bugtty_tty[0]; /* Kinda ugly hack */
+ if (tp == NULL )
+ return;
+
+ if (buginstat()) {
+ while (buginstat()) {
+ u_char c = buginchr() & 0xff;
+ (*linesw[tp->t_line].l_rint)(c, tp);
+ }
+ /*
+ wakeup(tp);
+ */
+ }
+}
+#endif
+
+int
+bugttywrite(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+#if 0
+ /* bypass tty output routines. */
+ int i, cnt, s;
+ int oldoff;
+
+ s = spltty();
+ oldoff = uio->uio_offset;
+ do {
+ uiomove(bug_obuffer, BUGBUF, uio);
+ bugoutstr(bug_obuffer, &bug_obuffer[uio->uio_offset - oldoff]);
+ oldoff = uio->uio_offset;
+ } while (uio->uio_resid != 0);
+ splx(s);
+
+ return (0);
+#else
+ struct tty *tp;
+ if((tp = bugtty_tty[BUGTTYUNIT(dev)]) == NULL)
+ return (ENXIO);
+ return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
+#endif
+}
+
+int
+bugttyioctl(dev, cmd, data, flag, p)
+ dev_t dev;
+ int cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ int unit = BUGTTYUNIT(dev);
+ struct tty *tp = bugtty_tty[unit];
+ int error;
+
+ if (!tp)
+ return (ENXIO);
+
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
+ if (error >= 0)
+ return (error);
+
+ error = ttioctl(tp, cmd, data, flag, p);
+ if (error >= 0)
+ return (error);
+
+ switch (cmd) {
+ case TIOCSBRK:
+ /* */
+ break;
+
+ case TIOCCBRK:
+ /* */
+ break;
+
+ case TIOCSDTR:
+ (void) bugttymctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIS);
+ break;
+
+ case TIOCCDTR:
+ (void) bugttymctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIC);
+ break;
+
+ case TIOCMSET:
+ (void) bugttymctl(dev, *(int *) data, DMSET);
+ break;
+
+ case TIOCMBIS:
+ (void) bugttymctl(dev, *(int *) data, DMBIS);
+ break;
+
+ case TIOCMBIC:
+ (void) bugttymctl(dev, *(int *) data, DMBIC);
+ break;
+
+ case TIOCMGET:
+ *(int *)data = bugttymctl(dev, 0, DMGET);
+ break;
+ case TIOCGFLAGS:
+ *(int *)data = SWFLAGS(dev);
+ break;
+ case TIOCSFLAGS:
+ error = suser(p->p_ucred, &p->p_acflag);
+ if (error != 0)
+ return (EPERM);
+
+ bugttyswflags = *(int *)data;
+ bugttyswflags &= /* only allow valid flags */
+ (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS);
+ break;
+ default:
+ return (ENOTTY);
+ }
+
+ return (0);
+}
+
+int
+bugttystop(tp, flag)
+ struct tty *tp;
+ int flag;
+{
+ int s;
+
+ s = spltty();
+ if (tp->t_state & TS_BUSY) {
+ if ((tp->t_state & TS_TTSTOP) == 0)
+ tp->t_state |= TS_FLUSH;
+ }
+ splx(s);
+ return (0);
+}
+
+/*
+ * bugtty is the last possible choice for a console device.
+ */
+int
+bugttycnprobe(cp)
+ struct consdev *cp;
+{
+ int maj;
+ extern int needprom;
+
+ if (needprom == 0) {
+ cp->cn_pri = CN_DEAD;
+ return (0);
+ }
+
+#if 0
+ switch (cputyp) {
+ case CPU_147:
+ case CPU_162:
+ cp->cn_pri = CN_NORMAL;
+ return (0);
+ default:
+ break;
+ }
+#else
+ cp->cn_pri = CN_NORMAL;
+ return (0);
+#endif /* 0 */
+
+ /* locate the major number */
+ for (maj = 0; maj < nchrdev; maj++)
+ if (cdevsw[maj].d_open == bugttyopen)
+ break;
+
+ cp->cn_dev = makedev(maj, 0);
+ cp->cn_pri = CN_NORMAL;
+
+ return (1);
+}
+
+int
+bugttycninit(cp)
+ struct consdev *cp;
+{
+}
+
+int
+bugttycngetc(dev)
+ dev_t dev;
+{
+ return (buginchr());
+}
+
+int
+bugttycnputc(dev, c)
+ dev_t dev;
+ char c;
+{
+ if (c == '\n')
+ bugoutchr('\r');
+ bugoutchr(c);
+}
diff --git a/sys/arch/mvme88k/dev/clock.c b/sys/arch/mvme88k/dev/clock.c
new file mode 100644
index 00000000000..77b458f2526
--- /dev/null
+++ b/sys/arch/mvme88k/dev/clock.c
@@ -0,0 +1,109 @@
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <machine/board.h>
+#include <machine/bug.h>
+#include <machine/pcctworeg.h>
+
+extern u_int *pcc_io_base;
+extern const u_int timer_reload;
+void setstatclockrate (int hzrate)
+{
+}
+
+resettodr()
+{
+}
+
+int
+hexdectodec(unsigned char n)
+{
+
+ return(((n>>4)&0x0F)*10 + (n&0x0F));
+}
+
+#define STARTOFTIME 1970
+#define FEBRUARY 2
+#define leapyear(year) (((year)%4==0) && ((year)%100) != 0 || ((year)%400) == 0)
+#define days_in_year(year) (leapyear((year)) ? 366 : 365)
+#define days_in_month(a) (month_days[(a) - 1])
+
+static int month_days[12] = {
+ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+
+inittodr(time_t base)
+{
+ struct bugrtc rtc;
+ u_long sec, min, hour, day, month, year;
+ u_long i, tmp, timebuf;
+
+ /* ignore suggested time, use realtime clock via bug */
+ bugrtcrd(&rtc);
+ sec = hexdectodec(rtc.s);
+ min = hexdectodec(rtc.m);
+ hour = hexdectodec(rtc.H);
+ day = hexdectodec(rtc.D);
+ month = hexdectodec(rtc.M);
+ year = hexdectodec(rtc.Y) + 1900;
+
+ tmp = 0;
+ for (i = STARTOFTIME; i < year; i++) {
+ tmp += days_in_year(i);
+ }
+ for (i = 1; i < month; i++) {
+ tmp += days_in_month(i);
+ }
+ if (leapyear(year) && month > FEBRUARY) {
+ tmp++;
+ }
+ printf("date yy mm dd hh mm.ss:%02d %02d %02d %02d %02d.%02d:",
+ year,month,day,hour,min, sec);
+ tmp += (day -1);
+ timebuf = (((tmp * 24 + hour) * 60 + min) * 60 + sec);
+ printf(" epochsec %d\n",timebuf);
+ time.tv_sec = timebuf;
+ time.tv_usec = 0;
+}
+
+clkread()
+{
+}
+
+cpu_initclocks()
+{
+#if 0
+ u_int *io_base;
+ io_base = 0xfffe1000; /* should really be return of virtmem alloc */
+ /*
+ io_base = pcc_io_base;
+ */
+ /* timer 2 setup */
+ PCC_TIMER2_PRE(io_base) = timer_reload;
+ PCC_TIMER2_CTR(io_base) = 0x7;
+ PCC_TIMER2_ICR(io_base) = 0x8e;
+#endif
+}
+
+/*
+ * Clock interrupts.
+ */
+int
+clockintr(cap)
+ void *cap;
+{
+#if 0
+ volatile register unsigned char icr;
+ /* clear clock interrupt */
+ asm ("ld.b %0,%1" : "=r" (icr) : "" (TIMER2ICR));
+ icr |= ICLR;
+ asm ("st.b %0,%1" : "=r" (icr) : "" (TIMER2ICR));
+
+ /* read the limit register to clear the interrupt */
+#endif /* 0 */
+ hardclock((struct clockframe *)cap);
+
+ return (1);
+}
diff --git a/sys/arch/mvme88k/dev/m88k/bugio.c b/sys/arch/mvme88k/dev/m88k/bugio.c
new file mode 100644
index 00000000000..932614a29d5
--- /dev/null
+++ b/sys/arch/mvme88k/dev/m88k/bugio.c
@@ -0,0 +1,108 @@
+#include <machine/bugio.h>
+
+#define INCHR "0x0000"
+#define INSTAT "0x0001"
+#define INLN "0x0002"
+#define READSTR "0x0003"
+#define READLN "0x0004"
+#define DSKRD "0x0010"
+#define DSKWR "0x0011"
+#define DSKCFIG "0x0012"
+#define OUTCHR "0x0020"
+#define OUTSTR "0x0021"
+#define PCRLF "0x0026"
+#define TMDISP "0x0042"
+#define DELAY "0x0043"
+#define RTC_DSP "0x0052"
+#define RTC_RD "0x0053"
+#define RETURN "0x0063"
+#define BRD_ID "0x0070"
+#define BUGTRAP "0x01F0"
+
+char
+buginchr(void)
+{
+ register int cc asm("r2");
+ asm("or r9,r0," INCHR);
+ asm("tb0 0,r0,0x1F0");
+ /*asm("or %0,r0,r2" : "=r" (cc) : );*/
+ return ((char)cc & 0xFF);
+}
+
+/* return 1 if not empty else 0 */
+
+buginstat(void)
+{
+ int ret;
+ asm("or r9,r0," INSTAT);
+ asm("tb0 0,r0,0x1F0");
+ asm("or %0,r0,r2" : "=r" (ret) : );
+ return (ret & 0x40 ? 1 : 0);
+}
+
+bugoutchr(unsigned char c)
+{
+ unsigned char cc;
+
+ if ((cc = c) == '\n') {
+ bugpcrlf();
+ return;
+ }
+ asm("or r2,r0,%0" : : "r" (cc));
+ asm("or r9,r0," OUTCHR);
+ asm("tb0 0,r0,0x1F0");
+}
+
+bugoutstr(char *s, char *se)
+{
+ asm("or r9,r0," OUTSTR);
+ asm("tb0 0,r0,0x1F0");
+}
+
+bugpcrlf(void)
+{
+ asm("or r9,r0," PCRLF);
+ asm("tb0 0,r0,0x1F0");
+}
+/* return 0 on success */
+
+bugdskrd(struct bugdisk_io *arg)
+{
+ int ret;
+ asm("or r9,r0, " DSKRD);
+ asm("tb0 0,r0,0x1F0");
+ asm("or %0,r0,r2" : "=r" (ret) : );
+ return ((ret&0x4) == 0x4 ? 1 : 0);
+}
+
+/* return 0 on success */
+
+bugdskwr(struct bugdisk_io *arg)
+{
+ int ret;
+ asm("or r9,r0, " DSKWR);
+ asm("tb0 0,r0,0x1F0");
+ asm("or %0,r0,r2" : "=r" (ret) : );
+ return ((ret&0x4) == 0x4 ? 1 : 0);
+}
+
+bugrtcrd(struct bugrtc *rtc)
+{
+ asm("or r9,r0, " RTC_RD);
+ asm("tb0 0,r0,0x1F0");
+}
+
+bugreturn(void)
+{
+ asm("or r9,r0, " RETURN);
+ asm("tb0 0,r0,0x1F0");
+}
+
+bugbrdid(struct bugbrdid *id)
+{
+ struct bugbrdid *ptr;
+ asm("or r9,r0, " BRD_ID);
+ asm("tb0 0,r0,0x1F0");
+ asm("or %0,r0,r2" : "=r" (ptr) : );
+ bcopy(ptr, id, sizeof(struct bugbrdid));
+}
diff --git a/sys/arch/mvme88k/dev/mb.c b/sys/arch/mvme88k/dev/mb.c
new file mode 100644
index 00000000000..2cf934de61f
--- /dev/null
+++ b/sys/arch/mvme88k/dev/mb.c
@@ -0,0 +1,87 @@
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/reboot.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/disklabel.h>
+#include <machine/cpu.h>
+
+void mbattach __P((struct device *, struct device *, void *));
+int mbprint __P((void *, char *));
+int mbmatch __P((struct device *, struct cfdata *, void *));
+int submatch( struct device *parent, struct cfdata *self, void *aux);
+
+/*
+ * mainbus driver
+ */
+struct cfdriver mainbuscd = {
+ NULL, "mainbus", mbmatch, mbattach,
+ DV_DULL, sizeof(struct device), NULL, 0
+};
+
+int
+mbmatch(pdp, cfp, auxp)
+ struct device *pdp;
+ struct cfdata *cfp;
+ void *auxp;
+{
+ if (cfp->cf_unit > 0)
+ return(0);
+ /*
+ * We are always here
+ */
+ return(1);
+}
+/*
+ * "find" all the things that should be there.
+ */
+void
+mbattach(pdp, dp, auxp)
+ struct device *pdp, *dp;
+ void *auxp;
+{
+ struct cfdata *cf;
+ extern int machineid;
+
+ /* nothing to do for this bus */
+ printf (" machine type %x\n", machineid);
+
+ if ((cf = config_search(submatch, dp, auxp)) != NULL) {
+ return;
+ }
+
+}
+
+mbprint(auxp, pnp)
+ void *auxp;
+ char *pnp;
+{
+ if (pnp)
+ printf("%s at %s", (char *)auxp, pnp);
+ return(UNCONF);
+}
+
+int
+submatch(parent, self, aux)
+ struct device *parent;
+ struct cfdata *self;
+ void *aux;
+{
+ if (!(*self->cf_driver->cd_match)(parent, self, NULL)) {
+ /*
+ * STOLEN - BE CAREFUL
+ * If we don't do this, isa_configure() will repeatedly try to
+ * probe devices that weren't found. But we need to be careful
+ * to do it only for the ISA bus, or we would cause things like
+ * `com0 at ast? slave ?' to not probe on the second ast.
+ */
+ if (!parent)
+ self->cf_fstate = FSTATE_FOUND;
+
+ return 0;
+ }
+
+ config_attach(parent, self, NULL, mbprint);
+
+ return 1;
+}
diff --git a/sys/arch/mvme88k/dev/pcc2.c b/sys/arch/mvme88k/dev/pcc2.c
new file mode 100644
index 00000000000..c78cbb24a81
--- /dev/null
+++ b/sys/arch/mvme88k/dev/pcc2.c
@@ -0,0 +1,253 @@
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <machine/cpu.h>
+#include <machine/pcc2.h>
+
+int m1x7pccprobe(struct device *parent, struct cfdata *self, void *aux);
+void m1x7pccattach(struct device *parent, struct device *self, void *aux);
+
+int abort_handler();
+extern void abort_intrv();
+extern void pcc_intrv();
+extern int intrh_debug;
+extern int machineid;
+extern void badtrap();
+extern int submatch( struct device *parent, struct cfdata *self, void *aux);
+/* static */ u_int *pcc_io_base;
+static u_int *pcc_vector_base;
+
+static void abort_setup();
+void timer2_intr();
+
+struct pcctwosoftc {
+ struct device sc_dev;
+ caddr_t sc_vaddr;
+ caddr_t sc_paddr;
+ struct pcctworeg *sc_pcc2;
+};
+
+void pcctwoattach __P((struct device *, struct device *, void *));
+int pcctwoprobe __P((struct device *, void *, void *));
+int pcctwoabort __P((struct frame *));
+
+struct cfdriver pcctwocd = {
+ NULL, "pcctwo", pcctwomatch, pcctwoattach,
+ DV_DULL, sizeof(struct pcctwosoftc), 0
+};
+
+struct pcctworeg *sys_pcc2 = NULL;
+
+int
+pcctwomatch(struct device *parent, struct cfdata *self, void *aux)
+{
+#if defined(__m88k__)
+ if (machineid == 0x187) {
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+void
+pcctwoattach(struct device *parent, struct device *self, void *aux)
+{
+ struct cfdata *cf;
+ volatile char *ibvr; /* Interrupt Base Vector Register */
+ u_int ibv; /* Interrupt Base Vector, offset from vbr */
+ u_int *iv; /* interupt vector */
+ int i;
+ u_int vector_base;
+
+ /* attach memory mapped io space */
+ /* map 0xfffe1000 - 0xfffe102f, 0xfffe2800 */
+ /* ppc_io_base = mmio(0xfffe1000, 1800, PG_RW|PG_CI); */
+ pcc_io_base = 0xfffe1000; /* should really be return of virtmem alloc */
+ /* set PCC vector base */
+ ibv = PCC_IBVR(pcc_io_base) & 0xf0;
+ ibvr = &PCC_IBVR(pcc_io_base);
+ printf("pcc:ibvr %x *ibvr %x ibv %x\n",ibvr,*ibvr, ibv);
+ pcc_vector_base = (u_int *)ibv;
+ asm volatile ("movec vbr,%0": "=d" (vector_base));
+ printf("pcc:vector_base %x\n",vector_base);
+ /* register "standard interupt handlers */
+
+ abort_setup();
+ iv = (u_int *)(vector_base + (ibv * 4));
+printf("iv %x\n",iv);
+ for (i = 0; i <= SOFT2_VECTOR; i++) {
+ iv[i] = (u_int)pcc_intrv;
+ }
+ /*
+ timer2_setup();
+ */
+ iv = (u_int *)(vector_base + (ibv + TICK2_VECTOR) * 4);
+ *iv = (u_int)&pcc_intrv;
+
+#ifdef DEBUG
+ if (intrh_debug)
+ pr_intrh();
+#endif
+ if ((cf = config_search(submatch, self, aux)) != NULL) {
+ return;
+ }
+ return ;
+}
+asm (" .text");
+asm (" .global _pcc_intrv");
+asm ("_pcc_intrv:");
+asm (" link a6,#0");
+asm (" movml a0/a1/d0/d1,sp@-");
+asm (" movel a6,a0");
+asm (" addql #4,a0");
+asm (" movel a0,sp@-");
+asm (" jbsr _pcc_handler");
+asm (" addql #4,sp");
+asm (" movml sp@+,a0/a1/d0/d1");
+asm (" unlk a6");
+asm (" jra rei");
+
+asm (" .global _abort_intrv");
+asm ("_abort_intrv:");
+asm (" movml a0/a1/d0/d1,sp@-");
+asm (" jbsr _abort_handler");
+asm (" movml sp@+,a0/a1/d0/d1");
+asm (" jra rei");
+/* asm (" .previous"); */
+
+void *m147le_arg;
+void
+pcc_handler(struct exception_frame *except)
+{
+ u_int vector;
+ int handled = 0;
+
+#if 0
+ printf("except %x\n",except);
+ printf("sr %x\n",except->sr);
+ printf("pc %x\n",except->pc);
+ printf("type %x\n",except->type);
+#endif
+ vector = except->vo;
+/* printf("vector %x\n",vector); */
+ vector = (vector/4 - (u_int)pcc_vector_base);
+/* printf("vector %x\n",vector); */
+
+ switch (vector) {
+ case AC_FAIL_VECTOR:
+ printf("ac_fail vector\n");
+ break;
+ case BERR_VECTOR:
+ printf("berr vector\n");
+ printf("pcc_handler:invalid vector %x\n",vector);
+ break;
+ case ABORT_VECTOR:
+ printf("abort vector\n");
+ abort_handler();
+ handled = 1;
+ break;
+ case SERIAL_VECTOR:
+ printf("serial vector\n");
+ PCC_SERIAL_ICR(0xfffe1000) = 0;
+ break;
+ case LANCE_VECTOR:
+ leintr(m147le_arg);
+ handled = 1;
+ break;
+ case SCSIPORT_VECTOR:
+ printf("scsiport vector\n");
+ m147sc_scintr();
+ break;
+ case SCSIDMA_VECTOR:
+ printf("scsidma vector\n");
+ m147sc_dmaintr();
+ break;
+ case PRINTER_VECTOR:
+ printf("printer vector\n");
+ break;
+ case TICK1_VECTOR:
+ printf("tick1 vector\n");
+ printf("pcc_handler:invalid vector %x\n",vector);
+ break;
+ case TICK2_VECTOR:
+ timer2_intr(except);
+ handled = 1;
+ break;
+ case SOFT1_VECTOR:
+ printf("soft1 vector\n");
+ break;
+ case SOFT2_VECTOR:
+ printf("soft2 vector\n");
+ break;
+ default:
+ printf("pcc_handler:invalid vector %x\n",vector);
+ }
+
+ if (handled == 0) {
+ printf("except %x\n",except);
+ printf("sr %x\n",except->sr);
+ printf("pc %x\n",except->pc);
+ printf("type %x\n",except->type);
+ }
+}
+
+
+int
+abort_handler()
+{
+ printf("aicr = 0x%x\n",PCC_ABRT_ICR(pcc_io_base));
+ PCC_ABRT_ICR(pcc_io_base) = 0x88;
+ printf("aicr = 0x%x\n",PCC_ABRT_ICR(pcc_io_base));
+ Debugger();
+ return 0;
+}
+static void abort_setup()
+{
+ printf("PCC_ABRT_ICR %x\n",&PCC_ABRT_ICR(pcc_io_base));
+ printf("aicr = 0x%x\n",PCC_ABRT_ICR(pcc_io_base));
+ PCC_ABRT_ICR(pcc_io_base) = 0x88;
+ printf("aicr = 0x%x\n",PCC_ABRT_ICR(pcc_io_base));
+}
+
+/* timer2 (clock) driver */
+
+/*const u_int timer_reload = 0; /* .4096 sec ? */
+/* const u_int timer_reload = 62870; 1/60 sec ? */
+const u_int timer_reload = 63936; /* 1/100 sec ? */
+
+#if 0
+void
+timer2_setup()
+{
+ u_int *io_base;
+ pcc_io_base = 0xfffe1000; /* should really be return of virtmem alloc */
+ io_base = pcc_io_base;
+ printf("pcc_io_base %x io_base %x\n",pcc_io_base, io_base);
+ printf("PCC_TIMER2_PRE %x\n",&PCC_TIMER2_PRE(io_base));
+ printf("PCC_TIMER2_CTR %x\n",&PCC_TIMER2_CTR(io_base));
+ printf("PCC_TIMER2_ICR %x\n",&PCC_TIMER2_ICR(io_base));
+ PCC_TIMER2_PRE(io_base) = timer_reload;
+ PCC_TIMER2_CTR(io_base) = 0x7;
+ PCC_TIMER2_ICR(io_base) = 0x8e;
+}
+#endif
+void
+timer2_intr(struct exception_frame *except)
+{
+ u_int *io_base;
+ pcc_io_base = 0xfffe1000; /* should really be return of virtmem alloc */
+ io_base = pcc_io_base;
+
+ if (0x80 && PCC_TIMER2_ICR(io_base)) {
+ PCC_TIMER2_ICR(io_base) = 0x8e;
+ /* hardclock(); */
+ hardclock(except);
+
+ } else {
+ printf("timer2_intr: vector called without interrupt\n");
+ }
+ /* REALLY UGLY HACK */
+ bugtty_chkinput();
+
+ return;
+}
diff --git a/sys/arch/mvme88k/dev/pcctwo.c b/sys/arch/mvme88k/dev/pcctwo.c
new file mode 100644
index 00000000000..be4fc02be6a
--- /dev/null
+++ b/sys/arch/mvme88k/dev/pcctwo.c
@@ -0,0 +1,252 @@
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 1995 Theo de Raadt
+ * All rights reserved.
+ *
+ * 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 Theo de Raadt
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+/*
+ * VME16x PCC2 chip
+ */
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/ioctl.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/tty.h>
+#include <sys/uio.h>
+#include <sys/callout.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/syslog.h>
+#include <sys/fcntl.h>
+#include <sys/device.h>
+#include <machine/cpu.h>
+#include <machine/autoconf.h>
+#include <dev/cons.h>
+#include <mvme68k/mvme68k/isr.h>
+
+#include <mvme68k/dev/pcctworeg.h>
+
+struct pcctwosoftc {
+ struct device sc_dev;
+ caddr_t sc_vaddr;
+ caddr_t sc_paddr;
+ struct pcctworeg *sc_pcc2;
+ struct intrhand sc_nmiih;
+};
+
+void pcctwoattach __P((struct device *, struct device *, void *));
+int pcctwomatch __P((struct device *, void *, void *));
+int pcctwoabort __P((struct frame *));
+
+struct cfdriver pcctwocd = {
+ NULL, "pcctwo", pcctwomatch, pcctwoattach,
+ DV_DULL, sizeof(struct pcctwosoftc), 0
+};
+
+struct pcctworeg *sys_pcc2 = NULL;
+
+struct intrhand *pcctwointrs[PCC2_NVEC];
+
+int
+pcctwomatch(parent, vcf, args)
+ struct device *parent;
+ void *vcf, *args;
+{
+ struct cfdata *cf = vcf;
+ struct confargs *ca = args;
+ struct pcctworeg *pcc2;
+
+ /* the PCC2 only exists on MVME16x's except the 162, right? */
+ if (cputyp == CPU_162 || cputyp == CPU_147)
+ return (0);
+ pcc2 = (struct pcctworeg *)(IIOV(ca->ca_paddr) + PCC2_PCC2CHIP_OFF);
+ if (badbaddr(pcc2))
+ return (0);
+ if (pcc2->pcc2_chipid != PCC2_CHIPID)
+ return (0);
+ return (1);
+}
+
+int
+pcctwo_print(args, bus)
+ void *args;
+ char *bus;
+{
+ struct confargs *ca = args;
+
+ printf(" offset 0x%x", ca->ca_offset);
+ if (ca->ca_ipl > 0)
+ printf(" ipl %d", ca->ca_ipl);
+ return (UNCONF);
+}
+
+int
+pcctwo_scan(parent, child, args)
+ struct device *parent;
+ void *child, *args;
+{
+ struct cfdata *cf = child;
+ struct pcctwosoftc *sc = (struct pcctwosoftc *)parent;
+ struct confargs *ca = args;
+ struct confargs oca;
+
+ if (parent->dv_cfdata->cf_driver->cd_indirect) {
+ printf(" indirect devices not supported\n");
+ return 0;
+ }
+
+ bzero(&oca, sizeof oca);
+ oca.ca_paddr = sc->sc_paddr + cf->cf_loc[0];
+ if (ISIIOVA(sc->sc_vaddr + cf->cf_loc[0]))
+ oca.ca_vaddr = sc->sc_vaddr + cf->cf_loc[0];
+ else
+ oca.ca_vaddr = (caddr_t)-1;
+ oca.ca_offset = cf->cf_loc[0];
+ oca.ca_ipl = cf->cf_loc[1];
+ oca.ca_bustype = BUS_PCCTWO;
+ oca.ca_master = (void *)sc->sc_pcc2;
+ oca.ca_name = cf->cf_driver->cd_name;
+ if ((*cf->cf_driver->cd_match)(parent, cf, &oca) == 0)
+ return (0);
+ config_attach(parent, cf, &oca, pcctwo_print);
+ return (1);
+}
+
+void
+pcctwoattach(parent, self, args)
+ struct device *parent, *self;
+ void *args;
+{
+ struct confargs *ca = args;
+ struct pcctwosoftc *sc = (struct pcctwosoftc *)self;
+ extern u_long vectab[], pcctwotrap;
+ int i;
+
+ if (sys_pcc2)
+ panic("pcc2 already attached!");
+
+ /*
+ * since we know ourself to land in intiobase land,
+ * we must adjust our address
+ */
+ sc->sc_paddr = ca->ca_paddr;
+ sc->sc_vaddr = (caddr_t)IIOV(sc->sc_paddr);
+ sc->sc_pcc2 = (struct pcctworeg *)(sc->sc_vaddr + PCC2_PCC2CHIP_OFF);
+ sys_pcc2 = sc->sc_pcc2;
+
+ printf(": rev %d\n", sc->sc_pcc2->pcc2_chiprev);
+
+ /*
+ * make the PCCTWO interrupt range point to the pcc2 trap routine.
+ */
+ for (i = 0; i < PCC2_NVEC; i++) {
+ vectab[PCC2_VECBASE+i] = (u_long)&pcctwotrap;
+ }
+
+ sc->sc_pcc2->pcc2_genctl |= PCC2_GENCTL_IEN; /* global irq enable */
+
+ sys_pcc2->pcc2_gpioirq = PCC2_GPIO_PLTY | PCC2_IRQ_IEN | 0x7;/*lvl7*/
+ sys_pcc2->pcc2_gpio = 0; /* do not turn on CR_O or CR_OE */
+ sc->sc_nmiih.ih_fn = pcctwoabort;
+ sc->sc_nmiih.ih_arg = 0;
+ sc->sc_nmiih.ih_lvl = 7;
+ sc->sc_nmiih.ih_wantframe = 1;
+ /*sc->sc_mc->mc_abort .... enable at ipl 7 */
+ pcctwointr_establish(PCC2V_GPIO, &sc->sc_nmiih);
+
+ sc->sc_pcc2->pcc2_vecbase = PCC2_VECBASE;
+ config_search(pcctwo_scan, self, args);
+}
+
+#ifndef PCCTWOINTR_ASM
+/*
+ * pcctwointr: called from locore with the PC and evec from the trap frame.
+ */
+int
+pcctwointr(pc, evec, frame)
+ int pc;
+ int evec;
+ void *frame;
+{
+ int vec = (evec & 0xfff) >> 2; /* XXX should be m68k macro? */
+ extern u_long intrcnt[]; /* XXX from locore */
+ struct intrhand *ih;
+ int r;
+
+ vec = vec & 0xf;
+ if (vec >= PCC2_NVEC)
+ goto bail;
+
+ cnt.v_intr++;
+ for (ih = pcctwointrs[vec]; ih; ih = ih->ih_next) {
+ if (ih->ih_wantframe)
+ r = (*ih->ih_fn)(frame);
+ else
+ r = (*ih->ih_fn)(ih->ih_arg);
+ if (r > 0)
+ return;
+ }
+bail:
+ return (straytrap(pc, evec));
+}
+#endif /* !PCCTWOINTR_ASM */
+
+/*
+ * pcctwointr_establish: establish pcctwo interrupt
+ */
+int
+pcctwointr_establish(vec, ih)
+ int vec;
+ struct intrhand *ih;
+{
+ if (vec >= PCC2_NVEC) {
+ printf("pcctwo: illegal vector: 0x%x\n", vec);
+ panic("pcctwointr_establish");
+ }
+
+ /* XXX should attach at tail */
+ ih->ih_next = pcctwointrs[vec];
+ pcctwointrs[vec] = ih;
+}
+int
+pcctwoabort(frame)
+ struct frame *frame;
+{
+#ifdef REALLY_CARE_ABOUT_DEBOUNCE
+ /* wait for it to debounce */
+ while (sys_pcc2->pcc2_abortirq & PCC2_ABORT_ABS)
+ ;
+#endif
+
+ sys_pcc2->pcc2_gpioirq = sys_pcc2->pcc2_gpioirq | PCC2_IRQ_ICLR;
+
+ nmihand(frame);
+ return (1);
+}