Annotation of sys/arch/hppa/dev/mongoose.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: mongoose.c,v 1.17 2004/11/08 20:54:04 miod Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 1998-2003 Michael Shalayeff
! 5: * All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: *
! 16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 19: * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
! 20: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
! 21: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
! 22: * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
! 24: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
! 25: * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
! 26: * THE POSSIBILITY OF SUCH DAMAGE.
! 27: */
! 28:
! 29: #include <sys/param.h>
! 30: #include <sys/systm.h>
! 31: #include <sys/device.h>
! 32: #include <sys/reboot.h>
! 33:
! 34: #include <machine/bus.h>
! 35: #include <machine/iomod.h>
! 36: #include <machine/autoconf.h>
! 37:
! 38: #include <hppa/dev/cpudevs.h>
! 39: #include <hppa/dev/viper.h>
! 40:
! 41: #include <dev/eisa/eisareg.h>
! 42: #include <dev/eisa/eisavar.h>
! 43:
! 44: #include <dev/isa/isareg.h>
! 45: #include <dev/isa/isavar.h>
! 46:
! 47: #include <hppa/dev/mongoosereg.h>
! 48: #include <hppa/dev/mongoosevar.h>
! 49:
! 50: void mgattach_gedoens(struct device *, struct device *, void *);
! 51: int mgmatch_gedoens(struct device *, void *, void *);
! 52:
! 53: struct cfattach mg_gedoens_ca = {
! 54: sizeof(struct mongoose_softc), mgmatch_gedoens, mgattach_gedoens
! 55: };
! 56:
! 57: struct cfdriver mongoose_cd = {
! 58: NULL, "mongoose", DV_DULL
! 59: };
! 60:
! 61: /* TODO: DMA guts */
! 62:
! 63: void
! 64: mg_eisa_attach_hook(struct device *parent, struct device *self,
! 65: struct eisabus_attach_args *mg)
! 66: {
! 67: }
! 68:
! 69: int
! 70: mg_intr_map(void *v, u_int irq, eisa_intr_handle_t *ehp)
! 71: {
! 72: *ehp = irq;
! 73: return 0;
! 74: }
! 75:
! 76: const char *
! 77: mg_intr_string(void *v, int irq)
! 78: {
! 79: static char buf[16];
! 80:
! 81: snprintf(buf, sizeof buf, "isa irq %d", irq);
! 82: return buf;
! 83: }
! 84:
! 85: void
! 86: mg_isa_attach_hook(struct device *parent, struct device *self,
! 87: struct isabus_attach_args *iba)
! 88: {
! 89:
! 90: }
! 91:
! 92: void *
! 93: mg_intr_establish(void *v, int irq, int type, int pri,
! 94: int (*handler)(void *), void *arg, const char *name)
! 95: {
! 96: struct hppa_isa_iv *iv;
! 97: struct mongoose_softc *sc = v;
! 98: volatile u_int8_t *imr, *pic;
! 99:
! 100: if (!sc || irq < 0 || irq >= MONGOOSE_NINTS ||
! 101: (0 <= irq && irq < MONGOOSE_NINTS && sc->sc_iv[irq].iv_handler))
! 102: return NULL;
! 103:
! 104: if (type != IST_LEVEL && type != IST_EDGE) {
! 105: #ifdef DEBUG
! 106: printf("%s: bad interrupt level (%d)\n", sc->sc_dev.dv_xname,
! 107: type);
! 108: #endif
! 109: return NULL;
! 110: }
! 111:
! 112: iv = &sc->sc_iv[irq];
! 113: if (iv->iv_handler) {
! 114: #ifdef DEBUG
! 115: printf("%s: irq %d already established\n", sc->sc_dev.dv_xname,
! 116: irq);
! 117: #endif
! 118: return NULL;
! 119: }
! 120:
! 121: iv->iv_name = name;
! 122: iv->iv_pri = pri;
! 123: iv->iv_handler = handler;
! 124: iv->iv_arg = arg;
! 125:
! 126: if (irq < 8) {
! 127: imr = &sc->sc_ctrl->imr0;
! 128: pic = &sc->sc_ctrl->pic0;
! 129: } else {
! 130: imr = &sc->sc_ctrl->imr1;
! 131: pic = &sc->sc_ctrl->pic1;
! 132: irq -= 8;
! 133: }
! 134:
! 135: *imr |= 1 << irq;
! 136: *pic |= (type == IST_LEVEL) << irq;
! 137:
! 138: /* TODO: ack it? */
! 139:
! 140: return iv;
! 141: }
! 142:
! 143: void
! 144: mg_intr_disestablish(void *v, void *cookie)
! 145: {
! 146: struct hppa_isa_iv *iv = cookie;
! 147: struct mongoose_softc *sc = v;
! 148: int irq = iv - sc->sc_iv;
! 149: volatile u_int8_t *imr;
! 150:
! 151: if (!sc || !cookie)
! 152: return;
! 153:
! 154: if (irq < 8)
! 155: imr = &sc->sc_ctrl->imr0;
! 156: else
! 157: imr = &sc->sc_ctrl->imr1;
! 158: *imr &= ~(1 << irq);
! 159: /* TODO: ack it? */
! 160:
! 161: iv->iv_handler = NULL;
! 162: }
! 163:
! 164: int
! 165: mg_intr_check(void *v, int irq, int type)
! 166: {
! 167: return 0;
! 168: }
! 169:
! 170: int
! 171: mg_intr(void *v)
! 172: {
! 173: struct mongoose_softc *sc = v;
! 174: struct hppa_isa_iv *iv;
! 175: int s, irq = 0;
! 176:
! 177: iv = &sc->sc_iv[irq];
! 178: s = splraise(iv->iv_pri);
! 179: (iv->iv_handler)(iv->iv_arg);
! 180: splx(s);
! 181:
! 182: return 0;
! 183: }
! 184:
! 185: int
! 186: mg_eisa_iomap(void *v, bus_addr_t addr, bus_size_t size, int cacheable,
! 187: bus_space_handle_t *bshp)
! 188: {
! 189: struct mongoose_softc *sc = v;
! 190:
! 191: /* see if it's ISA space we are mapping */
! 192: if (0x100 <= addr && addr < 0x400) {
! 193: #define TOISA(a) ((((a) & 0x3f8) << 9) + ((a) & 7))
! 194: size = TOISA(addr + size) - TOISA(addr);
! 195: addr = TOISA(addr);
! 196: }
! 197:
! 198: return (sc->sc_bt->hbt_map)(NULL, sc->sc_iomap + addr, size,
! 199: cacheable, bshp);
! 200: }
! 201:
! 202: int
! 203: mg_eisa_memmap(void *v, bus_addr_t addr, bus_size_t size, int cacheable,
! 204: bus_space_handle_t *bshp)
! 205: {
! 206: /* TODO: eisa memory map */
! 207: return -1;
! 208: }
! 209:
! 210: void
! 211: mg_eisa_memunmap(void *v, bus_space_handle_t bsh, bus_size_t size)
! 212: {
! 213: /* TODO: eisa memory unmap */
! 214: }
! 215:
! 216: void
! 217: mg_isa_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op)
! 218: {
! 219: sync_caches();
! 220: }
! 221:
! 222: u_int16_t
! 223: mg_isa_r2(void *v, bus_space_handle_t h, bus_size_t o)
! 224: {
! 225: register u_int16_t r = *((volatile u_int16_t *)(h + o));
! 226: return letoh16(r);
! 227: }
! 228:
! 229: u_int32_t
! 230: mg_isa_r4(void *v, bus_space_handle_t h, bus_size_t o)
! 231: {
! 232: register u_int32_t r = *((volatile u_int32_t *)(h + o));
! 233: return letoh32(r);
! 234: }
! 235:
! 236: void
! 237: mg_isa_w2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv)
! 238: {
! 239: *((volatile u_int16_t *)(h + o)) = htole16(vv);
! 240: }
! 241:
! 242: void
! 243: mg_isa_w4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv)
! 244: {
! 245: *((volatile u_int32_t *)(h + o)) = htole32(vv);
! 246: }
! 247:
! 248: void
! 249: mg_isa_rm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
! 250: {
! 251: h += o;
! 252: while (c--)
! 253: *(a++) = letoh16(*(volatile u_int16_t *)h);
! 254: }
! 255:
! 256: void
! 257: mg_isa_rm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
! 258: {
! 259: h += o;
! 260: while (c--)
! 261: *(a++) = letoh32(*(volatile u_int32_t *)h);
! 262: }
! 263:
! 264: void
! 265: mg_isa_wm_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
! 266: {
! 267: register u_int16_t r;
! 268: h += o;
! 269: while (c--) {
! 270: r = *(a++);
! 271: *(volatile u_int16_t *)h = htole16(r);
! 272: }
! 273: }
! 274:
! 275: void
! 276: mg_isa_wm_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
! 277: {
! 278: register u_int32_t r;
! 279: h += o;
! 280: while (c--) {
! 281: r = *(a++);
! 282: *(volatile u_int32_t *)h = htole32(r);
! 283: }
! 284: }
! 285:
! 286: void
! 287: mg_isa_sm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
! 288: {
! 289: vv = htole16(vv);
! 290: h += o;
! 291: while (c--)
! 292: *(volatile u_int16_t *)h = vv;
! 293: }
! 294:
! 295: void
! 296: mg_isa_sm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
! 297: {
! 298: vv = htole32(vv);
! 299: h += o;
! 300: while (c--)
! 301: *(volatile u_int32_t *)h = vv;
! 302: }
! 303:
! 304: void
! 305: mg_isa_rr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
! 306: {
! 307: register u_int16_t r;
! 308: h += o;
! 309: while (c--) {
! 310: r = *((volatile u_int16_t *)h)++;
! 311: *(a++) = letoh16(r);
! 312: }
! 313: }
! 314:
! 315: void
! 316: mg_isa_rr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
! 317: {
! 318: register u_int32_t r;
! 319: h += o;
! 320: while (c--) {
! 321: r = *((volatile u_int32_t *)h)++;
! 322: *(a++) = letoh32(r);
! 323: }
! 324: }
! 325:
! 326: void
! 327: mg_isa_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
! 328: {
! 329: register u_int16_t r;
! 330: h += o;
! 331: while (c--) {
! 332: r = *(a++);
! 333: *((volatile u_int16_t *)h)++ = htole16(r);
! 334: }
! 335: }
! 336:
! 337: void
! 338: mg_isa_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
! 339: {
! 340: register u_int32_t r;
! 341: h += o;
! 342: while (c--) {
! 343: r = *(a++);
! 344: *((volatile u_int32_t *)h)++ = htole32(r);
! 345: }
! 346: }
! 347:
! 348: void
! 349: mg_isa_sr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
! 350: {
! 351: vv = htole16(vv);
! 352: h += o;
! 353: while (c--)
! 354: *((volatile u_int16_t *)h)++ = vv;
! 355: }
! 356:
! 357: void
! 358: mg_isa_sr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
! 359: {
! 360: vv = htole32(vv);
! 361: h += o;
! 362: while (c--)
! 363: *((volatile u_int32_t *)h)++ = vv;
! 364: }
! 365:
! 366: int
! 367: mgattach_common(sc)
! 368: struct mongoose_softc *sc;
! 369: {
! 370: struct hppa_bus_space_tag *bt;
! 371: union mongoose_attach_args ea;
! 372: char brid[EISA_IDSTRINGLEN];
! 373:
! 374: viper_eisa_en();
! 375:
! 376: /* BUS RESET */
! 377: sc->sc_ctrl->nmi_ext = MONGOOSE_NMI_BUSRESET;
! 378: DELAY(1);
! 379: sc->sc_ctrl->nmi_ext = 0;
! 380: DELAY(100);
! 381:
! 382: /* determine eisa board id */
! 383: {
! 384: u_int8_t id[4], *p;
! 385: p = (u_int8_t *)(sc->sc_iomap + EISA_SLOTOFF_VID);
! 386: id[0] = *p++;
! 387: id[1] = *p++;
! 388: id[2] = *p++;
! 389: id[3] = *p++;
! 390:
! 391: brid[0] = EISA_VENDID_0(id);
! 392: brid[1] = EISA_VENDID_1(id);
! 393: brid[2] = EISA_VENDID_2(id);
! 394: brid[3] = EISA_PRODID_0(id + 2);
! 395: brid[4] = EISA_PRODID_1(id + 2);
! 396: brid[5] = EISA_PRODID_2(id + 2);
! 397: brid[6] = EISA_PRODID_3(id + 2);
! 398: brid[7] = '\0';
! 399: }
! 400:
! 401: printf (": %s rev %d, %d MHz\n", brid, sc->sc_regs->version,
! 402: (sc->sc_regs->clock? 33 : 25));
! 403: sc->sc_regs->liowait = 1; /* disable isa wait states */
! 404: sc->sc_regs->lock = 1; /* bus unlock */
! 405:
! 406: /* attach EISA */
! 407: sc->sc_ec.ec_v = sc;
! 408: sc->sc_ec.ec_attach_hook = mg_eisa_attach_hook;
! 409: sc->sc_ec.ec_intr_establish = mg_intr_establish;
! 410: sc->sc_ec.ec_intr_disestablish = mg_intr_disestablish;
! 411: sc->sc_ec.ec_intr_string = mg_intr_string;
! 412: sc->sc_ec.ec_intr_map = mg_intr_map;
! 413: /* inherit the bus tags for eisa from the mainbus */
! 414: bt = &sc->sc_eiot;
! 415: bcopy(sc->sc_bt, bt, sizeof(*bt));
! 416: bt->hbt_cookie = sc;
! 417: bt->hbt_map = mg_eisa_iomap;
! 418: #define R(n) bt->__CONCAT(hbt_,n) = &__CONCAT(mg_isa_,n)
! 419: /* R(barrier); */
! 420: R(r2); R(r4); R(w2); R(w4);
! 421: R(rm_2);R(rm_4);R(wm_2);R(wm_4);R(sm_2);R(sm_4);
! 422: R(rr_2);R(rr_4);R(wr_2);R(wr_4);R(sr_2);R(sr_4);
! 423:
! 424: bt = &sc->sc_ememt;
! 425: bcopy(sc->sc_bt, bt, sizeof(*bt));
! 426: bt->hbt_cookie = sc;
! 427: bt->hbt_map = mg_eisa_memmap;
! 428: bt->hbt_unmap = mg_eisa_memunmap;
! 429: /* attachment guts */
! 430: ea.mongoose_eisa.eba_busname = "eisa";
! 431: ea.mongoose_eisa.eba_iot = &sc->sc_eiot;
! 432: ea.mongoose_eisa.eba_memt = &sc->sc_ememt;
! 433: ea.mongoose_eisa.eba_dmat = NULL /* &sc->sc_edmat */;
! 434: ea.mongoose_eisa.eba_ec = &sc->sc_ec;
! 435: config_found((struct device *)sc, &ea.mongoose_eisa, mgprint);
! 436:
! 437: sc->sc_ic.ic_v = sc;
! 438: sc->sc_ic.ic_attach_hook = mg_isa_attach_hook;
! 439: sc->sc_ic.ic_intr_establish = mg_intr_establish;
! 440: sc->sc_ic.ic_intr_disestablish = mg_intr_disestablish;
! 441: sc->sc_ic.ic_intr_check = mg_intr_check;
! 442: /* inherit the bus tags for isa from the eisa */
! 443: bt = &sc->sc_imemt;
! 444: bcopy(&sc->sc_ememt, bt, sizeof(*bt));
! 445: bt = &sc->sc_iiot;
! 446: bcopy(&sc->sc_eiot, bt, sizeof(*bt));
! 447: /* TODO: DMA tags */
! 448: /* attachment guts */
! 449: ea.mongoose_isa.iba_busname = "isa";
! 450: ea.mongoose_isa.iba_iot = &sc->sc_iiot;
! 451: ea.mongoose_isa.iba_memt = &sc->sc_imemt;
! 452: #if NISADMA > 0
! 453: ea.mongoose_isa.iba_dmat = &sc->sc_idmat;
! 454: #endif
! 455: ea.mongoose_isa.iba_ic = &sc->sc_ic;
! 456: config_found((struct device *)sc, &ea.mongoose_isa, mgprint);
! 457: #undef R
! 458:
! 459: return (0);
! 460: }
! 461:
! 462: int
! 463: mgprint(aux, pnp)
! 464: void *aux;
! 465: const char *pnp;
! 466: {
! 467: union mongoose_attach_args *ea = aux;
! 468:
! 469: if (pnp)
! 470: printf ("%s at %s", ea->mongoose_name, pnp);
! 471:
! 472: return (UNCONF);
! 473: }
! 474:
! 475: int
! 476: mgmatch_gedoens(parent, cfdata, aux)
! 477: struct device *parent;
! 478: void *cfdata;
! 479: void *aux;
! 480: {
! 481: register struct confargs *ca = aux;
! 482: /* struct cfdata *cf = cfdata; */
! 483: bus_space_handle_t ioh;
! 484:
! 485: if (ca->ca_type.iodc_type != HPPA_TYPE_BHA ||
! 486: (ca->ca_type.iodc_sv_model != HPPA_BHA_EISA &&
! 487: ca->ca_type.iodc_sv_model != HPPA_BHA_WEISA))
! 488: return 0;
! 489:
! 490: if (bus_space_map(ca->ca_iot, ca->ca_hpa + MONGOOSE_MONGOOSE,
! 491: IOMOD_HPASIZE, 0, &ioh))
! 492: return 0;
! 493:
! 494: /* XXX check EISA signature */
! 495:
! 496: bus_space_unmap(ca->ca_iot, ioh, IOMOD_HPASIZE);
! 497:
! 498: return 1;
! 499: }
! 500:
! 501: void
! 502: mgattach_gedoens(parent, self, aux)
! 503: struct device *parent;
! 504: struct device *self;
! 505: void *aux;
! 506: {
! 507: register struct confargs *ca = aux;
! 508: register struct mongoose_softc *sc = (struct mongoose_softc *)self;
! 509:
! 510: sc->sc_bt = ca->ca_iot;
! 511: sc->sc_iomap = ca->ca_hpa;
! 512: sc->sc_regs = (struct mongoose_regs *)(ca->ca_hpa + MONGOOSE_MONGOOSE);
! 513: sc->sc_ctrl = (struct mongoose_ctrl *)(ca->ca_hpa + MONGOOSE_CTRL);
! 514:
! 515: if (mgattach_common(sc) != 0)
! 516: return;
! 517:
! 518: /* attach interrupt */
! 519: sc->sc_ih = cpu_intr_establish(IPL_HIGH, ca->ca_irq,
! 520: mg_intr, sc, sc->sc_dev.dv_xname);
! 521: }
CVSweb