1 1.22 thorpej /* $NetBSD: gvpio.c,v 1.22 2021/08/07 16:18:41 thorpej Exp $ */ 2 1.1 is 3 1.1 is /* 4 1.1 is * Copyright (c) 1997 Ignatios Souvatzis 5 1.1 is * All rights reserved. 6 1.1 is * 7 1.1 is * Redistribution and use in source and binary forms, with or without 8 1.1 is * modification, are permitted provided that the following conditions 9 1.1 is * are met: 10 1.1 is * 1. Redistributions of source code must retain the above copyright 11 1.1 is * notice, this list of conditions and the following disclaimer. 12 1.1 is * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 is * notice, this list of conditions and the following disclaimer in the 14 1.1 is * documentation and/or other materials provided with the distribution. 15 1.1 is * 16 1.1 is * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 is * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 is * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 is * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 is * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 1.1 is * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 1.1 is * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 1.1 is * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 1.1 is * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 1.1 is * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 1.1 is */ 27 1.9 aymeric 28 1.9 aymeric #include <sys/cdefs.h> 29 1.22 thorpej __KERNEL_RCSID(0, "$NetBSD: gvpio.c,v 1.22 2021/08/07 16:18:41 thorpej Exp $"); 30 1.1 is 31 1.1 is /* 32 1.1 is * GVP I/O Extender 33 1.1 is */ 34 1.1 is 35 1.1 is #include <sys/types.h> 36 1.1 is 37 1.1 is #include <sys/conf.h> 38 1.1 is #include <sys/device.h> 39 1.1 is #include <sys/systm.h> 40 1.1 is #include <sys/param.h> 41 1.19 dyoung #include <sys/bus.h> 42 1.1 is 43 1.1 is #include <machine/intr.h> 44 1.1 is 45 1.1 is #include <amiga/include/cpu.h> 46 1.1 is 47 1.1 is #include <amiga/amiga/device.h> 48 1.1 is #include <amiga/amiga/drcustom.h> 49 1.1 is 50 1.1 is #include <amiga/dev/supio.h> 51 1.1 is #include <amiga/dev/zbusvar.h> 52 1.1 is #include <amiga/dev/gvpbusvar.h> 53 1.1 is 54 1.1 is struct gvpio_softc { 55 1.1 is struct bus_space_tag sc_bst; 56 1.16 christos void *sc_cntr; 57 1.1 is LIST_HEAD(, gvpcom_int_hdl) sc_comhdls; 58 1.1 is struct isr sc_comisr; 59 1.1 is }; 60 1.1 is 61 1.20 chs int gvpiomatch(device_t, cfdata_t, void *); 62 1.20 chs void gvpioattach(device_t, device_t, void *); 63 1.20 chs int gvpioprint(void *, const char *); 64 1.7 aymeric int gvp_com_intr(void *); 65 1.20 chs void gvp_com_intr_establish(device_t, struct gvpcom_int_hdl *); 66 1.1 is 67 1.20 chs CFATTACH_DECL_NEW(gvpio, sizeof(struct gvpio_softc), 68 1.12 thorpej gvpiomatch, gvpioattach, NULL, NULL); 69 1.1 is 70 1.1 is int 71 1.20 chs gvpiomatch(device_t parent, cfdata_t cf, void *aux) 72 1.1 is { 73 1.1 is 74 1.1 is struct gvpbus_args *gap; 75 1.1 is 76 1.20 chs gap = aux; 77 1.1 is 78 1.1 is if (gap->flags & GVP_IO) 79 1.1 is return (1); 80 1.1 is 81 1.1 is return (0); 82 1.1 is } 83 1.1 is 84 1.1 is struct gvpio_devs { 85 1.1 is char *name; 86 1.1 is int off; 87 1.1 is int arg; 88 1.1 is int ipl; 89 1.1 is } gvpiodevs[] = { 90 1.1 is { "com", 0x0b0, 115200 * 16 * 4, 6 }, 91 1.1 is { "com", 0x130, 115200 * 16 * 4, 6 }, 92 1.1 is { "lpt", 0x1b0, 0, 2 }, 93 1.1 is { 0 } 94 1.1 is }; 95 1.1 is 96 1.1 is void 97 1.20 chs gvpioattach(device_t parent, device_t self, void *aux) 98 1.1 is { 99 1.1 is struct gvpio_softc *giosc; 100 1.1 is struct gvpio_devs *giosd; 101 1.1 is struct gvpbus_args *gap; 102 1.1 is struct supio_attach_args supa; 103 1.16 christos volatile void *gbase; 104 1.18 phx #ifdef __m68k__ 105 1.1 is u_int16_t needpsl; 106 1.18 phx #endif 107 1.1 is 108 1.20 chs giosc = device_private(self); 109 1.20 chs gap = aux; 110 1.1 is 111 1.1 is if (parent) 112 1.1 is printf("\n"); 113 1.1 is 114 1.1 is gbase = gap->zargs.va; 115 1.1 is giosc->sc_cntr = &gbase[0x41]; 116 1.1 is giosc->sc_bst.base = (u_long)gbase + 1; 117 1.6 is giosc->sc_bst.absm = &amiga_bus_stride_2; 118 1.1 is LIST_INIT(&giosc->sc_comhdls); 119 1.1 is giosd = gvpiodevs; 120 1.1 is 121 1.1 is supa.supio_iot = &giosc->sc_bst; 122 1.1 is 123 1.1 is gbase[0x041] = 0; 124 1.1 is gbase[0x161 + 1*2] = 0; 125 1.1 is gbase[0x261 + 1*2] = 0; 126 1.1 is gbase[0x361 + 2*2] = 0; 127 1.1 is gbase[0x461] = 0xd0; 128 1.1 is 129 1.1 is while (giosd->name) { 130 1.1 is supa.supio_name = giosd->name; 131 1.1 is supa.supio_iobase = giosd->off; 132 1.1 is supa.supio_arg = giosd->arg; 133 1.1 is supa.supio_ipl = giosd->ipl; 134 1.22 thorpej config_found(self, &supa, gvpioprint, CFARGS_NONE); /* XXX */ 135 1.1 is ++giosd; 136 1.1 is } 137 1.1 is if (giosc->sc_comhdls.lh_first) { 138 1.18 phx #ifdef __m68k__ 139 1.14 wiz /* XXX this should be really in the interrupt stuff */ 140 1.1 is needpsl = PSL_S|PSL_IPL6; 141 1.15 yamt if (ipl2spl_table[IPL_SERIAL] < needpsl) { 142 1.15 yamt printf("%s: raising ipl2spl_table[IPL_SERIAL] " 143 1.15 yamt "from 0x%x to 0x%x\n", 144 1.20 chs device_xname(self), ipl2spl_table[IPL_SERIAL], 145 1.15 yamt needpsl); 146 1.15 yamt ipl2spl_table[IPL_SERIAL] = needpsl; 147 1.1 is } 148 1.18 phx #endif 149 1.1 is giosc->sc_comisr.isr_intr = gvp_com_intr; 150 1.1 is giosc->sc_comisr.isr_arg = giosc; 151 1.1 is giosc->sc_comisr.isr_ipl = 6; 152 1.1 is add_isr(&giosc->sc_comisr); 153 1.1 is } 154 1.1 is gbase[0x041] = 0x08; 155 1.1 is } 156 1.1 is 157 1.1 is int 158 1.20 chs gvpioprint(void *aux, const char *pnp) 159 1.1 is { 160 1.1 is struct supio_attach_args *supa; 161 1.20 chs 162 1.20 chs supa = aux; 163 1.1 is 164 1.1 is if (pnp == NULL) 165 1.1 is return(QUIET); 166 1.1 is 167 1.13 thorpej aprint_normal("%s at %s port 0x%02x ipl %d", 168 1.1 is supa->supio_name, pnp, supa->supio_iobase, supa->supio_ipl); 169 1.1 is 170 1.1 is return(UNCONF); 171 1.1 is } 172 1.1 is 173 1.1 is void 174 1.20 chs gvp_com_intr_establish(device_t self, struct gvpcom_int_hdl *p) 175 1.1 is { 176 1.1 is struct gvpio_softc *sc; 177 1.1 is 178 1.20 chs sc = device_private(self); 179 1.1 is LIST_INSERT_HEAD(&sc->sc_comhdls, p, next); 180 1.1 is 181 1.1 is } 182 1.1 is 183 1.1 is int 184 1.7 aymeric gvp_com_intr(void *p) 185 1.1 is { 186 1.1 is struct gvpio_softc *sc; 187 1.1 is struct gvpcom_int_hdl *np; 188 1.16 christos volatile void *cntr; 189 1.1 is 190 1.1 is sc = (struct gvpio_softc *)p; 191 1.1 is 192 1.1 is cntr = sc->sc_cntr; 193 1.1 is 194 1.1 is if (!(*cntr & 0x2)) 195 1.1 is return (0); 196 1.1 is 197 1.1 is *cntr &= ~0xa; 198 1.1 is 199 1.1 is for (np = sc->sc_comhdls.lh_first; np != NULL; 200 1.1 is np = np->next.le_next) { 201 1.1 is 202 1.1 is (*np->f)(np->p); 203 1.1 is } 204 1.1 is *cntr |= 0x8; 205 1.1 is 206 1.1 is return (1); 207 1.1 is } 208