1 /* $NetBSD: bus_space_alignstride_chipdep.c,v 1.2 2002/03/23 14:20:41 simonb 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 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * Copyright (c) 1995, 1996 Carnegie-Mellon University. 42 * All rights reserved. 43 * 44 * Author: Chris G. Demetriou 45 * 46 * Permission to use, copy, modify and distribute this software and 47 * its documentation is hereby granted, provided that both the copyright 48 * notice and this permission notice appear in all copies of the 49 * software, derivative works or modified versions, and any portions 50 * thereof, and that both notices appear in supporting documentation. 51 * 52 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 53 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 54 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 55 * 56 * Carnegie Mellon requests users of this software to return to 57 * 58 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 59 * School of Computer Science 60 * Carnegie Mellon University 61 * Pittsburgh PA 15213-3890 62 * 63 * any improvements or extensions that they make and grant Carnegie the 64 * rights to redistribute these changes. 65 */ 66 67 /* 68 * Common Chipset "bus I/O" functions. 69 * 70 * uses: 71 * CHIP name of the 'chip' it's being compiled for. 72 * CHIP_BASE memory or I/O space base to use. 73 * CHIP_EX_STORE 74 * If defined, device-provided static storage area 75 * for the memory or I/O space extent. If this is 76 * defined, CHIP_EX_STORE_SIZE must also be defined. 77 * If this is not defined, a static area will be 78 * declared. 79 * CHIP_EX_STORE_SIZE 80 * Size of the device-provided static storage area 81 * for the memory or I/O memory space extent. 82 */ 83 84 #include <sys/extent.h> 85 86 #define __C(A,B) __CONCAT(A,B) 87 #define __S(S) __STRING(S) 88 89 #ifdef CHIP_IO 90 #define __BS(A) __C(__C(CHIP,_bus_io_),A) 91 #endif 92 #ifdef CHIP_MEM 93 #define __BS(A) __C(__C(CHIP,_bus_mem_),A) 94 #endif 95 96 /* mapping/unmapping */ 97 int __BS(map)(void *, bus_addr_t, bus_size_t, int, 98 bus_space_handle_t *, int); 99 void __BS(unmap)(void *, bus_space_handle_t, bus_size_t, int); 100 int __BS(subregion)(void *, bus_space_handle_t, bus_size_t, 101 bus_size_t, bus_space_handle_t *); 102 103 int __BS(translate)(void *, bus_addr_t, bus_size_t, int, 104 struct mips_bus_space_translation *); 105 int __BS(get_window)(void *, int, 106 struct mips_bus_space_translation *); 107 108 /* allocation/deallocation */ 109 int __BS(alloc)(void *, bus_addr_t, bus_addr_t, bus_size_t, 110 bus_size_t, bus_addr_t, int, bus_addr_t *, 111 bus_space_handle_t *); 112 void __BS(free)(void *, bus_space_handle_t, bus_size_t); 113 114 /* get kernel virtual address */ 115 void * __BS(vaddr)(void *, bus_space_handle_t); 116 117 /* mmap for user */ 118 paddr_t __BS(mmap)(void *, bus_addr_t, off_t, int, int); 119 120 /* barrier */ 121 inline void __BS(barrier)(void *, bus_space_handle_t, bus_size_t, 122 bus_size_t, int); 123 124 /* read (single) */ 125 inline uint8_t __BS(read_1)(void *, bus_space_handle_t, bus_size_t); 126 inline uint16_t __BS(read_2)(void *, bus_space_handle_t, bus_size_t); 127 inline uint32_t __BS(read_4)(void *, bus_space_handle_t, bus_size_t); 128 inline uint64_t __BS(read_8)(void *, bus_space_handle_t, bus_size_t); 129 130 /* read multiple */ 131 void __BS(read_multi_1)(void *, bus_space_handle_t, bus_size_t, 132 uint8_t *, bus_size_t); 133 void __BS(read_multi_2)(void *, bus_space_handle_t, bus_size_t, 134 uint16_t *, bus_size_t); 135 void __BS(read_multi_4)(void *, bus_space_handle_t, bus_size_t, 136 uint32_t *, bus_size_t); 137 void __BS(read_multi_8)(void *, bus_space_handle_t, bus_size_t, 138 uint64_t *, bus_size_t); 139 140 /* read region */ 141 void __BS(read_region_1)(void *, bus_space_handle_t, bus_size_t, 142 uint8_t *, bus_size_t); 143 void __BS(read_region_2)(void *, bus_space_handle_t, bus_size_t, 144 uint16_t *, bus_size_t); 145 void __BS(read_region_4)(void *, bus_space_handle_t, bus_size_t, 146 uint32_t *, bus_size_t); 147 void __BS(read_region_8)(void *, bus_space_handle_t, bus_size_t, 148 uint64_t *, bus_size_t); 149 150 /* write (single) */ 151 inline void __BS(write_1)(void *, bus_space_handle_t, bus_size_t, uint8_t); 152 inline void __BS(write_2)(void *, bus_space_handle_t, bus_size_t, uint16_t); 153 inline void __BS(write_4)(void *, bus_space_handle_t, bus_size_t, uint32_t); 154 inline void __BS(write_8)(void *, bus_space_handle_t, bus_size_t, uint64_t); 155 156 /* write multiple */ 157 void __BS(write_multi_1)(void *, bus_space_handle_t, bus_size_t, 158 const uint8_t *, bus_size_t); 159 void __BS(write_multi_2)(void *, bus_space_handle_t, bus_size_t, 160 const uint16_t *, bus_size_t); 161 void __BS(write_multi_4)(void *, bus_space_handle_t, bus_size_t, 162 const uint32_t *, bus_size_t); 163 void __BS(write_multi_8)(void *, bus_space_handle_t, bus_size_t, 164 const uint64_t *, bus_size_t); 165 166 /* write region */ 167 void __BS(write_region_1)(void *, bus_space_handle_t, bus_size_t, 168 const uint8_t *, bus_size_t); 169 void __BS(write_region_2)(void *, bus_space_handle_t, bus_size_t, 170 const uint16_t *, bus_size_t); 171 void __BS(write_region_4)(void *, bus_space_handle_t, bus_size_t, 172 const uint32_t *, bus_size_t); 173 void __BS(write_region_8)(void *, bus_space_handle_t, bus_size_t, 174 const uint64_t *, bus_size_t); 175 176 /* set multiple */ 177 void __BS(set_multi_1)(void *, bus_space_handle_t, bus_size_t, 178 uint8_t, bus_size_t); 179 void __BS(set_multi_2)(void *, bus_space_handle_t, bus_size_t, 180 uint16_t, bus_size_t); 181 void __BS(set_multi_4)(void *, bus_space_handle_t, bus_size_t, 182 uint32_t, bus_size_t); 183 void __BS(set_multi_8)(void *, bus_space_handle_t, bus_size_t, 184 uint64_t, bus_size_t); 185 186 /* set region */ 187 void __BS(set_region_1)(void *, bus_space_handle_t, bus_size_t, 188 uint8_t, bus_size_t); 189 void __BS(set_region_2)(void *, bus_space_handle_t, bus_size_t, 190 uint16_t, bus_size_t); 191 void __BS(set_region_4)(void *, bus_space_handle_t, bus_size_t, 192 uint32_t, bus_size_t); 193 void __BS(set_region_8)(void *, bus_space_handle_t, bus_size_t, 194 uint64_t, bus_size_t); 195 196 /* copy */ 197 void __BS(copy_region_1)(void *, bus_space_handle_t, bus_size_t, 198 bus_space_handle_t, bus_size_t, bus_size_t); 199 void __BS(copy_region_2)(void *, bus_space_handle_t, bus_size_t, 200 bus_space_handle_t, bus_size_t, bus_size_t); 201 void __BS(copy_region_4)(void *, bus_space_handle_t, bus_size_t, 202 bus_space_handle_t, bus_size_t, bus_size_t); 203 void __BS(copy_region_8)(void *, bus_space_handle_t, bus_size_t, 204 bus_space_handle_t, bus_size_t, bus_size_t); 205 206 #ifdef CHIP_EXTENT 207 #ifndef CHIP_EX_STORE 208 static long 209 __BS(ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 210 #define CHIP_EX_STORE(v) (__BS(ex_storage)) 211 #define CHIP_EX_STORE_SIZE(v) (sizeof __BS(ex_storage)) 212 #endif 213 #endif /* CHIP_EXTENT */ 214 215 #ifndef CHIP_ALIGN_STRIDE 216 #define CHIP_ALIGN_STRIDE 0 217 #endif 218 219 void 220 __BS(init)(bus_space_tag_t t, void *v) 221 { 222 #ifdef CHIP_EXTENT 223 struct extent *ex; 224 #endif 225 226 /* 227 * Initialize the bus space tag. 228 */ 229 230 /* cookie */ 231 t->bs_cookie = v; 232 233 /* mapping/unmapping */ 234 t->bs_map = __BS(map); 235 t->bs_unmap = __BS(unmap); 236 t->bs_subregion = __BS(subregion); 237 238 t->bs_translate = __BS(translate); 239 t->bs_get_window = __BS(get_window); 240 241 /* allocation/deallocation */ 242 t->bs_alloc = __BS(alloc); 243 t->bs_free = __BS(free); 244 245 /* get kernel virtual address */ 246 t->bs_vaddr = __BS(vaddr); 247 248 /* mmap for user */ 249 t->bs_mmap = __BS(mmap); 250 251 /* barrier */ 252 t->bs_barrier = __BS(barrier); 253 254 /* read (single) */ 255 t->bs_r_1 = __BS(read_1); 256 t->bs_r_2 = __BS(read_2); 257 t->bs_r_4 = __BS(read_4); 258 t->bs_r_8 = __BS(read_8); 259 260 /* read multiple */ 261 t->bs_rm_1 = __BS(read_multi_1); 262 t->bs_rm_2 = __BS(read_multi_2); 263 t->bs_rm_4 = __BS(read_multi_4); 264 t->bs_rm_8 = __BS(read_multi_8); 265 266 /* read region */ 267 t->bs_rr_1 = __BS(read_region_1); 268 t->bs_rr_2 = __BS(read_region_2); 269 t->bs_rr_4 = __BS(read_region_4); 270 t->bs_rr_8 = __BS(read_region_8); 271 272 /* write (single) */ 273 t->bs_w_1 = __BS(write_1); 274 t->bs_w_2 = __BS(write_2); 275 t->bs_w_4 = __BS(write_4); 276 t->bs_w_8 = __BS(write_8); 277 278 /* write multiple */ 279 t->bs_wm_1 = __BS(write_multi_1); 280 t->bs_wm_2 = __BS(write_multi_2); 281 t->bs_wm_4 = __BS(write_multi_4); 282 t->bs_wm_8 = __BS(write_multi_8); 283 284 /* write region */ 285 t->bs_wr_1 = __BS(write_region_1); 286 t->bs_wr_2 = __BS(write_region_2); 287 t->bs_wr_4 = __BS(write_region_4); 288 t->bs_wr_8 = __BS(write_region_8); 289 290 /* set multiple */ 291 t->bs_sm_1 = __BS(set_multi_1); 292 t->bs_sm_2 = __BS(set_multi_2); 293 t->bs_sm_4 = __BS(set_multi_4); 294 t->bs_sm_8 = __BS(set_multi_8); 295 296 /* set region */ 297 t->bs_sr_1 = __BS(set_region_1); 298 t->bs_sr_2 = __BS(set_region_2); 299 t->bs_sr_4 = __BS(set_region_4); 300 t->bs_sr_8 = __BS(set_region_8); 301 302 /* copy */ 303 t->bs_c_1 = __BS(copy_region_1); 304 t->bs_c_2 = __BS(copy_region_2); 305 t->bs_c_4 = __BS(copy_region_4); 306 t->bs_c_8 = __BS(copy_region_8); 307 308 #ifdef CHIP_EXTENT 309 /* XXX WE WANT EXTENT_NOCOALESCE, BUT WE CAN'T USE IT. XXX */ 310 ex = extent_create(__S(__BS(bus)), 0x0UL, 0xffffffffUL, M_DEVBUF, 311 (caddr_t)CHIP_EX_STORE(v), CHIP_EX_STORE_SIZE(v), EX_NOWAIT); 312 extent_alloc_region(ex, 0, 0xffffffffUL, EX_NOWAIT); 313 314 #ifdef CHIP_W1_BUS_START 315 /* 316 * The window may be disabled. We notice this by seeing 317 * -1 as the bus base address. 318 */ 319 if (CHIP_W1_BUS_START(v) == (bus_addr_t) -1) { 320 #ifdef EXTENT_DEBUG 321 printf("xxx: this space is disabled\n"); 322 #endif 323 return; 324 } 325 326 #ifdef EXTENT_DEBUG 327 printf("xxx: freeing from 0x%lx to 0x%lx\n", CHIP_W1_BUS_START(v), 328 CHIP_W1_BUS_END(v)); 329 #endif 330 extent_free(ex, CHIP_W1_BUS_START(v), 331 CHIP_W1_BUS_END(v) - CHIP_W1_BUS_START(v) + 1, EX_NOWAIT); 332 #endif 333 #ifdef CHIP_W2_BUS_START 334 if (CHIP_W2_BUS_START(v) != CHIP_W1_BUS_START(v)) { 335 #ifdef EXTENT_DEBUG 336 printf("xxx: freeing from 0x%lx to 0x%lx\n", 337 CHIP_W2_BUS_START(v), CHIP_W2_BUS_END(v)); 338 #endif 339 extent_free(ex, CHIP_W2_BUS_START(v), 340 CHIP_W2_BUS_END(v) - CHIP_W2_BUS_START(v) + 1, EX_NOWAIT); 341 } else { 342 #ifdef EXTENT_DEBUG 343 printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n", 344 CHIP_W2_BUS_START(v), CHIP_W2_BUS_END(v)); 345 #endif 346 } 347 #endif 348 #ifdef CHIP_W3_BUS_START 349 if (CHIP_W3_BUS_START(v) != CHIP_W1_BUS_START(v) && 350 CHIP_W3_BUS_START(v) != CHIP_W2_BUS_START(v)) { 351 #ifdef EXTENT_DEBUG 352 printf("xxx: freeing from 0x%lx to 0x%lx\n", 353 CHIP_W3_BUS_START(v), CHIP_W3_BUS_END(v)); 354 #endif 355 extent_free(ex, CHIP_W3_BUS_START(v), 356 CHIP_W3_BUS_END(v) - CHIP_W3_BUS_START(v) + 1, EX_NOWAIT); 357 } else { 358 #ifdef EXTENT_DEBUG 359 printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n", 360 CHIP_W2_BUS_START(v), CHIP_W2_BUS_END(v)); 361 #endif 362 } 363 #endif 364 365 #ifdef EXTENT_DEBUG 366 extent_print(ex); 367 #endif 368 CHIP_EXTENT(v) = ex; 369 #endif /* CHIP_EXTENT */ 370 } 371 372 int 373 __BS(translate)(void *v, bus_addr_t addr, bus_size_t len, int flags, 374 struct mips_bus_space_translation *mbst) 375 { 376 bus_addr_t end = addr + (len - 1); 377 #if CHIP_ALIGN_STRIDE != 0 378 int linear = flags & BUS_SPACE_MAP_LINEAR; 379 380 /* 381 * Can't map xxx space linearly. 382 */ 383 if (linear) 384 return (EOPNOTSUPP); 385 #endif 386 387 #ifdef CHIP_W1_BUS_START 388 if (addr >= CHIP_W1_BUS_START(v) && end <= CHIP_W1_BUS_END(v)) 389 return (__BS(get_window)(v, 0, mbst)); 390 #endif 391 392 #ifdef CHIP_W2_BUS_START 393 if (addr >= CHIP_W2_BUS_START(v) && end <= CHIP_W2_BUS_END(v)) 394 return (__BS(get_window)(v, 1, mbst)); 395 #endif 396 397 #ifdef CHIP_W3_BUS_START 398 if (addr >= CHIP_W3_BUS_START(v) && end <= CHIP_W3_BUS_END(v)) 399 return (__BS(get_window)(v, 2, mbst)); 400 #endif 401 402 #ifdef EXTENT_DEBUG 403 printf("\n"); 404 #ifdef CHIP_W1_BUS_START 405 printf("%s: window[1]=0x%lx-0x%lx\n", 406 __S(__BS(map)), CHIP_W1_BUS_START(v), 407 CHIP_W1_BUS_END(v)); 408 #endif 409 #ifdef CHIP_W2_BUS_START 410 printf("%s: window[2]=0x%lx-0x%lx\n", 411 __S(__BS(map)), CHIP_W2_BUS_START(v), 412 CHIP_W2_BUS_END(v)); 413 #endif 414 #ifdef CHIP_W3_BUS_START 415 printf("%s: window[3]=0x%lx-0x%lx\n", 416 __S(__BS(map)), CHIP_W3_BUS_START(v), 417 CHIP_W3_BUS_END(v)); 418 #endif 419 #endif /* EXTENT_DEBUG */ 420 /* No translation. */ 421 return (EINVAL); 422 } 423 424 int 425 __BS(get_window)(void *v, int window, struct mips_bus_space_translation *mbst) 426 { 427 428 switch (window) { 429 #ifdef CHIP_W1_BUS_START 430 case 0: 431 mbst->mbst_bus_start = CHIP_W1_BUS_START(v); 432 mbst->mbst_bus_end = CHIP_W1_BUS_END(v); 433 mbst->mbst_sys_start = CHIP_W1_SYS_START(v); 434 mbst->mbst_sys_end = CHIP_W1_SYS_END(v); 435 mbst->mbst_align_stride = CHIP_ALIGN_STRIDE; 436 mbst->mbst_flags = 0; 437 break; 438 #endif 439 440 #ifdef CHIP_W2_BUS_START 441 case 1: 442 mbst->mbst_bus_start = CHIP_W2_BUS_START(v); 443 mbst->mbst_bus_end = CHIP_W2_BUS_END(v); 444 mbst->mbst_sys_start = CHIP_W2_SYS_START(v); 445 mbst->mbst_sys_end = CHIP_W2_SYS_END(v); 446 mbst->mbst_align_stride = CHIP_ALIGN_STRIDE; 447 mbst->mbst_flags = 0; 448 break; 449 #endif 450 451 #ifdef CHIP_W3_BUS_START 452 case 2: 453 mbst->mbst_bus_start = CHIP_W3_BUS_START(v); 454 mbst->mbst_bus_end = CHIP_W3_BUS_END(v); 455 mbst->mbst_sys_start = CHIP_W3_SYS_START(v); 456 mbst->mbst_sys_end = CHIP_W3_SYS_END(v); 457 mbst->mbst_align_stride = CHIP_ALIGN_STRIDE; 458 mbst->mbst_flags = 0; 459 break; 460 #endif 461 462 default: 463 panic(__S(__BS(get_window)) ": invalid window %d", 464 window); 465 } 466 467 return (0); 468 } 469 470 int 471 __BS(map)(void *v, bus_addr_t addr, bus_size_t size, int flags, 472 bus_space_handle_t *hp, int acct) 473 { 474 struct mips_bus_space_translation mbst; 475 int error; 476 477 /* 478 * Get the translation for this address. 479 */ 480 error = __BS(translate)(v, addr, size, flags, &mbst); 481 if (error) 482 return (error); 483 484 #ifdef CHIP_EXTENT 485 if (acct == 0) 486 goto mapit; 487 488 #ifdef EXTENT_DEBUG 489 printf("xxx: allocating 0x%lx to 0x%lx\n", addr, addr + size - 1); 490 #endif 491 error = extent_alloc_region(CHIP_EXTENT(v), addr, size, 492 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 493 if (error) { 494 #ifdef EXTENT_DEBUG 495 printf("xxx: allocation failed (%d)\n", error); 496 extent_print(CHIP_EXTENT(v)); 497 #endif 498 return (error); 499 } 500 501 mapit: 502 #endif /* CHIP_EXTENT */ 503 if (flags & BUS_SPACE_MAP_CACHEABLE) 504 *hp = MIPS_PHYS_TO_KSEG0(mbst.mbst_sys_start + 505 (addr - mbst.mbst_bus_start)); 506 else 507 *hp = MIPS_PHYS_TO_KSEG1(mbst.mbst_sys_start + 508 (addr - mbst.mbst_bus_start)); 509 510 return (0); 511 } 512 513 void 514 __BS(unmap)(void *v, bus_space_handle_t h, bus_size_t size, int acct) 515 { 516 #ifdef CHIP_EXTENT 517 bus_addr_t addr; 518 int error; 519 520 if (acct == 0) 521 return; 522 523 #ifdef EXTENT_DEBUG 524 printf("xxx: freeing handle 0x%lx for 0x%lx\n", h, size); 525 #endif 526 527 if (h >= MIPS_KSEG0_START && h < MIPS_KSEG1_START) 528 h = MIPS_KSEG0_TO_PHYS(h); 529 else 530 h = MIPS_KSEG1_TO_PHYS(h); 531 532 #ifdef CHIP_W1_BUS_START 533 if (h >= CHIP_W1_SYS_START(v) && h <= CHIP_W1_SYS_END(v)) { 534 addr = CHIP_W1_BUS_START(v) + (h - CHIP_W1_SYS_START(v)); 535 } else 536 #endif 537 #ifdef CHIP_W2_BUS_START 538 if (h >= CHIP_W2_SYS_START(v) && h <= CHIP_W2_SYS_END(v)) { 539 addr = CHIP_W2_BUS_START(v) + (h - CHIP_W2_SYS_START(v)); 540 } else 541 #endif 542 #ifdef CHIP_W3_BUS_START 543 if (h >= CHIP_W3_SYS_START(v) && h <= CHIP_W3_SYS_END(v)) { 544 addr = CHIP_W3_BUS_START(v) + (h - CHIP_W3_SYS_START(v)); 545 } else 546 #endif 547 { 548 printf("\n"); 549 #ifdef CHIP_W1_BUS_START 550 printf("%s: sys window[1]=0x%lx-0x%lx\n", 551 __S(__BS(map)), CHIP_W1_SYS_START(v), 552 CHIP_W1_SYS_END(v)); 553 #endif 554 #ifdef CHIP_W2_BUS_START 555 printf("%s: sys window[2]=0x%lx-0x%lx\n", 556 __S(__BS(map)), CHIP_W2_SYS_START(v), 557 CHIP_W2_SYS_END(v)); 558 #endif 559 #ifdef CHIP_W3_BUS_START 560 printf("%s: sys window[3]=0x%lx-0x%lx\n", 561 __S(__BS(map)), CHIP_W3_SYS_START(v), 562 CHIP_W3_SYS_END(v)); 563 #endif 564 panic("%s: don't know how to unmap %lx", __S(__BS(unmap)), h); 565 } 566 567 #ifdef EXTENT_DEBUG 568 printf("xxx: freeing 0x%lx to 0x%lx\n", addr, addr + size - 1); 569 #endif 570 error = extent_free(CHIP_EXTENT(v), addr, size, 571 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 572 if (error) { 573 printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n", 574 __S(__BS(unmap)), addr, addr + size - 1, 575 error); 576 #ifdef EXTENT_DEBUG 577 extent_print(CHIP_EXTENT(v)); 578 #endif 579 } 580 #endif /* CHIP_EXTENT */ 581 } 582 583 int 584 __BS(subregion)(void *v, bus_space_handle_t h, bus_size_t offset, 585 bus_size_t size, bus_space_handle_t *nh) 586 { 587 588 *nh = h + (offset << CHIP_ALIGN_STRIDE); 589 return (0); 590 } 591 592 int 593 __BS(alloc)(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, 594 bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp, 595 bus_space_handle_t *bshp) 596 { 597 #ifdef CHIP_EXTENT 598 struct mips_bus_space_translation mbst; 599 bus_addr_t addr; 600 int error; 601 #if CHIP_ALIGN_STRIDE != 0 602 int linear = flags & BUS_SPACE_MAP_LINEAR; 603 604 /* 605 * Can't map xxx space linearly. 606 */ 607 if (linear) 608 return (EOPNOTSUPP); 609 #endif 610 611 /* 612 * Do the requested allocation. 613 */ 614 #ifdef EXTENT_DEBUG 615 printf("xxx: allocating from 0x%lx to 0x%lx\n", rstart, rend); 616 #endif 617 error = extent_alloc_subregion(CHIP_EXTENT(v), rstart, rend, size, 618 align, boundary, 619 EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0), 620 &addr); 621 if (error) { 622 #ifdef EXTENT_DEBUG 623 printf("xxx: allocation failed (%d)\n", error); 624 extent_print(CHIP_EXTENT(v)); 625 #endif 626 return (error); 627 } 628 629 #ifdef EXTENT_DEBUG 630 printf("xxx: allocated 0x%lx to 0x%lx\n", addr, addr + size - 1); 631 #endif 632 633 error = __BS(translate)(v, addr, size, flags, &mbst); 634 if (error) { 635 (void) extent_free(CHIP_EXTENT(v), addr, size, 636 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 637 return (error); 638 } 639 640 *addrp = addr; 641 if (flags & BUS_SPACE_MAP_CACHEABLE) 642 *bshp = MIPS_PHYS_TO_KSEG0(mbst.mbst_sys_start + 643 (addr - mbst.mbst_bus_start)); 644 else 645 *bshp = MIPS_PHYS_TO_KSEG1(mbst.mbst_sys_start + 646 (addr - mbst.mbst_bus_start)); 647 648 return (0); 649 #else /* ! CHIP_EXTENT */ 650 return (EOPNOTSUPP); 651 #endif /* CHIP_EXTENT */ 652 } 653 654 void 655 __BS(free)(void *v, bus_space_handle_t bsh, bus_size_t size) 656 { 657 658 /* Unmap does all we need to do. */ 659 __BS(unmap)(v, bsh, size, 1); 660 } 661 662 void * 663 __BS(vaddr)(void *v, bus_space_handle_t bsh) 664 { 665 666 #if CHIP_ALIGN_STRIDE != 0 667 /* Linear mappings not possible. */ 668 return (NULL); 669 #else 670 return ((void *)bsh); 671 #endif 672 } 673 674 paddr_t 675 __BS(mmap)(void *v, bus_addr_t addr, off_t off, int prot, int flags) 676 { 677 #ifdef CHIP_IO 678 679 /* Not supported for I/O space. */ 680 return (-1); 681 #elif defined(CHIP_MEM) 682 struct mips_bus_space_translation mbst; 683 int error; 684 685 /* 686 * Get the translation for this address. 687 */ 688 error = __BS(translate)(v, addr, off + PAGE_SIZE, flags, 689 &mbst); 690 if (error) 691 return (-1); 692 693 return (mips_btop(mbst.mbst_sys_start + 694 (addr - mbst.mbst_bus_start) + off)); 695 #else 696 # error must define one of CHIP_IO or CHIP_MEM 697 #endif 698 } 699 700 inline void 701 __BS(barrier)(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int f) 702 { 703 704 /* XXX XXX XXX */ 705 if ((f & BUS_SPACE_BARRIER_WRITE) != 0) 706 wbflush(); 707 } 708 709 inline uint8_t 710 __BS(read_1)(void *v, bus_space_handle_t h, bus_size_t off) 711 { 712 uint8_t *ptr = (void *)(h + (off << CHIP_ALIGN_STRIDE)); 713 714 return (*ptr); 715 } 716 717 inline uint16_t 718 __BS(read_2)(void *v, bus_space_handle_t h, bus_size_t off) 719 { 720 #if CHIP_ALIGN_STRIDE >= 1 721 uint16_t *ptr = (void *)(h + (off << (CHIP_ALIGN_STRIDE - 1))); 722 #else 723 uint16_t *ptr = (void *)(h + off); 724 #endif 725 726 return (*ptr); 727 } 728 729 inline uint32_t 730 __BS(read_4)(void *v, bus_space_handle_t h, bus_size_t off) 731 { 732 #if CHIP_ALIGN_STRIDE >= 2 733 uint32_t *ptr = (void *)(h + (off << (CHIP_ALIGN_STRIDE - 2))); 734 #else 735 uint32_t *ptr = (void *)(h + off); 736 #endif 737 738 return (*ptr); 739 } 740 741 inline uint64_t 742 __BS(read_8)(void *v, bus_space_handle_t h, bus_size_t off) 743 { 744 745 /* XXX XXX XXX */ 746 panic("%s not implemented", __S(__BS(read_8))); 747 } 748 749 #define CHIP_read_multi_N(BYTES,TYPE) \ 750 void \ 751 __C(__BS(read_multi_),BYTES)(void *v, bus_space_handle_t h, \ 752 bus_size_t o, TYPE *a, bus_size_t c) \ 753 { \ 754 \ 755 while (c-- > 0) { \ 756 __BS(barrier)(v, h, o, sizeof *a, \ 757 BUS_SPACE_BARRIER_READ); \ 758 *a++ = __C(__BS(read_),BYTES)(v, h, o); \ 759 } \ 760 } 761 CHIP_read_multi_N(1,uint8_t) 762 CHIP_read_multi_N(2,uint16_t) 763 CHIP_read_multi_N(4,uint32_t) 764 CHIP_read_multi_N(8,uint64_t) 765 766 #define CHIP_read_region_N(BYTES,TYPE) \ 767 void \ 768 __C(__BS(read_region_),BYTES)(void *v, bus_space_handle_t h, \ 769 bus_size_t o, TYPE *a, bus_size_t c) \ 770 { \ 771 \ 772 while (c-- > 0) { \ 773 *a++ = __C(__BS(read_),BYTES)(v, h, o); \ 774 o += sizeof *a; \ 775 } \ 776 } 777 CHIP_read_region_N(1,uint8_t) 778 CHIP_read_region_N(2,uint16_t) 779 CHIP_read_region_N(4,uint32_t) 780 CHIP_read_region_N(8,uint64_t) 781 782 inline void 783 __BS(write_1)(void *v, bus_space_handle_t h, bus_size_t off, uint8_t val) 784 { 785 uint8_t *ptr = (void *)(h + (off << CHIP_ALIGN_STRIDE)); 786 787 *ptr = val; 788 } 789 790 inline void 791 __BS(write_2)(void *v, bus_space_handle_t h, bus_size_t off, uint16_t val) 792 { 793 #if CHIP_ALIGN_STRIDE >= 1 794 uint16_t *ptr = (void *)(h + (off << (CHIP_ALIGN_STRIDE - 1))); 795 #else 796 uint16_t *ptr = (void *)(h + off); 797 #endif 798 799 *ptr = val; 800 } 801 802 inline void 803 __BS(write_4)(void *v, bus_space_handle_t h, bus_size_t off, uint32_t val) 804 { 805 #if CHIP_ALIGN_STRIDE >= 2 806 uint32_t *ptr = (void *)(h + (off << (CHIP_ALIGN_STRIDE - 2))); 807 #else 808 uint32_t *ptr = (void *)(h + off); 809 #endif 810 811 *ptr = val; 812 } 813 814 inline void 815 __BS(write_8)(void *v, bus_space_handle_t h, bus_size_t off, uint64_t val) 816 { 817 818 /* XXX XXX XXX */ 819 panic("%s not implemented", __S(__BS(write_8))); 820 } 821 822 #define CHIP_write_multi_N(BYTES,TYPE) \ 823 void \ 824 __C(__BS(write_multi_),BYTES)(void *v, bus_space_handle_t h, \ 825 bus_size_t o, const TYPE *a, bus_size_t c) \ 826 { \ 827 \ 828 while (c-- > 0) { \ 829 __C(__BS(write_),BYTES)(v, h, o, *a++); \ 830 __BS(barrier)(v, h, o, sizeof *a, \ 831 BUS_SPACE_BARRIER_WRITE); \ 832 } \ 833 } 834 CHIP_write_multi_N(1,uint8_t) 835 CHIP_write_multi_N(2,uint16_t) 836 CHIP_write_multi_N(4,uint32_t) 837 CHIP_write_multi_N(8,uint64_t) 838 839 #define CHIP_write_region_N(BYTES,TYPE) \ 840 void \ 841 __C(__BS(write_region_),BYTES)(void *v, bus_space_handle_t h, \ 842 bus_size_t o, const TYPE *a, bus_size_t c) \ 843 { \ 844 \ 845 while (c-- > 0) { \ 846 __C(__BS(write_),BYTES)(v, h, o, *a++); \ 847 o += sizeof *a; \ 848 } \ 849 } 850 CHIP_write_region_N(1,uint8_t) 851 CHIP_write_region_N(2,uint16_t) 852 CHIP_write_region_N(4,uint32_t) 853 CHIP_write_region_N(8,uint64_t) 854 855 #define CHIP_set_multi_N(BYTES,TYPE) \ 856 void \ 857 __C(__BS(set_multi_),BYTES)(void *v, bus_space_handle_t h, \ 858 bus_size_t o, TYPE val, bus_size_t c) \ 859 { \ 860 \ 861 while (c-- > 0) { \ 862 __C(__BS(write_),BYTES)(v, h, o, val); \ 863 __BS(barrier)(v, h, o, sizeof val, \ 864 BUS_SPACE_BARRIER_WRITE); \ 865 } \ 866 } 867 CHIP_set_multi_N(1,uint8_t) 868 CHIP_set_multi_N(2,uint16_t) 869 CHIP_set_multi_N(4,uint32_t) 870 CHIP_set_multi_N(8,uint64_t) 871 872 #define CHIP_set_region_N(BYTES,TYPE) \ 873 void \ 874 __C(__BS(set_region_),BYTES)(void *v, bus_space_handle_t h, \ 875 bus_size_t o, TYPE val, bus_size_t c) \ 876 { \ 877 \ 878 while (c-- > 0) { \ 879 __C(__BS(write_),BYTES)(v, h, o, val); \ 880 o += sizeof val; \ 881 } \ 882 } 883 CHIP_set_region_N(1,uint8_t) 884 CHIP_set_region_N(2,uint16_t) 885 CHIP_set_region_N(4,uint32_t) 886 CHIP_set_region_N(8,uint64_t) 887 888 #define CHIP_copy_region_N(BYTES) \ 889 void \ 890 __C(__BS(copy_region_),BYTES)(void *v, bus_space_handle_t h1, \ 891 bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c) \ 892 { \ 893 bus_size_t o; \ 894 \ 895 if ((h1 + o1) >= (h2 + o2)) { \ 896 /* src after dest: copy forward */ \ 897 for (o = 0; c != 0; c--, o += BYTES) \ 898 __C(__BS(write_),BYTES)(v, h2, o2 + o, \ 899 __C(__BS(read_),BYTES)(v, h1, o1 + o)); \ 900 } else { \ 901 /* dest after src: copy backwards */ \ 902 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \ 903 __C(__BS(write_),BYTES)(v, h2, o2 + o, \ 904 __C(__BS(read_),BYTES)(v, h1, o1 + o)); \ 905 } \ 906 } 907 CHIP_copy_region_N(1) 908 CHIP_copy_region_N(2) 909 CHIP_copy_region_N(4) 910 CHIP_copy_region_N(8) 911