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