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