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