1*78d5ff0eSmpi /* $OpenBSD: mongoose.c,v 1.23 2022/03/13 08:04:38 mpi Exp $ */
279c49b90Smickey
379c49b90Smickey /*
4fef2e65fSmickey * Copyright (c) 1998-2003 Michael Shalayeff
579c49b90Smickey * All rights reserved.
679c49b90Smickey *
779c49b90Smickey * Redistribution and use in source and binary forms, with or without
879c49b90Smickey * modification, are permitted provided that the following conditions
979c49b90Smickey * are met:
1079c49b90Smickey * 1. Redistributions of source code must retain the above copyright
1179c49b90Smickey * notice, this list of conditions and the following disclaimer.
1279c49b90Smickey * 2. Redistributions in binary form must reproduce the above copyright
1379c49b90Smickey * notice, this list of conditions and the following disclaimer in the
1479c49b90Smickey * documentation and/or other materials provided with the distribution.
1579c49b90Smickey *
1679c49b90Smickey * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1779c49b90Smickey * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1879c49b90Smickey * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1917293d32Smickey * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
2017293d32Smickey * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2117293d32Smickey * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2217293d32Smickey * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2317293d32Smickey * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2417293d32Smickey * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2517293d32Smickey * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2617293d32Smickey * THE POSSIBILITY OF SUCH DAMAGE.
2779c49b90Smickey */
2879c49b90Smickey
2979c49b90Smickey #include <sys/param.h>
3079c49b90Smickey #include <sys/systm.h>
3179c49b90Smickey #include <sys/device.h>
3279c49b90Smickey #include <sys/reboot.h>
3379c49b90Smickey
3479c49b90Smickey #include <machine/bus.h>
3579c49b90Smickey #include <machine/iomod.h>
3679c49b90Smickey #include <machine/autoconf.h>
3779c49b90Smickey
3879c49b90Smickey #include <hppa/dev/cpudevs.h>
399c43451cSmickey #include <hppa/dev/viper.h>
4079c49b90Smickey
4179c49b90Smickey #include <dev/eisa/eisareg.h>
4279c49b90Smickey #include <dev/eisa/eisavar.h>
4379c49b90Smickey
4479c49b90Smickey #include <dev/isa/isareg.h>
4579c49b90Smickey #include <dev/isa/isavar.h>
4679c49b90Smickey
47a8c1b917Smiod #include <hppa/dev/mongoosereg.h>
48a8c1b917Smiod #include <hppa/dev/mongoosevar.h>
49c5618357Smickey
50a8c1b917Smiod void mgattach_gedoens(struct device *, struct device *, void *);
51a8c1b917Smiod int mgmatch_gedoens(struct device *, void *, void *);
529c43451cSmickey
53*78d5ff0eSmpi const struct cfattach mg_gedoens_ca = {
54a8c1b917Smiod sizeof(struct mongoose_softc), mgmatch_gedoens, mgattach_gedoens
5579c49b90Smickey };
5679c49b90Smickey
5779c49b90Smickey struct cfdriver mongoose_cd = {
58005605d6Smiod NULL, "mongoose", DV_DULL
5979c49b90Smickey };
6079c49b90Smickey
61dd6e4488Sderaadt void mg_eisa_attach_hook(struct device *parent,
62dd6e4488Sderaadt struct device *self,
63dd6e4488Sderaadt struct eisabus_attach_args *mg);
64dd6e4488Sderaadt int mg_intr_map(void *v, u_int irq, eisa_intr_handle_t *ehp);
65dd6e4488Sderaadt const char *mg_intr_string(void *v, int irq);
66dd6e4488Sderaadt void mg_isa_attach_hook(struct device *parent,
67dd6e4488Sderaadt struct device *self,
68dd6e4488Sderaadt struct isabus_attach_args *iba);
69dd6e4488Sderaadt void *mg_intr_establish(void *v, int irq, int type, int pri,
70dd6e4488Sderaadt int (*handler)(void *), void *arg, const char *name);
71dd6e4488Sderaadt void mg_intr_disestablish(void *v, void *cookie);
72dd6e4488Sderaadt int mg_intr_check(void *v, int irq, int type);
73dd6e4488Sderaadt int mg_eisa_iomap(void *v, bus_addr_t addr, bus_size_t size,
74dd6e4488Sderaadt int flags, bus_space_handle_t *bshp);
75dd6e4488Sderaadt int mg_eisa_memmap(void *v, bus_addr_t addr, bus_size_t size,
76dd6e4488Sderaadt int flags, bus_space_handle_t *bshp);
77dd6e4488Sderaadt void mg_eisa_memunmap(void *v, bus_space_handle_t bsh,
78dd6e4488Sderaadt bus_size_t size);
79dd6e4488Sderaadt void mg_isa_barrier(void *v, bus_space_handle_t h, bus_size_t o,
80dd6e4488Sderaadt bus_size_t l, int op);
81dd6e4488Sderaadt u_int16_t mg_isa_r2(void *v, bus_space_handle_t h, bus_size_t o);
82dd6e4488Sderaadt u_int32_t mg_isa_r4(void *v, bus_space_handle_t h, bus_size_t o);
83dd6e4488Sderaadt void mg_isa_w2(void *v, bus_space_handle_t h, bus_size_t o,
84dd6e4488Sderaadt u_int16_t vv);
85dd6e4488Sderaadt void mg_isa_w4(void *v, bus_space_handle_t h, bus_size_t o,
86dd6e4488Sderaadt u_int32_t vv);
87dd6e4488Sderaadt void mg_isa_rm_2(void *v, bus_space_handle_t h, bus_size_t o,
88dd6e4488Sderaadt u_int16_t *a, bus_size_t c);
89dd6e4488Sderaadt void mg_isa_rm_4(void *v, bus_space_handle_t h, bus_size_t o,
90dd6e4488Sderaadt u_int32_t *a, bus_size_t c);
91dd6e4488Sderaadt void mg_isa_wm_2(void *v, bus_space_handle_t h, bus_size_t o,
92dd6e4488Sderaadt const u_int16_t *a, bus_size_t c);
93dd6e4488Sderaadt void mg_isa_wm_4(void *v, bus_space_handle_t h, bus_size_t o,
94dd6e4488Sderaadt const u_int32_t *a, bus_size_t c);
95dd6e4488Sderaadt void mg_isa_sm_2(void *v, bus_space_handle_t h, bus_size_t o,
96dd6e4488Sderaadt u_int16_t vv, bus_size_t c);
97dd6e4488Sderaadt void mg_isa_sm_4(void *v, bus_space_handle_t h, bus_size_t o,
98dd6e4488Sderaadt u_int32_t vv, bus_size_t c);
99dd6e4488Sderaadt void mg_isa_rr_2(void *v, bus_space_handle_t h, bus_size_t o,
100dd6e4488Sderaadt u_int16_t *a, bus_size_t c);
101dd6e4488Sderaadt void mg_isa_rr_4(void *v, bus_space_handle_t h, bus_size_t o,
102dd6e4488Sderaadt u_int32_t *a, bus_size_t c);
103dd6e4488Sderaadt void mg_isa_wr_2(void *v, bus_space_handle_t h, bus_size_t o,
104dd6e4488Sderaadt const u_int16_t *a, bus_size_t c);
105dd6e4488Sderaadt void mg_isa_wr_4(void *v, bus_space_handle_t h, bus_size_t o,
106dd6e4488Sderaadt const u_int32_t *a, bus_size_t c);
107dd6e4488Sderaadt void mg_isa_sr_2(void *v, bus_space_handle_t h, bus_size_t o,
108dd6e4488Sderaadt u_int16_t vv, bus_size_t c);
109dd6e4488Sderaadt void mg_isa_sr_4(void *v, bus_space_handle_t h, bus_size_t o,
110dd6e4488Sderaadt u_int32_t vv, bus_size_t c);
111dd6e4488Sderaadt
11217293d32Smickey /* TODO: DMA guts */
11379c49b90Smickey
1144d51ed4eSmickey void
mg_eisa_attach_hook(struct device * parent,struct device * self,struct eisabus_attach_args * mg)1154d51ed4eSmickey mg_eisa_attach_hook(struct device *parent, struct device *self,
1164d51ed4eSmickey struct eisabus_attach_args *mg)
1174d51ed4eSmickey {
1184d51ed4eSmickey }
1194d51ed4eSmickey
1204d51ed4eSmickey int
mg_intr_map(void * v,u_int irq,eisa_intr_handle_t * ehp)1214d51ed4eSmickey mg_intr_map(void *v, u_int irq, eisa_intr_handle_t *ehp)
1224d51ed4eSmickey {
1234d51ed4eSmickey *ehp = irq;
1244d51ed4eSmickey return 0;
1254d51ed4eSmickey }
1264d51ed4eSmickey
1274d51ed4eSmickey const char *
mg_intr_string(void * v,int irq)1284d51ed4eSmickey mg_intr_string(void *v, int irq)
1294d51ed4eSmickey {
1304d51ed4eSmickey static char buf[16];
1314d51ed4eSmickey
132094fa01fSderaadt snprintf(buf, sizeof buf, "isa irq %d", irq);
1334d51ed4eSmickey return buf;
1344d51ed4eSmickey }
1354d51ed4eSmickey
1364d51ed4eSmickey void
mg_isa_attach_hook(struct device * parent,struct device * self,struct isabus_attach_args * iba)1374d51ed4eSmickey mg_isa_attach_hook(struct device *parent, struct device *self,
1384d51ed4eSmickey struct isabus_attach_args *iba)
1394d51ed4eSmickey {
1404d51ed4eSmickey
1414d51ed4eSmickey }
1424d51ed4eSmickey
143aa2f1e1bSmickey void *
mg_intr_establish(void * v,int irq,int type,int pri,int (* handler)(void *),void * arg,const char * name)144aa2f1e1bSmickey mg_intr_establish(void *v, int irq, int type, int pri,
14540f562c2Smickey int (*handler)(void *), void *arg, const char *name)
146aa2f1e1bSmickey {
147aa2f1e1bSmickey struct hppa_isa_iv *iv;
148aa2f1e1bSmickey struct mongoose_softc *sc = v;
149aa2f1e1bSmickey volatile u_int8_t *imr, *pic;
150aa2f1e1bSmickey
151aa2f1e1bSmickey if (!sc || irq < 0 || irq >= MONGOOSE_NINTS ||
152aa2f1e1bSmickey (0 <= irq && irq < MONGOOSE_NINTS && sc->sc_iv[irq].iv_handler))
153aa2f1e1bSmickey return NULL;
154aa2f1e1bSmickey
155aa2f1e1bSmickey if (type != IST_LEVEL && type != IST_EDGE) {
156aa2f1e1bSmickey #ifdef DEBUG
157aa2f1e1bSmickey printf("%s: bad interrupt level (%d)\n", sc->sc_dev.dv_xname,
158aa2f1e1bSmickey type);
159aa2f1e1bSmickey #endif
160aa2f1e1bSmickey return NULL;
161aa2f1e1bSmickey }
162aa2f1e1bSmickey
163aa2f1e1bSmickey iv = &sc->sc_iv[irq];
164aa2f1e1bSmickey if (iv->iv_handler) {
165aa2f1e1bSmickey #ifdef DEBUG
166aa2f1e1bSmickey printf("%s: irq %d already established\n", sc->sc_dev.dv_xname,
167aa2f1e1bSmickey irq);
168aa2f1e1bSmickey #endif
169aa2f1e1bSmickey return NULL;
170aa2f1e1bSmickey }
171aa2f1e1bSmickey
172aa2f1e1bSmickey iv->iv_name = name;
173aa2f1e1bSmickey iv->iv_pri = pri;
174aa2f1e1bSmickey iv->iv_handler = handler;
175aa2f1e1bSmickey iv->iv_arg = arg;
176aa2f1e1bSmickey
177aa2f1e1bSmickey if (irq < 8) {
178aa2f1e1bSmickey imr = &sc->sc_ctrl->imr0;
179aa2f1e1bSmickey pic = &sc->sc_ctrl->pic0;
180aa2f1e1bSmickey } else {
181aa2f1e1bSmickey imr = &sc->sc_ctrl->imr1;
182aa2f1e1bSmickey pic = &sc->sc_ctrl->pic1;
183aa2f1e1bSmickey irq -= 8;
184aa2f1e1bSmickey }
185aa2f1e1bSmickey
186aa2f1e1bSmickey *imr |= 1 << irq;
187aa2f1e1bSmickey *pic |= (type == IST_LEVEL) << irq;
188aa2f1e1bSmickey
189aa2f1e1bSmickey /* TODO: ack it? */
190aa2f1e1bSmickey
191aa2f1e1bSmickey return iv;
192aa2f1e1bSmickey }
193aa2f1e1bSmickey
194aa2f1e1bSmickey void
mg_intr_disestablish(void * v,void * cookie)195aa2f1e1bSmickey mg_intr_disestablish(void *v, void *cookie)
196aa2f1e1bSmickey {
197aa2f1e1bSmickey struct hppa_isa_iv *iv = cookie;
198aa2f1e1bSmickey struct mongoose_softc *sc = v;
199fc5790baSjsg int irq;
200aa2f1e1bSmickey volatile u_int8_t *imr;
201aa2f1e1bSmickey
202aa2f1e1bSmickey if (!sc || !cookie)
203aa2f1e1bSmickey return;
204aa2f1e1bSmickey
205fc5790baSjsg irq = iv - sc->sc_iv;
206aa2f1e1bSmickey if (irq < 8)
207aa2f1e1bSmickey imr = &sc->sc_ctrl->imr0;
208aa2f1e1bSmickey else
209aa2f1e1bSmickey imr = &sc->sc_ctrl->imr1;
210aa2f1e1bSmickey *imr &= ~(1 << irq);
211aa2f1e1bSmickey /* TODO: ack it? */
212aa2f1e1bSmickey
213aa2f1e1bSmickey iv->iv_handler = NULL;
214aa2f1e1bSmickey }
215aa2f1e1bSmickey
2164d51ed4eSmickey int
mg_intr_check(void * v,int irq,int type)2174d51ed4eSmickey mg_intr_check(void *v, int irq, int type)
2184d51ed4eSmickey {
2194d51ed4eSmickey return 0;
2204d51ed4eSmickey }
2214d51ed4eSmickey
2224d51ed4eSmickey int
mg_intr(void * v)2234d51ed4eSmickey mg_intr(void *v)
2244d51ed4eSmickey {
225aa2f1e1bSmickey struct mongoose_softc *sc = v;
226aa2f1e1bSmickey struct hppa_isa_iv *iv;
227aa2f1e1bSmickey int s, irq = 0;
228aa2f1e1bSmickey
229aa2f1e1bSmickey iv = &sc->sc_iv[irq];
230969c5366Smickey s = splraise(iv->iv_pri);
231aa2f1e1bSmickey (iv->iv_handler)(iv->iv_arg);
232aa2f1e1bSmickey splx(s);
233aa2f1e1bSmickey
2344d51ed4eSmickey return 0;
2354d51ed4eSmickey }
2364d51ed4eSmickey
2374d51ed4eSmickey int
mg_eisa_iomap(void * v,bus_addr_t addr,bus_size_t size,int flags,bus_space_handle_t * bshp)2382ab138fdSmiod mg_eisa_iomap(void *v, bus_addr_t addr, bus_size_t size, int flags,
2394d51ed4eSmickey bus_space_handle_t *bshp)
2404d51ed4eSmickey {
2414d51ed4eSmickey struct mongoose_softc *sc = v;
2424d51ed4eSmickey
2434d51ed4eSmickey /* see if it's ISA space we are mapping */
2444d51ed4eSmickey if (0x100 <= addr && addr < 0x400) {
2454d51ed4eSmickey #define TOISA(a) ((((a) & 0x3f8) << 9) + ((a) & 7))
2464d51ed4eSmickey size = TOISA(addr + size) - TOISA(addr);
2474d51ed4eSmickey addr = TOISA(addr);
2484d51ed4eSmickey }
2494d51ed4eSmickey
2504d51ed4eSmickey return (sc->sc_bt->hbt_map)(NULL, sc->sc_iomap + addr, size,
2512ab138fdSmiod flags, bshp);
2524d51ed4eSmickey }
2534d51ed4eSmickey
2544d51ed4eSmickey int
mg_eisa_memmap(void * v,bus_addr_t addr,bus_size_t size,int flags,bus_space_handle_t * bshp)2552ab138fdSmiod mg_eisa_memmap(void *v, bus_addr_t addr, bus_size_t size, int flags,
2564d51ed4eSmickey bus_space_handle_t *bshp)
2574d51ed4eSmickey {
2584d51ed4eSmickey /* TODO: eisa memory map */
2594d51ed4eSmickey return -1;
2604d51ed4eSmickey }
2614d51ed4eSmickey
2624d51ed4eSmickey void
mg_eisa_memunmap(void * v,bus_space_handle_t bsh,bus_size_t size)2634d51ed4eSmickey mg_eisa_memunmap(void *v, bus_space_handle_t bsh, bus_size_t size)
2644d51ed4eSmickey {
2654d51ed4eSmickey /* TODO: eisa memory unmap */
2664d51ed4eSmickey }
2674d51ed4eSmickey
2684d51ed4eSmickey void
mg_isa_barrier(void * v,bus_space_handle_t h,bus_size_t o,bus_size_t l,int op)2694d51ed4eSmickey mg_isa_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op)
2704d51ed4eSmickey {
2714d51ed4eSmickey sync_caches();
2724d51ed4eSmickey }
2734d51ed4eSmickey
2744d51ed4eSmickey u_int16_t
mg_isa_r2(void * v,bus_space_handle_t h,bus_size_t o)2754d51ed4eSmickey mg_isa_r2(void *v, bus_space_handle_t h, bus_size_t o)
2764d51ed4eSmickey {
2774d51ed4eSmickey register u_int16_t r = *((volatile u_int16_t *)(h + o));
2784d51ed4eSmickey return letoh16(r);
2794d51ed4eSmickey }
2804d51ed4eSmickey
2814d51ed4eSmickey u_int32_t
mg_isa_r4(void * v,bus_space_handle_t h,bus_size_t o)2824d51ed4eSmickey mg_isa_r4(void *v, bus_space_handle_t h, bus_size_t o)
2834d51ed4eSmickey {
2844d51ed4eSmickey register u_int32_t r = *((volatile u_int32_t *)(h + o));
2854d51ed4eSmickey return letoh32(r);
2864d51ed4eSmickey }
2874d51ed4eSmickey
2884d51ed4eSmickey void
mg_isa_w2(void * v,bus_space_handle_t h,bus_size_t o,u_int16_t vv)2894d51ed4eSmickey mg_isa_w2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv)
2904d51ed4eSmickey {
2914d51ed4eSmickey *((volatile u_int16_t *)(h + o)) = htole16(vv);
2924d51ed4eSmickey }
2934d51ed4eSmickey
2944d51ed4eSmickey void
mg_isa_w4(void * v,bus_space_handle_t h,bus_size_t o,u_int32_t vv)2954d51ed4eSmickey mg_isa_w4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv)
2964d51ed4eSmickey {
2974d51ed4eSmickey *((volatile u_int32_t *)(h + o)) = htole32(vv);
2984d51ed4eSmickey }
2994d51ed4eSmickey
3004d51ed4eSmickey void
mg_isa_rm_2(void * v,bus_space_handle_t h,bus_size_t o,u_int16_t * a,bus_size_t c)3014d51ed4eSmickey mg_isa_rm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
3024d51ed4eSmickey {
3034d51ed4eSmickey h += o;
3044d51ed4eSmickey while (c--)
3054d51ed4eSmickey *(a++) = letoh16(*(volatile u_int16_t *)h);
3064d51ed4eSmickey }
3074d51ed4eSmickey
3084d51ed4eSmickey void
mg_isa_rm_4(void * v,bus_space_handle_t h,bus_size_t o,u_int32_t * a,bus_size_t c)3094d51ed4eSmickey mg_isa_rm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
3104d51ed4eSmickey {
3114d51ed4eSmickey h += o;
3124d51ed4eSmickey while (c--)
3134d51ed4eSmickey *(a++) = letoh32(*(volatile u_int32_t *)h);
3144d51ed4eSmickey }
3154d51ed4eSmickey
3164d51ed4eSmickey void
mg_isa_wm_2(void * v,bus_space_handle_t h,bus_size_t o,const u_int16_t * a,bus_size_t c)3174d51ed4eSmickey mg_isa_wm_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
3184d51ed4eSmickey {
3194d51ed4eSmickey register u_int16_t r;
3204d51ed4eSmickey h += o;
3214d51ed4eSmickey while (c--) {
3224d51ed4eSmickey r = *(a++);
3234d51ed4eSmickey *(volatile u_int16_t *)h = htole16(r);
3244d51ed4eSmickey }
3254d51ed4eSmickey }
3264d51ed4eSmickey
3274d51ed4eSmickey void
mg_isa_wm_4(void * v,bus_space_handle_t h,bus_size_t o,const u_int32_t * a,bus_size_t c)3284d51ed4eSmickey mg_isa_wm_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
3294d51ed4eSmickey {
3304d51ed4eSmickey register u_int32_t r;
3314d51ed4eSmickey h += o;
3324d51ed4eSmickey while (c--) {
3334d51ed4eSmickey r = *(a++);
3344d51ed4eSmickey *(volatile u_int32_t *)h = htole32(r);
3354d51ed4eSmickey }
3364d51ed4eSmickey }
3374d51ed4eSmickey
3384d51ed4eSmickey void
mg_isa_sm_2(void * v,bus_space_handle_t h,bus_size_t o,u_int16_t vv,bus_size_t c)3394d51ed4eSmickey mg_isa_sm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
3404d51ed4eSmickey {
3414d51ed4eSmickey vv = htole16(vv);
3424d51ed4eSmickey h += o;
3434d51ed4eSmickey while (c--)
3444d51ed4eSmickey *(volatile u_int16_t *)h = vv;
3454d51ed4eSmickey }
3464d51ed4eSmickey
3474d51ed4eSmickey void
mg_isa_sm_4(void * v,bus_space_handle_t h,bus_size_t o,u_int32_t vv,bus_size_t c)3484d51ed4eSmickey mg_isa_sm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
3494d51ed4eSmickey {
3504d51ed4eSmickey vv = htole32(vv);
3514d51ed4eSmickey h += o;
3524d51ed4eSmickey while (c--)
3534d51ed4eSmickey *(volatile u_int32_t *)h = vv;
3544d51ed4eSmickey }
3554d51ed4eSmickey
3564d51ed4eSmickey void
mg_isa_rr_2(void * v,bus_space_handle_t h,bus_size_t o,u_int16_t * a,bus_size_t c)3574d51ed4eSmickey mg_isa_rr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
3584d51ed4eSmickey {
3591cec59e7Skettenis volatile u_int16_t *p = (u_int16_t *)(h + o);
3601cec59e7Skettenis u_int32_t r;
3611cec59e7Skettenis
3624d51ed4eSmickey while (c--) {
3631cec59e7Skettenis r = *p++;
3641cec59e7Skettenis *a++ = letoh16(r);
3654d51ed4eSmickey }
3664d51ed4eSmickey }
3674d51ed4eSmickey
3684d51ed4eSmickey void
mg_isa_rr_4(void * v,bus_space_handle_t h,bus_size_t o,u_int32_t * a,bus_size_t c)3694d51ed4eSmickey mg_isa_rr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
3704d51ed4eSmickey {
3711cec59e7Skettenis volatile u_int32_t *p = (u_int32_t *)(h + o);
3721cec59e7Skettenis u_int32_t r;
3731cec59e7Skettenis
3744d51ed4eSmickey while (c--) {
3751cec59e7Skettenis r = *p++;
3761cec59e7Skettenis *a++ = letoh32(r);
3774d51ed4eSmickey }
3784d51ed4eSmickey }
3794d51ed4eSmickey
3804d51ed4eSmickey void
mg_isa_wr_2(void * v,bus_space_handle_t h,bus_size_t o,const u_int16_t * a,bus_size_t c)3814d51ed4eSmickey mg_isa_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
3824d51ed4eSmickey {
3831cec59e7Skettenis volatile u_int16_t *p = (u_int16_t *)(h + o);
3841cec59e7Skettenis u_int32_t r;
3851cec59e7Skettenis
3864d51ed4eSmickey while (c--) {
3871cec59e7Skettenis r = *a++;
3881cec59e7Skettenis *p++ = htole16(r);
3894d51ed4eSmickey }
3904d51ed4eSmickey }
3914d51ed4eSmickey
3924d51ed4eSmickey void
mg_isa_wr_4(void * v,bus_space_handle_t h,bus_size_t o,const u_int32_t * a,bus_size_t c)3934d51ed4eSmickey mg_isa_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
3944d51ed4eSmickey {
3951cec59e7Skettenis volatile u_int32_t *p = (u_int32_t *)(h + o);
3961cec59e7Skettenis u_int32_t r;
3971cec59e7Skettenis
3984d51ed4eSmickey while (c--) {
3991cec59e7Skettenis r = *a++;
4001cec59e7Skettenis *p++ = htole32(r);
4014d51ed4eSmickey }
4024d51ed4eSmickey }
4034d51ed4eSmickey
4044d51ed4eSmickey void
mg_isa_sr_2(void * v,bus_space_handle_t h,bus_size_t o,u_int16_t vv,bus_size_t c)4054d51ed4eSmickey mg_isa_sr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
4064d51ed4eSmickey {
4071cec59e7Skettenis volatile u_int16_t *p = (u_int16_t *)(h + o);
4081cec59e7Skettenis
4094d51ed4eSmickey vv = htole16(vv);
4104d51ed4eSmickey while (c--)
4111cec59e7Skettenis *p++ = vv;
4124d51ed4eSmickey }
4134d51ed4eSmickey
4144d51ed4eSmickey void
mg_isa_sr_4(void * v,bus_space_handle_t h,bus_size_t o,u_int32_t vv,bus_size_t c)4154d51ed4eSmickey mg_isa_sr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
4164d51ed4eSmickey {
4171cec59e7Skettenis volatile u_int32_t *p = (u_int32_t *)(h + o);
4181cec59e7Skettenis
4194d51ed4eSmickey vv = htole32(vv);
4204d51ed4eSmickey while (c--)
4211cec59e7Skettenis *p++ = vv;
4224d51ed4eSmickey }
4234d51ed4eSmickey
42479c49b90Smickey int
mgattach_common(sc)425a8c1b917Smiod mgattach_common(sc)
426a8c1b917Smiod struct mongoose_softc *sc;
42779c49b90Smickey {
4284d51ed4eSmickey struct hppa_bus_space_tag *bt;
42979c49b90Smickey union mongoose_attach_args ea;
4309c43451cSmickey char brid[EISA_IDSTRINGLEN];
43179c49b90Smickey
4329c43451cSmickey viper_eisa_en();
43379c49b90Smickey
4349c43451cSmickey /* BUS RESET */
4359c43451cSmickey sc->sc_ctrl->nmi_ext = MONGOOSE_NMI_BUSRESET;
4369c43451cSmickey DELAY(1);
4379c43451cSmickey sc->sc_ctrl->nmi_ext = 0;
4389c43451cSmickey DELAY(100);
43979c49b90Smickey
4409c43451cSmickey /* determine eisa board id */
4419c43451cSmickey {
4429c43451cSmickey u_int8_t id[4], *p;
443a8c1b917Smiod p = (u_int8_t *)(sc->sc_iomap + EISA_SLOTOFF_VID);
4449c43451cSmickey id[0] = *p++;
4459c43451cSmickey id[1] = *p++;
4469c43451cSmickey id[2] = *p++;
4479c43451cSmickey id[3] = *p++;
4489c43451cSmickey
4499c43451cSmickey brid[0] = EISA_VENDID_0(id);
4509c43451cSmickey brid[1] = EISA_VENDID_1(id);
4519c43451cSmickey brid[2] = EISA_VENDID_2(id);
4529c43451cSmickey brid[3] = EISA_PRODID_0(id + 2);
4539c43451cSmickey brid[4] = EISA_PRODID_1(id + 2);
4549c43451cSmickey brid[5] = EISA_PRODID_2(id + 2);
4559c43451cSmickey brid[6] = EISA_PRODID_3(id + 2);
4569c43451cSmickey brid[7] = '\0';
4579c43451cSmickey }
4589c43451cSmickey
4599c43451cSmickey printf (": %s rev %d, %d MHz\n", brid, sc->sc_regs->version,
460c5618357Smickey (sc->sc_regs->clock? 33 : 25));
461c5618357Smickey sc->sc_regs->liowait = 1; /* disable isa wait states */
462c5618357Smickey sc->sc_regs->lock = 1; /* bus unlock */
46379c49b90Smickey
46479c49b90Smickey /* attach EISA */
46579c49b90Smickey sc->sc_ec.ec_v = sc;
46617293d32Smickey sc->sc_ec.ec_attach_hook = mg_eisa_attach_hook;
46717293d32Smickey sc->sc_ec.ec_intr_establish = mg_intr_establish;
46817293d32Smickey sc->sc_ec.ec_intr_disestablish = mg_intr_disestablish;
46917293d32Smickey sc->sc_ec.ec_intr_string = mg_intr_string;
47017293d32Smickey sc->sc_ec.ec_intr_map = mg_intr_map;
47117293d32Smickey /* inherit the bus tags for eisa from the mainbus */
4724d51ed4eSmickey bt = &sc->sc_eiot;
473a8c1b917Smiod bcopy(sc->sc_bt, bt, sizeof(*bt));
4744d51ed4eSmickey bt->hbt_cookie = sc;
4754d51ed4eSmickey bt->hbt_map = mg_eisa_iomap;
4764d51ed4eSmickey #define R(n) bt->__CONCAT(hbt_,n) = &__CONCAT(mg_isa_,n)
4774d51ed4eSmickey /* R(barrier); */
4784d51ed4eSmickey R(r2); R(r4); R(w2); R(w4);
4794d51ed4eSmickey R(rm_2);R(rm_4);R(wm_2);R(wm_4);R(sm_2);R(sm_4);
4804d51ed4eSmickey R(rr_2);R(rr_4);R(wr_2);R(wr_4);R(sr_2);R(sr_4);
4814d51ed4eSmickey
4824d51ed4eSmickey bt = &sc->sc_ememt;
483a8c1b917Smiod bcopy(sc->sc_bt, bt, sizeof(*bt));
4844d51ed4eSmickey bt->hbt_cookie = sc;
4854d51ed4eSmickey bt->hbt_map = mg_eisa_memmap;
4864d51ed4eSmickey bt->hbt_unmap = mg_eisa_memunmap;
48717293d32Smickey /* attachment guts */
48879c49b90Smickey ea.mongoose_eisa.eba_busname = "eisa";
48917293d32Smickey ea.mongoose_eisa.eba_iot = &sc->sc_eiot;
49017293d32Smickey ea.mongoose_eisa.eba_memt = &sc->sc_ememt;
4919c43451cSmickey ea.mongoose_eisa.eba_dmat = NULL /* &sc->sc_edmat */;
49279c49b90Smickey ea.mongoose_eisa.eba_ec = &sc->sc_ec;
493a8c1b917Smiod config_found((struct device *)sc, &ea.mongoose_eisa, mgprint);
49479c49b90Smickey
49579c49b90Smickey sc->sc_ic.ic_v = sc;
49617293d32Smickey sc->sc_ic.ic_attach_hook = mg_isa_attach_hook;
49717293d32Smickey sc->sc_ic.ic_intr_establish = mg_intr_establish;
49817293d32Smickey sc->sc_ic.ic_intr_disestablish = mg_intr_disestablish;
49917293d32Smickey sc->sc_ic.ic_intr_check = mg_intr_check;
500aa2f1e1bSmickey /* inherit the bus tags for isa from the eisa */
501aa2f1e1bSmickey bt = &sc->sc_imemt;
502aa2f1e1bSmickey bcopy(&sc->sc_ememt, bt, sizeof(*bt));
503aa2f1e1bSmickey bt = &sc->sc_iiot;
504aa2f1e1bSmickey bcopy(&sc->sc_eiot, bt, sizeof(*bt));
50517293d32Smickey /* TODO: DMA tags */
50617293d32Smickey /* attachment guts */
50779c49b90Smickey ea.mongoose_isa.iba_busname = "isa";
50817293d32Smickey ea.mongoose_isa.iba_iot = &sc->sc_iiot;
50917293d32Smickey ea.mongoose_isa.iba_memt = &sc->sc_imemt;
510c5618357Smickey #if NISADMA > 0
5119c43451cSmickey ea.mongoose_isa.iba_dmat = &sc->sc_idmat;
512c5618357Smickey #endif
51379c49b90Smickey ea.mongoose_isa.iba_ic = &sc->sc_ic;
514a8c1b917Smiod config_found((struct device *)sc, &ea.mongoose_isa, mgprint);
5154d51ed4eSmickey #undef R
5169c43451cSmickey
517a8c1b917Smiod return (0);
51879c49b90Smickey }
51979c49b90Smickey
52079c49b90Smickey int
mgprint(aux,pnp)52179c49b90Smickey mgprint(aux, pnp)
52279c49b90Smickey void *aux;
52379c49b90Smickey const char *pnp;
52479c49b90Smickey {
52579c49b90Smickey union mongoose_attach_args *ea = aux;
52679c49b90Smickey
52779c49b90Smickey if (pnp)
52879c49b90Smickey printf ("%s at %s", ea->mongoose_name, pnp);
52979c49b90Smickey
53079c49b90Smickey return (UNCONF);
53179c49b90Smickey }
53279c49b90Smickey
533a8c1b917Smiod int
mgmatch_gedoens(parent,cfdata,aux)534a8c1b917Smiod mgmatch_gedoens(parent, cfdata, aux)
535a8c1b917Smiod struct device *parent;
536a8c1b917Smiod void *cfdata;
537a8c1b917Smiod void *aux;
538a8c1b917Smiod {
539a8c1b917Smiod register struct confargs *ca = aux;
540a8c1b917Smiod /* struct cfdata *cf = cfdata; */
541a8c1b917Smiod bus_space_handle_t ioh;
542a8c1b917Smiod
543a8c1b917Smiod if (ca->ca_type.iodc_type != HPPA_TYPE_BHA ||
544a8c1b917Smiod (ca->ca_type.iodc_sv_model != HPPA_BHA_EISA &&
545a8c1b917Smiod ca->ca_type.iodc_sv_model != HPPA_BHA_WEISA))
546a8c1b917Smiod return 0;
547a8c1b917Smiod
548a8c1b917Smiod if (bus_space_map(ca->ca_iot, ca->ca_hpa + MONGOOSE_MONGOOSE,
549a8c1b917Smiod IOMOD_HPASIZE, 0, &ioh))
550a8c1b917Smiod return 0;
551a8c1b917Smiod
552a8c1b917Smiod /* XXX check EISA signature */
553a8c1b917Smiod
554a8c1b917Smiod bus_space_unmap(ca->ca_iot, ioh, IOMOD_HPASIZE);
555a8c1b917Smiod
556a8c1b917Smiod return 1;
557a8c1b917Smiod }
558a8c1b917Smiod
559a8c1b917Smiod void
mgattach_gedoens(parent,self,aux)560a8c1b917Smiod mgattach_gedoens(parent, self, aux)
561a8c1b917Smiod struct device *parent;
562a8c1b917Smiod struct device *self;
563a8c1b917Smiod void *aux;
564a8c1b917Smiod {
565a8c1b917Smiod register struct confargs *ca = aux;
566a8c1b917Smiod register struct mongoose_softc *sc = (struct mongoose_softc *)self;
56795b1714cSkettenis bus_space_handle_t ioh;
568a8c1b917Smiod
569a8c1b917Smiod sc->sc_bt = ca->ca_iot;
570a8c1b917Smiod sc->sc_iomap = ca->ca_hpa;
57195b1714cSkettenis
57295b1714cSkettenis if (bus_space_map(ca->ca_iot, ca->ca_hpa + MONGOOSE_MONGOOSE,
57395b1714cSkettenis sizeof(struct mongoose_regs), 0, &ioh) != 0) {
57495b1714cSkettenis printf(": can't map IO space\n");
57595b1714cSkettenis return;
57695b1714cSkettenis }
57795b1714cSkettenis sc->sc_regs = (struct mongoose_regs *)ioh;
57895b1714cSkettenis
57995b1714cSkettenis if (bus_space_map(ca->ca_iot, ca->ca_hpa + MONGOOSE_CTRL,
58095b1714cSkettenis sizeof(struct mongoose_ctrl), 0, &ioh) != 0) {
58195b1714cSkettenis printf(": can't map control registers\n");
58295b1714cSkettenis bus_space_unmap(ca->ca_iot, (bus_space_handle_t)sc->sc_regs,
58395b1714cSkettenis sizeof(struct mongoose_regs));
58495b1714cSkettenis return;
58595b1714cSkettenis }
58695b1714cSkettenis sc->sc_ctrl = (struct mongoose_ctrl *)ioh;
587a8c1b917Smiod
588a8c1b917Smiod if (mgattach_common(sc) != 0)
589a8c1b917Smiod return;
590a8c1b917Smiod
591a8c1b917Smiod /* attach interrupt */
592a8c1b917Smiod sc->sc_ih = cpu_intr_establish(IPL_HIGH, ca->ca_irq,
593a8c1b917Smiod mg_intr, sc, sc->sc_dev.dv_xname);
594a8c1b917Smiod }
595