diff options
author | Steve Murphree <smurph@cvs.openbsd.org> | 2001-06-26 21:58:11 +0000 |
---|---|---|
committer | Steve Murphree <smurph@cvs.openbsd.org> | 2001-06-26 21:58:11 +0000 |
commit | 416f561c78b0eca90fdb484e72a96080b0825dca (patch) | |
tree | d310db0254b85229b90b9d90e79cabfbbcb6101a /sys/arch/mvmeppc/dev | |
parent | 77682e0d8d22531ed2952aaab30aae7c69483b3d (diff) |
Initial import of mvmeppc.
Diffstat (limited to 'sys/arch/mvmeppc/dev')
-rw-r--r-- | sys/arch/mvmeppc/dev/bugio.c | 482 | ||||
-rw-r--r-- | sys/arch/mvmeppc/dev/bugtty.c | 492 | ||||
-rw-r--r-- | sys/arch/mvmeppc/dev/clock.c | 397 | ||||
-rw-r--r-- | sys/arch/mvmeppc/dev/cpu.c | 267 | ||||
-rw-r--r-- | sys/arch/mvmeppc/dev/mainbus.c | 159 | ||||
-rw-r--r-- | sys/arch/mvmeppc/dev/mem.c | 176 | ||||
-rw-r--r-- | sys/arch/mvmeppc/dev/nvramreg.h | 86 | ||||
-rw-r--r-- | sys/arch/mvmeppc/dev/openpic.c | 1035 | ||||
-rw-r--r-- | sys/arch/mvmeppc/dev/openpicreg.h | 90 | ||||
-rw-r--r-- | sys/arch/mvmeppc/dev/raven.c | 99 | ||||
-rw-r--r-- | sys/arch/mvmeppc/dev/ravenreg.h | 123 | ||||
-rw-r--r-- | sys/arch/mvmeppc/dev/ravenvar.h | 387 |
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_ */ |