summaryrefslogtreecommitdiff
path: root/sys/arch/mvmeppc/dev
diff options
context:
space:
mode:
authorSteve Murphree <smurph@cvs.openbsd.org>2001-06-26 21:58:11 +0000
committerSteve Murphree <smurph@cvs.openbsd.org>2001-06-26 21:58:11 +0000
commit416f561c78b0eca90fdb484e72a96080b0825dca (patch)
treed310db0254b85229b90b9d90e79cabfbbcb6101a /sys/arch/mvmeppc/dev
parent77682e0d8d22531ed2952aaab30aae7c69483b3d (diff)
Initial import of mvmeppc.
Diffstat (limited to 'sys/arch/mvmeppc/dev')
-rw-r--r--sys/arch/mvmeppc/dev/bugio.c482
-rw-r--r--sys/arch/mvmeppc/dev/bugtty.c492
-rw-r--r--sys/arch/mvmeppc/dev/clock.c397
-rw-r--r--sys/arch/mvmeppc/dev/cpu.c267
-rw-r--r--sys/arch/mvmeppc/dev/mainbus.c159
-rw-r--r--sys/arch/mvmeppc/dev/mem.c176
-rw-r--r--sys/arch/mvmeppc/dev/nvramreg.h86
-rw-r--r--sys/arch/mvmeppc/dev/openpic.c1035
-rw-r--r--sys/arch/mvmeppc/dev/openpicreg.h90
-rw-r--r--sys/arch/mvmeppc/dev/raven.c99
-rw-r--r--sys/arch/mvmeppc/dev/ravenreg.h123
-rw-r--r--sys/arch/mvmeppc/dev/ravenvar.h387
12 files changed, 3793 insertions, 0 deletions
diff --git a/sys/arch/mvmeppc/dev/bugio.c b/sys/arch/mvmeppc/dev/bugio.c
new file mode 100644
index 00000000000..f526c8a3a9e
--- /dev/null
+++ b/sys/arch/mvmeppc/dev/bugio.c
@@ -0,0 +1,482 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <machine/prom.h>
+
+
+/* BUG - timing routine */
+void
+mvmeprom_delay(msec)
+ int msec; /* This is r3 */
+{
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+ asm volatile ("mr 3, %0" :: "r"(msec));
+ MVMEPROM_CALL(MVMEPROM_DELAY);
+ ppc_set_msr(omsr);
+}
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_diskrd(arg)
+ struct mvmeprom_dskio *arg;
+{
+ int ret;
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+
+ asm volatile ("mr 3, %0" :: "r"(arg));
+ MVMEPROM_CALL(MVMEPROM_NETRD);
+ asm volatile ("mr %0, 3" : "=r" (ret));
+ ppc_set_msr(omsr);
+ return ((ret & 0x8));
+}
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_diskwr(arg)
+ struct mvmeprom_dskio *arg;
+{
+ int ret;
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+
+ asm volatile ("mr 3, %0" :: "r"(arg));
+ MVMEPROM_CALL(MVMEPROM_DSKWR);
+ asm volatile ("mr %0, 3" : "=r" (ret));
+ ppc_set_msr(omsr);
+ return ((ret & 0x8));
+}
+
+/* BUG - query board routines */
+struct mvmeprom_brdid *
+mvmeprom_brdid()
+{
+ struct mvmeprom_brdid *id;
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+
+ MVMEPROM_CALL(MVMEPROM_BRD_ID);
+ asm volatile ("mr %0, 3": "=r" (id):);
+ ppc_set_msr(omsr);
+ return (id);
+}
+
+/* returns 0 if no characters ready to read */
+int
+mvmeprom_getchar()
+{
+ int ret;
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+
+ MVMEPROM_CALL(MVMEPROM_INCHR);
+ asm volatile ("mr %0, 3" : "=r" (ret));
+ ppc_set_msr(omsr);
+ return ret;
+}
+
+/* returns 0 if no characters ready to read */
+int
+mvmeprom_instat()
+{
+ int ret;
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+
+ MVMEPROM_CALL(MVMEPROM_INSTAT);
+ asm volatile ("mr %0, 3" : "=r" (ret));
+ ppc_set_msr(omsr);
+ return (!(ret & 0x4));
+}
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_netctrl(arg)
+ struct mvmeprom_netctrl *arg;
+{
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+ asm volatile ("mr 3, %0":: "r" (arg));
+ MVMEPROM_CALL(MVMEPROM_NETCTRL);
+ ppc_set_msr(omsr);
+ return (arg->status);
+}
+
+int
+mvmeprom_netctrl_init(clun, dlun)
+u_char clun;
+u_char dlun;
+{
+ struct mvmeprom_netctrl niocall;
+ niocall.clun = clun;
+ niocall.dlun = dlun;
+ niocall.status = 0;
+ niocall.cmd = 0; /* init */
+ niocall.addr = 0;
+ niocall.len = 0;
+ niocall.flags = 0;
+ mvmeprom_netctrl(&niocall);
+ return(niocall.status);
+}
+
+int
+mvmeprom_netctrl_hwa(clun, dlun, addr, len)
+u_char clun;
+u_char dlun;
+void *addr;
+u_long *len;
+{
+ struct mvmeprom_netctrl niocall;
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+ niocall.clun = clun;
+ niocall.dlun = dlun;
+ niocall.status = 0;
+ niocall.cmd = 1; /* get hw address */
+ niocall.addr = addr;
+ niocall.len = *len;
+ niocall.flags = 0;
+ mvmeprom_netctrl(&niocall);
+ *len = niocall.len;
+ return(niocall.status);
+}
+
+int
+mvmeprom_netctrl_tx(clun, dlun, addr, len)
+u_char clun;
+u_char dlun;
+void *addr;
+u_long *len;
+{
+ struct mvmeprom_netctrl niocall;
+ niocall.clun = clun;
+ niocall.dlun = dlun;
+ niocall.status = 0;
+ niocall.cmd = 2; /* transmit */
+ niocall.addr = addr;
+ niocall.len = *len;
+ niocall.flags = 0;
+ mvmeprom_netctrl(&niocall);
+ *len = niocall.len;
+ return(niocall.status);
+}
+
+int
+mvmeprom_netctrl_rx(clun, dlun, addr, len)
+u_char clun;
+u_char dlun;
+void *addr;
+u_long *len;
+{
+ struct mvmeprom_netctrl niocall;
+ niocall.clun = clun;
+ niocall.dlun = dlun;
+ niocall.status = 0;
+ niocall.cmd = 3; /* receive */
+ niocall.addr = addr;
+ niocall.len = *len;
+ niocall.flags = 0;
+ mvmeprom_netctrl(&niocall);
+ *len = niocall.len;
+ return(niocall.status);
+}
+
+int
+mvmeprom_netctrl_flush_rx(clun, dlun)
+u_char clun;
+u_char dlun;
+{
+ struct mvmeprom_netctrl niocall;
+ niocall.clun = clun;
+ niocall.dlun = dlun;
+ niocall.status = 0;
+ niocall.cmd = 4; /* reset */
+ niocall.addr = 0;
+ niocall.len = 0;
+ niocall.flags = 0;
+ mvmeprom_netctrl(&niocall);
+ return(niocall.status);
+}
+
+int
+mvmeprom_netctrl_reset(clun, dlun)
+u_char clun;
+u_char dlun;
+{
+ struct mvmeprom_netctrl niocall;
+ niocall.clun = clun;
+ niocall.dlun = dlun;
+ niocall.status = 0;
+ niocall.cmd = 5; /* reset */
+ niocall.addr = 0;
+ niocall.len = 0;
+ niocall.flags = 0;
+ mvmeprom_netctrl(&niocall);
+ return(niocall.status);
+}
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_netfopen(arg)
+ struct mvmeprom_netfopen *arg;
+{
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+ asm volatile ("mr 3, %0": : "r" (arg));
+ MVMEPROM_CALL(MVMEPROM_NETFOPEN);
+ ppc_set_msr(omsr);
+ return (arg->status);
+}
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_netfread(arg)
+ struct mvmeprom_netfread *arg;
+{
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+ asm volatile ("mr 3, %0": : "r" (arg));
+ MVMEPROM_CALL(MVMEPROM_NETFREAD);
+ ppc_set_msr(omsr);
+ return (arg->status);
+}
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_netrd(arg)
+ struct mvmeprom_netio *arg;
+{
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+ asm volatile ("mr 3, %0": : "r" (arg));
+ MVMEPROM_CALL(MVMEPROM_NETRD);
+ ppc_set_msr(omsr);
+ return (arg->status);
+}
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_netwr(arg)
+ struct mvmeprom_netio *arg;
+{
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+ asm volatile ("mr 3, %0": : "r" (arg));
+ MVMEPROM_CALL(MVMEPROM_NETWR);
+ ppc_set_msr(omsr);
+ return (arg->status);
+}
+
+void
+mvmeprom_outln(start, end)
+ char *start, *end;
+{
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+ asm volatile ("mr 3, %0": : "r" (start));
+ asm volatile ("mr 4, %0": : "r" (end));
+ MVMEPROM_CALL(MVMEPROM_OUTLN);
+ ppc_set_msr(omsr);
+}
+
+void
+mvmeprom_outstr(start, end)
+ char *start, *end;
+{
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+ asm volatile ("mr 3, %0": : "r" (start));
+ asm volatile ("mr 4, %0": : "r" (end));
+ MVMEPROM_CALL(MVMEPROM_OUTSTR);
+ ppc_set_msr(omsr);
+}
+
+void
+mvmeprom_outchar(c)
+ int c;
+{
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+ asm volatile ("mr 3, %0" :: "r" (c));
+ MVMEPROM_CALL(MVMEPROM_OUTCHR);
+ ppc_set_msr(omsr);
+}
+
+/* BUG - return to bug routine */
+void
+mvmeprom_return()
+{
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+ MVMEPROM_CALL(MVMEPROM_RETURN);
+ ppc_set_msr(omsr);
+ /*NOTREACHED*/
+}
+
+
+void
+mvmeprom_rtc_rd(ptime)
+ struct mvmeprom_time *ptime;
+{
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+ asm volatile ("mr 3, %0": : "r" (ptime));
+ MVMEPROM_CALL(MVMEPROM_RTC_RD);
+ ppc_set_msr(omsr);
+}
+
+int
+bugenvsz(void)
+{
+ register int ret;
+ char tmp[1];
+ void *ptr = tmp;
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+
+ asm volatile ("mr 3, %0": : "r" (ptr));
+ asm volatile ("li 5, 0x1");
+ asm volatile ("li 5, 0x0"); /* get size */
+ MVMEPROM_CALL(MVMEPROM_ENVIRON);
+ asm volatile ("mr %0, 3" : "=r" (ret));
+ ppc_set_msr(omsr);
+
+ return(ret);
+}
+
+struct bugenviron bugenviron;
+int bugenv_init = 0;
+char bugenv_buf[1024];
+
+#ifdef BUG_DEBUG
+void bug_printenv(void);
+
+void
+bug_printenv(void)
+{
+ printf("Startup Mode: %c\n", bugenviron.s.s_mode);
+ printf("Startup Menu: %c\n", bugenviron.s.s_menu);
+ printf("Remote Start: %c\n", bugenviron.s.s_remotestart);
+ printf("Probe Devs: %c\n", bugenviron.s.s_probe);
+ printf("Negate Sysfail: %c\n", bugenviron.s.s_negsysfail);
+ printf("Reset SCSI Bus: %c\n", bugenviron.s.s_resetscsi);
+ printf("Ignore CFNA Block: %c\n", bugenviron.s.s_nocfblk);
+ printf("SCSI sync method: %c\n", bugenviron.s.s_scsisync);
+
+ printf("Auto Boot Enable: %c\n", bugenviron.b.b_enable);
+ printf("Auto Boot on power-up Only: %c\n", bugenviron.b.b_poweruponly);
+ printf("Auto Boot CLUN: %02x\n", bugenviron.b.b_clun);
+ printf("Auto Boot DLUN: %02x\n", bugenviron.b.b_dlun);
+ printf("Auto Boot Delay: %02x\n", bugenviron.b.b_delay);
+ printf("Auto Boot String: %s\n", bugenviron.b.b_string);
+
+ printf("ROM Boot Enable: %c\n", bugenviron.r.r_enable);
+ printf("ROM Boot on power-up Only: %c\n", bugenviron.r.r_poweruponly);
+ printf("ROM Boot Scan VME bus: %c\n", bugenviron.r.r_bootvme);
+ printf("ROM Boot Delay: %02x\n", bugenviron.r.r_delay);
+ printf("ROM Boot Start: %08x\n", bugenviron.r.r_start);
+ printf("ROM Boot End: %08x\n", bugenviron.r.r_end);
+
+ printf("Net Boot Enable: %c\n", bugenviron.n.n_enable);
+ printf("Net Boot on power-up Only: %c\n", bugenviron.n.n_poweruponly);
+ printf("Net Boot CLUN: %02x\n", bugenviron.n.n_clun);
+ printf("Net Boot DLUN: %02x\n", bugenviron.n.n_dlun);
+ printf("Net Boot Delay: %02x\n", bugenviron.n.n_delay);
+ printf("Net Boot CFG param pointer: %08x\n", bugenviron.n.n_param);
+
+ printf("Memory Size Enable: %c\n", bugenviron.m.m_sizeenable);
+ printf("Memory Start: %08x\n", bugenviron.m.m_start);
+ printf("Memory End: %08x\n", bugenviron.m.m_end);
+
+ Debugger();
+}
+#else
+#define bug_printenv()
+#endif
+
+struct bugenviron *
+mvmeprom_envrd(void)
+{
+ register int ret;
+ char *ptr, *dptr, *ptr_end;
+ int env_size = 0;
+ int pkt_typ, pkt_len;
+ unsigned long omsr = ppc_get_msr();
+ ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE));
+
+ env_size = bugenvsz();
+ bzero(&bugenviron, sizeof(struct bugenviron));
+ bzero(&bugenv_buf[0], 1024);
+ ptr = bugenv_buf;
+
+ if (ptr != NULL) {
+
+ asm volatile ("mr 3, %0": : "r" (ptr));
+ asm volatile ("mr 4, %0": : "r" (env_size));
+ asm volatile ("li 5, 0x2");
+ MVMEPROM_CALL(MVMEPROM_ENVIRON);
+ asm volatile ("mr %0, 3" : "=r" (ret));
+
+ if (ret) { /* scram if we have an error */
+ ppc_set_msr(omsr);
+ return NULL;
+ }
+ ptr_end = ptr + env_size;
+ while (ptr <= ptr_end) {
+ pkt_typ = *ptr++;
+ pkt_len = *ptr++;
+ dptr = ptr;
+ switch (pkt_typ) {
+ case BUG_ENV_END:
+ bugenv_init = 1; /* we have read the env */
+ bug_printenv();
+ ppc_set_msr(omsr);
+ return(&bugenviron);
+ break;
+ case BUG_STARTUP_PARAM:
+ /* All chars. We can use bcopy. */
+ bcopy(dptr, &bugenviron.s.s_mode, pkt_len);
+ break;
+ case BUG_AUTOBOOT_INFO:
+ /* All chars. We can use bcopy. */
+ bcopy(dptr, &bugenviron.b.b_enable, pkt_len);
+ break;
+ case BUG_ROMBOOT_INFO:
+ /* This data stream has integer info that
+ * may not be word aligned. We can't use
+ * bcopy for the whole struct in this
+ * instance. */
+ bcopy(dptr, &bugenviron.r.r_enable, 4);
+ dptr+=4;
+ bcopy(dptr, &bugenviron.r.r_start, 4);
+ dptr+=4;
+ bcopy(dptr, &bugenviron.r.r_end, 4);
+ break;
+ case BUG_NETBOOT_INFO:
+ /* This data stream has integer info that
+ * may not be word aligned. We can't use
+ * bcopy for the whole struct in this
+ * instance. */
+ bcopy(dptr, &bugenviron.n.n_enable, 5);
+ dptr+=5;
+ bcopy(dptr, &bugenviron.n.n_param, 4);
+ break;
+ case BUG_MEMORY_INFO:
+ bugenviron.m.m_sizeenable = *dptr++;
+ bcopy(dptr, &bugenviron.m.m_start, 4);
+ dptr+=4;
+ bcopy(dptr, &bugenviron.m.m_end, 4);
+ break;
+ }
+ ptr += pkt_len;
+ }
+ }
+ ppc_set_msr(omsr);
+ return NULL;
+}
+
diff --git a/sys/arch/mvmeppc/dev/bugtty.c b/sys/arch/mvmeppc/dev/bugtty.c
new file mode 100644
index 00000000000..fc38b8f9127
--- /dev/null
+++ b/sys/arch/mvmeppc/dev/bugtty.c
@@ -0,0 +1,492 @@
+/* $OpenBSD: bugtty.c,v 1.1 2001/06/26 21:57:40 smurph Exp $ */
+/* Copyright (c) 1998 Steve Murphree, Jr.
+ * 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/prom.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 cfattach bugtty_ca = {
+ sizeof(struct device), bugttymatch, bugttyattach
+};
+
+struct cfdriver bugtty_cd = {
+ NULL, "bugtty", DV_TTY, 0
+};
+
+/* prototypes */
+int bugttycnprobe __P((struct consdev *cp));
+int bugttycninit __P((struct consdev *cp));
+int bugttycngetc __P((dev_t dev));
+void 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));
+
+struct tty *bugttytty __P((dev_t dev));
+int bugttymctl __P((dev_t dev, int bits, int how));
+int bugttyparam __P((struct tty *tp, struct termios *tm));
+
+#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];
+
+struct tty *bugtty_tty[NBUGTTY];
+
+/*
+ int ca_bustype;
+ void *ca_vaddr;
+ void *ca_paddr;
+ int ca_offset;
+ int ca_len;
+ int ca_ipl;
+ int ca_vec;
+ char *ca_name;
+ void *ca_master; points to bus-dependent data
+*/
+
+int
+bugttymatch(parent, self, aux)
+ struct device *parent;
+ void *self;
+ void *aux;
+{
+ struct confargs *ca = aux;
+ return (1);
+}
+
+void
+bugttyattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ printf(": bugtty\n");
+}
+
+#define BUGTTYUNIT(x) ((x) & (0x7f))
+void bugttyoutput __P((struct tty *tp));
+
+int bugttydefaultrate = TTYDEF_SPEED;
+int bugttyswflags;
+
+struct tty *
+bugttytty(dev)
+ dev_t dev;
+{
+ int unit;
+ unit = BUGTTYUNIT(dev);
+ if (unit >= 4) {
+ return (NULL);
+ }
+ return bugtty_tty[unit];
+}
+
+int
+bugttymctl(dev, bits, how)
+ dev_t dev;
+ int bits, how;
+{
+ 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;
+
+ 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(tp, tm)
+ struct tty *tp;
+ struct termios *tm;
+{
+ return (0);
+}
+
+void
+bugttyoutput(tp)
+ struct tty *tp;
+{
+ int cc, s, 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);
+ mvmeprom_outstr(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));
+}
+
+/* only to be called at splclk() */
+void
+bugtty_chkinput()
+{
+ struct tty *tp;
+ int rc = 0;
+ tp = bugtty_tty[0]; /* Kinda ugly hack */
+ if (tp == NULL )
+ return;
+
+ if ((rc = mvmeprom_instat()) != 0) {
+ while (mvmeprom_instat() != 0) {
+ u_char c = mvmeprom_getchar() & 0xff;
+ (*linesw[tp->t_line].l_rint)(c, tp);
+ }
+ /*
+ wakeup(tp);
+ */
+ }
+}
+
+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;
+
+ /* 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;
+{
+ /* Nothing to do */
+ return 0;
+}
+
+int
+bugttycngetc(dev)
+ dev_t dev;
+{
+ return (mvmeprom_getchar());
+}
+
+void
+bugttycnputc(dev, c)
+ dev_t dev;
+ char c;
+{
+ if (c == '\n')
+ mvmeprom_outchar('\r');
+ mvmeprom_outchar(c);
+}
diff --git a/sys/arch/mvmeppc/dev/clock.c b/sys/arch/mvmeppc/dev/clock.c
new file mode 100644
index 00000000000..a5e7af5d53b
--- /dev/null
+++ b/sys/arch/mvmeppc/dev/clock.c
@@ -0,0 +1,397 @@
+/* $OpenBSD: clock.c,v 1.1 2001/06/26 21:57:40 smurph Exp $ */
+/* $NetBSD: clock.c,v 1.1 1996/09/30 16:34:40 ws Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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/kernel.h>
+
+#include <machine/pio.h>
+#include <machine/intr.h>
+#include <machine/powerpc.h>
+
+void resettodr();
+/*
+ * Initially we assume a processor with a bus frequency of 12.5 MHz.
+ */
+static u_long ticks_per_sec = 3125000;
+static u_long ns_per_tick = 320;
+static long ticks_per_intr = 0;
+static volatile u_long lasttb;
+
+/*
+ * BCD to decimal and decimal to BCD.
+ */
+#define FROMBCD(x) (((x) >> 4) * 10 + ((x) & 0xf))
+#define TOBCD(x) (((x) / 10 * 16) + ((x) % 10))
+
+#define SECDAY (24 * 60 * 60)
+#define SECYR (SECDAY * 365)
+#define LEAPYEAR(y) (((y) & 3) == 0)
+#define YEAR0 1900
+
+static u_long
+chiptotime __P((int sec, int min, int hour, int day, int mon, int year));
+
+struct chiptime {
+ int sec;
+ int min;
+ int hour;
+ int wday;
+ int day;
+ int mon;
+ int year;
+};
+
+static void timetochip __P((struct chiptime *c));
+
+/*
+ * For now we let the machine run with boot time, not changing the clock
+ * at inittodr at all.
+ *
+ * We might continue to do this due to setting up the real wall clock with
+ * a user level utility in the future.
+ */
+
+/* ARGSUSED */
+void
+inittodr(base)
+time_t base;
+{
+ int sec, min, hour, day, mon, year;
+
+ int badbase = 0, waszero = base == 0;
+
+ if (base < 5 * SECYR) {
+ /*
+ * If base is 0, assume filesystem time is just unknown
+ * instead of preposterous. Don't bark.
+ */
+ if (base != 0)
+ printf("WARNING: preposterous time in file system\n");
+ /* not going to use it anyway, if the chip is readable */
+ base = 21*SECYR + 186*SECDAY + SECDAY/2;
+ badbase = 1;
+ }
+
+ if (fw->clock_read != NULL ) {
+ (fw->clock_read)( &sec, &min, &hour, &day, &mon, &year);
+ time.tv_sec = chiptotime(sec, min, hour, day, mon, year);
+ } else if (fw->time_read != NULL) {
+ u_long cursec;
+ (fw->time_read)(&cursec);
+ time.tv_sec = cursec;
+ } else {
+ /* force failure */
+ time.tv_sec = 0;
+ }
+ if (time.tv_sec == 0) {
+ printf("WARNING: unable to get date/time");
+ /*
+ * Believe the time in the file system for lack of
+ * anything better, resetting the clock.
+ */
+ time.tv_sec = base;
+ if (!badbase)
+ resettodr();
+ } else {
+ int deltat;
+
+ time.tv_sec += tz.tz_minuteswest * 60;
+ if (tz.tz_dsttime)
+ time.tv_sec -= 3600;
+
+ deltat = time.tv_sec - base;
+
+ if (deltat < 0)
+ deltat = -deltat;
+ if (waszero || deltat < 2 * SECDAY)
+ return;
+ printf("WARNING: clock %s %d days",
+ time.tv_sec < base ? "lost" : "gained", deltat / SECDAY);
+ }
+ printf(" -- CHECK AND RESET THE DATE!\n");
+}
+
+/*
+ * This code is defunct after 2068.
+ * Will Unix still be here then??
+ */
+const short dayyr[12] =
+{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
+
+static u_long
+chiptotime(sec, min, hour, day, mon, year)
+int sec, min, hour, day, mon, year;
+{
+ int days, yr;
+
+ sec = FROMBCD(sec);
+ min = FROMBCD(min);
+ hour = FROMBCD(hour);
+ day = FROMBCD(day);
+ mon = FROMBCD(mon);
+ year = FROMBCD(year) + YEAR0;
+
+ /* simple sanity checks */
+ if (year < 1970 || mon < 1 || mon > 12 || day < 1 || day > 31)
+ return (0);
+ days = 0;
+ for (yr = 1970; yr < year; yr++)
+ days += LEAPYEAR(yr) ? 366 : 365;
+ days += dayyr[mon - 1] + day - 1;
+ if (LEAPYEAR(yr) && mon > 2)
+ days++;
+ /* now have days since Jan 1, 1970; the rest is easy... */
+ return (days * SECDAY + hour * 3600 + min * 60 + sec);
+}
+
+void
+timetochip(c)
+ register struct chiptime *c;
+{
+ register int t, t2, t3, now = time.tv_sec;
+
+ /* January 1 1970 was a Thursday (4 in unix wdays) */
+ /* compute the days since the epoch */
+ t2 = now / SECDAY;
+
+ t3 = (t2 + 4) % 7; /* day of week */
+ c->wday = TOBCD(t3 + 1);
+
+ /* compute the year */
+ t = 69;
+ while (t2 >= 0) { /* whittle off years */
+ t3 = t2;
+ t++;
+ t2 -= LEAPYEAR(t) ? 366 : 365;
+ }
+ c->year = t;
+
+ /* t3 = month + day; separate */
+ t = LEAPYEAR(t);
+ for (t2 = 1; t2 < 12; t2++)
+ if (t3 < (dayyr[t2] + ((t && (t2 > 1)) ? 1:0)))
+ break;
+
+ /* t2 is month */
+ c->mon = t2;
+ c->day = t3 - dayyr[t2 - 1] + 1;
+ if (t && t2 > 2)
+ c->day--;
+
+ /* the rest is easy */
+ t = now % SECDAY;
+ c->hour = t / 3600;
+ t %= 3600;
+ c->min = t / 60;
+ c->sec = t % 60;
+
+ c->sec = TOBCD(c->sec);
+ c->min = TOBCD(c->min);
+ c->hour = TOBCD(c->hour);
+ c->day = TOBCD(c->day);
+ c->mon = TOBCD(c->mon);
+ c->year = TOBCD((c->year - YEAR0) % 100);
+}
+
+
+/*
+ * Similar to the above
+ */
+void
+resettodr()
+{
+ struct timeval curtime = time;
+ if (fw->clock_write != NULL) {
+ struct chiptime c;
+ timetochip(&c);
+ (fw->clock_write)(c.sec, c.min, c.hour, c.day, c.mon, c.year);
+ } else if (fw->time_write != NULL) {
+ curtime.tv_sec -= tz.tz_minuteswest * 60;
+ if (tz.tz_dsttime) {
+ curtime.tv_sec += 3600;
+ }
+ (fw->time_write)(curtime.tv_sec);
+ }
+}
+
+void
+decr_intr(frame)
+struct clockframe *frame;
+{
+ int msr;
+ u_long tb;
+ long tick;
+ int nticks;
+ int pri;
+
+ /*
+ * Check whether we are initialized.
+ */
+ if (!ticks_per_intr)
+ return;
+
+ intrcnt[PPC_CLK_IRQ]++;
+
+ /*
+ * Based on the actual time delay since the last decrementer reload,
+ * we arrange for earlier interrupt next time.
+ */
+ asm ("mftb %0; mfdec %1" : "=r"(tb), "=r"(tick));
+ for (nticks = 0; tick < 0; nticks++)
+ tick += ticks_per_intr;
+ asm volatile ("mtdec %0" :: "r"(tick));
+ /*
+ * lasttb is used during microtime. Set it to the virtual
+ * start of this tick interval.
+ */
+ lasttb = tb + tick - ticks_per_intr;
+
+ pri = splclock();
+
+ if (pri & SPL_CLOCK) {
+ tickspending += nticks;
+ } else {
+ nticks += tickspending;
+ tickspending = 0;
+ /*
+ * Reenable interrupts
+ */
+ asm volatile ("mfmsr %0; ori %0, %0, %1; mtmsr %0"
+ : "=r"(msr) : "K"(PSL_EE));
+
+ /*
+ * Do standard timer interrupt stuff.
+ * Do softclock stuff only on the last iteration.
+ */
+ frame->pri = pri | SINT_CLOCK;
+ while (--nticks > 0)
+ hardclock(frame);
+ frame->pri = pri;
+ hardclock(frame);
+ }
+ splx(pri);
+}
+
+void
+cpu_initclocks()
+{
+ int msr, scratch;
+ asm volatile ("mfmsr %0; andi. %1, %0, %2; mtmsr %1"
+ : "=r"(msr), "=r"(scratch) : "K"((u_short)~PSL_EE));
+ asm volatile ("mftb %0" : "=r"(lasttb));
+ asm volatile ("mtdec %0" :: "r"(ticks_per_intr));
+ asm volatile ("mtmsr %0" :: "r"(msr));
+}
+
+void
+calc_delayconst()
+{
+ int qhandle, phandle;
+ char name[32];
+ int msr, scratch;
+
+ ticks_per_sec = ppc_tps();
+ asm volatile ("mfmsr %0; andi. %1, %0, %2; mtmsr %1"
+ : "=r"(msr), "=r"(scratch) : "K"((u_short)~PSL_EE));
+ ns_per_tick = 1000000000 / ticks_per_sec;
+ ticks_per_intr = ticks_per_sec / hz;
+ asm volatile ("mtmsr %0" :: "r"(msr));
+}
+
+static inline u_quad_t
+mftb()
+{
+ u_long scratch;
+ u_quad_t tb;
+
+ asm ("1: mftbu %0; mftb %0+1; mftbu %1; cmpw 0,%0,%1; bne 1b"
+ : "=r"(tb), "=r"(scratch));
+ return tb;
+}
+
+/*
+ * Fill in *tvp with current time with microsecond resolution.
+ */
+void
+microtime(tvp)
+struct timeval *tvp;
+{
+ u_long tb;
+ u_long ticks;
+ int msr, scratch;
+
+ asm volatile ("mfmsr %0; andi. %1,%0,%2; mtmsr %1"
+ : "=r"(msr), "=r"(scratch) : "K"((u_short)~PSL_EE));
+ asm ("mftb %0" : "=r"(tb));
+ ticks = (tb - lasttb) * ns_per_tick;
+ *tvp = time;
+ asm volatile ("mtmsr %0" :: "r"(msr));
+ ticks /= 1000;
+ tvp->tv_usec += ticks;
+ while (tvp->tv_usec >= 1000000) {
+ tvp->tv_usec -= 1000000;
+ tvp->tv_sec++;
+ }
+}
+
+/*
+ * Wait for about n microseconds (us) (at least!).
+ */
+void
+delay(n)
+unsigned n;
+{
+ u_quad_t tb;
+ u_long tbh, tbl, scratch;
+
+ tb = mftb();
+ tb += (n * 1000 + ns_per_tick - 1) / ns_per_tick;
+ tbh = tb >> 32;
+ tbl = tb;
+ asm ("1: mftbu %0; cmplw %0,%1; blt 1b; bgt 2f;"
+ " mftb %0; cmplw %0,%2; blt 1b; 2:"
+ :: "r"(scratch), "r"(tbh), "r"(tbl));
+
+ tb = mftb();
+}
+
+/*
+ * Nothing to do.
+ */
+void
+setstatclockrate(arg)
+int arg;
+{
+ /* Do nothing */
+}
diff --git a/sys/arch/mvmeppc/dev/cpu.c b/sys/arch/mvmeppc/dev/cpu.c
new file mode 100644
index 00000000000..253c2ed0030
--- /dev/null
+++ b/sys/arch/mvmeppc/dev/cpu.c
@@ -0,0 +1,267 @@
+/* $OpenBSD: cpu.c,v 1.1 2001/06/26 21:57:41 smurph Exp $ */
+
+/*
+ * Copyright (c) 1997 Per Fogelstrom
+ * Copyright (c) 1997 RTMX Inc
+ *
+ * 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 under OpenBSD for RTMX Inc
+ * North Carolina, USA, by Per Fogelstrom, Opsycon AB, Sweden.
+ * 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/proc.h>
+#include <sys/user.h>
+#include <sys/device.h>
+
+#include <machine/autoconf.h>
+
+char cpu_model[80];
+char machine[] = "powerpc"; /* cpu architecture */
+
+/* Definition of the driver for autoconfig. */
+static int cpumatch(struct device *, void *, void *);
+static void cpuattach(struct device *, struct device *, void *);
+
+struct cfattach cpu_ca = {
+ sizeof(struct device), cpumatch, cpuattach
+};
+struct cfdriver cpu_cd = {
+ NULL, "cpu", DV_DULL, NULL, 0
+};
+
+static int
+cpumatch(parent, cfdata, aux)
+ struct device *parent;
+ void *cfdata;
+ void *aux;
+{
+ struct confargs *ca = aux;
+
+ /* make sure that we're looking for a CPU. */
+ if (strcmp(ca->ca_name, cpu_cd.cd_name) != 0)
+ return (0);
+
+ return (1);
+}
+void config_l2cr();
+
+static void
+cpuattach(parent, dev, aux)
+ struct device *parent;
+ struct device *dev;
+ void *aux;
+{
+ int cpu, pvr;
+ char name[32];
+ int qhandle, phandle;
+ unsigned int clock_freq = 0;
+
+ __asm__ ("mfpvr %0" : "=r"(pvr));
+ cpu = pvr >> 16;
+ switch (cpu) {
+ case 1:
+ sprintf(cpu_model, "601");
+ break;
+ case 3:
+ sprintf(cpu_model, "603");
+ break;
+ case 4:
+ sprintf(cpu_model, "604");
+ break;
+ case 5:
+ sprintf(cpu_model, "602");
+ break;
+ case 6:
+ sprintf(cpu_model, "603e");
+ break;
+ case 7:
+ sprintf(cpu_model, "603ev");
+ break;
+ case 8:
+ sprintf(cpu_model, "750");
+ break;
+ case 9:
+ sprintf(cpu_model, "604ev");
+ break;
+ case 12:
+ sprintf(cpu_model, "7400(G4)");
+ break;
+ case 20:
+ sprintf(cpu_model, "620");
+ break;
+ default:
+ sprintf(cpu_model, "Version %x", cpu);
+ break;
+ }
+ sprintf(cpu_model + strlen(cpu_model), " (Revision %x)", pvr & 0xffff);
+ printf(": %s", cpu_model);
+
+ /* This should only be executed on openfirmware systems... */
+#ifdef OFW
+ for (qhandle = OF_peer(0); qhandle; qhandle = phandle) {
+ if (OF_getprop(qhandle, "device_type", name, sizeof name) >= 0
+ && !strcmp(name, "cpu")
+ && OF_getprop(qhandle, "clock-frequency",
+ &clock_freq , sizeof clock_freq ) >= 0)
+ {
+ break;
+ }
+ if (phandle = OF_child(qhandle))
+ continue;
+ while (qhandle) {
+ if (phandle = OF_peer(qhandle))
+ break;
+ qhandle = OF_parent(qhandle);
+ }
+ }
+
+ if (clock_freq != 0) {
+ /* Openfirmware stores clock in HZ, not Mhz */
+ clock_freq /= 1000000;
+ printf(": %d Mhz", clock_freq);
+
+ }
+#endif
+ /* if processor is G3 or G4, configure l2 cache */
+ if ( (cpu == 8) || (cpu == 12) ) {
+ config_l2cr();
+ }
+ printf("\n");
+
+
+}
+
+#define L2CR 1017
+
+#define L2CR_L2E 0x80000000 /* 0: L2 enable */
+#define L2CR_L2PE 0x40000000 /* 1: L2 data parity enable */
+#define L2CR_L2SIZ 0x30000000 /* 2-3: L2 size */
+#define L2SIZ_RESERVED 0x00000000
+#define L2SIZ_256K 0x10000000
+#define L2SIZ_512K 0x20000000
+#define L2SIZ_1M 0x30000000
+#define L2CR_L2CLK 0x0e000000 /* 4-6: L2 clock ratio */
+#define L2CLK_DIS 0x00000000 /* disable L2 clock */
+#define L2CLK_10 0x02000000 /* core clock / 1 */
+#define L2CLK_15 0x04000000 /* / 1.5 */
+#define L2CLK_20 0x08000000 /* / 2 */
+#define L2CLK_25 0x0a000000 /* / 2.5 */
+#define L2CLK_30 0x0c000000 /* / 3 */
+#define L2CR_L2RAM 0x01800000 /* 7-8: L2 RAM type */
+#define L2RAM_FLOWTHRU_BURST 0x00000000
+#define L2RAM_PIPELINE_BURST 0x01000000
+#define L2RAM_PIPELINE_LATE 0x01800000
+#define L2CR_L2DO 0x00400000 /* 9: L2 data-only.
+ Setting this bit disables instruction
+ caching. */
+#define L2CR_L2I 0x00200000 /* 10: L2 global invalidate. */
+#define L2CR_L2CTL 0x00100000 /* 11: L2 RAM control (ZZ enable).
+ Enables automatic operation of the
+ L2ZZ (low-power mode) signal. */
+#define L2CR_L2WT 0x00080000 /* 12: L2 write-through. */
+#define L2CR_L2TS 0x00040000 /* 13: L2 test support. */
+#define L2CR_L2OH 0x00030000 /* 14-15: L2 output hold. */
+#define L2CR_L2SL 0x00008000 /* 16: L2 DLL slow. */
+#define L2CR_L2DF 0x00004000 /* 17: L2 differential clock. */
+#define L2CR_L2BYP 0x00002000 /* 18: L2 DLL bypass. */
+#define L2CR_L2IP 0x00000001 /* 31: L2 global invalidate in progress
+ (read only). */
+#ifdef L2CR_CONFIG
+u_int l2cr_config = L2CR_CONFIG;
+#else
+u_int l2cr_config = 0;
+#endif
+
+void
+config_l2cr()
+{
+ u_int l2cr, x;
+
+ __asm __volatile ("mfspr %0, 1017" : "=r"(l2cr));
+
+ /*
+ * Configure L2 cache if not enabled.
+ */
+ if ((l2cr & L2CR_L2E) == 0 && l2cr_config != 0) {
+ l2cr = l2cr_config;
+ asm volatile ("mtspr 1017,%0" :: "r"(l2cr));
+
+ /* Wait for L2 clock to be stable (640 L2 clocks). */
+ delay(100);
+
+ /* Invalidate all L2 contents. */
+ l2cr |= L2CR_L2I;
+ asm volatile ("mtspr 1017,%0" :: "r"(l2cr));
+ do {
+ asm volatile ("mfspr %0, 1017" : "=r"(x));
+ } while (x & L2CR_L2IP);
+
+ /* Enable L2 cache. */
+ l2cr &= ~L2CR_L2I;
+ l2cr |= L2CR_L2E;
+ asm volatile ("mtspr 1017,%0" :: "r"(l2cr));
+ }
+
+ if (l2cr & L2CR_L2E) {
+ switch (l2cr & L2CR_L2SIZ) {
+ case L2SIZ_256K:
+ printf(": 256KB");
+ break;
+ case L2SIZ_512K:
+ printf(": 512KB");
+ break;
+ case L2SIZ_1M:
+ printf(": 1MB");
+ break;
+ default:
+ printf(": unknown size");
+ }
+#if 0
+ switch (l2cr & L2CR_L2RAM) {
+ case L2RAM_FLOWTHRU_BURST:
+ printf(" Flow-through synchronous burst SRAM");
+ break;
+ case L2RAM_PIPELINE_BURST:
+ printf(" Pipelined synchronous burst SRAM");
+ break;
+ case L2RAM_PIPELINE_LATE:
+ printf(" Pipelined synchronous late-write SRAM");
+ break;
+ default:
+ printf(" unknown type");
+ }
+
+ if (l2cr & L2CR_L2PE)
+ printf(" with parity");
+#endif
+ printf(" backside cache");
+ } else
+ printf(": L2 cache not enabled");
+
+}
diff --git a/sys/arch/mvmeppc/dev/mainbus.c b/sys/arch/mvmeppc/dev/mainbus.c
new file mode 100644
index 00000000000..968d1cd5a78
--- /dev/null
+++ b/sys/arch/mvmeppc/dev/mainbus.c
@@ -0,0 +1,159 @@
+/* $OpenBSD: mainbus.c,v 1.1 2001/06/26 21:57:41 smurph Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/reboot.h>
+
+#include <machine/autoconf.h>
+
+struct mainbus_softc {
+ struct device sc_dv;
+ struct bushook sc_bus;
+};
+
+/* Definition of the mainbus driver. */
+static int mbmatch __P((struct device *, void *, void *));
+static void mbattach __P((struct device *, struct device *, void *));
+static int mbprint __P((void *, const char *));
+
+struct cfattach mainbus_ca = {
+ sizeof(struct device), mbmatch, mbattach
+};
+struct cfdriver mainbus_cd = {
+ NULL, "mainbus", DV_DULL, NULL, 0
+};
+
+void mb_intr_establish __P((struct confargs *, int (*)(void *), void *));
+void mb_intr_disestablish __P((struct confargs *));
+caddr_t mb_cvtaddr __P((struct confargs *));
+int mb_matchname __P((struct confargs *, char *));
+
+static int attached = 0;
+
+static int
+mbmatch(parent, cfdata, aux)
+ struct device *parent;
+ void *cfdata;
+ void *aux;
+{
+ struct cfdata *cf = cfdata;
+
+ /*
+ * That one mainbus is always here.
+ */
+ if (!attached) {
+ return(1);
+ } else {
+ return(0);
+ }
+}
+
+static void
+mbattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct mainbus_softc *sc = (struct mainbus_softc *)self;
+ struct confargs nca;
+ extern int system_type;
+
+ printf("\n");
+
+ attached = 1;
+
+ sc->sc_bus.bh_dv = (struct device *)sc;
+ sc->sc_bus.bh_type = BUS_MAIN;
+ sc->sc_bus.bh_intr_establish = mb_intr_establish;
+ sc->sc_bus.bh_intr_disestablish = mb_intr_disestablish;
+ sc->sc_bus.bh_matchname = mb_matchname;
+
+ /*
+ * Try to find and attach all of the CPUs in the machine.
+ * ( Right now only one CPU so code is simple )
+ */
+
+ nca.ca_name = "cpu";
+ nca.ca_bus = &sc->sc_bus;
+ config_found(self, &nca, mbprint);
+
+ /* The following machines have an ISA bus */
+ /* Do ISA first so the interrupt controller is set up! */
+ nca.ca_name = "isabr";
+ nca.ca_bus = &sc->sc_bus;
+ config_found(self, &nca, mbprint);
+
+ nca.ca_name = "mpcpcibr";
+ nca.ca_bus = &sc->sc_bus;
+ config_found(self, &nca, mbprint);
+}
+
+static int
+mbprint(aux, pnp)
+ void *aux;
+ const char *pnp;
+{
+ if (pnp)
+ return (QUIET);
+ return (UNCONF);
+}
+
+void
+mb_intr_establish(ca, handler, val)
+ struct confargs *ca;
+ int (*handler) __P((void *));
+ void *val;
+{
+ panic("can never mb_intr_establish");
+}
+
+void
+mb_intr_disestablish(ca)
+ struct confargs *ca;
+{
+ panic("can never mb_intr_disestablish");
+}
+
+caddr_t
+mb_cvtaddr(ca)
+ struct confargs *ca;
+{
+
+ return (NULL);
+}
+
+int
+mb_matchname(ca, name)
+ struct confargs *ca;
+ char *name;
+{
+ return (strcmp(name, ca->ca_name) == 0);
+}
diff --git a/sys/arch/mvmeppc/dev/mem.c b/sys/arch/mvmeppc/dev/mem.c
new file mode 100644
index 00000000000..25e15ccdd6b
--- /dev/null
+++ b/sys/arch/mvmeppc/dev/mem.c
@@ -0,0 +1,176 @@
+/* $OpenBSD: mem.c,v 1.1 2001/06/26 21:57:41 smurph Exp $ */
+/* $NetBSD: mem.c,v 1.1 1996/09/30 16:34:50 ws Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department.
+ *
+ * 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 University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ *
+ * @(#)mem.c 8.3 (Berkeley) 1/12/94
+ */
+
+/*
+ * Memory special file
+ */
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/buf.h>
+#include <sys/systm.h>
+#include <sys/uio.h>
+#include <sys/malloc.h>
+
+#include <vm/vm.h>
+
+/*ARGSUSED*/
+int
+mmopen(dev, flag, mode)
+ dev_t dev;
+ int flag, mode;
+{
+
+ switch (minor(dev)) {
+ case 0:
+ case 1:
+ case 2:
+ case 12:
+ return (0);
+ default:
+ return (ENXIO);
+ }
+}
+
+/*ARGSUSED*/
+int
+mmclose(dev, flag, mode)
+ dev_t dev;
+ int flag, mode;
+{
+
+ return 0;
+}
+
+/*ARGSUSED*/
+int
+mmrw(dev, uio, flags)
+ dev_t dev;
+ struct uio *uio;
+ int flags;
+{
+ vm_offset_t o, v;
+ u_int c;
+ struct iovec *iov;
+ int error = 0;
+ static caddr_t zeropage;
+
+ while (uio->uio_resid > 0 && error == 0) {
+ iov = uio->uio_iov;
+ if (iov->iov_len == 0) {
+ uio->uio_iov++;
+ uio->uio_iovcnt--;
+ if (uio->uio_iovcnt < 0)
+ panic("mmrw");
+ continue;
+ }
+ switch (minor(dev)) {
+
+/* minor device 0 is physical memory */
+ case 0:
+ v = uio->uio_offset;
+ c = uio->uio_resid;
+ /* This doesn't allow device mapping! XXX */
+ pmap_real_memory(&v, &c);
+ error = uiomove((caddr_t)v, c, uio);
+ continue;
+
+/* minor device 1 is kernel memory */
+ case 1:
+ v = uio->uio_offset;
+ c = min(iov->iov_len, MAXPHYS);
+ error = uiomove((caddr_t)v, c, uio);
+ continue;
+
+/* minor device 2 is EOF/RATHOLE */
+ case 2:
+ if (uio->uio_rw == UIO_WRITE)
+ uio->uio_resid = 0;
+ return 0;
+
+/* minor device 12 (/dev/zero) is source of nulls on read, rathole on write */
+ case 12:
+ if (uio->uio_rw == UIO_WRITE) {
+ c = iov->iov_len;
+ break;
+ }
+ if (zeropage == NULL) {
+ zeropage = (caddr_t)malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
+ bzero(zeropage, PAGE_SIZE);
+ }
+ c = min(iov->iov_len, PAGE_SIZE);
+ error = uiomove(zeropage, c, uio);
+ continue;
+
+ default:
+ return ENXIO;
+ }
+ if (error)
+ break;
+ iov->iov_base += c;
+ iov->iov_len -= c;
+ uio->uio_offset += c;
+ uio->uio_resid -= c;
+ }
+ return error;
+}
+
+int
+mmmmap(dev, off, prot)
+ dev_t dev;
+ int off, prot;
+{
+ return (-1);
+}
+
+/*ARGSUSED*/
+int
+mmioctl(dev, cmd, data, flags, p)
+ dev_t dev;
+ u_long cmd;
+ caddr_t data;
+ int flags;
+ struct proc *p;
+{
+ return (EOPNOTSUPP);
+}
diff --git a/sys/arch/mvmeppc/dev/nvramreg.h b/sys/arch/mvmeppc/dev/nvramreg.h
new file mode 100644
index 00000000000..96c2737f75b
--- /dev/null
+++ b/sys/arch/mvmeppc/dev/nvramreg.h
@@ -0,0 +1,86 @@
+/* $OpenBSD: nvramreg.h,v 1.1 2001/06/26 21:57:41 smurph Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. 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, Berkeley and its contributors.
+ * 4. 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.
+ *
+ * @(#)clockreg.h 8.1 (Berkeley) 6/11/93
+ */
+
+/*
+ * mvme2x00 Mostek TOD clock/NVRAM
+ */
+
+/*
+ * Mostek MK48T59 clock.
+ *
+ * This chip is 8k in size.
+ * The first TOD clock starts at offset 0x1FF8. The following structure
+ * describes last 2K of it's 8K address space. The first 6K of the NVRAM
+ * space is used for various things as follows:
+ * 0000-0fff User Area
+ * 1000-10ff Networking Area
+ * 1100-16f7 Operating System Area
+ * 16f8-1ef7 ROM Debugger Area
+ * 1ef8-1ff7 Configuration Area (Ethernet address etc)
+ * 1ff8-1fff TOD clock
+ */
+
+#define NVRAM_S0 0x80000074
+#define NVRAM_S1 0x80000075
+#define NVRAM_DATA 0x80000077
+
+#define RTC_SECONDS 0x1FF9
+#define RTC_MINUTES 0x1FFA
+#define RTC_HOURS 0x1FFB
+#define RTC_DAY_OF_WEEK 0x1FFC
+#define RTC_DAY_OF_MONTH 0x1FFD
+#define RTC_MONTH 0x1FFE
+#define RTC_YEAR 0x1FFF
+
+#define RTC_CONTROLA 0x1FF8
+#define RTC_CA_WRITE 0x80
+#define RTC_CA_READ 0x40
+#define RTC_CA_CALIB_SIGN 0x20
+#define RTC_CA_CALIB_MASK 0x1f
+
+#define RTC_CONTROLB 0x1FF9
+#define RTC_CB_STOP 0x80
+
diff --git a/sys/arch/mvmeppc/dev/openpic.c b/sys/arch/mvmeppc/dev/openpic.c
new file mode 100644
index 00000000000..f4e2a391e2c
--- /dev/null
+++ b/sys/arch/mvmeppc/dev/openpic.c
@@ -0,0 +1,1035 @@
+/* $OpenBSD: openpic.c,v 1.1 2001/06/26 21:57:41 smurph Exp $ */
+
+/*-
+ * Copyright (c) 1995 Per Fogelstrom
+ * Copyright (c) 1993, 1994 Charles M. Hannum.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz and Don Ahn.
+ *
+ * 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 University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ *
+ * @(#)isa.c 7.2 (Berkeley) 5/12/91
+ */
+
+#if 0
+#define OP_DEBUG
+#endif
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/ioctl.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#ifdef UVM
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <uvm/uvm.h>
+#endif
+
+#include <machine/autoconf.h>
+#include <machine/intr.h>
+#include <machine/psl.h>
+#include <machine/pio.h>
+#include <mvmeppc/dev/openpicreg.h>
+#include <mvmeppc/dev/ravenvar.h>
+#include <mvmeppc/dev/ravenreg.h>
+
+#define ICU_LEN 32
+#define LEGAL_IRQ(x) ((x >= 0) && (x < ICU_LEN))
+#define IO_ICU1 (RAVEN_P_ISA_IO_SPACE + 0x20)
+#define IO_ICU2 (RAVEN_P_ISA_IO_SPACE + 0xA0)
+#define IRQ_SLAVE 2
+#define ICU_OFFSET 16
+unsigned char icu1_val = 0xff;
+unsigned char icu2_val = 0xff;
+
+#define SET_ICUS() (outb(IO_ICU1 + 1, imen), outb(IO_ICU2 + 1, imen >> 8))
+
+static int intrtype[ICU_LEN], intrmask[ICU_LEN], intrlevel[ICU_LEN];
+static struct intrhand *intrhand[ICU_LEN] = { 0 };
+static int hwirq[ICU_LEN], virq[ICU_LEN];
+unsigned int imen /* = 0xffffffff */; /* XXX */
+static int virq_max = 0;
+
+struct evcnt evirq[ICU_LEN];
+
+static int fakeintr __P((void *));
+static char *intr_typename(int type);
+static void intr_calculatemasks();
+static __inline int cntlzw(int x);
+static int mapirq(int irq);
+static int read_irq();
+void openpic_enable_irq_mask(int irq_mask);
+
+static struct raven_reg *ravenp = (struct raven_reg *)NULL;
+
+#define HWIRQ_MAX 27
+#define HWIRQ_MASK 0x0fffffff
+
+
+static __inline u_int openpic_read __P((int));
+static __inline void openpic_write __P((int, u_int));
+void openpic_enable_irq __P((int, int));
+void openpic_disable_irq __P((int));
+void openpic_init();
+void openpic_set_priority __P((int, int));
+void openpic_set_vec_pri __P((int, int));
+static __inline int openpic_read_irq __P((int));
+static __inline void openpic_eoi __P((int));
+
+void i8259_init __P((void));
+int i8259_intr __P((void));
+void i8259_enable_irq __P((int));
+void i8259_disable_irq __P((int));
+void *i8259_intr_establish( void * lcv, int irq, int type, int level,
+ int (*ih_fun) __P((void *)), void *ih_arg, char *name);
+
+struct openpic_softc {
+ struct device sc_dev;
+};
+
+int openpic_match __P((struct device *parent, void *cf, void *aux));
+void openpic_attach __P((struct device *, struct device *, void *));
+void openpic_do_pending_int();
+void ext_intr_openpic();
+
+struct cfattach openpic_ca = {
+ sizeof(struct openpic_softc),
+ openpic_match,
+ openpic_attach
+};
+
+struct cfdriver openpic_cd = {
+ NULL, "openpic", DV_DULL
+};
+
+struct pci_route {
+ int pci;
+ int openpic;
+} pci_routes[] = {
+ 10, 2,
+ 11, 4,
+ 14, 3,
+ 15, 5,
+ 0, 0,
+};
+
+static int isaintrs = 0;
+
+int
+openpic_match(parent, cf, aux)
+ struct device *parent;
+ void *cf;
+ void *aux;
+{
+ struct confargs *ca = aux;
+
+ /* We must be a child of the raven device */
+ if (strcmp(parent->dv_cfdata->cf_driver->cd_name, "raven") != 0)
+ return (0);
+ /* don't attach more than once. */
+ if (ravenp != (struct raven_reg *)NULL){
+#ifdef DIAGNOSTIC
+ printf("openpic: trying to attach more than once!");
+#endif
+ return(0);
+ }
+ /* If there is a raven, then there is a mpic! */
+ return 1;
+}
+
+u_int8_t *interrupt_reg;
+typedef void (void_f) (void);
+extern void_f *pending_int_f;
+static int abort_switch (void *arg);
+static int i8259_dummy (void *arg);
+
+typedef int mac_intr_handle_t;
+
+typedef void *(intr_establish_t) __P((void *, mac_intr_handle_t,
+ int, int, int (*func)(void *), void *, char *));
+typedef void (intr_disestablish_t) __P((void *, void *));
+
+vaddr_t openpic_base;
+void * openpic_intr_establish( void * lcv, int irq, int type, int level,
+ int (*ih_fun) __P((void *)), void *ih_arg, char *name);
+void openpic_intr_disestablish( void *lcp, void *arg);
+void openpic_collect_preconf_intr();
+
+void
+openpic_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct confargs *ca = aux;
+ struct openpic_softc *sc = (void *)self;
+ extern intr_establish_t *intr_establish_func;
+ extern intr_disestablish_t *intr_disestablish_func;
+#if 0
+ extern intr_establish_t *mac_intr_establish_func;
+ extern intr_disestablish_t *mac_intr_disestablish_func;
+#endif
+ openpic_base = (vaddr_t)MPCIC_REG/* mapiodev (MPCIC_REG, 0x22000)*/;
+
+ printf(": version 0x%x", openpic_read(OPENPIC_FEATURE) & 0xFF);
+
+ i8259_init();
+ openpic_init();
+
+ pending_int_f = openpic_do_pending_int;
+ intr_establish_func = openpic_intr_establish;
+ intr_disestablish_func = openpic_intr_disestablish;
+#if 0
+ mac_intr_establish_func = openpic_intr_establish;
+ mac_intr_disestablish_func = openpic_intr_disestablish;
+#endif
+ install_extint(ext_intr_openpic);
+
+#if 1
+ openpic_collect_preconf_intr();
+#endif
+
+#if 1
+
+ intr_establish_func(parent, 0x00, IST_LEVEL, IPL_HIGH,
+ i8259_dummy, (void *)0x00, "8259 Interrupt");
+ i8259_intr_establish(parent, 0x08, IST_EDGE, IPL_HIGH,
+ abort_switch, (void *)0x08, "abort button");
+#endif
+/*
+ ppc_intr_enable(1);
+*/
+ printf("\n");
+}
+
+void
+openpic_collect_preconf_intr()
+{
+ int i;
+ for (i = 0; i < ppc_configed_intr_cnt; i++) {
+#ifdef DEBUG
+ printf("\n\t%s irq %d level %d fun %x arg %x",
+ ppc_configed_intr[i].ih_what, ppc_configed_intr[i].ih_irq,
+ ppc_configed_intr[i].ih_level, ppc_configed_intr[i].ih_fun,
+ ppc_configed_intr[i].ih_arg);
+#endif
+ openpic_intr_establish(NULL, ppc_configed_intr[i].ih_irq,
+ IST_LEVEL, ppc_configed_intr[i].ih_level,
+ ppc_configed_intr[i].ih_fun, ppc_configed_intr[i].ih_arg,
+ ppc_configed_intr[i].ih_what);
+ }
+}
+
+static int
+abort_switch (void *arg)
+{
+#ifdef DDB
+ printf("Abort button pressed, entering debugger.\n");
+ Debugger();
+#else
+ printf("Abort button pressed, debugger not available.\n");
+#endif
+ return 1;
+}
+
+static int
+i8259_dummy (void *arg)
+{
+ return 1;
+}
+
+static int
+fakeintr(arg)
+ void *arg;
+{
+
+ return 0;
+}
+
+/*
+ * Register an interrupt handler.
+ */
+void *
+i8259_intr_establish(lcv, irq, type, level, ih_fun, ih_arg, name)
+ void * lcv;
+ int irq;
+ int type;
+ int level;
+ int (*ih_fun) __P((void *));
+ void *ih_arg;
+ char *name;
+{
+ struct intrhand **p, *q, *ih;
+ static struct intrhand fakehand;
+ extern int cold;
+
+ fakehand.ih_next = NULL;
+ fakehand.ih_fun = fakeintr;
+
+#if 0
+printf("i8259_intr_establish, hI %d L %d ", irq, type);
+#endif
+ isaintrs++;
+ irq = mapirq(irq + ICU_OFFSET);
+#if 0
+printf("vI %d ", irq);
+#endif
+
+ /* no point in sleeping unless someone can free memory. */
+ ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
+ if (ih == NULL)
+ panic("i8259_intr_establish: can't malloc handler info");
+
+ if (!LEGAL_IRQ(irq) || type == IST_NONE)
+ panic("i8259_intr_establish: bogus irq or type");
+
+ switch (intrtype[irq]) {
+ case IST_NONE:
+ intrtype[irq] = type;
+ break;
+ case IST_EDGE:
+ case IST_LEVEL:
+ if (type == intrtype[irq])
+ break;
+ case IST_PULSE:
+ if (type != IST_NONE)
+ panic("intr_establish: can't share %s with %s",
+ intr_typename(intrtype[irq]),
+ intr_typename(type));
+ break;
+ }
+
+ /*
+ * Figure out where to put the handler.
+ * This is O(N^2), but we want to preserve the order, and N is
+ * generally small.
+ */
+ for (p = &intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
+ ;
+
+ /*
+ * Actually install a fake handler momentarily, since we might be doing
+ * this with interrupts enabled and DON'T WANt the real routine called
+ * until masking is set up.
+ */
+ fakehand.ih_level = level;
+ *p = &fakehand;
+
+ intr_calculatemasks();
+
+ /*
+ * Poke the real handler in now.
+ */
+ ih->ih_fun = ih_fun;
+ ih->ih_arg = ih_arg;
+ ih->ih_count = 0;
+ ih->ih_next = NULL;
+ ih->ih_level = level;
+ ih->ih_irq = irq;
+ *p = ih;
+
+ return (ih);
+}
+
+
+/*
+ * Register an interrupt handler.
+ */
+void *
+openpic_intr_establish(lcv, irq, type, level, ih_fun, ih_arg, name)
+ void * lcv;
+ int irq;
+ int type;
+ int level;
+ int (*ih_fun) __P((void *));
+ void *ih_arg;
+ char *name;
+{
+ struct intrhand **p, *q, *ih;
+ static struct intrhand fakehand;
+ struct pci_route *pr;
+ extern int cold;
+
+ fakehand.ih_next = NULL;
+ fakehand.ih_fun = fakeintr;
+
+#if 0
+printf("mac_intr_establish, hI %d L %d ", irq, type);
+#endif
+
+ pr = pci_routes;
+ while (pr->pci !=0) {
+ irq = (pr->pci == irq) ? pr->openpic : irq;
+ pr++;
+ }
+
+ irq = mapirq(irq);
+#if 0
+printf("vI %d ", irq);
+#endif
+
+ /* no point in sleeping unless someone can free memory. */
+ ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
+ if (ih == NULL)
+ panic("intr_establish: can't malloc handler info");
+
+ if (!LEGAL_IRQ(irq) || type == IST_NONE)
+ panic("intr_establish: bogus irq or type");
+
+ switch (intrtype[irq]) {
+ case IST_NONE:
+ intrtype[irq] = type;
+ break;
+ case IST_EDGE:
+ case IST_LEVEL:
+ if (type == intrtype[irq])
+ break;
+ case IST_PULSE:
+ if (type != IST_NONE)
+ panic("intr_establish: can't share %s with %s",
+ intr_typename(intrtype[irq]),
+ intr_typename(type));
+ break;
+ }
+
+ /*
+ * Figure out where to put the handler.
+ * This is O(N^2), but we want to preserve the order, and N is
+ * generally small.
+ */
+ for (p = &intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
+ ;
+
+ /*
+ * Actually install a fake handler momentarily, since we might be doing
+ * this with interrupts enabled and DON'T WANt the real routine called
+ * until masking is set up.
+ */
+ fakehand.ih_level = level;
+ *p = &fakehand;
+
+ intr_calculatemasks();
+
+ /*
+ * Poke the real handler in now.
+ */
+ ih->ih_fun = ih_fun;
+ ih->ih_arg = ih_arg;
+ ih->ih_count = 0;
+ ih->ih_next = NULL;
+ ih->ih_level = level;
+ ih->ih_irq = irq;
+ *p = ih;
+
+ return (ih);
+}
+
+/*
+ * Deregister an interrupt handler.
+ */
+void
+openpic_intr_disestablish(lcp, arg)
+ void *lcp;
+ void *arg;
+{
+ struct intrhand *ih = arg;
+ int irq = ih->ih_irq;
+ struct intrhand **p, *q;
+
+ if (!LEGAL_IRQ(irq))
+ panic("intr_disestablish: bogus irq");
+
+ /*
+ * Remove the handler from the chain.
+ * This is O(n^2), too.
+ */
+ for (p = &intrhand[irq]; (q = *p) != NULL && q != ih; p = &q->ih_next)
+ ;
+ if (q)
+ *p = q->ih_next;
+ else
+ panic("intr_disestablish: handler not registered");
+ free((void *)ih, M_DEVBUF);
+
+ intr_calculatemasks();
+
+ if (intrhand[irq] == NULL)
+ intrtype[irq] = IST_NONE;
+}
+
+
+static char *
+intr_typename(type)
+ int type;
+{
+
+ switch (type) {
+ case IST_NONE :
+ return ("none");
+ case IST_PULSE:
+ return ("pulsed");
+ case IST_EDGE:
+ return ("edge-triggered");
+ case IST_LEVEL:
+ return ("level-triggered");
+ default:
+ panic("intr_typename: invalid type %d", type);
+#if 1 /* XXX */
+ return ("unknown");
+#endif
+ }
+}
+
+/*
+ * Recalculate the interrupt masks from scratch.
+ * We could code special registry and deregistry versions of this function that
+ * would be faster, but the code would be nastier, and we don't expect this to
+ * happen very much anyway.
+ */
+static void
+intr_calculatemasks()
+{
+ int irq, level;
+ struct intrhand *q;
+#ifdef OP_DEBUG
+ printf("intr_calculatemasks() ");
+#endif
+ /* First, figure out which levels each IRQ uses. */
+ for (irq = 0; irq < ICU_LEN; irq++) {
+ register int levels = 0;
+ for (q = intrhand[irq]; q; q = q->ih_next)
+ levels |= 1 << q->ih_level;
+ intrlevel[irq] = levels;
+ }
+
+ /* Then figure out which IRQs use each level. */
+ for (level = 0; level < 5; level++) {
+ register int irqs = 0;
+ for (irq = 0; irq < ICU_LEN; irq++)
+ if (intrlevel[irq] & (1 << level))
+ irqs |= 1 << irq;
+ imask[level] = irqs | SINT_MASK;
+ }
+
+ /*
+ * There are tty, network and disk drivers that use free() at interrupt
+ * time, so imp > (tty | net | bio).
+ */
+ imask[IPL_IMP] |= imask[IPL_TTY] | imask[IPL_NET] | imask[IPL_BIO];
+
+ /*
+ * Enforce a hierarchy that gives slow devices a better chance at not
+ * dropping data.
+ */
+ imask[IPL_TTY] |= imask[IPL_NET] | imask[IPL_BIO];
+ imask[IPL_NET] |= imask[IPL_BIO];
+
+ /*
+ * These are pseudo-levels.
+ */
+ imask[IPL_NONE] = 0x00000000;
+ imask[IPL_HIGH] = 0xffffffff;
+
+ /* And eventually calculate the complete masks. */
+ for (irq = 0; irq < ICU_LEN; irq++) {
+ register int irqs = 1 << irq;
+ for (q = intrhand[irq]; q; q = q->ih_next)
+ irqs |= imask[q->ih_level];
+ intrmask[irq] = irqs | SINT_MASK;
+ }
+
+ /* Lastly, determine which IRQs are actually in use. */
+ {
+ register int irqs = 0;
+ for (irq = 0; irq < ICU_LEN; irq++) {
+ if (intrhand[irq]) {
+ irqs |= 1 << irq;
+ if (hwirq[irq] >= ICU_OFFSET)
+ i8259_enable_irq(hwirq[irq]);
+ else
+ openpic_enable_irq(hwirq[irq], intrtype[irq]);
+ } else {
+ if (hwirq[irq] >= ICU_OFFSET)
+ i8259_disable_irq(hwirq[irq]);
+ else
+ openpic_disable_irq(hwirq[irq]);
+ }
+ }
+ }
+#if 0
+ i8259_enable_irq(2);
+#endif
+}
+/*
+ * Map 64 irqs into 32 (bits).
+ */
+static int
+mapirq(irq)
+ int irq;
+{
+ int v;
+
+ if (irq < 0 || irq >= ICU_LEN)
+ panic("invalid irq");
+ virq_max++;
+ v = virq_max;
+ if (v > HWIRQ_MAX)
+ panic("virq overflow");
+
+ hwirq[v] = irq;
+ virq[irq] = v;
+#if 0
+printf("\nmapirq %x to %x\n", irq, v);
+#endif
+
+ return v;
+}
+
+/*
+ * Count leading zeros.
+ */
+static __inline int
+cntlzw(x)
+ int x;
+{
+ int a;
+
+ __asm __volatile ("cntlzw %0,%1" : "=r"(a) : "r"(x));
+
+ return a;
+}
+
+
+void
+openpic_do_pending_int()
+{
+ struct intrhand *ih;
+ int irq;
+ int pcpl;
+ int hwpend;
+ int emsr, dmsr;
+ static int processing;
+
+ if (processing)
+ return;
+
+#ifdef OP_DEBUG
+ printf("openpic_do_pending_int()\n");
+#endif
+ processing = 1;
+ pcpl = splhigh(); /* Turn off all */
+ asm volatile("mfmsr %0" : "=r"(emsr));
+ dmsr = emsr & ~PSL_EE;
+ asm volatile("mtmsr %0" :: "r"(dmsr));
+
+ hwpend = ipending & ~pcpl; /* Do now unmasked pendings */
+ imen &= ~hwpend;
+ openpic_enable_irq_mask(~imen);
+
+ hwpend &= HWIRQ_MASK;
+ while (hwpend) {
+ irq = 31 - cntlzw(hwpend);
+ hwpend &= ~(1L << irq);
+ ih = intrhand[irq];
+ while(ih) {
+ (*ih->ih_fun)(ih->ih_arg);
+ ih = ih->ih_next;
+ }
+
+ evirq[hwirq[irq]].ev_count++;
+ }
+
+ /*out32rb(INT_ENABLE_REG, ~imen);*/
+
+ do {
+ if((ipending & SINT_CLOCK) & ~pcpl) {
+ ipending &= ~SINT_CLOCK;
+ softclock();
+ }
+ if((ipending & SINT_NET) & ~pcpl) {
+ extern int netisr;
+ int pisr = netisr;
+ netisr = 0;
+ ipending &= ~SINT_NET;
+ softnet(pisr);
+ }
+ } while (ipending & (SINT_NET|SINT_CLOCK) & ~cpl);
+ ipending &= pcpl;
+ cpl = pcpl; /* Don't use splx... we are here already! */
+ asm volatile("mtmsr %0" :: "r"(emsr));
+ processing = 0;
+}
+
+u_int
+openpic_read(reg)
+ int reg;
+{
+ char *addr = (void *)(openpic_base + reg);
+
+ return in32rb(addr);
+}
+
+void
+openpic_write(reg, val)
+ int reg;
+ u_int val;
+{
+ char *addr = (void *)(openpic_base + reg);
+
+ out32rb(addr, val);
+}
+
+void
+openpic_enable_irq_mask(irq_mask)
+int irq_mask;
+{
+ int irq;
+#ifdef OP_DEBUG
+ printf("openpic_enable_irq_mask()\n");
+#endif
+ for ( irq = 0; irq <= virq_max; irq++) {
+ if (irq_mask & (1 << irq)) {
+ if (hwirq[irq] >= ICU_OFFSET)
+ i8259_enable_irq(hwirq[irq]);
+ else
+ openpic_enable_irq(hwirq[irq], intrtype[irq]);
+ } else {
+ if (hwirq[irq] >= ICU_OFFSET)
+ i8259_disable_irq(hwirq[irq]);
+ else
+ openpic_disable_irq(hwirq[irq]);
+ }
+ }
+}
+
+void
+openpic_enable_irq(irq, type)
+ int irq;
+ int type;
+{
+ u_int x;
+ /* skip invalid irqs */
+ if (irq == -1)
+ return;
+
+ x = openpic_read(OPENPIC_SRC_VECTOR(irq));
+ x &= ~(OPENPIC_IMASK|OPENPIC_SENSE_LEVEL|OPENPIC_SENSE_EDGE);
+ if (type == IST_LEVEL) {
+ x |= OPENPIC_SENSE_LEVEL;
+ } else {
+ x |= OPENPIC_SENSE_EDGE;
+ }
+#ifdef OP_DEBUG
+ printf("enabeling irq %d, type %d, val 0x%08x\n", irq, type, x);
+#endif
+
+ openpic_write(OPENPIC_SRC_VECTOR(irq), x);
+}
+
+void
+openpic_disable_irq(irq)
+ int irq;
+{
+ u_int x;
+ /* skip invalid irqs */
+ if (irq == -1)
+ return;
+
+ x = openpic_read(OPENPIC_SRC_VECTOR(irq));
+ x |= OPENPIC_IMASK;
+#ifdef OP_DEBUG
+ printf("disabeling irq %d, val 0x%08x\n", irq, x);
+#endif
+
+ openpic_write(OPENPIC_SRC_VECTOR(irq), x);
+}
+
+void
+i8259_set_irq_mask(void)
+{
+ if (icu2_val != 0xFF) {
+ /* Turn on the second IC */
+ icu1_val &= ~(1 << 2);
+ } else {
+ icu1_val |= (1 << 2);
+ }
+
+ outb(IO_ICU1 + 1, icu1_val);
+ outb(IO_ICU2 + 1, icu2_val);
+}
+
+void
+i8259_disable_irq(irq)
+int irq;
+{
+ if (irq >= ICU_OFFSET)
+ irq -= ICU_OFFSET;
+ if (irq < 8)
+ icu1_val |= 1 << irq;
+ else
+ icu2_val |= 1 << (irq - 8);
+ i8259_set_irq_mask();
+#ifdef OP_DEBUG
+ printf("disabeling isa irq %d\n", irq);
+#endif
+}
+
+void
+i8259_enable_irq(irq)
+int irq;
+{
+
+ if (irq >= ICU_OFFSET)
+ irq -= ICU_OFFSET;
+ if ( irq < 8 )
+ icu1_val &= ~(1 << irq);
+ else
+ icu2_val &= ~(1 << (irq - 8));
+ i8259_set_irq_mask();
+#ifdef OP_DEBUG
+ printf("enabeling isa irq %d\n", irq);
+#endif
+
+}
+
+void
+openpic_set_priority(cpu, pri)
+ int cpu, pri;
+{
+ u_int x;
+
+ x = openpic_read(OPENPIC_CPU_PRIORITY(cpu));
+ x &= ~OPENPIC_CPU_PRIORITY_MASK;
+ x |= pri;
+ openpic_write(OPENPIC_CPU_PRIORITY(cpu), x);
+}
+
+int
+openpic_read_irq(cpu)
+ int cpu;
+{
+ return openpic_read(OPENPIC_IACK(cpu)) & OPENPIC_VECTOR_MASK;
+}
+
+void
+openpic_eoi(cpu)
+ int cpu;
+{
+ openpic_write(OPENPIC_EOI(cpu), 0);
+ openpic_read(OPENPIC_EOI(cpu));
+}
+
+void i8259_init(void)
+{
+ /* initialize 8259's */
+ outb(IO_ICU1, 0x11); /* reset; program device, four bytes */
+ outb(IO_ICU1+1, ICU_OFFSET); /* starting at this vector index */
+ outb(IO_ICU1+1, 1 << IRQ_SLAVE); /* slave on line 2 */
+ outb(IO_ICU1+1, 1); /* 8086 mode */
+ outb(IO_ICU1+1, 0xff); /* leave interrupts masked */
+ /* init interrupt controller 2 */
+ outb(IO_ICU2, 0x11); /* reset; program device, four bytes */
+ outb(IO_ICU2+1, ICU_OFFSET+8); /* staring at this vector index */
+ outb(IO_ICU2+1, IRQ_SLAVE);
+ outb(IO_ICU2+1, 1); /* 8086 mode */
+ outb(IO_ICU2+1, 0xff); /* leave interrupts masked */
+}
+
+int i8259_intr(void)
+{
+ int irq;
+
+ /*
+ * Perform an interrupt acknowledge cycle on controller 1
+ */
+ outb(IO_ICU1, 0x0C);
+ irq = inb(IO_ICU1) & 7;
+#ifdef OP_DEBUG
+ printf("isa intr = %d\n", irq);
+#endif
+ if (irq == 2)
+ {
+ /*
+ * Interrupt is cascaded so perform interrupt
+ * acknowledge on controller 2
+ */
+ outb(IO_ICU2, 0x0C);
+ irq = (inb(IO_ICU2) & 7) + 8;
+ }
+ else if (irq==7)
+ {
+ /*
+ * This may be a spurious interrupt
+ *
+ * Read the interrupt status register. If the most
+ * significant bit is not set then there is no valid
+ * interrupt
+ */
+ outb(IO_ICU1, 0x0B);
+ if(~inb(IO_ICU1)&0x80)
+ return 0xFF;
+ }
+ return (ICU_OFFSET + irq);
+}
+
+void
+ext_intr_openpic()
+{
+ int irq, realirq;
+ int r_imen;
+ int pcpl;
+ struct intrhand *ih;
+
+#ifdef OP_DEBUG
+ printf("Interrupt!\n");
+#endif
+ pcpl = splhigh(); /* Turn off all */
+
+ realirq = openpic_read_irq(0);
+#ifdef OP_DEBUG
+ printf("irq %d\n", realirq);
+#endif
+
+ while ((realirq != 0xFF) && (realirq != 0xAA)) {
+ if (realirq == 0x00){
+ realirq = i8259_intr();
+#ifdef OP_DEBUG
+ printf("irq2 %d\n", realirq);
+#endif
+ openpic_eoi(0);
+ if (realirq == 0xFF)
+ continue;
+ }
+
+ irq = virq[realirq];
+ intrcnt[realirq]++;
+
+ /* XXX check range */
+
+ r_imen = 1 << irq;
+
+ if ((pcpl & r_imen) != 0) {
+ ipending |= r_imen; /* Masked! Mark this as pending */
+ if (realirq >= ICU_OFFSET)
+ i8259_disable_irq(realirq);
+ else
+ openpic_disable_irq(realirq);
+ } else {
+ ih = intrhand[irq];
+ while (ih) {
+ (*ih->ih_fun)(ih->ih_arg);
+ ih = ih->ih_next;
+ }
+#ifdef UVM
+ uvmexp.intrs++;
+#else
+#endif
+ evirq[realirq].ev_count++;
+ }
+
+ openpic_eoi(0);
+
+ realirq = openpic_read_irq(0);
+ }
+
+ splx(pcpl); /* Process pendings. */
+}
+
+void openpic_set_vec_pri(int irq, int pri)
+{
+ u_int x;
+ x = openpic_read(OPENPIC_SRC_VECTOR(irq));
+ x &= ~OPENPIC_PRIORITY_MASK;
+ x |= pri << OPENPIC_PRIORITY_SHIFT;
+ openpic_write(OPENPIC_SRC_VECTOR(irq), x);
+}
+
+void openpic_initirq(int irq, int pri, int vec, int pol, int sense)
+{
+ u_int x;
+ x = (vec & OPENPIC_VECTOR_MASK);
+ x |= OPENPIC_IMASK;
+ x |= (pol ? OPENPIC_POLARITY_POSITIVE : OPENPIC_POLARITY_NEGATIVE);
+ x |= (sense ? OPENPIC_SENSE_LEVEL : OPENPIC_SENSE_EDGE);
+ x |= pri << OPENPIC_PRIORITY_SHIFT;
+ openpic_write(OPENPIC_SRC_VECTOR(irq), x);
+}
+
+void
+openpic_init()
+{
+ int irq;
+ u_int x;
+
+ /* disable all interrupts and init hwirq[] */
+ for (irq = 0; irq < ICU_LEN; irq++){
+ hwirq[irq] = -1;
+ openpic_write(OPENPIC_SRC_VECTOR(irq), OPENPIC_IMASK);
+ }
+ openpic_set_priority(0, 15);
+
+ /* we don't need 8259 pass through mode */
+ x = openpic_read(OPENPIC_CONFIG);
+ x |= OPENPIC_CONFIG_8259_PASSTHRU_DISABLE;
+ openpic_write(OPENPIC_CONFIG, x);
+
+ /* send all interrupts to cpu 0 */
+ for (irq = 0; irq < ICU_LEN; irq++)
+ openpic_write(OPENPIC_SRC_DEST(irq), CPU(0));
+
+ /* special case for intr src 0 */
+ openpic_initirq(0, 8, 0, 1, 0);
+
+ for (irq = 1; irq < ICU_LEN; irq++) {
+ openpic_initirq(irq, 8, irq, 0, 1);
+ }
+
+ /* XXX set spurious intr vector */
+ openpic_write(OPENPIC_SPURIOUS_VECTOR, 0xFF);
+
+ /* unmask interrupts for cpu 0 */
+ openpic_set_priority(0, 0);
+
+ /* clear all pending interrunts */
+ for (irq = 0; irq < ICU_OFFSET; irq++) {
+ openpic_read_irq(0);
+ openpic_eoi(0);
+ }
+
+ for (irq = 0; irq < ICU_OFFSET; irq++){
+ i8259_disable_irq(irq);
+ openpic_disable_irq(irq);
+ }
+
+ install_extint(ext_intr_openpic);
+}
diff --git a/sys/arch/mvmeppc/dev/openpicreg.h b/sys/arch/mvmeppc/dev/openpicreg.h
new file mode 100644
index 00000000000..72fe1f17af0
--- /dev/null
+++ b/sys/arch/mvmeppc/dev/openpicreg.h
@@ -0,0 +1,90 @@
+/* $NetBSD: openpicreg.h,v 1.1 2000/02/14 12:45:53 tsubai Exp $ */
+
+/*-
+ * Copyright (c) 2000 Tsubai Masanari. 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. 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.
+ */
+
+/*
+ * GLOBAL/TIMER register (IDU base + 0x1000)
+ */
+
+/* feature reporting reg 0 */
+#define OPENPIC_FEATURE 0x1000
+
+/* global config reg 0 */
+#define OPENPIC_CONFIG 0x1020
+#define OPENPIC_CONFIG_RESET 0x80000000
+#define OPENPIC_CONFIG_8259_PASSTHRU_DISABLE 0x20000000
+
+/* vendor ID */
+#define OPENPIC_VENDOR_ID 0x1080
+
+/* processor initialization reg */
+#define OPENPIC_PROC_INIT 0x1090
+
+/* IPI vector/priority reg */
+#define OPENPIC_IPI_VECTOR(ipi) (0x10a0 + (ipi) * 0x10)
+
+/* spurious intr. vector */
+#define OPENPIC_SPURIOUS_VECTOR 0x10e0
+
+
+/*
+ * INTERRUPT SOURCE register (IDU base + 0x10000)
+ */
+
+/* interrupt vector/priority reg */
+#define OPENPIC_SRC_VECTOR(irq) (0x10000 + (irq) * 0x20)
+#define OPENPIC_SENSE_LEVEL 0x00400000
+#define OPENPIC_SENSE_EDGE 0x00000000
+#define OPENPIC_POLARITY_POSITIVE 0x00800000
+#define OPENPIC_POLARITY_NEGATIVE 0x00000000
+#define OPENPIC_IMASK 0x80000000
+#define OPENPIC_ACTIVITY 0x40000000
+#define OPENPIC_PRIORITY_MASK 0x000f0000
+#define OPENPIC_PRIORITY_SHIFT 16
+#define OPENPIC_VECTOR_MASK 0x000000ff
+
+/* interrupt destination cpu */
+#define OPENPIC_SRC_DEST(irq) (0x10010 + (irq) * 0x20)
+
+#define CPU(x) (1 << (x))
+
+/*
+ * PROCESSOR register (IDU base + 0x20000)
+ */
+
+/* IPI command reg */
+#define OPENPIC_IPI(cpu, ipi) (0x20040 + (cpu) * 0x1000 + (ipi))
+
+/* current task priority reg */
+#define OPENPIC_CPU_PRIORITY(cpu) (0x20080 + (cpu) * 0x1000)
+#define OPENPIC_CPU_PRIORITY_MASK 0x0000000f
+
+/* interrupt acknowledge reg */
+#define OPENPIC_IACK(cpu) (0x200a0 + (cpu) * 0x1000)
+
+/* end of interrupt reg */
+#define OPENPIC_EOI(cpu) (0x200b0 + (cpu) * 0x1000)
diff --git a/sys/arch/mvmeppc/dev/raven.c b/sys/arch/mvmeppc/dev/raven.c
new file mode 100644
index 00000000000..f198db8e83c
--- /dev/null
+++ b/sys/arch/mvmeppc/dev/raven.c
@@ -0,0 +1,99 @@
+/* $OpenBSD: raven.c,v 1.1 2001/06/26 21:57:41 smurph Exp $ */
+
+/*
+ * Copyright (c) 2001 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed under OpenBSD for RTMX Inc
+ * by Per Fogelstrom, Opsycon AB.
+ * 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.
+ *
+ */
+
+/*
+ * Motorola 'Raven' ASIC driver.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
+#include <sys/proc.h>
+#include <vm/vm.h>
+
+#include <machine/autoconf.h>
+
+#include <mvmeppc/dev/ravenreg.h>
+#include <mvmeppc/dev/ravenvar.h>
+
+int raven_match __P((struct device *, void *, void *));
+void raven_attach __P((struct device *, struct device *, void *));
+
+struct cfattach raven_ca = {
+ sizeof(struct raven_softc), raven_match, raven_attach,
+};
+
+struct cfdriver raven_cd = {
+ NULL, "raven", DV_DULL,
+};
+
+int
+raven_match(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct confargs *ca = aux;
+ unsigned *reg = (unsigned *)RAVEN_REG;
+
+ /* check for a live address */
+ if (badaddr((char *)reg, 4))
+ return 0;
+
+ /* now check and see if it's a raven ASIC */
+ if (*reg != RAVEN_MAGIC)
+ return 0;
+
+ return 1;
+}
+
+void
+raven_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct raven_softc *sc = (struct raven_softc *)self;
+ struct confargs *ca = aux;
+ struct mpic_feature *feature = (struct mpic_feature *)MPCIC_FEATURE;
+
+ /* set system type */
+ system_type = MVME; /* We are a Motorola MVME SBC */
+
+ printf(": RAVEN, Version 0x%x.\n", feature->vid);
+ while (config_found(self, NULL, NULL))
+ ;
+}
+
+
diff --git a/sys/arch/mvmeppc/dev/ravenreg.h b/sys/arch/mvmeppc/dev/ravenreg.h
new file mode 100644
index 00000000000..295e4b5e717
--- /dev/null
+++ b/sys/arch/mvmeppc/dev/ravenreg.h
@@ -0,0 +1,123 @@
+/* $OpenBSD: ravenreg.h,v 1.1 2001/06/26 21:57:41 smurph Exp $ */
+
+/*
+ * Copyright (c) 2001 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed under OpenBSD for RTMX Inc
+ * by Per Fogelstrom, Opsycon AB.
+ * 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.
+ *
+ *
+ * ravenreg.h: Motorola 'Raven' PowerPC to PCI bridge controller
+ */
+
+#ifndef _MACHINE_RAVENREG_H_
+#define _MACHINE_RAVENREG_H_
+
+#define RAVEN_REG 0xFEFF0000
+#define RAVEN_VENDOR 0xFEFF0000
+#define RAVEN_MAGIC 0x10574801 /* vendor information */
+#define RAVEN_DEVICE 0xFEFF0002
+#define RAVEN_REVID 0xFEFF0005
+#define RAVEN_GCSR 0xFEFF0008
+#define RAVEN_FEAT 0xFEFF000A
+#define RAVEN_MARB 0xFEFF000E
+#define RAVEN_PIACK 0xFEFF0030
+
+#define RAVEN_MSADD0 0xFEFF0040
+#define RAVEN_MSADD0_PREP 0xC000FCFF
+#define RAVEN_MSOFF0 0xFEFF0044
+#define RAVEN_MSOFF0_PREP 0x400000C2
+#define RAVEN_MSADD1 0xFEFF0048
+#define RAVEN_MSADD1_PREP 0x00000000
+#define RAVEN_MSOFF1 0xFEFF004C
+#define RAVEN_MSOFF1_PREP 0x00000002
+#define RAVEN_MSADD2 0xFEFF0050
+#define RAVEN_MSADD2_PREP 0x00000000
+#define RAVEN_MSOFF2 0xFEFF0054
+#define RAVEN_MSOFF2_PREP 0x00000002
+#define RAVEN_MSADD3 0xFEFF0058
+#define RAVEN_MSADD3_PREP 0x8000BFFF
+#define RAVEN_MSOFF3 0xFEFF005C
+#define RAVEN_MSOFF3_PREP 0x800000C0
+
+/* Where we map the PCI memory space - MAP A*/
+#define RAVEN_V_PCI_MEM_SPACE 0xc0000000 /* Viritual */
+#define RAVEN_P_PCI_MEM_SPACE 0xc0000000 /* Physical */
+
+/* Where we map the PCI I/O space - MAP A*/
+#define RAVEN_P_ISA_IO_SPACE 0x80000000
+#define RAVEN_V_ISA_IO_SPACE 0x80000000
+#define RAVEN_V_PCI_IO_SPACE 0x80000000
+#define RAVEN_P_PCI_IO_SPACE 0x80000000
+
+#define PREP_CONFIG_ADD 0x80000CF8
+#define PREP_CONFIG_DAT 0x80000CFC
+
+/* Where we map the config space */
+#define RAVEN_PCI_CONF_SPACE (RAVEN_V_ISA_IO_SPACE + 0x00800000)
+
+/* Where we map the PCI memory space - MAP B*/
+#define RAVEN_P_PCI_MEM_SPACE_MAP_B 0x80000000 /* Physical */
+
+/* Where we map the PCI I/O space - MAP B*/
+#define RAVEN_P_PCI_IO_SPACE_MAP_B 0xfe000000
+
+/* offsets from base pointer */
+#define RAVEN_REGOFFS(x) ((x) | 0x80000000)
+
+/* Where PCI devices sees CPU memory. */
+#define RAVEN_PCI_CPUMEM 0x80000000
+
+#define RAVEN_PCI_VENDOR 0x00
+#define RAVEN_PCI_DEVICE 0x02
+#define RAVEN_PCI_CMD 0x04
+#define RAVEN_PCI_STAT 0x06
+#define RAVEN_PCI_REVID 0x08
+#define RAVEN_PCI_IO 0x10
+#define RAVEN_PCI_MEM 0x14
+#define RAVEN_PCI_PSADD0 0x80
+#define RAVEN_PCI_PSADD0_VAL 0x8000FBFF
+#define RAVEN_PCI_PSOFF0 0x84
+#define RAVEN_PCI_PSOFF0_VAL 0x800000F0
+#define RAVEN_PCI_PSADD1 0x88
+#define RAVEN_PCI_PSADD1_VAL 0xC000FCFF
+#define RAVEN_PCI_PSOFF1 0x8C
+#define RAVEN_PCI_PSOFF1_VAL 0x400000F0
+#define RAVEN_PCI_PSADD2 0x90
+#define RAVEN_PCI_PSADD2_VAL 0x00000000
+#define RAVEN_PCI_PSOFF2 0x94
+#define RAVEN_PCI_PSOFF2_VAL 0x00000000
+#define RAVEN_PCI_PSADD3 0x98
+#define RAVEN_PCI_PSADD3_VAL 0x00000000
+#define RAVEN_PCI_PSOFF3 0x9C
+#define RAVEN_PCI_PSOFF3_VAL 0x00000000
+
+#define RAVEN_CMD_IOSP 0x0001
+#define RAVEN_CMD_MEMSP 0x0002
+#define RAVEN_CMD_MASTR 0x0004
+
+#endif /* _MACHINE_RAVENREG_H_ */
diff --git a/sys/arch/mvmeppc/dev/ravenvar.h b/sys/arch/mvmeppc/dev/ravenvar.h
new file mode 100644
index 00000000000..2d922a1bb80
--- /dev/null
+++ b/sys/arch/mvmeppc/dev/ravenvar.h
@@ -0,0 +1,387 @@
+/* $OpenBSD: ravenvar.h,v 1.1 2001/06/26 21:57:42 smurph Exp $ */
+
+/*
+ * Copyright (c) 2001 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed under OpenBSD for RTMX Inc
+ * by Per Fogelstrom, Opsycon AB.
+ * 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.
+ *
+ *
+ * ravenreg.h: Motorola 'Raven' PowerPC to PCI bridge controller
+ */
+
+#ifndef _DEV_RAVENVAR_H_
+#define _DEV_RAVENREG_H_
+
+#define MPCIC_REG 0xFC000000
+#define MPCIC_FEATURE (MPCIC_REG | 0x01000)
+#define MPCIC_GCR (MPCIC_REG | 0x01020)
+#define MPCIC_VID (MPCIC_REG | 0x01080)
+#define MPCIC_PINIT (MPCIC_REG | 0x01090)
+#define MPCIC_IPI0 (MPCIC_REG | 0x010A0)
+#define MPCIC_IPI1 (MPCIC_REG | 0x010B0)
+#define MPCIC_IPI2 (MPCIC_REG | 0x010C0)
+#define MPCIC_IPI3 (MPCIC_REG | 0x010D0)
+#define MPCIC_SP (MPCIC_REG | 0x010E0)
+#define MPCIC_TFR (MPCIC_REG | 0x010F0)
+#define MPCIC_T0CC (MPCIC_REG | 0x01100)
+#define MPCIC_T0BC (MPCIC_REG | 0x01110)
+#define MPCIC_T0VP (MPCIC_REG | 0x01120)
+#define MPCIC_T0D (MPCIC_REG | 0x01130)
+#define MPCIC_T1CC (MPCIC_REG | 0x01140)
+#define MPCIC_T1BC (MPCIC_REG | 0x01150)
+#define MPCIC_T1VP (MPCIC_REG | 0x01160)
+#define MPCIC_T1D (MPCIC_REG | 0x01170)
+#define MPCIC_T2CC (MPCIC_REG | 0x01180)
+#define MPCIC_T2BC (MPCIC_REG | 0x01190)
+#define MPCIC_T2VP (MPCIC_REG | 0x011A0)
+#define MPCIC_T2D (MPCIC_REG | 0x011B0)
+#define MPCIC_T3CC (MPCIC_REG | 0x011C0)
+#define MPCIC_T3BC (MPCIC_REG | 0x011D0)
+#define MPCIC_T3VP (MPCIC_REG | 0x011E0)
+#define MPCIC_T3D (MPCIC_REG | 0x011F0)
+#define MPCIC_INT0VP (MPCIC_REG | 0x10000)
+#define MPCIC_INT0D (MPCIC_REG | 0x10010)
+#define MPCIC_INT1VP (MPCIC_REG | 0x10020)
+#define MPCIC_INT1D (MPCIC_REG | 0x10030)
+#define MPCIC_INT2VP (MPCIC_REG | 0x10040)
+#define MPCIC_INT2D (MPCIC_REG | 0x10050)
+#define MPCIC_INT3VP (MPCIC_REG | 0x10060)
+#define MPCIC_INT3D (MPCIC_REG | 0x10070)
+#define MPCIC_INT4VP (MPCIC_REG | 0x10080)
+#define MPCIC_INT4D (MPCIC_REG | 0x10090)
+#define MPCIC_INT5VP (MPCIC_REG | 0x100A0)
+#define MPCIC_INT5D (MPCIC_REG | 0x100B0)
+#define MPCIC_INT6VP (MPCIC_REG | 0x100C0)
+#define MPCIC_INT6D (MPCIC_REG | 0x100D0)
+#define MPCIC_INT7VP (MPCIC_REG | 0x100E0)
+#define MPCIC_INT7D (MPCIC_REG | 0x100F0)
+#define MPCIC_INT8VP (MPCIC_REG | 0x10100)
+#define MPCIC_INT8D (MPCIC_REG | 0x10110)
+#define MPCIC_INT9VP (MPCIC_REG | 0x10120)
+#define MPCIC_INT9D (MPCIC_REG | 0x10130)
+#define MPCIC_INT10VP (MPCIC_REG | 0x10140)
+#define MPCIC_INT10D (MPCIC_REG | 0x10150)
+#define MPCIC_INT11VP (MPCIC_REG | 0x10160)
+#define MPCIC_INT11D (MPCIC_REG | 0x10170)
+#define MPCIC_INT12VP (MPCIC_REG | 0x10180)
+#define MPCIC_INT12D (MPCIC_REG | 0x10190)
+#define MPCIC_INT13VP (MPCIC_REG | 0x101A0)
+#define MPCIC_INT13D (MPCIC_REG | 0x101B0)
+#define MPCIC_INT14VP (MPCIC_REG | 0x101C0)
+#define MPCIC_INT14D (MPCIC_REG | 0x101D0)
+#define MPCIC_INT15VP (MPCIC_REG | 0x101E0)
+#define MPCIC_INT15D (MPCIC_REG | 0x101F0)
+#define MPCIC_EVP (MPCIC_REG | 0x10200)
+#define MPCIC_ED (MPCIC_REG | 0x10210)
+#define MPCIC_P0_IPI0_D (MPCIC_REG | 0x20040)
+#define MPCIC_P0_IPI1_D (MPCIC_REG | 0x20050)
+#define MPCIC_P0_IPI2_D (MPCIC_REG | 0x20060)
+#define MPCIC_P0_IPI3_D (MPCIC_REG | 0x20070)
+#define MPCIC_P0_TP (MPCIC_REG | 0x20080)
+#define MPCIC_P0_IACK (MPCIC_REG | 0x200A0)
+#define MPCIC_P0_EOI (MPCIC_REG | 0x200B0)
+#define MPCIC_P1_IPI0_D (MPCIC_REG | 0x21040)
+#define MPCIC_P1_IPI1_D (MPCIC_REG | 0x21050)
+#define MPCIC_P1_IPI2_D (MPCIC_REG | 0x21060)
+#define MPCIC_P1_IPI3_D (MPCIC_REG | 0x21070)
+#define MPCIC_P1_TP (MPCIC_REG | 0x21080)
+#define MPCIC_P1_IACK (MPCIC_REG | 0x210A0)
+#define MPCIC_P1_EOI (MPCIC_REG | 0x210B0)
+
+#define PROC0 0x01
+#define PROC1 0x02
+
+#define GCR_M 0x04
+#define VP_MASKED 0x00000080
+#define VP_LEVEL 0x00004000
+#define VP_POL 0x00008000
+#define VP_VEC(x) ((x) << 24)
+#define VP_PRI(x) ((x) << 8)
+
+struct mpic_feature {
+ unsigned int res1 : 4,
+ nirq : 12,
+ res2 : 3,
+ ncpu : 5,
+ vid : 8;
+};
+
+struct mpic_gcr {
+ unsigned int reset : 1,
+ res1 : 1,
+ cmode : 1,
+ res2 : 29;
+};
+
+struct mpic_vid {
+ unsigned int res1 : 8,
+ stp : 8,
+ res2 : 16;
+};
+
+
+struct mpic_ipivp {
+ unsigned int masked : 1,
+ act : 1,
+ res1 : 10,
+ pri : 4,
+ res2 : 8,
+ vec : 8;
+};
+
+struct mpic_timer_count {
+ unsigned int toggle : 1,
+ count : 31;
+};
+
+struct mpic_timer_bcount {
+ unsigned int inhib : 1,
+ count : 31;
+};
+
+struct mpic_timer_vp {
+ unsigned int masked : 1,
+ act : 1,
+ res1 : 10,
+ pri : 4,
+ res2 : 8,
+ vec : 8;
+};
+
+struct mpic_timer {
+ struct mpic_timer_count *cr;
+ struct mpic_timer_bcount *bcr;
+ struct mpic_timer_vp *vp;
+ unsigned char *dest;
+};
+
+struct mpic_ext_vp {
+ unsigned int masked : 1,
+ act : 1,
+ res1 : 6,
+ polarity : 1,
+ sense : 1,
+ res2 : 2,
+ pri : 4,
+ res3 : 8,
+ vec : 8;
+};
+
+struct mpic_ext_intr {
+ volatile unsigned int *vp;
+ volatile unsigned char *dest;
+};
+
+struct mpic_err_vp {
+ unsigned int masked : 1,
+ act : 1,
+ res3 : 7,
+ sense : 1,
+ res2 : 2,
+ pri : 4,
+ res1 : 8,
+ vec : 8;
+};
+
+#if 1
+struct raven_reg {
+ struct mpic_feature *feature;
+ unsigned int *gcr;
+ struct mpic_vid *vid;
+ char *p_init;
+ struct mpic_ipivp *ipi[4];
+ char *sp;
+ unsigned int *timer_freq;
+ struct mpic_timer timer[4];
+ /* external interrupt configuration registers */
+ struct mpic_ext_intr extint[16];
+ unsigned int *p0_ipi0d;
+ unsigned int *p0_ipi1d;
+ unsigned int *p0_ipi2d;
+ unsigned int *p0_ipi3d;
+ unsigned int *p1_ipi0d;
+ unsigned int *p1_ipi1d;
+ unsigned int *p1_ipi2d;
+ unsigned int *p1_ipi3d;
+ /* task priority registers (IPL) */
+ unsigned char *tp[2];
+ /* interrupt acknowledge registers */
+ volatile unsigned char *iack[2];
+ /* end of interrupt registers */
+ volatile unsigned char *eio[2];
+};
+
+#else
+struct raven_reg {
+ struct mpic_feature *feature = (struct mpic_feature *)MPCIC_FEATURE;
+ struct mpic_gcr *gcr = (struct mpic_gcr *)MPCIC_GCR;
+ struct mpic_vid *vid = (struct mpic_vid *)MPCIC_VID;
+ char *p_init = (char *)MPCIC_PINIT;
+#if 0
+ struct mpic_ipivp *ipi0 = (struct mpic_ipivp *)MPCIC_IPI0;
+ struct mpic_ipivp *ipi1 = (struct mpic_ipivp *)MPCIC_IPI1;
+ struct mpic_ipivp *ipi2 = (struct mpic_ipivp *)MPCIC_IPI2;
+ struct mpic_ipivp *ipi3 = (struct mpic_ipivp *)MPCIC_IPI3;
+#else
+ struct mpic_ipivp *ipi[4] = {
+ (struct mpic_ipivp *)MPCIC_IPI0,
+ (struct mpic_ipivp *)MPCIC_IPI1,
+ (struct mpic_ipivp *)MPCIC_IPI2,
+ (struct mpic_ipivp *)MPCIC_IPI3,
+ };
+#endif
+ char *sp = (char *)MPCIC_SP;
+ unsigned int *timer_freq = (unsigned int *)MPCIC_TFR;
+#if 1
+ struct mpic_timer timer[4] = {
+ {(struct mpic_timer_count *)MPCIC_T0CC,
+ (struct mpic_timer_bcount *)MPCIC_T0BC,
+ (struct mpic_timer_vp *)MPCIC_T0VP,
+ (unsigned char *)MPCIC_T0D},
+ {(struct mpic_timer_count *)MPCIC_T1CC,
+ (struct mpic_timer_bcount *)MPCIC_T1BC,
+ (struct mpic_timer_vp *)MPCIC_T1VP,
+ (unsigned char *)MPCIC_T1D},
+ {(struct mpic_timer_count *)MPCIC_T2CC,
+ (struct mpic_timer_bcount *)MPCIC_T2BC,
+ (struct mpic_timer_vp *)MPCIC_T2VP,
+ (unsigned char *)MPCIC_T2D},
+ {(struct mpic_timer_count *)MPCIC_T3CC,
+ (struct mpic_timer_bcount *)MPCIC_T3BC,
+ (struct mpic_timer_vp *)MPCIC_T3VP,
+ (unsigned char *)MPCIC_T3D}
+ };
+#else
+ struct mpic_timer_count *t0c = (struct mpic_timer_count *)MPCIC_T0CC;
+ struct mpic_timer_bcount *t0bc = (struct mpic_timer_bcount *)MPCIC_T0BC;
+ struct mpic_timer_vp *t0vp = (struct mpic_timer_vp *)MPCIC_T0VP;
+ unsigned int *t0d = (unsigned int *)MPCIC_T0D;
+ struct mpic_timer_count *t1c = (struct mpic_timer_count *)MPCIC_T1CC;
+ struct mpic_timer_bcount *t1bc = (struct mpic_timer_bcount *)MPCIC_T1BC;
+ struct mpic_timer_vp *t1vp = (struct mpic_timer_vp *)MPCIC_T1VP;
+ unsigned int *t1d = (unsigned int *)MPCIC_T1D;
+ struct mpic_timer_count *t2c = (struct mpic_timer_count *)MPCIC_T2CC;
+ struct mpic_timer_bcount *t2bc = (struct mpic_timer_bcount *)MPCIC_T2BC;
+ struct mpic_timer_vp *t2vp = (struct mpic_timer_vp *)MPCIC_T2VP;
+ unsigned int *t2d = (unsigned int *)MPCIC_T2D;
+ struct mpic_timer_count *t3c = (struct mpic_timer_count *)MPCIC_T3CC;
+ struct mpic_timer_bcount *t3bc = (struct mpic_timer_bcount *)MPCIC_T3BC;
+ struct mpic_timer_vp *t3vp = (struct mpic_timer_vp *)MPCIC_T3VP;
+ unsigned int *t3d = (unsigned int *)MPCIC_T3D;
+#endif
+
+#if 1
+ /* external interrupt configuration registers */
+ struct mpic_ext_intr extint[16] = {
+ {(struct mpic_ext_vp *)MPCIC_INT0VP, (unsigned char *)MPCIC_INT0D},
+ {(struct mpic_ext_vp *)MPCIC_INT1VP, (unsigned char *)MPCIC_INT1D},
+ {(struct mpic_ext_vp *)MPCIC_INT2VP, (unsigned char *)MPCIC_INT2D},
+ {(struct mpic_ext_vp *)MPCIC_INT3VP, (unsigned char *)MPCIC_INT3D},
+ {(struct mpic_ext_vp *)MPCIC_INT4VP, (unsigned char *)MPCIC_INT4D},
+ {(struct mpic_ext_vp *)MPCIC_INT5VP, (unsigned char *)MPCIC_INT5D},
+ {(struct mpic_ext_vp *)MPCIC_INT6VP, (unsigned char *)MPCIC_INT6D},
+ {(struct mpic_ext_vp *)MPCIC_INT7VP, (unsigned char *)MPCIC_INT7D},
+ {(struct mpic_ext_vp *)MPCIC_INT8VP, (unsigned char *)MPCIC_INT8D},
+ {(struct mpic_ext_vp *)MPCIC_INT9VP, (unsigned char *)MPCIC_INT9D},
+ {(struct mpic_ext_vp *)MPCIC_INT1VP, (unsigned char *)MPCIC_INT10D},
+ {(struct mpic_ext_vp *)MPCIC_INT11VP, (unsigned char *)MPCIC_INT11D},
+ {(struct mpic_ext_vp *)MPCIC_INT12VP, (unsigned char *)MPCIC_INT12D},
+ {(struct mpic_ext_vp *)MPCIC_INT13VP, (unsigned char *)MPCIC_INT13D},
+ {(struct mpic_ext_vp *)MPCIC_INT14VP, (unsigned char *)MPCIC_INT14D},
+ {(struct mpic_ext_vp *)MPCIC_INT16VP, (unsigned char *)MPCIC_INT15D}
+ };
+#else
+ struct mpic_ext_vp *ext0vp = (struct mpic_ext_vp *)MPCIC_INT0VP;
+ unsigned int *ext0d = (unsigned int *)MPCIC_INT0D;
+ struct mpic_ext_vp *ext1vp = (struct mpic_ext_vp *)MPCIC_INT1VP;
+ unsigned int *ext1d = (unsigned int *)MPCIC_INT1D;
+ struct mpic_ext_vp *ext2vp = (struct mpic_ext_vp *)MPCIC_INT2VP;
+ unsigned int *ext2d = (unsigned int *)MPCIC_INT2D;
+ struct mpic_ext_vp *ext3vp = (struct mpic_ext_vp *)MPCIC_INT3VP;
+ unsigned int *ext3d = (unsigned int *)MPCIC_INT3D;
+ struct mpic_ext_vp *ext4vp = (struct mpic_ext_vp *)MPCIC_INT4VP;
+ unsigned int *ext4d = (unsigned int *)MPCIC_INT4D;
+ struct mpic_ext_vp *ext5vp = (struct mpic_ext_vp *)MPCIC_INT5VP;
+ unsigned int *ext5d = (unsigned int *)MPCIC_INT5D;
+ struct mpic_ext_vp *ext6vp = (struct mpic_ext_vp *)MPCIC_INT6VP;
+ unsigned int *ext6d = (unsigned int *)MPCIC_INT6D;
+ struct mpic_ext_vp *ext7vp = (struct mpic_ext_vp *)MPCIC_INT7VP;
+ unsigned int *ext7d = (unsigned int *)MPCIC_INT7D;
+ struct mpic_ext_vp *ext8vp = (struct mpic_ext_vp *)MPCIC_INT8VP;
+ unsigned int *ext8d = (unsigned int *)MPCIC_INT8D;
+ struct mpic_ext_vp *ext9vp = (struct mpic_ext_vp *)MPCIC_INT9VP;
+ unsigned int *ext9d = (unsigned int *)MPCIC_INT9D;
+ struct mpic_ext_vp *ext10vp = (struct mpic_ext_vp *)MPCIC_INT10VP;
+ unsigned int *ext10d = (unsigned int *)MPCIC_INT10D;
+ struct mpic_ext_vp *ext11vp = (struct mpic_ext_vp *)MPCIC_INT11VP;
+ unsigned int *ext11d = (unsigned int *)MPCIC_INT11D;
+ struct mpic_ext_vp *ext12vp = (struct mpic_ext_vp *)MPCIC_INT12VP;
+ unsigned int *ext12d = (unsigned int *)MPCIC_INT12D;
+ struct mpic_ext_vp *ext13vp = (struct mpic_ext_vp *)MPCIC_INT13VP;
+ unsigned int *ext13d = (unsigned int *)MPCIC_INT13D;
+ struct mpic_ext_vp *ext14vp = (struct mpic_ext_vp *)MPCIC_INT14VP;
+ unsigned int *ext14d = (unsigned int *)MPCIC_INT14D;
+ struct mpic_ext_vp *ext15vp = (struct mpic_ext_vp *)MPCIC_INT15VP;
+ unsigned int *ext15d = (unsigned int *)MPCIC_INT15D;
+ struct mpic_err_vp *errvp = (struct mpic_err_vp *)MPCIC_EVP;
+ unsigned int *errd = (unsigned int *)MPCIC_ED;
+#endif
+ unsigned int *p0_ipi0d = (unsigned int *)MPCIC_P0_IPI0_D;
+ unsigned int *p0_ipi1d = (unsigned int *)MPCIC_P0_IPI1_D;
+ unsigned int *p0_ipi2d = (unsigned int *)MPCIC_P0_IPI2_D;
+ unsigned int *p0_ipi3d = (unsigned int *)MPCIC_P0_IPI3_D;
+ unsigned int *p1_ipi0d = (unsigned int *)MPCIC_P1_IPI0_D;
+ unsigned int *p1_ipi1d = (unsigned int *)MPCIC_P1_IPI1_D;
+ unsigned int *p1_ipi2d = (unsigned int *)MPCIC_P1_IPI2_D;
+ unsigned int *p1_ipi3d = (unsigned int *)MPCIC_P1_IPI3_D;
+
+ /* task priority registers (IPL) */
+ unsigned char *tp[2] = {
+ (unsigned char *)MPCIC_P0_TP,
+ (unsigned char *)MPCIC_P1_TP
+ };
+ /* interrupt acknowledge registers */
+ volatile unsigned char *iack[2] = {
+ (volatile unsigned char *)MPCIC_P0_IACK,
+ (volatile unsigned char *)MPCIC_P1_IACK
+ };
+ /* end of interrupt registers */
+ volatile unsigned char *eio[2] = {
+ (volatile unsigned char *)MPCIC_P0_EOI,
+ (volatile unsigned char *)MPCIC_P1_EOI,
+ };
+}
+#endif
+
+struct raven_softc {
+ struct device sc_dev;
+ struct raven_reg *sc_reg;
+};
+
+
+#endif /* _DEV_RAVENVAR_H_ */