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
49int	elroy_match(device_t, cfdata_t, void *);
50void	elroy_attach(device_t, device_t, void *);
51
52CFATTACH_DECL_NEW(elroy, sizeof(struct elroy_softc), elroy_match, elroy_attach,
53    NULL, NULL);
54
55extern struct cfdriver elroy_cd;
56
57void elroy_write32(volatile uint32_t *, uint32_t);
58uint32_t elroy_read32(volatile uint32_t *);
59void elroy_attach_hook(device_t, device_t, struct pcibus_attach_args *);
60int elroy_maxdevs(void *, int);
61pcitag_t elroy_make_tag(void *, int, int, int);
62void elroy_decompose_tag(void *, pcitag_t, int *, int *, int *);
63pcireg_t elroy_conf_read(void *, pcitag_t, int);
64void elroy_conf_write(void *, pcitag_t, int, pcireg_t);
65
66int elroy_iomap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *);
67int elroy_memmap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *);
68int elroy_subregion(void *, bus_space_handle_t, bus_size_t, bus_size_t,
69    bus_space_handle_t *);
70int 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 *);
72int 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 *);
74void elroy_unmap(void *, bus_space_handle_t, bus_size_t);
75void elroy_free(void *, bus_space_handle_t, bus_size_t);
76void elroy_barrier(void *, bus_space_handle_t, bus_size_t, bus_size_t, int);
77void *elroy_alloc_parent(device_t, struct pci_attach_args *, int);
78void *elroy_vaddr(void *, bus_space_handle_t);
79paddr_t elroy_mmap(void *, bus_addr_t, off_t, int, int);
80
81uint8_t elroy_r1(void *, bus_space_handle_t, bus_size_t);
82uint16_t elroy_r2(void *, bus_space_handle_t, bus_size_t);
83uint32_t elroy_r4(void *, bus_space_handle_t, bus_size_t);
84uint64_t elroy_r8(void *, bus_space_handle_t, bus_size_t);
85uint16_t elroy_rs2(void *, bus_space_handle_t, bus_size_t);
86uint32_t elroy_rs4(void *, bus_space_handle_t, bus_size_t);
87uint64_t elroy_rs8(void *, bus_space_handle_t, bus_size_t);
88void elroy_w1(void *, bus_space_handle_t, bus_size_t, uint8_t);
89void elroy_w2(void *, bus_space_handle_t, bus_size_t, uint16_t);
90void elroy_w4(void *, bus_space_handle_t, bus_size_t, uint32_t);
91void elroy_w8(void *, bus_space_handle_t, bus_size_t, uint64_t);
92void elroy_ws2(void *, bus_space_handle_t, bus_size_t, uint16_t);
93void elroy_ws4(void *, bus_space_handle_t, bus_size_t, uint32_t);
94void elroy_ws8(void *, bus_space_handle_t, bus_size_t, uint64_t);
95
96void elroy_rm_1(void *, bus_space_handle_t, bus_size_t, uint8_t *,
97    bus_size_t);
98void elroy_rm_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
99    bus_size_t);
100void elroy_rm_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
101    bus_size_t);
102void elroy_rm_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
103    bus_size_t);
104void elroy_wm_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *,
105    bus_size_t);
106void elroy_wm_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
107    bus_size_t);
108void elroy_wm_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
109    bus_size_t);
110void elroy_wm_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
111    bus_size_t);
112void elroy_sm_1(void *, bus_space_handle_t, bus_size_t, uint8_t,
113    bus_size_t);
114void elroy_sm_2(void *, bus_space_handle_t, bus_size_t, uint16_t,
115    bus_size_t);
116void elroy_sm_4(void *, bus_space_handle_t, bus_size_t, uint32_t,
117    bus_size_t);
118void elroy_sm_8(void *, bus_space_handle_t, bus_size_t, uint64_t,
119    bus_size_t);
120
121void elroy_rrm_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
122    bus_size_t);
123void elroy_rrm_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
124    bus_size_t);
125void elroy_rrm_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
126    bus_size_t);
127void elroy_wrm_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
128    bus_size_t);
129void elroy_wrm_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
130    bus_size_t);
131void elroy_wrm_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
132    bus_size_t);
133void elroy_rr_1(void *, bus_space_handle_t, bus_size_t, uint8_t *,
134    bus_size_t);
135void elroy_rr_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
136    bus_size_t);
137void elroy_rr_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
138    bus_size_t);
139void elroy_rr_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
140    bus_size_t);
141void elroy_wr_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *,
142    bus_size_t);
143void elroy_wr_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
144    bus_size_t);
145void elroy_wr_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
146    bus_size_t);
147void elroy_wr_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
148    bus_size_t);
149
150void elroy_rrr_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
151    bus_size_t);
152void elroy_rrr_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
153    bus_size_t);
154void elroy_rrr_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
155    bus_size_t);
156void elroy_wrr_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
157    bus_size_t);
158void elroy_wrr_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
159    bus_size_t);
160void elroy_wrr_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
161    bus_size_t);
162void elroy_sr_1(void *, bus_space_handle_t, bus_size_t, uint8_t,
163    bus_size_t);
164void elroy_sr_2(void *, bus_space_handle_t, bus_size_t, uint16_t,
165    bus_size_t);
166void elroy_sr_4(void *, bus_space_handle_t, bus_size_t, uint32_t,
167    bus_size_t);
168void elroy_sr_8(void *, bus_space_handle_t, bus_size_t, uint64_t,
169    bus_size_t);
170void elroy_cp_1(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
171    bus_size_t, bus_size_t);
172void elroy_cp_2(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
173    bus_size_t, bus_size_t);
174void elroy_cp_4(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
175    bus_size_t, bus_size_t);
176void elroy_cp_8(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
177    bus_size_t, bus_size_t);
178
179int elroy_dmamap_create(void *, bus_size_t, int, bus_size_t, bus_size_t,
180    int, bus_dmamap_t *);
181void elroy_dmamap_destroy(void *, bus_dmamap_t);
182int elroy_dmamap_load(void *, bus_dmamap_t, void *, bus_size_t,
183    struct proc *, int);
184int elroy_dmamap_load_mbuf(void *, bus_dmamap_t, struct mbuf *, int);
185int elroy_dmamap_load_uio(void *, bus_dmamap_t, struct uio *, int);
186int elroy_dmamap_load_raw(void *, bus_dmamap_t, bus_dma_segment_t *,
187    int, bus_size_t, int);
188void elroy_dmamap_unload(void *, bus_dmamap_t);
189void elroy_dmamap_sync(void *, bus_dmamap_t, bus_addr_t, bus_size_t,
190    int);
191int elroy_dmamem_alloc(void *, bus_size_t, bus_size_t, bus_size_t,
192    bus_dma_segment_t *, int, int *, int);
193void elroy_dmamem_free(void *, bus_dma_segment_t *, int);
194int elroy_dmamem_map(void *, bus_dma_segment_t *, int, size_t,
195    void **, int);
196void elroy_dmamem_unmap(void *, void *, size_t);
197paddr_t elroy_dmamem_mmap(void *, bus_dma_segment_t *, int, off_t,
198    int, int);
199
200int
201elroy_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
214void
215elroy_write32(volatile uint32_t *p, uint32_t v)
216{
217	*p = v;
218}
219
220uint32_t
221elroy_read32(volatile uint32_t *p)
222{
223	return *p;
224}
225
226void
227elroy_attach_hook(device_t parent, device_t self,
228    struct pcibus_attach_args *pba)
229{
230
231}
232
233int
234elroy_maxdevs(void *v, int bus)
235{
236	return (32);
237}
238
239pcitag_t
240elroy_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
248void
249elroy_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
256pcireg_t
257elroy_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
295void
296elroy_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
335int
336elroy_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
350int
351elroy_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
364int
365elroy_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
372int
373elroy_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
395int
396elroy_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
410void
411elroy_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
418void
419elroy_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
425void
426elroy_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
439void *
440elroy_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
494void *
495elroy_vaddr(void *v, bus_space_handle_t h)
496{
497	return ((void *)h);
498}
499
500paddr_t
501elroy_mmap(void *v, bus_addr_t addr, off_t off, int prot, int flags)
502{
503
504	return -1;
505}
506
507uint8_t
508elroy_r1(void *v, bus_space_handle_t h, bus_size_t o)
509{
510	h += o;
511	return *(volatile uint8_t *)h;
512}
513
514uint16_t
515elroy_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
524uint32_t
525elroy_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
534uint64_t
535elroy_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
544uint16_t
545elroy_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
554uint32_t
555elroy_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
564uint64_t
565elroy_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
574void
575elroy_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
581void
582elroy_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
591void
592elroy_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
599void
600elroy_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
606void
607elroy_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
616void
617elroy_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
623void
624elroy_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
630void
631elroy_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
641void
642elroy_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
652void
653elroy_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
663void
664elroy_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
674void
675elroy_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
685void
686elroy_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
696void
697elroy_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
707void
708elroy_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
718void
719elroy_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
729void
730elroy_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
741void
742elroy_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
753void
754elroy_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
765void
766elroy_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
777void
778elroy_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
789void
790elroy_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
801void
802elroy_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
814void
815elroy_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
827void
828elroy_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
840void
841elroy_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
851void
852elroy_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
864void
865elroy_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
877void
878elroy_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
890void
891elroy_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
901void
902elroy_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
914void
915elroy_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
927void
928elroy_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
940void
941elroy_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
952void
953elroy_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
964void
965elroy_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
976void
977elroy_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
989void
990elroy_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
1002void
1003elroy_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
1015void
1016elroy_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
1026void
1027elroy_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
1038void
1039elroy_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
1050void
1051elroy_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
1062void
1063elroy_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
1070void
1071elroy_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
1081void
1082elroy_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
1092void
1093elroy_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
1103const 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
1125int
1126elroy_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
1137void
1138elroy_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
1145int
1146elroy_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
1154int
1155elroy_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
1162int
1163elroy_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
1170int
1171elroy_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
1179void
1180elroy_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
1187void
1188elroy_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
1196int
1197elroy_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
1207void
1208elroy_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
1215int
1216elroy_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
1224void
1225elroy_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
1232paddr_t
1233elroy_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
1241const 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
1252const 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
1268void
1269elroy_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
1346printf("lmm %llx/%llx gmm %llx/%llx wlm %llx/%llx wgm %llx/%llx io %llx/%llx eio %llx/%llx\n",
1347le64toh(r->lmmio_base), le64toh(r->lmmio_mask),
1348le64toh(r->gmmio_base), le64toh(r->gmmio_mask),
1349le64toh(r->wlmmio_base), le64toh(r->wlmmio_mask),
1350le64toh(r->wgmmio_base), le64toh(r->wgmmio_mask),
1351le64toh(r->io_base), le64toh(r->io_mask),
1352le64toh(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