1 /* $OpenBSD: obio.c,v 1.9 2014/11/16 12:30:57 deraadt Exp $ */ 2 /* $NetBSD: obio.c,v 1.1 2006/09/01 21:26:18 uwe Exp $ */ 3 4 /*- 5 * Copyright (c) 1998 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Charles M. Hannum. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/device.h> 36 37 #include <uvm/uvm_extern.h> 38 39 #include <sh/devreg.h> 40 #include <sh/mmu.h> 41 #include <sh/pmap.h> 42 #include <sh/pte.h> 43 44 #include <machine/bus.h> 45 #include <machine/cpu.h> 46 #include <machine/intr.h> 47 48 #include <landisk/dev/obiovar.h> 49 50 int obio_match(struct device *, void *, void *); 51 void obio_attach(struct device *, struct device *, void *); 52 int obio_print(void *, const char *); 53 int obio_search(struct device *, void *, void *); 54 55 struct cfattach obio_ca = { 56 sizeof(struct obio_softc), obio_match, obio_attach 57 }; 58 59 struct cfdriver obio_cd = { 60 0, "obio", DV_DULL 61 }; 62 63 int 64 obio_match(struct device *parent, void *vcf, void *aux) 65 { 66 struct obiobus_attach_args *oba = aux; 67 68 if (strcmp(oba->oba_busname, obio_cd.cd_name) != 0) 69 return (0); 70 71 return (1); 72 } 73 74 void 75 obio_attach(struct device *parent, struct device *self, void *aux) 76 { 77 struct obio_softc *sc = (struct obio_softc *)self; 78 struct obiobus_attach_args *oba = aux; 79 80 printf("\n"); 81 82 sc->sc_iot = oba->oba_iot; 83 sc->sc_memt = oba->oba_memt; 84 85 config_search(obio_search, self, NULL); 86 } 87 88 int 89 obio_search(struct device *parent, void *vcf, void *aux) 90 { 91 struct obio_softc *sc = (struct obio_softc *)parent; 92 struct cfdata *cf = vcf; 93 struct obio_attach_args oa; 94 struct obio_io res_io[1]; 95 struct obio_iomem res_mem[1]; 96 struct obio_irq res_irq[1]; 97 98 oa.oa_iot = sc->sc_iot; 99 oa.oa_memt = sc->sc_memt; 100 oa.oa_nio = oa.oa_niomem = oa.oa_nirq = 0; 101 102 if (cf->cf_iobase != IOBASEUNK) { 103 res_io[0].or_addr = cf->cf_iobase; 104 res_io[0].or_size = cf->cf_iosize; 105 oa.oa_io = res_io; 106 oa.oa_nio = 1; 107 } 108 109 if (cf->cf_maddr != MADDRUNK) { 110 res_mem[0].or_addr = cf->cf_maddr; 111 res_mem[0].or_size = cf->cf_msize; 112 oa.oa_iomem = res_mem; 113 oa.oa_niomem = 1; 114 } 115 116 if (cf->cf_irq != IRQUNK) { 117 res_irq[0].or_irq = cf->cf_irq; 118 oa.oa_irq = res_irq; 119 oa.oa_nirq = 1; 120 } 121 122 if ((*cf->cf_attach->ca_match)(parent, cf, &oa) == 0) 123 return (0); 124 125 config_attach(parent, cf, &oa, obio_print); 126 return (1); 127 } 128 129 int 130 obio_print(void *args, const char *name) 131 { 132 struct obio_attach_args *oa = args; 133 const char *sep; 134 int i; 135 136 if (oa->oa_nio) { 137 sep = ""; 138 printf(" port "); 139 for (i = 0; i < oa->oa_nio; i++) { 140 if (oa->oa_io[i].or_size == 0) 141 continue; 142 printf("%s0x%x", sep, oa->oa_io[i].or_addr); 143 if (oa->oa_io[i].or_size > 1) 144 printf("-0x%x", oa->oa_io[i].or_addr + 145 oa->oa_io[i].or_size - 1); 146 sep = ","; 147 } 148 } 149 150 if (oa->oa_niomem) { 151 sep = ""; 152 printf(" iomem "); 153 for (i = 0; i < oa->oa_niomem; i++) { 154 if (oa->oa_iomem[i].or_size == 0) 155 continue; 156 printf("%s0x%x", sep, oa->oa_iomem[i].or_addr); 157 if (oa->oa_iomem[i].or_size > 1) 158 printf("-0x%x", oa->oa_iomem[i].or_addr + 159 oa->oa_iomem[i].or_size - 1); 160 sep = ","; 161 } 162 } 163 164 if (oa->oa_nirq) { 165 sep = ""; 166 printf(" irq "); 167 for (i = 0; i < oa->oa_nirq; i++) { 168 if (oa->oa_irq[i].or_irq == IRQUNK) 169 continue; 170 printf("%s%d", sep, oa->oa_irq[i].or_irq); 171 sep = ","; 172 } 173 } 174 175 return (UNCONF); 176 } 177 178 /* 179 * Set up an interrupt handler to start being called. 180 */ 181 void * 182 obio_intr_establish(int irq, int level, int (*ih_fun)(void *), void *ih_arg, 183 const char *ih_name) 184 { 185 return extintr_establish(irq, level, ih_fun, ih_arg, ih_name); 186 } 187 188 /* 189 * Deregister an interrupt handler. 190 */ 191 void 192 obio_intr_disestablish(void *arg) 193 { 194 extintr_disestablish(arg); 195 } 196 197 /* 198 * on-board I/O bus space 199 */ 200 #define OBIO_IOMEM_IO 0 /* space is i/o space */ 201 #define OBIO_IOMEM_MEM 1 /* space is mem space */ 202 #define OBIO_IOMEM_PCMCIA_IO 2 /* PCMCIA IO space */ 203 #define OBIO_IOMEM_PCMCIA_MEM 3 /* PCMCIA Mem space */ 204 #define OBIO_IOMEM_PCMCIA_ATT 4 /* PCMCIA Attr space */ 205 #define OBIO_IOMEM_PCMCIA_8BIT 0x8000 /* PCMCIA BUS 8 BIT WIDTH */ 206 #define OBIO_IOMEM_PCMCIA_IO8 \ 207 (OBIO_IOMEM_PCMCIA_IO|OBIO_IOMEM_PCMCIA_8BIT) 208 #define OBIO_IOMEM_PCMCIA_MEM8 \ 209 (OBIO_IOMEM_PCMCIA_MEM|OBIO_IOMEM_PCMCIA_8BIT) 210 #define OBIO_IOMEM_PCMCIA_ATT8 \ 211 (OBIO_IOMEM_PCMCIA_ATT|OBIO_IOMEM_PCMCIA_8BIT) 212 213 int obio_iomem_map(void *v, bus_addr_t bpa, bus_size_t size, int flags, 214 bus_space_handle_t *bshp); 215 void obio_iomem_unmap(void *v, bus_space_handle_t bsh, bus_size_t size); 216 int obio_iomem_subregion(void *v, bus_space_handle_t bsh, 217 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp); 218 int obio_iomem_alloc(void *v, bus_addr_t rstart, bus_addr_t rend, 219 bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags, 220 bus_addr_t *bpap, bus_space_handle_t *bshp); 221 void obio_iomem_free(void *v, bus_space_handle_t bsh, bus_size_t size); 222 void *obio_iomem_vaddr(void *v, bus_space_handle_t bsh); 223 224 int obio_iomem_add_mapping(bus_addr_t, bus_size_t, int, 225 bus_space_handle_t *); 226 227 int 228 obio_iomem_add_mapping(bus_addr_t bpa, bus_size_t size, int type, 229 bus_space_handle_t *bshp) 230 { 231 u_long pa, endpa; 232 vaddr_t va; 233 pt_entry_t *pte; 234 unsigned int m = 0; 235 int io_type = type & ~OBIO_IOMEM_PCMCIA_8BIT; 236 237 pa = trunc_page(bpa); 238 endpa = round_page(bpa + size); 239 240 #ifdef DIAGNOSTIC 241 if (endpa <= pa) 242 panic("obio_iomem_add_mapping: overflow"); 243 #endif 244 245 va = uvm_km_valloc(kernel_map, endpa - pa); 246 if (va == 0) 247 return (ENOMEM); 248 249 *bshp = (bus_space_handle_t)(va + (bpa & PGOFSET)); 250 251 #define MODE(t, s) \ 252 ((t) & OBIO_IOMEM_PCMCIA_8BIT) ? \ 253 _PG_PCMCIA_ ## s ## 8 : \ 254 _PG_PCMCIA_ ## s ## 16 255 switch (io_type) { 256 default: 257 panic("unknown pcmcia space."); 258 /* NOTREACHED */ 259 case OBIO_IOMEM_PCMCIA_IO: 260 m = MODE(type, IO); 261 break; 262 case OBIO_IOMEM_PCMCIA_MEM: 263 m = MODE(type, MEM); 264 break; 265 case OBIO_IOMEM_PCMCIA_ATT: 266 m = MODE(type, ATTR); 267 break; 268 } 269 #undef MODE 270 271 for (; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) { 272 pmap_kenter_pa(va, pa, PROT_READ | PROT_WRITE); 273 pte = __pmap_kpte_lookup(va); 274 KDASSERT(pte); 275 *pte |= m; /* PTEA PCMCIA assistant bit */ 276 sh_tlb_update(0, va, *pte); 277 } 278 279 return (0); 280 } 281 282 int 283 obio_iomem_map(void *v, bus_addr_t bpa, bus_size_t size, 284 int flags, bus_space_handle_t *bshp) 285 { 286 bus_addr_t addr = SH3_PHYS_TO_P2SEG(bpa); 287 int error; 288 289 KASSERT((bpa & SH3_PHYS_MASK) == bpa); 290 291 if (bpa < 0x14000000 || bpa >= 0x1c000000) { 292 /* CS0,1,2,3,4,7 */ 293 *bshp = (bus_space_handle_t)addr; 294 return (0); 295 } 296 297 /* CS5,6 */ 298 error = obio_iomem_add_mapping(addr, size, (int)(u_long)v, bshp); 299 300 return (error); 301 } 302 303 void 304 obio_iomem_unmap(void *v, bus_space_handle_t bsh, bus_size_t size) 305 { 306 u_long va, endva; 307 bus_addr_t bpa; 308 309 if (bsh >= SH3_P2SEG_BASE && bsh <= SH3_P2SEG_END) { 310 /* maybe CS0,1,2,3,4,7 */ 311 return; 312 } 313 314 /* CS5,6 */ 315 va = trunc_page(bsh); 316 endva = round_page(bsh + size); 317 318 #ifdef DIAGNOSTIC 319 if (endva <= va) 320 panic("obio_io_unmap: overflow"); 321 #endif 322 323 pmap_extract(pmap_kernel(), va, &bpa); 324 bpa += bsh & PGOFSET; 325 326 pmap_kremove(va, endva - va); 327 328 /* 329 * Free the kernel virtual mapping. 330 */ 331 uvm_km_free(kernel_map, va, endva - va); 332 } 333 334 int 335 obio_iomem_subregion(void *v, bus_space_handle_t bsh, 336 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp) 337 { 338 *nbshp = bsh + offset; 339 340 return (0); 341 } 342 343 int 344 obio_iomem_alloc(void *v, bus_addr_t rstart, bus_addr_t rend, 345 bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags, 346 bus_addr_t *bpap, bus_space_handle_t *bshp) 347 { 348 *bshp = *bpap = rstart; 349 350 return (0); 351 } 352 353 void 354 obio_iomem_free(void *v, bus_space_handle_t bsh, bus_size_t size) 355 { 356 obio_iomem_unmap(v, bsh, size); 357 } 358 359 void * 360 obio_iomem_vaddr(void *v, bus_space_handle_t bsh) 361 { 362 return ((void *)bsh); 363 } 364 365 /* 366 * on-board I/O bus space read/write 367 */ 368 uint8_t obio_iomem_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset); 369 uint16_t obio_iomem_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset); 370 uint32_t obio_iomem_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset); 371 void obio_iomem_read_multi_1(void *v, bus_space_handle_t bsh, 372 bus_size_t offset, uint8_t *addr, bus_size_t count); 373 void obio_iomem_read_multi_2(void *v, bus_space_handle_t bsh, 374 bus_size_t offset, uint16_t *addr, bus_size_t count); 375 void obio_iomem_read_multi_4(void *v, bus_space_handle_t bsh, 376 bus_size_t offset, uint32_t *addr, bus_size_t count); 377 void obio_iomem_read_raw_multi_2(void *v, bus_space_handle_t bsh, 378 bus_size_t offset, uint8_t *addr, bus_size_t count); 379 void obio_iomem_read_raw_multi_4(void *v, bus_space_handle_t bsh, 380 bus_size_t offset, uint8_t *addr, bus_size_t count); 381 void obio_iomem_read_region_1(void *v, bus_space_handle_t bsh, 382 bus_size_t offset, uint8_t *addr, bus_size_t count); 383 void obio_iomem_read_region_2(void *v, bus_space_handle_t bsh, 384 bus_size_t offset, uint16_t *addr, bus_size_t count); 385 void obio_iomem_read_region_4(void *v, bus_space_handle_t bsh, 386 bus_size_t offset, uint32_t *addr, bus_size_t count); 387 void obio_iomem_read_raw_region_2(void *v, bus_space_handle_t bsh, 388 bus_size_t offset, uint8_t *addr, bus_size_t count); 389 void obio_iomem_read_raw_region_4(void *v, bus_space_handle_t bsh, 390 bus_size_t offset, uint8_t *addr, bus_size_t count); 391 void obio_iomem_write_1(void *v, bus_space_handle_t bsh, bus_size_t offset, 392 uint8_t value); 393 void obio_iomem_write_2(void *v, bus_space_handle_t bsh, bus_size_t offset, 394 uint16_t value); 395 void obio_iomem_write_4(void *v, bus_space_handle_t bsh, bus_size_t offset, 396 uint32_t value); 397 void obio_iomem_write_multi_1(void *v, bus_space_handle_t bsh, 398 bus_size_t offset, const uint8_t *addr, bus_size_t count); 399 void obio_iomem_write_multi_2(void *v, bus_space_handle_t bsh, 400 bus_size_t offset, const uint16_t *addr, bus_size_t count); 401 void obio_iomem_write_multi_4(void *v, bus_space_handle_t bsh, 402 bus_size_t offset, const uint32_t *addr, bus_size_t count); 403 void obio_iomem_write_raw_multi_2(void *v, bus_space_handle_t bsh, 404 bus_size_t offset, const uint8_t *addr, bus_size_t count); 405 void obio_iomem_write_raw_multi_4(void *v, bus_space_handle_t bsh, 406 bus_size_t offset, const uint8_t *addr, bus_size_t count); 407 void obio_iomem_write_region_1(void *v, bus_space_handle_t bsh, 408 bus_size_t offset, const uint8_t *addr, bus_size_t count); 409 void obio_iomem_write_region_2(void *v, bus_space_handle_t bsh, 410 bus_size_t offset, const uint16_t *addr, bus_size_t count); 411 void obio_iomem_write_region_4(void *v, bus_space_handle_t bsh, 412 bus_size_t offset, const uint32_t *addr, bus_size_t count); 413 void obio_iomem_write_raw_region_2(void *v, bus_space_handle_t bsh, 414 bus_size_t offset, const uint8_t *addr, bus_size_t count); 415 void obio_iomem_write_raw_region_4(void *v, bus_space_handle_t bsh, 416 bus_size_t offset, const uint8_t *addr, bus_size_t count); 417 void obio_iomem_set_multi_1(void *v, bus_space_handle_t bsh, bus_size_t offset, 418 uint8_t val, bus_size_t count); 419 void obio_iomem_set_multi_2(void *v, bus_space_handle_t bsh, bus_size_t offset, 420 uint16_t val, bus_size_t count); 421 void obio_iomem_set_multi_4(void *v, bus_space_handle_t bsh, bus_size_t offset, 422 uint32_t val, bus_size_t count); 423 void obio_iomem_set_region_1(void *v, bus_space_handle_t bsh, 424 bus_size_t offset, uint8_t val, bus_size_t count); 425 void obio_iomem_set_region_2(void *v, bus_space_handle_t bsh, 426 bus_size_t offset, uint16_t val, bus_size_t count); 427 void obio_iomem_set_region_4(void *v, bus_space_handle_t bsh, 428 bus_size_t offset, uint32_t val, bus_size_t count); 429 void obio_iomem_copy_1(void *v, bus_space_handle_t h1, bus_size_t o1, 430 bus_space_handle_t h2, bus_size_t o2, bus_size_t count); 431 void obio_iomem_copy_2(void *v, bus_space_handle_t h1, bus_size_t o1, 432 bus_space_handle_t h2, bus_size_t o2, bus_size_t count); 433 void obio_iomem_copy_4(void *v, bus_space_handle_t h1, bus_size_t o1, 434 bus_space_handle_t h2, bus_size_t o2, bus_size_t count); 435 436 struct _bus_space obio_bus_io = 437 { 438 .bs_cookie = (void *)OBIO_IOMEM_PCMCIA_IO, 439 440 .bs_map = obio_iomem_map, 441 .bs_unmap = obio_iomem_unmap, 442 .bs_subregion = obio_iomem_subregion, 443 444 .bs_alloc = obio_iomem_alloc, 445 .bs_free = obio_iomem_free, 446 447 .bs_vaddr = obio_iomem_vaddr, 448 449 .bs_r_1 = obio_iomem_read_1, 450 .bs_r_2 = obio_iomem_read_2, 451 .bs_r_4 = obio_iomem_read_4, 452 453 .bs_rm_1 = obio_iomem_read_multi_1, 454 .bs_rm_2 = obio_iomem_read_multi_2, 455 .bs_rm_4 = obio_iomem_read_multi_4, 456 457 .bs_rrm_2 = obio_iomem_read_raw_multi_2, 458 .bs_rrm_4 = obio_iomem_read_raw_multi_4, 459 460 .bs_rr_1 = obio_iomem_read_region_1, 461 .bs_rr_2 = obio_iomem_read_region_2, 462 .bs_rr_4 = obio_iomem_read_region_4, 463 464 .bs_rrr_2 = obio_iomem_read_raw_region_2, 465 .bs_rrr_4 = obio_iomem_read_raw_region_4, 466 467 .bs_w_1 = obio_iomem_write_1, 468 .bs_w_2 = obio_iomem_write_2, 469 .bs_w_4 = obio_iomem_write_4, 470 471 .bs_wm_1 = obio_iomem_write_multi_1, 472 .bs_wm_2 = obio_iomem_write_multi_2, 473 .bs_wm_4 = obio_iomem_write_multi_4, 474 475 .bs_wrm_2 = obio_iomem_write_raw_multi_2, 476 .bs_wrm_4 = obio_iomem_write_raw_multi_4, 477 478 .bs_wr_1 = obio_iomem_write_region_1, 479 .bs_wr_2 = obio_iomem_write_region_2, 480 .bs_wr_4 = obio_iomem_write_region_4, 481 482 .bs_wrr_2 = obio_iomem_write_raw_region_2, 483 .bs_wrr_4 = obio_iomem_write_raw_region_4, 484 485 .bs_sm_1 = obio_iomem_set_multi_1, 486 .bs_sm_2 = obio_iomem_set_multi_2, 487 .bs_sm_4 = obio_iomem_set_multi_4, 488 489 .bs_sr_1 = obio_iomem_set_region_1, 490 .bs_sr_2 = obio_iomem_set_region_2, 491 .bs_sr_4 = obio_iomem_set_region_4, 492 493 .bs_c_1 = obio_iomem_copy_1, 494 .bs_c_2 = obio_iomem_copy_2, 495 .bs_c_4 = obio_iomem_copy_4, 496 }; 497 498 struct _bus_space obio_bus_mem = 499 { 500 .bs_cookie = (void *)OBIO_IOMEM_PCMCIA_MEM, 501 502 .bs_map = obio_iomem_map, 503 .bs_unmap = obio_iomem_unmap, 504 .bs_subregion = obio_iomem_subregion, 505 506 .bs_alloc = obio_iomem_alloc, 507 .bs_free = obio_iomem_free, 508 509 .bs_vaddr = obio_iomem_vaddr, 510 511 .bs_r_1 = obio_iomem_read_1, 512 .bs_r_2 = obio_iomem_read_2, 513 .bs_r_4 = obio_iomem_read_4, 514 515 .bs_rm_1 = obio_iomem_read_multi_1, 516 .bs_rm_2 = obio_iomem_read_multi_2, 517 .bs_rm_4 = obio_iomem_read_multi_4, 518 519 .bs_rrm_2 = obio_iomem_read_raw_multi_2, 520 .bs_rrm_4 = obio_iomem_read_raw_multi_4, 521 522 .bs_rr_1 = obio_iomem_read_region_1, 523 .bs_rr_2 = obio_iomem_read_region_2, 524 .bs_rr_4 = obio_iomem_read_region_4, 525 526 .bs_rrr_2 = obio_iomem_read_raw_region_2, 527 .bs_rrr_4 = obio_iomem_read_raw_region_4, 528 529 .bs_w_1 = obio_iomem_write_1, 530 .bs_w_2 = obio_iomem_write_2, 531 .bs_w_4 = obio_iomem_write_4, 532 533 .bs_wm_1 = obio_iomem_write_multi_1, 534 .bs_wm_2 = obio_iomem_write_multi_2, 535 .bs_wm_4 = obio_iomem_write_multi_4, 536 537 .bs_wrm_2 = obio_iomem_write_raw_multi_2, 538 .bs_wrm_4 = obio_iomem_write_raw_multi_4, 539 540 .bs_wr_1 = obio_iomem_write_region_1, 541 .bs_wr_2 = obio_iomem_write_region_2, 542 .bs_wr_4 = obio_iomem_write_region_4, 543 544 .bs_wrr_2 = obio_iomem_write_raw_region_2, 545 .bs_wrr_4 = obio_iomem_write_raw_region_4, 546 547 .bs_sm_1 = obio_iomem_set_multi_1, 548 .bs_sm_2 = obio_iomem_set_multi_2, 549 .bs_sm_4 = obio_iomem_set_multi_4, 550 551 .bs_sr_1 = obio_iomem_set_region_1, 552 .bs_sr_2 = obio_iomem_set_region_2, 553 .bs_sr_4 = obio_iomem_set_region_4, 554 555 .bs_c_1 = obio_iomem_copy_1, 556 .bs_c_2 = obio_iomem_copy_2, 557 .bs_c_4 = obio_iomem_copy_4, 558 }; 559 560 /* read */ 561 uint8_t 562 obio_iomem_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset) 563 { 564 return *(volatile uint8_t *)(bsh + offset); 565 } 566 567 uint16_t 568 obio_iomem_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset) 569 { 570 return *(volatile uint16_t *)(bsh + offset); 571 } 572 573 uint32_t 574 obio_iomem_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset) 575 { 576 return *(volatile uint32_t *)(bsh + offset); 577 } 578 579 void 580 obio_iomem_read_multi_1(void *v, bus_space_handle_t bsh, 581 bus_size_t offset, uint8_t *addr, bus_size_t count) 582 { 583 volatile uint8_t *p = (void *)(bsh + offset); 584 585 while (count--) { 586 *addr++ = *p; 587 } 588 } 589 590 void 591 obio_iomem_read_multi_2(void *v, bus_space_handle_t bsh, 592 bus_size_t offset, uint16_t *addr, bus_size_t count) 593 { 594 volatile uint16_t *p = (void *)(bsh + offset); 595 596 while (count--) { 597 *addr++ = *p; 598 } 599 } 600 601 void 602 obio_iomem_read_multi_4(void *v, bus_space_handle_t bsh, 603 bus_size_t offset, uint32_t *addr, bus_size_t count) 604 { 605 volatile uint32_t *p = (void *)(bsh + offset); 606 607 while (count--) { 608 *addr++ = *p; 609 } 610 } 611 612 void 613 obio_iomem_read_raw_multi_2(void *v, bus_space_handle_t bsh, 614 bus_size_t offset, uint8_t *addr, bus_size_t count) 615 { 616 volatile uint16_t *p = (void *)(bsh + offset); 617 618 count >>= 1; 619 while (count--) { 620 *(uint16_t *)addr = *p; 621 addr += 2; 622 } 623 } 624 625 void 626 obio_iomem_read_raw_multi_4(void *v, bus_space_handle_t bsh, 627 bus_size_t offset, uint8_t *addr, bus_size_t count) 628 { 629 volatile uint32_t *p = (void *)(bsh + offset); 630 631 count >>= 2; 632 while (count--) { 633 *(uint32_t *)addr = *p; 634 addr += 4; 635 } 636 } 637 638 void 639 obio_iomem_read_region_1(void *v, bus_space_handle_t bsh, 640 bus_size_t offset, uint8_t *addr, bus_size_t count) 641 { 642 volatile uint8_t *p = (void *)(bsh + offset); 643 644 while (count--) { 645 *addr++ = *p++; 646 } 647 } 648 649 void 650 obio_iomem_read_region_2(void *v, bus_space_handle_t bsh, 651 bus_size_t offset, uint16_t *addr, bus_size_t count) 652 { 653 volatile uint16_t *p = (void *)(bsh + offset); 654 655 while (count--) { 656 *addr++ = *p++; 657 } 658 } 659 660 void 661 obio_iomem_read_region_4(void *v, bus_space_handle_t bsh, 662 bus_size_t offset, uint32_t *addr, bus_size_t count) 663 { 664 volatile uint32_t *p = (void *)(bsh + offset); 665 666 while (count--) { 667 *addr++ = *p++; 668 } 669 } 670 671 void 672 obio_iomem_read_raw_region_2(void *v, bus_space_handle_t bsh, 673 bus_size_t offset, uint8_t *addr, bus_size_t count) 674 { 675 volatile uint16_t *p = (void *)(bsh + offset); 676 677 count >>= 1; 678 while (count--) { 679 *(uint16_t *)addr = *p++; 680 addr += 2; 681 } 682 } 683 684 void 685 obio_iomem_read_raw_region_4(void *v, bus_space_handle_t bsh, 686 bus_size_t offset, uint8_t *addr, bus_size_t count) 687 { 688 volatile uint32_t *p = (void *)(bsh + offset); 689 690 count >>= 2; 691 while (count--) { 692 *(uint32_t *)addr = *p++; 693 addr += 4; 694 } 695 } 696 697 /* write */ 698 void 699 obio_iomem_write_1(void *v, bus_space_handle_t bsh, bus_size_t offset, 700 uint8_t value) 701 { 702 *(volatile uint8_t *)(bsh + offset) = value; 703 } 704 705 void 706 obio_iomem_write_2(void *v, bus_space_handle_t bsh, bus_size_t offset, 707 uint16_t value) 708 { 709 *(volatile uint16_t *)(bsh + offset) = value; 710 } 711 712 void 713 obio_iomem_write_4(void *v, bus_space_handle_t bsh, bus_size_t offset, 714 uint32_t value) 715 { 716 *(volatile uint32_t *)(bsh + offset) = value; 717 } 718 719 void 720 obio_iomem_write_multi_1(void *v, bus_space_handle_t bsh, 721 bus_size_t offset, const uint8_t *addr, bus_size_t count) 722 { 723 volatile uint8_t *p = (void *)(bsh + offset); 724 725 while (count--) { 726 *p = *addr++; 727 } 728 } 729 730 void 731 obio_iomem_write_multi_2(void *v, bus_space_handle_t bsh, 732 bus_size_t offset, const uint16_t *addr, bus_size_t count) 733 { 734 volatile uint16_t *p = (void *)(bsh + offset); 735 736 while (count--) { 737 *p = *addr++; 738 } 739 } 740 741 void 742 obio_iomem_write_multi_4(void *v, bus_space_handle_t bsh, 743 bus_size_t offset, const uint32_t *addr, bus_size_t count) 744 { 745 volatile uint32_t *p = (void *)(bsh + offset); 746 747 while (count--) { 748 *p = *addr++; 749 } 750 } 751 752 void 753 obio_iomem_write_raw_multi_2(void *v, bus_space_handle_t bsh, 754 bus_size_t offset, const uint8_t *addr, bus_size_t count) 755 { 756 volatile uint16_t *p = (void *)(bsh + offset); 757 758 count >>= 1; 759 while (count--) { 760 *p = *(uint16_t *)addr; 761 addr += 2; 762 } 763 } 764 765 void 766 obio_iomem_write_raw_multi_4(void *v, bus_space_handle_t bsh, 767 bus_size_t offset, const uint8_t *addr, bus_size_t count) 768 { 769 volatile uint32_t *p = (void *)(bsh + offset); 770 771 count >>= 2; 772 while (count--) { 773 *p = *(uint32_t *)addr; 774 addr += 4; 775 } 776 } 777 778 void 779 obio_iomem_write_region_1(void *v, bus_space_handle_t bsh, 780 bus_size_t offset, const uint8_t *addr, bus_size_t count) 781 { 782 volatile uint8_t *p = (void *)(bsh + offset); 783 784 while (count--) { 785 *p++ = *addr++; 786 } 787 } 788 789 void 790 obio_iomem_write_region_2(void *v, bus_space_handle_t bsh, 791 bus_size_t offset, const uint16_t *addr, bus_size_t count) 792 { 793 volatile uint16_t *p = (void *)(bsh + offset); 794 795 while (count--) { 796 *p++ = *addr++; 797 } 798 } 799 800 void 801 obio_iomem_write_region_4(void *v, bus_space_handle_t bsh, 802 bus_size_t offset, const uint32_t *addr, bus_size_t count) 803 { 804 volatile uint32_t *p = (void *)(bsh + offset); 805 806 while (count--) { 807 *p++ = *addr++; 808 } 809 } 810 811 void 812 obio_iomem_write_raw_region_2(void *v, bus_space_handle_t bsh, 813 bus_size_t offset, const uint8_t *addr, bus_size_t count) 814 { 815 volatile uint16_t *p = (void *)(bsh + offset); 816 817 count >>= 1; 818 while (count--) { 819 *p++ = *(uint16_t *)addr; 820 addr += 2; 821 } 822 } 823 824 void 825 obio_iomem_write_raw_region_4(void *v, bus_space_handle_t bsh, 826 bus_size_t offset, const uint8_t *addr, bus_size_t count) 827 { 828 volatile uint32_t *p = (void *)(bsh + offset); 829 830 count >>= 2; 831 while (count--) { 832 *p++ = *(uint32_t *)addr; 833 addr += 4; 834 } 835 } 836 837 void 838 obio_iomem_set_multi_1(void *v, bus_space_handle_t bsh, 839 bus_size_t offset, uint8_t val, bus_size_t count) 840 { 841 volatile uint8_t *p = (void *)(bsh + offset); 842 843 while (count--) { 844 *p = val; 845 } 846 } 847 848 void 849 obio_iomem_set_multi_2(void *v, bus_space_handle_t bsh, 850 bus_size_t offset, uint16_t val, bus_size_t count) 851 { 852 volatile uint16_t *p = (void *)(bsh + offset); 853 854 while (count--) { 855 *p = val; 856 } 857 } 858 859 void 860 obio_iomem_set_multi_4(void *v, bus_space_handle_t bsh, 861 bus_size_t offset, uint32_t val, bus_size_t count) 862 { 863 volatile uint32_t *p = (void *)(bsh + offset); 864 865 while (count--) { 866 *p = val; 867 } 868 } 869 870 void 871 obio_iomem_set_region_1(void *v, bus_space_handle_t bsh, 872 bus_size_t offset, uint8_t val, bus_size_t count) 873 { 874 volatile uint8_t *addr = (void *)(bsh + offset); 875 876 while (count--) { 877 *addr++ = val; 878 } 879 } 880 881 void 882 obio_iomem_set_region_2(void *v, bus_space_handle_t bsh, 883 bus_size_t offset, uint16_t val, bus_size_t count) 884 { 885 volatile uint16_t *addr = (void *)(bsh + offset); 886 887 while (count--) { 888 *addr++ = val; 889 } 890 } 891 892 void 893 obio_iomem_set_region_4(void *v, bus_space_handle_t bsh, 894 bus_size_t offset, uint32_t val, bus_size_t count) 895 { 896 volatile uint32_t *addr = (void *)(bsh + offset); 897 898 while (count--) { 899 *addr++ = val; 900 } 901 } 902 903 void 904 obio_iomem_copy_1(void *v, bus_space_handle_t h1, bus_size_t o1, 905 bus_space_handle_t h2, bus_size_t o2, bus_size_t count) 906 { 907 volatile uint8_t *addr1 = (void *)(h1 + o1); 908 volatile uint8_t *addr2 = (void *)(h2 + o2); 909 910 if (addr1 >= addr2) { /* src after dest: copy forward */ 911 while (count--) { 912 *addr2++ = *addr1++; 913 } 914 } else { /* dest after src: copy backwards */ 915 addr1 += count - 1; 916 addr2 += count - 1; 917 while (count--) { 918 *addr2-- = *addr1--; 919 } 920 } 921 } 922 923 void 924 obio_iomem_copy_2(void *v, bus_space_handle_t h1, bus_size_t o1, 925 bus_space_handle_t h2, bus_size_t o2, bus_size_t count) 926 { 927 volatile uint16_t *addr1 = (void *)(h1 + o1); 928 volatile uint16_t *addr2 = (void *)(h2 + o2); 929 930 if (addr1 >= addr2) { /* src after dest: copy forward */ 931 while (count--) { 932 *addr2++ = *addr1++; 933 } 934 } else { /* dest after src: copy backwards */ 935 addr1 += count - 1; 936 addr2 += count - 1; 937 while (count--) { 938 *addr2-- = *addr1--; 939 } 940 } 941 } 942 943 void 944 obio_iomem_copy_4(void *v, bus_space_handle_t h1, bus_size_t o1, 945 bus_space_handle_t h2, bus_size_t o2, bus_size_t count) 946 { 947 volatile uint32_t *addr1 = (void *)(h1 + o1); 948 volatile uint32_t *addr2 = (void *)(h2 + o2); 949 950 if (addr1 >= addr2) { /* src after dest: copy forward */ 951 while (count--) { 952 *addr2++ = *addr1++; 953 } 954 } else { /* dest after src: copy backwards */ 955 addr1 += count - 1; 956 addr2 += count - 1; 957 while (count--) { 958 *addr2-- = *addr1--; 959 } 960 } 961 } 962