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