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