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