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