Annotation of sys/arch/mvme88k/dev/bussw.c, Revision 1.1.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