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