1 1.7 thorpej /* $NetBSD: mongoose.c,v 1.7 2021/08/07 16:18:55 thorpej Exp $ */ 2 1.1 skrll 3 1.1 skrll /* $OpenBSD: mongoose.c,v 1.19 2010/01/01 20:28:42 kettenis Exp $ */ 4 1.1 skrll 5 1.1 skrll /* 6 1.1 skrll * Copyright (c) 1998-2003 Michael Shalayeff 7 1.1 skrll * All rights reserved. 8 1.1 skrll * 9 1.1 skrll * Redistribution and use in source and binary forms, with or without 10 1.1 skrll * modification, are permitted provided that the following conditions 11 1.1 skrll * are met: 12 1.1 skrll * 1. Redistributions of source code must retain the above copyright 13 1.1 skrll * notice, this list of conditions and the following disclaimer. 14 1.1 skrll * 2. Redistributions in binary form must reproduce the above copyright 15 1.1 skrll * notice, this list of conditions and the following disclaimer in the 16 1.1 skrll * documentation and/or other materials provided with the distribution. 17 1.1 skrll * 18 1.1 skrll * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 1.1 skrll * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 1.1 skrll * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 1.1 skrll * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 22 1.1 skrll * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 1.1 skrll * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 1.1 skrll * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 1.1 skrll * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 1.1 skrll * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 1.1 skrll * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 1.1 skrll * THE POSSIBILITY OF SUCH DAMAGE. 29 1.1 skrll */ 30 1.1 skrll 31 1.1 skrll #include <sys/cdefs.h> 32 1.7 thorpej __KERNEL_RCSID(0, "$NetBSD: mongoose.c,v 1.7 2021/08/07 16:18:55 thorpej Exp $"); 33 1.1 skrll 34 1.1 skrll #define MONGOOSE_DEBUG 9 35 1.1 skrll 36 1.1 skrll #include <sys/param.h> 37 1.1 skrll #include <sys/systm.h> 38 1.1 skrll #include <sys/device.h> 39 1.1 skrll #include <sys/reboot.h> 40 1.1 skrll 41 1.1 skrll #include <sys/bus.h> 42 1.1 skrll #include <machine/iomod.h> 43 1.1 skrll #include <machine/autoconf.h> 44 1.1 skrll 45 1.1 skrll #include <hppa/dev/cpudevs.h> 46 1.1 skrll #include <hppa/dev/viper.h> 47 1.1 skrll 48 1.1 skrll #include <dev/eisa/eisareg.h> 49 1.1 skrll #include <dev/eisa/eisavar.h> 50 1.1 skrll 51 1.1 skrll #include <dev/isa/isareg.h> 52 1.1 skrll #include <dev/isa/isavar.h> 53 1.1 skrll 54 1.1 skrll /* EISA Bus Adapter registers definitions */ 55 1.1 skrll #define MONGOOSE_MONGOOSE 0x10000 56 1.1 skrll struct mongoose_regs { 57 1.1 skrll uint8_t version; 58 1.1 skrll uint8_t lock; 59 1.1 skrll uint8_t liowait; 60 1.1 skrll uint8_t clock; 61 1.1 skrll uint8_t reserved[0xf000 - 4]; 62 1.1 skrll uint8_t intack; 63 1.1 skrll }; 64 1.1 skrll 65 1.1 skrll #define MONGOOSE_CTRL 0x00000 66 1.1 skrll #define MONGOOSE_NINTS 16 67 1.1 skrll struct mongoose_ctrl { 68 1.1 skrll struct dma0 { 69 1.1 skrll struct { 70 1.1 skrll uint32_t addr : 8; 71 1.1 skrll uint32_t count: 8; 72 1.1 skrll } ch[4]; 73 1.1 skrll uint8_t command; 74 1.1 skrll uint8_t request; 75 1.1 skrll uint8_t mask_channel; 76 1.1 skrll uint8_t mode; 77 1.1 skrll uint8_t clr_byte_ptr; 78 1.1 skrll uint8_t master_clear; 79 1.1 skrll uint8_t mask_clear; 80 1.1 skrll uint8_t master_write; 81 1.1 skrll uint8_t pad[8]; 82 1.1 skrll } dma0; 83 1.1 skrll 84 1.1 skrll uint8_t irr0; /* 0x20 */ 85 1.1 skrll uint8_t imr0; 86 1.1 skrll uint8_t iack; /* 0x22 -- 2 b2b reads generate 87 1.1 skrll (e)isa Iack cycle & returns int level */ 88 1.1 skrll uint8_t pad0[29]; 89 1.1 skrll 90 1.1 skrll struct timers { 91 1.1 skrll uint8_t sysclk; 92 1.1 skrll uint8_t refresh; 93 1.1 skrll uint8_t spkr; 94 1.1 skrll uint8_t ctrl; 95 1.1 skrll uint32_t pad; 96 1.1 skrll } tmr[2]; /* 0x40 -- timers control */ 97 1.1 skrll uint8_t pad1[16]; 98 1.1 skrll 99 1.1 skrll uint16_t inmi; /* 0x60 NMI control */ 100 1.1 skrll uint8_t pad2[30]; 101 1.1 skrll struct { 102 1.1 skrll uint8_t pad0; 103 1.1 skrll uint8_t ch2; 104 1.1 skrll uint8_t ch3; 105 1.1 skrll uint8_t ch1; 106 1.1 skrll uint8_t pad1; 107 1.1 skrll uint8_t pad2[3]; 108 1.1 skrll uint8_t ch0; 109 1.1 skrll uint8_t pad4; 110 1.1 skrll uint8_t ch6; 111 1.1 skrll uint8_t ch7; 112 1.1 skrll uint8_t ch5; 113 1.1 skrll uint8_t pad5[3]; 114 1.1 skrll uint8_t pad6[16]; 115 1.1 skrll } pr; /* 0x80 */ 116 1.1 skrll 117 1.1 skrll uint8_t irr1; /* 0xa0 */ 118 1.1 skrll uint8_t imr1; 119 1.1 skrll uint8_t pad3[30]; 120 1.1 skrll 121 1.1 skrll struct dma1 { 122 1.1 skrll struct { 123 1.1 skrll uint32_t addr : 8; 124 1.1 skrll uint32_t pad0 : 8; 125 1.1 skrll uint32_t count: 8; 126 1.1 skrll uint32_t pad1 : 8; 127 1.1 skrll } ch[4]; 128 1.1 skrll uint8_t command; 129 1.1 skrll uint8_t pad0; 130 1.1 skrll uint8_t request; 131 1.1 skrll uint8_t pad1; 132 1.1 skrll uint8_t mask_channel; 133 1.1 skrll uint8_t pad2; 134 1.1 skrll uint8_t mode; 135 1.1 skrll uint8_t pad3; 136 1.1 skrll uint8_t clr_byte_ptr; 137 1.1 skrll uint8_t pad4; 138 1.1 skrll uint8_t master_clear; 139 1.1 skrll uint8_t pad5; 140 1.1 skrll uint8_t mask_clear; 141 1.1 skrll uint8_t pad6; 142 1.1 skrll uint8_t master_write; 143 1.1 skrll uint8_t pad7; 144 1.1 skrll } dma1; /* 0xc0 */ 145 1.1 skrll 146 1.1 skrll uint8_t master_req; /* 0xe0 master request register */ 147 1.1 skrll uint8_t pad4[31]; 148 1.1 skrll 149 1.1 skrll uint8_t pad5[0x3d0]; /* 0x4d0 */ 150 1.1 skrll uint8_t pic0; /* 0 - edge, 1 - level */ 151 1.1 skrll uint8_t pic1; 152 1.1 skrll uint8_t pad6[0x460]; 153 1.1 skrll uint8_t nmi; 154 1.1 skrll uint8_t nmi_ext; 155 1.1 skrll #define MONGOOSE_NMI_BUSRESET 0x01 156 1.1 skrll #define MONGOOSE_NMI_IOPORT_EN 0x02 157 1.1 skrll #define MONGOOSE_NMI_EN 0x04 158 1.1 skrll #define MONGOOSE_NMI_MTMO_EN 0x08 159 1.1 skrll #define MONGOOSE_NMI_RES4 0x10 160 1.1 skrll #define MONGOOSE_NMI_IOPORT_INT 0x20 161 1.1 skrll #define MONGOOSE_NMI_MASTER_INT 0x40 162 1.1 skrll #define MONGOOSE_NMI_INT 0x80 163 1.1 skrll }; 164 1.1 skrll 165 1.1 skrll #define MONGOOSE_IOMAP 0x100000 166 1.1 skrll 167 1.1 skrll struct hppa_isa_iv { 168 1.1 skrll int (*iv_handler)(void *arg); 169 1.1 skrll void *iv_arg; 170 1.1 skrll int iv_pri; 171 1.1 skrll 172 1.1 skrll struct evcnt iv_evcnt; 173 1.1 skrll /* don't do sharing, we won't have many slots anyway 174 1.1 skrll struct hppa_isa_iv *iv_next; 175 1.1 skrll */ 176 1.1 skrll }; 177 1.1 skrll 178 1.1 skrll struct mongoose_softc { 179 1.1 skrll device_t sc_dev; 180 1.1 skrll void *sc_ih; 181 1.1 skrll 182 1.1 skrll bus_space_tag_t sc_bt; 183 1.1 skrll volatile struct mongoose_regs *sc_regs; 184 1.1 skrll volatile struct mongoose_ctrl *sc_ctrl; 185 1.1 skrll bus_addr_t sc_iomap; 186 1.1 skrll 187 1.1 skrll /* interrupts section */ 188 1.1 skrll struct hppa_eisa_chipset sc_ec; 189 1.1 skrll struct hppa_isa_chipset sc_ic; 190 1.1 skrll struct hppa_isa_iv sc_iv[MONGOOSE_NINTS]; 191 1.1 skrll 192 1.1 skrll /* isa/eisa bus guts */ 193 1.1 skrll struct hppa_bus_space_tag sc_eiot; 194 1.1 skrll struct hppa_bus_space_tag sc_ememt; 195 1.1 skrll struct hppa_bus_dma_tag sc_edmat; 196 1.1 skrll struct hppa_bus_space_tag sc_iiot; 197 1.1 skrll struct hppa_bus_space_tag sc_imemt; 198 1.1 skrll struct hppa_bus_dma_tag sc_idmat; 199 1.1 skrll }; 200 1.1 skrll 201 1.1 skrll union mongoose_attach_args { 202 1.1 skrll struct eisabus_attach_args mongoose_eisa; 203 1.1 skrll struct isabus_attach_args mongoose_isa; 204 1.1 skrll }; 205 1.1 skrll 206 1.1 skrll void mg_eisa_attach_hook(device_t, device_t, struct eisabus_attach_args *); 207 1.1 skrll int mg_intr_map(void *, u_int, eisa_intr_handle_t *); 208 1.3 christos const char *mg_intr_string(void *, int, char *, size_t); 209 1.1 skrll void mg_isa_attach_hook(device_t, device_t, struct isabus_attach_args *); 210 1.1 skrll void mg_isa_detach_hook(isa_chipset_tag_t, device_t); 211 1.1 skrll void *mg_intr_establish(void *, int, int, int, int (*)(void *), void *); 212 1.1 skrll void mg_intr_disestablish(void *, void *); 213 1.1 skrll int mg_intr_check(void *, int, int); 214 1.1 skrll int mg_intr(void *); 215 1.1 skrll int mg_eisa_iomap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *); 216 1.1 skrll int mg_eisa_memmap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *); 217 1.1 skrll void mg_eisa_memunmap(void *, bus_space_handle_t, bus_size_t); 218 1.1 skrll void mg_isa_barrier(void *, bus_space_handle_t, bus_size_t, bus_size_t, int); 219 1.1 skrll uint16_t mg_isa_r2(void *, bus_space_handle_t, bus_size_t); 220 1.1 skrll uint32_t mg_isa_r4(void *, bus_space_handle_t, bus_size_t); 221 1.1 skrll void mg_isa_w2(void *, bus_space_handle_t, bus_size_t, uint16_t); 222 1.1 skrll void mg_isa_w4(void *, bus_space_handle_t, bus_size_t, uint32_t); 223 1.1 skrll void mg_isa_rm_2(void *, bus_space_handle_t, bus_size_t, uint16_t *, bus_size_t); 224 1.1 skrll void mg_isa_rm_4(void *, bus_space_handle_t, bus_size_t, uint32_t *, bus_size_t); 225 1.1 skrll void mg_isa_wm_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *, bus_size_t); 226 1.1 skrll void mg_isa_wm_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *, bus_size_t); 227 1.1 skrll void mg_isa_sm_2(void *, bus_space_handle_t, bus_size_t, uint16_t, bus_size_t); 228 1.1 skrll void mg_isa_sm_4(void *, bus_space_handle_t, bus_size_t, uint32_t, bus_size_t); 229 1.1 skrll void mg_isa_rr_2(void *, bus_space_handle_t, bus_size_t, uint16_t *, bus_size_t); 230 1.1 skrll void mg_isa_rr_4(void *, bus_space_handle_t, bus_size_t, uint32_t *, bus_size_t); 231 1.1 skrll void mg_isa_wr_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *, bus_size_t); 232 1.1 skrll void mg_isa_wr_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *, bus_size_t); 233 1.1 skrll void mg_isa_sr_2(void *, bus_space_handle_t, bus_size_t, uint16_t, bus_size_t); 234 1.1 skrll void mg_isa_sr_4(void *, bus_space_handle_t, bus_size_t, uint32_t, bus_size_t); 235 1.1 skrll 236 1.1 skrll int mgmatch(device_t, cfdata_t, void *); 237 1.1 skrll void mgattach(device_t, device_t, void *); 238 1.1 skrll 239 1.1 skrll CFATTACH_DECL_NEW(mongoose, sizeof(struct mongoose_softc), 240 1.1 skrll mgmatch, mgattach, NULL, NULL); 241 1.1 skrll 242 1.1 skrll /* TODO: DMA guts */ 243 1.1 skrll 244 1.1 skrll void 245 1.1 skrll mg_eisa_attach_hook(device_t parent, device_t self, 246 1.1 skrll struct eisabus_attach_args *mg) 247 1.1 skrll { 248 1.1 skrll } 249 1.1 skrll 250 1.1 skrll int 251 1.1 skrll mg_intr_map(void *v, u_int irq, eisa_intr_handle_t *ehp) 252 1.1 skrll { 253 1.1 skrll *ehp = irq; 254 1.1 skrll return 0; 255 1.1 skrll } 256 1.1 skrll 257 1.1 skrll const char * 258 1.3 christos mg_intr_string(void *v, int irq, char *buf, size_t len) 259 1.1 skrll { 260 1.3 christos snprintf (buf, len, "isa irq %d", irq); 261 1.1 skrll return buf; 262 1.1 skrll } 263 1.1 skrll 264 1.1 skrll void 265 1.1 skrll mg_isa_attach_hook(device_t parent, device_t self, 266 1.1 skrll struct isabus_attach_args *iba) 267 1.1 skrll { 268 1.1 skrll 269 1.1 skrll } 270 1.1 skrll 271 1.1 skrll void 272 1.1 skrll mg_isa_detach_hook(isa_chipset_tag_t ic, device_t self) 273 1.1 skrll { 274 1.1 skrll 275 1.1 skrll } 276 1.1 skrll 277 1.1 skrll void * 278 1.1 skrll mg_intr_establish(void *v, int irq, int type, int pri, 279 1.1 skrll int (*handler)(void *), void *arg) 280 1.1 skrll { 281 1.1 skrll struct hppa_isa_iv *iv; 282 1.1 skrll struct mongoose_softc *sc = v; 283 1.1 skrll volatile uint8_t *imr, *pic; 284 1.1 skrll 285 1.1 skrll if (!sc || irq < 0 || irq >= MONGOOSE_NINTS || 286 1.1 skrll (0 <= irq && irq < MONGOOSE_NINTS && sc->sc_iv[irq].iv_handler)) 287 1.1 skrll return NULL; 288 1.1 skrll 289 1.1 skrll if (type != IST_LEVEL && type != IST_EDGE) { 290 1.1 skrll aprint_debug_dev(sc->sc_dev, "bad interrupt level (%d)\n", 291 1.1 skrll type); 292 1.1 skrll return NULL; 293 1.1 skrll } 294 1.1 skrll 295 1.1 skrll iv = &sc->sc_iv[irq]; 296 1.1 skrll if (iv->iv_handler) { 297 1.1 skrll aprint_debug_dev(sc->sc_dev, "irq %d already established\n", 298 1.1 skrll irq); 299 1.1 skrll return NULL; 300 1.1 skrll } 301 1.1 skrll 302 1.1 skrll iv->iv_pri = pri; 303 1.1 skrll iv->iv_handler = handler; 304 1.1 skrll iv->iv_arg = arg; 305 1.5 skrll 306 1.1 skrll if (irq < 8) { 307 1.1 skrll imr = &sc->sc_ctrl->imr0; 308 1.1 skrll pic = &sc->sc_ctrl->pic0; 309 1.1 skrll } else { 310 1.1 skrll imr = &sc->sc_ctrl->imr1; 311 1.1 skrll pic = &sc->sc_ctrl->pic1; 312 1.1 skrll irq -= 8; 313 1.1 skrll } 314 1.1 skrll 315 1.1 skrll *imr |= 1 << irq; 316 1.1 skrll *pic |= (type == IST_LEVEL) << irq; 317 1.1 skrll 318 1.1 skrll /* TODO: ack it? */ 319 1.1 skrll 320 1.1 skrll return iv; 321 1.1 skrll } 322 1.1 skrll 323 1.1 skrll void 324 1.1 skrll mg_intr_disestablish(void *v, void *cookie) 325 1.1 skrll { 326 1.1 skrll struct hppa_isa_iv *iv = cookie; 327 1.1 skrll struct mongoose_softc *sc = v; 328 1.4 maya int irq; 329 1.1 skrll volatile uint8_t *imr; 330 1.1 skrll 331 1.1 skrll if (!sc || !cookie) 332 1.1 skrll return; 333 1.1 skrll 334 1.4 maya irq = iv - sc->sc_iv; 335 1.4 maya 336 1.1 skrll if (irq < 8) 337 1.1 skrll imr = &sc->sc_ctrl->imr0; 338 1.1 skrll else 339 1.1 skrll imr = &sc->sc_ctrl->imr1; 340 1.1 skrll *imr &= ~(1 << irq); 341 1.1 skrll /* TODO: ack it? */ 342 1.1 skrll 343 1.1 skrll iv->iv_handler = NULL; 344 1.1 skrll } 345 1.1 skrll 346 1.1 skrll int 347 1.1 skrll mg_intr_check(void *v, int irq, int type) 348 1.1 skrll { 349 1.1 skrll return 0; 350 1.1 skrll } 351 1.1 skrll 352 1.1 skrll int 353 1.1 skrll mg_intr(void *v) 354 1.1 skrll { 355 1.1 skrll struct mongoose_softc *sc = v; 356 1.1 skrll struct hppa_isa_iv *iv; 357 1.1 skrll int s, irq = 0; 358 1.1 skrll 359 1.1 skrll iv = &sc->sc_iv[irq]; 360 1.1 skrll s = splraise(iv->iv_pri); 361 1.1 skrll (iv->iv_handler)(iv->iv_arg); 362 1.1 skrll splx(s); 363 1.1 skrll 364 1.1 skrll return 0; 365 1.1 skrll } 366 1.1 skrll 367 1.1 skrll int 368 1.1 skrll mg_eisa_iomap(void *v, bus_addr_t addr, bus_size_t size, int cacheable, 369 1.1 skrll bus_space_handle_t *bshp) 370 1.1 skrll { 371 1.1 skrll struct mongoose_softc *sc = v; 372 1.1 skrll 373 1.1 skrll /* see if it's ISA space we are mapping */ 374 1.1 skrll if (0x100 <= addr && addr < 0x400) { 375 1.1 skrll #define TOISA(a) ((((a) & 0x3f8) << 9) + ((a) & 7)) 376 1.1 skrll size = TOISA(addr + size) - TOISA(addr); 377 1.1 skrll addr = TOISA(addr); 378 1.1 skrll } 379 1.1 skrll 380 1.1 skrll return (sc->sc_bt->hbt_map)(NULL, sc->sc_iomap + addr, size, 381 1.1 skrll cacheable, bshp); 382 1.1 skrll } 383 1.1 skrll 384 1.1 skrll int 385 1.1 skrll mg_eisa_memmap(void *v, bus_addr_t addr, bus_size_t size, int cacheable, 386 1.1 skrll bus_space_handle_t *bshp) 387 1.1 skrll { 388 1.1 skrll /* TODO: eisa memory map */ 389 1.1 skrll return -1; 390 1.1 skrll } 391 1.1 skrll 392 1.1 skrll void 393 1.1 skrll mg_eisa_memunmap(void *v, bus_space_handle_t bsh, bus_size_t size) 394 1.1 skrll { 395 1.1 skrll /* TODO: eisa memory unmap */ 396 1.1 skrll } 397 1.1 skrll 398 1.1 skrll void 399 1.1 skrll mg_isa_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op) 400 1.1 skrll { 401 1.1 skrll sync_caches(); 402 1.1 skrll } 403 1.1 skrll 404 1.1 skrll uint16_t 405 1.1 skrll mg_isa_r2(void *v, bus_space_handle_t h, bus_size_t o) 406 1.1 skrll { 407 1.1 skrll uint16_t r = *((volatile uint16_t *)(h + o)); 408 1.1 skrll 409 1.1 skrll return le16toh(r); 410 1.1 skrll } 411 1.1 skrll 412 1.1 skrll uint32_t 413 1.1 skrll mg_isa_r4(void *v, bus_space_handle_t h, bus_size_t o) 414 1.1 skrll { 415 1.1 skrll uint32_t r = *((volatile uint32_t *)(h + o)); 416 1.1 skrll 417 1.1 skrll return le32toh(r); 418 1.1 skrll } 419 1.1 skrll 420 1.1 skrll void 421 1.1 skrll mg_isa_w2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv) 422 1.1 skrll { 423 1.1 skrll *((volatile uint16_t *)(h + o)) = htole16(vv); 424 1.1 skrll } 425 1.1 skrll 426 1.1 skrll void 427 1.1 skrll mg_isa_w4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv) 428 1.1 skrll { 429 1.1 skrll *((volatile uint32_t *)(h + o)) = htole32(vv); 430 1.1 skrll } 431 1.1 skrll 432 1.1 skrll void 433 1.1 skrll mg_isa_rm_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t *a, bus_size_t c) 434 1.1 skrll { 435 1.1 skrll h += o; 436 1.1 skrll while (c--) 437 1.1 skrll *(a++) = le16toh(*(volatile uint16_t *)h); 438 1.1 skrll } 439 1.1 skrll 440 1.1 skrll void 441 1.1 skrll mg_isa_rm_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t *a, bus_size_t c) 442 1.1 skrll { 443 1.1 skrll h += o; 444 1.1 skrll while (c--) 445 1.1 skrll *(a++) = le32toh(*(volatile uint32_t *)h); 446 1.1 skrll } 447 1.1 skrll 448 1.1 skrll void 449 1.1 skrll mg_isa_wm_2(void *v, bus_space_handle_t h, bus_size_t o, const uint16_t *a, bus_size_t c) 450 1.1 skrll { 451 1.1 skrll uint16_t r; 452 1.1 skrll 453 1.1 skrll h += o; 454 1.1 skrll while (c--) { 455 1.1 skrll r = *(a++); 456 1.1 skrll *(volatile uint16_t *)h = htole16(r); 457 1.1 skrll } 458 1.1 skrll } 459 1.1 skrll 460 1.1 skrll void 461 1.1 skrll mg_isa_wm_4(void *v, bus_space_handle_t h, bus_size_t o, const uint32_t *a, bus_size_t c) 462 1.1 skrll { 463 1.1 skrll uint32_t r; 464 1.1 skrll 465 1.1 skrll h += o; 466 1.1 skrll while (c--) { 467 1.1 skrll r = *(a++); 468 1.1 skrll *(volatile uint32_t *)h = htole32(r); 469 1.1 skrll } 470 1.1 skrll } 471 1.1 skrll 472 1.1 skrll void 473 1.1 skrll mg_isa_sm_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv, bus_size_t c) 474 1.1 skrll { 475 1.1 skrll vv = htole16(vv); 476 1.1 skrll h += o; 477 1.1 skrll while (c--) 478 1.1 skrll *(volatile uint16_t *)h = vv; 479 1.1 skrll } 480 1.1 skrll 481 1.1 skrll void 482 1.1 skrll mg_isa_sm_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv, bus_size_t c) 483 1.1 skrll { 484 1.1 skrll vv = htole32(vv); 485 1.1 skrll h += o; 486 1.1 skrll while (c--) 487 1.1 skrll *(volatile uint32_t *)h = vv; 488 1.1 skrll } 489 1.1 skrll 490 1.1 skrll void 491 1.1 skrll mg_isa_rr_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t *a, bus_size_t c) 492 1.1 skrll { 493 1.1 skrll uint16_t r; 494 1.1 skrll volatile uint16_t *p; 495 1.1 skrll 496 1.1 skrll h += o; 497 1.1 skrll p = (void *)h; 498 1.1 skrll while (c--) { 499 1.1 skrll r = *p++; 500 1.1 skrll *a++ = le16toh(r); 501 1.1 skrll } 502 1.1 skrll } 503 1.1 skrll 504 1.1 skrll void 505 1.1 skrll mg_isa_rr_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t *a, bus_size_t c) 506 1.1 skrll { 507 1.1 skrll uint32_t r; 508 1.1 skrll volatile uint32_t *p; 509 1.1 skrll 510 1.1 skrll h += o; 511 1.1 skrll p = (void *)h; 512 1.1 skrll while (c--) { 513 1.1 skrll r = *p++; 514 1.1 skrll *a++ = le32toh(r); 515 1.1 skrll } 516 1.1 skrll } 517 1.1 skrll 518 1.1 skrll void 519 1.1 skrll mg_isa_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const uint16_t *a, bus_size_t c) 520 1.1 skrll { 521 1.1 skrll uint16_t r; 522 1.1 skrll volatile uint16_t *p; 523 1.1 skrll 524 1.1 skrll h += o; 525 1.1 skrll p = (void *)h; 526 1.1 skrll while (c--) { 527 1.1 skrll r = *a++; 528 1.1 skrll *p++ = htole16(r); 529 1.1 skrll } 530 1.1 skrll } 531 1.1 skrll 532 1.1 skrll void 533 1.1 skrll mg_isa_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const uint32_t *a, bus_size_t c) 534 1.1 skrll { 535 1.1 skrll uint32_t r; 536 1.1 skrll volatile uint32_t *p; 537 1.1 skrll 538 1.1 skrll h += o; 539 1.1 skrll p = (void *)h; 540 1.1 skrll while (c--) { 541 1.1 skrll r = *a++; 542 1.1 skrll *p++ = htole32(r); 543 1.1 skrll } 544 1.1 skrll } 545 1.1 skrll 546 1.1 skrll void 547 1.1 skrll mg_isa_sr_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv, bus_size_t c) 548 1.1 skrll { 549 1.1 skrll volatile uint16_t *p; 550 1.1 skrll 551 1.1 skrll vv = htole16(vv); 552 1.1 skrll h += o; 553 1.1 skrll p = (void *)h; 554 1.1 skrll while (c--) 555 1.1 skrll *p++ = vv; 556 1.1 skrll } 557 1.1 skrll 558 1.1 skrll void 559 1.1 skrll mg_isa_sr_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv, bus_size_t c) 560 1.1 skrll { 561 1.1 skrll volatile uint32_t *p; 562 1.1 skrll 563 1.1 skrll vv = htole32(vv); 564 1.1 skrll h += o; 565 1.1 skrll p = (void *)h; 566 1.1 skrll while (c--) 567 1.1 skrll *p++ = vv; 568 1.1 skrll } 569 1.1 skrll 570 1.1 skrll int 571 1.1 skrll mgmatch(device_t parent, cfdata_t cf, void *aux) 572 1.1 skrll { 573 1.1 skrll struct confargs *ca = aux; 574 1.1 skrll bus_space_handle_t ioh; 575 1.1 skrll 576 1.1 skrll if (ca->ca_type.iodc_type != HPPA_TYPE_BHA || 577 1.1 skrll ca->ca_type.iodc_sv_model != HPPA_BHA_EISA) 578 1.1 skrll return 0; 579 1.1 skrll 580 1.1 skrll if (bus_space_map(ca->ca_iot, ca->ca_hpa + MONGOOSE_MONGOOSE, 581 1.1 skrll sizeof(struct mongoose_regs), 0, &ioh)) 582 1.1 skrll return 0; 583 1.1 skrll 584 1.1 skrll /* XXX check EISA signature */ 585 1.1 skrll 586 1.1 skrll bus_space_unmap(ca->ca_iot, ioh, sizeof(struct mongoose_regs)); 587 1.1 skrll 588 1.1 skrll return 1; 589 1.1 skrll } 590 1.1 skrll 591 1.1 skrll void 592 1.1 skrll mgattach(device_t parent, device_t self, void *aux) 593 1.1 skrll { 594 1.1 skrll struct confargs *ca = aux; 595 1.1 skrll struct mongoose_softc *sc = device_private(self); 596 1.1 skrll struct cpu_info *ci = &cpus[0]; 597 1.1 skrll struct hppa_bus_space_tag *bt; 598 1.1 skrll union mongoose_attach_args ea; 599 1.1 skrll char brid[EISA_IDSTRINGLEN]; 600 1.1 skrll bus_space_handle_t ioh; 601 1.1 skrll 602 1.1 skrll sc->sc_dev = self; 603 1.1 skrll sc->sc_bt = ca->ca_iot; 604 1.1 skrll sc->sc_iomap = ca->ca_hpa; 605 1.1 skrll if (bus_space_map(ca->ca_iot, ca->ca_hpa + MONGOOSE_MONGOOSE, 606 1.1 skrll sizeof(struct mongoose_regs), 0, &ioh)) { 607 1.1 skrll aprint_error(": can't map registers\n"); 608 1.1 skrll return; 609 1.1 skrll } 610 1.1 skrll sc->sc_regs = (struct mongoose_regs *)ioh; 611 1.1 skrll 612 1.1 skrll if (bus_space_map(ca->ca_iot, ca->ca_hpa + MONGOOSE_CTRL, 613 1.1 skrll sizeof(struct mongoose_ctrl), 0, &ioh)) { 614 1.1 skrll aprint_error(": can't map control registers\n"); 615 1.1 skrll bus_space_unmap(ca->ca_iot, (bus_space_handle_t)sc->sc_regs, 616 1.1 skrll sizeof(struct mongoose_regs)); 617 1.1 skrll return; 618 1.1 skrll } 619 1.1 skrll 620 1.1 skrll ca->ca_irq = hppa_intr_allocate_bit(&ci->ci_ir, ca->ca_irq); 621 1.1 skrll if (ca->ca_irq == HPPACF_IRQ_UNDEF) { 622 1.1 skrll aprint_error(": can't allocate interrupt\n"); 623 1.1 skrll return; 624 1.1 skrll } 625 1.1 skrll 626 1.1 skrll sc->sc_ctrl = (struct mongoose_ctrl *)ioh; 627 1.1 skrll 628 1.1 skrll viper_eisa_en(); 629 1.1 skrll 630 1.1 skrll /* BUS RESET */ 631 1.1 skrll sc->sc_ctrl->nmi_ext = MONGOOSE_NMI_BUSRESET; 632 1.1 skrll DELAY(1); 633 1.1 skrll sc->sc_ctrl->nmi_ext = 0; 634 1.1 skrll DELAY(100); 635 1.1 skrll 636 1.1 skrll /* determine eisa board id */ 637 1.1 skrll { 638 1.1 skrll uint8_t id[4], *p; 639 1.1 skrll /* XXX this is awful */ 640 1.1 skrll p = (uint8_t *)(ioh + EISA_SLOTOFF_VID); 641 1.1 skrll id[0] = *p++; 642 1.1 skrll id[1] = *p++; 643 1.1 skrll id[2] = *p++; 644 1.1 skrll id[3] = *p++; 645 1.1 skrll 646 1.1 skrll brid[0] = EISA_VENDID_0(id); 647 1.1 skrll brid[1] = EISA_VENDID_1(id); 648 1.1 skrll brid[2] = EISA_VENDID_2(id); 649 1.1 skrll brid[3] = EISA_PRODID_0(id + 2); 650 1.1 skrll brid[4] = EISA_PRODID_1(id + 2); 651 1.1 skrll brid[5] = EISA_PRODID_2(id + 2); 652 1.1 skrll brid[6] = EISA_PRODID_3(id + 2); 653 1.1 skrll brid[7] = '\0'; 654 1.1 skrll } 655 1.1 skrll 656 1.1 skrll aprint_normal(": %s rev %d, %d MHz\n", brid, sc->sc_regs->version, 657 1.1 skrll (sc->sc_regs->clock? 33 : 25)); 658 1.1 skrll sc->sc_regs->liowait = 1; /* disable isa wait states */ 659 1.1 skrll sc->sc_regs->lock = 1; /* bus unlock */ 660 1.1 skrll 661 1.1 skrll /* attach EISA */ 662 1.1 skrll sc->sc_ec.ec_v = sc; 663 1.1 skrll sc->sc_ec.ec_attach_hook = mg_eisa_attach_hook; 664 1.1 skrll sc->sc_ec.ec_intr_establish = mg_intr_establish; 665 1.1 skrll sc->sc_ec.ec_intr_disestablish = mg_intr_disestablish; 666 1.1 skrll sc->sc_ec.ec_intr_string = mg_intr_string; 667 1.1 skrll sc->sc_ec.ec_intr_map = mg_intr_map; 668 1.1 skrll 669 1.1 skrll /* inherit the bus tags for eisa from the mainbus */ 670 1.1 skrll bt = &sc->sc_eiot; 671 1.1 skrll memcpy(bt, ca->ca_iot, sizeof(*bt)); 672 1.1 skrll bt->hbt_cookie = sc; 673 1.1 skrll bt->hbt_map = mg_eisa_iomap; 674 1.1 skrll #define R(n) bt->__CONCAT(hbt_,n) = &__CONCAT(mg_isa_,n) 675 1.1 skrll /* R(barrier); */ 676 1.1 skrll R(r2); R(r4); R(w2); R(w4); 677 1.1 skrll R(rm_2);R(rm_4);R(wm_2);R(wm_4);R(sm_2);R(sm_4); 678 1.1 skrll R(rr_2);R(rr_4);R(wr_2);R(wr_4);R(sr_2);R(sr_4); 679 1.1 skrll 680 1.1 skrll bt = &sc->sc_ememt; 681 1.1 skrll memcpy(bt, ca->ca_iot, sizeof(*bt)); 682 1.1 skrll bt->hbt_cookie = sc; 683 1.1 skrll bt->hbt_map = mg_eisa_memmap; 684 1.1 skrll bt->hbt_unmap = mg_eisa_memunmap; 685 1.1 skrll 686 1.1 skrll /* attachment guts */ 687 1.1 skrll ea.mongoose_eisa.eba_iot = &sc->sc_eiot; 688 1.1 skrll ea.mongoose_eisa.eba_memt = &sc->sc_ememt; 689 1.1 skrll ea.mongoose_eisa.eba_dmat = NULL /* &sc->sc_edmat */; 690 1.1 skrll ea.mongoose_eisa.eba_ec = &sc->sc_ec; 691 1.6 thorpej config_found(self, &ea.mongoose_eisa, eisabusprint, 692 1.7 thorpej CFARGS(.iattr = "eisabus")); 693 1.1 skrll 694 1.1 skrll sc->sc_ic.ic_v = sc; 695 1.1 skrll sc->sc_ic.ic_attach_hook = mg_isa_attach_hook; 696 1.1 skrll sc->sc_ic.ic_detach_hook = mg_isa_detach_hook; 697 1.1 skrll sc->sc_ic.ic_intr_establish = mg_intr_establish; 698 1.1 skrll sc->sc_ic.ic_intr_disestablish = mg_intr_disestablish; 699 1.1 skrll sc->sc_ic.ic_intr_check = mg_intr_check; 700 1.1 skrll 701 1.1 skrll /* inherit the bus tags for isa from the eisa */ 702 1.1 skrll bt = &sc->sc_imemt; 703 1.1 skrll memcpy(bt, &sc->sc_ememt, sizeof(*bt)); 704 1.1 skrll bt = &sc->sc_iiot; 705 1.1 skrll memcpy(bt, &sc->sc_eiot, sizeof(*bt)); 706 1.1 skrll 707 1.1 skrll /* TODO: DMA tags */ 708 1.1 skrll 709 1.1 skrll /* attachment guts */ 710 1.1 skrll ea.mongoose_isa.iba_iot = &sc->sc_iiot; 711 1.1 skrll ea.mongoose_isa.iba_memt = &sc->sc_imemt; 712 1.1 skrll #if NISADMA > 0 713 1.1 skrll ea.mongoose_isa.iba_dmat = &sc->sc_idmat; 714 1.1 skrll #endif 715 1.1 skrll ea.mongoose_isa.iba_ic = &sc->sc_ic; 716 1.6 thorpej config_found(self, &ea.mongoose_isa, isabusprint, 717 1.7 thorpej CFARGS(.iattr = "isabus")); 718 1.1 skrll #undef R 719 1.1 skrll 720 1.1 skrll /* attach interrupt */ 721 1.1 skrll sc->sc_ih = hppa_intr_establish(IPL_NONE, mg_intr, sc, &ci->ci_ir, 722 1.1 skrll ca->ca_irq); 723 1.1 skrll } 724