Annotation of sys/arch/mvme88k/dev/bussw.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: bussw.c,v 1.17 2006/05/08 14:36:10 miod Exp $ */
! 2: /*
! 3: * Copyright (c) 1999 Steve Murphree, Jr.
! 4: *
! 5: * Redistribution and use in source and binary forms, with or without
! 6: * modification, are permitted provided that the following conditions
! 7: * are met:
! 8: * 1. Redistributions of source code must retain the above copyright
! 9: * notice, this list of conditions and the following disclaimer.
! 10: * 2. Redistributions in binary form must reproduce the above copyright
! 11: * notice, this list of conditions and the following disclaimer in the
! 12: * documentation and/or other materials provided with the distribution.
! 13: *
! 14: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
! 15: * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! 16: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 17: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
! 18: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 19: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 20: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 21: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 22: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 23: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 24: * SUCH DAMAGE.
! 25: */
! 26:
! 27: #include <sys/param.h>
! 28: #include <sys/kernel.h>
! 29: #include <sys/device.h>
! 30: #include <sys/systm.h>
! 31:
! 32: #include <machine/autoconf.h>
! 33: #include <machine/cpu.h>
! 34:
! 35: #include <mvme88k/dev/busswreg.h>
! 36:
! 37: struct bussw_softc {
! 38: struct device sc_dev;
! 39: struct intrhand sc_abih; /* `abort' switch */
! 40: bus_space_tag_t sc_iot;
! 41: bus_space_handle_t sc_ioh;
! 42: };
! 43:
! 44: void bussw_attach(struct device *, struct device *, void *);
! 45: int bussw_match(struct device *, void *, void *);
! 46:
! 47: struct cfattach bussw_ca = {
! 48: sizeof(struct bussw_softc), bussw_match, bussw_attach
! 49: };
! 50:
! 51: struct cfdriver bussw_cd = {
! 52: NULL, "bussw", DV_DULL
! 53: };
! 54:
! 55: int bussw_print(void *, const char *);
! 56: int bussw_scan(struct device *, void *, void *);
! 57: int busswabort(void *);
! 58: int busswintr_establish(int, struct intrhand *, const char *);
! 59:
! 60: int
! 61: bussw_match(parent, vcf, args)
! 62: struct device *parent;
! 63: void *vcf, *args;
! 64: {
! 65: struct confargs *ca = args;
! 66: bus_space_handle_t ioh;
! 67: int rc;
! 68: u_int8_t chipid;
! 69:
! 70: /* Don't match if wrong cpu */
! 71: if (brdtyp != BRD_197)
! 72: return 0;
! 73:
! 74: if (bus_space_map(ca->ca_iot, ca->ca_paddr, BS_SIZE, 0, &ioh) != 0)
! 75: return 0;
! 76: rc = badaddr((vaddr_t)bus_space_vaddr(ca->ca_iot, ioh), 4);
! 77: if (rc == 0) {
! 78: chipid = bus_space_read_1(ca->ca_iot, ioh, BS_CHIPID);
! 79: if (chipid != BUSSWITCH_ID) {
! 80: #ifdef DEBUG
! 81: printf("==> busswitch: wrong chip id %x\n", chipid);
! 82: #endif
! 83: rc = -1;
! 84: }
! 85: }
! 86: bus_space_unmap(ca->ca_iot, ioh, BS_SIZE);
! 87:
! 88: return rc == 0;
! 89: }
! 90:
! 91: void
! 92: bussw_attach(parent, self, args)
! 93: struct device *parent, *self;
! 94: void *args;
! 95: {
! 96: struct confargs *ca = args;
! 97: struct bussw_softc *sc = (struct bussw_softc *)self;
! 98: bus_space_handle_t ioh;
! 99:
! 100: if (bus_space_map(ca->ca_iot, ca->ca_paddr, BS_SIZE, 0, &ioh) != 0) {
! 101: printf(": can't map registers!\n");
! 102: return;
! 103: }
! 104:
! 105: sc->sc_iot = ca->ca_iot;
! 106: sc->sc_ioh = ioh;
! 107:
! 108: bus_space_write_1(sc->sc_iot, ioh, BS_VBASE,
! 109: bus_space_read_1(sc->sc_iot, ioh, BS_VBASE) | BS_VECBASE);
! 110: bus_space_write_2(sc->sc_iot, ioh, BS_GCSR,
! 111: bus_space_read_2(sc->sc_iot, ioh, BS_GCSR) | BS_GCSR_XIPL);
! 112:
! 113: /*
! 114: * pseudo driver, abort interrupt handler
! 115: */
! 116: sc->sc_abih.ih_fn = busswabort;
! 117: sc->sc_abih.ih_arg = 0;
! 118: sc->sc_abih.ih_wantframe = 1;
! 119: sc->sc_abih.ih_ipl = IPL_NMI;
! 120:
! 121: busswintr_establish(BS_ABORTIRQ, &sc->sc_abih, "abort");
! 122: bus_space_write_1(sc->sc_iot, ioh, BS_ABORT,
! 123: bus_space_read_4(sc->sc_iot, ioh, BS_ABORT) | BS_ABORT_IEN);
! 124:
! 125: printf(": rev %x\n",
! 126: bus_space_read_1(sc->sc_iot, ioh, BS_CHIPREV));
! 127:
! 128: config_search(bussw_scan, self, args);
! 129: }
! 130:
! 131: int
! 132: bussw_print(args, bus)
! 133: void *args;
! 134: const char *bus;
! 135: {
! 136: struct confargs *ca = args;
! 137:
! 138: if (ca->ca_offset != -1)
! 139: printf(" offset 0x%x", ca->ca_offset);
! 140: if (ca->ca_ipl > 0)
! 141: printf(" ipl %d", ca->ca_ipl);
! 142: return (UNCONF);
! 143: }
! 144:
! 145: int
! 146: bussw_scan(parent, child, args)
! 147: struct device *parent;
! 148: void *child, *args;
! 149: {
! 150: struct cfdata *cf = child;
! 151: struct confargs oca, *ca = args;
! 152:
! 153: bzero(&oca, sizeof oca);
! 154: oca.ca_iot = ca->ca_iot;
! 155: oca.ca_dmat = ca->ca_dmat;
! 156: oca.ca_offset = cf->cf_loc[0];
! 157: oca.ca_ipl = cf->cf_loc[1];
! 158: if (oca.ca_offset != -1) {
! 159: oca.ca_paddr = ca->ca_paddr + oca.ca_offset;
! 160: } else {
! 161: oca.ca_paddr = -1;
! 162: }
! 163: oca.ca_bustype = BUS_BUSSWITCH;
! 164: oca.ca_name = cf->cf_driver->cd_name;
! 165: if ((*cf->cf_attach->ca_match)(parent, cf, &oca) == 0)
! 166: return (0);
! 167: config_attach(parent, cf, &oca, bussw_print);
! 168: return (1);
! 169: }
! 170:
! 171: int
! 172: busswintr_establish(int vec, struct intrhand *ih, const char *name)
! 173: {
! 174: #ifdef DIAGNOSTIC
! 175: if (vec < 0 || vec >= BS_NVEC)
! 176: panic("busswintr_establish: illegal vector 0x%x", vec);
! 177: #endif
! 178:
! 179: return intr_establish(BS_VECBASE + vec, ih, name);
! 180: }
! 181:
! 182: int
! 183: busswabort(eframe)
! 184: void *eframe;
! 185: {
! 186: struct frame *frame = eframe;
! 187:
! 188: struct bussw_softc *sc = (struct bussw_softc *)bussw_cd.cd_devs[0];
! 189: u_int8_t abort;
! 190:
! 191: abort = bus_space_read_1(sc->sc_iot, sc->sc_ioh, BS_ABORT);
! 192: if (abort & BS_ABORT_INT) {
! 193: bus_space_write_1(sc->sc_iot, sc->sc_ioh, BS_ABORT,
! 194: abort | BS_ABORT_ICLR);
! 195: nmihand(frame);
! 196: return 1;
! 197: }
! 198: return 0;
! 199: }
CVSweb