Home | History | Annotate | Line # | Download | only in dev
shpcic.c revision 1.11
      1 /*	$NetBSD: shpcic.c,v 1.11 2007/11/06 03:23:15 uwe 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.11 2007/11/06 03:23:15 uwe 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 
     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, struct cfdata *, void *);
     69 static void	shpcic_attach(device_t, device_t, void *);
     70 
     71 CFATTACH_DECL(shpcic, sizeof(struct device),
     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, struct cfdata *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 	    M_DEVBUF, NULL, 0, EX_NOWAIT);
    232 	memext = extent_create("pcimem",
    233 	    SH4_PCIC_MEM, SH4_PCIC_MEM + SH4_PCIC_MEM_SIZE - 1,
    234 	    M_DEVBUF, 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_ENABLED | PCI_FLAGS_MEM_ENABLED;
    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 	s = splhigh();
    299 	_reg_write_4(SH4_PCIPAR, tag | reg);
    300 	data = _reg_read_4(SH4_PCIPDR);
    301 	_reg_write_4(SH4_PCIPAR, 0);
    302 	splx(s);
    303 
    304 	return data;
    305 }
    306 
    307 void
    308 shpcic_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
    309 {
    310 	int s;
    311 
    312 	s = splhigh();
    313 	_reg_write_4(SH4_PCIPAR, tag | reg);
    314 	_reg_write_4(SH4_PCIPDR, data);
    315 	_reg_write_4(SH4_PCIPAR, 0);
    316 	splx(s);
    317 }
    318 
    319 int
    320 shpcic_set_intr_priority(int intr, int level)
    321 {
    322 	int evtcode;
    323 
    324 	if ((intr != 0) && (intr != 1)) {
    325 		return (-1);
    326 	}
    327 	if ((level < IPL_NONE) || (level > IPL_HIGH)) {
    328 		return (-1);
    329 	}
    330 
    331 	if (intr == 0) {
    332 		evtcode = SH4_INTEVT_PCIERR;
    333 	} else {
    334 		evtcode = SH4_INTEVT_PCISERR;
    335 	}
    336 
    337 	intpri_intr_priority(evtcode, shpcic_intr_priority[intr]);
    338 	shpcic_intr_priority[intr] = level;
    339 
    340 	return (0);
    341 }
    342 
    343 void *
    344 shpcic_intr_establish(int evtcode, int (*ih_func)(void *), void *ih_arg)
    345 {
    346 	int level;
    347 
    348 	switch (evtcode) {
    349 	case SH4_INTEVT_PCISERR:
    350 		level = shpcic_intr_priority[1];
    351 		break;
    352 
    353 	case SH4_INTEVT_PCIDMA3:
    354 	case SH4_INTEVT_PCIDMA2:
    355 	case SH4_INTEVT_PCIDMA1:
    356 	case SH4_INTEVT_PCIDMA0:
    357 	case SH4_INTEVT_PCIPWON:
    358 	case SH4_INTEVT_PCIPWDWN:
    359 	case SH4_INTEVT_PCIERR:
    360 		level = shpcic_intr_priority[0];
    361 		break;
    362 
    363 	default:
    364 		printf("shpcic_intr_establish: unknown evtcode = 0x%08x\n",
    365 		    evtcode);
    366 		return NULL;
    367 	}
    368 
    369 	return intc_intr_establish(evtcode, IST_LEVEL, level, ih_func, ih_arg);
    370 }
    371 
    372 void
    373 shpcic_intr_disestablish(void *ih)
    374 {
    375 
    376 	intc_intr_disestablish(ih);
    377 }
    378 
    379 /*
    380  * shpcic bus space
    381  */
    382 int
    383 shpcic_iomem_map(void *v, bus_addr_t bpa, bus_size_t size,
    384     int flags, bus_space_handle_t *bshp)
    385 {
    386 
    387 	*bshp = (bus_space_handle_t)bpa;
    388 
    389 	return (0);
    390 }
    391 
    392 void
    393 shpcic_iomem_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
    394 {
    395 
    396 	/* Nothing to do */
    397 }
    398 
    399 int
    400 shpcic_iomem_subregion(void *v, bus_space_handle_t bsh,
    401     bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
    402 {
    403 
    404 	*nbshp = bsh + offset;
    405 
    406 	return (0);
    407 }
    408 
    409 int
    410 shpcic_iomem_alloc(void *v, bus_addr_t rstart, bus_addr_t rend,
    411     bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
    412     bus_addr_t *bpap, bus_space_handle_t *bshp)
    413 {
    414 
    415 	*bshp = *bpap = rstart;
    416 
    417 	return (0);
    418 }
    419 
    420 void
    421 shpcic_iomem_free(void *v, bus_space_handle_t bsh, bus_size_t size)
    422 {
    423 
    424 	/* Nothing to do */
    425 }
    426 
    427 /*
    428  * shpcic bus space io/mem read/write
    429  */
    430 /* read */
    431 static inline uint8_t __shpcic_io_read_1(bus_space_handle_t bsh,
    432     bus_size_t offset);
    433 static inline uint16_t __shpcic_io_read_2(bus_space_handle_t bsh,
    434     bus_size_t offset);
    435 static inline uint32_t __shpcic_io_read_4(bus_space_handle_t bsh,
    436     bus_size_t offset);
    437 static inline uint8_t __shpcic_mem_read_1(bus_space_handle_t bsh,
    438     bus_size_t offset);
    439 static inline uint16_t __shpcic_mem_read_2(bus_space_handle_t bsh,
    440     bus_size_t offset);
    441 static inline uint32_t __shpcic_mem_read_4(bus_space_handle_t bsh,
    442     bus_size_t offset);
    443 
    444 static inline uint8_t
    445 __shpcic_io_read_1(bus_space_handle_t bsh, bus_size_t offset)
    446 {
    447 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
    448 
    449 	return *(volatile uint8_t *)(SH4_PCIC_IO + adr);
    450 }
    451 
    452 static inline uint16_t
    453 __shpcic_io_read_2(bus_space_handle_t bsh, bus_size_t offset)
    454 {
    455 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
    456 
    457 	return *(volatile uint16_t *)(SH4_PCIC_IO + adr);
    458 }
    459 
    460 static inline uint32_t
    461 __shpcic_io_read_4(bus_space_handle_t bsh, bus_size_t offset)
    462 {
    463 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
    464 
    465 	return *(volatile uint32_t *)(SH4_PCIC_IO + adr);
    466 }
    467 
    468 static inline uint8_t
    469 __shpcic_mem_read_1(bus_space_handle_t bsh, bus_size_t offset)
    470 {
    471 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
    472 
    473 	return *(volatile uint8_t *)(SH4_PCIC_MEM + adr);
    474 }
    475 
    476 static inline uint16_t
    477 __shpcic_mem_read_2(bus_space_handle_t bsh, bus_size_t offset)
    478 {
    479 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
    480 
    481 	return *(volatile uint16_t *)(SH4_PCIC_MEM + adr);
    482 }
    483 
    484 static inline uint32_t
    485 __shpcic_mem_read_4(bus_space_handle_t bsh, bus_size_t offset)
    486 {
    487 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
    488 
    489 	return *(volatile uint32_t *)(SH4_PCIC_MEM + adr);
    490 }
    491 
    492 /*
    493  * read single
    494  */
    495 uint8_t
    496 shpcic_io_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset)
    497 {
    498 	uint8_t value;
    499 
    500 	value = __shpcic_io_read_1(bsh, offset);
    501 
    502 	return value;
    503 }
    504 
    505 uint16_t
    506 shpcic_io_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset)
    507 {
    508 	uint16_t value;
    509 
    510 	value = __shpcic_io_read_2(bsh, offset);
    511 
    512 	return value;
    513 }
    514 
    515 uint32_t
    516 shpcic_io_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset)
    517 {
    518 	uint32_t value;
    519 
    520 	value = __shpcic_io_read_4(bsh, offset);
    521 
    522 	return value;
    523 }
    524 
    525 uint8_t
    526 shpcic_mem_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset)
    527 {
    528 	uint8_t value;
    529 
    530 	value = __shpcic_mem_read_1(bsh, offset);
    531 
    532 	return value;
    533 }
    534 
    535 uint16_t
    536 shpcic_mem_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset)
    537 {
    538 	uint16_t value;
    539 
    540 	value = __shpcic_mem_read_2(bsh, offset);
    541 
    542 	return value;
    543 }
    544 
    545 uint32_t
    546 shpcic_mem_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset)
    547 {
    548 	uint32_t value;
    549 
    550 	value = __shpcic_mem_read_4(bsh, offset);
    551 
    552 	return value;
    553 }
    554 
    555 /*
    556  * read multi
    557  */
    558 void
    559 shpcic_io_read_multi_1(void *v, bus_space_handle_t bsh,
    560     bus_size_t offset, uint8_t *addr, bus_size_t count)
    561 {
    562 
    563 	while (count--) {
    564 		*addr++ = __shpcic_io_read_1(bsh, offset);
    565 	}
    566 }
    567 
    568 void
    569 shpcic_io_read_multi_2(void *v, bus_space_handle_t bsh,
    570     bus_size_t offset, uint16_t *addr, bus_size_t count)
    571 {
    572 
    573 	while (count--) {
    574 		*addr++ = __shpcic_io_read_2(bsh, offset);
    575 	}
    576 }
    577 
    578 void
    579 shpcic_io_read_multi_4(void *v, bus_space_handle_t bsh,
    580     bus_size_t offset, uint32_t *addr, bus_size_t count)
    581 {
    582 
    583 	while (count--) {
    584 		*addr++ = __shpcic_io_read_4(bsh, offset);
    585 	}
    586 }
    587 
    588 void
    589 shpcic_mem_read_multi_1(void *v, bus_space_handle_t bsh,
    590     bus_size_t offset, uint8_t *addr, bus_size_t count)
    591 {
    592 
    593 	while (count--) {
    594 		*addr++ = __shpcic_mem_read_1(bsh, offset);
    595 	}
    596 }
    597 
    598 void
    599 shpcic_mem_read_multi_2(void *v, bus_space_handle_t bsh,
    600     bus_size_t offset, uint16_t *addr, bus_size_t count)
    601 {
    602 
    603 	while (count--) {
    604 		*addr++ = __shpcic_mem_read_2(bsh, offset);
    605 	}
    606 }
    607 
    608 void
    609 shpcic_mem_read_multi_4(void *v, bus_space_handle_t bsh,
    610     bus_size_t offset, uint32_t *addr, bus_size_t count)
    611 {
    612 
    613 	while (count--) {
    614 		*addr++ = __shpcic_mem_read_4(bsh, offset);
    615 	}
    616 }
    617 
    618 /*
    619  *
    620  * read region
    621  */
    622 void
    623 shpcic_io_read_region_1(void *v, bus_space_handle_t bsh,
    624     bus_size_t offset, uint8_t *addr, bus_size_t count)
    625 {
    626 
    627 	while (count--) {
    628 		*addr++ = __shpcic_io_read_1(bsh, offset);
    629 		offset += 1;
    630 	}
    631 }
    632 
    633 void
    634 shpcic_io_read_region_2(void *v, bus_space_handle_t bsh,
    635     bus_size_t offset, uint16_t *addr, bus_size_t count)
    636 {
    637 
    638 	while (count--) {
    639 		*addr++ = __shpcic_io_read_2(bsh, offset);
    640 		offset += 2;
    641 	}
    642 }
    643 
    644 void
    645 shpcic_io_read_region_4(void *v, bus_space_handle_t bsh,
    646     bus_size_t offset, uint32_t *addr, bus_size_t count)
    647 {
    648 
    649 	while (count--) {
    650 		*addr++ = __shpcic_io_read_4(bsh, offset);
    651 		offset += 4;
    652 	}
    653 }
    654 
    655 void
    656 shpcic_mem_read_region_1(void *v, bus_space_handle_t bsh,
    657     bus_size_t offset, uint8_t *addr, bus_size_t count)
    658 {
    659 
    660 	while (count--) {
    661 		*addr++ = __shpcic_mem_read_1(bsh, offset);
    662 		offset += 1;
    663 	}
    664 }
    665 
    666 void
    667 shpcic_mem_read_region_2(void *v, bus_space_handle_t bsh,
    668     bus_size_t offset, uint16_t *addr, bus_size_t count)
    669 {
    670 
    671 	while (count--) {
    672 		*addr++ = __shpcic_mem_read_2(bsh, offset);
    673 		offset += 2;
    674 	}
    675 }
    676 
    677 void
    678 shpcic_mem_read_region_4(void *v, bus_space_handle_t bsh,
    679     bus_size_t offset, uint32_t *addr, bus_size_t count)
    680 {
    681 
    682 	while (count--) {
    683 		*addr++ = __shpcic_mem_read_4(bsh, offset);
    684 		offset += 4;
    685 	}
    686 }
    687 
    688 /* write */
    689 static inline void __shpcic_io_write_1(bus_space_handle_t bsh,
    690     bus_size_t offset, uint8_t value);
    691 static inline void __shpcic_io_write_2(bus_space_handle_t bsh,
    692     bus_size_t offset, uint16_t value);
    693 static inline void __shpcic_io_write_4(bus_space_handle_t bsh,
    694     bus_size_t offset, uint32_t value);
    695 static inline void __shpcic_mem_write_1(bus_space_handle_t bsh,
    696     bus_size_t offset, uint8_t value);
    697 static inline void __shpcic_mem_write_2(bus_space_handle_t bsh,
    698     bus_size_t offset, uint16_t value);
    699 static inline void __shpcic_mem_write_4(bus_space_handle_t bsh,
    700     bus_size_t offset, uint32_t value);
    701 
    702 static inline void
    703 __shpcic_io_write_1(bus_space_handle_t bsh, bus_size_t offset,
    704     uint8_t value)
    705 {
    706 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
    707 
    708 	*(volatile uint8_t *)(SH4_PCIC_IO + adr) = value;
    709 }
    710 
    711 static inline void
    712 __shpcic_io_write_2(bus_space_handle_t bsh, bus_size_t offset,
    713     uint16_t value)
    714 {
    715 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
    716 
    717 	*(volatile uint16_t *)(SH4_PCIC_IO + adr) = value;
    718 }
    719 
    720 static inline void
    721 __shpcic_io_write_4(bus_space_handle_t bsh, bus_size_t offset,
    722     uint32_t value)
    723 {
    724 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
    725 
    726 	*(volatile uint32_t *)(SH4_PCIC_IO + adr) = value;
    727 }
    728 
    729 static inline void
    730 __shpcic_mem_write_1(bus_space_handle_t bsh, bus_size_t offset,
    731     uint8_t value)
    732 {
    733 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
    734 
    735 	*(volatile uint8_t *)(SH4_PCIC_MEM + adr) = value;
    736 }
    737 
    738 static inline void
    739 __shpcic_mem_write_2(bus_space_handle_t bsh, bus_size_t offset,
    740     uint16_t value)
    741 {
    742 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
    743 
    744 	*(volatile uint16_t *)(SH4_PCIC_MEM + adr) = value;
    745 }
    746 
    747 static inline void
    748 __shpcic_mem_write_4(bus_space_handle_t bsh, bus_size_t offset,
    749     uint32_t value)
    750 {
    751 	u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
    752 
    753 	*(volatile uint32_t *)(SH4_PCIC_MEM + adr) = value;
    754 }
    755 
    756 /*
    757  * write single
    758  */
    759 void
    760 shpcic_io_write_1(void *v, bus_space_handle_t bsh,
    761     bus_size_t offset, uint8_t value)
    762 {
    763 
    764 	__shpcic_io_write_1(bsh, offset, value);
    765 }
    766 
    767 void
    768 shpcic_io_write_2(void *v, bus_space_handle_t bsh,
    769     bus_size_t offset, uint16_t value)
    770 {
    771 
    772 	__shpcic_io_write_2(bsh, offset, value);
    773 }
    774 
    775 void
    776 shpcic_io_write_4(void *v, bus_space_handle_t bsh,
    777     bus_size_t offset, uint32_t value)
    778 {
    779 
    780 	__shpcic_io_write_4(bsh, offset, value);
    781 }
    782 
    783 void
    784 shpcic_mem_write_1(void *v, bus_space_handle_t bsh,
    785     bus_size_t offset, uint8_t value)
    786 {
    787 
    788 	__shpcic_mem_write_1(bsh, offset, value);
    789 }
    790 
    791 void
    792 shpcic_mem_write_2(void *v, bus_space_handle_t bsh,
    793     bus_size_t offset, uint16_t value)
    794 {
    795 
    796 	__shpcic_mem_write_2(bsh, offset, value);
    797 }
    798 
    799 void
    800 shpcic_mem_write_4(void *v, bus_space_handle_t bsh,
    801     bus_size_t offset, uint32_t value)
    802 {
    803 
    804 	__shpcic_mem_write_4(bsh, offset, value);
    805 }
    806 
    807 /*
    808  * write multi
    809  */
    810 void
    811 shpcic_io_write_multi_1(void *v, bus_space_handle_t bsh,
    812     bus_size_t offset, const uint8_t *addr, bus_size_t count)
    813 {
    814 
    815 	while (count--) {
    816 		__shpcic_io_write_1(bsh, offset, *addr++);
    817 	}
    818 }
    819 
    820 void
    821 shpcic_io_write_multi_2(void *v, bus_space_handle_t bsh,
    822     bus_size_t offset, const uint16_t *addr, bus_size_t count)
    823 {
    824 
    825 	while (count--) {
    826 		__shpcic_io_write_2(bsh, offset, *addr++);
    827 	}
    828 }
    829 
    830 void
    831 shpcic_io_write_multi_4(void *v, bus_space_handle_t bsh,
    832     bus_size_t offset, const uint32_t *addr, bus_size_t count)
    833 {
    834 
    835 	while (count--) {
    836 		__shpcic_io_write_4(bsh, offset, *addr++);
    837 	}
    838 }
    839 
    840 void
    841 shpcic_mem_write_multi_1(void *v, bus_space_handle_t bsh,
    842     bus_size_t offset, const uint8_t *addr, bus_size_t count)
    843 {
    844 
    845 	while (count--) {
    846 		__shpcic_mem_write_1(bsh, offset, *addr++);
    847 	}
    848 }
    849 
    850 void
    851 shpcic_mem_write_multi_2(void *v, bus_space_handle_t bsh,
    852     bus_size_t offset, const uint16_t *addr, bus_size_t count)
    853 {
    854 
    855 	while (count--) {
    856 		__shpcic_mem_write_2(bsh, offset, *addr++);
    857 	}
    858 }
    859 
    860 void
    861 shpcic_mem_write_multi_4(void *v, bus_space_handle_t bsh,
    862     bus_size_t offset, const uint32_t *addr, bus_size_t count)
    863 {
    864 
    865 	while (count--) {
    866 		__shpcic_mem_write_4(bsh, offset, *addr++);
    867 	}
    868 }
    869 
    870 /*
    871  * write region
    872  */
    873 void
    874 shpcic_io_write_region_1(void *v, bus_space_handle_t bsh,
    875     bus_size_t offset, const uint8_t *addr, bus_size_t count)
    876 {
    877 
    878 	while (count--) {
    879 		__shpcic_io_write_1(bsh, offset, *addr++);
    880 		offset += 1;
    881 	}
    882 }
    883 
    884 void
    885 shpcic_io_write_region_2(void *v, bus_space_handle_t bsh,
    886     bus_size_t offset, const uint16_t *addr, bus_size_t count)
    887 {
    888 
    889 	while (count--) {
    890 		__shpcic_io_write_2(bsh, offset, *addr++);
    891 		offset += 2;
    892 	}
    893 }
    894 
    895 void
    896 shpcic_io_write_region_4(void *v, bus_space_handle_t bsh,
    897     bus_size_t offset, const uint32_t *addr, bus_size_t count)
    898 {
    899 
    900 	while (count--) {
    901 		__shpcic_io_write_4(bsh, offset, *addr++);
    902 		offset += 4;
    903 	}
    904 }
    905 
    906 void
    907 shpcic_mem_write_region_1(void *v, bus_space_handle_t bsh,
    908     bus_size_t offset, const uint8_t *addr, bus_size_t count)
    909 {
    910 
    911 	while (count--) {
    912 		__shpcic_mem_write_1(bsh, offset, *addr++);
    913 		offset += 1;
    914 	}
    915 }
    916 
    917 void
    918 shpcic_mem_write_region_2(void *v, bus_space_handle_t bsh,
    919     bus_size_t offset, const uint16_t *addr, bus_size_t count)
    920 {
    921 
    922 	while (count--) {
    923 		__shpcic_mem_write_2(bsh, offset, *addr++);
    924 		offset += 2;
    925 	}
    926 }
    927 
    928 void
    929 shpcic_mem_write_region_4(void *v, bus_space_handle_t bsh,
    930     bus_size_t offset, const uint32_t *addr, bus_size_t count)
    931 {
    932 
    933 	while (count--) {
    934 		__shpcic_mem_write_4(bsh, offset, *addr++);
    935 		offset += 4;
    936 	}
    937 }
    938 
    939 /*
    940  * set multi
    941  */
    942 void
    943 shpcic_io_set_multi_1(void *v, bus_space_handle_t bsh,
    944     bus_size_t offset, uint8_t value, bus_size_t count)
    945 {
    946 
    947 	while (count--) {
    948 		__shpcic_io_write_1(bsh, offset, value);
    949 	}
    950 }
    951 
    952 void
    953 shpcic_io_set_multi_2(void *v, bus_space_handle_t bsh,
    954     bus_size_t offset, uint16_t value, bus_size_t count)
    955 {
    956 
    957 	while (count--) {
    958 		__shpcic_io_write_2(bsh, offset, value);
    959 	}
    960 }
    961 
    962 void
    963 shpcic_io_set_multi_4(void *v, bus_space_handle_t bsh,
    964     bus_size_t offset, uint32_t value, bus_size_t count)
    965 {
    966 
    967 	while (count--) {
    968 		__shpcic_io_write_4(bsh, offset, value);
    969 	}
    970 }
    971 
    972 void
    973 shpcic_mem_set_multi_1(void *v, bus_space_handle_t bsh,
    974     bus_size_t offset, uint8_t value, bus_size_t count)
    975 {
    976 
    977 	while (count--) {
    978 		__shpcic_mem_write_1(bsh, offset, value);
    979 	}
    980 }
    981 
    982 void
    983 shpcic_mem_set_multi_2(void *v, bus_space_handle_t bsh,
    984     bus_size_t offset, uint16_t value, bus_size_t count)
    985 {
    986 
    987 	while (count--) {
    988 		__shpcic_mem_write_2(bsh, offset, value);
    989 	}
    990 }
    991 
    992 void
    993 shpcic_mem_set_multi_4(void *v, bus_space_handle_t bsh,
    994     bus_size_t offset, uint32_t value, bus_size_t count)
    995 {
    996 
    997 	while (count--) {
    998 		__shpcic_mem_write_4(bsh, offset, value);
    999 	}
   1000 }
   1001 
   1002 /*
   1003  * set region
   1004  */
   1005 void
   1006 shpcic_io_set_region_1(void *v, bus_space_handle_t bsh,
   1007     bus_size_t offset, uint8_t value, bus_size_t count)
   1008 {
   1009 
   1010 	while (count--) {
   1011 		__shpcic_io_write_1(bsh, offset, value);
   1012 		offset += 1;
   1013 	}
   1014 }
   1015 
   1016 void
   1017 shpcic_io_set_region_2(void *v, bus_space_handle_t bsh,
   1018     bus_size_t offset, uint16_t value, bus_size_t count)
   1019 {
   1020 
   1021 	while (count--) {
   1022 		__shpcic_io_write_2(bsh, offset, value);
   1023 		offset += 2;
   1024 	}
   1025 }
   1026 
   1027 void
   1028 shpcic_io_set_region_4(void *v, bus_space_handle_t bsh,
   1029     bus_size_t offset, uint32_t value, bus_size_t count)
   1030 {
   1031 
   1032 	while (count--) {
   1033 		__shpcic_io_write_4(bsh, offset, value);
   1034 		offset += 4;
   1035 	}
   1036 }
   1037 
   1038 void
   1039 shpcic_mem_set_region_1(void *v, bus_space_handle_t bsh,
   1040     bus_size_t offset, uint8_t value, bus_size_t count)
   1041 {
   1042 
   1043 	while (count--) {
   1044 		__shpcic_mem_write_1(bsh, offset, value);
   1045 		offset += 1;
   1046 	}
   1047 }
   1048 
   1049 void
   1050 shpcic_mem_set_region_2(void *v, bus_space_handle_t bsh,
   1051     bus_size_t offset, uint16_t value, bus_size_t count)
   1052 {
   1053 
   1054 	while (count--) {
   1055 		__shpcic_mem_write_2(bsh, offset, value);
   1056 		offset += 2;
   1057 	}
   1058 }
   1059 
   1060 void
   1061 shpcic_mem_set_region_4(void *v, bus_space_handle_t bsh,
   1062     bus_size_t offset, uint32_t value, bus_size_t count)
   1063 {
   1064 
   1065 	while (count--) {
   1066 		__shpcic_mem_write_4(bsh, offset, value);
   1067 		offset += 4;
   1068 	}
   1069 }
   1070 
   1071 /*
   1072  * copy region
   1073  */
   1074 void
   1075 shpcic_io_copy_region_1(void *v, bus_space_handle_t bsh1,
   1076     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
   1077 {
   1078 	u_long addr1 = bsh1 + off1;
   1079 	u_long addr2 = bsh2 + off2;
   1080 	uint8_t value;
   1081 
   1082 	if (addr1 >= addr2) {	/* src after dest: copy forward */
   1083 		while (count--) {
   1084 			value = __shpcic_io_read_1(bsh1, off1);
   1085 			__shpcic_io_write_1(bsh2, off2, value);
   1086 			off1 += 1;
   1087 			off2 += 1;
   1088 		}
   1089 	} else {		/* dest after src: copy backwards */
   1090 		off1 += (count - 1) * 1;
   1091 		off2 += (count - 1) * 1;
   1092 		while (count--) {
   1093 			value = __shpcic_io_read_1(bsh1, off1);
   1094 			__shpcic_io_write_1(bsh2, off2, value);
   1095 			off1 -= 1;
   1096 			off2 -= 1;
   1097 		}
   1098 	}
   1099 }
   1100 
   1101 void
   1102 shpcic_io_copy_region_2(void *v, bus_space_handle_t bsh1,
   1103     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
   1104 {
   1105 	u_long addr1 = bsh1 + off1;
   1106 	u_long addr2 = bsh2 + off2;
   1107 	uint16_t value;
   1108 
   1109 	if (addr1 >= addr2) {	/* src after dest: copy forward */
   1110 		while (count--) {
   1111 			value = __shpcic_io_read_2(bsh1, off1);
   1112 			__shpcic_io_write_2(bsh2, off2, value);
   1113 			off1 += 2;
   1114 			off2 += 2;
   1115 		}
   1116 	} else {		/* dest after src: copy backwards */
   1117 		off1 += (count - 1) * 2;
   1118 		off2 += (count - 1) * 2;
   1119 		while (count--) {
   1120 			value = __shpcic_io_read_2(bsh1, off1);
   1121 			__shpcic_io_write_2(bsh2, off2, value);
   1122 			off1 -= 2;
   1123 			off2 -= 2;
   1124 		}
   1125 	}
   1126 }
   1127 
   1128 void
   1129 shpcic_io_copy_region_4(void *v, bus_space_handle_t bsh1,
   1130     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
   1131 {
   1132 	u_long addr1 = bsh1 + off1;
   1133 	u_long addr2 = bsh2 + off2;
   1134 	uint32_t value;
   1135 
   1136 	if (addr1 >= addr2) {	/* src after dest: copy forward */
   1137 		while (count--) {
   1138 			value = __shpcic_io_read_4(bsh1, off1);
   1139 			__shpcic_io_write_4(bsh2, off2, value);
   1140 			off1 += 4;
   1141 			off2 += 4;
   1142 		}
   1143 	} else {		/* dest after src: copy backwards */
   1144 		off1 += (count - 1) * 4;
   1145 		off2 += (count - 1) * 4;
   1146 		while (count--) {
   1147 			value = __shpcic_io_read_4(bsh1, off1);
   1148 			__shpcic_io_write_4(bsh2, off2, value);
   1149 			off1 -= 4;
   1150 			off2 -= 4;
   1151 		}
   1152 	}
   1153 }
   1154 
   1155 void
   1156 shpcic_mem_copy_region_1(void *v, bus_space_handle_t bsh1,
   1157     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
   1158 {
   1159 	u_long addr1 = bsh1 + off1;
   1160 	u_long addr2 = bsh2 + off2;
   1161 	uint8_t value;
   1162 
   1163 	if (addr1 >= addr2) {	/* src after dest: copy forward */
   1164 		while (count--) {
   1165 			value = __shpcic_mem_read_1(bsh1, off1);
   1166 			__shpcic_mem_write_1(bsh2, off2, value);
   1167 			off1 += 1;
   1168 			off2 += 1;
   1169 		}
   1170 	} else {		/* dest after src: copy backwards */
   1171 		off1 += (count - 1) * 1;
   1172 		off2 += (count - 1) * 1;
   1173 		while (count--) {
   1174 			value = __shpcic_mem_read_1(bsh1, off1);
   1175 			__shpcic_mem_write_1(bsh2, off2, value);
   1176 			off1 -= 1;
   1177 			off2 -= 1;
   1178 		}
   1179 	}
   1180 }
   1181 
   1182 void
   1183 shpcic_mem_copy_region_2(void *v, bus_space_handle_t bsh1,
   1184     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
   1185 {
   1186 	u_long addr1 = bsh1 + off1;
   1187 	u_long addr2 = bsh2 + off2;
   1188 	uint16_t value;
   1189 
   1190 	if (addr1 >= addr2) {	/* src after dest: copy forward */
   1191 		while (count--) {
   1192 			value = __shpcic_mem_read_2(bsh1, off1);
   1193 			__shpcic_mem_write_2(bsh2, off2, value);
   1194 			off1 += 2;
   1195 			off2 += 2;
   1196 		}
   1197 	} else {		/* dest after src: copy backwards */
   1198 		off1 += (count - 1) * 2;
   1199 		off2 += (count - 1) * 2;
   1200 		while (count--) {
   1201 			value = __shpcic_mem_read_2(bsh1, off1);
   1202 			__shpcic_mem_write_2(bsh2, off2, value);
   1203 			off1 -= 2;
   1204 			off2 -= 2;
   1205 		}
   1206 	}
   1207 }
   1208 
   1209 void
   1210 shpcic_mem_copy_region_4(void *v, bus_space_handle_t bsh1,
   1211     bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
   1212 {
   1213 	u_long addr1 = bsh1 + off1;
   1214 	u_long addr2 = bsh2 + off2;
   1215 	uint32_t value;
   1216 
   1217 	if (addr1 >= addr2) {	/* src after dest: copy forward */
   1218 		while (count--) {
   1219 			value = __shpcic_mem_read_4(bsh1, off1);
   1220 			__shpcic_mem_write_4(bsh2, off2, value);
   1221 			off1 += 4;
   1222 			off2 += 4;
   1223 		}
   1224 	} else {		/* dest after src: copy backwards */
   1225 		off1 += (count - 1) * 4;
   1226 		off2 += (count - 1) * 4;
   1227 		while (count--) {
   1228 			value = __shpcic_mem_read_4(bsh1, off1);
   1229 			__shpcic_mem_write_4(bsh2, off2, value);
   1230 			off1 -= 4;
   1231 			off2 -= 4;
   1232 		}
   1233 	}
   1234 }
   1235