From: aoyama Date: Fri, 19 Dec 2014 13:17:35 +0000 (+0000) Subject: Move cbus.c, cbusvar.h, and pcex.c to new 'cbus' directory, to gather X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=f136e85a4200534dbe51aaf11ad27b9b21fe8762;p=openbsd Move cbus.c, cbusvar.h, and pcex.c to new 'cbus' directory, to gather 'C-bus' device drivers in it. More devices on cbus(4) will be added, hopefully :-) ok miod@ --- diff --git a/sys/arch/luna88k/cbus/cbus.c b/sys/arch/luna88k/cbus/cbus.c new file mode 100644 index 00000000000..571296b137c --- /dev/null +++ b/sys/arch/luna88k/cbus/cbus.c @@ -0,0 +1,297 @@ +/* $OpenBSD: cbus.c,v 1.1 2014/12/19 13:17:35 aoyama Exp $ */ + +/* + * Copyright (c) 2014 Kenji Aoyama. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * PC-9801 extension board slot bus ('C-bus') driver for LUNA-88K2. + */ + +#include +#include +#include +#include + +#include /* ff1() */ +#include +#include /* PC_BASE */ + +#include +#include /* isrlink_autovec() */ + +#if 0 +#define CBUS_DEBUG +#endif + +/* + * C-bus interrupt status register + */ +#define CBUS_INTR_STAT_REG (PC_BASE + 0x1100000) +volatile u_int8_t *cbus_isreg = (u_int8_t *)CBUS_INTR_STAT_REG; + +/* autoconf stuff */ +int cbus_match(struct device *, void *, void *); +void cbus_attach(struct device *, struct device *, void *); +int cbus_print(void *, const char *); + +struct cbus_softc { + struct device sc_dev; + struct cbus_isr_t cbus_isr[NCBUSISR]; + u_int8_t registered; +}; + +const struct cfattach cbus_ca = { + sizeof(struct cbus_softc), cbus_match, cbus_attach +}; + +struct cfdriver cbus_cd = { + NULL, "cbus", DV_DULL +}; + +/* prototypes */ +int cbus_isrlink(int (*)(void *), void *, int, const char *); +int cbus_isrunlink(int (*)(void *), int); +void cbus_isrdispatch(int); +int cbus_intr(void *); + +int +cbus_match(struct device *parent, void *cf, void *aux) +{ + struct mainbus_attach_args *ma = aux; + + if (strcmp(ma->ma_name, cbus_cd.cd_name)) + return 0; +#if 0 + if (badaddr((vaddr_t)ma->ma_addr, 4)) + return 0; +#endif + return 1; +} + +void +cbus_attach(struct device *parent, struct device *self, void *args) +{ + struct cbus_softc *sc = (struct cbus_softc *)self; + struct mainbus_attach_args *ma = args; + struct cbus_attach_args caa; + int i; + + for (i = 0; i < NCBUSISR; i++) { + sc->cbus_isr[i].isr_func = NULL; + /* clearing interrupt flags (INT0-INT6) */ + *cbus_isreg = (u_int8_t)i; + } + + /* register C-bus interrupt service routine on mainbus */ + isrlink_autovec(cbus_intr, (void *)self, ma->ma_ilvl, + ISRPRI_TTY, self->dv_xname); + + printf("\n"); + + caa.intlevel = -1; /* not specified */ + config_found(self, &caa, cbus_print); + return; +} + +int +cbus_print(void *aux, const char *pnp) +{ + struct cbus_attach_args *caa = aux; +#if 0 /* not yet */ + if (pnp) + printf("%s at %s", caa->name, pnp); /* not configured */ +#endif + if (caa->intlevel != -1) + printf(" INT %d", caa->intlevel); + + return UNCONF; +} + +/* + * Register a C-bus interrupt service routine. + */ +int +cbus_isrlink(int (*func)(void *), void *arg, int ipl, const char *name) +{ + struct cbus_softc *sc = NULL; + + if (cbus_cd.cd_ndevs != 0) + sc = cbus_cd.cd_devs[0]; + if (sc == NULL) + panic("cbus_isrlink: can't find cbus_softc"); + +#ifdef DIAGNOSTIC + if (ipl < 0 || ipl >= NCBUSISR) { + printf("cbus_isrlink: bad ipl %d\n", ipl); + return -1; + } +#endif + + if (sc->cbus_isr[ipl].isr_func != NULL) { + printf("cbus_isrlink: isr already assigned on INT%d\n", ipl); + return -1; + } + + /* set the entry */ + sc->cbus_isr[ipl].isr_func = func; + sc->cbus_isr[ipl].isr_arg = arg; + evcount_attach(&(sc->cbus_isr[ipl].isr_count), name, &ipl); + sc->registered |= (1 << (6 - ipl)); +#ifdef CBUS_DEBUG + printf("cbus_isrlink: sc->registered = 0x%02x\n", sc->registered); +#endif + + return 0; +} + +/* + * Unregister a C-bus interrupt service routine. + */ +int +cbus_isrunlink(int (*func)(void *), int ipl) +{ + struct cbus_softc *sc = NULL; + + if (cbus_cd.cd_ndevs != 0) + sc = cbus_cd.cd_devs[0]; + if (sc == NULL) + panic("cbus_isrunlink: can't find cbus_softc"); + +#ifdef DIAGNOSTIC + if (ipl < 0 || ipl >= NCBUSISR) { + printf("cbus_isrunlink: bad ipl %d\n", ipl); + return -1; + } +#endif + + if (sc->cbus_isr[ipl].isr_func == NULL) { + printf("cbus_isrunlink: isr not assigned on INT%d\n", ipl); + return -1; + } + + /* reset the entry */ + sc->cbus_isr[ipl].isr_func = NULL; + sc->cbus_isr[ipl].isr_arg = NULL; + evcount_detach(&(sc->cbus_isr[ipl].isr_count)); + sc->registered &= ~(1 << (6 - ipl)); +#ifdef CBUS_DEBUG + printf("cbus_isrunlink: sc->registered = 0x%02x\n", sc->registered); +#endif + + return 0; +} + +/* + * Dispatch C-bus interrupt service routines. + */ +void +cbus_isrdispatch(int ipl) +{ + int rc; + static int straycount, unexpected; + struct cbus_softc *sc = NULL; + + if (cbus_cd.cd_ndevs != 0) + sc = cbus_cd.cd_devs[0]; + if (sc == NULL) + panic("cbus_isrdispatch: can't find cbus_softc"); + +#ifdef DIAGNOSTIC + if (ipl < 0 || ipl >= NCBUSISR) + panic("cbus_isrdispatch: bad ipl 0x%d", ipl); +#endif + + if (sc->cbus_isr[ipl].isr_func == NULL) { + printf("cbus_isrdispatch: ipl %d unexpected\n", ipl); + if (++unexpected > 10) + panic("too many unexpected interrupts"); + return; + } + + rc = sc->cbus_isr[ipl].isr_func(sc->cbus_isr[ipl].isr_arg); + if (rc != 0) + sc->cbus_isr[ipl].isr_count.ec_count++; + + if (rc) + straycount = 0; + else if (++straycount > 50) + panic("cbus_isrdispatch: too many stray interrupts"); + else + printf("cbus_isrdispatch: stray level %d interrupt\n", ipl); +} + +/* + * Note about interrupt on PC-9801 extension board slot + * + * PC-9801 extension board slot bus (so-called 'C-bus' in Japan) use 8 own + * interrupt levels, INT0-INT6, and NMI. On LUNA-88K2, they all trigger + * level 4 interrupt on mainbus, so we need to check the dedicated interrupt + * status register to know which C-bus interrupt is occurred. + * + * The interrupt status register for C-bus is located at + * (u_int8_t *)CBUS_INTR_STAT. Each bit of the register becomes 0 when + * corresponding C-bus interrupt has occurred, otherwise 1. + * + * bit 7 = NMI(?) + * bit 6 = INT0 + * bit 5 = INT1 + * : + * bit 0 = INT6 + * + * To clear the C-bus interrupt flag, write the corresponding 'bit' number + * (as u_int_8) to the register. For example, if you want to clear INT1, + * you should write '5' like: + * *(u_int8_t *)CBUS_INTR_STAT = 5; + */ + +/* + * Interrupt handler on mainbus. + */ +int +cbus_intr(void *arg) +{ + struct cbus_softc *sc = (struct cbus_softc *)arg; + u_int8_t intr_status; + int n; + + /* + * LUNA-88K2's interrupt level 4 is shared with other devices, + * such as le(4), for example. So we check: + * - the value of our C-bus interrupt status register, and + * - if the INT level is what we are looking for. + */ + intr_status = *cbus_isreg & sc->registered; + if (intr_status == sc->registered) return 0; /* Not for me */ + +#ifdef CBUS_DEBUG + printf("cbus_intr: called, *cbus_isreg=0x%02x, registered = 0x%02x\n", + *cbus_isreg, sc->registered); +#endif + /* Make the bit pattern that we should proces */ + intr_status = intr_status ^ sc->registered; +#ifdef CBUS_DEBUG + printf("cbus_intr: processing 0x%02x\n", intr_status); +#endif + + /* Process, and clear each interrupt flag */ + while ((n = ff1(intr_status)) != 32) { + cbus_isrdispatch(6 - n); + *cbus_isreg = (u_int8_t)n; + intr_status &= ~(1 << n); + } + + return 1; +} diff --git a/sys/arch/luna88k/cbus/cbusvar.h b/sys/arch/luna88k/cbus/cbusvar.h new file mode 100644 index 00000000000..547a2371c16 --- /dev/null +++ b/sys/arch/luna88k/cbus/cbusvar.h @@ -0,0 +1,46 @@ +/* $OpenBSD: cbusvar.h,v 1.1 2014/12/19 13:17:35 aoyama Exp $ */ + +/* + * Copyright (c) 2014 Kenji Aoyama. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * PC-9801 extension board slot bus ('C-bus') driver for LUNA-88K2. + */ + +#include +#include + +/* + * Currently 7 level C-bus interrupts (INT0 - INT6) are supported. + */ +#define NCBUSISR 7 + +/* + * C-bus interrupt handler + */ +struct cbus_isr_t { + int (*isr_func)(void *); + void *isr_arg; + struct evcount isr_count; +}; + +int cbus_isrlink(int (*)(void *), void *, int, const char *); +int cbus_isrunlink(int (*)(void *), int); +void cbus_isrdispatch(int); + +struct cbus_attach_args { + int intlevel; +}; diff --git a/sys/arch/luna88k/cbus/pcex.c b/sys/arch/luna88k/cbus/pcex.c new file mode 100644 index 00000000000..d48962b1c48 --- /dev/null +++ b/sys/arch/luna88k/cbus/pcex.c @@ -0,0 +1,212 @@ +/* $OpenBSD: pcex.c,v 1.1 2014/12/19 13:17:35 aoyama Exp $ */ + +/* + * Copyright (c) 2014 Kenji Aoyama. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * PC-9801 extension board slot direct access driver for LUNA-88K2. + */ + +#include +#include /* tsleep()/wakeup() */ +#include +#include + +#include +#include /* PC_BASE */ +#include +#include + +#include + +extern int hz; + +#if 0 +#define PCEX_DEBUG +#endif + +#define PCEXMEM_BASE PC_BASE +#define PCEXIO_BASE (PC_BASE + 0x1000000) + +/* autoconf stuff */ +int pcex_match(struct device *, void *, void *); +void pcex_attach(struct device *, struct device *, void *); + +struct pcex_softc { + struct device sc_dev; + int intr_use[NCBUSISR]; +}; + +const struct cfattach pcex_ca = { + sizeof(struct pcex_softc), pcex_match, pcex_attach +}; + +struct cfdriver pcex_cd = { + NULL, "pcex", DV_DULL +}; + +/* prototypes */ +int pcex_intr(void *); +int pcex_set_int(struct pcex_softc *, u_int); +int pcex_reset_int(struct pcex_softc *, u_int); +int pcex_wait_int(struct pcex_softc *, u_int); + +int +pcex_match(struct device *parent, void *cf, void *aux) +{ + return 1; /* XXX: always matched */ +} + +void +pcex_attach(struct device *parent, struct device *self, void *args) +{ + struct pcex_softc *sc = (struct pcex_softc *)self; + int i; + + for (i = 0; i < NCBUSISR; i++) + sc->intr_use[i] = 0; + + printf("\n"); + return; +} + +int +pcexopen(dev_t dev, int flag, int mode, struct proc *p) +{ + switch (minor(dev)) { + case 0: /* memory area */ + case 1: /* I/O port area */ + return 0; + default: + return ENXIO; + } +} + +int +pcexclose(dev_t dev, int flag, int mode, struct proc *p) +{ + return (0); +} + +paddr_t +pcexmmap(dev_t dev, off_t offset, int prot) +{ + paddr_t cookie = -1; + + switch (minor(dev)) { + case 0: /* memory area */ + if (offset >= 0 && offset < 0x1000000) + cookie = (paddr_t)(PCEXMEM_BASE + offset); + break; + case 1: /* I/O port area */ + if (offset >= 0 && offset < 0x10000) + cookie = (paddr_t)(PCEXIO_BASE + offset); + break; + default: + break; + } + + return cookie; +} + +int +pcexioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) +{ + struct pcex_softc *sc = NULL; + u_int level; + + if (pcex_cd.cd_ndevs != 0) + sc = pcex_cd.cd_devs[0]; + if (sc == NULL) + return ENXIO; + + level = *(u_int *)data; + + switch(cmd) { + case PCEXSETLEVEL: + return pcex_set_int(sc, level); + + case PCEXRESETLEVEL: + return pcex_reset_int(sc, level); + + case PCEXWAITINT: + return pcex_wait_int(sc, level); + + default: + return ENOTTY; + } +} + +int +pcex_set_int(struct pcex_softc *sc, u_int level) +{ + if (level > 6) + return EINVAL; + if (sc->intr_use[level] != 0) + return EINVAL; /* Duplicate */ + + sc->intr_use[level] = 1; + cbus_isrlink(pcex_intr, &(sc->intr_use[level]), level, + sc->sc_dev.dv_xname); + + return 0; +} + +int +pcex_reset_int(struct pcex_softc *sc, u_int level) +{ + if (level > 6) + return EINVAL; + if (sc->intr_use[level] == 0) + return EINVAL; /* Not registered */ + + sc->intr_use[level] = 0; + cbus_isrunlink(pcex_intr, level); + + return 0; +} + +int +pcex_wait_int(struct pcex_softc *sc, u_int level) +{ + int ret; + + if (level > 6) + return EINVAL; + if (sc->intr_use[level] == 0) + return EINVAL; /* Not registered */ + + ret = tsleep(&(sc->intr_use[level]), PWAIT | PCATCH, "pcex", + hz /* XXX: 1 sec. */); + +#ifdef PCEX_DEBUG + if (ret == EWOULDBLOCK) + printf("pcex_wait_int: timeout in tsleep\n"); +#endif + return ret; +} + +int +pcex_intr(void *arg) +{ +#ifdef PCEX_DEBUG + printf("pcex_intr: called, arg=%p\n", arg); +#endif + /* Just wakeup(9) for now */ + wakeup(arg); + + return 1; +} diff --git a/sys/arch/luna88k/conf/files.luna88k b/sys/arch/luna88k/conf/files.luna88k index 69b87de8953..0acf5f35326 100644 --- a/sys/arch/luna88k/conf/files.luna88k +++ b/sys/arch/luna88k/conf/files.luna88k @@ -1,4 +1,4 @@ -# $OpenBSD: files.luna88k,v 1.22 2014/12/08 13:24:04 aoyama Exp $ +# $OpenBSD: files.luna88k,v 1.23 2014/12/19 13:17:35 aoyama Exp $ # maxpartitions 16 @@ -67,11 +67,11 @@ file arch/luna88k/dev/mb89352.c spc device cbus {} attach cbus at mainbus -file arch/luna88k/dev/cbus.c +file arch/luna88k/cbus/cbus.c device pcex attach pcex at cbus -file arch/luna88k/dev/pcex.c pcex needs-flag +file arch/luna88k/cbus/pcex.c pcex needs-flag # list of standard files file arch/luna88k/luna88k/clock.c diff --git a/sys/arch/luna88k/dev/cbus.c b/sys/arch/luna88k/dev/cbus.c deleted file mode 100644 index 1f92b8f0ca5..00000000000 --- a/sys/arch/luna88k/dev/cbus.c +++ /dev/null @@ -1,297 +0,0 @@ -/* $OpenBSD: cbus.c,v 1.1 2014/12/08 13:24:04 aoyama Exp $ */ - -/* - * Copyright (c) 2014 Kenji Aoyama. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * PC-9801 extension board slot bus ('C-bus') driver for LUNA-88K2. - */ - -#include -#include -#include -#include - -#include /* ff1() */ -#include -#include /* PC_BASE */ - -#include -#include /* isrlink_autovec() */ - -#if 0 -#define CBUS_DEBUG -#endif - -/* - * C-bus interrupt status register - */ -#define CBUS_INTR_STAT_REG (PC_BASE + 0x1100000) -volatile u_int8_t *cbus_isreg = (u_int8_t *)CBUS_INTR_STAT_REG; - -/* autoconf stuff */ -int cbus_match(struct device *, void *, void *); -void cbus_attach(struct device *, struct device *, void *); -int cbus_print(void *, const char *); - -struct cbus_softc { - struct device sc_dev; - struct cbus_isr_t cbus_isr[NCBUSISR]; - u_int8_t registered; -}; - -const struct cfattach cbus_ca = { - sizeof(struct cbus_softc), cbus_match, cbus_attach -}; - -struct cfdriver cbus_cd = { - NULL, "cbus", DV_DULL -}; - -/* prototypes */ -int cbus_isrlink(int (*)(void *), void *, int, const char *); -int cbus_isrunlink(int (*)(void *), int); -void cbus_isrdispatch(int); -int cbus_intr(void *); - -int -cbus_match(struct device *parent, void *cf, void *aux) -{ - struct mainbus_attach_args *ma = aux; - - if (strcmp(ma->ma_name, cbus_cd.cd_name)) - return 0; -#if 0 - if (badaddr((vaddr_t)ma->ma_addr, 4)) - return 0; -#endif - return 1; -} - -void -cbus_attach(struct device *parent, struct device *self, void *args) -{ - struct cbus_softc *sc = (struct cbus_softc *)self; - struct mainbus_attach_args *ma = args; - struct cbus_attach_args caa; - int i; - - for (i = 0; i < NCBUSISR; i++) { - sc->cbus_isr[i].isr_func = NULL; - /* clearing interrupt flags (INT0-INT6) */ - *cbus_isreg = (u_int8_t)i; - } - - /* register C-bus interrupt service routine on mainbus */ - isrlink_autovec(cbus_intr, (void *)self, ma->ma_ilvl, - ISRPRI_TTY, self->dv_xname); - - printf("\n"); - - caa.intlevel = -1; /* not specified */ - config_found(self, &caa, cbus_print); - return; -} - -int -cbus_print(void *aux, const char *pnp) -{ - struct cbus_attach_args *caa = aux; -#if 0 /* not yet */ - if (pnp) - printf("%s at %s", caa->name, pnp); /* not configured */ -#endif - if (caa->intlevel != -1) - printf(" INT %d", caa->intlevel); - - return UNCONF; -} - -/* - * Register a C-bus interrupt service routine. - */ -int -cbus_isrlink(int (*func)(void *), void *arg, int ipl, const char *name) -{ - struct cbus_softc *sc = NULL; - - if (cbus_cd.cd_ndevs != 0) - sc = cbus_cd.cd_devs[0]; - if (sc == NULL) - panic("cbus_isrlink: can't find cbus_softc"); - -#ifdef DIAGNOSTIC - if (ipl < 0 || ipl >= NCBUSISR) { - printf("cbus_isrlink: bad ipl %d\n", ipl); - return -1; - } -#endif - - if (sc->cbus_isr[ipl].isr_func != NULL) { - printf("cbus_isrlink: isr already assigned on INT%d\n", ipl); - return -1; - } - - /* set the entry */ - sc->cbus_isr[ipl].isr_func = func; - sc->cbus_isr[ipl].isr_arg = arg; - evcount_attach(&(sc->cbus_isr[ipl].isr_count), name, &ipl); - sc->registered |= (1 << (6 - ipl)); -#ifdef CBUS_DEBUG - printf("cbus_isrlink: sc->registered = 0x%02x\n", sc->registered); -#endif - - return 0; -} - -/* - * Unregister a C-bus interrupt service routine. - */ -int -cbus_isrunlink(int (*func)(void *), int ipl) -{ - struct cbus_softc *sc = NULL; - - if (cbus_cd.cd_ndevs != 0) - sc = cbus_cd.cd_devs[0]; - if (sc == NULL) - panic("cbus_isrunlink: can't find cbus_softc"); - -#ifdef DIAGNOSTIC - if (ipl < 0 || ipl >= NCBUSISR) { - printf("cbus_isrunlink: bad ipl %d\n", ipl); - return -1; - } -#endif - - if (sc->cbus_isr[ipl].isr_func == NULL) { - printf("cbus_isrunlink: isr not assigned on INT%d\n", ipl); - return -1; - } - - /* reset the entry */ - sc->cbus_isr[ipl].isr_func = NULL; - sc->cbus_isr[ipl].isr_arg = NULL; - evcount_detach(&(sc->cbus_isr[ipl].isr_count)); - sc->registered &= ~(1 << (6 - ipl)); -#ifdef CBUS_DEBUG - printf("cbus_isrunlink: sc->registered = 0x%02x\n", sc->registered); -#endif - - return 0; -} - -/* - * Dispatch C-bus interrupt service routines. - */ -void -cbus_isrdispatch(int ipl) -{ - int rc; - static int straycount, unexpected; - struct cbus_softc *sc = NULL; - - if (cbus_cd.cd_ndevs != 0) - sc = cbus_cd.cd_devs[0]; - if (sc == NULL) - panic("cbus_isrdispatch: can't find cbus_softc"); - -#ifdef DIAGNOSTIC - if (ipl < 0 || ipl >= NCBUSISR) - panic("cbus_isrdispatch: bad ipl 0x%d", ipl); -#endif - - if (sc->cbus_isr[ipl].isr_func == NULL) { - printf("cbus_isrdispatch: ipl %d unexpected\n", ipl); - if (++unexpected > 10) - panic("too many unexpected interrupts"); - return; - } - - rc = sc->cbus_isr[ipl].isr_func(sc->cbus_isr[ipl].isr_arg); - if (rc != 0) - sc->cbus_isr[ipl].isr_count.ec_count++; - - if (rc) - straycount = 0; - else if (++straycount > 50) - panic("cbus_isrdispatch: too many stray interrupts"); - else - printf("cbus_isrdispatch: stray level %d interrupt\n", ipl); -} - -/* - * Note about interrupt on PC-9801 extension board slot - * - * PC-9801 extension board slot bus (so-called 'C-bus' in Japan) use 8 own - * interrupt levels, INT0-INT6, and NMI. On LUNA-88K2, they all trigger - * level 4 interrupt on mainbus, so we need to check the dedicated interrupt - * status register to know which C-bus interrupt is occurred. - * - * The interrupt status register for C-bus is located at - * (u_int8_t *)CBUS_INTR_STAT. Each bit of the register becomes 0 when - * corresponding C-bus interrupt has occurred, otherwise 1. - * - * bit 7 = NMI(?) - * bit 6 = INT0 - * bit 5 = INT1 - * : - * bit 0 = INT6 - * - * To clear the C-bus interrupt flag, write the corresponding 'bit' number - * (as u_int_8) to the register. For example, if you want to clear INT1, - * you should write '5' like: - * *(u_int8_t *)CBUS_INTR_STAT = 5; - */ - -/* - * Interrupt handler on mainbus. - */ -int -cbus_intr(void *arg) -{ - struct cbus_softc *sc = (struct cbus_softc *)arg; - u_int8_t intr_status; - int n; - - /* - * LUNA-88K2's interrupt level 4 is shared with other devices, - * such as le(4), for example. So we check: - * - the value of our C-bus interrupt status register, and - * - if the INT level is what we are looking for. - */ - intr_status = *cbus_isreg & sc->registered; - if (intr_status == sc->registered) return 0; /* Not for me */ - -#ifdef CBUS_DEBUG - printf("cbus_intr: called, *cbus_isreg=0x%02x, registered = 0x%02x\n", - *cbus_isreg, sc->registered); -#endif - /* Make the bit pattern that we should proces */ - intr_status = intr_status ^ sc->registered; -#ifdef CBUS_DEBUG - printf("cbus_intr: processing 0x%02x\n", intr_status); -#endif - - /* Process, and clear each interrupt flag */ - while ((n = ff1(intr_status)) != 32) { - cbus_isrdispatch(6 - n); - *cbus_isreg = (u_int8_t)n; - intr_status &= ~(1 << n); - } - - return 1; -} diff --git a/sys/arch/luna88k/dev/cbusvar.h b/sys/arch/luna88k/dev/cbusvar.h deleted file mode 100644 index c73e8629223..00000000000 --- a/sys/arch/luna88k/dev/cbusvar.h +++ /dev/null @@ -1,46 +0,0 @@ -/* $OpenBSD: cbusvar.h,v 1.1 2014/12/08 13:24:04 aoyama Exp $ */ - -/* - * Copyright (c) 2014 Kenji Aoyama. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * PC-9801 extension board slot bus ('C-bus') driver for LUNA-88K2. - */ - -#include -#include - -/* - * Currently 7 level C-bus interrupts (INT0 - INT6) are supported. - */ -#define NCBUSISR 7 - -/* - * C-bus interrupt handler - */ -struct cbus_isr_t { - int (*isr_func)(void *); - void *isr_arg; - struct evcount isr_count; -}; - -int cbus_isrlink(int (*)(void *), void *, int, const char *); -int cbus_isrunlink(int (*)(void *), int); -void cbus_isrdispatch(int); - -struct cbus_attach_args { - int intlevel; -}; diff --git a/sys/arch/luna88k/dev/pcex.c b/sys/arch/luna88k/dev/pcex.c deleted file mode 100644 index 82e8d19abac..00000000000 --- a/sys/arch/luna88k/dev/pcex.c +++ /dev/null @@ -1,212 +0,0 @@ -/* $OpenBSD: pcex.c,v 1.4 2014/12/08 13:24:04 aoyama Exp $ */ - -/* - * Copyright (c) 2014 Kenji Aoyama. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * PC-9801 extension board slot direct access driver for LUNA-88K2. - */ - -#include -#include /* tsleep()/wakeup() */ -#include -#include - -#include -#include /* PC_BASE */ -#include -#include - -#include - -extern int hz; - -#if 0 -#define PCEX_DEBUG -#endif - -#define PCEXMEM_BASE PC_BASE -#define PCEXIO_BASE (PC_BASE + 0x1000000) - -/* autoconf stuff */ -int pcex_match(struct device *, void *, void *); -void pcex_attach(struct device *, struct device *, void *); - -struct pcex_softc { - struct device sc_dev; - int intr_use[NCBUSISR]; -}; - -const struct cfattach pcex_ca = { - sizeof(struct pcex_softc), pcex_match, pcex_attach -}; - -struct cfdriver pcex_cd = { - NULL, "pcex", DV_DULL -}; - -/* prototypes */ -int pcex_intr(void *); -int pcex_set_int(struct pcex_softc *, u_int); -int pcex_reset_int(struct pcex_softc *, u_int); -int pcex_wait_int(struct pcex_softc *, u_int); - -int -pcex_match(struct device *parent, void *cf, void *aux) -{ - return 1; /* XXX: always matched */ -} - -void -pcex_attach(struct device *parent, struct device *self, void *args) -{ - struct pcex_softc *sc = (struct pcex_softc *)self; - int i; - - for (i = 0; i < NCBUSISR; i++) - sc->intr_use[i] = 0; - - printf("\n"); - return; -} - -int -pcexopen(dev_t dev, int flag, int mode, struct proc *p) -{ - switch (minor(dev)) { - case 0: /* memory area */ - case 1: /* I/O port area */ - return 0; - default: - return ENXIO; - } -} - -int -pcexclose(dev_t dev, int flag, int mode, struct proc *p) -{ - return (0); -} - -paddr_t -pcexmmap(dev_t dev, off_t offset, int prot) -{ - paddr_t cookie = -1; - - switch (minor(dev)) { - case 0: /* memory area */ - if (offset >= 0 && offset < 0x1000000) - cookie = (paddr_t)(PCEXMEM_BASE + offset); - break; - case 1: /* I/O port area */ - if (offset >= 0 && offset < 0x10000) - cookie = (paddr_t)(PCEXIO_BASE + offset); - break; - default: - break; - } - - return cookie; -} - -int -pcexioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) -{ - struct pcex_softc *sc = NULL; - u_int level; - - if (pcex_cd.cd_ndevs != 0) - sc = pcex_cd.cd_devs[0]; - if (sc == NULL) - return ENXIO; - - level = *(u_int *)data; - - switch(cmd) { - case PCEXSETLEVEL: - return pcex_set_int(sc, level); - - case PCEXRESETLEVEL: - return pcex_reset_int(sc, level); - - case PCEXWAITINT: - return pcex_wait_int(sc, level); - - default: - return ENOTTY; - } -} - -int -pcex_set_int(struct pcex_softc *sc, u_int level) -{ - if (level > 6) - return EINVAL; - if (sc->intr_use[level] != 0) - return EINVAL; /* Duplicate */ - - sc->intr_use[level] = 1; - cbus_isrlink(pcex_intr, &(sc->intr_use[level]), level, - sc->sc_dev.dv_xname); - - return 0; -} - -int -pcex_reset_int(struct pcex_softc *sc, u_int level) -{ - if (level > 6) - return EINVAL; - if (sc->intr_use[level] == 0) - return EINVAL; /* Not registered */ - - sc->intr_use[level] = 0; - cbus_isrunlink(pcex_intr, level); - - return 0; -} - -int -pcex_wait_int(struct pcex_softc *sc, u_int level) -{ - int ret; - - if (level > 6) - return EINVAL; - if (sc->intr_use[level] == 0) - return EINVAL; /* Not registered */ - - ret = tsleep(&(sc->intr_use[level]), PWAIT | PCATCH, "pcex", - hz /* XXX: 1 sec. */); - -#ifdef PCEX_DEBUG - if (ret == EWOULDBLOCK) - printf("pcex_wait_int: timeout in tsleep\n"); -#endif - return ret; -} - -int -pcex_intr(void *arg) -{ -#ifdef PCEX_DEBUG - printf("pcex_intr: called, arg=%p\n", arg); -#endif - /* Just wakeup(9) for now */ - wakeup(arg); - - return 1; -}