diff options
Diffstat (limited to 'sys/arch/mvme88k/dev/bussw.c')
-rw-r--r-- | sys/arch/mvme88k/dev/bussw.c | 105 |
1 files changed, 65 insertions, 40 deletions
diff --git a/sys/arch/mvme88k/dev/bussw.c b/sys/arch/mvme88k/dev/bussw.c index 5cb31f6f72a..1368cfd9a0d 100644 --- a/sys/arch/mvme88k/dev/bussw.c +++ b/sys/arch/mvme88k/dev/bussw.c @@ -1,5 +1,4 @@ -/* $OpenBSD: bussw.c,v 1.12 2004/04/14 13:43:13 miod Exp $ */ - +/* $OpenBSD: bussw.c,v 1.13 2004/04/24 19:51:47 miod Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. * @@ -39,14 +38,13 @@ #include <machine/vmparam.h> #include <mvme88k/dev/busswreg.h> -#include <mvme88k/dev/busswfunc.h> struct bussw_softc { struct device sc_dev; - void * sc_paddr; - void * sc_vaddr; + paddr_t sc_base; struct intrhand sc_abih; /* `abort' switch */ - struct bussw_reg *sc_bussw; + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; }; void bussw_attach(struct device *, struct device *, void *); @@ -60,9 +58,10 @@ struct cfdriver bussw_cd = { NULL, "bussw", DV_DULL }; -int bussw_print(void *args, const char *bus); -int bussw_scan(struct device *parent, void *child, void *args); -int busswabort(void *); +int bussw_print(void *, const char *); +int bussw_scan(struct device *, void *, void *); +int busswabort(void *); +int busswintr_establish(int, struct intrhand *); int bussw_match(parent, vcf, args) @@ -70,17 +69,29 @@ bussw_match(parent, vcf, args) void *vcf, *args; { struct confargs *ca = args; - struct bussw_reg *bussw; + bus_space_handle_t ioh; + int rc; + u_int8_t chipid; /* Don't match if wrong cpu */ if (brdtyp != BRD_197) - return (0); - - bussw = (struct bussw_reg *)(IIOV(ca->ca_paddr)); - if (badvaddr((vaddr_t)bussw, 4)) - return (0); + return 0; + + if (bus_space_map(ca->ca_iot, ca->ca_paddr, BS_SIZE, 0, &ioh) != 0) + return 0; + rc = badvaddr((vaddr_t)bus_space_vaddr(ca->ca_iot, ioh), 4); + if (rc == 0) { + chipid = bus_space_read_1(ca->ca_iot, ioh, BS_CHIPID); + if (chipid != BUSSWITCH_ID) { +#ifdef DEBUG + printf("==> busswitch: wrong chip id %x\n", chipid); +#endif + rc = -1; + } + } + bus_space_unmap(ca->ca_iot, ioh, BS_SIZE); - return (1); + return rc == 0; } void @@ -90,23 +101,37 @@ bussw_attach(parent, self, args) { struct confargs *ca = args; struct bussw_softc *sc = (struct bussw_softc *)self; - struct bussw_reg *bs; + bus_space_handle_t ioh; + + if (bus_space_map(ca->ca_iot, ca->ca_paddr, BS_SIZE, 0, &ioh) != 0) { + printf(": can't map registers!\n"); + return; + } + + sc->sc_iot = ca->ca_iot; + sc->sc_ioh = ioh; + sc->sc_base = ca->ca_paddr; + + bus_space_write_1(sc->sc_iot, ioh, BS_VBASE, + bus_space_read_1(sc->sc_iot, ioh, BS_VBASE) | BS_VECBASE); + bus_space_write_2(sc->sc_iot, ioh, BS_GCSR, + bus_space_read_2(sc->sc_iot, ioh, BS_GCSR) | BS_GCSR_XIPL); - sc->sc_vaddr = sc->sc_paddr = ca->ca_paddr; - bs = sc->sc_bussw = (struct bussw_reg *)sc->sc_vaddr; - bs->bs_intr2 |= BS_VECBASE; - bs->bs_gcsr |= BS_GCSR_XIPL; /* * pseudo driver, abort interrupt handler - */ + */ sc->sc_abih.ih_fn = busswabort; sc->sc_abih.ih_arg = 0; sc->sc_abih.ih_wantframe = 1; - sc->sc_abih.ih_ipl = IPL_NMI; /* level 8!! */ + sc->sc_abih.ih_ipl = IPL_NMI; + busswintr_establish(BS_ABORTIRQ, &sc->sc_abih); - bs->bs_intr1 |= BS_INTR1_ABORT_IEN; + bus_space_write_1(sc->sc_iot, ioh, BS_ABORT, + bus_space_read_4(sc->sc_iot, ioh, BS_ABORT) | BS_ABORT_IEN); + + printf(": rev %x\n", + bus_space_read_1(sc->sc_iot, ioh, BS_CHIPREV)); - printf(": rev %ld\n", BS_CHIPREV(bs)); config_search(bussw_scan, self, args); } @@ -134,17 +159,15 @@ bussw_scan(parent, child, args) struct confargs oca; bzero(&oca, sizeof oca); + oca.ca_iot = sc->sc_iot; oca.ca_offset = cf->cf_loc[0]; oca.ca_ipl = cf->cf_loc[1]; - if (((int)oca.ca_offset != -1) && ISIIOVA(sc->sc_vaddr + oca.ca_offset)) { - oca.ca_vaddr = sc->sc_vaddr + oca.ca_offset; - oca.ca_paddr = sc->sc_paddr + oca.ca_offset; + if (oca.ca_offset != -1) { + oca.ca_paddr = sc->sc_base + oca.ca_offset; } else { - oca.ca_vaddr = (void *)-1; - oca.ca_paddr = (void *)-1; + oca.ca_paddr = -1; } oca.ca_bustype = BUS_BUSSWITCH; - oca.ca_master = (void *)sc->sc_bussw; oca.ca_name = cf->cf_driver->cd_name; if ((*cf->cf_attach->ca_match)(parent, cf, &oca) == 0) return (0); @@ -157,11 +180,12 @@ busswintr_establish(vec, ih) int vec; struct intrhand *ih; { - if (vec >= BS_NVEC) { - printf("bussw: illegal vector: 0x%x\n", vec); - panic("busswintr_establish"); - } - return (intr_establish(BS_VECBASE+vec, ih)); +#ifdef DIAGNOSTIC + if (vec < 0 || vec >= BS_NVEC) + panic("busswintr_establish: illegal vector 0x%x\n", vec); +#endif + + return (intr_establish(BS_VECBASE + vec, ih)); } int @@ -171,13 +195,14 @@ busswabort(eframe) struct frame *frame = eframe; struct bussw_softc *sc = (struct bussw_softc *)bussw_cd.cd_devs[0]; - struct bussw_reg *bs = sc->sc_bussw; + u_int8_t abort; - if (bs->bs_intr1 & BS_INTR1_ABORT_INT) { - bs->bs_intr1 |= BS_INTR1_ABORT_ICLR; + abort = bus_space_read_1(sc->sc_iot, sc->sc_ioh, BS_ABORT); + if (abort & BS_ABORT_INT) { + bus_space_write_1(sc->sc_iot, sc->sc_ioh, BS_ABORT, + abort | BS_ABORT_ICLR); nmihand(frame); return 1; } return 0; } - |