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