1 /* $NetBSD: isa_machdep.c,v 1.7 2005/12/11 12:18:13 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Wayne Knowles 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <sys/cdefs.h> 40 __KERNEL_RCSID(0, "$NetBSD: isa_machdep.c,v 1.7 2005/12/11 12:18:13 christos Exp $"); 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/device.h> 45 #include <sys/malloc.h> 46 #include <sys/queue.h> 47 48 #include <machine/sysconf.h> 49 #include <machine/autoconf.h> 50 #include <machine/mainboard.h> 51 #include <machine/bus.h> 52 53 #include <dev/isa/isavar.h> 54 #include <dev/isa/isareg.h> 55 56 static int mipscoisabusprint __P((void *auxp, const char *)); 57 static int isabusmatch __P((struct device *, struct cfdata *, void *)); 58 static void isabusattach __P((struct device *, struct device *, void *)); 59 60 struct isabus_softc { 61 struct device sc_dev; 62 struct mipsco_isa_chipset sc_isa_ic; 63 }; 64 65 CFATTACH_DECL(isabus, sizeof(struct isabus_softc), 66 isabusmatch, isabusattach, NULL, NULL); 67 68 extern struct cfdriver isabus_cd; 69 70 static struct mipsco_bus_space isa_io_bst, isa_mem_bst, isa_ctl_bst; 71 static struct mipsco_bus_dma_tag isa_dmatag; 72 73 static void isa_bus_space_init __P((struct mipsco_bus_space *, const char *, 74 paddr_t, size_t)); 75 int isa_intr __P((void *)); 76 77 78 int 79 isabusmatch(pdp, cfp, aux) 80 struct device *pdp; 81 struct cfdata *cfp; 82 void *aux; 83 { 84 struct confargs *ca = aux; 85 86 if (strcmp(ca->ca_name, isabus_cd.cd_name) != 0) 87 return 0; 88 return 1; 89 } 90 91 static void 92 isa_bus_space_init(bst, type, paddr, len) 93 struct mipsco_bus_space *bst; 94 const char *type; 95 paddr_t paddr; 96 size_t len; 97 { 98 vaddr_t vaddr = MIPS_PHYS_TO_KSEG1(paddr); /* XXX */ 99 100 /* Setup default bus_space */ 101 mipsco_bus_space_init(bst, type, paddr, vaddr, 0x0, len); 102 103 /* ISA bus maps 1 word for every byte, therefore stride = 2 */ 104 mipsco_bus_space_set_aligned_stride(bst, 2); 105 106 /* 107 * ISA bus will do an automatic byte swap, but when accessing 108 * memory using bus_space_stream functions we need to byte swap 109 * to reverse the one performed in hardware 110 */ 111 bst->bs_bswap = 1; 112 113 bst->bs_intr_establish = (void *)isa_intr_establish; 114 115 printf(" %s %p", type, (void *)vaddr); 116 } 117 118 119 void 120 isabusattach(pdp, dp, aux) 121 struct device *pdp, *dp; 122 void *aux; 123 { 124 struct isabus_softc *sc = (struct isabus_softc *)dp; 125 struct mipsco_isa_chipset *ic = &sc->sc_isa_ic; 126 struct isabus_attach_args iba; 127 128 printf(":"); 129 130 iba.iba_iot = &isa_io_bst; 131 iba.iba_memt = &isa_mem_bst; 132 iba.iba_dmat = &isa_dmatag; 133 iba.iba_ic = ic; 134 135 isa_bus_space_init(&isa_io_bst, "isa_io", PIZAZZ_ISA_IOBASE, 136 PIZAZZ_ISA_IOSIZE); 137 138 isa_bus_space_init(&isa_mem_bst, "isa_mem", PIZAZZ_ISA_MEMBASE, 139 PIZAZZ_ISA_MEMSIZE); 140 141 isa_bus_space_init(&isa_ctl_bst, "isa_intr", PIZAZZ_ISA_INTRLATCH, 142 sizeof(u_int32_t)); 143 144 _bus_dma_tag_init(&isa_dmatag); 145 146 ic->ic_bst = &isa_ctl_bst; 147 148 if (bus_space_map(ic->ic_bst, 0x00000, sizeof(u_int32_t), 149 BUS_SPACE_MAP_LINEAR, &ic->ic_bsh) != 0) { 150 printf(": can't map intrreg\n"); 151 return; 152 } 153 154 /* Clear ISA interrupt latch */ 155 bus_space_write_4(ic->ic_bst, ic->ic_bsh, 0, 0); 156 157 evcnt_attach_dynamic(&ic->ic_intrcnt, EVCNT_TYPE_INTR, NULL, 158 dp->dv_xname, "intr"); 159 160 LIST_INIT(&ic->intr_q); 161 (*platform.intr_establish)(SYS_INTR_ATBUS, isa_intr, ic); 162 163 printf("\n"); 164 config_found_ia(dp, "isabus", &iba, mipscoisabusprint); 165 } 166 167 int 168 mipscoisabusprint(auxp, name) 169 void *auxp; 170 const char *name; 171 { 172 if(name == NULL) 173 return(UNCONF); 174 return(QUIET); 175 } 176 177 void 178 isa_attach_hook(parent, self, iba) 179 struct device *parent, *self; 180 struct isabus_attach_args *iba; 181 { 182 } 183 184 const struct evcnt * 185 isa_intr_evcnt(isa_chipset_tag_t ic, int irq) 186 { 187 /* XXX for now, no evcnt parent reported */ 188 return NULL; 189 } 190 191 void * 192 isa_intr_establish(ic, intr, type, level, ih_fun, ih_arg) 193 isa_chipset_tag_t ic; 194 int intr; 195 int type; /* XXX not yet */ 196 int level; /* XXX not yet */ 197 int (*ih_fun) __P((void*)); 198 void *ih_arg; 199 { 200 struct mipsco_intrhand *ih; 201 202 ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT); 203 if (ih == NULL) 204 panic("isa_intr_establish: malloc failed"); 205 206 ih->ih_fun = ih_fun; 207 ih->ih_arg = ih_arg; 208 LIST_INSERT_HEAD(&ic->intr_q, ih, ih_q); 209 return ih; 210 } 211 212 void 213 isa_intr_disestablish(ic, cookie) 214 isa_chipset_tag_t ic; 215 void *cookie; 216 { 217 struct mipsco_intrhand *ih = cookie; 218 219 LIST_REMOVE(ih, ih_q); 220 free(ih, M_DEVBUF); 221 } 222 223 int 224 isa_intr_alloc(ic, mask, type, irq) 225 isa_chipset_tag_t ic; 226 int mask; 227 int type; 228 int *irq; 229 { 230 return 0; 231 } 232 233 int 234 isa_intr(arg) 235 void *arg; 236 { 237 struct mipsco_isa_chipset *ic = (struct mipsco_isa_chipset *)arg; 238 struct mipsco_intrhand *ih; 239 int rv, handled; 240 241 ic->ic_intrcnt.ev_count++; 242 243 handled = 0; 244 LIST_FOREACH(ih, &ic->intr_q, ih_q) { 245 /* 246 * The handler returns one of three values: 247 * 0: This interrupt wasn't for me. 248 * 1: This interrupt was for me. 249 * -1: This interrupt might have been for me, but I can't say 250 * for sure. 251 */ 252 rv = (*ih->ih_fun)(ih->ih_arg); 253 handled |= (rv != 0); 254 } 255 256 /* Clear ISA interrupt latch */ 257 bus_space_write_4(ic->ic_bst, ic->ic_bsh, 0, 0); 258 259 return handled; 260 } 261