1 /* $NetBSD: bus_space_alignstride_chipdep.c,v 1.32 2022/09/29 07:00:46 skrll Exp $ */ 2 3 /*- 4 * Copyright (c) 1998, 2000, 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 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 /* 34 * Copyright (c) 1995, 1996 Carnegie-Mellon University. 35 * All rights reserved. 36 * 37 * Author: Chris G. Demetriou 38 * 39 * Permission to use, copy, modify and distribute this software and 40 * its documentation is hereby granted, provided that both the copyright 41 * notice and this permission notice appear in all copies of the 42 * software, derivative works or modified versions, and any portions 43 * thereof, and that both notices appear in supporting documentation. 44 * 45 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 46 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 47 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 48 * 49 * Carnegie Mellon requests users of this software to return to 50 * 51 * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU 52 * School of Computer Science 53 * Carnegie Mellon University 54 * Pittsburgh PA 15213-3890 55 * 56 * any improvements or extensions that they make and grant Carnegie the 57 * rights to redistribute these changes. 58 */ 59 60 /* 61 * Common Chipset "bus I/O" functions. 62 * 63 * uses: 64 * CHIP name of the 'chip' it's being compiled for. 65 * CHIP_BASE memory or I/O space base to use. 66 * CHIP_EX_STORE 67 * If defined, device-provided static storage area 68 * for the memory or I/O space extent. If this is 69 * defined, CHIP_EX_STORE_SIZE must also be defined. 70 * If this is not defined, a static area will be 71 * declared. 72 * CHIP_EX_STORE_SIZE 73 * Size of the device-provided static storage area 74 * for the memory or I/O memory space extent. 75 * CHIP_LITTLE_ENDIAN | CHIP_BIG_ENDIAN 76 * For endian-specific busses, like PCI (little). 77 * CHIP_WRONG_ENDIAN 78 * For things like PCI bridges with endian conversion that 79 * can't be turned off, so we need to switch address bits 80 * for 8 and 16bit accesses. 81 * Example: MACE PCI bridge in SGI O2 82 * CHIP_ACCESS_SIZE 83 * Size (in bytes) of minimum bus access, e.g. 4 84 * to indicate all bus cycles are 32-bits. Defaults 85 * to 1, indicating any access size is valid. 86 */ 87 88 #include <sys/cdefs.h> 89 __KERNEL_RCSID(0, "$NetBSD: bus_space_alignstride_chipdep.c,v 1.32 2022/09/29 07:00:46 skrll Exp $"); 90 91 #ifdef CHIP_EXTENT 92 #include <sys/extent.h> 93 #endif 94 95 #include <mips/locore.h> 96 97 #include <uvm/uvm_extern.h> 98 99 #if defined(__mips_o32) && defined(MIPS3) 100 #define NEED_64BIT_ASM 101 #endif 102 103 #define __C(A,B) __CONCAT(A,B) 104 #define __S(S) __STRING(S) 105 106 #ifdef CHIP_IO 107 #define __BS(A) __C(__C(CHIP,_bus_io_),A) 108 #endif 109 #ifdef CHIP_MEM 110 #define __BS(A) __C(__C(CHIP,_bus_mem_),A) 111 #endif 112 113 #if defined(CHIP_LITTLE_ENDIAN) 114 #define CHIP_SWAP16(x) le16toh(x) 115 #define CHIP_SWAP32(x) le32toh(x) 116 #define CHIP_SWAP64(x) le64toh(x) 117 #define CHIP_NEED_STREAM 1 118 #elif defined(CHIP_BIG_ENDIAN) 119 #define CHIP_SWAP16(x) be16toh(x) 120 #define CHIP_SWAP32(x) be32toh(x) 121 #define CHIP_SWAP64(x) be64toh(x) 122 #define CHIP_NEED_STREAM 1 123 #else 124 #define CHIP_SWAP16(x) (x) 125 #define CHIP_SWAP32(x) (x) 126 #define CHIP_SWAP64(x) (x) 127 #endif 128 129 #ifndef CHIP_ACCESS_SIZE 130 #define CHIP_ACCESS_SIZE 1 131 #endif 132 133 #if CHIP_ACCESS_SIZE==1 134 # define CHIP_SWAP_ACCESS(x) (x) 135 #elif CHIP_ACCESS_SIZE==2 136 # define CHIP_SWAP_ACCESS(x) CHIP_SWAP16(x) 137 #elif CHIP_ACCESS_SIZE==4 138 # define CHIP_SWAP_ACCESS(x) CHIP_SWAP32(x) 139 #elif CHIP_ACCESS_SIZE==8 140 # ifndef MIPS3_PLUS 141 # error 8 byte access size not available 142 # endif 143 # define CHIP_SWAP_ACCESS(x) CHIP_SWAP64(x) 144 #else 145 # error your access size not implemented 146 #endif 147 148 /* 149 * The logic here determines a few macros to support requirements for 150 * whole-word accesses: 151 * 152 * CHIP_TYPE is a uintXX_t that represents the native access type for the bus. 153 * 154 * CHIP_SHIFTXX is the number of bits to shift a big-endian value to convert 155 * convert between the CHIP_TYPE and uintXX_t. 156 * 157 * The idea is that if we want to do a 16bit load from a bus that only 158 * supports 32-bit accesses, we will access the first 16 bits of the 159 * addressed 32-bit word. 160 * 161 * Obviously (hopefully) this method is inadequate to support addressing the 162 * second half of a 16-bit word, or the upper 3/4 of a 32-bit value, etc. 163 * In other words, the drivers should probably not be relying on this! 164 * 165 * We should probably come back in here some day and handle offsets properly. 166 * to do that, we need to mask off the low order bits of the address, and 167 * then figure out which bits they correspond to. 168 * 169 * If we have fixed access size limitations, we need to make sure that 170 * handle shifting required for big-endian storage. The reality is 171 * that if the bus only supports size "n", then drivers should 172 * probably only access it using "n" sized (or bigger) accesses. 173 */ 174 175 #if CHIP_ACCESS_SIZE == 1 176 #define CHIP_TYPE uint8_t 177 #endif 178 179 #if CHIP_ACCESS_SIZE == 2 180 #define CHIP_TYPE uint16_t 181 #endif 182 183 #if CHIP_ACCESS_SIZE == 4 184 #define CHIP_TYPE uint32_t 185 #endif 186 187 #if CHIP_ACCESS_SIZE == 8 188 #define CHIP_TYPE uint64_t 189 #endif 190 191 #ifndef CHIP_TYPE 192 #error "Invalid chip access size!" 193 #endif 194 195 #ifdef CHIP_EXTENT 196 #ifndef CHIP_EX_STORE 197 static long 198 __BS(ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 199 #define CHIP_EX_STORE(v) (__BS(ex_storage)) 200 #define CHIP_EX_STORE_SIZE(v) (sizeof __BS(ex_storage)) 201 #endif 202 #endif /* CHIP_EXTENT */ 203 204 #ifndef CHIP_ALIGN_STRIDE 205 #define CHIP_ALIGN_STRIDE 0 206 #endif 207 208 #ifdef CHIP_WRONG_ENDIAN 209 #define CHIP_OFF8(o) ((o) ^ 3) 210 #else 211 #if CHIP_ALIGN_STRIDE > 0 212 #define CHIP_OFF8(o) ((o) << (CHIP_ALIGN_STRIDE)) 213 #else 214 #define CHIP_OFF8(o) (o) 215 #endif 216 #endif 217 218 #ifdef CHIP_WRONG_ENDIAN 219 #define CHIP_OFF16(o) ((o) ^ 2) 220 #else 221 #if CHIP_ALIGN_STRIDE > 1 222 #define CHIP_OFF16(o) ((o) << (CHIP_ALIGN_STRIDE - 1)) 223 #else 224 #define CHIP_OFF16(o) (o) 225 #endif 226 #endif 227 228 #if CHIP_ALIGN_STRIDE > 2 229 #define CHIP_OFF32(o) ((o) << (CHIP_ALIGN_STRIDE - 2)) 230 #else 231 #define CHIP_OFF32(o) (o) 232 #endif 233 234 #if CHIP_ALIGN_STRIDE > 3 235 #define CHIP_OFF64(o) ((o) << (CHIP_ALIGN_STRIDE - 3)) 236 #else 237 #define CHIP_OFF64(o) (o) 238 #endif 239 240 241 static int 242 __BS(get_window)(void *v, int window, struct mips_bus_space_translation *mbst) 243 { 244 245 switch (window) { 246 #ifdef CHIP_W1_BUS_START 247 case 0: 248 mbst->mbst_bus_start = CHIP_W1_BUS_START(v); 249 mbst->mbst_bus_end = CHIP_W1_BUS_END(v); 250 mbst->mbst_sys_start = CHIP_W1_SYS_START(v); 251 mbst->mbst_sys_end = CHIP_W1_SYS_END(v); 252 mbst->mbst_align_stride = CHIP_ALIGN_STRIDE; 253 mbst->mbst_flags = 0; 254 break; 255 #endif 256 257 #ifdef CHIP_W2_BUS_START 258 case 1: 259 mbst->mbst_bus_start = CHIP_W2_BUS_START(v); 260 mbst->mbst_bus_end = CHIP_W2_BUS_END(v); 261 mbst->mbst_sys_start = CHIP_W2_SYS_START(v); 262 mbst->mbst_sys_end = CHIP_W2_SYS_END(v); 263 mbst->mbst_align_stride = CHIP_ALIGN_STRIDE; 264 mbst->mbst_flags = 0; 265 break; 266 #endif 267 268 #ifdef CHIP_W3_BUS_START 269 case 2: 270 mbst->mbst_bus_start = CHIP_W3_BUS_START(v); 271 mbst->mbst_bus_end = CHIP_W3_BUS_END(v); 272 mbst->mbst_sys_start = CHIP_W3_SYS_START(v); 273 mbst->mbst_sys_end = CHIP_W3_SYS_END(v); 274 mbst->mbst_align_stride = CHIP_ALIGN_STRIDE; 275 mbst->mbst_flags = 0; 276 break; 277 #endif 278 279 default: 280 panic(__S(__BS(get_window)) ": invalid window %d", 281 window); 282 } 283 284 return (0); 285 } 286 287 static int 288 __BS(translate)(void *v, bus_addr_t addr, bus_size_t len, int flags, 289 struct mips_bus_space_translation *mbst) 290 { 291 bus_addr_t end = addr + (len - 1); 292 #if CHIP_ALIGN_STRIDE != 0 293 int linear = flags & BUS_SPACE_MAP_LINEAR; 294 295 /* 296 * Can't map xxx space linearly. 297 */ 298 if (linear) 299 return (EOPNOTSUPP); 300 #endif 301 302 #ifdef CHIP_W1_BUS_START 303 if (addr >= CHIP_W1_BUS_START(v) && end <= CHIP_W1_BUS_END(v)) 304 return (__BS(get_window)(v, 0, mbst)); 305 #endif 306 307 #ifdef CHIP_W2_BUS_START 308 if (addr >= CHIP_W2_BUS_START(v) && end <= CHIP_W2_BUS_END(v)) 309 return (__BS(get_window)(v, 1, mbst)); 310 #endif 311 312 #ifdef CHIP_W3_BUS_START 313 if (addr >= CHIP_W3_BUS_START(v) && end <= CHIP_W3_BUS_END(v)) 314 return (__BS(get_window)(v, 2, mbst)); 315 #endif 316 317 #ifdef EXTENT_DEBUG 318 printf("\n"); 319 #ifdef CHIP_W1_BUS_START 320 printf("%s: window[1]=0x%lx-0x%lx\n", __S(__BS(map)), 321 (u_long)CHIP_W1_BUS_START(v), (u_long)CHIP_W1_BUS_END(v)); 322 #endif 323 #ifdef CHIP_W2_BUS_START 324 printf("%s: window[2]=0x%lx-0x%lx\n", __S(__BS(map)), 325 (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); 326 #endif 327 #ifdef CHIP_W3_BUS_START 328 printf("%s: window[3]=0x%lx-0x%lx\n", __S(__BS(map)), 329 (u_long)CHIP_W3_BUS_START(v), (u_long)CHIP_W3_BUS_END(v)); 330 #endif 331 #endif /* EXTENT_DEBUG */ 332 /* No translation. */ 333 return (EINVAL); 334 } 335 336 static int 337 __BS(map)(void *v, bus_addr_t addr, bus_size_t size, int flags, 338 bus_space_handle_t *hp, int acct) 339 { 340 struct mips_bus_space_translation mbst; 341 int error; 342 343 /* 344 * Get the translation for this address. 345 */ 346 error = __BS(translate)(v, addr, size, flags, &mbst); 347 if (error) 348 return (error); 349 350 #ifdef CHIP_EXTENT 351 if (acct == 0) 352 goto mapit; 353 354 #ifdef EXTENT_DEBUG 355 printf("%s: allocating %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n", 356 __S(__BS(map)), addr, addr + size - 1); 357 #endif 358 error = extent_alloc_region(CHIP_EXTENT(v), addr, size, 359 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 360 if (error) { 361 #ifdef EXTENT_DEBUG 362 printf("%s: allocation failed (%d)\n", __S(__BS(map)), error); 363 extent_print(CHIP_EXTENT(v)); 364 #endif 365 return (error); 366 } 367 368 mapit: 369 #endif /* CHIP_EXTENT */ 370 371 addr = mbst.mbst_sys_start + (addr - mbst.mbst_bus_start); 372 373 #if defined(__mips_n32) || defined(_LP64) 374 if (flags & BUS_SPACE_MAP_CACHEABLE) { 375 #ifdef __mips_n32 376 if (((addr + size) & ~MIPS_PHYS_MASK) == 0) 377 *hp = (intptr_t)MIPS_PHYS_TO_KSEG0(addr); 378 else 379 #endif 380 *hp = MIPS_PHYS_TO_XKPHYS_CACHED(addr); 381 } else if (flags & BUS_SPACE_MAP_PREFETCHABLE) { 382 *hp = MIPS_PHYS_TO_XKPHYS_ACC(addr); 383 } else { 384 #ifdef __mips_n32 385 if (((addr + size) & ~MIPS_PHYS_MASK) == 0) 386 *hp = (intptr_t)MIPS_PHYS_TO_KSEG1(addr); 387 else 388 #endif 389 *hp = MIPS_PHYS_TO_XKPHYS_UNCACHED(addr); 390 } 391 #else 392 if (((addr + size) & ~MIPS_PHYS_MASK) != 0) { 393 vaddr_t va; 394 paddr_t pa; 395 int s; 396 397 size = round_page((addr % PAGE_SIZE) + size); 398 va = uvm_km_alloc(kernel_map, size, PAGE_SIZE, 399 UVM_KMF_VAONLY | UVM_KMF_NOWAIT); 400 if (va == 0) 401 return ENOMEM; 402 403 /* check use of handle_is_km in BS(unmap) */ 404 KASSERT(!(MIPS_KSEG0_P(va) || MIPS_KSEG1_P(va))); 405 406 *hp = va + (addr & PAGE_MASK); 407 pa = trunc_page(addr); 408 409 s = splhigh(); 410 while (size != 0) { 411 pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, 0); 412 pa += PAGE_SIZE; 413 va += PAGE_SIZE; 414 size -= PAGE_SIZE; 415 } 416 pmap_update(pmap_kernel()); 417 splx(s); 418 } else { 419 if (flags & BUS_SPACE_MAP_CACHEABLE) 420 *hp = (intptr_t)MIPS_PHYS_TO_KSEG0(addr); 421 else 422 *hp = (intptr_t)MIPS_PHYS_TO_KSEG1(addr); 423 } 424 #endif 425 426 return (0); 427 } 428 429 static void 430 __BS(unmap)(void *v, bus_space_handle_t h, bus_size_t size, int acct) 431 { 432 #if !defined(_LP64) || defined(CHIP_EXTENT) 433 bus_addr_t addr = 0; /* initialize to appease gcc */ 434 #endif 435 #ifndef _LP64 436 bool handle_is_km; 437 438 /* determine if h is addr obtained from uvm_km_alloc */ 439 handle_is_km = !(MIPS_KSEG0_P(h) || MIPS_KSEG1_P(h)); 440 #ifdef __mips_n32 441 if (handle_is_km == true) 442 handle_is_km = !MIPS_XKPHYS_P(h); 443 #endif 444 if (handle_is_km == true) { 445 paddr_t pa; 446 vaddr_t va = (vaddr_t)trunc_page(h); 447 vsize_t sz = (vsize_t)round_page((h % PAGE_SIZE) + size); 448 int s; 449 450 s = splhigh(); 451 452 if (pmap_extract(pmap_kernel(), (vaddr_t)h, &pa) == false) 453 panic("%s: pmap_extract failed", __func__); 454 addr = (bus_addr_t)pa; 455 #if 0 456 printf("%s:%d: addr %#"PRIxBUSADDR", sz %#"PRIxVSIZE"\n", 457 __func__, __LINE__, addr, sz); 458 #endif 459 /* sanity check: this is why we couldn't map w/ kseg[0,1] */ 460 KASSERT (((addr + sz) & ~MIPS_PHYS_MASK) != 0); 461 462 pmap_kremove(va, sz); 463 pmap_update(pmap_kernel()); 464 uvm_km_free(kernel_map, va, sz, UVM_KMF_VAONLY); 465 466 splx(s); 467 } 468 #endif /* _LP64 */ 469 470 #ifdef CHIP_EXTENT 471 472 if (acct == 0) 473 return; 474 475 #ifdef EXTENT_DEBUG 476 printf("%s: freeing handle %#"PRIxBSH" for %#"PRIxBUSSIZE"\n", 477 __S(__BS(unmap)), h, size); 478 #endif 479 480 #ifdef _LP64 481 KASSERT(MIPS_XKPHYS_P(h)); 482 addr = MIPS_XKPHYS_TO_PHYS(h); 483 #else 484 if (handle_is_km == false) { 485 if (MIPS_KSEG0_P(h)) 486 addr = MIPS_KSEG0_TO_PHYS(h); 487 #ifdef __mips_n32 488 else if (MIPS_XKPHYS_P(h)) 489 addr = MIPS_XKPHYS_TO_PHYS(h); 490 #endif 491 else 492 addr = MIPS_KSEG1_TO_PHYS(h); 493 } 494 #endif 495 496 #ifdef CHIP_W1_BUS_START 497 if (addr >= CHIP_W1_SYS_START(v) && addr <= CHIP_W1_SYS_END(v)) { 498 addr = CHIP_W1_BUS_START(v) + (addr - CHIP_W1_SYS_START(v)); 499 } else 500 #endif 501 #ifdef CHIP_W2_BUS_START 502 if (addr >= CHIP_W2_SYS_START(v) && addr <= CHIP_W2_SYS_END(v)) { 503 addr = CHIP_W2_BUS_START(v) + (addr - CHIP_W2_SYS_START(v)); 504 } else 505 #endif 506 #ifdef CHIP_W3_BUS_START 507 if (addr >= CHIP_W3_SYS_START(v) && addr <= CHIP_W3_SYS_END(v)) { 508 addr = CHIP_W3_BUS_START(v) + (addr - CHIP_W3_SYS_START(v)); 509 } else 510 #endif 511 { 512 printf("\n"); 513 #ifdef CHIP_W1_BUS_START 514 printf("%s: sys window[1]=0x%lx-0x%lx\n", 515 __S(__BS(unmap)), (u_long)CHIP_W1_SYS_START(v), 516 (u_long)CHIP_W1_SYS_END(v)); 517 #endif 518 #ifdef CHIP_W2_BUS_START 519 printf("%s: sys window[2]=0x%lx-0x%lx\n", 520 __S(__BS(unmap)), (u_long)CHIP_W2_SYS_START(v), 521 (u_long)CHIP_W2_SYS_END(v)); 522 #endif 523 #ifdef CHIP_W3_BUS_START 524 printf("%s: sys window[3]=0x%lx-0x%lx\n", 525 __S(__BS(unmap)), (u_long)CHIP_W3_SYS_START(v), 526 (u_long)CHIP_W3_SYS_END(v)); 527 #endif 528 panic("%s: don't know how to unmap %#"PRIxBSH, __S(__BS(unmap)), h); 529 } 530 531 #ifdef EXTENT_DEBUG 532 printf("%s: freeing %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n", 533 __S(__BS(unmap)), addr, addr + size - 1); 534 #endif 535 int error = extent_free(CHIP_EXTENT(v), addr, size, 536 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 537 if (error) { 538 printf("%s: WARNING: could not unmap" 539 " %#"PRIxBUSADDR"-%#"PRIxBUSADDR" (error %d)\n", 540 __S(__BS(unmap)), addr, addr + size - 1, error); 541 #ifdef EXTENT_DEBUG 542 extent_print(CHIP_EXTENT(v)); 543 #endif 544 } 545 #endif /* CHIP_EXTENT */ 546 #if !defined(_LP64) || defined(CHIP_EXTENT) 547 __USE(addr); 548 #endif 549 } 550 551 static int 552 __BS(subregion)(void *v, bus_space_handle_t h, bus_size_t offset, 553 bus_size_t size, bus_space_handle_t *nh) 554 { 555 556 *nh = h + (offset << CHIP_ALIGN_STRIDE); 557 return (0); 558 } 559 560 static int 561 __BS(alloc)(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, 562 bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp, 563 bus_space_handle_t *bshp) 564 { 565 #ifdef CHIP_EXTENT 566 struct mips_bus_space_translation mbst; 567 u_long addr; /* bogus but makes extent happy */ 568 int error; 569 #if CHIP_ALIGN_STRIDE != 0 570 int linear = flags & BUS_SPACE_MAP_LINEAR; 571 572 /* 573 * Can't map xxx space linearly. 574 */ 575 if (linear) 576 return (EOPNOTSUPP); 577 #endif 578 579 /* 580 * Do the requested allocation. 581 */ 582 #ifdef EXTENT_DEBUG 583 printf("%s: allocating from %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n", 584 __S(__BS(alloc)), rstart, rend); 585 #endif 586 error = extent_alloc_subregion(CHIP_EXTENT(v), rstart, rend, size, 587 align, boundary, 588 EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0), 589 &addr); 590 if (error) { 591 #ifdef EXTENT_DEBUG 592 printf("%s: allocation failed (%d)\n", __S(__BS(alloc)), error); 593 extent_print(CHIP_EXTENT(v)); 594 #endif 595 return (error); 596 } 597 598 #ifdef EXTENT_DEBUG 599 printf("%s: allocated 0x%lx to %#"PRIxBUSSIZE"\n", 600 __S(__BS(alloc)), addr, addr + size - 1); 601 #endif 602 603 error = __BS(translate)(v, addr, size, flags, &mbst); 604 if (error) { 605 (void) extent_free(CHIP_EXTENT(v), addr, size, 606 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 607 return (error); 608 } 609 610 *addrp = addr; 611 #if !defined(__mips_o32) 612 if (flags & BUS_SPACE_MAP_CACHEABLE) { 613 *bshp = MIPS_PHYS_TO_XKPHYS_CACHED(mbst.mbst_sys_start + 614 (addr - mbst.mbst_bus_start)); 615 } else { 616 *bshp = MIPS_PHYS_TO_XKPHYS_UNCACHED(mbst.mbst_sys_start + 617 (addr - mbst.mbst_bus_start)); 618 } 619 #else 620 if (flags & BUS_SPACE_MAP_CACHEABLE) { 621 *bshp = MIPS_PHYS_TO_KSEG0(mbst.mbst_sys_start + 622 (addr - mbst.mbst_bus_start)); 623 } else 624 *bshp = MIPS_PHYS_TO_KSEG1(mbst.mbst_sys_start + 625 (addr - mbst.mbst_bus_start)); 626 #endif 627 628 return (0); 629 #else /* ! CHIP_EXTENT */ 630 return (EOPNOTSUPP); 631 #endif /* CHIP_EXTENT */ 632 } 633 634 static void 635 __BS(free)(void *v, bus_space_handle_t bsh, bus_size_t size) 636 { 637 638 /* Unmap does all we need to do. */ 639 __BS(unmap)(v, bsh, size, 1); 640 } 641 642 static void * 643 __BS(vaddr)(void *v, bus_space_handle_t bsh) 644 { 645 646 #if (CHIP_ALIGN_STRIDE != 0) 647 /* Linear mappings not possible. */ 648 return (NULL); 649 #elif defined(__mips_n32) 650 if (MIPS_KSEG0_P(bsh) || MIPS_KSEG1_P(bsh) || MIPS_KSEG2_P(bsh)) 651 return ((void *)(intptr_t)bsh); 652 return NULL; 653 #else 654 return ((void *)bsh); 655 #endif 656 } 657 658 static paddr_t 659 __BS(mmap)(void *v, bus_addr_t addr, off_t off, int prot, int flags) 660 { 661 #ifdef CHIP_IO 662 663 /* Not supported for I/O space. */ 664 return (-1); 665 #elif defined(CHIP_MEM) 666 paddr_t ret; 667 struct mips_bus_space_translation mbst; 668 int error; 669 670 /* 671 * Get the translation for this address. 672 */ 673 error = __BS(translate)(v, addr, off + PAGE_SIZE, flags, 674 &mbst); 675 if (error) 676 return (-1); 677 ret = mbst.mbst_sys_start + (addr - mbst.mbst_bus_start) + off; 678 #if defined(_MIPS_PADDR_T_64BIT) || defined(_LP64) 679 if (flags & BUS_SPACE_MAP_PREFETCHABLE) { 680 ret |= PGC_PREFETCH; 681 } 682 #endif 683 684 return (mips_btop(ret)); 685 #else 686 # error must define one of CHIP_IO or CHIP_MEM 687 #endif 688 } 689 690 static void 691 __BS(barrier)(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int f) 692 { 693 694 /* XXX XXX XXX */ 695 if ((f & BUS_SPACE_BARRIER_WRITE) != 0) 696 wbflush(); 697 } 698 699 static uint8_t 700 __BS(read_1)(void *v, bus_space_handle_t h, bus_size_t off) 701 { 702 h += CHIP_OFF8(off); 703 704 const int shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8; 705 h &= ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)); 706 #if CHIP_ACCESS_SIZE == 8 707 const CHIP_TYPE val = mips3_ld(h); 708 #elif CHIP_ACCESS_SIZE == 4 709 const CHIP_TYPE val = mips_lwu(h); 710 #elif CHIP_ACCESS_SIZE == 2 711 const CHIP_TYPE val = mips_lhu(h); 712 #else 713 const uint8_t val = mips_lbu(h); 714 #endif 715 const uint8_t r = (uint8_t)(CHIP_SWAP_ACCESS(val) >> shift); 716 717 return r; 718 } 719 720 static uint16_t 721 __BS(read_2)(void *v, bus_space_handle_t h, bus_size_t off) 722 { 723 KASSERT((off & 1) == 0); 724 h += CHIP_OFF16(off); 725 726 const int shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8; 727 h &= ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)); 728 #if CHIP_ACCESS_SIZE == 8 729 const CHIP_TYPE val = mips3_ld(h); 730 #elif CHIP_ACCESS_SIZE == 4 731 const CHIP_TYPE val = mips_lwu(h); 732 #else 733 const uint16_t val = mips_lhu(h); 734 #endif 735 const uint16_t r = (uint16_t)CHIP_SWAP16(val >> shift); 736 737 return r; 738 } 739 740 static uint32_t 741 __BS(read_4)(void *v, bus_space_handle_t h, bus_size_t off) 742 { 743 KASSERT((off & 3) == 0); 744 745 h += CHIP_OFF32(off); 746 const int shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8; 747 h &= ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)); 748 #if CHIP_ACCESS_SIZE > 4 749 const CHIP_TYPE val = mips3_ld(h); 750 #else /* CHIP_ACCESS_SIZE > 4 */ 751 const uint32_t val = mips_lwu(h); 752 #endif 753 const uint32_t r = (uint32_t)CHIP_SWAP32(val >> shift); 754 755 return r; 756 } 757 758 static uint64_t 759 __BS(read_8)(void *v, bus_space_handle_t h, bus_size_t off) 760 { 761 #ifdef MIPS3_64BIT 762 KASSERT((off & 7) == 0); 763 h += CHIP_OFF64(off); 764 const int shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8; 765 h &= ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)); 766 const uint64_t r = CHIP_SWAP64(mips3_ld(h) >> shift); 767 768 return r; 769 #else 770 panic("%s: not implemented!", __func__); 771 #endif 772 } 773 774 775 #define CHIP_read_multi_N(BYTES,TYPE) \ 776 static void \ 777 __C(__BS(read_multi_),BYTES)(void *v, bus_space_handle_t h, \ 778 bus_size_t o, TYPE *a, bus_size_t c) \ 779 { \ 780 \ 781 while (c-- > 0) { \ 782 __BS(barrier)(v, h, o, sizeof *a, \ 783 BUS_SPACE_BARRIER_READ); \ 784 *a++ = __C(__BS(read_),BYTES)(v, h, o); \ 785 } \ 786 } 787 CHIP_read_multi_N(1,uint8_t) 788 CHIP_read_multi_N(2,uint16_t) 789 CHIP_read_multi_N(4,uint32_t) 790 CHIP_read_multi_N(8,uint64_t) 791 792 #define CHIP_read_region_N(BYTES,TYPE) \ 793 static void \ 794 __C(__BS(read_region_),BYTES)(void *v, bus_space_handle_t h, \ 795 bus_size_t o, TYPE *a, bus_size_t c) \ 796 { \ 797 \ 798 while (c-- > 0) { \ 799 *a++ = __C(__BS(read_),BYTES)(v, h, o); \ 800 o += sizeof *a; \ 801 } \ 802 } 803 CHIP_read_region_N(1,uint8_t) 804 CHIP_read_region_N(2,uint16_t) 805 CHIP_read_region_N(4,uint32_t) 806 CHIP_read_region_N(8,uint64_t) 807 808 809 static void 810 __BS(write_1)(void *v, bus_space_handle_t h, bus_size_t off, uint8_t val) 811 { 812 h += CHIP_OFF8(off); 813 814 #if CHIP_ACCESS_SIZE == 1 815 mips_sb(h, val); 816 #else 817 const int shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8; 818 h &= ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)); 819 CHIP_TYPE cval = CHIP_SWAP_ACCESS(((CHIP_TYPE)val) << shift); 820 # if CHIP_ACCESS_SIZE == 8 821 mips3_sd(h, cval); 822 # elif CHIP_ACCESS_SIZE == 4 823 mips_sw(h, cval); 824 # else 825 mips_sh(h, cval); 826 # endif 827 #endif 828 } 829 830 static void 831 __BS(write_2)(void *v, bus_space_handle_t h, bus_size_t off, uint16_t val) 832 { 833 KASSERT((h & 1) == 0); 834 KASSERT((off & 1) == 0); 835 836 h += CHIP_OFF16(off); 837 #if CHIP_ACCESS_SIZE <= 2 838 mips_sh(h, CHIP_SWAP16(val)); 839 #else 840 const int shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8; 841 h &= ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)); 842 CHIP_TYPE cval = ((CHIP_TYPE)CHIP_SWAP16(val)) << shift; 843 # if CHIP_ACCESS_SIZE == 8 844 mips3_sd(h, cval); 845 # else 846 mips_sw(h, cval); 847 # endif 848 #endif 849 } 850 851 static void 852 __BS(write_4)(void *v, bus_space_handle_t h, bus_size_t off, uint32_t val) 853 { 854 KASSERT((h & 3) == 0); 855 KASSERT((off & 3) == 0); 856 857 h += CHIP_OFF32(off); 858 #if CHIP_ACCESS_SIZE <= 4 859 mips_sw(h, CHIP_SWAP32(val)); 860 #else 861 const int shift = (h & (CHIP_ACCESS_SIZE - 1)) * 8; 862 h &= ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)); 863 mips3_sd(h, ((CHIP_TYPE)CHIP_SWAP32(val)) << shift); 864 #endif 865 } 866 867 static void 868 __BS(write_8)(void *v, bus_space_handle_t h, bus_size_t off, uint64_t val) 869 { 870 #ifdef MIPS3_64BIT 871 KASSERT((h & 7) == 0); 872 KASSERT((off & 7) == 0); 873 874 h += CHIP_OFF64(off); 875 mips3_sd(h, CHIP_SWAP64(val)); 876 #else 877 panic("%s: not implemented!", __func__); 878 #endif 879 } 880 881 #define CHIP_write_multi_N(BYTES,TYPE) \ 882 static void \ 883 __C(__BS(write_multi_),BYTES)(void *v, bus_space_handle_t h, \ 884 bus_size_t o, const TYPE *a, bus_size_t c) \ 885 { \ 886 \ 887 while (c-- > 0) { \ 888 __C(__BS(write_),BYTES)(v, h, o, *a++); \ 889 __BS(barrier)(v, h, o, sizeof *a, \ 890 BUS_SPACE_BARRIER_WRITE); \ 891 } \ 892 } 893 CHIP_write_multi_N(1,uint8_t) 894 CHIP_write_multi_N(2,uint16_t) 895 CHIP_write_multi_N(4,uint32_t) 896 CHIP_write_multi_N(8,uint64_t) 897 898 #define CHIP_write_region_N(BYTES,TYPE) \ 899 static void \ 900 __C(__BS(write_region_),BYTES)(void *v, bus_space_handle_t h, \ 901 bus_size_t o, const TYPE *a, bus_size_t c) \ 902 { \ 903 \ 904 while (c-- > 0) { \ 905 __C(__BS(write_),BYTES)(v, h, o, *a++); \ 906 o += sizeof *a; \ 907 } \ 908 } 909 CHIP_write_region_N(1,uint8_t) 910 CHIP_write_region_N(2,uint16_t) 911 CHIP_write_region_N(4,uint32_t) 912 CHIP_write_region_N(8,uint64_t) 913 914 #define CHIP_set_multi_N(BYTES,TYPE) \ 915 static void \ 916 __C(__BS(set_multi_),BYTES)(void *v, bus_space_handle_t h, \ 917 bus_size_t o, TYPE val, bus_size_t c) \ 918 { \ 919 \ 920 while (c-- > 0) { \ 921 __C(__BS(write_),BYTES)(v, h, o, val); \ 922 __BS(barrier)(v, h, o, sizeof val, \ 923 BUS_SPACE_BARRIER_WRITE); \ 924 } \ 925 } 926 CHIP_set_multi_N(1,uint8_t) 927 CHIP_set_multi_N(2,uint16_t) 928 CHIP_set_multi_N(4,uint32_t) 929 CHIP_set_multi_N(8,uint64_t) 930 931 #define CHIP_set_region_N(BYTES,TYPE) \ 932 static void \ 933 __C(__BS(set_region_),BYTES)(void *v, bus_space_handle_t h, \ 934 bus_size_t o, TYPE val, bus_size_t c) \ 935 { \ 936 \ 937 while (c-- > 0) { \ 938 __C(__BS(write_),BYTES)(v, h, o, val); \ 939 o += sizeof val; \ 940 } \ 941 } 942 CHIP_set_region_N(1,uint8_t) 943 CHIP_set_region_N(2,uint16_t) 944 CHIP_set_region_N(4,uint32_t) 945 CHIP_set_region_N(8,uint64_t) 946 947 #define CHIP_copy_region_N(BYTES) \ 948 static void \ 949 __C(__BS(copy_region_),BYTES)(void *v, bus_space_handle_t h1, \ 950 bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c) \ 951 { \ 952 bus_size_t o; \ 953 \ 954 if ((h1 + o1) >= (h2 + o2)) { \ 955 /* src after dest: copy forward */ \ 956 for (o = 0; c != 0; c--, o += BYTES) \ 957 __C(__BS(write_),BYTES)(v, h2, o2 + o, \ 958 __C(__BS(read_),BYTES)(v, h1, o1 + o)); \ 959 } else { \ 960 /* dest after src: copy backwards */ \ 961 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \ 962 __C(__BS(write_),BYTES)(v, h2, o2 + o, \ 963 __C(__BS(read_),BYTES)(v, h1, o1 + o)); \ 964 } \ 965 } 966 CHIP_copy_region_N(1) 967 CHIP_copy_region_N(2) 968 CHIP_copy_region_N(4) 969 CHIP_copy_region_N(8) 970 971 #ifdef CHIP_NEED_STREAM 972 973 static uint8_t 974 __BS(read_stream_1)(void *v, bus_space_handle_t h, bus_size_t off) 975 { 976 h += CHIP_OFF8(off); 977 978 #if CHIP_ACCESS_SIZE == 8 979 return (uint8_t)mips3_ld(h); 980 #elif CHIP_ACCESS_SIZE == 4 981 return (uint8_t)mips_lwu(h); 982 #elif CHIP_ACCESS_SIZE == 2 983 return (uint8_t)mips_lhu(h); 984 #else 985 return mips_lbu(h); 986 #endif 987 } 988 989 static uint16_t 990 __BS(read_stream_2)(void *v, bus_space_handle_t h, bus_size_t off) 991 { 992 h += CHIP_OFF16(off); 993 #if CHIP_ACCESS_SIZE == 8 994 return (uint16_t)mips3_ld(h); 995 #elif CHIP_ACCESS_SIZE == 4 996 return (uint16_t)mips_lwu(h); 997 #else 998 return (uint16_t)mips_lbu(h); 999 #endif 1000 } 1001 1002 static uint32_t 1003 __BS(read_stream_4)(void *v, bus_space_handle_t h, bus_size_t off) 1004 { 1005 h += CHIP_OFF32(off); 1006 #if CHIP_ACCESS_SIZE == 8 1007 return (uint32_t)mips3_ld(h); 1008 #else 1009 return (uint32_t)mips_lwu(h); 1010 #endif 1011 } 1012 1013 static uint64_t 1014 __BS(read_stream_8)(void *v, bus_space_handle_t h, bus_size_t off) 1015 { 1016 #ifdef MIPS3_64BIT 1017 h += CHIP_OFF64(off); 1018 return mips3_ld(h); 1019 #else 1020 panic("%s: not implemented!", __func__); 1021 #endif 1022 } 1023 1024 #define CHIP_read_multi_stream_N(BYTES,TYPE) \ 1025 static void \ 1026 __C(__BS(read_multi_stream_),BYTES)(void *v, bus_space_handle_t h, \ 1027 bus_size_t o, TYPE *a, bus_size_t c) \ 1028 { \ 1029 \ 1030 while (c-- > 0) { \ 1031 __BS(barrier)(v, h, o, sizeof *a, \ 1032 BUS_SPACE_BARRIER_READ); \ 1033 *a++ = __C(__BS(read_stream_),BYTES)(v, h, o); \ 1034 } \ 1035 } 1036 CHIP_read_multi_stream_N(1,uint8_t) 1037 CHIP_read_multi_stream_N(2,uint16_t) 1038 CHIP_read_multi_stream_N(4,uint32_t) 1039 CHIP_read_multi_stream_N(8,uint64_t) 1040 1041 #define CHIP_read_region_stream_N(BYTES,TYPE) \ 1042 static void \ 1043 __C(__BS(read_region_stream_),BYTES)(void *v, bus_space_handle_t h, \ 1044 bus_size_t o, TYPE *a, bus_size_t c) \ 1045 { \ 1046 \ 1047 while (c-- > 0) { \ 1048 *a++ = __C(__BS(read_stream_),BYTES)(v, h, o); \ 1049 o += sizeof *a; \ 1050 } \ 1051 } 1052 CHIP_read_region_stream_N(1,uint8_t) 1053 CHIP_read_region_stream_N(2,uint16_t) 1054 CHIP_read_region_stream_N(4,uint32_t) 1055 CHIP_read_region_stream_N(8,uint64_t) 1056 1057 static void 1058 __BS(write_stream_1)(void *v, bus_space_handle_t h, bus_size_t off, 1059 uint8_t val) 1060 { 1061 #if CHIP_ACCESS_SIZE == 8 1062 mips3_sd(h, val); 1063 #elif CHIP_ACCESS_SIZE == 4 1064 mips_sw(h, val); 1065 #elif CHIP_ACCESS_SIZE == 2 1066 mips_sh(h, val); 1067 #else 1068 mips_sb(h, val); 1069 #endif 1070 } 1071 1072 static void 1073 __BS(write_stream_2)(void *v, bus_space_handle_t h, bus_size_t off, 1074 uint16_t val) 1075 { 1076 #if CHIP_ACCESS_SIZE == 8 1077 mips3_sd(h, val); 1078 #elif CHIP_ACCESS_SIZE == 4 1079 mips_sw(h, val); 1080 #else 1081 mips_sh(h, val); 1082 #endif 1083 } 1084 1085 static void 1086 __BS(write_stream_4)(void *v, bus_space_handle_t h, bus_size_t off, 1087 uint32_t val) 1088 { 1089 h += CHIP_OFF32(off); 1090 #if CHIP_ACCESS_SIZE == 8 1091 mips3_sd(h, val); 1092 #else 1093 mips_sw(h, val); 1094 #endif 1095 } 1096 1097 static void 1098 __BS(write_stream_8)(void *v, bus_space_handle_t h, bus_size_t off, 1099 uint64_t val) 1100 { 1101 #ifdef MIPS3_64BIT 1102 h += CHIP_OFF64(off); 1103 mips3_sd(h, val); 1104 #else 1105 panic("%s: not implemented!", __func__); 1106 #endif 1107 } 1108 1109 #define CHIP_write_multi_stream_N(BYTES,TYPE) \ 1110 static void \ 1111 __C(__BS(write_multi_stream_),BYTES)(void *v, bus_space_handle_t h, \ 1112 bus_size_t o, const TYPE *a, bus_size_t c) \ 1113 { \ 1114 \ 1115 while (c-- > 0) { \ 1116 __C(__BS(write_stream_),BYTES)(v, h, o, *a++); \ 1117 __BS(barrier)(v, h, o, sizeof *a, \ 1118 BUS_SPACE_BARRIER_WRITE); \ 1119 } \ 1120 } 1121 CHIP_write_multi_stream_N(1,uint8_t) 1122 CHIP_write_multi_stream_N(2,uint16_t) 1123 CHIP_write_multi_stream_N(4,uint32_t) 1124 CHIP_write_multi_stream_N(8,uint64_t) 1125 1126 #define CHIP_write_region_stream_N(BYTES,TYPE) \ 1127 static void \ 1128 __C(__BS(write_region_stream_),BYTES)(void *v, bus_space_handle_t h, \ 1129 bus_size_t o, const TYPE *a, bus_size_t c) \ 1130 { \ 1131 \ 1132 while (c-- > 0) { \ 1133 __C(__BS(write_stream_),BYTES)(v, h, o, *a++); \ 1134 o += sizeof *a; \ 1135 } \ 1136 } 1137 CHIP_write_region_stream_N(1,uint8_t) 1138 CHIP_write_region_stream_N(2,uint16_t) 1139 CHIP_write_region_stream_N(4,uint32_t) 1140 CHIP_write_region_stream_N(8,uint64_t) 1141 1142 #endif /* CHIP_NEED_STREAM */ 1143 1144 void 1145 __BS(init)(bus_space_tag_t t, void *v) 1146 { 1147 #ifdef CHIP_EXTENT 1148 struct extent *ex; 1149 #endif 1150 1151 /* 1152 * Initialize the bus space tag. 1153 */ 1154 1155 /* cookie */ 1156 t->bs_cookie = v; 1157 1158 /* mapping/unmapping */ 1159 t->bs_map = __BS(map); 1160 t->bs_unmap = __BS(unmap); 1161 t->bs_subregion = __BS(subregion); 1162 1163 t->bs_translate = __BS(translate); 1164 t->bs_get_window = __BS(get_window); 1165 1166 /* allocation/deallocation */ 1167 t->bs_alloc = __BS(alloc); 1168 t->bs_free = __BS(free); 1169 1170 /* get kernel virtual address */ 1171 t->bs_vaddr = __BS(vaddr); 1172 1173 /* mmap for user */ 1174 t->bs_mmap = __BS(mmap); 1175 1176 /* barrier */ 1177 t->bs_barrier = __BS(barrier); 1178 1179 /* read (single) */ 1180 t->bs_r_1 = __BS(read_1); 1181 t->bs_r_2 = __BS(read_2); 1182 t->bs_r_4 = __BS(read_4); 1183 t->bs_r_8 = __BS(read_8); 1184 1185 /* read multiple */ 1186 t->bs_rm_1 = __BS(read_multi_1); 1187 t->bs_rm_2 = __BS(read_multi_2); 1188 t->bs_rm_4 = __BS(read_multi_4); 1189 t->bs_rm_8 = __BS(read_multi_8); 1190 1191 /* read region */ 1192 t->bs_rr_1 = __BS(read_region_1); 1193 t->bs_rr_2 = __BS(read_region_2); 1194 t->bs_rr_4 = __BS(read_region_4); 1195 t->bs_rr_8 = __BS(read_region_8); 1196 1197 /* write (single) */ 1198 t->bs_w_1 = __BS(write_1); 1199 t->bs_w_2 = __BS(write_2); 1200 t->bs_w_4 = __BS(write_4); 1201 t->bs_w_8 = __BS(write_8); 1202 1203 /* write multiple */ 1204 t->bs_wm_1 = __BS(write_multi_1); 1205 t->bs_wm_2 = __BS(write_multi_2); 1206 t->bs_wm_4 = __BS(write_multi_4); 1207 t->bs_wm_8 = __BS(write_multi_8); 1208 1209 /* write region */ 1210 t->bs_wr_1 = __BS(write_region_1); 1211 t->bs_wr_2 = __BS(write_region_2); 1212 t->bs_wr_4 = __BS(write_region_4); 1213 t->bs_wr_8 = __BS(write_region_8); 1214 1215 /* set multiple */ 1216 t->bs_sm_1 = __BS(set_multi_1); 1217 t->bs_sm_2 = __BS(set_multi_2); 1218 t->bs_sm_4 = __BS(set_multi_4); 1219 t->bs_sm_8 = __BS(set_multi_8); 1220 1221 /* set region */ 1222 t->bs_sr_1 = __BS(set_region_1); 1223 t->bs_sr_2 = __BS(set_region_2); 1224 t->bs_sr_4 = __BS(set_region_4); 1225 t->bs_sr_8 = __BS(set_region_8); 1226 1227 /* copy */ 1228 t->bs_c_1 = __BS(copy_region_1); 1229 t->bs_c_2 = __BS(copy_region_2); 1230 t->bs_c_4 = __BS(copy_region_4); 1231 t->bs_c_8 = __BS(copy_region_8); 1232 1233 #ifdef CHIP_NEED_STREAM 1234 /* read (single), stream */ 1235 t->bs_rs_1 = __BS(read_stream_1); 1236 t->bs_rs_2 = __BS(read_stream_2); 1237 t->bs_rs_4 = __BS(read_stream_4); 1238 t->bs_rs_8 = __BS(read_stream_8); 1239 1240 /* read multiple, stream */ 1241 t->bs_rms_1 = __BS(read_multi_stream_1); 1242 t->bs_rms_2 = __BS(read_multi_stream_2); 1243 t->bs_rms_4 = __BS(read_multi_stream_4); 1244 t->bs_rms_8 = __BS(read_multi_stream_8); 1245 1246 /* read region, stream */ 1247 t->bs_rrs_1 = __BS(read_region_stream_1); 1248 t->bs_rrs_2 = __BS(read_region_stream_2); 1249 t->bs_rrs_4 = __BS(read_region_stream_4); 1250 t->bs_rrs_8 = __BS(read_region_stream_8); 1251 1252 /* write (single), stream */ 1253 t->bs_ws_1 = __BS(write_stream_1); 1254 t->bs_ws_2 = __BS(write_stream_2); 1255 t->bs_ws_4 = __BS(write_stream_4); 1256 t->bs_ws_8 = __BS(write_stream_8); 1257 1258 /* write multiple, stream */ 1259 t->bs_wms_1 = __BS(write_multi_stream_1); 1260 t->bs_wms_2 = __BS(write_multi_stream_2); 1261 t->bs_wms_4 = __BS(write_multi_stream_4); 1262 t->bs_wms_8 = __BS(write_multi_stream_8); 1263 1264 /* write region, stream */ 1265 t->bs_wrs_1 = __BS(write_region_stream_1); 1266 t->bs_wrs_2 = __BS(write_region_stream_2); 1267 t->bs_wrs_4 = __BS(write_region_stream_4); 1268 t->bs_wrs_8 = __BS(write_region_stream_8); 1269 1270 #else /* CHIP_NEED_STREAM */ 1271 1272 /* read (single), stream */ 1273 t->bs_rs_1 = __BS(read_1); 1274 t->bs_rs_2 = __BS(read_2); 1275 t->bs_rs_4 = __BS(read_4); 1276 t->bs_rs_8 = __BS(read_8); 1277 1278 /* read multiple, stream */ 1279 t->bs_rms_1 = __BS(read_multi_1); 1280 t->bs_rms_2 = __BS(read_multi_2); 1281 t->bs_rms_4 = __BS(read_multi_4); 1282 t->bs_rms_8 = __BS(read_multi_8); 1283 1284 /* read region, stream */ 1285 t->bs_rrs_1 = __BS(read_region_1); 1286 t->bs_rrs_2 = __BS(read_region_2); 1287 t->bs_rrs_4 = __BS(read_region_4); 1288 t->bs_rrs_8 = __BS(read_region_8); 1289 1290 /* write (single), stream */ 1291 t->bs_ws_1 = __BS(write_1); 1292 t->bs_ws_2 = __BS(write_2); 1293 t->bs_ws_4 = __BS(write_4); 1294 t->bs_ws_8 = __BS(write_8); 1295 1296 /* write multiple, stream */ 1297 t->bs_wms_1 = __BS(write_multi_1); 1298 t->bs_wms_2 = __BS(write_multi_2); 1299 t->bs_wms_4 = __BS(write_multi_4); 1300 t->bs_wms_8 = __BS(write_multi_8); 1301 1302 /* write region, stream */ 1303 t->bs_wrs_1 = __BS(write_region_1); 1304 t->bs_wrs_2 = __BS(write_region_2); 1305 t->bs_wrs_4 = __BS(write_region_4); 1306 t->bs_wrs_8 = __BS(write_region_8); 1307 #endif /* CHIP_NEED_STREAM */ 1308 1309 #ifdef CHIP_EXTENT 1310 /* XXX WE WANT EXTENT_NOCOALESCE, BUT WE CAN'T USE IT. XXX */ 1311 ex = extent_create(__S(__BS(bus)), 0x0UL, ~0UL, 1312 (void *)CHIP_EX_STORE(v), CHIP_EX_STORE_SIZE(v), EX_NOWAIT); 1313 extent_alloc_region(ex, 0, ~0UL, EX_NOWAIT); 1314 1315 #ifdef CHIP_W1_BUS_START 1316 /* 1317 * The window may be disabled. We notice this by seeing 1318 * -1 as the bus base address. 1319 */ 1320 if (CHIP_W1_BUS_START(v) == (bus_addr_t) -1) { 1321 #ifdef EXTENT_DEBUG 1322 printf("%s: this space is disabled\n", __S(__BS(init))); 1323 #endif 1324 return; 1325 } 1326 1327 #ifdef EXTENT_DEBUG 1328 printf("%s: freeing from %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n", 1329 __S(__BS(init)), (bus_addr_t)CHIP_W1_BUS_START(v), 1330 (bus_addr_t)CHIP_W1_BUS_END(v)); 1331 #endif 1332 extent_free(ex, CHIP_W1_BUS_START(v), 1333 CHIP_W1_BUS_END(v) - CHIP_W1_BUS_START(v) + 1, EX_NOWAIT); 1334 #endif 1335 #ifdef CHIP_W2_BUS_START 1336 if (CHIP_W2_BUS_START(v) != CHIP_W1_BUS_START(v)) { 1337 #ifdef EXTENT_DEBUG 1338 printf("xxx: freeing from 0x%lx to 0x%lx\n", 1339 (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); 1340 #endif 1341 extent_free(ex, CHIP_W2_BUS_START(v), 1342 CHIP_W2_BUS_END(v) - CHIP_W2_BUS_START(v) + 1, EX_NOWAIT); 1343 } else { 1344 #ifdef EXTENT_DEBUG 1345 printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n", 1346 (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); 1347 #endif 1348 } 1349 #endif 1350 #ifdef CHIP_W3_BUS_START 1351 if (CHIP_W3_BUS_START(v) != CHIP_W1_BUS_START(v) && 1352 CHIP_W3_BUS_START(v) != CHIP_W2_BUS_START(v)) { 1353 #ifdef EXTENT_DEBUG 1354 printf("xxx: freeing from 0x%lx to 0x%lx\n", 1355 (u_long)CHIP_W3_BUS_START(v), (u_long)CHIP_W3_BUS_END(v)); 1356 #endif 1357 extent_free(ex, CHIP_W3_BUS_START(v), 1358 CHIP_W3_BUS_END(v) - CHIP_W3_BUS_START(v) + 1, EX_NOWAIT); 1359 } else { 1360 #ifdef EXTENT_DEBUG 1361 printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n", 1362 (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); 1363 #endif 1364 } 1365 #endif 1366 1367 #ifdef EXTENT_DEBUG 1368 extent_print(ex); 1369 #endif 1370 CHIP_EXTENT(v) = ex; 1371 #endif /* CHIP_EXTENT */ 1372 } 1373 1374