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