xref: /netbsd-src/sys/arch/hppa/dev/elroy.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /*	$NetBSD: elroy.c,v 1.3 2021/04/24 23:36:39 thorpej Exp $	*/
2 
3 /*	$OpenBSD: elroy.c,v 1.5 2009/03/30 21:24:57 kettenis Exp $	*/
4 
5 /*
6  * Copyright (c) 2005 Michael Shalayeff
7  * All rights reserved.
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
18  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 /* #include "cardbus.h" */
23 
24 #include <sys/param.h>
25 #include <sys/systm.h>
26 #include <sys/device.h>
27 #include <sys/reboot.h>
28 #include <sys/malloc.h>
29 #include <sys/extent.h>
30 
31 #include <machine/iomod.h>
32 #include <machine/autoconf.h>
33 
34 #include <hppa/dev/cpudevs.h>
35 
36 #if NCARDBUS > 0
37 #include <dev/cardbus/rbus.h>
38 #endif
39 
40 #include <dev/pci/pcireg.h>
41 #include <dev/pci/pcivar.h>
42 #include <dev/pci/pcidevs.h>
43 
44 #include <hppa/dev/elroyreg.h>
45 #include <hppa/dev/elroyvar.h>
46 
47 #define	ELROY_MEM_CHUNK		0x800000
48 #define	ELROY_MEM_WINDOW	(2 * ELROY_MEM_CHUNK)
49 
50 int	elroy_match(device_t, cfdata_t, void *);
51 void	elroy_attach(device_t, device_t, void *);
52 
53 CFATTACH_DECL_NEW(elroy, sizeof(struct elroy_softc), elroy_match, elroy_attach,
54     NULL, NULL);
55 
56 extern struct cfdriver elroy_cd;
57 
58 void elroy_write32(volatile uint32_t *, uint32_t);
59 uint32_t elroy_read32(volatile uint32_t *);
60 void elroy_attach_hook(device_t, device_t, struct pcibus_attach_args *);
61 int elroy_maxdevs(void *, int);
62 pcitag_t elroy_make_tag(void *, int, int, int);
63 void elroy_decompose_tag(void *, pcitag_t, int *, int *, int *);
64 pcireg_t elroy_conf_read(void *, pcitag_t, int);
65 void elroy_conf_write(void *, pcitag_t, int, pcireg_t);
66 
67 int elroy_iomap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *);
68 int elroy_memmap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *);
69 int elroy_subregion(void *, bus_space_handle_t, bus_size_t, bus_size_t,
70     bus_space_handle_t *);
71 int elroy_ioalloc(void *, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t,
72     bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
73 int elroy_memalloc(void *, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t,
74     bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
75 void elroy_unmap(void *, bus_space_handle_t, bus_size_t);
76 void elroy_free(void *, bus_space_handle_t, bus_size_t);
77 void elroy_barrier(void *, bus_space_handle_t, bus_size_t, bus_size_t, int);
78 void *elroy_alloc_parent(device_t, struct pci_attach_args *, int);
79 void *elroy_vaddr(void *, bus_space_handle_t);
80 paddr_t elroy_mmap(void *, bus_addr_t, off_t, int, int);
81 
82 uint8_t elroy_r1(void *, bus_space_handle_t, bus_size_t);
83 uint16_t elroy_r2(void *, bus_space_handle_t, bus_size_t);
84 uint32_t elroy_r4(void *, bus_space_handle_t, bus_size_t);
85 uint64_t elroy_r8(void *, bus_space_handle_t, bus_size_t);
86 void elroy_w1(void *, bus_space_handle_t, bus_size_t, uint8_t);
87 void elroy_w2(void *, bus_space_handle_t, bus_size_t, uint16_t);
88 void elroy_w4(void *, bus_space_handle_t, bus_size_t, uint32_t);
89 void elroy_w8(void *, bus_space_handle_t, bus_size_t, uint64_t);
90 
91 void elroy_rm_1(void *, bus_space_handle_t, bus_size_t, uint8_t *,
92     bus_size_t);
93 void elroy_rm_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
94     bus_size_t);
95 void elroy_rm_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
96     bus_size_t);
97 void elroy_rm_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
98     bus_size_t);
99 void elroy_wm_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *,
100     bus_size_t);
101 void elroy_wm_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
102     bus_size_t);
103 void elroy_wm_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
104     bus_size_t);
105 void elroy_wm_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
106     bus_size_t);
107 void elroy_sm_1(void *, bus_space_handle_t, bus_size_t, uint8_t,
108     bus_size_t);
109 void elroy_sm_2(void *, bus_space_handle_t, bus_size_t, uint16_t,
110     bus_size_t);
111 void elroy_sm_4(void *, bus_space_handle_t, bus_size_t, uint32_t,
112     bus_size_t);
113 void elroy_sm_8(void *, bus_space_handle_t, bus_size_t, uint64_t,
114     bus_size_t);
115 
116 void elroy_rrm_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
117     bus_size_t);
118 void elroy_rrm_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
119     bus_size_t);
120 void elroy_rrm_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
121     bus_size_t);
122 void elroy_wrm_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
123     bus_size_t);
124 void elroy_wrm_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
125     bus_size_t);
126 void elroy_wrm_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
127     bus_size_t);
128 void elroy_rr_1(void *, bus_space_handle_t, bus_size_t, uint8_t *,
129     bus_size_t);
130 void elroy_rr_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
131     bus_size_t);
132 void elroy_rr_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
133     bus_size_t);
134 void elroy_rr_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
135     bus_size_t);
136 void elroy_wr_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *,
137     bus_size_t);
138 void elroy_wr_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
139     bus_size_t);
140 void elroy_wr_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
141     bus_size_t);
142 void elroy_wr_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
143     bus_size_t);
144 
145 void elroy_rrr_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
146     bus_size_t);
147 void elroy_rrr_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
148     bus_size_t);
149 void elroy_rrr_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
150     bus_size_t);
151 void elroy_wrr_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
152     bus_size_t);
153 void elroy_wrr_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
154     bus_size_t);
155 void elroy_wrr_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
156     bus_size_t);
157 void elroy_sr_1(void *, bus_space_handle_t, bus_size_t, uint8_t,
158     bus_size_t);
159 void elroy_sr_2(void *, bus_space_handle_t, bus_size_t, uint16_t,
160     bus_size_t);
161 void elroy_sr_4(void *, bus_space_handle_t, bus_size_t, uint32_t,
162     bus_size_t);
163 void elroy_sr_8(void *, bus_space_handle_t, bus_size_t, uint64_t,
164     bus_size_t);
165 void elroy_cp_1(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
166     bus_size_t, bus_size_t);
167 void elroy_cp_2(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
168     bus_size_t, bus_size_t);
169 void elroy_cp_4(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
170     bus_size_t, bus_size_t);
171 void elroy_cp_8(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
172     bus_size_t, bus_size_t);
173 
174 int elroy_dmamap_create(void *, bus_size_t, int, bus_size_t, bus_size_t,
175     int, bus_dmamap_t *);
176 void elroy_dmamap_destroy(void *, bus_dmamap_t);
177 int elroy_dmamap_load(void *, bus_dmamap_t, void *, bus_size_t,
178     struct proc *, int);
179 int elroy_dmamap_load_mbuf(void *, bus_dmamap_t, struct mbuf *, int);
180 int elroy_dmamap_load_uio(void *, bus_dmamap_t, struct uio *, int);
181 int elroy_dmamap_load_raw(void *, bus_dmamap_t, bus_dma_segment_t *,
182     int, bus_size_t, int);
183 void elroy_dmamap_unload(void *, bus_dmamap_t);
184 void elroy_dmamap_sync(void *, bus_dmamap_t, bus_addr_t, bus_size_t,
185     int);
186 int elroy_dmamem_alloc(void *, bus_size_t, bus_size_t, bus_size_t,
187     bus_dma_segment_t *, int, int *, int);
188 void elroy_dmamem_free(void *, bus_dma_segment_t *, int);
189 int elroy_dmamem_map(void *, bus_dma_segment_t *, int, size_t,
190     void **, int);
191 void elroy_dmamem_unmap(void *, void *, size_t);
192 paddr_t elroy_dmamem_mmap(void *, bus_dma_segment_t *, int, off_t,
193     int, int);
194 
195 int
196 elroy_match(device_t parent, cfdata_t cf, void *aux)
197 {
198 	struct confargs *ca = aux;
199 
200 	if ((ca->ca_name && !strcmp(ca->ca_name, "lba")) ||
201 	    (ca->ca_type.iodc_type == HPPA_TYPE_BRIDGE &&
202 	     ca->ca_type.iodc_sv_model == HPPA_BRIDGE_DINO &&
203 	     ca->ca_type.iodc_model == 0x78))
204 		return (1);
205 
206 	return (0);
207 }
208 
209 void
210 elroy_write32(volatile uint32_t *p, uint32_t v)
211 {
212 	*p = v;
213 }
214 
215 uint32_t
216 elroy_read32(volatile uint32_t *p)
217 {
218 	return *p;
219 }
220 
221 void
222 elroy_attach_hook(device_t parent, device_t self,
223     struct pcibus_attach_args *pba)
224 {
225 
226 }
227 
228 int
229 elroy_maxdevs(void *v, int bus)
230 {
231 	return (32);
232 }
233 
234 pcitag_t
235 elroy_make_tag(void *v, int bus, int dev, int func)
236 {
237 	if (bus > 255 || dev > 31 || func > 7)
238 		panic("elroy_make_tag: bad request");
239 
240 	return ((bus << 16) | (dev << 11) | (func << 8));
241 }
242 
243 void
244 elroy_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func)
245 {
246 	*bus = (tag >> 16) & 0xff;
247 	*dev = (tag >> 11) & 0x1f;
248 	*func= (tag >>  8) & 0x07;
249 }
250 
251 pcireg_t
252 elroy_conf_read(void *v, pcitag_t tag, int reg)
253 {
254 	struct elroy_softc *sc = v;
255 	volatile struct elroy_regs *r = sc->sc_regs;
256 	uint32_t arb_mask, err_cfg, control;
257 	pcireg_t data;
258 
259 /* printf("elroy_conf_read(%p, 0x%08x, 0x%x)", v, tag, reg); */
260 
261 	if ((unsigned int)reg >= PCI_CONF_SIZE)
262 		return ((pcireg_t) -1);
263 
264 	arb_mask = elroy_read32(&r->arb_mask);
265 	err_cfg = elroy_read32(&r->err_cfg);
266 	control = elroy_read32(&r->control);
267 	if (!arb_mask)
268 		elroy_write32(&r->arb_mask, htole32(ELROY_ARB_ENABLE));
269 	elroy_write32(&r->err_cfg, err_cfg |
270 	    htole32(ELROY_ERRCFG_SMART | ELROY_ERRCFG_CM));
271 	elroy_write32(&r->control, (control | htole32(ELROY_CONTROL_CE)) &
272 	    ~htole32(ELROY_CONTROL_HF));
273 
274 	elroy_write32(&r->pci_conf_addr, htole32(tag | reg));
275 	(void)elroy_read32(&r->pci_conf_addr);
276 	data = elroy_read32(&r->pci_conf_data);
277 
278 	elroy_write32(&r->control, control |
279 	    htole32(ELROY_CONTROL_CE|ELROY_CONTROL_CL));
280 	elroy_write32(&r->control, control);
281 	elroy_write32(&r->err_cfg, err_cfg);
282 	if (!arb_mask)
283 		elroy_write32(&r->arb_mask, arb_mask);
284 
285 	data = le32toh(data);
286 /* printf("=0x%08x (@ 0x%08x)\n", data, le32toh(data1)); */
287 	return (data);
288 }
289 
290 void
291 elroy_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
292 {
293 	struct elroy_softc *sc = v;
294 	volatile struct elroy_regs *r = sc->sc_regs;
295 	uint32_t arb_mask, err_cfg, control;
296 
297 /* printf("elroy_conf_write(%p, 0x%08x, 0x%x, 0x%x)\n", v, tag, reg, data); */
298 
299 	if ((unsigned int)reg >= PCI_CONF_SIZE)
300 		return;
301 
302 	arb_mask = elroy_read32(&r->arb_mask);
303 	err_cfg = elroy_read32(&r->err_cfg);
304 	control = elroy_read32(&r->control);
305 	if (!arb_mask)
306 		elroy_write32(&r->arb_mask, htole32(ELROY_ARB_ENABLE));
307 	elroy_write32(&r->err_cfg, err_cfg |
308 	    htole32(ELROY_ERRCFG_SMART | ELROY_ERRCFG_CM));
309 	elroy_write32(&r->control, (control | htole32(ELROY_CONTROL_CE)) &
310 	    ~htole32(ELROY_CONTROL_HF));
311 
312 	/* fix coalescing config writes errata by interleaving w/ a read */
313 	elroy_write32(&r->pci_conf_addr, htole32(tag | PCI_ID_REG));
314 	(void)elroy_read32(&r->pci_conf_addr);
315 	(void)elroy_read32(&r->pci_conf_data);
316 
317 	elroy_write32(&r->pci_conf_addr, htole32(tag | reg));
318 	(void)elroy_read32(&r->pci_conf_addr);
319 	elroy_write32(&r->pci_conf_data, htole32(data));
320 	(void)elroy_read32(&r->pci_conf_addr);
321 
322 	elroy_write32(&r->control, control |
323 	    htole32(ELROY_CONTROL_CE|ELROY_CONTROL_CL));
324 	elroy_write32(&r->control, control);
325 	elroy_write32(&r->err_cfg, err_cfg);
326 	if (!arb_mask)
327 		elroy_write32(&r->arb_mask, arb_mask);
328 }
329 
330 int
331 elroy_iomap(void *v, bus_addr_t bpa, bus_size_t size,
332     int flags, bus_space_handle_t *bshp)
333 {
334 	struct elroy_softc *sc = v;
335 	/* volatile struct elroy_regs *r = sc->sc_regs; */
336 	int error;
337 
338 	if ((error = bus_space_map(sc->sc_bt, bpa + sc->sc_iobase, size,
339 	    flags, bshp)))
340 		return (error);
341 
342 	return (0);
343 }
344 
345 int
346 elroy_memmap(void *v, bus_addr_t bpa, bus_size_t size,
347     int flags, bus_space_handle_t *bshp)
348 {
349 	struct elroy_softc *sc = v;
350 	/* volatile struct elroy_regs *r = sc->sc_regs; */
351 	int error;
352 
353 	if ((error = bus_space_map(sc->sc_bt, bpa, size, flags, bshp)))
354 		return (error);
355 
356 	return (0);
357 }
358 
359 int
360 elroy_subregion(void *v, bus_space_handle_t bsh, bus_size_t offset,
361     bus_size_t size, bus_space_handle_t *nbshp)
362 {
363 	*nbshp = bsh + offset;
364 	return (0);
365 }
366 
367 int
368 elroy_ioalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
369     bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
370     bus_space_handle_t *bshp)
371 {
372 	struct elroy_softc *sc = v;
373 	volatile struct elroy_regs *r = sc->sc_regs;
374 	bus_addr_t iostart, ioend;
375 
376 	iostart = r->io_base & ~htole32(ELROY_BASE_RE);
377 	ioend = iostart + ~htole32(r->io_mask) + 1;
378 	if (rstart < iostart || rend > ioend)
379 		panic("elroy_ioalloc: bad region start/end");
380 
381 	rstart += sc->sc_iobase;
382 	rend += sc->sc_iobase;
383 	if (bus_space_alloc(sc->sc_bt, rstart, rend, size,
384 	    align, boundary, flags, addrp, bshp))
385 		return (ENOMEM);
386 
387 	return (0);
388 }
389 
390 int
391 elroy_memalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
392     bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
393     bus_space_handle_t *bshp)
394 {
395 	struct elroy_softc *sc = v;
396 	/* volatile struct elroy_regs *r = sc->sc_regs; */
397 
398 	if (bus_space_alloc(sc->sc_bt, rstart, rend, size,
399 	    align, boundary, flags, addrp, bshp))
400 		return (ENOMEM);
401 
402 	return (0);
403 }
404 
405 void
406 elroy_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
407 {
408 	struct elroy_softc *sc = v;
409 
410 	bus_space_free(sc->sc_bt, bsh, size);
411 }
412 
413 void
414 elroy_free(void *v, bus_space_handle_t bh, bus_size_t size)
415 {
416 	/* should be enough */
417 	elroy_unmap(v, bh, size);
418 }
419 
420 void
421 elroy_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op)
422 {
423 	struct elroy_softc *sc = v;
424 	volatile struct elroy_regs *r = sc->sc_regs;
425 
426 	sync_caches();
427 	if (op & BUS_SPACE_BARRIER_WRITE) {
428 		(void)r->pci_id;	/* flush write fifo */
429 		sync_caches();
430 	}
431 }
432 
433 #if NCARDBUS > 0
434 void *
435 elroy_alloc_parent(device_t self, struct pci_attach_args *pa, int io)
436 {
437 #if 0	/* TODO */
438 
439 	struct elroy_softc *sc = pa->pa_pc->_cookie;
440 	struct extent *ex;
441 	bus_space_tag_t tag;
442 	bus_addr_t start;
443 	bus_size_t size;
444 
445 	if (io) {
446 		ex = sc->sc_ioex;
447 		tag = pa->pa_iot;
448 		start = 0xa000;
449 		size = 0x1000;
450 	} else {
451 		if (!sc->sc_memex) {
452 			bus_space_handle_t memh;
453 			bus_addr_t mem_start;
454 
455 			if (elroy_memalloc(sc, 0xf0800000, 0xff7fffff,
456 			    ELROY_MEM_WINDOW, ELROY_MEM_WINDOW, EX_NOBOUNDARY,
457 			    0, &mem_start, &memh))
458 				return (NULL);
459 
460 			snprintf(sc->sc_memexname, sizeof(sc->sc_memexname),
461 			    "%s_mem", device_xname(sc->sc_dv));
462 			if ((sc->sc_memex = extent_create(sc->sc_memexname,
463 			    mem_start, mem_start + ELROY_MEM_WINDOW,
464 			    NULL, 0, EX_NOWAIT | EX_MALLOCOK)) == NULL) {
465 				extent_destroy(sc->sc_ioex);
466 				bus_space_free(sc->sc_bt, memh,
467 				    ELROY_MEM_WINDOW);
468 				return (NULL);
469 			}
470 		}
471 		ex = sc->sc_memex;
472 		tag = pa->pa_memt;
473 		start = ex->ex_start;
474 		size = ELROY_MEM_CHUNK;
475 	}
476 
477 	if (extent_alloc_subregion(ex, start, ex->ex_end, size, size, 0,
478 	    EX_NOBOUNDARY, EX_NOWAIT, &start))
479 		return (NULL);
480 
481 	extent_free(ex, start, size, EX_NOWAIT);
482 	return rbus_new_root_share(tag, ex, start, size, 0);
483 #else
484 	return (NULL);
485 #endif
486 }
487 #endif
488 
489 void *
490 elroy_vaddr(void *v, bus_space_handle_t h)
491 {
492 	return ((void *)h);
493 }
494 
495 paddr_t
496 elroy_mmap(void *v, bus_addr_t addr, off_t off, int prot, int flags)
497 {
498 
499 	return -1;
500 }
501 
502 uint8_t
503 elroy_r1(void *v, bus_space_handle_t h, bus_size_t o)
504 {
505 	h += o;
506 	return *(volatile uint8_t *)h;
507 }
508 
509 uint16_t
510 elroy_r2(void *v, bus_space_handle_t h, bus_size_t o)
511 {
512 	volatile uint16_t *p;
513 
514 	h += o;
515 	p = (volatile uint16_t *)h;
516 	return (le16toh(*p));
517 }
518 
519 uint32_t
520 elroy_r4(void *v, bus_space_handle_t h, bus_size_t o)
521 {
522 	uint32_t data;
523 
524 	h += o;
525 	data = *(volatile uint32_t *)h;
526 	return (le32toh(data));
527 }
528 
529 uint64_t
530 elroy_r8(void *v, bus_space_handle_t h, bus_size_t o)
531 {
532 	uint64_t data;
533 
534 	h += o;
535 	data = *(volatile uint64_t *)h;
536 	return (le64toh(data));
537 }
538 
539 void
540 elroy_w1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv)
541 {
542 	h += o;
543 	*(volatile uint8_t *)h = vv;
544 }
545 
546 void
547 elroy_w2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv)
548 {
549 	volatile uint16_t *p;
550 
551 	h += o;
552 	p = (volatile uint16_t *)h;
553 	*p = htole16(vv);
554 }
555 
556 void
557 elroy_w4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv)
558 {
559 	h += o;
560 	vv = htole32(vv);
561 	*(volatile uint32_t *)h = vv;
562 }
563 
564 void
565 elroy_w8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv)
566 {
567 	h += o;
568 	*(volatile uint64_t *)h = htole64(vv);
569 }
570 
571 
572 void
573 elroy_rm_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t *a, bus_size_t c)
574 {
575 	volatile uint8_t *p;
576 
577 	h += o;
578 	p = (volatile uint8_t *)h;
579 	while (c--)
580 		*a++ = *p;
581 }
582 
583 void
584 elroy_rm_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t *a, bus_size_t c)
585 {
586 	volatile uint16_t *p;
587 
588 	h += o;
589 	p = (volatile uint16_t *)h;
590 	while (c--)
591 		*a++ = le16toh(*p);
592 }
593 
594 void
595 elroy_rm_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t *a, bus_size_t c)
596 {
597 	volatile uint32_t *p;
598 
599 	h += o;
600 	p = (volatile uint32_t *)h;
601 	while (c--)
602 		*a++ = le32toh(*p);
603 }
604 
605 void
606 elroy_rm_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t *a, bus_size_t c)
607 {
608 	volatile uint64_t *p;
609 
610 	h += o;
611 	p = (volatile uint64_t *)h;
612 	while (c--)
613 		*a++ = le64toh(*p);
614 }
615 
616 void
617 elroy_wm_1(void *v, bus_space_handle_t h, bus_size_t o, const uint8_t *a, bus_size_t c)
618 {
619 	volatile uint8_t *p;
620 
621 	h += o;
622 	p = (volatile uint8_t *)h;
623 	while (c--)
624 		*p = *a++;
625 }
626 
627 void
628 elroy_wm_2(void *v, bus_space_handle_t h, bus_size_t o, const uint16_t *a, bus_size_t c)
629 {
630 	volatile uint16_t *p;
631 
632 	h += o;
633 	p = (volatile uint16_t *)h;
634 	while (c--)
635 		*p = htole16(*a++);
636 }
637 
638 void
639 elroy_wm_4(void *v, bus_space_handle_t h, bus_size_t o, const uint32_t *a, bus_size_t c)
640 {
641 	volatile uint32_t *p;
642 
643 	h += o;
644 	p = (volatile uint32_t *)h;
645 	while (c--)
646 		*p = htole32(*a++);
647 }
648 
649 void
650 elroy_wm_8(void *v, bus_space_handle_t h, bus_size_t o, const uint64_t *a, bus_size_t c)
651 {
652 	volatile uint64_t *p;
653 
654 	h += o;
655 	p = (volatile uint64_t *)h;
656 	while (c--)
657 		*p = htole64(*a++);
658 }
659 
660 void
661 elroy_sm_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv, bus_size_t c)
662 {
663 	volatile uint8_t *p;
664 
665 	h += o;
666 	p = (volatile uint8_t *)h;
667 	while (c--)
668 		*p = vv;
669 }
670 
671 void
672 elroy_sm_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv, bus_size_t c)
673 {
674 	volatile uint16_t *p;
675 
676 	h += o;
677 	p = (volatile uint16_t *)h;
678 	vv = htole16(vv);
679 	while (c--)
680 		*p = vv;
681 }
682 
683 void
684 elroy_sm_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv, bus_size_t c)
685 {
686 	volatile uint32_t *p;
687 
688 	h += o;
689 	p = (volatile uint32_t *)h;
690 	vv = htole32(vv);
691 	while (c--)
692 		*p = vv;
693 }
694 
695 void
696 elroy_sm_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv, bus_size_t c)
697 {
698 	volatile uint64_t *p;
699 
700 	h += o;
701 	p = (volatile uint64_t *)h;
702 	vv = htole64(vv);
703 	while (c--)
704 		*p = vv;
705 }
706 
707 void
708 elroy_rrm_2(void *v, bus_space_handle_t h, bus_size_t o,
709     uint16_t *a, bus_size_t c)
710 {
711 	volatile uint16_t *p, *q = a;
712 
713 	h += o;
714 	p = (volatile uint16_t *)h;
715 	while (c--)
716 		*q++ = *p;
717 }
718 
719 void
720 elroy_rrm_4(void *v, bus_space_handle_t h, bus_size_t o,
721     uint32_t *a, bus_size_t c)
722 {
723 	volatile uint32_t *p, *q = a;
724 
725 	h += o;
726 	p = (volatile uint32_t *)h;
727 	while (c--)
728 		*q++ = *p;
729 }
730 
731 void
732 elroy_rrm_8(void *v, bus_space_handle_t h, bus_size_t o,
733     uint64_t *a, bus_size_t c)
734 {
735 	volatile uint64_t *p, *q = a;
736 
737 	h += o;
738 	p = (volatile uint64_t *)h;
739 	while (c--)
740 		*q++ = *p;
741 }
742 
743 void
744 elroy_wrm_2(void *v, bus_space_handle_t h, bus_size_t o,
745     const uint16_t *a, bus_size_t c)
746 {
747 	volatile uint16_t *p;
748 	const uint16_t *q = a;
749 
750 	h += o;
751 	p = (volatile uint16_t *)h;
752 	while (c--)
753 		*p = *q++;
754 }
755 
756 void
757 elroy_wrm_4(void *v, bus_space_handle_t h, bus_size_t o,
758     const uint32_t *a, bus_size_t c)
759 {
760 	volatile uint32_t *p;
761 	const uint32_t *q = a;
762 
763 	h += o;
764 	p = (volatile uint32_t *)h;
765 	while (c--)
766 		*p = *q++;
767 }
768 
769 void
770 elroy_wrm_8(void *v, bus_space_handle_t h, bus_size_t o,
771     const uint64_t *a, bus_size_t c)
772 {
773 	volatile uint64_t *p;
774 	const uint64_t *q = a;
775 
776 	h += o;
777 	p = (volatile uint64_t *)h;
778 	while (c--)
779 		*p = *q++;
780 }
781 
782 void
783 elroy_rr_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t *a, bus_size_t c)
784 {
785 	volatile uint8_t *p;
786 
787 	h += o;
788 	p = (volatile uint8_t *)h;
789 	while (c--)
790 		*a++ = *p++;
791 }
792 
793 void
794 elroy_rr_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t *a, bus_size_t c)
795 {
796 	volatile uint16_t *p, data;
797 
798 	h += o;
799 	p = (volatile uint16_t *)h;
800 	while (c--) {
801 		data = *p++;
802 		*a++ = le16toh(data);
803 	}
804 }
805 
806 void
807 elroy_rr_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t *a, bus_size_t c)
808 {
809 	volatile uint32_t *p, data;
810 
811 	h += o;
812 	p = (volatile uint32_t *)h;
813 	while (c--) {
814 		data = *p++;
815 		*a++ = le32toh(data);
816 	}
817 }
818 
819 void
820 elroy_rr_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t *a, bus_size_t c)
821 {
822 	volatile uint64_t *p, data;
823 
824 	h += o;
825 	p = (volatile uint64_t *)h;
826 	while (c--) {
827 		data = *p++;
828 		*a++ = le64toh(data);
829 	}
830 }
831 
832 void
833 elroy_wr_1(void *v, bus_space_handle_t h, bus_size_t o, const uint8_t *a, bus_size_t c)
834 {
835 	volatile uint8_t *p;
836 
837 	h += o;
838 	p = (volatile uint8_t *)h;
839 	while (c--)
840 		*p++ = *a++;
841 }
842 
843 void
844 elroy_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const uint16_t *a, bus_size_t c)
845 {
846 	volatile uint16_t *p, data;
847 
848 	h += o;
849 	p = (volatile uint16_t *)h;
850 	while (c--) {
851 		data = *a++;
852 		*p++ = htole16(data);
853 	}
854 }
855 
856 void
857 elroy_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const uint32_t *a, bus_size_t c)
858 {
859 	volatile uint32_t *p, data;
860 
861 	h += o;
862 	p = (volatile uint32_t *)h;
863 	while (c--) {
864 		data = *a++;
865 		*p++ = htole32(data);
866 	}
867 }
868 
869 void
870 elroy_wr_8(void *v, bus_space_handle_t h, bus_size_t o, const uint64_t *a, bus_size_t c)
871 {
872 	volatile uint64_t *p, data;
873 
874 	h += o;
875 	p = (volatile uint64_t *)h;
876 	while (c--) {
877 		data = *a++;
878 		*p++ = htole64(data);
879 	}
880 }
881 
882 void
883 elroy_rrr_2(void *v, bus_space_handle_t h, bus_size_t o,
884     uint16_t *a, bus_size_t c)
885 {
886 	volatile uint16_t *p, *q = a;
887 
888 	h += o;
889 	p = (volatile uint16_t *)h;
890 	while (c--)
891 		*q++ = *p++;
892 }
893 
894 void
895 elroy_rrr_4(void *v, bus_space_handle_t h, bus_size_t o,
896     uint32_t *a, bus_size_t c)
897 {
898 	volatile uint32_t *p, *q = a;
899 
900 	h += o;
901 	p = (volatile uint32_t *)h;
902 	while (c--)
903 		*q++ = *p++;
904 }
905 
906 void
907 elroy_rrr_8(void *v, bus_space_handle_t h, bus_size_t o,
908     uint64_t *a, bus_size_t c)
909 {
910 	volatile uint64_t *p, *q = a;
911 
912 	h += o;
913 	p = (volatile uint64_t *)h;
914 	while (c--)
915 		*q++ = *p++;
916 }
917 
918 void
919 elroy_wrr_2(void *v, bus_space_handle_t h, bus_size_t o,
920     const uint16_t *a, bus_size_t c)
921 {
922 	volatile uint16_t *p;
923 	const uint16_t *q = a;
924 
925 	h += o;
926 	p = (volatile uint16_t *)h;
927 	while (c--)
928 		*p++ = *q++;
929 }
930 
931 void
932 elroy_wrr_4(void *v, bus_space_handle_t h, bus_size_t o,
933     const uint32_t *a, bus_size_t c)
934 {
935 	volatile uint32_t *p;
936 	const uint32_t *q = a;
937 
938 	h += o;
939 	p = (volatile uint32_t *)h;
940 	while (c--)
941 		*p++ = *q++;
942 }
943 
944 void
945 elroy_wrr_8(void *v, bus_space_handle_t h, bus_size_t o,
946     const uint64_t *a, bus_size_t c)
947 {
948 	volatile uint64_t *p;
949 	const uint64_t *q = a;
950 
951 	h += o;
952 	p = (volatile uint64_t *)h;
953 	while (c--)
954 		*p++ = *q++;
955 }
956 
957 void
958 elroy_sr_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv, bus_size_t c)
959 {
960 	volatile uint8_t *p;
961 
962 	h += o;
963 	p = (volatile uint8_t *)h;
964 	while (c--)
965 		*p++ = vv;
966 }
967 
968 void
969 elroy_sr_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv, bus_size_t c)
970 {
971 	volatile uint16_t *p;
972 
973 	h += o;
974 	vv = htole16(vv);
975 	p = (volatile uint16_t *)h;
976 	while (c--)
977 		*p++ = vv;
978 }
979 
980 void
981 elroy_sr_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv, bus_size_t c)
982 {
983 	volatile uint32_t *p;
984 
985 	h += o;
986 	vv = htole32(vv);
987 	p = (volatile uint32_t *)h;
988 	while (c--)
989 		*p++ = vv;
990 }
991 
992 void
993 elroy_sr_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv, bus_size_t c)
994 {
995 	volatile uint64_t *p;
996 
997 	h += o;
998 	vv = htole64(vv);
999 	p = (volatile uint64_t *)h;
1000 	while (c--)
1001 		*p++ = vv;
1002 }
1003 
1004 void
1005 elroy_cp_1(void *v, bus_space_handle_t h1, bus_size_t o1,
1006 	  bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1007 {
1008 	while (c--)
1009 		elroy_w1(v, h1, o1++, elroy_r1(v, h2, o2++));
1010 }
1011 
1012 void
1013 elroy_cp_2(void *v, bus_space_handle_t h1, bus_size_t o1,
1014 	  bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1015 {
1016 	while (c--) {
1017 		elroy_w2(v, h1, o1, elroy_r2(v, h2, o2));
1018 		o1 += 2;
1019 		o2 += 2;
1020 	}
1021 }
1022 
1023 void
1024 elroy_cp_4(void *v, bus_space_handle_t h1, bus_size_t o1,
1025 	  bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1026 {
1027 	while (c--) {
1028 		elroy_w4(v, h1, o1, elroy_r4(v, h2, o2));
1029 		o1 += 4;
1030 		o2 += 4;
1031 	}
1032 }
1033 
1034 void
1035 elroy_cp_8(void *v, bus_space_handle_t h1, bus_size_t o1,
1036 	  bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1037 {
1038 	while (c--) {
1039 		elroy_w8(v, h1, o1, elroy_r8(v, h2, o2));
1040 		o1 += 8;
1041 		o2 += 8;
1042 	}
1043 }
1044 
1045 const struct hppa_bus_space_tag elroy_iomemt = {
1046 	NULL,
1047 
1048 	NULL, elroy_unmap, elroy_subregion, NULL, elroy_free,
1049 	elroy_barrier, elroy_vaddr, elroy_mmap,
1050 	elroy_r1,    elroy_r2,    elroy_r4,    elroy_r8,
1051 	elroy_w1,    elroy_w2,    elroy_w4,    elroy_w8,
1052 	elroy_rm_1,  elroy_rm_2,  elroy_rm_4,  elroy_rm_8,
1053 	elroy_wm_1,  elroy_wm_2,  elroy_wm_4,  elroy_wm_8,
1054 	elroy_sm_1,  elroy_sm_2,  elroy_sm_4,  elroy_sm_8,
1055 		     elroy_rrm_2, elroy_rrm_4, elroy_rrm_8,
1056 		     elroy_wrm_2, elroy_wrm_4, elroy_wrm_8,
1057 	elroy_rr_1,  elroy_rr_2,  elroy_rr_4,  elroy_rr_8,
1058 	elroy_wr_1,  elroy_wr_2,  elroy_wr_4,  elroy_wr_8,
1059 		     elroy_rrr_2, elroy_rrr_4, elroy_rrr_8,
1060 		     elroy_wrr_2, elroy_wrr_4, elroy_wrr_8,
1061 	elroy_sr_1,  elroy_sr_2,  elroy_sr_4,  elroy_sr_8,
1062 	elroy_cp_1,  elroy_cp_2,  elroy_cp_4,  elroy_cp_8
1063 };
1064 
1065 int
1066 elroy_dmamap_create(void *v, bus_size_t size, int nsegments,
1067     bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp)
1068 {
1069 	struct elroy_softc *sc = v;
1070 
1071 	/* TODO check the addresses, boundary, enable dma */
1072 
1073 	return (bus_dmamap_create(sc->sc_dmat, size, nsegments,
1074 	    maxsegsz, boundary, flags, dmamp));
1075 }
1076 
1077 void
1078 elroy_dmamap_destroy(void *v, bus_dmamap_t map)
1079 {
1080 	struct elroy_softc *sc = v;
1081 
1082 	bus_dmamap_destroy(sc->sc_dmat, map);
1083 }
1084 
1085 int
1086 elroy_dmamap_load(void *v, bus_dmamap_t map, void *addr, bus_size_t size,
1087     struct proc *p, int flags)
1088 {
1089 	struct elroy_softc *sc = v;
1090 
1091 	return (bus_dmamap_load(sc->sc_dmat, map, addr, size, p, flags));
1092 }
1093 
1094 int
1095 elroy_dmamap_load_mbuf(void *v, bus_dmamap_t map, struct mbuf *m, int flags)
1096 {
1097 	struct elroy_softc *sc = v;
1098 
1099 	return (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, flags));
1100 }
1101 
1102 int
1103 elroy_dmamap_load_uio(void *v, bus_dmamap_t map, struct uio *uio, int flags)
1104 {
1105 	struct elroy_softc *sc = v;
1106 
1107 	return (bus_dmamap_load_uio(sc->sc_dmat, map, uio, flags));
1108 }
1109 
1110 int
1111 elroy_dmamap_load_raw(void *v, bus_dmamap_t map, bus_dma_segment_t *segs,
1112     int nsegs, bus_size_t size, int flags)
1113 {
1114 	struct elroy_softc *sc = v;
1115 
1116 	return (bus_dmamap_load_raw(sc->sc_dmat, map, segs, nsegs, size, flags));
1117 }
1118 
1119 void
1120 elroy_dmamap_unload(void *v, bus_dmamap_t map)
1121 {
1122 	struct elroy_softc *sc = v;
1123 
1124 	bus_dmamap_unload(sc->sc_dmat, map);
1125 }
1126 
1127 void
1128 elroy_dmamap_sync(void *v, bus_dmamap_t map, bus_addr_t off,
1129     bus_size_t len, int ops)
1130 {
1131 	struct elroy_softc *sc = v;
1132 
1133 	bus_dmamap_sync(sc->sc_dmat, map, off, len, ops);
1134 }
1135 
1136 int
1137 elroy_dmamem_alloc(void *v, bus_size_t size, bus_size_t alignment,
1138     bus_size_t boundary, bus_dma_segment_t *segs,
1139     int nsegs, int *rsegs, int flags)
1140 {
1141 	struct elroy_softc *sc = v;
1142 
1143 	return (bus_dmamem_alloc(sc->sc_dmat, size, alignment, boundary,
1144 	    segs, nsegs, rsegs, flags));
1145 }
1146 
1147 void
1148 elroy_dmamem_free(void *v, bus_dma_segment_t *segs, int nsegs)
1149 {
1150 	struct elroy_softc *sc = v;
1151 
1152 	bus_dmamem_free(sc->sc_dmat, segs, nsegs);
1153 }
1154 
1155 int
1156 elroy_dmamem_map(void *v, bus_dma_segment_t *segs, int nsegs, size_t size,
1157     void **kvap, int flags)
1158 {
1159 	struct elroy_softc *sc = v;
1160 
1161 	return (bus_dmamem_map(sc->sc_dmat, segs, nsegs, size, kvap, flags));
1162 }
1163 
1164 void
1165 elroy_dmamem_unmap(void *v, void *kva, size_t size)
1166 {
1167 	struct elroy_softc *sc = v;
1168 
1169 	bus_dmamem_unmap(sc->sc_dmat, kva, size);
1170 }
1171 
1172 paddr_t
1173 elroy_dmamem_mmap(void *v, bus_dma_segment_t *segs, int nsegs, off_t off,
1174     int prot, int flags)
1175 {
1176 	struct elroy_softc *sc = v;
1177 
1178 	return (bus_dmamem_mmap(sc->sc_dmat, segs, nsegs, off, prot, flags));
1179 }
1180 
1181 const struct hppa_bus_dma_tag elroy_dmat = {
1182 	NULL,
1183 	elroy_dmamap_create, elroy_dmamap_destroy,
1184 	elroy_dmamap_load, elroy_dmamap_load_mbuf,
1185 	elroy_dmamap_load_uio, elroy_dmamap_load_raw,
1186 	elroy_dmamap_unload, elroy_dmamap_sync,
1187 
1188 	elroy_dmamem_alloc, elroy_dmamem_free, elroy_dmamem_map,
1189 	elroy_dmamem_unmap, elroy_dmamem_mmap
1190 };
1191 
1192 const struct hppa_pci_chipset_tag elroy_pc = {
1193 	NULL,
1194 	elroy_attach_hook, elroy_maxdevs, elroy_make_tag, elroy_decompose_tag,
1195 	elroy_conf_read, elroy_conf_write,
1196 	apic_intr_map, apic_intr_string,
1197 	apic_intr_establish, apic_intr_disestablish,
1198 #if NCARDBUS > 0
1199 	elroy_alloc_parent
1200 #else
1201 	NULL
1202 #endif
1203 };
1204 
1205 void
1206 elroy_attach(device_t parent, device_t self, void *aux)
1207 {
1208 	struct elroy_softc *sc = device_private(self);
1209 	struct confargs *ca = (struct confargs *)aux;
1210 	struct pcibus_attach_args pba;
1211 	volatile struct elroy_regs *r;
1212 	const char *p = NULL, *q;
1213 	int i;
1214 
1215 	sc->sc_dv = self;
1216 	sc->sc_hpa = ca->ca_hpa;
1217 	sc->sc_bt = ca->ca_iot;
1218 	sc->sc_dmat = ca->ca_dmatag;
1219 	if (bus_space_map(sc->sc_bt, ca->ca_hpa, ca->ca_hpasz, 0, &sc->sc_bh)) {
1220 		aprint_error(": can't map space\n");
1221 		return;
1222 	}
1223 
1224 	sc->sc_regs = r = bus_space_vaddr(sc->sc_bt, sc->sc_bh);
1225 	elroy_write32(&r->pci_cmdstat, htole32(PCI_COMMAND_IO_ENABLE |
1226 	    PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE));
1227 
1228 	elroy_write32(&r->control, elroy_read32(&r->control) &
1229 	    ~htole32(ELROY_CONTROL_RF));
1230 	for (i = 5000; i-- &&
1231 	    elroy_read32(&r->status) & htole32(ELROY_STATUS_RC); DELAY(10));
1232 	if (i < 0) {
1233 		char buf[128]; /* XXXNH */
1234 
1235 		snprintb(buf, sizeof(buf), ELROY_STATUS_BITS,
1236 		    htole32(r->status));
1237 		aprint_error(": reset failed; status %s\n", buf);
1238 		return;
1239 	}
1240 
1241 	q = "";
1242 	sc->sc_ver = PCI_REVISION(le32toh(elroy_read32(&r->pci_class)));
1243 	switch ((ca->ca_type.iodc_model << 4) |
1244 	    (ca->ca_type.iodc_revision >> 4)) {
1245 	case 0x782:
1246 		p = "Elroy";
1247 		switch (sc->sc_ver) {
1248 		default:
1249 			q = "+";
1250 		case 5:	sc->sc_ver = 0x40;	break;
1251 		case 4:	sc->sc_ver = 0x30;	break;
1252 		case 3:	sc->sc_ver = 0x22;	break;
1253 		case 2:	sc->sc_ver = 0x21;	break;
1254 		case 1:	sc->sc_ver = 0x20;	break;
1255 		case 0:	sc->sc_ver = 0x10;	break;
1256 		}
1257 		break;
1258 
1259 	case 0x783:
1260 		p = "Mercury";
1261 		break;
1262 
1263 	case 0x784:
1264 		p = "Quicksilver";
1265 		break;
1266 
1267 	default:
1268 		p = "Mojo";
1269 		break;
1270 	}
1271 
1272 	aprint_normal(": %s TR%d.%d%s", p, sc->sc_ver >> 4, sc->sc_ver & 0xf,
1273 	    q);
1274 	apic_attach(sc);
1275 	aprint_normal("\n");
1276 
1277 	elroy_write32(&r->imask, htole32(0xffffffff << 30));
1278 	elroy_write32(&r->ibase, htole32(ELROY_BASE_RE));
1279 
1280 	/* TODO reserve elroy's pci space ? */
1281 
1282 #if 0
1283 printf("lmm %llx/%llx gmm %llx/%llx wlm %llx/%llx wgm %llx/%llx io %llx/%llx eio %llx/%llx\n",
1284 le64toh(r->lmmio_base), le64toh(r->lmmio_mask),
1285 le64toh(r->gmmio_base), le64toh(r->gmmio_mask),
1286 le64toh(r->wlmmio_base), le64toh(r->wlmmio_mask),
1287 le64toh(r->wgmmio_base), le64toh(r->wgmmio_mask),
1288 le64toh(r->io_base), le64toh(r->io_mask),
1289 le64toh(r->eio_base), le64toh(r->eio_mask));
1290 #endif
1291 
1292 	/* XXX evil hack! */
1293 	sc->sc_iobase = 0xfee00000;
1294 
1295 	sc->sc_iot = elroy_iomemt;
1296 	sc->sc_iot.hbt_cookie = sc;
1297 	sc->sc_iot.hbt_map = elroy_iomap;
1298 	sc->sc_iot.hbt_alloc = elroy_ioalloc;
1299 	sc->sc_memt = elroy_iomemt;
1300 	sc->sc_memt.hbt_cookie = sc;
1301 	sc->sc_memt.hbt_map = elroy_memmap;
1302 	sc->sc_memt.hbt_alloc = elroy_memalloc;
1303 	sc->sc_pc = elroy_pc;
1304 	sc->sc_pc._cookie = sc;
1305 	sc->sc_dmatag = elroy_dmat;
1306 	sc->sc_dmatag._cookie = sc;
1307 
1308 	memset(&pba, 0, sizeof(pba));
1309 	pba.pba_iot = &sc->sc_iot;
1310 	pba.pba_memt = &sc->sc_memt;
1311 	pba.pba_dmat = &sc->sc_dmatag;
1312 	pba.pba_pc = &sc->sc_pc;
1313 	pba.pba_bus = 0; /* (le32toh(elroy_read32(&r->busnum)) & 0xff) >> 4; */
1314  	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
1315 
1316 	config_found(self, &pba, pcibusprint, CFARG_EOL);
1317 }
1318