xref: /netbsd-src/sys/arch/hppa/dev/elroy.c (revision 03ccf6a52a8b237aeab75af8fd07ee29759e298a)
1*03ccf6a5Sskrll /*	$NetBSD: elroy.c,v 1.9 2024/12/29 07:51:25 skrll Exp $	*/
26d3ceb1dSskrll 
36d3ceb1dSskrll /*	$OpenBSD: elroy.c,v 1.5 2009/03/30 21:24:57 kettenis Exp $	*/
46d3ceb1dSskrll 
56d3ceb1dSskrll /*
66d3ceb1dSskrll  * Copyright (c) 2005 Michael Shalayeff
76d3ceb1dSskrll  * All rights reserved.
86d3ceb1dSskrll  *
96d3ceb1dSskrll  * Permission to use, copy, modify, and distribute this software for any
106d3ceb1dSskrll  * purpose with or without fee is hereby granted, provided that the above
116d3ceb1dSskrll  * copyright notice and this permission notice appear in all copies.
126d3ceb1dSskrll  *
136d3ceb1dSskrll  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
146d3ceb1dSskrll  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
156d3ceb1dSskrll  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
166d3ceb1dSskrll  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
176d3ceb1dSskrll  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
186d3ceb1dSskrll  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
196d3ceb1dSskrll  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
206d3ceb1dSskrll  */
216d3ceb1dSskrll 
226d3ceb1dSskrll /* #include "cardbus.h" */
236d3ceb1dSskrll 
246d3ceb1dSskrll #include <sys/param.h>
256d3ceb1dSskrll #include <sys/systm.h>
266d3ceb1dSskrll #include <sys/device.h>
276d3ceb1dSskrll #include <sys/reboot.h>
286d3ceb1dSskrll #include <sys/extent.h>
296d3ceb1dSskrll 
306d3ceb1dSskrll #include <machine/iomod.h>
316d3ceb1dSskrll #include <machine/autoconf.h>
326d3ceb1dSskrll 
336d3ceb1dSskrll #include <hppa/dev/cpudevs.h>
346d3ceb1dSskrll 
356d3ceb1dSskrll #if NCARDBUS > 0
366d3ceb1dSskrll #include <dev/cardbus/rbus.h>
376d3ceb1dSskrll #endif
386d3ceb1dSskrll 
396d3ceb1dSskrll #include <dev/pci/pcireg.h>
406d3ceb1dSskrll #include <dev/pci/pcivar.h>
416d3ceb1dSskrll #include <dev/pci/pcidevs.h>
426d3ceb1dSskrll 
436d3ceb1dSskrll #include <hppa/dev/elroyreg.h>
446d3ceb1dSskrll #include <hppa/dev/elroyvar.h>
456d3ceb1dSskrll 
466d3ceb1dSskrll #define	ELROY_MEM_CHUNK		0x800000
476d3ceb1dSskrll #define	ELROY_MEM_WINDOW	(2 * ELROY_MEM_CHUNK)
486d3ceb1dSskrll 
496d3ceb1dSskrll int	elroy_match(device_t, cfdata_t, void *);
506d3ceb1dSskrll void	elroy_attach(device_t, device_t, void *);
516d3ceb1dSskrll 
526d3ceb1dSskrll CFATTACH_DECL_NEW(elroy, sizeof(struct elroy_softc), elroy_match, elroy_attach,
536d3ceb1dSskrll     NULL, NULL);
546d3ceb1dSskrll 
556d3ceb1dSskrll extern struct cfdriver elroy_cd;
566d3ceb1dSskrll 
576d3ceb1dSskrll void elroy_write32(volatile uint32_t *, uint32_t);
586d3ceb1dSskrll uint32_t elroy_read32(volatile uint32_t *);
596d3ceb1dSskrll void elroy_attach_hook(device_t, device_t, struct pcibus_attach_args *);
606d3ceb1dSskrll int elroy_maxdevs(void *, int);
616d3ceb1dSskrll pcitag_t elroy_make_tag(void *, int, int, int);
626d3ceb1dSskrll void elroy_decompose_tag(void *, pcitag_t, int *, int *, int *);
636d3ceb1dSskrll pcireg_t elroy_conf_read(void *, pcitag_t, int);
646d3ceb1dSskrll void elroy_conf_write(void *, pcitag_t, int, pcireg_t);
656d3ceb1dSskrll 
666d3ceb1dSskrll int elroy_iomap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *);
676d3ceb1dSskrll int elroy_memmap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *);
686d3ceb1dSskrll int elroy_subregion(void *, bus_space_handle_t, bus_size_t, bus_size_t,
696d3ceb1dSskrll     bus_space_handle_t *);
706d3ceb1dSskrll int elroy_ioalloc(void *, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t,
716d3ceb1dSskrll     bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
726d3ceb1dSskrll int elroy_memalloc(void *, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t,
736d3ceb1dSskrll     bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
746d3ceb1dSskrll void elroy_unmap(void *, bus_space_handle_t, bus_size_t);
756d3ceb1dSskrll void elroy_free(void *, bus_space_handle_t, bus_size_t);
766d3ceb1dSskrll void elroy_barrier(void *, bus_space_handle_t, bus_size_t, bus_size_t, int);
776d3ceb1dSskrll void *elroy_alloc_parent(device_t, struct pci_attach_args *, int);
786d3ceb1dSskrll void *elroy_vaddr(void *, bus_space_handle_t);
796d3ceb1dSskrll paddr_t elroy_mmap(void *, bus_addr_t, off_t, int, int);
806d3ceb1dSskrll 
816d3ceb1dSskrll uint8_t elroy_r1(void *, bus_space_handle_t, bus_size_t);
826d3ceb1dSskrll uint16_t elroy_r2(void *, bus_space_handle_t, bus_size_t);
836d3ceb1dSskrll uint32_t elroy_r4(void *, bus_space_handle_t, bus_size_t);
846d3ceb1dSskrll uint64_t elroy_r8(void *, bus_space_handle_t, bus_size_t);
85dbeed521Smacallan uint16_t elroy_rs2(void *, bus_space_handle_t, bus_size_t);
86dbeed521Smacallan uint32_t elroy_rs4(void *, bus_space_handle_t, bus_size_t);
87dbeed521Smacallan uint64_t elroy_rs8(void *, bus_space_handle_t, bus_size_t);
886d3ceb1dSskrll void elroy_w1(void *, bus_space_handle_t, bus_size_t, uint8_t);
896d3ceb1dSskrll void elroy_w2(void *, bus_space_handle_t, bus_size_t, uint16_t);
906d3ceb1dSskrll void elroy_w4(void *, bus_space_handle_t, bus_size_t, uint32_t);
916d3ceb1dSskrll void elroy_w8(void *, bus_space_handle_t, bus_size_t, uint64_t);
92dbeed521Smacallan void elroy_ws2(void *, bus_space_handle_t, bus_size_t, uint16_t);
93dbeed521Smacallan void elroy_ws4(void *, bus_space_handle_t, bus_size_t, uint32_t);
94dbeed521Smacallan void elroy_ws8(void *, bus_space_handle_t, bus_size_t, uint64_t);
956d3ceb1dSskrll 
966d3ceb1dSskrll void elroy_rm_1(void *, bus_space_handle_t, bus_size_t, uint8_t *,
976d3ceb1dSskrll     bus_size_t);
986d3ceb1dSskrll void elroy_rm_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
996d3ceb1dSskrll     bus_size_t);
1006d3ceb1dSskrll void elroy_rm_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
1016d3ceb1dSskrll     bus_size_t);
1026d3ceb1dSskrll void elroy_rm_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
1036d3ceb1dSskrll     bus_size_t);
1046d3ceb1dSskrll void elroy_wm_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *,
1056d3ceb1dSskrll     bus_size_t);
1066d3ceb1dSskrll void elroy_wm_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
1076d3ceb1dSskrll     bus_size_t);
1086d3ceb1dSskrll void elroy_wm_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
1096d3ceb1dSskrll     bus_size_t);
1106d3ceb1dSskrll void elroy_wm_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
1116d3ceb1dSskrll     bus_size_t);
1126d3ceb1dSskrll void elroy_sm_1(void *, bus_space_handle_t, bus_size_t, uint8_t,
1136d3ceb1dSskrll     bus_size_t);
1146d3ceb1dSskrll void elroy_sm_2(void *, bus_space_handle_t, bus_size_t, uint16_t,
1156d3ceb1dSskrll     bus_size_t);
1166d3ceb1dSskrll void elroy_sm_4(void *, bus_space_handle_t, bus_size_t, uint32_t,
1176d3ceb1dSskrll     bus_size_t);
1186d3ceb1dSskrll void elroy_sm_8(void *, bus_space_handle_t, bus_size_t, uint64_t,
1196d3ceb1dSskrll     bus_size_t);
1206d3ceb1dSskrll 
1216d3ceb1dSskrll void elroy_rrm_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
1226d3ceb1dSskrll     bus_size_t);
1236d3ceb1dSskrll void elroy_rrm_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
1246d3ceb1dSskrll     bus_size_t);
1256d3ceb1dSskrll void elroy_rrm_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
1266d3ceb1dSskrll     bus_size_t);
1276d3ceb1dSskrll void elroy_wrm_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
1286d3ceb1dSskrll     bus_size_t);
1296d3ceb1dSskrll void elroy_wrm_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
1306d3ceb1dSskrll     bus_size_t);
1316d3ceb1dSskrll void elroy_wrm_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
1326d3ceb1dSskrll     bus_size_t);
1336d3ceb1dSskrll void elroy_rr_1(void *, bus_space_handle_t, bus_size_t, uint8_t *,
1346d3ceb1dSskrll     bus_size_t);
1356d3ceb1dSskrll void elroy_rr_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
1366d3ceb1dSskrll     bus_size_t);
1376d3ceb1dSskrll void elroy_rr_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
1386d3ceb1dSskrll     bus_size_t);
1396d3ceb1dSskrll void elroy_rr_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
1406d3ceb1dSskrll     bus_size_t);
1416d3ceb1dSskrll void elroy_wr_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *,
1426d3ceb1dSskrll     bus_size_t);
1436d3ceb1dSskrll void elroy_wr_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
1446d3ceb1dSskrll     bus_size_t);
1456d3ceb1dSskrll void elroy_wr_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
1466d3ceb1dSskrll     bus_size_t);
1476d3ceb1dSskrll void elroy_wr_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
1486d3ceb1dSskrll     bus_size_t);
1496d3ceb1dSskrll 
1506d3ceb1dSskrll void elroy_rrr_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
1516d3ceb1dSskrll     bus_size_t);
1526d3ceb1dSskrll void elroy_rrr_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
1536d3ceb1dSskrll     bus_size_t);
1546d3ceb1dSskrll void elroy_rrr_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
1556d3ceb1dSskrll     bus_size_t);
1566d3ceb1dSskrll void elroy_wrr_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
1576d3ceb1dSskrll     bus_size_t);
1586d3ceb1dSskrll void elroy_wrr_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
1596d3ceb1dSskrll     bus_size_t);
1606d3ceb1dSskrll void elroy_wrr_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
1616d3ceb1dSskrll     bus_size_t);
1626d3ceb1dSskrll void elroy_sr_1(void *, bus_space_handle_t, bus_size_t, uint8_t,
1636d3ceb1dSskrll     bus_size_t);
1646d3ceb1dSskrll void elroy_sr_2(void *, bus_space_handle_t, bus_size_t, uint16_t,
1656d3ceb1dSskrll     bus_size_t);
1666d3ceb1dSskrll void elroy_sr_4(void *, bus_space_handle_t, bus_size_t, uint32_t,
1676d3ceb1dSskrll     bus_size_t);
1686d3ceb1dSskrll void elroy_sr_8(void *, bus_space_handle_t, bus_size_t, uint64_t,
1696d3ceb1dSskrll     bus_size_t);
1706d3ceb1dSskrll void elroy_cp_1(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
1716d3ceb1dSskrll     bus_size_t, bus_size_t);
1726d3ceb1dSskrll void elroy_cp_2(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
1736d3ceb1dSskrll     bus_size_t, bus_size_t);
1746d3ceb1dSskrll void elroy_cp_4(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
1756d3ceb1dSskrll     bus_size_t, bus_size_t);
1766d3ceb1dSskrll void elroy_cp_8(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
1776d3ceb1dSskrll     bus_size_t, bus_size_t);
1786d3ceb1dSskrll 
1796d3ceb1dSskrll int elroy_dmamap_create(void *, bus_size_t, int, bus_size_t, bus_size_t,
1806d3ceb1dSskrll     int, bus_dmamap_t *);
1816d3ceb1dSskrll void elroy_dmamap_destroy(void *, bus_dmamap_t);
1826d3ceb1dSskrll int elroy_dmamap_load(void *, bus_dmamap_t, void *, bus_size_t,
1836d3ceb1dSskrll     struct proc *, int);
1846d3ceb1dSskrll int elroy_dmamap_load_mbuf(void *, bus_dmamap_t, struct mbuf *, int);
1856d3ceb1dSskrll int elroy_dmamap_load_uio(void *, bus_dmamap_t, struct uio *, int);
1866d3ceb1dSskrll int elroy_dmamap_load_raw(void *, bus_dmamap_t, bus_dma_segment_t *,
1876d3ceb1dSskrll     int, bus_size_t, int);
1886d3ceb1dSskrll void elroy_dmamap_unload(void *, bus_dmamap_t);
1896d3ceb1dSskrll void elroy_dmamap_sync(void *, bus_dmamap_t, bus_addr_t, bus_size_t,
1906d3ceb1dSskrll     int);
1916d3ceb1dSskrll int elroy_dmamem_alloc(void *, bus_size_t, bus_size_t, bus_size_t,
1926d3ceb1dSskrll     bus_dma_segment_t *, int, int *, int);
1936d3ceb1dSskrll void elroy_dmamem_free(void *, bus_dma_segment_t *, int);
1946d3ceb1dSskrll int elroy_dmamem_map(void *, bus_dma_segment_t *, int, size_t,
1956d3ceb1dSskrll     void **, int);
1966d3ceb1dSskrll void elroy_dmamem_unmap(void *, void *, size_t);
1976d3ceb1dSskrll paddr_t elroy_dmamem_mmap(void *, bus_dma_segment_t *, int, off_t,
1986d3ceb1dSskrll     int, int);
1996d3ceb1dSskrll 
2006d3ceb1dSskrll int
2016d3ceb1dSskrll elroy_match(device_t parent, cfdata_t cf, void *aux)
2026d3ceb1dSskrll {
2036d3ceb1dSskrll 	struct confargs *ca = aux;
2046d3ceb1dSskrll 
2056d3ceb1dSskrll 	if ((ca->ca_name && !strcmp(ca->ca_name, "lba")) ||
2066d3ceb1dSskrll 	    (ca->ca_type.iodc_type == HPPA_TYPE_BRIDGE &&
2076d3ceb1dSskrll 	     ca->ca_type.iodc_sv_model == HPPA_BRIDGE_DINO &&
2086d3ceb1dSskrll 	     ca->ca_type.iodc_model == 0x78))
209*03ccf6a5Sskrll 		return 1;
2106d3ceb1dSskrll 
211*03ccf6a5Sskrll 	return 0;
2126d3ceb1dSskrll }
2136d3ceb1dSskrll 
2146d3ceb1dSskrll void
2156d3ceb1dSskrll elroy_write32(volatile uint32_t *p, uint32_t v)
2166d3ceb1dSskrll {
2176d3ceb1dSskrll 	*p = v;
2186d3ceb1dSskrll }
2196d3ceb1dSskrll 
2206d3ceb1dSskrll uint32_t
2216d3ceb1dSskrll elroy_read32(volatile uint32_t *p)
2226d3ceb1dSskrll {
2236d3ceb1dSskrll 	return *p;
2246d3ceb1dSskrll }
2256d3ceb1dSskrll 
2266d3ceb1dSskrll void
2276d3ceb1dSskrll elroy_attach_hook(device_t parent, device_t self,
2286d3ceb1dSskrll     struct pcibus_attach_args *pba)
2296d3ceb1dSskrll {
2306d3ceb1dSskrll 
2316d3ceb1dSskrll }
2326d3ceb1dSskrll 
2336d3ceb1dSskrll int
2346d3ceb1dSskrll elroy_maxdevs(void *v, int bus)
2356d3ceb1dSskrll {
236*03ccf6a5Sskrll 	return 32;
2376d3ceb1dSskrll }
2386d3ceb1dSskrll 
2396d3ceb1dSskrll pcitag_t
2406d3ceb1dSskrll elroy_make_tag(void *v, int bus, int dev, int func)
2416d3ceb1dSskrll {
2426d3ceb1dSskrll 	if (bus > 255 || dev > 31 || func > 7)
2436d3ceb1dSskrll 		panic("elroy_make_tag: bad request");
2446d3ceb1dSskrll 
245*03ccf6a5Sskrll 	return (bus << 16) | (dev << 11) | (func << 8);
2466d3ceb1dSskrll }
2476d3ceb1dSskrll 
2486d3ceb1dSskrll void
2496d3ceb1dSskrll elroy_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func)
2506d3ceb1dSskrll {
2516d3ceb1dSskrll 	*bus = (tag >> 16) & 0xff;
2526d3ceb1dSskrll 	*dev = (tag >> 11) & 0x1f;
2536d3ceb1dSskrll 	*func= (tag >>  8) & 0x07;
2546d3ceb1dSskrll }
2556d3ceb1dSskrll 
2566d3ceb1dSskrll pcireg_t
2576d3ceb1dSskrll elroy_conf_read(void *v, pcitag_t tag, int reg)
2586d3ceb1dSskrll {
2596d3ceb1dSskrll 	struct elroy_softc *sc = v;
2606d3ceb1dSskrll 	volatile struct elroy_regs *r = sc->sc_regs;
2616d3ceb1dSskrll 	uint32_t arb_mask, err_cfg, control;
2626d3ceb1dSskrll 	pcireg_t data;
2636d3ceb1dSskrll 
2646d3ceb1dSskrll /* printf("elroy_conf_read(%p, 0x%08x, 0x%x)", v, tag, reg); */
265605f564fSmsaitoh 
266605f564fSmsaitoh 	if ((unsigned int)reg >= PCI_CONF_SIZE)
267*03ccf6a5Sskrll 		return (pcireg_t) -1;
268605f564fSmsaitoh 
2696d3ceb1dSskrll 	arb_mask = elroy_read32(&r->arb_mask);
2706d3ceb1dSskrll 	err_cfg = elroy_read32(&r->err_cfg);
2716d3ceb1dSskrll 	control = elroy_read32(&r->control);
2726d3ceb1dSskrll 	if (!arb_mask)
2736d3ceb1dSskrll 		elroy_write32(&r->arb_mask, htole32(ELROY_ARB_ENABLE));
2746d3ceb1dSskrll 	elroy_write32(&r->err_cfg, err_cfg |
2756d3ceb1dSskrll 	    htole32(ELROY_ERRCFG_SMART | ELROY_ERRCFG_CM));
2766d3ceb1dSskrll 	elroy_write32(&r->control, (control | htole32(ELROY_CONTROL_CE)) &
2776d3ceb1dSskrll 	    ~htole32(ELROY_CONTROL_HF));
2786d3ceb1dSskrll 
2796d3ceb1dSskrll 	elroy_write32(&r->pci_conf_addr, htole32(tag | reg));
2806d3ceb1dSskrll 	(void)elroy_read32(&r->pci_conf_addr);
2816d3ceb1dSskrll 	data = elroy_read32(&r->pci_conf_data);
2826d3ceb1dSskrll 
2836d3ceb1dSskrll 	elroy_write32(&r->control, control |
2846d3ceb1dSskrll 	    htole32(ELROY_CONTROL_CE|ELROY_CONTROL_CL));
2856d3ceb1dSskrll 	elroy_write32(&r->control, control);
2866d3ceb1dSskrll 	elroy_write32(&r->err_cfg, err_cfg);
2876d3ceb1dSskrll 	if (!arb_mask)
2886d3ceb1dSskrll 		elroy_write32(&r->arb_mask, arb_mask);
2896d3ceb1dSskrll 
2906d3ceb1dSskrll 	data = le32toh(data);
2916d3ceb1dSskrll /* printf("=0x%08x (@ 0x%08x)\n", data, le32toh(data1)); */
292*03ccf6a5Sskrll 	return data;
2936d3ceb1dSskrll }
2946d3ceb1dSskrll 
2956d3ceb1dSskrll void
2966d3ceb1dSskrll elroy_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
2976d3ceb1dSskrll {
2986d3ceb1dSskrll 	struct elroy_softc *sc = v;
2996d3ceb1dSskrll 	volatile struct elroy_regs *r = sc->sc_regs;
3006d3ceb1dSskrll 	uint32_t arb_mask, err_cfg, control;
3016d3ceb1dSskrll 
3026d3ceb1dSskrll /* printf("elroy_conf_write(%p, 0x%08x, 0x%x, 0x%x)\n", v, tag, reg, data); */
303605f564fSmsaitoh 
304605f564fSmsaitoh 	if ((unsigned int)reg >= PCI_CONF_SIZE)
305605f564fSmsaitoh 		return;
306605f564fSmsaitoh 
3076d3ceb1dSskrll 	arb_mask = elroy_read32(&r->arb_mask);
3086d3ceb1dSskrll 	err_cfg = elroy_read32(&r->err_cfg);
3096d3ceb1dSskrll 	control = elroy_read32(&r->control);
3106d3ceb1dSskrll 	if (!arb_mask)
3116d3ceb1dSskrll 		elroy_write32(&r->arb_mask, htole32(ELROY_ARB_ENABLE));
3126d3ceb1dSskrll 	elroy_write32(&r->err_cfg, err_cfg |
3136d3ceb1dSskrll 	    htole32(ELROY_ERRCFG_SMART | ELROY_ERRCFG_CM));
3146d3ceb1dSskrll 	elroy_write32(&r->control, (control | htole32(ELROY_CONTROL_CE)) &
3156d3ceb1dSskrll 	    ~htole32(ELROY_CONTROL_HF));
3166d3ceb1dSskrll 
3176d3ceb1dSskrll 	/* fix coalescing config writes errata by interleaving w/ a read */
3186d3ceb1dSskrll 	elroy_write32(&r->pci_conf_addr, htole32(tag | PCI_ID_REG));
3196d3ceb1dSskrll 	(void)elroy_read32(&r->pci_conf_addr);
3206d3ceb1dSskrll 	(void)elroy_read32(&r->pci_conf_data);
3216d3ceb1dSskrll 
3226d3ceb1dSskrll 	elroy_write32(&r->pci_conf_addr, htole32(tag | reg));
3236d3ceb1dSskrll 	(void)elroy_read32(&r->pci_conf_addr);
3246d3ceb1dSskrll 	elroy_write32(&r->pci_conf_data, htole32(data));
3256d3ceb1dSskrll 	(void)elroy_read32(&r->pci_conf_addr);
3266d3ceb1dSskrll 
3276d3ceb1dSskrll 	elroy_write32(&r->control, control |
3286d3ceb1dSskrll 	    htole32(ELROY_CONTROL_CE|ELROY_CONTROL_CL));
3296d3ceb1dSskrll 	elroy_write32(&r->control, control);
3306d3ceb1dSskrll 	elroy_write32(&r->err_cfg, err_cfg);
3316d3ceb1dSskrll 	if (!arb_mask)
3326d3ceb1dSskrll 		elroy_write32(&r->arb_mask, arb_mask);
3336d3ceb1dSskrll }
3346d3ceb1dSskrll 
3356d3ceb1dSskrll int
3366d3ceb1dSskrll elroy_iomap(void *v, bus_addr_t bpa, bus_size_t size,
3376d3ceb1dSskrll     int flags, bus_space_handle_t *bshp)
3386d3ceb1dSskrll {
3396d3ceb1dSskrll 	struct elroy_softc *sc = v;
3406d3ceb1dSskrll 	/* volatile struct elroy_regs *r = sc->sc_regs; */
3416d3ceb1dSskrll 	int error;
3426d3ceb1dSskrll 
3436d3ceb1dSskrll 	if ((error = bus_space_map(sc->sc_bt, bpa + sc->sc_iobase, size,
3446d3ceb1dSskrll 	    flags, bshp)))
345*03ccf6a5Sskrll 		return error;
3466d3ceb1dSskrll 
347*03ccf6a5Sskrll 	return 0;
3486d3ceb1dSskrll }
3496d3ceb1dSskrll 
3506d3ceb1dSskrll int
3516d3ceb1dSskrll elroy_memmap(void *v, bus_addr_t bpa, bus_size_t size,
3526d3ceb1dSskrll     int flags, bus_space_handle_t *bshp)
3536d3ceb1dSskrll {
3546d3ceb1dSskrll 	struct elroy_softc *sc = v;
3556d3ceb1dSskrll 	/* volatile struct elroy_regs *r = sc->sc_regs; */
3566d3ceb1dSskrll 	int error;
3576d3ceb1dSskrll 
3586d3ceb1dSskrll 	if ((error = bus_space_map(sc->sc_bt, bpa, size, flags, bshp)))
359*03ccf6a5Sskrll 		return error;
3606d3ceb1dSskrll 
361*03ccf6a5Sskrll 	return 0;
3626d3ceb1dSskrll }
3636d3ceb1dSskrll 
3646d3ceb1dSskrll int
3656d3ceb1dSskrll elroy_subregion(void *v, bus_space_handle_t bsh, bus_size_t offset,
3666d3ceb1dSskrll     bus_size_t size, bus_space_handle_t *nbshp)
3676d3ceb1dSskrll {
3686d3ceb1dSskrll 	*nbshp = bsh + offset;
369*03ccf6a5Sskrll 	return 0;
3706d3ceb1dSskrll }
3716d3ceb1dSskrll 
3726d3ceb1dSskrll int
3736d3ceb1dSskrll elroy_ioalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
3746d3ceb1dSskrll     bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
3756d3ceb1dSskrll     bus_space_handle_t *bshp)
3766d3ceb1dSskrll {
3776d3ceb1dSskrll 	struct elroy_softc *sc = v;
3786d3ceb1dSskrll 	volatile struct elroy_regs *r = sc->sc_regs;
3796d3ceb1dSskrll 	bus_addr_t iostart, ioend;
3806d3ceb1dSskrll 
3816d3ceb1dSskrll 	iostart = r->io_base & ~htole32(ELROY_BASE_RE);
3826d3ceb1dSskrll 	ioend = iostart + ~htole32(r->io_mask) + 1;
3836d3ceb1dSskrll 	if (rstart < iostart || rend > ioend)
3846d3ceb1dSskrll 		panic("elroy_ioalloc: bad region start/end");
3856d3ceb1dSskrll 
3866d3ceb1dSskrll 	rstart += sc->sc_iobase;
3876d3ceb1dSskrll 	rend += sc->sc_iobase;
3886d3ceb1dSskrll 	if (bus_space_alloc(sc->sc_bt, rstart, rend, size,
3896d3ceb1dSskrll 	    align, boundary, flags, addrp, bshp))
390*03ccf6a5Sskrll 		return ENOMEM;
3916d3ceb1dSskrll 
392*03ccf6a5Sskrll 	return 0;
3936d3ceb1dSskrll }
3946d3ceb1dSskrll 
3956d3ceb1dSskrll int
3966d3ceb1dSskrll elroy_memalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
3976d3ceb1dSskrll     bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
3986d3ceb1dSskrll     bus_space_handle_t *bshp)
3996d3ceb1dSskrll {
4006d3ceb1dSskrll 	struct elroy_softc *sc = v;
4016d3ceb1dSskrll 	/* volatile struct elroy_regs *r = sc->sc_regs; */
4026d3ceb1dSskrll 
4036d3ceb1dSskrll 	if (bus_space_alloc(sc->sc_bt, rstart, rend, size,
4046d3ceb1dSskrll 	    align, boundary, flags, addrp, bshp))
405*03ccf6a5Sskrll 		return ENOMEM;
4066d3ceb1dSskrll 
407*03ccf6a5Sskrll 	return 0;
4086d3ceb1dSskrll }
4096d3ceb1dSskrll 
4106d3ceb1dSskrll void
4116d3ceb1dSskrll elroy_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
4126d3ceb1dSskrll {
4136d3ceb1dSskrll 	struct elroy_softc *sc = v;
4146d3ceb1dSskrll 
4156d3ceb1dSskrll 	bus_space_free(sc->sc_bt, bsh, size);
4166d3ceb1dSskrll }
4176d3ceb1dSskrll 
4186d3ceb1dSskrll void
4196d3ceb1dSskrll elroy_free(void *v, bus_space_handle_t bh, bus_size_t size)
4206d3ceb1dSskrll {
4216d3ceb1dSskrll 	/* should be enough */
4226d3ceb1dSskrll 	elroy_unmap(v, bh, size);
4236d3ceb1dSskrll }
4246d3ceb1dSskrll 
4256d3ceb1dSskrll void
4266d3ceb1dSskrll elroy_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op)
4276d3ceb1dSskrll {
4286d3ceb1dSskrll 	struct elroy_softc *sc = v;
4296d3ceb1dSskrll 	volatile struct elroy_regs *r = sc->sc_regs;
4306d3ceb1dSskrll 
4316d3ceb1dSskrll 	sync_caches();
4326d3ceb1dSskrll 	if (op & BUS_SPACE_BARRIER_WRITE) {
4336d3ceb1dSskrll 		(void)r->pci_id;	/* flush write fifo */
4346d3ceb1dSskrll 		sync_caches();
4356d3ceb1dSskrll 	}
4366d3ceb1dSskrll }
4376d3ceb1dSskrll 
4386d3ceb1dSskrll #if NCARDBUS > 0
4396d3ceb1dSskrll void *
4406d3ceb1dSskrll elroy_alloc_parent(device_t self, struct pci_attach_args *pa, int io)
4416d3ceb1dSskrll {
4426d3ceb1dSskrll #if 0	/* TODO */
4436d3ceb1dSskrll 
4446d3ceb1dSskrll 	struct elroy_softc *sc = pa->pa_pc->_cookie;
4456d3ceb1dSskrll 	struct extent *ex;
4466d3ceb1dSskrll 	bus_space_tag_t tag;
4476d3ceb1dSskrll 	bus_addr_t start;
4486d3ceb1dSskrll 	bus_size_t size;
4496d3ceb1dSskrll 
4506d3ceb1dSskrll 	if (io) {
4516d3ceb1dSskrll 		ex = sc->sc_ioex;
4526d3ceb1dSskrll 		tag = pa->pa_iot;
4536d3ceb1dSskrll 		start = 0xa000;
4546d3ceb1dSskrll 		size = 0x1000;
4556d3ceb1dSskrll 	} else {
4566d3ceb1dSskrll 		if (!sc->sc_memex) {
4576d3ceb1dSskrll 			bus_space_handle_t memh;
4586d3ceb1dSskrll 			bus_addr_t mem_start;
4596d3ceb1dSskrll 
4606d3ceb1dSskrll 			if (elroy_memalloc(sc, 0xf0800000, 0xff7fffff,
4616d3ceb1dSskrll 			    ELROY_MEM_WINDOW, ELROY_MEM_WINDOW, EX_NOBOUNDARY,
4626d3ceb1dSskrll 			    0, &mem_start, &memh))
463*03ccf6a5Sskrll 				return NULL;
4646d3ceb1dSskrll 
4656d3ceb1dSskrll 			snprintf(sc->sc_memexname, sizeof(sc->sc_memexname),
4666d3ceb1dSskrll 			    "%s_mem", device_xname(sc->sc_dv));
4676d3ceb1dSskrll 			if ((sc->sc_memex = extent_create(sc->sc_memexname,
4686d3ceb1dSskrll 			    mem_start, mem_start + ELROY_MEM_WINDOW,
4696d3ceb1dSskrll 			    NULL, 0, EX_NOWAIT | EX_MALLOCOK)) == NULL) {
4706d3ceb1dSskrll 				extent_destroy(sc->sc_ioex);
4716d3ceb1dSskrll 				bus_space_free(sc->sc_bt, memh,
4726d3ceb1dSskrll 				    ELROY_MEM_WINDOW);
473*03ccf6a5Sskrll 				return NULL;
4746d3ceb1dSskrll 			}
4756d3ceb1dSskrll 		}
4766d3ceb1dSskrll 		ex = sc->sc_memex;
4776d3ceb1dSskrll 		tag = pa->pa_memt;
4786d3ceb1dSskrll 		start = ex->ex_start;
4796d3ceb1dSskrll 		size = ELROY_MEM_CHUNK;
4806d3ceb1dSskrll 	}
4816d3ceb1dSskrll 
4826d3ceb1dSskrll 	if (extent_alloc_subregion(ex, start, ex->ex_end, size, size, 0,
4836d3ceb1dSskrll 	    EX_NOBOUNDARY, EX_NOWAIT, &start))
484*03ccf6a5Sskrll 		return NULL;
4856d3ceb1dSskrll 
4866d3ceb1dSskrll 	extent_free(ex, start, size, EX_NOWAIT);
4876d3ceb1dSskrll 	return rbus_new_root_share(tag, ex, start, size, 0);
4886d3ceb1dSskrll #else
489*03ccf6a5Sskrll 	return NULL;
4906d3ceb1dSskrll #endif
4916d3ceb1dSskrll }
4926d3ceb1dSskrll #endif
4936d3ceb1dSskrll 
4946d3ceb1dSskrll void *
4956d3ceb1dSskrll elroy_vaddr(void *v, bus_space_handle_t h)
4966d3ceb1dSskrll {
497*03ccf6a5Sskrll 	return (void *)h;
4986d3ceb1dSskrll }
4996d3ceb1dSskrll 
5006d3ceb1dSskrll paddr_t
5016d3ceb1dSskrll elroy_mmap(void *v, bus_addr_t addr, off_t off, int prot, int flags)
5026d3ceb1dSskrll {
5037947237fSskrll 	return btop(addr + off);
5046d3ceb1dSskrll }
5056d3ceb1dSskrll 
5066d3ceb1dSskrll uint8_t
5076d3ceb1dSskrll elroy_r1(void *v, bus_space_handle_t h, bus_size_t o)
5086d3ceb1dSskrll {
5096d3ceb1dSskrll 	h += o;
5106d3ceb1dSskrll 	return *(volatile uint8_t *)h;
5116d3ceb1dSskrll }
5126d3ceb1dSskrll 
5136d3ceb1dSskrll uint16_t
5146d3ceb1dSskrll elroy_r2(void *v, bus_space_handle_t h, bus_size_t o)
5156d3ceb1dSskrll {
5166d3ceb1dSskrll 	volatile uint16_t *p;
5176d3ceb1dSskrll 
5186d3ceb1dSskrll 	h += o;
5196d3ceb1dSskrll 	p = (volatile uint16_t *)h;
520*03ccf6a5Sskrll 	return le16toh(*p);
5216d3ceb1dSskrll }
5226d3ceb1dSskrll 
5236d3ceb1dSskrll uint32_t
5246d3ceb1dSskrll elroy_r4(void *v, bus_space_handle_t h, bus_size_t o)
5256d3ceb1dSskrll {
5266d3ceb1dSskrll 	uint32_t data;
5276d3ceb1dSskrll 
5286d3ceb1dSskrll 	h += o;
5296d3ceb1dSskrll 	data = *(volatile uint32_t *)h;
530*03ccf6a5Sskrll 	return le32toh(data);
5316d3ceb1dSskrll }
5326d3ceb1dSskrll 
5336d3ceb1dSskrll uint64_t
5346d3ceb1dSskrll elroy_r8(void *v, bus_space_handle_t h, bus_size_t o)
5356d3ceb1dSskrll {
5366d3ceb1dSskrll 	uint64_t data;
5376d3ceb1dSskrll 
5386d3ceb1dSskrll 	h += o;
5396d3ceb1dSskrll 	data = *(volatile uint64_t *)h;
540*03ccf6a5Sskrll 	return le64toh(data);
5416d3ceb1dSskrll }
5426d3ceb1dSskrll 
543dbeed521Smacallan uint16_t
544dbeed521Smacallan elroy_rs2(void *v, bus_space_handle_t h, bus_size_t o)
545dbeed521Smacallan {
546dbeed521Smacallan 	volatile uint16_t *p;
547dbeed521Smacallan 
548dbeed521Smacallan 	h += o;
549dbeed521Smacallan 	p = (volatile uint16_t *)h;
550*03ccf6a5Sskrll 	return *p;
551dbeed521Smacallan }
552dbeed521Smacallan 
553dbeed521Smacallan uint32_t
554dbeed521Smacallan elroy_rs4(void *v, bus_space_handle_t h, bus_size_t o)
555dbeed521Smacallan {
556dbeed521Smacallan 	uint32_t data;
557dbeed521Smacallan 
558dbeed521Smacallan 	h += o;
559dbeed521Smacallan 	data = *(volatile uint32_t *)h;
560dbeed521Smacallan 	return data;
561dbeed521Smacallan }
562dbeed521Smacallan 
563dbeed521Smacallan uint64_t
564dbeed521Smacallan elroy_rs8(void *v, bus_space_handle_t h, bus_size_t o)
565dbeed521Smacallan {
566dbeed521Smacallan 	uint64_t data;
567dbeed521Smacallan 
568dbeed521Smacallan 	h += o;
569dbeed521Smacallan 	data = *(volatile uint64_t *)h;
570dbeed521Smacallan 	return data;
571dbeed521Smacallan }
572dbeed521Smacallan 
5736d3ceb1dSskrll void
5746d3ceb1dSskrll elroy_w1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv)
5756d3ceb1dSskrll {
5766d3ceb1dSskrll 	h += o;
5776d3ceb1dSskrll 	*(volatile uint8_t *)h = vv;
5786d3ceb1dSskrll }
5796d3ceb1dSskrll 
5806d3ceb1dSskrll void
5816d3ceb1dSskrll elroy_w2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv)
5826d3ceb1dSskrll {
5836d3ceb1dSskrll 	volatile uint16_t *p;
5846d3ceb1dSskrll 
5856d3ceb1dSskrll 	h += o;
5866d3ceb1dSskrll 	p = (volatile uint16_t *)h;
5876d3ceb1dSskrll 	*p = htole16(vv);
5886d3ceb1dSskrll }
5896d3ceb1dSskrll 
5906d3ceb1dSskrll void
5916d3ceb1dSskrll elroy_w4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv)
5926d3ceb1dSskrll {
5936d3ceb1dSskrll 	h += o;
5946d3ceb1dSskrll 	vv = htole32(vv);
5956d3ceb1dSskrll 	*(volatile uint32_t *)h = vv;
5966d3ceb1dSskrll }
5976d3ceb1dSskrll 
5986d3ceb1dSskrll void
5996d3ceb1dSskrll elroy_w8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv)
6006d3ceb1dSskrll {
6016d3ceb1dSskrll 	h += o;
6026d3ceb1dSskrll 	*(volatile uint64_t *)h = htole64(vv);
6036d3ceb1dSskrll }
6046d3ceb1dSskrll 
605dbeed521Smacallan void
606dbeed521Smacallan elroy_ws2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv)
607dbeed521Smacallan {
608dbeed521Smacallan 	volatile uint16_t *p;
609dbeed521Smacallan 
610dbeed521Smacallan 	h += o;
611dbeed521Smacallan 	p = (volatile uint16_t *)h;
612dbeed521Smacallan 	*p = vv;
613dbeed521Smacallan }
614dbeed521Smacallan 
615dbeed521Smacallan void
616dbeed521Smacallan elroy_ws4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv)
617dbeed521Smacallan {
618dbeed521Smacallan 	h += o;
619dbeed521Smacallan 	*(volatile uint32_t *)h = vv;
620dbeed521Smacallan }
621dbeed521Smacallan 
622dbeed521Smacallan void
623dbeed521Smacallan elroy_ws8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv)
624dbeed521Smacallan {
625dbeed521Smacallan 	h += o;
626dbeed521Smacallan 	*(volatile uint64_t *)h = vv;
627dbeed521Smacallan }
6286d3ceb1dSskrll 
6296d3ceb1dSskrll void
6306d3ceb1dSskrll elroy_rm_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t *a, bus_size_t c)
6316d3ceb1dSskrll {
6326d3ceb1dSskrll 	volatile uint8_t *p;
6336d3ceb1dSskrll 
6346d3ceb1dSskrll 	h += o;
6356d3ceb1dSskrll 	p = (volatile uint8_t *)h;
6366d3ceb1dSskrll 	while (c--)
6376d3ceb1dSskrll 		*a++ = *p;
6386d3ceb1dSskrll }
6396d3ceb1dSskrll 
6406d3ceb1dSskrll void
6416d3ceb1dSskrll elroy_rm_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t *a, bus_size_t c)
6426d3ceb1dSskrll {
6436d3ceb1dSskrll 	volatile uint16_t *p;
6446d3ceb1dSskrll 
6456d3ceb1dSskrll 	h += o;
6466d3ceb1dSskrll 	p = (volatile uint16_t *)h;
6476d3ceb1dSskrll 	while (c--)
6486d3ceb1dSskrll 		*a++ = le16toh(*p);
6496d3ceb1dSskrll }
6506d3ceb1dSskrll 
6516d3ceb1dSskrll void
6526d3ceb1dSskrll elroy_rm_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t *a, bus_size_t c)
6536d3ceb1dSskrll {
6546d3ceb1dSskrll 	volatile uint32_t *p;
6556d3ceb1dSskrll 
6566d3ceb1dSskrll 	h += o;
6576d3ceb1dSskrll 	p = (volatile uint32_t *)h;
6586d3ceb1dSskrll 	while (c--)
6596d3ceb1dSskrll 		*a++ = le32toh(*p);
6606d3ceb1dSskrll }
6616d3ceb1dSskrll 
6626d3ceb1dSskrll void
6636d3ceb1dSskrll elroy_rm_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t *a, bus_size_t c)
6646d3ceb1dSskrll {
6656d3ceb1dSskrll 	volatile uint64_t *p;
6666d3ceb1dSskrll 
6676d3ceb1dSskrll 	h += o;
6686d3ceb1dSskrll 	p = (volatile uint64_t *)h;
6696d3ceb1dSskrll 	while (c--)
6706d3ceb1dSskrll 		*a++ = le64toh(*p);
6716d3ceb1dSskrll }
6726d3ceb1dSskrll 
6736d3ceb1dSskrll void
6746d3ceb1dSskrll elroy_wm_1(void *v, bus_space_handle_t h, bus_size_t o, const uint8_t *a, bus_size_t c)
6756d3ceb1dSskrll {
6766d3ceb1dSskrll 	volatile uint8_t *p;
6776d3ceb1dSskrll 
6786d3ceb1dSskrll 	h += o;
6796d3ceb1dSskrll 	p = (volatile uint8_t *)h;
6806d3ceb1dSskrll 	while (c--)
6816d3ceb1dSskrll 		*p = *a++;
6826d3ceb1dSskrll }
6836d3ceb1dSskrll 
6846d3ceb1dSskrll void
6856d3ceb1dSskrll elroy_wm_2(void *v, bus_space_handle_t h, bus_size_t o, const uint16_t *a, bus_size_t c)
6866d3ceb1dSskrll {
6876d3ceb1dSskrll 	volatile uint16_t *p;
6886d3ceb1dSskrll 
6896d3ceb1dSskrll 	h += o;
6906d3ceb1dSskrll 	p = (volatile uint16_t *)h;
6916d3ceb1dSskrll 	while (c--)
6926d3ceb1dSskrll 		*p = htole16(*a++);
6936d3ceb1dSskrll }
6946d3ceb1dSskrll 
6956d3ceb1dSskrll void
6966d3ceb1dSskrll elroy_wm_4(void *v, bus_space_handle_t h, bus_size_t o, const uint32_t *a, bus_size_t c)
6976d3ceb1dSskrll {
6986d3ceb1dSskrll 	volatile uint32_t *p;
6996d3ceb1dSskrll 
7006d3ceb1dSskrll 	h += o;
7016d3ceb1dSskrll 	p = (volatile uint32_t *)h;
7026d3ceb1dSskrll 	while (c--)
7036d3ceb1dSskrll 		*p = htole32(*a++);
7046d3ceb1dSskrll }
7056d3ceb1dSskrll 
7066d3ceb1dSskrll void
7076d3ceb1dSskrll elroy_wm_8(void *v, bus_space_handle_t h, bus_size_t o, const uint64_t *a, bus_size_t c)
7086d3ceb1dSskrll {
7096d3ceb1dSskrll 	volatile uint64_t *p;
7106d3ceb1dSskrll 
7116d3ceb1dSskrll 	h += o;
7126d3ceb1dSskrll 	p = (volatile uint64_t *)h;
7136d3ceb1dSskrll 	while (c--)
7146d3ceb1dSskrll 		*p = htole64(*a++);
7156d3ceb1dSskrll }
7166d3ceb1dSskrll 
7176d3ceb1dSskrll void
7186d3ceb1dSskrll elroy_sm_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv, bus_size_t c)
7196d3ceb1dSskrll {
7206d3ceb1dSskrll 	volatile uint8_t *p;
7216d3ceb1dSskrll 
7226d3ceb1dSskrll 	h += o;
7236d3ceb1dSskrll 	p = (volatile uint8_t *)h;
7246d3ceb1dSskrll 	while (c--)
7256d3ceb1dSskrll 		*p = vv;
7266d3ceb1dSskrll }
7276d3ceb1dSskrll 
7286d3ceb1dSskrll void
7296d3ceb1dSskrll elroy_sm_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv, bus_size_t c)
7306d3ceb1dSskrll {
7316d3ceb1dSskrll 	volatile uint16_t *p;
7326d3ceb1dSskrll 
7336d3ceb1dSskrll 	h += o;
7346d3ceb1dSskrll 	p = (volatile uint16_t *)h;
7356d3ceb1dSskrll 	vv = htole16(vv);
7366d3ceb1dSskrll 	while (c--)
7376d3ceb1dSskrll 		*p = vv;
7386d3ceb1dSskrll }
7396d3ceb1dSskrll 
7406d3ceb1dSskrll void
7416d3ceb1dSskrll elroy_sm_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv, bus_size_t c)
7426d3ceb1dSskrll {
7436d3ceb1dSskrll 	volatile uint32_t *p;
7446d3ceb1dSskrll 
7456d3ceb1dSskrll 	h += o;
7466d3ceb1dSskrll 	p = (volatile uint32_t *)h;
7476d3ceb1dSskrll 	vv = htole32(vv);
7486d3ceb1dSskrll 	while (c--)
7496d3ceb1dSskrll 		*p = vv;
7506d3ceb1dSskrll }
7516d3ceb1dSskrll 
7526d3ceb1dSskrll void
7536d3ceb1dSskrll elroy_sm_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv, bus_size_t c)
7546d3ceb1dSskrll {
7556d3ceb1dSskrll 	volatile uint64_t *p;
7566d3ceb1dSskrll 
7576d3ceb1dSskrll 	h += o;
7586d3ceb1dSskrll 	p = (volatile uint64_t *)h;
7596d3ceb1dSskrll 	vv = htole64(vv);
7606d3ceb1dSskrll 	while (c--)
7616d3ceb1dSskrll 		*p = vv;
7626d3ceb1dSskrll }
7636d3ceb1dSskrll 
7646d3ceb1dSskrll void
7656d3ceb1dSskrll elroy_rrm_2(void *v, bus_space_handle_t h, bus_size_t o,
7666d3ceb1dSskrll     uint16_t *a, bus_size_t c)
7676d3ceb1dSskrll {
7686d3ceb1dSskrll 	volatile uint16_t *p, *q = a;
7696d3ceb1dSskrll 
7706d3ceb1dSskrll 	h += o;
7716d3ceb1dSskrll 	p = (volatile uint16_t *)h;
7726d3ceb1dSskrll 	while (c--)
7736d3ceb1dSskrll 		*q++ = *p;
7746d3ceb1dSskrll }
7756d3ceb1dSskrll 
7766d3ceb1dSskrll void
7776d3ceb1dSskrll elroy_rrm_4(void *v, bus_space_handle_t h, bus_size_t o,
7786d3ceb1dSskrll     uint32_t *a, bus_size_t c)
7796d3ceb1dSskrll {
7806d3ceb1dSskrll 	volatile uint32_t *p, *q = a;
7816d3ceb1dSskrll 
7826d3ceb1dSskrll 	h += o;
7836d3ceb1dSskrll 	p = (volatile uint32_t *)h;
7846d3ceb1dSskrll 	while (c--)
7856d3ceb1dSskrll 		*q++ = *p;
7866d3ceb1dSskrll }
7876d3ceb1dSskrll 
7886d3ceb1dSskrll void
7896d3ceb1dSskrll elroy_rrm_8(void *v, bus_space_handle_t h, bus_size_t o,
7906d3ceb1dSskrll     uint64_t *a, bus_size_t c)
7916d3ceb1dSskrll {
7926d3ceb1dSskrll 	volatile uint64_t *p, *q = a;
7936d3ceb1dSskrll 
7946d3ceb1dSskrll 	h += o;
7956d3ceb1dSskrll 	p = (volatile uint64_t *)h;
7966d3ceb1dSskrll 	while (c--)
7976d3ceb1dSskrll 		*q++ = *p;
7986d3ceb1dSskrll }
7996d3ceb1dSskrll 
8006d3ceb1dSskrll void
8016d3ceb1dSskrll elroy_wrm_2(void *v, bus_space_handle_t h, bus_size_t o,
8026d3ceb1dSskrll     const uint16_t *a, bus_size_t c)
8036d3ceb1dSskrll {
8046d3ceb1dSskrll 	volatile uint16_t *p;
8056d3ceb1dSskrll 	const uint16_t *q = a;
8066d3ceb1dSskrll 
8076d3ceb1dSskrll 	h += o;
8086d3ceb1dSskrll 	p = (volatile uint16_t *)h;
8096d3ceb1dSskrll 	while (c--)
8106d3ceb1dSskrll 		*p = *q++;
8116d3ceb1dSskrll }
8126d3ceb1dSskrll 
8136d3ceb1dSskrll void
8146d3ceb1dSskrll elroy_wrm_4(void *v, bus_space_handle_t h, bus_size_t o,
8156d3ceb1dSskrll     const uint32_t *a, bus_size_t c)
8166d3ceb1dSskrll {
8176d3ceb1dSskrll 	volatile uint32_t *p;
8186d3ceb1dSskrll 	const uint32_t *q = a;
8196d3ceb1dSskrll 
8206d3ceb1dSskrll 	h += o;
8216d3ceb1dSskrll 	p = (volatile uint32_t *)h;
8226d3ceb1dSskrll 	while (c--)
8236d3ceb1dSskrll 		*p = *q++;
8246d3ceb1dSskrll }
8256d3ceb1dSskrll 
8266d3ceb1dSskrll void
8276d3ceb1dSskrll elroy_wrm_8(void *v, bus_space_handle_t h, bus_size_t o,
8286d3ceb1dSskrll     const uint64_t *a, bus_size_t c)
8296d3ceb1dSskrll {
8306d3ceb1dSskrll 	volatile uint64_t *p;
8316d3ceb1dSskrll 	const uint64_t *q = a;
8326d3ceb1dSskrll 
8336d3ceb1dSskrll 	h += o;
8346d3ceb1dSskrll 	p = (volatile uint64_t *)h;
8356d3ceb1dSskrll 	while (c--)
8366d3ceb1dSskrll 		*p = *q++;
8376d3ceb1dSskrll }
8386d3ceb1dSskrll 
8396d3ceb1dSskrll void
8406d3ceb1dSskrll elroy_rr_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t *a, bus_size_t c)
8416d3ceb1dSskrll {
8426d3ceb1dSskrll 	volatile uint8_t *p;
8436d3ceb1dSskrll 
8446d3ceb1dSskrll 	h += o;
8456d3ceb1dSskrll 	p = (volatile uint8_t *)h;
8466d3ceb1dSskrll 	while (c--)
8476d3ceb1dSskrll 		*a++ = *p++;
8486d3ceb1dSskrll }
8496d3ceb1dSskrll 
8506d3ceb1dSskrll void
8516d3ceb1dSskrll elroy_rr_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t *a, bus_size_t c)
8526d3ceb1dSskrll {
8536d3ceb1dSskrll 	volatile uint16_t *p, data;
8546d3ceb1dSskrll 
8556d3ceb1dSskrll 	h += o;
8566d3ceb1dSskrll 	p = (volatile uint16_t *)h;
8576d3ceb1dSskrll 	while (c--) {
8586d3ceb1dSskrll 		data = *p++;
8596d3ceb1dSskrll 		*a++ = le16toh(data);
8606d3ceb1dSskrll 	}
8616d3ceb1dSskrll }
8626d3ceb1dSskrll 
8636d3ceb1dSskrll void
8646d3ceb1dSskrll elroy_rr_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t *a, bus_size_t c)
8656d3ceb1dSskrll {
8666d3ceb1dSskrll 	volatile uint32_t *p, data;
8676d3ceb1dSskrll 
8686d3ceb1dSskrll 	h += o;
8696d3ceb1dSskrll 	p = (volatile uint32_t *)h;
8706d3ceb1dSskrll 	while (c--) {
8716d3ceb1dSskrll 		data = *p++;
8726d3ceb1dSskrll 		*a++ = le32toh(data);
8736d3ceb1dSskrll 	}
8746d3ceb1dSskrll }
8756d3ceb1dSskrll 
8766d3ceb1dSskrll void
8776d3ceb1dSskrll elroy_rr_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t *a, bus_size_t c)
8786d3ceb1dSskrll {
8796d3ceb1dSskrll 	volatile uint64_t *p, data;
8806d3ceb1dSskrll 
8816d3ceb1dSskrll 	h += o;
8826d3ceb1dSskrll 	p = (volatile uint64_t *)h;
8836d3ceb1dSskrll 	while (c--) {
8846d3ceb1dSskrll 		data = *p++;
8856d3ceb1dSskrll 		*a++ = le64toh(data);
8866d3ceb1dSskrll 	}
8876d3ceb1dSskrll }
8886d3ceb1dSskrll 
8896d3ceb1dSskrll void
8906d3ceb1dSskrll elroy_wr_1(void *v, bus_space_handle_t h, bus_size_t o, const uint8_t *a, bus_size_t c)
8916d3ceb1dSskrll {
8926d3ceb1dSskrll 	volatile uint8_t *p;
8936d3ceb1dSskrll 
8946d3ceb1dSskrll 	h += o;
8956d3ceb1dSskrll 	p = (volatile uint8_t *)h;
8966d3ceb1dSskrll 	while (c--)
8976d3ceb1dSskrll 		*p++ = *a++;
8986d3ceb1dSskrll }
8996d3ceb1dSskrll 
9006d3ceb1dSskrll void
9016d3ceb1dSskrll elroy_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const uint16_t *a, bus_size_t c)
9026d3ceb1dSskrll {
9036d3ceb1dSskrll 	volatile uint16_t *p, data;
9046d3ceb1dSskrll 
9056d3ceb1dSskrll 	h += o;
9066d3ceb1dSskrll 	p = (volatile uint16_t *)h;
9076d3ceb1dSskrll 	while (c--) {
9086d3ceb1dSskrll 		data = *a++;
9096d3ceb1dSskrll 		*p++ = htole16(data);
9106d3ceb1dSskrll 	}
9116d3ceb1dSskrll }
9126d3ceb1dSskrll 
9136d3ceb1dSskrll void
9146d3ceb1dSskrll elroy_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const uint32_t *a, bus_size_t c)
9156d3ceb1dSskrll {
9166d3ceb1dSskrll 	volatile uint32_t *p, data;
9176d3ceb1dSskrll 
9186d3ceb1dSskrll 	h += o;
9196d3ceb1dSskrll 	p = (volatile uint32_t *)h;
9206d3ceb1dSskrll 	while (c--) {
9216d3ceb1dSskrll 		data = *a++;
9226d3ceb1dSskrll 		*p++ = htole32(data);
9236d3ceb1dSskrll 	}
9246d3ceb1dSskrll }
9256d3ceb1dSskrll 
9266d3ceb1dSskrll void
9276d3ceb1dSskrll elroy_wr_8(void *v, bus_space_handle_t h, bus_size_t o, const uint64_t *a, bus_size_t c)
9286d3ceb1dSskrll {
9296d3ceb1dSskrll 	volatile uint64_t *p, data;
9306d3ceb1dSskrll 
9316d3ceb1dSskrll 	h += o;
9326d3ceb1dSskrll 	p = (volatile uint64_t *)h;
9336d3ceb1dSskrll 	while (c--) {
9346d3ceb1dSskrll 		data = *a++;
9356d3ceb1dSskrll 		*p++ = htole64(data);
9366d3ceb1dSskrll 	}
9376d3ceb1dSskrll }
9386d3ceb1dSskrll 
9396d3ceb1dSskrll void
9406d3ceb1dSskrll elroy_rrr_2(void *v, bus_space_handle_t h, bus_size_t o,
9416d3ceb1dSskrll     uint16_t *a, bus_size_t c)
9426d3ceb1dSskrll {
9436d3ceb1dSskrll 	volatile uint16_t *p, *q = a;
9446d3ceb1dSskrll 
9456d3ceb1dSskrll 	h += o;
9466d3ceb1dSskrll 	p = (volatile uint16_t *)h;
9476d3ceb1dSskrll 	while (c--)
9486d3ceb1dSskrll 		*q++ = *p++;
9496d3ceb1dSskrll }
9506d3ceb1dSskrll 
9516d3ceb1dSskrll void
9526d3ceb1dSskrll elroy_rrr_4(void *v, bus_space_handle_t h, bus_size_t o,
9536d3ceb1dSskrll     uint32_t *a, bus_size_t c)
9546d3ceb1dSskrll {
9556d3ceb1dSskrll 	volatile uint32_t *p, *q = a;
9566d3ceb1dSskrll 
9576d3ceb1dSskrll 	h += o;
9586d3ceb1dSskrll 	p = (volatile uint32_t *)h;
9596d3ceb1dSskrll 	while (c--)
9606d3ceb1dSskrll 		*q++ = *p++;
9616d3ceb1dSskrll }
9626d3ceb1dSskrll 
9636d3ceb1dSskrll void
9646d3ceb1dSskrll elroy_rrr_8(void *v, bus_space_handle_t h, bus_size_t o,
9656d3ceb1dSskrll     uint64_t *a, bus_size_t c)
9666d3ceb1dSskrll {
9676d3ceb1dSskrll 	volatile uint64_t *p, *q = a;
9686d3ceb1dSskrll 
9696d3ceb1dSskrll 	h += o;
9706d3ceb1dSskrll 	p = (volatile uint64_t *)h;
9716d3ceb1dSskrll 	while (c--)
9726d3ceb1dSskrll 		*q++ = *p++;
9736d3ceb1dSskrll }
9746d3ceb1dSskrll 
9756d3ceb1dSskrll void
9766d3ceb1dSskrll elroy_wrr_2(void *v, bus_space_handle_t h, bus_size_t o,
9776d3ceb1dSskrll     const uint16_t *a, bus_size_t c)
9786d3ceb1dSskrll {
9796d3ceb1dSskrll 	volatile uint16_t *p;
9806d3ceb1dSskrll 	const uint16_t *q = a;
9816d3ceb1dSskrll 
9826d3ceb1dSskrll 	h += o;
9836d3ceb1dSskrll 	p = (volatile uint16_t *)h;
9846d3ceb1dSskrll 	while (c--)
9856d3ceb1dSskrll 		*p++ = *q++;
9866d3ceb1dSskrll }
9876d3ceb1dSskrll 
9886d3ceb1dSskrll void
9896d3ceb1dSskrll elroy_wrr_4(void *v, bus_space_handle_t h, bus_size_t o,
9906d3ceb1dSskrll     const uint32_t *a, bus_size_t c)
9916d3ceb1dSskrll {
9926d3ceb1dSskrll 	volatile uint32_t *p;
9936d3ceb1dSskrll 	const uint32_t *q = a;
9946d3ceb1dSskrll 
9956d3ceb1dSskrll 	h += o;
9966d3ceb1dSskrll 	p = (volatile uint32_t *)h;
9976d3ceb1dSskrll 	while (c--)
9986d3ceb1dSskrll 		*p++ = *q++;
9996d3ceb1dSskrll }
10006d3ceb1dSskrll 
10016d3ceb1dSskrll void
10026d3ceb1dSskrll elroy_wrr_8(void *v, bus_space_handle_t h, bus_size_t o,
10036d3ceb1dSskrll     const uint64_t *a, bus_size_t c)
10046d3ceb1dSskrll {
10056d3ceb1dSskrll 	volatile uint64_t *p;
10066d3ceb1dSskrll 	const uint64_t *q = a;
10076d3ceb1dSskrll 
10086d3ceb1dSskrll 	h += o;
10096d3ceb1dSskrll 	p = (volatile uint64_t *)h;
10106d3ceb1dSskrll 	while (c--)
10116d3ceb1dSskrll 		*p++ = *q++;
10126d3ceb1dSskrll }
10136d3ceb1dSskrll 
10146d3ceb1dSskrll void
10156d3ceb1dSskrll elroy_sr_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv, bus_size_t c)
10166d3ceb1dSskrll {
10176d3ceb1dSskrll 	volatile uint8_t *p;
10186d3ceb1dSskrll 
10196d3ceb1dSskrll 	h += o;
10206d3ceb1dSskrll 	p = (volatile uint8_t *)h;
10216d3ceb1dSskrll 	while (c--)
10226d3ceb1dSskrll 		*p++ = vv;
10236d3ceb1dSskrll }
10246d3ceb1dSskrll 
10256d3ceb1dSskrll void
10266d3ceb1dSskrll elroy_sr_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv, bus_size_t c)
10276d3ceb1dSskrll {
10286d3ceb1dSskrll 	volatile uint16_t *p;
10296d3ceb1dSskrll 
10306d3ceb1dSskrll 	h += o;
10316d3ceb1dSskrll 	vv = htole16(vv);
10326d3ceb1dSskrll 	p = (volatile uint16_t *)h;
10336d3ceb1dSskrll 	while (c--)
10346d3ceb1dSskrll 		*p++ = vv;
10356d3ceb1dSskrll }
10366d3ceb1dSskrll 
10376d3ceb1dSskrll void
10386d3ceb1dSskrll elroy_sr_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv, bus_size_t c)
10396d3ceb1dSskrll {
10406d3ceb1dSskrll 	volatile uint32_t *p;
10416d3ceb1dSskrll 
10426d3ceb1dSskrll 	h += o;
10436d3ceb1dSskrll 	vv = htole32(vv);
10446d3ceb1dSskrll 	p = (volatile uint32_t *)h;
10456d3ceb1dSskrll 	while (c--)
10466d3ceb1dSskrll 		*p++ = vv;
10476d3ceb1dSskrll }
10486d3ceb1dSskrll 
10496d3ceb1dSskrll void
10506d3ceb1dSskrll elroy_sr_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv, bus_size_t c)
10516d3ceb1dSskrll {
10526d3ceb1dSskrll 	volatile uint64_t *p;
10536d3ceb1dSskrll 
10546d3ceb1dSskrll 	h += o;
10556d3ceb1dSskrll 	vv = htole64(vv);
10566d3ceb1dSskrll 	p = (volatile uint64_t *)h;
10576d3ceb1dSskrll 	while (c--)
10586d3ceb1dSskrll 		*p++ = vv;
10596d3ceb1dSskrll }
10606d3ceb1dSskrll 
10616d3ceb1dSskrll void
10626d3ceb1dSskrll elroy_cp_1(void *v, bus_space_handle_t h1, bus_size_t o1,
10636d3ceb1dSskrll 	  bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
10646d3ceb1dSskrll {
10656d3ceb1dSskrll 	while (c--)
10666d3ceb1dSskrll 		elroy_w1(v, h1, o1++, elroy_r1(v, h2, o2++));
10676d3ceb1dSskrll }
10686d3ceb1dSskrll 
10696d3ceb1dSskrll void
10706d3ceb1dSskrll elroy_cp_2(void *v, bus_space_handle_t h1, bus_size_t o1,
10716d3ceb1dSskrll 	  bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
10726d3ceb1dSskrll {
10736d3ceb1dSskrll 	while (c--) {
10746d3ceb1dSskrll 		elroy_w2(v, h1, o1, elroy_r2(v, h2, o2));
10756d3ceb1dSskrll 		o1 += 2;
10766d3ceb1dSskrll 		o2 += 2;
10776d3ceb1dSskrll 	}
10786d3ceb1dSskrll }
10796d3ceb1dSskrll 
10806d3ceb1dSskrll void
10816d3ceb1dSskrll elroy_cp_4(void *v, bus_space_handle_t h1, bus_size_t o1,
10826d3ceb1dSskrll 	  bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
10836d3ceb1dSskrll {
10846d3ceb1dSskrll 	while (c--) {
10856d3ceb1dSskrll 		elroy_w4(v, h1, o1, elroy_r4(v, h2, o2));
10866d3ceb1dSskrll 		o1 += 4;
10876d3ceb1dSskrll 		o2 += 4;
10886d3ceb1dSskrll 	}
10896d3ceb1dSskrll }
10906d3ceb1dSskrll 
10916d3ceb1dSskrll void
10926d3ceb1dSskrll elroy_cp_8(void *v, bus_space_handle_t h1, bus_size_t o1,
10936d3ceb1dSskrll 	  bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
10946d3ceb1dSskrll {
10956d3ceb1dSskrll 	while (c--) {
10966d3ceb1dSskrll 		elroy_w8(v, h1, o1, elroy_r8(v, h2, o2));
10976d3ceb1dSskrll 		o1 += 8;
10986d3ceb1dSskrll 		o2 += 8;
10996d3ceb1dSskrll 	}
11006d3ceb1dSskrll }
11016d3ceb1dSskrll 
11026d3ceb1dSskrll const struct hppa_bus_space_tag elroy_iomemt = {
11036d3ceb1dSskrll 	NULL,
11046d3ceb1dSskrll 
11056d3ceb1dSskrll 	NULL, elroy_unmap, elroy_subregion, NULL, elroy_free,
11066d3ceb1dSskrll 	elroy_barrier, elroy_vaddr, elroy_mmap,
11076d3ceb1dSskrll 	elroy_r1,    elroy_r2,    elroy_r4,    elroy_r8,
1108dbeed521Smacallan 	             elroy_rs2,   elroy_rs4,   elroy_rs8,
11096d3ceb1dSskrll 	elroy_w1,    elroy_w2,    elroy_w4,    elroy_w8,
1110dbeed521Smacallan 	             elroy_ws2,   elroy_ws4,   elroy_ws8,
11116d3ceb1dSskrll 	elroy_rm_1,  elroy_rm_2,  elroy_rm_4,  elroy_rm_8,
11126d3ceb1dSskrll 	elroy_wm_1,  elroy_wm_2,  elroy_wm_4,  elroy_wm_8,
11136d3ceb1dSskrll 	elroy_sm_1,  elroy_sm_2,  elroy_sm_4,  elroy_sm_8,
11146d3ceb1dSskrll 		     elroy_rrm_2, elroy_rrm_4, elroy_rrm_8,
11156d3ceb1dSskrll 		     elroy_wrm_2, elroy_wrm_4, elroy_wrm_8,
11166d3ceb1dSskrll 	elroy_rr_1,  elroy_rr_2,  elroy_rr_4,  elroy_rr_8,
11176d3ceb1dSskrll 	elroy_wr_1,  elroy_wr_2,  elroy_wr_4,  elroy_wr_8,
11186d3ceb1dSskrll 		     elroy_rrr_2, elroy_rrr_4, elroy_rrr_8,
11196d3ceb1dSskrll 		     elroy_wrr_2, elroy_wrr_4, elroy_wrr_8,
11206d3ceb1dSskrll 	elroy_sr_1,  elroy_sr_2,  elroy_sr_4,  elroy_sr_8,
11216d3ceb1dSskrll 	elroy_cp_1,  elroy_cp_2,  elroy_cp_4,  elroy_cp_8
11226d3ceb1dSskrll };
11236d3ceb1dSskrll 
11246d3ceb1dSskrll int
11256d3ceb1dSskrll elroy_dmamap_create(void *v, bus_size_t size, int nsegments,
11266d3ceb1dSskrll     bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp)
11276d3ceb1dSskrll {
11286d3ceb1dSskrll 	struct elroy_softc *sc = v;
11296d3ceb1dSskrll 
11306d3ceb1dSskrll 	/* TODO check the addresses, boundary, enable dma */
11316d3ceb1dSskrll 
1132*03ccf6a5Sskrll 	return bus_dmamap_create(sc->sc_dmat, size, nsegments,
1133*03ccf6a5Sskrll 	    maxsegsz, boundary, flags, dmamp);
11346d3ceb1dSskrll }
11356d3ceb1dSskrll 
11366d3ceb1dSskrll void
11376d3ceb1dSskrll elroy_dmamap_destroy(void *v, bus_dmamap_t map)
11386d3ceb1dSskrll {
11396d3ceb1dSskrll 	struct elroy_softc *sc = v;
11406d3ceb1dSskrll 
11416d3ceb1dSskrll 	bus_dmamap_destroy(sc->sc_dmat, map);
11426d3ceb1dSskrll }
11436d3ceb1dSskrll 
11446d3ceb1dSskrll int
11456d3ceb1dSskrll elroy_dmamap_load(void *v, bus_dmamap_t map, void *addr, bus_size_t size,
11466d3ceb1dSskrll     struct proc *p, int flags)
11476d3ceb1dSskrll {
11486d3ceb1dSskrll 	struct elroy_softc *sc = v;
11496d3ceb1dSskrll 
1150*03ccf6a5Sskrll 	return bus_dmamap_load(sc->sc_dmat, map, addr, size, p, flags);
11516d3ceb1dSskrll }
11526d3ceb1dSskrll 
11536d3ceb1dSskrll int
11546d3ceb1dSskrll elroy_dmamap_load_mbuf(void *v, bus_dmamap_t map, struct mbuf *m, int flags)
11556d3ceb1dSskrll {
11566d3ceb1dSskrll 	struct elroy_softc *sc = v;
11576d3ceb1dSskrll 
1158*03ccf6a5Sskrll 	return bus_dmamap_load_mbuf(sc->sc_dmat, map, m, flags);
11596d3ceb1dSskrll }
11606d3ceb1dSskrll 
11616d3ceb1dSskrll int
11626d3ceb1dSskrll elroy_dmamap_load_uio(void *v, bus_dmamap_t map, struct uio *uio, int flags)
11636d3ceb1dSskrll {
11646d3ceb1dSskrll 	struct elroy_softc *sc = v;
11656d3ceb1dSskrll 
1166*03ccf6a5Sskrll 	return bus_dmamap_load_uio(sc->sc_dmat, map, uio, flags);
11676d3ceb1dSskrll }
11686d3ceb1dSskrll 
11696d3ceb1dSskrll int
11706d3ceb1dSskrll elroy_dmamap_load_raw(void *v, bus_dmamap_t map, bus_dma_segment_t *segs,
11716d3ceb1dSskrll     int nsegs, bus_size_t size, int flags)
11726d3ceb1dSskrll {
11736d3ceb1dSskrll 	struct elroy_softc *sc = v;
11746d3ceb1dSskrll 
1175*03ccf6a5Sskrll 	return bus_dmamap_load_raw(sc->sc_dmat, map, segs, nsegs, size, flags);
11766d3ceb1dSskrll }
11776d3ceb1dSskrll 
11786d3ceb1dSskrll void
11796d3ceb1dSskrll elroy_dmamap_unload(void *v, bus_dmamap_t map)
11806d3ceb1dSskrll {
11816d3ceb1dSskrll 	struct elroy_softc *sc = v;
11826d3ceb1dSskrll 
11836d3ceb1dSskrll 	bus_dmamap_unload(sc->sc_dmat, map);
11846d3ceb1dSskrll }
11856d3ceb1dSskrll 
11866d3ceb1dSskrll void
11876d3ceb1dSskrll elroy_dmamap_sync(void *v, bus_dmamap_t map, bus_addr_t off,
11886d3ceb1dSskrll     bus_size_t len, int ops)
11896d3ceb1dSskrll {
11906d3ceb1dSskrll 	struct elroy_softc *sc = v;
11916d3ceb1dSskrll 
11926d3ceb1dSskrll 	bus_dmamap_sync(sc->sc_dmat, map, off, len, ops);
11936d3ceb1dSskrll }
11946d3ceb1dSskrll 
11956d3ceb1dSskrll int
11966d3ceb1dSskrll elroy_dmamem_alloc(void *v, bus_size_t size, bus_size_t alignment,
11976d3ceb1dSskrll     bus_size_t boundary, bus_dma_segment_t *segs,
11986d3ceb1dSskrll     int nsegs, int *rsegs, int flags)
11996d3ceb1dSskrll {
12006d3ceb1dSskrll 	struct elroy_softc *sc = v;
12016d3ceb1dSskrll 
1202*03ccf6a5Sskrll 	return bus_dmamem_alloc(sc->sc_dmat, size, alignment, boundary,
1203*03ccf6a5Sskrll 	    segs, nsegs, rsegs, flags);
12046d3ceb1dSskrll }
12056d3ceb1dSskrll 
12066d3ceb1dSskrll void
12076d3ceb1dSskrll elroy_dmamem_free(void *v, bus_dma_segment_t *segs, int nsegs)
12086d3ceb1dSskrll {
12096d3ceb1dSskrll 	struct elroy_softc *sc = v;
12106d3ceb1dSskrll 
12116d3ceb1dSskrll 	bus_dmamem_free(sc->sc_dmat, segs, nsegs);
12126d3ceb1dSskrll }
12136d3ceb1dSskrll 
12146d3ceb1dSskrll int
12156d3ceb1dSskrll elroy_dmamem_map(void *v, bus_dma_segment_t *segs, int nsegs, size_t size,
12166d3ceb1dSskrll     void **kvap, int flags)
12176d3ceb1dSskrll {
12186d3ceb1dSskrll 	struct elroy_softc *sc = v;
12196d3ceb1dSskrll 
1220*03ccf6a5Sskrll 	return bus_dmamem_map(sc->sc_dmat, segs, nsegs, size, kvap, flags);
12216d3ceb1dSskrll }
12226d3ceb1dSskrll 
12236d3ceb1dSskrll void
12246d3ceb1dSskrll elroy_dmamem_unmap(void *v, void *kva, size_t size)
12256d3ceb1dSskrll {
12266d3ceb1dSskrll 	struct elroy_softc *sc = v;
12276d3ceb1dSskrll 
12286d3ceb1dSskrll 	bus_dmamem_unmap(sc->sc_dmat, kva, size);
12296d3ceb1dSskrll }
12306d3ceb1dSskrll 
12316d3ceb1dSskrll paddr_t
12326d3ceb1dSskrll elroy_dmamem_mmap(void *v, bus_dma_segment_t *segs, int nsegs, off_t off,
12336d3ceb1dSskrll     int prot, int flags)
12346d3ceb1dSskrll {
12356d3ceb1dSskrll 	struct elroy_softc *sc = v;
12366d3ceb1dSskrll 
1237*03ccf6a5Sskrll 	return bus_dmamem_mmap(sc->sc_dmat, segs, nsegs, off, prot, flags);
12386d3ceb1dSskrll }
12396d3ceb1dSskrll 
12406d3ceb1dSskrll const struct hppa_bus_dma_tag elroy_dmat = {
12416d3ceb1dSskrll 	NULL,
12426d3ceb1dSskrll 	elroy_dmamap_create, elroy_dmamap_destroy,
12436d3ceb1dSskrll 	elroy_dmamap_load, elroy_dmamap_load_mbuf,
12446d3ceb1dSskrll 	elroy_dmamap_load_uio, elroy_dmamap_load_raw,
12456d3ceb1dSskrll 	elroy_dmamap_unload, elroy_dmamap_sync,
12466d3ceb1dSskrll 
12476d3ceb1dSskrll 	elroy_dmamem_alloc, elroy_dmamem_free, elroy_dmamem_map,
12486d3ceb1dSskrll 	elroy_dmamem_unmap, elroy_dmamem_mmap
12496d3ceb1dSskrll };
12506d3ceb1dSskrll 
12516d3ceb1dSskrll const struct hppa_pci_chipset_tag elroy_pc = {
125255f4a551Sskrll 	.pc_attach_hook = elroy_attach_hook,
125355f4a551Sskrll 	.pc_bus_maxdevs = elroy_maxdevs,
125455f4a551Sskrll 	.pc_make_tag = elroy_make_tag,
125555f4a551Sskrll 	.pc_decompose_tag = elroy_decompose_tag,
125655f4a551Sskrll 	.pc_conf_read = elroy_conf_read,
125755f4a551Sskrll 	.pc_conf_write = elroy_conf_write,
125855f4a551Sskrll 	.pc_intr_map = apic_intr_map,
125955f4a551Sskrll 	.pc_intr_string = apic_intr_string,
126055f4a551Sskrll 	.pc_intr_establish = apic_intr_establish,
126155f4a551Sskrll 	.pc_intr_disestablish = apic_intr_disestablish,
12626d3ceb1dSskrll #if NCARDBUS > 0
126355f4a551Sskrll 	.pc_alloc_parent = elroy_alloc_parent
12646d3ceb1dSskrll #endif
12656d3ceb1dSskrll };
12666d3ceb1dSskrll 
12676d3ceb1dSskrll void
12686d3ceb1dSskrll elroy_attach(device_t parent, device_t self, void *aux)
12696d3ceb1dSskrll {
12706d3ceb1dSskrll 	struct elroy_softc *sc = device_private(self);
12716d3ceb1dSskrll 	struct confargs *ca = (struct confargs *)aux;
12726d3ceb1dSskrll 	struct pcibus_attach_args pba;
12736d3ceb1dSskrll 	volatile struct elroy_regs *r;
12746d3ceb1dSskrll 	const char *p = NULL, *q;
12756d3ceb1dSskrll 	int i;
12766d3ceb1dSskrll 
12776d3ceb1dSskrll 	sc->sc_dv = self;
12786d3ceb1dSskrll 	sc->sc_hpa = ca->ca_hpa;
12796d3ceb1dSskrll 	sc->sc_bt = ca->ca_iot;
12806d3ceb1dSskrll 	sc->sc_dmat = ca->ca_dmatag;
12816d3ceb1dSskrll 	if (bus_space_map(sc->sc_bt, ca->ca_hpa, ca->ca_hpasz, 0, &sc->sc_bh)) {
12826d3ceb1dSskrll 		aprint_error(": can't map space\n");
12836d3ceb1dSskrll 		return;
12846d3ceb1dSskrll 	}
12856d3ceb1dSskrll 
12866d3ceb1dSskrll 	sc->sc_regs = r = bus_space_vaddr(sc->sc_bt, sc->sc_bh);
12876d3ceb1dSskrll 	elroy_write32(&r->pci_cmdstat, htole32(PCI_COMMAND_IO_ENABLE |
12886d3ceb1dSskrll 	    PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE));
12896d3ceb1dSskrll 
12906d3ceb1dSskrll 	elroy_write32(&r->control, elroy_read32(&r->control) &
12916d3ceb1dSskrll 	    ~htole32(ELROY_CONTROL_RF));
12926d3ceb1dSskrll 	for (i = 5000; i-- &&
12936d3ceb1dSskrll 	    elroy_read32(&r->status) & htole32(ELROY_STATUS_RC); DELAY(10));
12946d3ceb1dSskrll 	if (i < 0) {
12956d3ceb1dSskrll 		char buf[128]; /* XXXNH */
12966d3ceb1dSskrll 
12976d3ceb1dSskrll 		snprintb(buf, sizeof(buf), ELROY_STATUS_BITS,
12986d3ceb1dSskrll 		    htole32(r->status));
12996d3ceb1dSskrll 		aprint_error(": reset failed; status %s\n", buf);
13006d3ceb1dSskrll 		return;
13016d3ceb1dSskrll 	}
13026d3ceb1dSskrll 
13036d3ceb1dSskrll 	q = "";
13046d3ceb1dSskrll 	sc->sc_ver = PCI_REVISION(le32toh(elroy_read32(&r->pci_class)));
13056d3ceb1dSskrll 	switch ((ca->ca_type.iodc_model << 4) |
13066d3ceb1dSskrll 	    (ca->ca_type.iodc_revision >> 4)) {
13076d3ceb1dSskrll 	case 0x782:
13086d3ceb1dSskrll 		p = "Elroy";
13096d3ceb1dSskrll 		switch (sc->sc_ver) {
13106d3ceb1dSskrll 		default:
13116d3ceb1dSskrll 			q = "+";
13126d3ceb1dSskrll 		case 5:	sc->sc_ver = 0x40;	break;
13136d3ceb1dSskrll 		case 4:	sc->sc_ver = 0x30;	break;
13146d3ceb1dSskrll 		case 3:	sc->sc_ver = 0x22;	break;
13156d3ceb1dSskrll 		case 2:	sc->sc_ver = 0x21;	break;
13166d3ceb1dSskrll 		case 1:	sc->sc_ver = 0x20;	break;
13176d3ceb1dSskrll 		case 0:	sc->sc_ver = 0x10;	break;
13186d3ceb1dSskrll 		}
13196d3ceb1dSskrll 		break;
13206d3ceb1dSskrll 
13216d3ceb1dSskrll 	case 0x783:
13226d3ceb1dSskrll 		p = "Mercury";
13236d3ceb1dSskrll 		break;
13246d3ceb1dSskrll 
13256d3ceb1dSskrll 	case 0x784:
13266d3ceb1dSskrll 		p = "Quicksilver";
13276d3ceb1dSskrll 		break;
13286d3ceb1dSskrll 
13296d3ceb1dSskrll 	default:
13306d3ceb1dSskrll 		p = "Mojo";
13316d3ceb1dSskrll 		break;
13326d3ceb1dSskrll 	}
13336d3ceb1dSskrll 
13346d3ceb1dSskrll 	aprint_normal(": %s TR%d.%d%s", p, sc->sc_ver >> 4, sc->sc_ver & 0xf,
13356d3ceb1dSskrll 	    q);
13366d3ceb1dSskrll 	apic_attach(sc);
13376d3ceb1dSskrll 	aprint_normal("\n");
13386d3ceb1dSskrll 
13396d3ceb1dSskrll 	elroy_write32(&r->imask, htole32(0xffffffff << 30));
13406d3ceb1dSskrll 	elroy_write32(&r->ibase, htole32(ELROY_BASE_RE));
13416d3ceb1dSskrll 
13426d3ceb1dSskrll 	/* TODO reserve elroy's pci space ? */
13436d3ceb1dSskrll 
13446d3ceb1dSskrll #if 0
13456d3ceb1dSskrll printf("lmm %llx/%llx gmm %llx/%llx wlm %llx/%llx wgm %llx/%llx io %llx/%llx eio %llx/%llx\n",
13466d3ceb1dSskrll le64toh(r->lmmio_base), le64toh(r->lmmio_mask),
13476d3ceb1dSskrll le64toh(r->gmmio_base), le64toh(r->gmmio_mask),
13486d3ceb1dSskrll le64toh(r->wlmmio_base), le64toh(r->wlmmio_mask),
13496d3ceb1dSskrll le64toh(r->wgmmio_base), le64toh(r->wgmmio_mask),
13506d3ceb1dSskrll le64toh(r->io_base), le64toh(r->io_mask),
13516d3ceb1dSskrll le64toh(r->eio_base), le64toh(r->eio_mask));
13526d3ceb1dSskrll #endif
13536d3ceb1dSskrll 
13546d3ceb1dSskrll 	/* XXX evil hack! */
13556d3ceb1dSskrll 	sc->sc_iobase = 0xfee00000;
13566d3ceb1dSskrll 
13576d3ceb1dSskrll 	sc->sc_iot = elroy_iomemt;
13586d3ceb1dSskrll 	sc->sc_iot.hbt_cookie = sc;
13596d3ceb1dSskrll 	sc->sc_iot.hbt_map = elroy_iomap;
13606d3ceb1dSskrll 	sc->sc_iot.hbt_alloc = elroy_ioalloc;
13616d3ceb1dSskrll 	sc->sc_memt = elroy_iomemt;
13626d3ceb1dSskrll 	sc->sc_memt.hbt_cookie = sc;
13636d3ceb1dSskrll 	sc->sc_memt.hbt_map = elroy_memmap;
13646d3ceb1dSskrll 	sc->sc_memt.hbt_alloc = elroy_memalloc;
13656d3ceb1dSskrll 	sc->sc_pc = elroy_pc;
13666d3ceb1dSskrll 	sc->sc_pc._cookie = sc;
13676d3ceb1dSskrll 	sc->sc_dmatag = elroy_dmat;
13686d3ceb1dSskrll 	sc->sc_dmatag._cookie = sc;
13696d3ceb1dSskrll 
13706d3ceb1dSskrll 	memset(&pba, 0, sizeof(pba));
13716d3ceb1dSskrll 	pba.pba_iot = &sc->sc_iot;
13726d3ceb1dSskrll 	pba.pba_memt = &sc->sc_memt;
13736d3ceb1dSskrll 	pba.pba_dmat = &sc->sc_dmatag;
13746d3ceb1dSskrll 	pba.pba_pc = &sc->sc_pc;
13756d3ceb1dSskrll 	pba.pba_bus = 0; /* (le32toh(elroy_read32(&r->busnum)) & 0xff) >> 4; */
13766d3ceb1dSskrll  	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
13776d3ceb1dSskrll 
1378c7fb772bSthorpej 	config_found(self, &pba, pcibusprint, CFARGS_NONE);
13796d3ceb1dSskrll }
1380