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