xref: /openbsd-src/sys/arch/hppa/dev/dino.c (revision 8500990981f885cbe5e6a4958549cacc238b5ae6)
1 /*	$OpenBSD: dino.c,v 1.2 2003/10/30 19:25:12 mickey Exp $	*/
2 
3 /*
4  * Copyright (c) 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 "cardbus.h"
30 
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/device.h>
34 #include <sys/reboot.h>
35 #include <sys/malloc.h>
36 #include <sys/extent.h>
37 
38 #include <machine/iomod.h>
39 #include <machine/autoconf.h>
40 
41 #include <hppa/dev/cpudevs.h>
42 
43 #if NCARDBUS > 0
44 #include <dev/cardbus/rbus.h>
45 #endif
46 
47 #include <dev/pci/pcireg.h>
48 #include <dev/pci/pcivar.h>
49 #include <dev/pci/pcidevs.h>
50 
51 #define	DINO_MEM_CHUNK	0x800000
52 #define	DINO_MEM_WINDOW	(2 * DINO_MEM_CHUNK)
53 
54 struct dino_regs {
55 	u_int32_t	pad0;		/* 0x000 */
56 	u_int32_t	iar0;		/* 0x004 rw intr addr reg 0 */
57 	u_int32_t	iodc;		/* 0x008 rw iodc data/addr */
58 	u_int32_t	irr0;		/* 0x00c r  intr req reg 0 */
59 	u_int32_t	iar1;		/* 0x010 rw intr addr reg 1 */
60 	u_int32_t	irr1;		/* 0x014 r  intr req reg 1 */
61 	u_int32_t	imr;		/* 0x018 rw intr mask reg */
62 	u_int32_t	ipr;		/* 0x01c rw intr pending reg */
63 	u_int32_t	toc_addr;	/* 0x020 rw TOC addr reg */
64 	u_int32_t	icr;		/* 0x024 rw intr control reg */
65 	u_int32_t	ilr;		/* 0x028 r  intr level reg */
66 	u_int32_t	pad1;		/* 0x02c */
67 	u_int32_t	io_command;	/* 0x030  w command register */
68 	u_int32_t	io_status;	/* 0x034 r  status register */
69 	u_int32_t	io_control;	/* 0x038 rw control register */
70 	u_int32_t	pad2;		/* 0x03c AUX registers follow */
71 	u_int32_t	io_gsc_err_addr;/* 0x040 GSC error address */
72 	u_int32_t	io_err_info;	/* 0x044 error info register */
73 	u_int32_t	io_pci_err_addr;/* 0x048 PCI error address */
74 	u_int32_t	pad3[4];	/* 0x04c */
75 	u_int32_t	io_fbb_en;	/* 0x05c fast back2back enable reg */
76 	u_int32_t	io_addr_en;	/* 0x060 address enable reg */
77 	u_int32_t	pci_addr;	/* 0x064 PCI conf/io/mem addr reg */
78 	u_int32_t	pci_conf_data;	/* 0x068 PCI conf data reg */
79 	u_int32_t	pci_io_data;	/* 0x06c PCI io data reg */
80 	u_int32_t	pci_mem_data;	/* 0x070 PCI memory data reg */
81 	u_int32_t	pad4[0x740/4];	/* 0x074 */
82 	u_int32_t	gsc2x_config;	/* 0x7b4 GSC2X config reg */
83 	u_int32_t	pad5[0x48/4];	/* 0x7b8: BSRS registers follow */
84 	u_int32_t	gmask;		/* 0x800 GSC arbitration mask */
85 	u_int32_t	pamr;		/* 0x804 PCI arbitration mask */
86 	u_int32_t	papr;		/* 0x808 PCI arbitration priority */
87 	u_int32_t	damode;		/* 0x80c PCI arbitration mode */
88 	u_int32_t	pcicmd;		/* 0x810 PCI command register */
89 	u_int32_t	pcists;		/* 0x814 PCI status register */
90 	u_int32_t	pad6;		/* 0x818 */
91 	u_int32_t	mltim;		/* 0x81c PCI master latency timer */
92 	u_int32_t	brdg_feat;	/* 0x820 PCI bridge feature enable */
93 	u_int32_t	pciror;		/* 0x824 PCI read optimization reg */
94 	u_int32_t	pciwor;		/* 0x828 PCI write optimization reg */
95 	u_int32_t	pad7;		/* 0x82c */
96 	u_int32_t	tltim;		/* 0x830 PCI target latency reg */
97 };
98 
99 struct dino_softc {
100 	struct  device sc_dv;
101 
102 	int sc_ver;
103 	void *sc_ih;
104 	u_int32_t sc_imr;
105 	bus_space_tag_t sc_bt;
106 	bus_space_handle_t sc_bh;
107 	bus_space_handle_t sc_memh;
108 	bus_dma_tag_t sc_dmat;
109 	volatile struct dino_regs *sc_regs;
110 
111 	struct hppa_pci_chipset_tag sc_pc;
112 	struct hppa_bus_space_tag sc_iot;
113 	char sc_ioexname[20];
114 	struct extent *sc_ioex;
115 	struct hppa_bus_space_tag sc_memt;
116 	char sc_memexname[20];
117 	struct extent *sc_memex;
118 	struct hppa_bus_dma_tag sc_dmatag;
119 };
120 
121 int	dinomatch(struct device *, void *, void *);
122 void	dinoattach(struct device *, struct device *, void *);
123 int	dino_intr(void *);
124 
125 struct cfattach dino_ca = {
126 	sizeof(struct dino_softc), dinomatch, dinoattach
127 };
128 
129 struct cfdriver dino_cd = {
130 	NULL, "dino", DV_DULL
131 };
132 
133 int
134 dinomatch(parent, cfdata, aux)
135 	struct device *parent;
136 	void *cfdata;
137 	void *aux;
138 {
139 	struct confargs *ca = aux;
140 	/* struct cfdata *cf = cfdata; */
141 
142 	/* there will be only one */
143 	if (ca->ca_type.iodc_type != HPPA_TYPE_BRIDGE ||
144 	    ca->ca_type.iodc_sv_model != HPPA_BRIDGE_DINO)
145 		return (0);
146 
147 	return (1);
148 }
149 
150 void
151 dino_attach_hook(struct device *parent, struct device *self,
152     struct pcibus_attach_args *pba)
153 {
154 
155 }
156 
157 int
158 dino_maxdevs(void *v, int bus)
159 {
160 	return (32);
161 }
162 
163 pcitag_t
164 dino_make_tag(void *v, int bus, int dev, int func)
165 {
166 	if (bus > 255 || dev > 31 || func > 7)
167 		panic("dino_make_tag: bad request");
168 
169 	return ((bus << 16) | (dev << 11) | (func << 8));
170 }
171 
172 void
173 dino_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func)
174 {
175 	*bus = (tag >> 16) & 0xff;
176 	*dev = (tag >> 11) & 0x1f;
177 	*func= (tag >>  8) & 0x07;
178 }
179 
180 pcireg_t
181 dino_conf_read(void *v, pcitag_t tag, int reg)
182 {
183 	struct dino_softc *sc = v;
184 	volatile struct dino_regs *r = sc->sc_regs;
185 	pcireg_t data;
186 
187 	r->pci_addr = tag | reg;
188 	data = r->pci_conf_data;
189 	return (letoh32(data));
190 }
191 
192 void
193 dino_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
194 {
195 	struct dino_softc *sc = v;
196 	volatile struct dino_regs *r = sc->sc_regs;
197 
198 	r->pci_addr = tag | reg;
199 	r->pci_conf_data = htole32(data);
200 }
201 
202 int
203 dino_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
204 {
205 	/* struct dino_softc *sc = v;
206 	volatile struct dino_regs *r = sc->sc_regs; */
207 	pci_chipset_tag_t pc = pa->pa_pc;
208 	pcitag_t tag = pa->pa_tag;
209 	pcireg_t reg;
210 
211 	reg = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
212 	*ihp = PCI_INTERRUPT_LINE(reg) + 1;
213 	return (*ihp == 0);
214 }
215 
216 const char *
217 dino_intr_string(void *v, pci_intr_handle_t ih)
218 {
219 	static char buf[32];
220 
221 	snprintf(buf, 32, "irq %d", ih);
222 
223 	return (buf);
224 }
225 
226 void *
227 dino_intr_establish(void *v, pci_intr_handle_t ih,
228     int pri, int (*handler)(void *), void *arg, char *name)
229 {
230 	struct dino_softc *sc = v;
231 	volatile struct dino_regs *r = sc->sc_regs;
232 	void *iv;
233 
234 	/* no mapping */
235 	if (ih == 0)
236 		return (NULL);
237 
238 	if ((iv = cpu_intr_map(sc->sc_ih, pri, ih - 1, handler, arg, name))) {
239 		if (cold)
240 			sc->sc_imr |= (1 << (ih - 1));
241 		else
242 			r->imr |= (1 << (ih - 1));
243 		r->icr &= ~(1 << (ih - 1));
244 	}
245 
246 	return (iv);
247 }
248 
249 void
250 dino_intr_disestablish(void *v, void *cookie)
251 {
252 #if 0
253 	struct dino_softc *sc = v;
254 	volatile struct dino_regs *r = sc->sc_regs;
255 
256 	r->imr &= ~(1 << (ih - 1));
257 
258 	TODO cpu_intr_unmap(sc->sc_ih, cookie);
259 #endif
260 }
261 
262 #if NCARDBUS > 0
263 void *
264 dino_alloc_parent(struct device *self, struct pci_attach_args *pa, int io)
265 {
266 	struct dino_softc *sc = pa->pa_pc->_cookie;
267 	struct extent *ex;
268 	bus_space_tag_t tag;
269 	bus_addr_t start;
270 	bus_size_t size;
271 
272 	if (io) {
273 		ex = sc->sc_ioex;
274 		tag = pa->pa_iot;
275 		start = 0xa000;
276 		size = 0x1000;
277 	} else {
278 		ex = sc->sc_memex;
279 		tag = pa->pa_memt;
280 		start = ex->ex_start;
281 		size = DINO_MEM_CHUNK;
282 	}
283 
284 	if (extent_alloc_subregion(ex, start, ex->ex_end, size, size, 0,
285 	    EX_NOBOUNDARY, EX_NOWAIT, &start))
286 		return (NULL);
287 
288 	extent_free(ex, start, size, EX_NOWAIT);
289 	return rbus_new_root_share(tag, ex, start, size, start);
290 }
291 #endif
292 
293 int
294 dino_iomap(void *v, bus_addr_t bpa, bus_size_t size,
295     int flags, bus_space_handle_t *bshp)
296 {
297 	struct dino_softc *sc = v;
298 	int error;
299 
300 	if (!(flags & BUS_SPACE_MAP_NOEXTENT) &&
301 	    (error = extent_alloc_region(sc->sc_ioex, bpa, size, EX_NOWAIT)))
302 		return (error);
303 
304 	if (bshp)
305 		*bshp = bpa;
306 
307 	return (0);
308 }
309 
310 int
311 dino_memmap(void *v, bus_addr_t bpa, bus_size_t size,
312     int flags, bus_space_handle_t *bshp)
313 {
314 	struct dino_softc *sc = v;
315 	volatile struct dino_regs *r = sc->sc_regs;
316 	u_int32_t reg;
317 	int error;
318 
319 	reg = r->io_addr_en;
320 	reg |= 1 << ((bpa >> 23) & 0x1f);
321 #ifdef DEBUG
322 	if (reg & 0x80000001)
323 		panic("mapping outside the mem extent range");
324 #endif
325 	/* map into the upper bus space, if not yet mapped this 8M */
326 	if (reg != r->io_addr_en) {
327 		bus_addr_t sbpa = bpa & 0xff800000;
328 
329 		if ((error = bus_space_map(sc->sc_bt, sbpa, DINO_MEM_CHUNK,
330 		    flags, bshp))) {
331 			return (error);
332 		}
333 		r->io_addr_en = reg;
334 
335 		if (bshp)
336 			*bshp += (bpa - sbpa);
337 	} else if (bshp)
338 		*bshp = bpa;
339 
340 	return (0);
341 }
342 
343 int
344 dino_subregion(void *v, bus_space_handle_t bsh, bus_size_t offset,
345     bus_size_t size, bus_space_handle_t *nbshp)
346 {
347 	*nbshp = bsh + offset;
348 	return (0);
349 }
350 
351 int
352 dino_ioalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
353     bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
354     bus_space_handle_t *bshp)
355 {
356 	struct dino_softc *sc = v;
357 	struct extent *ex = sc->sc_ioex;
358 	bus_addr_t bpa;
359 	int error;
360 
361 	if (rstart < ex->ex_start || rend > ex->ex_end)
362 		panic("dino_ioalloc: bad region start/end");
363 
364 	if ((error = extent_alloc_subregion(ex, rstart, rend, size,
365 	    align, 0, boundary, EX_NOWAIT, &bpa)))
366 		return (error);
367 
368 	if (addrp)
369 		*addrp = bpa;
370 	if (bshp)
371 		*bshp = bpa;
372 
373 	return (0);
374 }
375 
376 int
377 dino_memalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
378     bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
379     bus_space_handle_t *bshp)
380 {
381 	/* TODO dino_memalloc */
382 	return (-1);
383 }
384 
385 void
386 dino_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
387 {
388 	struct dino_softc *sc = v;
389 	struct extent *ex;
390 	bus_addr_t bpa;
391 
392 	bpa = bsh;
393 	if (bsh & 0xf0000000) {
394 		/* TODO dino_unmap mem */
395 		/* TODO unmap from the upper bus if the last use in this 8M */
396 		return;
397 	} else
398 		ex = sc->sc_ioex;
399 
400 	/* XXX gotta follow the BUS_SPACE_MAP_NOEXTENT flag */
401 	if (extent_free(ex, bpa, size, EX_NOWAIT))
402 		printf("dino_unmap: ps 0x%lx, size 0x%lx\n"
403 		    "dino_unmap: can't free region\n", bpa, size);
404 }
405 
406 void
407 dino_free(void *v, bus_space_handle_t bh, bus_size_t size)
408 {
409 	/* should be enough */
410 	dino_unmap(v, bh, size);
411 }
412 
413 void
414 dino_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op)
415 {
416 	sync_caches();
417 }
418 
419 u_int8_t
420 dino_r1(void *v, bus_space_handle_t h, bus_size_t o)
421 {
422 	h += o;
423 	if (h & 0xf0000000)
424 		return *(volatile u_int8_t *)h;
425 	else {
426 		struct dino_softc *sc = v;
427 		volatile struct dino_regs *r = sc->sc_regs;
428 		u_int8_t data;
429 
430 		r->pci_addr = h & ~3;
431 		data = *((volatile u_int8_t *)&r->pci_io_data + (h & 3));
432 		return (data);
433 	}
434 }
435 
436 u_int16_t
437 dino_r2(void *v, bus_space_handle_t h, bus_size_t o)
438 {
439 	u_int16_t data;
440 
441 	h += o;
442 	if (h & 0xf0000000)
443 		data = *(volatile u_int16_t *)h;
444 	else {
445 		struct dino_softc *sc = v;
446 		volatile struct dino_regs *r = sc->sc_regs;
447 
448 		r->pci_addr = h & ~3;
449 		data = *((volatile u_int16_t *)&r->pci_io_data + (h & 2));
450 	}
451 
452 	return (letoh16(data));
453 }
454 
455 u_int32_t
456 dino_r4(void *v, bus_space_handle_t h, bus_size_t o)
457 {
458 	u_int32_t data;
459 
460 	h += o;
461 	if (h & 0xf0000000)
462 		data = *(volatile u_int32_t *)h;
463 	else {
464 		struct dino_softc *sc = v;
465 		volatile struct dino_regs *r = sc->sc_regs;
466 
467 		r->pci_addr = h;
468 		data = r->pci_io_data;
469 	}
470 
471 	return (letoh32(data));
472 }
473 
474 u_int64_t
475 dino_r8(void *v, bus_space_handle_t h, bus_size_t o)
476 {
477 	h += o;
478 	if (h & 0xf0000000)
479 		return *(volatile u_int64_t *)h;
480 	else
481 		panic("dino_r8: not implemented");
482 }
483 
484 void
485 dino_w1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv)
486 {
487 	h += o;
488 	if (h & 0xf0000000)
489 		*(volatile u_int8_t *)h = vv;
490 	else {
491 		struct dino_softc *sc = v;
492 		volatile struct dino_regs *r = sc->sc_regs;
493 
494 		r->pci_addr = h & ~3;
495 		*((volatile u_int8_t *)&r->pci_io_data + (h & 3)) = vv;
496 	}
497 }
498 
499 void
500 dino_w2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv)
501 {
502 	h += o;
503 	vv = htole16(vv);
504 	if (h & 0xf0000000)
505 		*(volatile u_int16_t *)h = vv;
506 	else {
507 		struct dino_softc *sc = v;
508 		volatile struct dino_regs *r = sc->sc_regs;
509 
510 		r->pci_addr = h & ~3;
511 		*((volatile u_int16_t *)&r->pci_io_data + (h & 2)) = vv;
512 	}
513 }
514 
515 void
516 dino_w4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv)
517 {
518 	h += o;
519 	vv = htole32(vv);
520 	if (h & 0xf0000000)
521 		*(volatile u_int32_t *)h = vv;
522 	else {
523 		struct dino_softc *sc = v;
524 		volatile struct dino_regs *r = sc->sc_regs;
525 
526 		r->pci_addr = h;
527 		r->pci_io_data = vv;
528 	}
529 }
530 
531 void
532 dino_w8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t vv)
533 {
534 	h += o;
535 	if (h & 0xf0000000)
536 		*(volatile u_int64_t *)h = vv;
537 	else
538 		panic("dino_w8: not implemented");
539 }
540 
541 
542 void
543 dino_rm_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t *a, bus_size_t c)
544 {
545 	volatile u_int8_t *p;
546 
547 	h += o;
548 	if (h & 0xf0000000)
549 		p = (volatile u_int8_t *)h;
550 	else {
551 		struct dino_softc *sc = v;
552 		volatile struct dino_regs *r = sc->sc_regs;
553 
554 		r->pci_addr = h & ~3;
555 		p = (volatile u_int8_t *)&r->pci_io_data + (h & 3);
556 	}
557 
558 	while (c--)
559 		*a++ = *p;
560 }
561 
562 void
563 dino_rm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
564 {
565 	volatile u_int16_t *p;
566 
567 	h += o;
568 	if (h & 0xf0000000)
569 		p = (volatile u_int16_t *)h;
570 	else {
571 		struct dino_softc *sc = v;
572 		volatile struct dino_regs *r = sc->sc_regs;
573 
574 		r->pci_addr = h & ~3;
575 		p = (volatile u_int16_t *)&r->pci_io_data + (h & 2);
576 	}
577 
578 	while (c--)
579 		*a++ = *p;
580 }
581 
582 void
583 dino_rm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
584 {
585 	volatile u_int32_t *p;
586 
587 	h += o;
588 	if (h & 0xf0000000)
589 		p = (volatile u_int32_t *)h;
590 	else {
591 		struct dino_softc *sc = v;
592 		volatile struct dino_regs *r = sc->sc_regs;
593 
594 		r->pci_addr = h;
595 		p = (volatile u_int32_t *)&r->pci_io_data;
596 	}
597 
598 	while (c--)
599 		*a++ = *p;
600 }
601 
602 void
603 dino_rm_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t *a, bus_size_t c)
604 {
605 	panic("dino_rm_8: not implemented");
606 }
607 
608 void
609 dino_wm_1(void *v, bus_space_handle_t h, bus_size_t o, const u_int8_t *a, bus_size_t c)
610 {
611 	volatile u_int8_t *p;
612 
613 	h += o;
614 	if (h & 0xf0000000)
615 		p = (volatile u_int8_t *)h;
616 	else {
617 		struct dino_softc *sc = v;
618 		volatile struct dino_regs *r = sc->sc_regs;
619 
620 		r->pci_addr = h & ~3;
621 		p = (volatile u_int8_t *)&r->pci_io_data + (h & 3);
622 	}
623 
624 	while (c--)
625 		*p = *a++;
626 }
627 
628 void
629 dino_wm_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
630 {
631 	volatile u_int16_t *p;
632 
633 	h += o;
634 	if (h & 0xf0000000)
635 		p = (volatile u_int16_t *)h;
636 	else {
637 		struct dino_softc *sc = v;
638 		volatile struct dino_regs *r = sc->sc_regs;
639 
640 		r->pci_addr = h & ~3;
641 		p = (volatile u_int16_t *)&r->pci_io_data + (h & 2);
642 	}
643 
644 	while (c--)
645 		*p = *a++;
646 }
647 
648 void
649 dino_wm_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
650 {
651 	volatile u_int32_t *p;
652 
653 	h += o;
654 	if (h & 0xf0000000)
655 		p = (volatile u_int32_t *)h;
656 	else {
657 		struct dino_softc *sc = v;
658 		volatile struct dino_regs *r = sc->sc_regs;
659 
660 		r->pci_addr = h;
661 		p = (volatile u_int32_t *)&r->pci_io_data;
662 	}
663 
664 	while (c--)
665 		*p = *a++;
666 }
667 
668 void
669 dino_wm_8(void *v, bus_space_handle_t h, bus_size_t o, const u_int64_t *a, bus_size_t c)
670 {
671 	panic("dino_wm_8: not implemented");
672 }
673 
674 void
675 dino_sm_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv, bus_size_t c)
676 {
677 	volatile u_int8_t *p;
678 
679 	h += o;
680 	if (h & 0xf0000000)
681 		p = (volatile u_int8_t *)h;
682 	else {
683 		struct dino_softc *sc = v;
684 		volatile struct dino_regs *r = sc->sc_regs;
685 
686 		r->pci_addr = h & ~3;
687 		p = (volatile u_int8_t *)&r->pci_io_data + (h & 3);
688 	}
689 
690 	while (c--)
691 		*p = vv;
692 }
693 
694 void
695 dino_sm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
696 {
697 	volatile u_int16_t *p;
698 
699 	h += o;
700 	if (h & 0xf0000000)
701 		p = (volatile u_int16_t *)h;
702 	else {
703 		struct dino_softc *sc = v;
704 		volatile struct dino_regs *r = sc->sc_regs;
705 
706 		r->pci_addr = h & ~3;
707 		p = (volatile u_int16_t *)&r->pci_io_data + (h & 2);
708 	}
709 
710 	while (c--)
711 		*p = vv;
712 }
713 
714 void
715 dino_sm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
716 {
717 	volatile u_int32_t *p;
718 
719 	h += o;
720 	if (h & 0xf0000000)
721 		p = (volatile u_int32_t *)h;
722 	else {
723 		struct dino_softc *sc = v;
724 		volatile struct dino_regs *r = sc->sc_regs;
725 
726 		r->pci_addr = h;
727 		p = (volatile u_int32_t *)&r->pci_io_data;
728 	}
729 
730 	while (c--)
731 		*p = vv;
732 }
733 
734 void
735 dino_sm_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t vv, bus_size_t c)
736 {
737 	panic("dino_sm_8: not implemented");
738 }
739 
740 void
741 dino_rrm_2(void *v, bus_space_handle_t h, bus_size_t o,
742     u_int8_t *a, bus_size_t c)
743 {
744 	volatile u_int16_t *p;
745 
746 	h += o;
747 	if (h & 0xf0000000)
748 		p = (volatile u_int16_t *)h;
749 	else {
750 		struct dino_softc *sc = v;
751 		volatile struct dino_regs *r = sc->sc_regs;
752 
753 		r->pci_addr = h & ~3;
754 		p = (volatile u_int16_t *)&r->pci_io_data + (h & 2);
755 	}
756 
757 	while (c--)
758 		*a++ = swap16(*p);
759 }
760 
761 void
762 dino_rrm_4(void *v, bus_space_handle_t h, bus_size_t o,
763     u_int8_t *a, bus_size_t c)
764 {
765 	volatile u_int32_t *p;
766 
767 	h += o;
768 	if (h & 0xf0000000)
769 		p = (volatile u_int32_t *)h;
770 	else {
771 		struct dino_softc *sc = v;
772 		volatile struct dino_regs *r = sc->sc_regs;
773 
774 		r->pci_addr = h;
775 		p = (volatile u_int32_t *)&r->pci_io_data;
776 	}
777 
778 	while (c--)
779 		*a++ = swap32(*p);
780 }
781 
782 void
783 dino_rrm_8(void *v, bus_space_handle_t h, bus_size_t o,
784     u_int8_t *a, bus_size_t c)
785 {
786 	panic("dino_rrm_8: not implemented");
787 }
788 
789 void
790 dino_wrm_2(void *v, bus_space_handle_t h, bus_size_t o,
791     const u_int8_t *a, bus_size_t c)
792 {
793 	volatile u_int16_t *p;
794 
795 	h += o;
796 	if (h & 0xf0000000)
797 		p = (volatile u_int16_t *)h;
798 	else {
799 		struct dino_softc *sc = v;
800 		volatile struct dino_regs *r = sc->sc_regs;
801 
802 		r->pci_addr = h & ~3;
803 		p = (volatile u_int16_t *)&r->pci_io_data + (h & 2);
804 	}
805 
806 	while (c--)
807 		*p = swap16(*a++);
808 }
809 
810 void
811 dino_wrm_4(void *v, bus_space_handle_t h, bus_size_t o,
812     const u_int8_t *a, bus_size_t c)
813 {
814 	volatile u_int32_t *p;
815 
816 	h += o;
817 	if (h & 0xf0000000)
818 		p = (volatile u_int32_t *)h;
819 	else {
820 		struct dino_softc *sc = v;
821 		volatile struct dino_regs *r = sc->sc_regs;
822 
823 		r->pci_addr = h;
824 		p = (volatile u_int32_t *)&r->pci_io_data;
825 	}
826 
827 	while (c--)
828 		*p = swap32(*a++);
829 }
830 
831 void
832 dino_wrm_8(void *v, bus_space_handle_t h, bus_size_t o,
833     const u_int8_t *a, bus_size_t c)
834 {
835 	panic("dino_wrm_8: not implemented");
836 }
837 
838 void
839 dino_rr_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t *a, bus_size_t c)
840 {
841 	volatile u_int8_t *p;
842 
843 	h += o;
844 	if (h & 0xf0000000) {
845 		p = (volatile u_int8_t *)h;
846 		while (c--)
847 			*a++ = *p++;
848 	} else {
849 		struct dino_softc *sc = v;
850 		volatile struct dino_regs *r = sc->sc_regs;
851 
852 		r->pci_addr = h & ~3;
853 		while (c--) {
854 			p = (volatile u_int8_t *)&r->pci_io_data + (h & 3);
855 			*a++ = *p;
856 			if (!(++h & 3))
857 				r->pci_addr = h;
858 		}
859 	}
860 }
861 
862 void
863 dino_rr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
864 {
865 	volatile u_int16_t *p;
866 
867 	h += o;
868 	if (h & 0xf0000000) {
869 		p = (volatile u_int16_t *)h;
870 		while (c--)
871 			*a++ = *p++;
872 	} else {
873 		struct dino_softc *sc = v;
874 		volatile struct dino_regs *r = sc->sc_regs;
875 
876 		r->pci_addr = h & ~3;
877 		while (c--) {
878 			p = (volatile u_int16_t *)&r->pci_io_data + (h & 2);
879 			*a++ = *p;
880 			h += 2;
881 			if (!(h & 3))
882 				r->pci_addr = h;
883 		}
884 	}
885 }
886 
887 void
888 dino_rr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
889 {
890 	volatile u_int32_t *p;
891 
892 	h += o;
893 	if (h & 0xf0000000) {
894 		p = (volatile u_int32_t *)h;
895 		while (c--)
896 			*a++ = *p++;
897 	} else {
898 		struct dino_softc *sc = v;
899 		volatile struct dino_regs *r = sc->sc_regs;
900 
901 		for (; c--; h += 4) {
902 			r->pci_addr = h;
903 			*a++ = r->pci_io_data;
904 		}
905 	}
906 }
907 
908 void
909 dino_rr_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t *a, bus_size_t c)
910 {
911 	panic("dino_rr_8: not implemented");
912 }
913 
914 void
915 dino_wr_1(void *v, bus_space_handle_t h, bus_size_t o, const u_int8_t *a, bus_size_t c)
916 {
917 	volatile u_int8_t *p;
918 
919 	h += o;
920 	if (h & 0xf0000000) {
921 		p = (volatile u_int8_t *)h;
922 		while (c--)
923 			*p++ = *a++;
924 	} else {
925 		struct dino_softc *sc = v;
926 		volatile struct dino_regs *r = sc->sc_regs;
927 
928 		r->pci_addr = h & ~3;
929 		while (c--) {
930 			p = (volatile u_int8_t *)&r->pci_io_data + (h & 3);
931 			*p = *a++;
932 			if (!(++h & 3))
933 				r->pci_addr = h;
934 		}
935 	}
936 }
937 
938 void
939 dino_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
940 {
941 	volatile u_int16_t *p;
942 
943 	h += o;
944 	if (h & 0xf0000000) {
945 		p = (volatile u_int16_t *)h;
946 		while (c--)
947 			*p++ = *a++;
948 	} else {
949 		struct dino_softc *sc = v;
950 		volatile struct dino_regs *r = sc->sc_regs;
951 
952 		r->pci_addr = h & ~3;
953 		while (c--) {
954 			p = (volatile u_int16_t *)&r->pci_io_data + (h & 2);
955 			*p = *a++;
956 			h += 2;
957 			if (!(h & 3))
958 				r->pci_addr = h;
959 		}
960 	}
961 }
962 
963 void
964 dino_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
965 {
966 	volatile u_int32_t *p;
967 
968 	h += o;
969 	if (h & 0xf0000000) {
970 		p = (volatile u_int32_t *)h;
971 		while (c--)
972 			*p++ = *a++;
973 	} else {
974 		struct dino_softc *sc = v;
975 		volatile struct dino_regs *r = sc->sc_regs;
976 
977 		for (; c--; h += 4) {
978 			r->pci_addr = h;
979 			r->pci_io_data = *a++;
980 		}
981 	}
982 }
983 
984 void
985 dino_wr_8(void *v, bus_space_handle_t h, bus_size_t o, const u_int64_t *a, bus_size_t c)
986 {
987 	panic("dino_wr_8: not implemented");
988 }
989 
990 void
991 dino_rrr_2(void *v, bus_space_handle_t h, bus_size_t o,
992     u_int8_t *a, bus_size_t c)
993 {
994 	volatile u_int16_t *p;
995 
996 	h += o;
997 	if (h & 0xf0000000) {
998 		p = (volatile u_int16_t *)h;
999 		while (c--)
1000 			*a++ = swap16(*p++);
1001 	} else {
1002 		struct dino_softc *sc = v;
1003 		volatile struct dino_regs *r = sc->sc_regs;
1004 
1005 		r->pci_addr = h & ~3;
1006 		while (c--) {
1007 			p = (volatile u_int16_t *)&r->pci_io_data + (h & 2);
1008 			*a++ = swap16(*p);
1009 			h += 2;
1010 			if (!(h & 3))
1011 				r->pci_addr = h;
1012 		}
1013 	}
1014 }
1015 
1016 void
1017 dino_rrr_4(void *v, bus_space_handle_t h, bus_size_t o,
1018     u_int8_t *a, bus_size_t c)
1019 {
1020 	volatile u_int32_t *p;
1021 
1022 	h += o;
1023 	if (h & 0xf0000000) {
1024 		p = (volatile u_int32_t *)h;
1025 		while (c--)
1026 			*a++ = swap32(*p++);
1027 	} else {
1028 		struct dino_softc *sc = v;
1029 		volatile struct dino_regs *r = sc->sc_regs;
1030 
1031 		for (; c--; h += 4) {
1032 			r->pci_addr = h;
1033 			*a++ = swap32(r->pci_io_data);
1034 		}
1035 	}
1036 }
1037 
1038 void
1039 dino_rrr_8(void *v, bus_space_handle_t h, bus_size_t o,
1040     u_int8_t *a, bus_size_t c)
1041 {
1042 	panic("dino_rrr_8: not implemented");
1043 }
1044 
1045 void
1046 dino_wrr_2(void *v, bus_space_handle_t h, bus_size_t o,
1047     const u_int8_t *a, bus_size_t c)
1048 {
1049 	volatile u_int16_t *p;
1050 
1051 	h += o;
1052 	if (h & 0xf0000000) {
1053 		p = (volatile u_int16_t *)h;
1054 		while (c--)
1055 			*p++ = swap16(*a++);
1056 	} else {
1057 		struct dino_softc *sc = v;
1058 		volatile struct dino_regs *r = sc->sc_regs;
1059 
1060 		r->pci_addr = h & ~3;
1061 		while (c--) {
1062 			p = (volatile u_int16_t *)&r->pci_io_data + (h & 2);
1063 			*p = swap16(*a++);
1064 			h += 2;
1065 			if (!(h & 3))
1066 				r->pci_addr = h;
1067 		}
1068 	}
1069 }
1070 
1071 void
1072 dino_wrr_4(void *v, bus_space_handle_t h, bus_size_t o,
1073     const u_int8_t *a, bus_size_t c)
1074 {
1075 	volatile u_int32_t *p;
1076 
1077 	h += o;
1078 	if (h & 0xf0000000) {
1079 		p = (volatile u_int32_t *)h;
1080 		while (c--)
1081 			*p++ = swap32(*a++);
1082 	} else {
1083 		struct dino_softc *sc = v;
1084 		volatile struct dino_regs *r = sc->sc_regs;
1085 
1086 		for (; c--; h += 4) {
1087 			r->pci_addr = h;
1088 			r->pci_io_data = swap32(*a++);
1089 		}
1090 	}
1091 }
1092 
1093 void
1094 dino_wrr_8(void *v, bus_space_handle_t h, bus_size_t o,
1095     const u_int8_t *a, bus_size_t c)
1096 {
1097 	panic("dino_wrr_8: not implemented");
1098 }
1099 
1100 void
1101 dino_sr_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv, bus_size_t c)
1102 {
1103 	volatile u_int8_t *p;
1104 
1105 	h += o;
1106 	if (h & 0xf0000000) {
1107 		p = (volatile u_int8_t *)h;
1108 		while (c--)
1109 			*p++ = vv;
1110 	} else {
1111 		struct dino_softc *sc = v;
1112 		volatile struct dino_regs *r = sc->sc_regs;
1113 
1114 		r->pci_addr = h & ~3;
1115 		while (c--) {
1116 			p = (volatile u_int8_t *)&r->pci_io_data + (h & 3);
1117 			*p = vv;
1118 			if (!(++h & 3))
1119 				r->pci_addr = h;
1120 		}
1121 	}
1122 }
1123 
1124 void
1125 dino_sr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
1126 {
1127 	volatile u_int16_t *p;
1128 
1129 	h += o;
1130 	if (h & 0xf0000000) {
1131 		p = (volatile u_int16_t *)h;
1132 		while (c--)
1133 			*p++ = vv;
1134 	} else {
1135 		struct dino_softc *sc = v;
1136 		volatile struct dino_regs *r = sc->sc_regs;
1137 
1138 		r->pci_addr = h & ~3;
1139 		while (c--) {
1140 			p = (volatile u_int16_t *)&r->pci_io_data + (h & 2);
1141 			*p = vv;
1142 			h += 2;
1143 			if (!(h & 3))
1144 				r->pci_addr = h;
1145 		}
1146 	}
1147 }
1148 
1149 void
1150 dino_sr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
1151 {
1152 	volatile u_int32_t *p;
1153 
1154 	h += o;
1155 	if (h & 0xf0000000) {
1156 		p = (volatile u_int32_t *)h;
1157 		while (c--)
1158 			*p++ = vv;
1159 	} else {
1160 		struct dino_softc *sc = v;
1161 		volatile struct dino_regs *r = sc->sc_regs;
1162 
1163 		for (; c--; h += 4) {
1164 			r->pci_addr = h;
1165 			r->pci_io_data = vv;
1166 		}
1167 	}
1168 }
1169 
1170 void
1171 dino_sr_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t vv, bus_size_t c)
1172 {
1173 	panic("dino_sr_8: not implemented");
1174 }
1175 
1176 void
1177 dino_cp_1(void *v, bus_space_handle_t h1, bus_size_t o1,
1178 	  bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1179 {
1180 	while (c--)
1181 		dino_w1(v, h1, o1++, dino_r1(v, h2, o2++));
1182 }
1183 
1184 void
1185 dino_cp_2(void *v, bus_space_handle_t h1, bus_size_t o1,
1186 	  bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1187 {
1188 	while (c--) {
1189 		dino_w2(v, h1, o1, dino_r2(v, h2, o2));
1190 		o1 += 2;
1191 		o2 += 2;
1192 	}
1193 }
1194 
1195 void
1196 dino_cp_4(void *v, bus_space_handle_t h1, bus_size_t o1,
1197 	  bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1198 {
1199 	while (c--) {
1200 		dino_w4(v, h1, o1, dino_r4(v, h2, o2));
1201 		o1 += 4;
1202 		o2 += 4;
1203 	}
1204 }
1205 
1206 void
1207 dino_cp_8(void *v, bus_space_handle_t h1, bus_size_t o1,
1208 	  bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1209 {
1210 	while (c--) {
1211 		dino_w8(v, h1, o1, dino_r8(v, h2, o2));
1212 		o1 += 8;
1213 		o2 += 8;
1214 	}
1215 }
1216 
1217 
1218 const struct hppa_bus_space_tag dino_iomemt = {
1219 	NULL,
1220 
1221 	NULL, dino_unmap, dino_subregion, NULL, dino_free,
1222 	dino_barrier,
1223 	dino_r1,    dino_r2,    dino_r4,    dino_r8,
1224 	dino_w1,    dino_w2,    dino_w4,    dino_w8,
1225 	dino_rm_1,  dino_rm_2,  dino_rm_4,  dino_rm_8,
1226 	dino_wm_1,  dino_wm_2,  dino_wm_4,  dino_wm_8,
1227 	dino_sm_1,  dino_sm_2,  dino_sm_4,  dino_sm_8,
1228 	            dino_rrm_2, dino_rrm_4, dino_rrm_8,
1229 	            dino_wrm_2, dino_wrm_4, dino_wrm_8,
1230 	dino_rr_1,  dino_rr_2,  dino_rr_4,  dino_rr_8,
1231 	dino_wr_1,  dino_wr_2,  dino_wr_4,  dino_wr_8,
1232 	            dino_rrr_2, dino_rrr_4, dino_rrr_8,
1233 	            dino_wrr_2, dino_wrr_4, dino_wrr_8,
1234 	dino_sr_1,  dino_sr_2,  dino_sr_4,  dino_sr_8,
1235 	dino_cp_1,  dino_cp_2,  dino_cp_4,  dino_cp_8
1236 };
1237 
1238 int
1239 dino_dmamap_create(void *v, bus_size_t size, int nsegments,
1240     bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp)
1241 {
1242 	struct dino_softc *sc = v;
1243 
1244 	/* TODO check the addresses, boundary, enable dma */
1245 
1246 	return (bus_dmamap_create(sc->sc_dmat, size, nsegments,
1247 	    maxsegsz, boundary, flags, dmamp));
1248 }
1249 
1250 void
1251 dino_dmamap_destroy(void *v, bus_dmamap_t map)
1252 {
1253 	struct dino_softc *sc = v;
1254 
1255 	bus_dmamap_destroy(sc->sc_dmat, map);
1256 }
1257 
1258 int
1259 dino_dmamap_load(void *v, bus_dmamap_t map, void *addr, bus_size_t size,
1260     struct proc *p, int flags)
1261 {
1262 	struct dino_softc *sc = v;
1263 
1264 	return (bus_dmamap_load(sc->sc_dmat, map, addr, size, p, flags));
1265 }
1266 
1267 int
1268 dino_dmamap_load_mbuf(void *v, bus_dmamap_t map, struct mbuf *m, int flags)
1269 {
1270 	struct dino_softc *sc = v;
1271 
1272 	return (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, flags));
1273 }
1274 
1275 int
1276 dino_dmamap_load_uio(void *v, bus_dmamap_t map, struct uio *uio, int flags)
1277 {
1278 	struct dino_softc *sc = v;
1279 
1280 	return (bus_dmamap_load_uio(sc->sc_dmat, map, uio, flags));
1281 }
1282 
1283 int
1284 dino_dmamap_load_raw(void *v, bus_dmamap_t map, bus_dma_segment_t *segs,
1285     int nsegs, bus_size_t size, int flags)
1286 {
1287 	struct dino_softc *sc = v;
1288 
1289 	return (bus_dmamap_load_raw(sc->sc_dmat, map, segs, nsegs, size, flags));
1290 }
1291 
1292 void
1293 dino_dmamap_unload(void *v, bus_dmamap_t map)
1294 {
1295 	struct dino_softc *sc = v;
1296 
1297 	bus_dmamap_unload(sc->sc_dmat, map);
1298 }
1299 
1300 void
1301 dino_dmamap_sync(void *v, bus_dmamap_t map, bus_addr_t off,
1302     bus_size_t len, int ops)
1303 {
1304 	struct dino_softc *sc = v;
1305 
1306 	return (bus_dmamap_sync(sc->sc_dmat, map, off, len, ops));
1307 }
1308 
1309 int
1310 dino_dmamem_alloc(void *v, bus_size_t size, bus_size_t alignment,
1311     bus_size_t boundary, bus_dma_segment_t *segs,
1312     int nsegs, int *rsegs, int flags)
1313 {
1314 	struct dino_softc *sc = v;
1315 
1316 	return (bus_dmamem_alloc(sc->sc_dmat, size, alignment, boundary,
1317 	    segs, nsegs, rsegs, flags));
1318 }
1319 
1320 void
1321 dino_dmamem_free(void *v, bus_dma_segment_t *segs, int nsegs)
1322 {
1323 	struct dino_softc *sc = v;
1324 
1325 	bus_dmamem_free(sc->sc_dmat, segs, nsegs);
1326 }
1327 
1328 int
1329 dino_dmamem_map(void *v, bus_dma_segment_t *segs, int nsegs, size_t size,
1330     caddr_t *kvap, int flags)
1331 {
1332 	struct dino_softc *sc = v;
1333 
1334 	return (bus_dmamem_map(sc->sc_dmat, segs, nsegs, size, kvap, flags));
1335 }
1336 
1337 void
1338 dino_dmamem_unmap(void *v, caddr_t kva, size_t size)
1339 {
1340 	struct dino_softc *sc = v;
1341 
1342 	bus_dmamem_unmap(sc->sc_dmat, kva, size);
1343 }
1344 
1345 paddr_t
1346 dino_dmamem_mmap(void *v, bus_dma_segment_t *segs, int nsegs, off_t off,
1347     int prot, int flags)
1348 {
1349 	struct dino_softc *sc = v;
1350 
1351 	return (bus_dmamem_mmap(sc->sc_dmat, segs, nsegs, off, prot, flags));
1352 }
1353 
1354 const struct hppa_bus_dma_tag dino_dmat = {
1355 	NULL,
1356 	dino_dmamap_create, dino_dmamap_destroy,
1357 	dino_dmamap_load, dino_dmamap_load_mbuf,
1358 	dino_dmamap_load_uio, dino_dmamap_load_raw,
1359 	dino_dmamap_unload, dino_dmamap_sync,
1360 
1361 	dino_dmamem_alloc, dino_dmamem_free, dino_dmamem_map,
1362 	dino_dmamem_unmap, dino_dmamem_mmap
1363 };
1364 
1365 const struct hppa_pci_chipset_tag dino_pc = {
1366 	NULL,
1367 	dino_attach_hook, dino_maxdevs, dino_make_tag, dino_decompose_tag,
1368 	dino_conf_read, dino_conf_write,
1369 	dino_intr_map, dino_intr_string,
1370 	dino_intr_establish, dino_intr_disestablish,
1371 #if NCARDBUS > 0
1372 	dino_alloc_parent
1373 #else
1374 	NULL
1375 #endif
1376 };
1377 
1378 int
1379 dinoprint(void *aux, const char *pnp)
1380 {
1381 	struct pcibus_attach_args *pba = aux;
1382 
1383 	if (pnp)
1384 		printf("%s at %s\n", pba->pba_busname, pnp);
1385 	return (UNCONF);
1386 }
1387 
1388 void
1389 dinoattach(parent, self, aux)
1390 	struct device *parent;
1391 	struct device *self;
1392 	void *aux;
1393 {
1394 	struct dino_softc *sc = (struct dino_softc *)self;
1395 	struct confargs *ca = (struct confargs *)aux;
1396 	struct pcibus_attach_args pba;
1397 	volatile struct dino_regs *r;
1398 	bus_addr_t mem_start;
1399 	const char *p;
1400 	u_int data;
1401 	int s, ver;
1402 
1403 	sc->sc_bt = ca->ca_iot;
1404 	sc->sc_dmat = ca->ca_dmatag;
1405 	if (bus_space_map(sc->sc_bt, ca->ca_hpa, PAGE_SIZE, 0, &sc->sc_bh)) {
1406 		printf(": can't map space\n");
1407 		return;
1408 	}
1409 
1410 	sc->sc_regs = r = (volatile struct dino_regs *)sc->sc_bh;
1411 	r->io_control = 0x80;
1412 	r->pamr = 0;
1413 	r->papr = 0;
1414 	r->io_fbb_en |= 1;
1415 	r->io_addr_en = 0;
1416 	r->damode = 0;
1417 	r->gmask &= ~1;	/* allow GSC bus req */
1418 	r->pciror = 0;
1419 	r->pciwor = 0;
1420 	r->brdg_feat = 0xc0000000;
1421 
1422 	/* PCI reset */
1423 	r->pcicmd = 0x6f;
1424 
1425 	snprintf(sc->sc_ioexname, sizeof(sc->sc_ioexname),
1426 	    "%s_io", sc->sc_dv.dv_xname);
1427 	if ((sc->sc_ioex = extent_create(sc->sc_ioexname, 0, 0xffff,
1428 	    M_DEVBUF, NULL, 0, EX_NOWAIT | EX_MALLOCOK)) == NULL) {
1429 		printf(": cannot allocate I/O extent map\n");
1430 		bus_space_unmap(sc->sc_bt, sc->sc_bh, PAGE_SIZE);
1431 		return;
1432 	}
1433 
1434 	/* TODO reserve dino's pci space ? */
1435 
1436 	/* XXX assuming that dino attaches the last */
1437 	if (bus_space_alloc(sc->sc_bt, 0xf0800000, 0xff7fffff, DINO_MEM_WINDOW,
1438 	    DINO_MEM_CHUNK, EX_NOBOUNDARY, 0, &mem_start, &sc->sc_memh)) {
1439 		printf(": cannot allocate memory window\n");
1440 		bus_space_unmap(sc->sc_bt, sc->sc_bh, PAGE_SIZE);
1441 		return;
1442 	}
1443 	snprintf(sc->sc_memexname, sizeof(sc->sc_memexname),
1444 	    "%s_mem", sc->sc_dv.dv_xname);
1445 	if ((sc->sc_memex = extent_create(sc->sc_memexname, mem_start,
1446 	    mem_start + DINO_MEM_WINDOW, M_DEVBUF, NULL, 0,
1447 	    EX_NOWAIT | EX_MALLOCOK)) == NULL) {
1448 		printf(": cannot allocate MEM extent map\n");
1449 		extent_destroy(sc->sc_ioex);
1450 		bus_space_unmap(sc->sc_bt, sc->sc_bh, PAGE_SIZE);
1451 		bus_space_unmap(sc->sc_bt, sc->sc_memh, DINO_MEM_WINDOW);
1452 		return;
1453 	}
1454 
1455 	s = splhigh();
1456 	r->imr = ~0;
1457 	data = r->irr0;
1458 	r->imr = 0;
1459 	r->iar0 = cpu_gethpa(0) | (31 - ca->ca_irq);
1460 	splx(s);
1461 
1462 	sc->sc_ih = cpu_intr_establish(IPL_NESTED, ca->ca_irq,
1463 	    dino_intr, (void *)sc->sc_regs, sc->sc_dv.dv_xname);
1464 	/* TODO establish the bus error interrupt */
1465 
1466 	r->iodc = 0;
1467 	data = r->iodc;
1468 	ver = (ca->ca_type.iodc_model << 4) |
1469 	    (ca->ca_type.iodc_revision >> 4);
1470 	switch (ver) {
1471 	case 0x05d:	p = "Dino";	/* j2240 */
1472 	case 0x680:	p = "Dino";
1473 		switch (data >> 16) {
1474 		case 0x6800:	ver = 0x20;	break;
1475 		case 0x6801:	ver = 0x21;	break;
1476 		case 0x6802:	ver = 0x30;	break;
1477 		case 0x6803:	ver = 0x31;	break;
1478 		default:	ver = 0x40;	break;
1479 		}
1480 		break;
1481 
1482 	case 0x682:	p = "Cujo";
1483 		switch (data >> 16) {
1484 		case 0x6820:	ver = 0x10;	break;
1485 		case 0x6821:	ver = 0x20;	break;
1486 		default:	ver = 0x30;	break;
1487 		}
1488 		break;
1489 
1490 	default:	p = "Mojo";
1491 		ver = (data >> 16) & 0xff;
1492 		break;
1493 	}
1494 	sc->sc_ver = ver;
1495 	printf(": %s V%d.%d\n", p, ver >> 4, ver & 0xf);
1496 
1497 	sc->sc_iot = dino_iomemt;
1498 	sc->sc_iot.hbt_cookie = sc;
1499 	sc->sc_iot.hbt_map = dino_iomap;
1500 	sc->sc_iot.hbt_alloc = dino_ioalloc;
1501 	sc->sc_memt = dino_iomemt;
1502 	sc->sc_memt.hbt_cookie = sc;
1503 	sc->sc_memt.hbt_map = dino_memmap;
1504 	sc->sc_memt.hbt_alloc = dino_memalloc;
1505 	sc->sc_pc = dino_pc;
1506 	sc->sc_pc._cookie = sc;
1507 	sc->sc_dmatag = dino_dmat;
1508 	sc->sc_dmatag._cookie = sc;
1509 
1510 	pba.pba_busname = "pci";
1511 	pba.pba_iot = &sc->sc_iot;
1512 	pba.pba_memt = &sc->sc_memt;
1513 	pba.pba_dmat = &sc->sc_dmatag;
1514 	pba.pba_pc = &sc->sc_pc;
1515 	pba.pba_bus = 0;
1516 	config_found(self, &pba, dinoprint);
1517 
1518 	/* enable interrupts now that all the devices are there */
1519 	r->imr = sc->sc_imr;
1520 }
1521