Home | History | Annotate | Line # | Download | only in dev
shpcic.c revision 1.18
      1 /*	$NetBSD: shpcic.c,v 1.18 2015/10/02 05:22:52 msaitoh Exp $	*/
      2 
      3 /*-
      4  * Copyright (C) 2005 NONAKA Kimihiro <nonaka (at) netbsd.org>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include <sys/cdefs.h>
     29 __KERNEL_RCSID(0, "$NetBSD: shpcic.c,v 1.18 2015/10/02 05:22:52 msaitoh Exp $");
     30 
     31 #include "opt_pci.h"
     32 
     33 #include <sys/param.h>
     34 #include <sys/systm.h>
     35 #include <sys/kernel.h>
     36 #include <sys/device.h>
     37 #include <sys/extent.h>
     38 #include <sys/malloc.h>
     39 
     40 #include <dev/pci/pcireg.h>
     41 #include <dev/pci/pcivar.h>
     42 #include <dev/pci/pciconf.h>
     43 #include <dev/pci/pcidevs.h>
     44 
     45 #include <sh3/bscreg.h>
     46 #include <sh3/cache.h>
     47 #include <sh3/exception.h>
     48 #include <sh3/pcicreg.h>
     49 
     50 #include <sys/bus.h>
     51 #include <machine/intr.h>
     52 #include <machine/pci_machdep.h>
     53 
     54 
     55 #if defined(DEBUG) && !defined(SHPCIC_DEBUG)
     56 #define SHPCIC_DEBUG 0
     57 #endif
     58 #if defined(SHPCIC_DEBUG)
     59 int shpcic_debug = SHPCIC_DEBUG + 0;
     60 #define	DPRINTF(arg)	if (shpcic_debug) printf arg
     61 #else
     62 #define	DPRINTF(arg)
     63 #endif
     64 
     65 #define	PCI_MODE1_ENABLE	0x80000000UL
     66 
     67 
     68 static int	shpcic_match(device_t, cfdata_t, void *);
     69 static void	shpcic_attach(device_t, device_t, void *);
     70 
     71 CFATTACH_DECL_NEW(shpcic, 0,
     72     shpcic_match, shpcic_attach, NULL, NULL);
     73 
     74 
     75 /* There can be only one. */
     76 static int shpcic_found = 0;
     77 
     78 /* PCIC intr priotiry */
     79 static int shpcic_intr_priority[2] = { IPL_BIO, IPL_BIO };
     80 
     81 
     82 static int
     83 shpcic_match(device_t parent, cfdata_t cf, void *aux)
     84 {
     85 	pcireg_t id;
     86 
     87 	if (shpcic_found)
     88 		return (0);
     89 
     90 	switch (cpu_product) {
     91 	case CPU_PRODUCT_7751:
     92 	case CPU_PRODUCT_7751R:
     93 		break;
     94 
     95 	default:
     96 		return (0);
     97 	}
     98 
     99 
    100 	id = _reg_read_4(SH4_PCICONF0);
    101 
    102 	switch (PCI_VENDOR(id)) {
    103 	case PCI_VENDOR_HITACHI:
    104 		break;
    105 
    106 	default:
    107 		return (0);
    108 	}
    109 
    110 
    111 	switch (PCI_PRODUCT(id)) {
    112 	case PCI_PRODUCT_HITACHI_SH7751: /* FALLTHROUGH */
    113 	case PCI_PRODUCT_HITACHI_SH7751R:
    114 		break;
    115 
    116 	default:
    117 		return (0);
    118 	}
    119 
    120 	if (_reg_read_2(SH4_BCR2) & BCR2_PORTEN)
    121 		return (0);
    122 
    123 	return (1);
    124 }
    125 
    126 static void
    127 shpcic_attach(device_t parent, device_t self, void *aux)
    128 {
    129 	struct pcibus_attach_args pba;
    130 #ifdef PCI_NETBSD_CONFIGURE
    131 	struct extent *ioext, *memext;
    132 #endif
    133 	pcireg_t id, class;
    134 	char devinfo[256];
    135 
    136 	shpcic_found = 1;
    137 
    138 	aprint_naive("\n");
    139 
    140 	id = _reg_read_4(SH4_PCICONF0);
    141 	class = _reg_read_4(SH4_PCICONF2);
    142 	pci_devinfo(id, class, 1, devinfo, sizeof(devinfo));
    143 	aprint_normal(": %s\n", devinfo);
    144 
    145 	/* allow PCIC request */
    146 	_reg_write_4(SH4_BCR1, _reg_read_4(SH4_BCR1) | BCR1_BREQEN);
    147 
    148 	/* Initialize PCIC */
    149 	_reg_write_4(SH4_PCICR, PCICR_BASE | PCICR_RSTCTL);
    150 	delay(10 * 1000);
    151 	_reg_write_4(SH4_PCICR, PCICR_BASE);
    152 
    153 	/* Class: Host-Bridge */
    154 	_reg_write_4(SH4_PCICONF2,
    155 	    PCI_CLASS_CODE(PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_HOST, 0x00));
    156 
    157 #if !defined(DONT_INIT_PCIBSC)
    158 #if defined(PCIBCR_BCR1_VAL)
    159 	_reg_write_4(SH4_PCIBCR1, PCIBCR_BCR1_VAL);
    160 #else
    161 	_reg_write_4(SH4_PCIBCR1, _reg_read_4(SH4_BCR1) | BCR1_MASTER);
    162 #endif
    163 #if defined(PCIBCR_BCR2_VAL)
    164 	_reg_write_4(SH4_PCIBCR2, PCIBCR_BCR2_VAL);
    165 #else
    166 	_reg_write_4(SH4_PCIBCR2, _reg_read_2(SH4_BCR2));
    167 #endif
    168 #if defined(SH4) && defined(SH7751R)
    169 	if (cpu_product == CPU_PRODUCT_7751R) {
    170 #if defined(PCIBCR_BCR3_VAL)
    171 		_reg_write_4(SH4_PCIBCR3, PCIBCR_BCR3_VAL);
    172 #else
    173 		_reg_write_4(SH4_PCIBCR3, _reg_read_2(SH4_BCR3));
    174 #endif
    175 	}
    176 #endif	/* SH4 && SH7751R && PCIBCR_BCR3_VAL */
    177 #if defined(PCIBCR_WCR1_VAL)
    178 	_reg_write_4(SH4_PCIWCR1, PCIBCR_WCR1_VAL);
    179 #else
    180 	_reg_write_4(SH4_PCIWCR1, _reg_read_4(SH4_WCR1));
    181 #endif
    182 #if defined(PCIBCR_WCR2_VAL)
    183 	_reg_write_4(SH4_PCIWCR2, PCIBCR_WCR2_VAL);
    184 #else
    185 	_reg_write_4(SH4_PCIWCR2, _reg_read_4(SH4_WCR2));
    186 #endif
    187 #if defined(PCIBCR_WCR3_VAL)
    188 	_reg_write_4(SH4_PCIWCR3, PCIBCR_WCR3_VAL);
    189 #else
    190 	_reg_write_4(SH4_PCIWCR3, _reg_read_4(SH4_WCR3));
    191 #endif
    192 #if defined(PCIBCR_MCR_VAL)
    193 	_reg_write_4(SH4_PCIMCR, PCIBCR_MCR_VAL);
    194 #else
    195 	_reg_write_4(SH4_PCIMCR, _reg_read_4(SH4_MCR));
    196 #endif
    197 #endif	/* !DONT_INIT_PCIBSC */
    198 
    199 	/* set PCI I/O, memory base address */
    200 	_reg_write_4(SH4_PCIIOBR, SH4_PCIC_IO);
    201 	_reg_write_4(SH4_PCIMBR, SH4_PCIC_MEM);
    202 
    203 	/* set PCI local address 0 */
    204 	_reg_write_4(SH4_PCILSR0, (64 - 1) << 20);
    205 	_reg_write_4(SH4_PCILAR0, 0xac000000);
    206 	_reg_write_4(SH4_PCICONF5, 0xac000000);
    207 
    208 	/* set PCI local address 1 */
    209 	_reg_write_4(SH4_PCILSR1, (64 - 1) << 20);
    210 	_reg_write_4(SH4_PCILAR1, 0xac000000);
    211 	_reg_write_4(SH4_PCICONF6, 0x8c000000);
    212 
    213 	/* Enable I/O, memory, bus-master */
    214 	_reg_write_4(SH4_PCICONF1, PCI_COMMAND_IO_ENABLE
    215 	                           | PCI_COMMAND_MEM_ENABLE
    216 	                           | PCI_COMMAND_MASTER_ENABLE
    217 	                           | PCI_COMMAND_STEPPING_ENABLE
    218 				   | PCI_STATUS_DEVSEL_MEDIUM);
    219 
    220 	/* Initialize done. */
    221 	_reg_write_4(SH4_PCICR, PCICR_BASE | PCICR_CFINIT);
    222 
    223 	/* set PCI controller interrupt priority */
    224 	intpri_intr_priority(SH4_INTEVT_PCIERR, shpcic_intr_priority[0]);
    225 	intpri_intr_priority(SH4_INTEVT_PCISERR, shpcic_intr_priority[1]);
    226 
    227 	/* PCI bus */
    228 #ifdef PCI_NETBSD_CONFIGURE
    229 	ioext  = extent_create("pciio",
    230 	    SH4_PCIC_IO, SH4_PCIC_IO + SH4_PCIC_IO_SIZE - 1,
    231 	    NULL, 0, EX_NOWAIT);
    232 	memext = extent_create("pcimem",
    233 	    SH4_PCIC_MEM, SH4_PCIC_MEM + SH4_PCIC_MEM_SIZE - 1,
    234 	    NULL, 0, EX_NOWAIT);
    235 
    236 	pci_configure_bus(NULL, ioext, memext, NULL, 0, sh_cache_line_size);
    237 
    238 	extent_destroy(ioext);
    239 	extent_destroy(memext);
    240 #endif
    241 
    242 	/* PCI bus */
    243 	memset(&pba, 0, sizeof(pba));
    244 	pba.pba_iot = shpcic_get_bus_io_tag();
    245 	pba.pba_memt = shpcic_get_bus_mem_tag();
    246 	pba.pba_dmat = shpcic_get_bus_dma_tag();
    247 	pba.pba_dmat64 = NULL;
    248 	pba.pba_pc = NULL;
    249 	pba.pba_bus = 0;
    250 	pba.pba_bridgetag = NULL;
    251 	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
    252 	config_found(self, &pba, NULL);
    253 }
    254 
    255 int
    256 shpcic_bus_maxdevs(void *v, int busno)
    257 {
    258 
    259 	/*
    260 	 * Bus number is irrelevant.  Configuration Mechanism 1 is in
    261 	 * use, can have devices 0-32 (i.e. the `normal' range).
    262 	 */
    263 	return (32);
    264 }
    265 
    266 pcitag_t
    267 shpcic_make_tag(void *v, int bus, int device, int function)
    268 {
    269 	pcitag_t tag;
    270 
    271 	if (bus >= 256 || device >= 32 || function >= 8)
    272 		panic("pci_make_tag: bad request");
    273 
    274 	tag = PCI_MODE1_ENABLE |
    275 		    (bus << 16) | (device << 11) | (function << 8);
    276 
    277 	return (tag);
    278 }
    279 
    280 void
    281 shpcic_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp)
    282 {
    283 
    284 	if (bp != NULL)
    285 		*bp = (tag >> 16) & 0xff;
    286 	if (dp != NULL)
    287 		*dp = (tag >> 11) & 0x1f;
    288 	if (fp != NULL)
    289 		*fp = (tag >> 8) & 0x7;
    290 }
    291 
    292 pcireg_t
    293 shpcic_conf_read(void *v, pcitag_t tag, int reg)
    294 {
    295 	pcireg_t data;
    296 	int s;
    297 
    298 	if ((unsigned int)reg >= PCI_CONF_SIZE)
    299 		return (pcireg_t) -1;
    300 
    301 	s = splhigh();
    302 	_reg_write_4(SH4_PCIPAR, tag | reg);
    303 	data = _reg_read_4(SH4_PCIPDR);
    304 	_reg_write_4(SH4_PCIPAR, 0);
    305 	splx(s);
    306 
    307 	return data;
    308 }
    309 
    310 void
    311 shpcic_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
    312 {
    313 	int s;
    314 
    315 	if ((unsigned int)reg >= PCI_CONF_SIZE)
    316 		return;
    317 
    318 	s = splhigh();
    319 	_reg_write_4(SH4_PCIPAR, tag | reg);
    320 	_reg_write_4(SH4_PCIPDR, data);
    321 	_reg_write_4(SH4_PCIPAR, 0);
    322 	splx(s);
    323 }
    324 
    325 int
    326 shpcic_set_intr_priority(int intr, int level)
    327 {
    328 	int evtcode;
    329 
    330 	if ((intr != 0) && (intr != 1)) {
    331 		return (-1);
    332 	}
    333 	if ((level < IPL_NONE) || (level > IPL_HIGH)) {
    334 		return (-1);
    335 	}
    336 
    337 	if (intr == 0) {
    338 		evtcode = SH4_INTEVT_PCIERR;
    339 	} else {
    340 		evtcode = SH4_INTEVT_PCISERR;
    341 	}
    342 
    343 	intpri_intr_priority(evtcode, shpcic_intr_priority[intr]);
    344 	shpcic_intr_priority[intr] = level;
    345 
    346 	return (0);
    347 }
    348 
    349 void *
    350 shpcic_intr_establish(int evtcode, int (*ih_func)(void *), void *ih_arg)
    351 {
    352 	int level;
    353 
    354 	switch (evtcode) {
    355 	case SH4_INTEVT_PCISERR:
    356 		level = shpcic_intr_priority[1];
    357 		break;
    358 
    359 	case SH4_INTEVT_PCIDMA3:
    360 	case SH4_INTEVT_PCIDMA2:
    361 	case SH4_INTEVT_PCIDMA1:
    362 	case SH4_INTEVT_PCIDMA0:
    363 	case SH4_INTEVT_PCIPWON:
    364 	case SH4_INTEVT_PCIPWDWN:
    365 	case SH4_INTEVT_PCIERR:
    366 		level = shpcic_intr_priority[0];
    367 		break;
    368 
    369 	default:
    370 		printf("shpcic_intr_establish: unknown evtcode = 0x%08x\n",
    371 		    evtcode);
    372 		return NULL;
    373 	}
    374 
    375 	return intc_intr_establish(evtcode, IST_LEVEL, level, ih_func, ih_arg);
    376 }
    377 
    378 void
    379 shpcic_intr_disestablish(void *ih)
    380 {
    381 
    382 	intc_intr_disestablish(ih);
    383 }
    384 
    385 /*
    386  * shpcic bus space
    387  */
    388 int
    389 shpcic_iomem_map(void *v, bus_addr_t bpa, bus_size_t size,
    390     int flags, bus_space_handle_t *bshp)
    391 {
    392 
    393 	*bshp = (bus_space_handle_t)bpa;
    394 
    395 	return (0);
    396 }
    397 
    398 void
    399 shpcic_iomem_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
    400 {
    401 
    402 	/* Nothing to do */
    403 }
    404 
    405 int
    406 shpcic_iomem_subregion(void *v, bus_space_handle_t bsh,
    407     bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
    408 {
    409 
    410 	*nbshp = bsh + offset;
    411 
    412 	return (0);
    413 }
    414 
    415 int
    416 shpcic_iomem_alloc(void *v, bus_addr_t rstart, bus_addr_t rend,
    417     bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
    418     bus_addr_t *bpap, bus_space_handle_t *bshp)
    419 {
    420 
    421 	*bshp = *bpap = rstart;
    422 
    423 	return (0);
    424 }
    425 
    426 void
    427 shpcic_iomem_free(void *v, bus_space_handle_t bsh, bus_size_t size)
    428 {
    429 
    430 	/* Nothing to do */
    431 }
    432 
    433 paddr_t
    434 shpcic_iomem_mmap(void *v, bus_addr_t addr, off_t off, int prot, int flags)
    435 {
    436 
    437 	return (paddr_t)-1;
    438 }
    439 
    440 /*
    441  * shpcic bus space io/mem read/write
    442  */
    443 /* read */
    444 static inline uint8_t __shpcic_io_read_1(bus_space_handle_t bsh,
    445     bus_size_t offset);
    446 static inline uint16_t __shpcic_io_read_2(bus_space_handle_t bsh,
    447     bus_size_t offset);
    448 static inline uint32_t __shpcic_io_read_4(bus_space_handle_t bsh,
    449     bus_size_t offset);
    450 static inline uint8_t __shpcic_mem_read_1(bus_space_handle_t bsh,
    451     bus_size_t offset);
    452 static inline uint16_t __shpcic_mem_read_2(bus_space_handle_t bsh,
    453     bus_size_t offset);
    454 static inline uint32_t __shpcic_mem_read_4(bus_space_handle_t bsh,
    455     bus_size_t offset);
    456 
    457 static inline uint8_t
    458 __shpcic_io_read_1(bus_space_handle_t bsh, bus_size_t offset)
    459 {
    460 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
    461 
    462 	return *(volatile uint8_t *)(SH4_PCIC_IO + adr);
    463 }
    464 
    465 static inline uint16_t
    466 __shpcic_io_read_2(bus_space_handle_t bsh, bus_size_t offset)
    467 {
    468 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
    469 
    470 	return *(volatile uint16_t *)(SH4_PCIC_IO + adr);
    471 }
    472 
    473 static inline uint32_t
    474 __shpcic_io_read_4(bus_space_handle_t bsh, bus_size_t offset)
    475 {
    476 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
    477 
    478 	return *(volatile uint32_t *)(SH4_PCIC_IO + adr);
    479 }
    480 
    481 static inline uint8_t
    482 __shpcic_mem_read_1(bus_space_handle_t bsh, bus_size_t offset)
    483 {
    484 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
    485 
    486 	return *(volatile uint8_t *)(SH4_PCIC_MEM + adr);
    487 }
    488 
    489 static inline uint16_t
    490 __shpcic_mem_read_2(bus_space_handle_t bsh, bus_size_t offset)
    491 {
    492 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
    493 
    494 	return *(volatile uint16_t *)(SH4_PCIC_MEM + adr);
    495 }
    496 
    497 static inline uint32_t
    498 __shpcic_mem_read_4(bus_space_handle_t bsh, bus_size_t offset)
    499 {
    500 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
    501 
    502 	return *(volatile uint32_t *)(SH4_PCIC_MEM + adr);
    503 }
    504 
    505 /*
    506  * read single
    507  */
    508 uint8_t
    509 shpcic_io_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset)
    510 {
    511 	uint8_t value;
    512 
    513 	value = __shpcic_io_read_1(bsh, offset);
    514 
    515 	return value;
    516 }
    517 
    518 uint16_t
    519 shpcic_io_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset)
    520 {
    521 	uint16_t value;
    522 
    523 	value = __shpcic_io_read_2(bsh, offset);
    524 
    525 	return value;
    526 }
    527 
    528 uint32_t
    529 shpcic_io_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset)
    530 {
    531 	uint32_t value;
    532 
    533 	value = __shpcic_io_read_4(bsh, offset);
    534 
    535 	return value;
    536 }
    537 
    538 uint8_t
    539 shpcic_mem_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset)
    540 {
    541 	uint8_t value;
    542 
    543 	value = __shpcic_mem_read_1(bsh, offset);
    544 
    545 	return value;
    546 }
    547 
    548 uint16_t
    549 shpcic_mem_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset)
    550 {
    551 	uint16_t value;
    552 
    553 	value = __shpcic_mem_read_2(bsh, offset);
    554 
    555 	return value;
    556 }
    557 
    558 uint32_t
    559 shpcic_mem_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset)
    560 {
    561 	uint32_t value;
    562 
    563 	value = __shpcic_mem_read_4(bsh, offset);
    564 
    565 	return value;
    566 }
    567 
    568 /*
    569  * read multi
    570  */
    571 void
    572 shpcic_io_read_multi_1(void *v, bus_space_handle_t bsh,
    573     bus_size_t offset, uint8_t *addr, bus_size_t count)
    574 {
    575 
    576 	while (count--) {
    577 		*addr++ = __shpcic_io_read_1(bsh, offset);
    578 	}
    579 }
    580 
    581 void
    582 shpcic_io_read_multi_2(void *v, bus_space_handle_t bsh,
    583     bus_size_t offset, uint16_t *addr, bus_size_t count)
    584 {
    585 
    586 	while (count--) {
    587 		*addr++ = __shpcic_io_read_2(bsh, offset);
    588 	}
    589 }
    590 
    591 void
    592 shpcic_io_read_multi_4(void *v, bus_space_handle_t bsh,
    593     bus_size_t offset, uint32_t *addr, bus_size_t count)
    594 {
    595 
    596 	while (count--) {
    597 		*addr++ = __shpcic_io_read_4(bsh, offset);
    598 	}
    599 }
    600 
    601 void
    602 shpcic_mem_read_multi_1(void *v, bus_space_handle_t bsh,
    603     bus_size_t offset, uint8_t *addr, bus_size_t count)
    604 {
    605 
    606 	while (count--) {
    607 		*addr++ = __shpcic_mem_read_1(bsh, offset);
    608 	}
    609 }
    610 
    611 void
    612 shpcic_mem_read_multi_2(void *v, bus_space_handle_t bsh,
    613     bus_size_t offset, uint16_t *addr, bus_size_t count)
    614 {
    615 
    616 	while (count--) {
    617 		*addr++ = __shpcic_mem_read_2(bsh, offset);
    618 	}
    619 }
    620 
    621 void
    622 shpcic_mem_read_multi_4(void *v, bus_space_handle_t bsh,
    623     bus_size_t offset, uint32_t *addr, bus_size_t count)
    624 {
    625 
    626 	while (count--) {
    627 		*addr++ = __shpcic_mem_read_4(bsh, offset);
    628 	}
    629 }
    630 
    631 /*
    632  *
    633  * read region
    634  */
    635 void
    636 shpcic_io_read_region_1(void *v, bus_space_handle_t bsh,
    637     bus_size_t offset, uint8_t *addr, bus_size_t count)
    638 {
    639 
    640 	while (count--) {
    641 		*addr++ = __shpcic_io_read_1(bsh, offset);
    642 		offset += 1;
    643 	}
    644 }
    645 
    646 void
    647 shpcic_io_read_region_2(void *v, bus_space_handle_t bsh,
    648     bus_size_t offset, uint16_t *addr, bus_size_t count)
    649 {
    650 
    651 	while (count--) {
    652 		*addr++ = __shpcic_io_read_2(bsh, offset);
    653 		offset += 2;
    654 	}
    655 }
    656 
    657 void
    658 shpcic_io_read_region_4(void *v, bus_space_handle_t bsh,
    659     bus_size_t offset, uint32_t *addr, bus_size_t count)
    660 {
    661 
    662 	while (count--) {
    663 		*addr++ = __shpcic_io_read_4(bsh, offset);
    664 		offset += 4;
    665 	}
    666 }
    667 
    668 void
    669 shpcic_mem_read_region_1(void *v, bus_space_handle_t bsh,
    670     bus_size_t offset, uint8_t *addr, bus_size_t count)
    671 {
    672 
    673 	while (count--) {
    674 		*addr++ = __shpcic_mem_read_1(bsh, offset);
    675 		offset += 1;
    676 	}
    677 }
    678 
    679 void
    680 shpcic_mem_read_region_2(void *v, bus_space_handle_t bsh,
    681     bus_size_t offset, uint16_t *addr, bus_size_t count)
    682 {
    683 
    684 	while (count--) {
    685 		*addr++ = __shpcic_mem_read_2(bsh, offset);
    686 		offset += 2;
    687 	}
    688 }
    689 
    690 void
    691 shpcic_mem_read_region_4(void *v, bus_space_handle_t bsh,
    692     bus_size_t offset, uint32_t *addr, bus_size_t count)
    693 {
    694 
    695 	while (count--) {
    696 		*addr++ = __shpcic_mem_read_4(bsh, offset);
    697 		offset += 4;
    698 	}
    699 }
    700 
    701 /* write */
    702 static inline void __shpcic_io_write_1(bus_space_handle_t bsh,
    703     bus_size_t offset, uint8_t value);
    704 static inline void __shpcic_io_write_2(bus_space_handle_t bsh,
    705     bus_size_t offset, uint16_t value);
    706 static inline void __shpcic_io_write_4(bus_space_handle_t bsh,
    707     bus_size_t offset, uint32_t value);
    708 static inline void __shpcic_mem_write_1(bus_space_handle_t bsh,
    709     bus_size_t offset, uint8_t value);
    710 static inline void __shpcic_mem_write_2(bus_space_handle_t bsh,
    711     bus_size_t offset, uint16_t value);
    712 static inline void __shpcic_mem_write_4(bus_space_handle_t bsh,
    713     bus_size_t offset, uint32_t value);
    714 
    715 static inline void
    716 __shpcic_io_write_1(bus_space_handle_t bsh, bus_size_t offset,
    717     uint8_t value)
    718 {
    719 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
    720 
    721 	*(volatile uint8_t *)(SH4_PCIC_IO + adr) = value;
    722 }
    723 
    724 static inline void
    725 __shpcic_io_write_2(bus_space_handle_t bsh, bus_size_t offset,
    726     uint16_t value)
    727 {
    728 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
    729 
    730 	*(volatile uint16_t *)(SH4_PCIC_IO + adr) = value;
    731 }
    732 
    733 static inline void
    734 __shpcic_io_write_4(bus_space_handle_t bsh, bus_size_t offset,
    735     uint32_t value)
    736 {
    737 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
    738 
    739 	*(volatile uint32_t *)(SH4_PCIC_IO + adr) = value;
    740 }
    741 
    742 static inline void
    743 __shpcic_mem_write_1(bus_space_handle_t bsh, bus_size_t offset,
    744     uint8_t value)
    745 {
    746 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
    747 
    748 	*(volatile uint8_t *)(SH4_PCIC_MEM + adr) = value;
    749 }
    750 
    751 static inline void
    752 __shpcic_mem_write_2(bus_space_handle_t bsh, bus_size_t offset,
    753     uint16_t value)
    754 {
    755 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
    756 
    757 	*(volatile uint16_t *)(SH4_PCIC_MEM + adr) = value;
    758 }
    759 
    760 static inline void
    761 __shpcic_mem_write_4(bus_space_handle_t bsh, bus_size_t offset,
    762     uint32_t value)
    763 {
    764 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
    765 
    766 	*(volatile uint32_t *)(SH4_PCIC_MEM + adr) = value;
    767 }
    768 
    769 /*
    770  * write single
    771  */
    772 void
    773 shpcic_io_write_1(void *v, bus_space_handle_t bsh,
    774     bus_size_t offset, uint8_t value)
    775 {
    776 
    777 	__shpcic_io_write_1(bsh, offset, value);
    778 }
    779 
    780 void
    781 shpcic_io_write_2(void *v, bus_space_handle_t bsh,
    782     bus_size_t offset, uint16_t value)
    783 {
    784 
    785 	__shpcic_io_write_2(bsh, offset, value);
    786 }
    787 
    788 void
    789 shpcic_io_write_4(void *v, bus_space_handle_t bsh,
    790     bus_size_t offset, uint32_t value)
    791 {
    792 
    793 	__shpcic_io_write_4(bsh, offset, value);
    794 }
    795 
    796 void
    797 shpcic_mem_write_1(void *v, bus_space_handle_t bsh,
    798     bus_size_t offset, uint8_t value)
    799 {
    800 
    801 	__shpcic_mem_write_1(bsh, offset, value);
    802 }
    803 
    804 void
    805 shpcic_mem_write_2(void *v, bus_space_handle_t bsh,
    806     bus_size_t offset, uint16_t value)
    807 {
    808 
    809 	__shpcic_mem_write_2(bsh, offset, value);
    810 }
    811 
    812 void
    813 shpcic_mem_write_4(void *v, bus_space_handle_t bsh,
    814     bus_size_t offset, uint32_t value)
    815 {
    816 
    817 	__shpcic_mem_write_4(bsh, offset, value);
    818 }
    819 
    820 /*
    821  * write multi
    822  */
    823 void
    824 shpcic_io_write_multi_1(void *v, bus_space_handle_t bsh,
    825     bus_size_t offset, const uint8_t *addr, bus_size_t count)
    826 {
    827 
    828 	while (count--) {
    829 		__shpcic_io_write_1(bsh, offset, *addr++);
    830 	}
    831 }
    832 
    833 void
    834 shpcic_io_write_multi_2(void *v, bus_space_handle_t bsh,
    835     bus_size_t offset, const uint16_t *addr, bus_size_t count)
    836 {
    837 
    838 	while (count--) {
    839 		__shpcic_io_write_2(bsh, offset, *addr++);
    840 	}
    841 }
    842 
    843 void
    844 shpcic_io_write_multi_4(void *v, bus_space_handle_t bsh,
    845     bus_size_t offset, const uint32_t *addr, bus_size_t count)
    846 {
    847 
    848 	while (count--) {
    849 		__shpcic_io_write_4(bsh, offset, *addr++);
    850 	}
    851 }
    852 
    853 void
    854 shpcic_mem_write_multi_1(void *v, bus_space_handle_t bsh,
    855     bus_size_t offset, const uint8_t *addr, bus_size_t count)
    856 {
    857 
    858 	while (count--) {
    859 		__shpcic_mem_write_1(bsh, offset, *addr++);
    860 	}
    861 }
    862 
    863 void
    864 shpcic_mem_write_multi_2(void *v, bus_space_handle_t bsh,
    865     bus_size_t offset, const uint16_t *addr, bus_size_t count)
    866 {
    867 
    868 	while (count--) {
    869 		__shpcic_mem_write_2(bsh, offset, *addr++);
    870 	}
    871 }
    872 
    873 void
    874 shpcic_mem_write_multi_4(void *v, bus_space_handle_t bsh,
    875     bus_size_t offset, const uint32_t *addr, bus_size_t count)
    876 {
    877 
    878 	while (count--) {
    879 		__shpcic_mem_write_4(bsh, offset, *addr++);
    880 	}
    881 }
    882 
    883 /*
    884  * write region
    885  */
    886 void
    887 shpcic_io_write_region_1(void *v, bus_space_handle_t bsh,
    888     bus_size_t offset, const uint8_t *addr, bus_size_t count)
    889 {
    890 
    891 	while (count--) {
    892 		__shpcic_io_write_1(bsh, offset, *addr++);
    893 		offset += 1;
    894 	}
    895 }
    896 
    897 void
    898 shpcic_io_write_region_2(void *v, bus_space_handle_t bsh,
    899     bus_size_t offset, const uint16_t *addr, bus_size_t count)
    900 {
    901 
    902 	while (count--) {
    903 		__shpcic_io_write_2(bsh, offset, *addr++);
    904 		offset += 2;
    905 	}
    906 }
    907 
    908 void
    909 shpcic_io_write_region_4(void *v, bus_space_handle_t bsh,
    910     bus_size_t offset, const uint32_t *addr, bus_size_t count)
    911 {
    912 
    913 	while (count--) {
    914 		__shpcic_io_write_4(bsh, offset, *addr++);
    915 		offset += 4;
    916 	}
    917 }
    918 
    919 void
    920 shpcic_mem_write_region_1(void *v, bus_space_handle_t bsh,
    921     bus_size_t offset, const uint8_t *addr, bus_size_t count)
    922 {
    923 
    924 	while (count--) {
    925 		__shpcic_mem_write_1(bsh, offset, *addr++);
    926 		offset += 1;
    927 	}
    928 }
    929 
    930 void
    931 shpcic_mem_write_region_2(void *v, bus_space_handle_t bsh,
    932     bus_size_t offset, const uint16_t *addr, bus_size_t count)
    933 {
    934 
    935 	while (count--) {
    936 		__shpcic_mem_write_2(bsh, offset, *addr++);
    937 		offset += 2;
    938 	}
    939 }
    940 
    941 void
    942 shpcic_mem_write_region_4(void *v, bus_space_handle_t bsh,
    943     bus_size_t offset, const uint32_t *addr, bus_size_t count)
    944 {
    945 
    946 	while (count--) {
    947 		__shpcic_mem_write_4(bsh, offset, *addr++);
    948 		offset += 4;
    949 	}
    950 }
    951 
    952 /*
    953  * set multi
    954  */
    955 void
    956 shpcic_io_set_multi_1(void *v, bus_space_handle_t bsh,
    957     bus_size_t offset, uint8_t value, bus_size_t count)
    958 {
    959 
    960 	while (count--) {
    961 		__shpcic_io_write_1(bsh, offset, value);
    962 	}
    963 }
    964 
    965 void
    966 shpcic_io_set_multi_2(void *v, bus_space_handle_t bsh,
    967     bus_size_t offset, uint16_t value, bus_size_t count)
    968 {
    969 
    970 	while (count--) {
    971 		__shpcic_io_write_2(bsh, offset, value);
    972 	}
    973 }
    974 
    975 void
    976 shpcic_io_set_multi_4(void *v, bus_space_handle_t bsh,
    977     bus_size_t offset, uint32_t value, bus_size_t count)
    978 {
    979 
    980 	while (count--) {
    981 		__shpcic_io_write_4(bsh, offset, value);
    982 	}
    983 }
    984 
    985 void
    986 shpcic_mem_set_multi_1(void *v, bus_space_handle_t bsh,
    987     bus_size_t offset, uint8_t value, bus_size_t count)
    988 {
    989 
    990 	while (count--) {
    991 		__shpcic_mem_write_1(bsh, offset, value);
    992 	}
    993 }
    994 
    995 void
    996 shpcic_mem_set_multi_2(void *v, bus_space_handle_t bsh,
    997     bus_size_t offset, uint16_t value, bus_size_t count)
    998 {
    999 
   1000 	while (count--) {
   1001 		__shpcic_mem_write_2(bsh, offset, value);
   1002 	}
   1003 }
   1004 
   1005 void
   1006 shpcic_mem_set_multi_4(void *v, bus_space_handle_t bsh,
   1007     bus_size_t offset, uint32_t value, bus_size_t count)
   1008 {
   1009 
   1010 	while (count--) {
   1011 		__shpcic_mem_write_4(bsh, offset, value);
   1012 	}
   1013 }
   1014 
   1015 /*
   1016  * set region
   1017  */
   1018 void
   1019 shpcic_io_set_region_1(void *v, bus_space_handle_t bsh,
   1020     bus_size_t offset, uint8_t value, bus_size_t count)
   1021 {
   1022 
   1023 	while (count--) {
   1024 		__shpcic_io_write_1(bsh, offset, value);
   1025 		offset += 1;
   1026 	}
   1027 }
   1028 
   1029 void
   1030 shpcic_io_set_region_2(void *v, bus_space_handle_t bsh,
   1031     bus_size_t offset, uint16_t value, bus_size_t count)
   1032 {
   1033 
   1034 	while (count--) {
   1035 		__shpcic_io_write_2(bsh, offset, value);
   1036 		offset += 2;
   1037 	}
   1038 }
   1039 
   1040 void
   1041 shpcic_io_set_region_4(void *v, bus_space_handle_t bsh,
   1042     bus_size_t offset, uint32_t value, bus_size_t count)
   1043 {
   1044 
   1045 	while (count--) {
   1046 		__shpcic_io_write_4(bsh, offset, value);
   1047 		offset += 4;
   1048 	}
   1049 }
   1050 
   1051 void
   1052 shpcic_mem_set_region_1(void *v, bus_space_handle_t bsh,
   1053     bus_size_t offset, uint8_t value, bus_size_t count)
   1054 {
   1055 
   1056 	while (count--) {
   1057 		__shpcic_mem_write_1(bsh, offset, value);
   1058 		offset += 1;
   1059 	}
   1060 }
   1061 
   1062 void
   1063 shpcic_mem_set_region_2(void *v, bus_space_handle_t bsh,
   1064     bus_size_t offset, uint16_t value, bus_size_t count)
   1065 {
   1066 
   1067 	while (count--) {
   1068 		__shpcic_mem_write_2(bsh, offset, value);
   1069 		offset += 2;
   1070 	}
   1071 }
   1072 
   1073 void
   1074 shpcic_mem_set_region_4(void *v, bus_space_handle_t bsh,
   1075     bus_size_t offset, uint32_t value, bus_size_t count)
   1076 {
   1077 
   1078 	while (count--) {
   1079 		__shpcic_mem_write_4(bsh, offset, value);
   1080 		offset += 4;
   1081 	}
   1082 }
   1083 
   1084 /*
   1085  * copy region
   1086  */
   1087 void
   1088 shpcic_io_copy_region_1(void *v, bus_space_handle_t bsh1,
   1089     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
   1090 {
   1091 	u_long addr1 = bsh1 + off1;
   1092 	u_long addr2 = bsh2 + off2;
   1093 	uint8_t value;
   1094 
   1095 	if (addr1 >= addr2) {	/* src after dest: copy forward */
   1096 		while (count--) {
   1097 			value = __shpcic_io_read_1(bsh1, off1);
   1098 			__shpcic_io_write_1(bsh2, off2, value);
   1099 			off1 += 1;
   1100 			off2 += 1;
   1101 		}
   1102 	} else {		/* dest after src: copy backwards */
   1103 		off1 += (count - 1) * 1;
   1104 		off2 += (count - 1) * 1;
   1105 		while (count--) {
   1106 			value = __shpcic_io_read_1(bsh1, off1);
   1107 			__shpcic_io_write_1(bsh2, off2, value);
   1108 			off1 -= 1;
   1109 			off2 -= 1;
   1110 		}
   1111 	}
   1112 }
   1113 
   1114 void
   1115 shpcic_io_copy_region_2(void *v, bus_space_handle_t bsh1,
   1116     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
   1117 {
   1118 	u_long addr1 = bsh1 + off1;
   1119 	u_long addr2 = bsh2 + off2;
   1120 	uint16_t value;
   1121 
   1122 	if (addr1 >= addr2) {	/* src after dest: copy forward */
   1123 		while (count--) {
   1124 			value = __shpcic_io_read_2(bsh1, off1);
   1125 			__shpcic_io_write_2(bsh2, off2, value);
   1126 			off1 += 2;
   1127 			off2 += 2;
   1128 		}
   1129 	} else {		/* dest after src: copy backwards */
   1130 		off1 += (count - 1) * 2;
   1131 		off2 += (count - 1) * 2;
   1132 		while (count--) {
   1133 			value = __shpcic_io_read_2(bsh1, off1);
   1134 			__shpcic_io_write_2(bsh2, off2, value);
   1135 			off1 -= 2;
   1136 			off2 -= 2;
   1137 		}
   1138 	}
   1139 }
   1140 
   1141 void
   1142 shpcic_io_copy_region_4(void *v, bus_space_handle_t bsh1,
   1143     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
   1144 {
   1145 	u_long addr1 = bsh1 + off1;
   1146 	u_long addr2 = bsh2 + off2;
   1147 	uint32_t value;
   1148 
   1149 	if (addr1 >= addr2) {	/* src after dest: copy forward */
   1150 		while (count--) {
   1151 			value = __shpcic_io_read_4(bsh1, off1);
   1152 			__shpcic_io_write_4(bsh2, off2, value);
   1153 			off1 += 4;
   1154 			off2 += 4;
   1155 		}
   1156 	} else {		/* dest after src: copy backwards */
   1157 		off1 += (count - 1) * 4;
   1158 		off2 += (count - 1) * 4;
   1159 		while (count--) {
   1160 			value = __shpcic_io_read_4(bsh1, off1);
   1161 			__shpcic_io_write_4(bsh2, off2, value);
   1162 			off1 -= 4;
   1163 			off2 -= 4;
   1164 		}
   1165 	}
   1166 }
   1167 
   1168 void
   1169 shpcic_mem_copy_region_1(void *v, bus_space_handle_t bsh1,
   1170     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
   1171 {
   1172 	u_long addr1 = bsh1 + off1;
   1173 	u_long addr2 = bsh2 + off2;
   1174 	uint8_t value;
   1175 
   1176 	if (addr1 >= addr2) {	/* src after dest: copy forward */
   1177 		while (count--) {
   1178 			value = __shpcic_mem_read_1(bsh1, off1);
   1179 			__shpcic_mem_write_1(bsh2, off2, value);
   1180 			off1 += 1;
   1181 			off2 += 1;
   1182 		}
   1183 	} else {		/* dest after src: copy backwards */
   1184 		off1 += (count - 1) * 1;
   1185 		off2 += (count - 1) * 1;
   1186 		while (count--) {
   1187 			value = __shpcic_mem_read_1(bsh1, off1);
   1188 			__shpcic_mem_write_1(bsh2, off2, value);
   1189 			off1 -= 1;
   1190 			off2 -= 1;
   1191 		}
   1192 	}
   1193 }
   1194 
   1195 void
   1196 shpcic_mem_copy_region_2(void *v, bus_space_handle_t bsh1,
   1197     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
   1198 {
   1199 	u_long addr1 = bsh1 + off1;
   1200 	u_long addr2 = bsh2 + off2;
   1201 	uint16_t value;
   1202 
   1203 	if (addr1 >= addr2) {	/* src after dest: copy forward */
   1204 		while (count--) {
   1205 			value = __shpcic_mem_read_2(bsh1, off1);
   1206 			__shpcic_mem_write_2(bsh2, off2, value);
   1207 			off1 += 2;
   1208 			off2 += 2;
   1209 		}
   1210 	} else {		/* dest after src: copy backwards */
   1211 		off1 += (count - 1) * 2;
   1212 		off2 += (count - 1) * 2;
   1213 		while (count--) {
   1214 			value = __shpcic_mem_read_2(bsh1, off1);
   1215 			__shpcic_mem_write_2(bsh2, off2, value);
   1216 			off1 -= 2;
   1217 			off2 -= 2;
   1218 		}
   1219 	}
   1220 }
   1221 
   1222 void
   1223 shpcic_mem_copy_region_4(void *v, bus_space_handle_t bsh1,
   1224     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
   1225 {
   1226 	u_long addr1 = bsh1 + off1;
   1227 	u_long addr2 = bsh2 + off2;
   1228 	uint32_t value;
   1229 
   1230 	if (addr1 >= addr2) {	/* src after dest: copy forward */
   1231 		while (count--) {
   1232 			value = __shpcic_mem_read_4(bsh1, off1);
   1233 			__shpcic_mem_write_4(bsh2, off2, value);
   1234 			off1 += 4;
   1235 			off2 += 4;
   1236 		}
   1237 	} else {		/* dest after src: copy backwards */
   1238 		off1 += (count - 1) * 4;
   1239 		off2 += (count - 1) * 4;
   1240 		while (count--) {
   1241 			value = __shpcic_mem_read_4(bsh1, off1);
   1242 			__shpcic_mem_write_4(bsh2, off2, value);
   1243 			off1 -= 4;
   1244 			off2 -= 4;
   1245 		}
   1246 	}
   1247 }
   1248