1 /* $NetBSD: bus_space_alignstride_chipdep.c,v 1.4 2002/08/19 12:03:48 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 #ifdef CHIP_EXTENT 85 #include <sys/extent.h> 86 #endif 87 #include <sys/malloc.h> 88 89 #include <machine/locore.h> 90 91 #include <uvm/uvm_extern.h> 92 93 #define __C(A,B) __CONCAT(A,B) 94 #define __S(S) __STRING(S) 95 96 #ifdef CHIP_IO 97 #define __BS(A) __C(__C(CHIP,_bus_io_),A) 98 #endif 99 #ifdef CHIP_MEM 100 #define __BS(A) __C(__C(CHIP,_bus_mem_),A) 101 #endif 102 103 /* mapping/unmapping */ 104 int __BS(map)(void *, bus_addr_t, bus_size_t, int, 105 bus_space_handle_t *, int); 106 void __BS(unmap)(void *, bus_space_handle_t, bus_size_t, int); 107 int __BS(subregion)(void *, bus_space_handle_t, bus_size_t, 108 bus_size_t, bus_space_handle_t *); 109 110 int __BS(translate)(void *, bus_addr_t, bus_size_t, int, 111 struct mips_bus_space_translation *); 112 int __BS(get_window)(void *, int, 113 struct mips_bus_space_translation *); 114 115 /* allocation/deallocation */ 116 int __BS(alloc)(void *, bus_addr_t, bus_addr_t, bus_size_t, 117 bus_size_t, bus_addr_t, int, bus_addr_t *, 118 bus_space_handle_t *); 119 void __BS(free)(void *, bus_space_handle_t, bus_size_t); 120 121 /* get kernel virtual address */ 122 void * __BS(vaddr)(void *, bus_space_handle_t); 123 124 /* mmap for user */ 125 paddr_t __BS(mmap)(void *, bus_addr_t, off_t, int, int); 126 127 /* barrier */ 128 inline void __BS(barrier)(void *, bus_space_handle_t, bus_size_t, 129 bus_size_t, int); 130 131 /* read (single) */ 132 inline uint8_t __BS(read_1)(void *, bus_space_handle_t, bus_size_t); 133 inline uint16_t __BS(read_2)(void *, bus_space_handle_t, bus_size_t); 134 inline uint32_t __BS(read_4)(void *, bus_space_handle_t, bus_size_t); 135 inline uint64_t __BS(read_8)(void *, bus_space_handle_t, bus_size_t); 136 137 /* read multiple */ 138 void __BS(read_multi_1)(void *, bus_space_handle_t, bus_size_t, 139 uint8_t *, bus_size_t); 140 void __BS(read_multi_2)(void *, bus_space_handle_t, bus_size_t, 141 uint16_t *, bus_size_t); 142 void __BS(read_multi_4)(void *, bus_space_handle_t, bus_size_t, 143 uint32_t *, bus_size_t); 144 void __BS(read_multi_8)(void *, bus_space_handle_t, bus_size_t, 145 uint64_t *, bus_size_t); 146 147 /* read region */ 148 void __BS(read_region_1)(void *, bus_space_handle_t, bus_size_t, 149 uint8_t *, bus_size_t); 150 void __BS(read_region_2)(void *, bus_space_handle_t, bus_size_t, 151 uint16_t *, bus_size_t); 152 void __BS(read_region_4)(void *, bus_space_handle_t, bus_size_t, 153 uint32_t *, bus_size_t); 154 void __BS(read_region_8)(void *, bus_space_handle_t, bus_size_t, 155 uint64_t *, bus_size_t); 156 157 /* write (single) */ 158 inline void __BS(write_1)(void *, bus_space_handle_t, bus_size_t, uint8_t); 159 inline void __BS(write_2)(void *, bus_space_handle_t, bus_size_t, uint16_t); 160 inline void __BS(write_4)(void *, bus_space_handle_t, bus_size_t, uint32_t); 161 inline void __BS(write_8)(void *, bus_space_handle_t, bus_size_t, uint64_t); 162 163 /* write multiple */ 164 void __BS(write_multi_1)(void *, bus_space_handle_t, bus_size_t, 165 const uint8_t *, bus_size_t); 166 void __BS(write_multi_2)(void *, bus_space_handle_t, bus_size_t, 167 const uint16_t *, bus_size_t); 168 void __BS(write_multi_4)(void *, bus_space_handle_t, bus_size_t, 169 const uint32_t *, bus_size_t); 170 void __BS(write_multi_8)(void *, bus_space_handle_t, bus_size_t, 171 const uint64_t *, bus_size_t); 172 173 /* write region */ 174 void __BS(write_region_1)(void *, bus_space_handle_t, bus_size_t, 175 const uint8_t *, bus_size_t); 176 void __BS(write_region_2)(void *, bus_space_handle_t, bus_size_t, 177 const uint16_t *, bus_size_t); 178 void __BS(write_region_4)(void *, bus_space_handle_t, bus_size_t, 179 const uint32_t *, bus_size_t); 180 void __BS(write_region_8)(void *, bus_space_handle_t, bus_size_t, 181 const uint64_t *, bus_size_t); 182 183 /* set multiple */ 184 void __BS(set_multi_1)(void *, bus_space_handle_t, bus_size_t, 185 uint8_t, bus_size_t); 186 void __BS(set_multi_2)(void *, bus_space_handle_t, bus_size_t, 187 uint16_t, bus_size_t); 188 void __BS(set_multi_4)(void *, bus_space_handle_t, bus_size_t, 189 uint32_t, bus_size_t); 190 void __BS(set_multi_8)(void *, bus_space_handle_t, bus_size_t, 191 uint64_t, bus_size_t); 192 193 /* set region */ 194 void __BS(set_region_1)(void *, bus_space_handle_t, bus_size_t, 195 uint8_t, bus_size_t); 196 void __BS(set_region_2)(void *, bus_space_handle_t, bus_size_t, 197 uint16_t, bus_size_t); 198 void __BS(set_region_4)(void *, bus_space_handle_t, bus_size_t, 199 uint32_t, bus_size_t); 200 void __BS(set_region_8)(void *, bus_space_handle_t, bus_size_t, 201 uint64_t, bus_size_t); 202 203 /* copy */ 204 void __BS(copy_region_1)(void *, bus_space_handle_t, bus_size_t, 205 bus_space_handle_t, bus_size_t, bus_size_t); 206 void __BS(copy_region_2)(void *, bus_space_handle_t, bus_size_t, 207 bus_space_handle_t, bus_size_t, bus_size_t); 208 void __BS(copy_region_4)(void *, bus_space_handle_t, bus_size_t, 209 bus_space_handle_t, bus_size_t, bus_size_t); 210 void __BS(copy_region_8)(void *, bus_space_handle_t, bus_size_t, 211 bus_space_handle_t, bus_size_t, bus_size_t); 212 213 #ifdef CHIP_EXTENT 214 #ifndef CHIP_EX_STORE 215 static long 216 __BS(ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 217 #define CHIP_EX_STORE(v) (__BS(ex_storage)) 218 #define CHIP_EX_STORE_SIZE(v) (sizeof __BS(ex_storage)) 219 #endif 220 #endif /* CHIP_EXTENT */ 221 222 #ifndef CHIP_ALIGN_STRIDE 223 #define CHIP_ALIGN_STRIDE 0 224 #endif 225 226 void 227 __BS(init)(bus_space_tag_t t, void *v) 228 { 229 #ifdef CHIP_EXTENT 230 struct extent *ex; 231 #endif 232 233 /* 234 * Initialize the bus space tag. 235 */ 236 237 /* cookie */ 238 t->bs_cookie = v; 239 240 /* mapping/unmapping */ 241 t->bs_map = __BS(map); 242 t->bs_unmap = __BS(unmap); 243 t->bs_subregion = __BS(subregion); 244 245 t->bs_translate = __BS(translate); 246 t->bs_get_window = __BS(get_window); 247 248 /* allocation/deallocation */ 249 t->bs_alloc = __BS(alloc); 250 t->bs_free = __BS(free); 251 252 /* get kernel virtual address */ 253 t->bs_vaddr = __BS(vaddr); 254 255 /* mmap for user */ 256 t->bs_mmap = __BS(mmap); 257 258 /* barrier */ 259 t->bs_barrier = __BS(barrier); 260 261 /* read (single) */ 262 t->bs_r_1 = __BS(read_1); 263 t->bs_r_2 = __BS(read_2); 264 t->bs_r_4 = __BS(read_4); 265 t->bs_r_8 = __BS(read_8); 266 267 /* read multiple */ 268 t->bs_rm_1 = __BS(read_multi_1); 269 t->bs_rm_2 = __BS(read_multi_2); 270 t->bs_rm_4 = __BS(read_multi_4); 271 t->bs_rm_8 = __BS(read_multi_8); 272 273 /* read region */ 274 t->bs_rr_1 = __BS(read_region_1); 275 t->bs_rr_2 = __BS(read_region_2); 276 t->bs_rr_4 = __BS(read_region_4); 277 t->bs_rr_8 = __BS(read_region_8); 278 279 /* write (single) */ 280 t->bs_w_1 = __BS(write_1); 281 t->bs_w_2 = __BS(write_2); 282 t->bs_w_4 = __BS(write_4); 283 t->bs_w_8 = __BS(write_8); 284 285 /* write multiple */ 286 t->bs_wm_1 = __BS(write_multi_1); 287 t->bs_wm_2 = __BS(write_multi_2); 288 t->bs_wm_4 = __BS(write_multi_4); 289 t->bs_wm_8 = __BS(write_multi_8); 290 291 /* write region */ 292 t->bs_wr_1 = __BS(write_region_1); 293 t->bs_wr_2 = __BS(write_region_2); 294 t->bs_wr_4 = __BS(write_region_4); 295 t->bs_wr_8 = __BS(write_region_8); 296 297 /* set multiple */ 298 t->bs_sm_1 = __BS(set_multi_1); 299 t->bs_sm_2 = __BS(set_multi_2); 300 t->bs_sm_4 = __BS(set_multi_4); 301 t->bs_sm_8 = __BS(set_multi_8); 302 303 /* set region */ 304 t->bs_sr_1 = __BS(set_region_1); 305 t->bs_sr_2 = __BS(set_region_2); 306 t->bs_sr_4 = __BS(set_region_4); 307 t->bs_sr_8 = __BS(set_region_8); 308 309 /* copy */ 310 t->bs_c_1 = __BS(copy_region_1); 311 t->bs_c_2 = __BS(copy_region_2); 312 t->bs_c_4 = __BS(copy_region_4); 313 t->bs_c_8 = __BS(copy_region_8); 314 315 #ifdef CHIP_EXTENT 316 /* XXX WE WANT EXTENT_NOCOALESCE, BUT WE CAN'T USE IT. XXX */ 317 ex = extent_create(__S(__BS(bus)), 0x0UL, 0xffffffffUL, M_DEVBUF, 318 (caddr_t)CHIP_EX_STORE(v), CHIP_EX_STORE_SIZE(v), EX_NOWAIT); 319 extent_alloc_region(ex, 0, 0xffffffffUL, EX_NOWAIT); 320 321 #ifdef CHIP_W1_BUS_START 322 /* 323 * The window may be disabled. We notice this by seeing 324 * -1 as the bus base address. 325 */ 326 if (CHIP_W1_BUS_START(v) == (bus_addr_t) -1) { 327 #ifdef EXTENT_DEBUG 328 printf("xxx: this space is disabled\n"); 329 #endif 330 return; 331 } 332 333 #ifdef EXTENT_DEBUG 334 printf("xxx: freeing from 0x%x to 0x%x\n", CHIP_W1_BUS_START(v), 335 CHIP_W1_BUS_END(v)); 336 #endif 337 extent_free(ex, CHIP_W1_BUS_START(v), 338 CHIP_W1_BUS_END(v) - CHIP_W1_BUS_START(v) + 1, EX_NOWAIT); 339 #endif 340 #ifdef CHIP_W2_BUS_START 341 if (CHIP_W2_BUS_START(v) != CHIP_W1_BUS_START(v)) { 342 #ifdef EXTENT_DEBUG 343 printf("xxx: freeing from 0x%lx to 0x%lx\n", 344 (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); 345 #endif 346 extent_free(ex, CHIP_W2_BUS_START(v), 347 CHIP_W2_BUS_END(v) - CHIP_W2_BUS_START(v) + 1, EX_NOWAIT); 348 } else { 349 #ifdef EXTENT_DEBUG 350 printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n", 351 (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); 352 #endif 353 } 354 #endif 355 #ifdef CHIP_W3_BUS_START 356 if (CHIP_W3_BUS_START(v) != CHIP_W1_BUS_START(v) && 357 CHIP_W3_BUS_START(v) != CHIP_W2_BUS_START(v)) { 358 #ifdef EXTENT_DEBUG 359 printf("xxx: freeing from 0x%lx to 0x%lx\n", 360 (u_long)CHIP_W3_BUS_START(v), (u_long)CHIP_W3_BUS_END(v)); 361 #endif 362 extent_free(ex, CHIP_W3_BUS_START(v), 363 CHIP_W3_BUS_END(v) - CHIP_W3_BUS_START(v) + 1, EX_NOWAIT); 364 } else { 365 #ifdef EXTENT_DEBUG 366 printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n", 367 (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); 368 #endif 369 } 370 #endif 371 372 #ifdef EXTENT_DEBUG 373 extent_print(ex); 374 #endif 375 CHIP_EXTENT(v) = ex; 376 #endif /* CHIP_EXTENT */ 377 } 378 379 int 380 __BS(translate)(void *v, bus_addr_t addr, bus_size_t len, int flags, 381 struct mips_bus_space_translation *mbst) 382 { 383 bus_addr_t end = addr + (len - 1); 384 #if CHIP_ALIGN_STRIDE != 0 385 int linear = flags & BUS_SPACE_MAP_LINEAR; 386 387 /* 388 * Can't map xxx space linearly. 389 */ 390 if (linear) 391 return (EOPNOTSUPP); 392 #endif 393 394 #ifdef CHIP_W1_BUS_START 395 if (addr >= CHIP_W1_BUS_START(v) && end <= CHIP_W1_BUS_END(v)) 396 return (__BS(get_window)(v, 0, mbst)); 397 #endif 398 399 #ifdef CHIP_W2_BUS_START 400 if (addr >= CHIP_W2_BUS_START(v) && end <= CHIP_W2_BUS_END(v)) 401 return (__BS(get_window)(v, 1, mbst)); 402 #endif 403 404 #ifdef CHIP_W3_BUS_START 405 if (addr >= CHIP_W3_BUS_START(v) && end <= CHIP_W3_BUS_END(v)) 406 return (__BS(get_window)(v, 2, mbst)); 407 #endif 408 409 #ifdef EXTENT_DEBUG 410 printf("\n"); 411 #ifdef CHIP_W1_BUS_START 412 printf("%s: window[1]=0x%lx-0x%lx\n", __S(__BS(map)), 413 (u_long)CHIP_W1_BUS_START(v), (u_long)CHIP_W1_BUS_END(v)); 414 #endif 415 #ifdef CHIP_W2_BUS_START 416 printf("%s: window[2]=0x%lx-0x%lx\n", __S(__BS(map)), 417 (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); 418 #endif 419 #ifdef CHIP_W3_BUS_START 420 printf("%s: window[3]=0x%lx-0x%lx\n", __S(__BS(map)), 421 (u_long)CHIP_W3_BUS_START(v), (u_long)CHIP_W3_BUS_END(v)); 422 #endif 423 #endif /* EXTENT_DEBUG */ 424 /* No translation. */ 425 return (EINVAL); 426 } 427 428 int 429 __BS(get_window)(void *v, int window, struct mips_bus_space_translation *mbst) 430 { 431 432 switch (window) { 433 #ifdef CHIP_W1_BUS_START 434 case 0: 435 mbst->mbst_bus_start = CHIP_W1_BUS_START(v); 436 mbst->mbst_bus_end = CHIP_W1_BUS_END(v); 437 mbst->mbst_sys_start = CHIP_W1_SYS_START(v); 438 mbst->mbst_sys_end = CHIP_W1_SYS_END(v); 439 mbst->mbst_align_stride = CHIP_ALIGN_STRIDE; 440 mbst->mbst_flags = 0; 441 break; 442 #endif 443 444 #ifdef CHIP_W2_BUS_START 445 case 1: 446 mbst->mbst_bus_start = CHIP_W2_BUS_START(v); 447 mbst->mbst_bus_end = CHIP_W2_BUS_END(v); 448 mbst->mbst_sys_start = CHIP_W2_SYS_START(v); 449 mbst->mbst_sys_end = CHIP_W2_SYS_END(v); 450 mbst->mbst_align_stride = CHIP_ALIGN_STRIDE; 451 mbst->mbst_flags = 0; 452 break; 453 #endif 454 455 #ifdef CHIP_W3_BUS_START 456 case 2: 457 mbst->mbst_bus_start = CHIP_W3_BUS_START(v); 458 mbst->mbst_bus_end = CHIP_W3_BUS_END(v); 459 mbst->mbst_sys_start = CHIP_W3_SYS_START(v); 460 mbst->mbst_sys_end = CHIP_W3_SYS_END(v); 461 mbst->mbst_align_stride = CHIP_ALIGN_STRIDE; 462 mbst->mbst_flags = 0; 463 break; 464 #endif 465 466 default: 467 panic(__S(__BS(get_window)) ": invalid window %d", 468 window); 469 } 470 471 return (0); 472 } 473 474 int 475 __BS(map)(void *v, bus_addr_t addr, bus_size_t size, int flags, 476 bus_space_handle_t *hp, int acct) 477 { 478 struct mips_bus_space_translation mbst; 479 int error; 480 481 /* 482 * Get the translation for this address. 483 */ 484 error = __BS(translate)(v, addr, size, flags, &mbst); 485 if (error) 486 return (error); 487 488 #ifdef CHIP_EXTENT 489 if (acct == 0) 490 goto mapit; 491 492 #ifdef EXTENT_DEBUG 493 printf("xxx: allocating 0x%lx to 0x%lx\n", addr, addr + size - 1); 494 #endif 495 error = extent_alloc_region(CHIP_EXTENT(v), addr, size, 496 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 497 if (error) { 498 #ifdef EXTENT_DEBUG 499 printf("xxx: allocation failed (%d)\n", error); 500 extent_print(CHIP_EXTENT(v)); 501 #endif 502 return (error); 503 } 504 505 mapit: 506 #endif /* CHIP_EXTENT */ 507 if (flags & BUS_SPACE_MAP_CACHEABLE) 508 *hp = MIPS_PHYS_TO_KSEG0(mbst.mbst_sys_start + 509 (addr - mbst.mbst_bus_start)); 510 else 511 *hp = MIPS_PHYS_TO_KSEG1(mbst.mbst_sys_start + 512 (addr - mbst.mbst_bus_start)); 513 514 return (0); 515 } 516 517 void 518 __BS(unmap)(void *v, bus_space_handle_t h, bus_size_t size, int acct) 519 { 520 #ifdef CHIP_EXTENT 521 bus_addr_t addr; 522 int error; 523 524 if (acct == 0) 525 return; 526 527 #ifdef EXTENT_DEBUG 528 printf("xxx: freeing handle 0x%lx for 0x%lx\n", h, size); 529 #endif 530 531 if (h >= MIPS_KSEG0_START && h < MIPS_KSEG1_START) 532 h = MIPS_KSEG0_TO_PHYS(h); 533 else 534 h = MIPS_KSEG1_TO_PHYS(h); 535 536 #ifdef CHIP_W1_BUS_START 537 if (h >= CHIP_W1_SYS_START(v) && h <= CHIP_W1_SYS_END(v)) { 538 addr = CHIP_W1_BUS_START(v) + (h - CHIP_W1_SYS_START(v)); 539 } else 540 #endif 541 #ifdef CHIP_W2_BUS_START 542 if (h >= CHIP_W2_SYS_START(v) && h <= CHIP_W2_SYS_END(v)) { 543 addr = CHIP_W2_BUS_START(v) + (h - CHIP_W2_SYS_START(v)); 544 } else 545 #endif 546 #ifdef CHIP_W3_BUS_START 547 if (h >= CHIP_W3_SYS_START(v) && h <= CHIP_W3_SYS_END(v)) { 548 addr = CHIP_W3_BUS_START(v) + (h - CHIP_W3_SYS_START(v)); 549 } else 550 #endif 551 { 552 printf("\n"); 553 #ifdef CHIP_W1_BUS_START 554 printf("%s: sys window[1]=0x%lx-0x%lx\n", 555 __S(__BS(map)), (u_long)CHIP_W1_SYS_START(v), 556 (u_long)CHIP_W1_SYS_END(v)); 557 #endif 558 #ifdef CHIP_W2_BUS_START 559 printf("%s: sys window[2]=0x%lx-0x%lx\n", 560 __S(__BS(map)), (u_long)CHIP_W2_SYS_START(v), 561 (u_long)CHIP_W2_SYS_END(v)); 562 #endif 563 #ifdef CHIP_W3_BUS_START 564 printf("%s: sys window[3]=0x%lx-0x%lx\n", 565 __S(__BS(map)), (u_long)CHIP_W3_SYS_START(v), 566 (u_long)CHIP_W3_SYS_END(v)); 567 #endif 568 panic("%s: don't know how to unmap %lx", __S(__BS(unmap)), h); 569 } 570 571 #ifdef EXTENT_DEBUG 572 printf("xxx: freeing 0x%lx to 0x%lx\n", addr, addr + size - 1); 573 #endif 574 error = extent_free(CHIP_EXTENT(v), addr, size, 575 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 576 if (error) { 577 printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n", 578 __S(__BS(unmap)), addr, addr + size - 1, 579 error); 580 #ifdef EXTENT_DEBUG 581 extent_print(CHIP_EXTENT(v)); 582 #endif 583 } 584 #endif /* CHIP_EXTENT */ 585 } 586 587 int 588 __BS(subregion)(void *v, bus_space_handle_t h, bus_size_t offset, 589 bus_size_t size, bus_space_handle_t *nh) 590 { 591 592 *nh = h + (offset << CHIP_ALIGN_STRIDE); 593 return (0); 594 } 595 596 int 597 __BS(alloc)(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, 598 bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp, 599 bus_space_handle_t *bshp) 600 { 601 #ifdef CHIP_EXTENT 602 struct mips_bus_space_translation mbst; 603 bus_addr_t addr; 604 int error; 605 #if CHIP_ALIGN_STRIDE != 0 606 int linear = flags & BUS_SPACE_MAP_LINEAR; 607 608 /* 609 * Can't map xxx space linearly. 610 */ 611 if (linear) 612 return (EOPNOTSUPP); 613 #endif 614 615 /* 616 * Do the requested allocation. 617 */ 618 #ifdef EXTENT_DEBUG 619 printf("xxx: allocating from 0x%lx to 0x%lx\n", rstart, rend); 620 #endif 621 error = extent_alloc_subregion(CHIP_EXTENT(v), rstart, rend, size, 622 align, boundary, 623 EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0), 624 &addr); 625 if (error) { 626 #ifdef EXTENT_DEBUG 627 printf("xxx: allocation failed (%d)\n", error); 628 extent_print(CHIP_EXTENT(v)); 629 #endif 630 return (error); 631 } 632 633 #ifdef EXTENT_DEBUG 634 printf("xxx: allocated 0x%lx to 0x%lx\n", addr, addr + size - 1); 635 #endif 636 637 error = __BS(translate)(v, addr, size, flags, &mbst); 638 if (error) { 639 (void) extent_free(CHIP_EXTENT(v), addr, size, 640 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 641 return (error); 642 } 643 644 *addrp = addr; 645 if (flags & BUS_SPACE_MAP_CACHEABLE) 646 *bshp = MIPS_PHYS_TO_KSEG0(mbst.mbst_sys_start + 647 (addr - mbst.mbst_bus_start)); 648 else 649 *bshp = MIPS_PHYS_TO_KSEG1(mbst.mbst_sys_start + 650 (addr - mbst.mbst_bus_start)); 651 652 return (0); 653 #else /* ! CHIP_EXTENT */ 654 return (EOPNOTSUPP); 655 #endif /* CHIP_EXTENT */ 656 } 657 658 void 659 __BS(free)(void *v, bus_space_handle_t bsh, bus_size_t size) 660 { 661 662 /* Unmap does all we need to do. */ 663 __BS(unmap)(v, bsh, size, 1); 664 } 665 666 void * 667 __BS(vaddr)(void *v, bus_space_handle_t bsh) 668 { 669 670 #if CHIP_ALIGN_STRIDE != 0 671 /* Linear mappings not possible. */ 672 return (NULL); 673 #else 674 return ((void *)bsh); 675 #endif 676 } 677 678 paddr_t 679 __BS(mmap)(void *v, bus_addr_t addr, off_t off, int prot, int flags) 680 { 681 #ifdef CHIP_IO 682 683 /* Not supported for I/O space. */ 684 return (-1); 685 #elif defined(CHIP_MEM) 686 struct mips_bus_space_translation mbst; 687 int error; 688 689 /* 690 * Get the translation for this address. 691 */ 692 error = __BS(translate)(v, addr, off + PAGE_SIZE, flags, 693 &mbst); 694 if (error) 695 return (-1); 696 697 return (mips_btop(mbst.mbst_sys_start + 698 (addr - mbst.mbst_bus_start) + off)); 699 #else 700 # error must define one of CHIP_IO or CHIP_MEM 701 #endif 702 } 703 704 inline void 705 __BS(barrier)(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int f) 706 { 707 708 /* XXX XXX XXX */ 709 if ((f & BUS_SPACE_BARRIER_WRITE) != 0) 710 wbflush(); 711 } 712 713 inline uint8_t 714 __BS(read_1)(void *v, bus_space_handle_t h, bus_size_t off) 715 { 716 #ifdef CHIP_ACCESSTYPE 717 CHIP_ACCESSTYPE *ptr = (void *)(h + (off << CHIP_ALIGN_STRIDE)); 718 CHIP_ACCESSTYPE rval; 719 720 rval = *ptr; 721 return (rval & 0xff); /* XXX BigEndian safe? */ 722 #else /* !CHIP_ACCESSTYPE */ 723 uint8_t *ptr = (void *)(h + (off << CHIP_ALIGN_STRIDE)); 724 725 return (*ptr); 726 #endif /* !CHIP_ACCESSTYPE */ 727 } 728 729 inline uint16_t 730 __BS(read_2)(void *v, bus_space_handle_t h, bus_size_t off) 731 { 732 #ifdef CHIP_ACCESSTYPE 733 #if CHIP_ALIGN_STRIDE >= 1 734 CHIP_ACCESSTYPE *ptr = (void *)(h + (off << (CHIP_ALIGN_STRIDE - 1))); 735 #else 736 CHIP_ACCESSTYPE *ptr = (void *)(h + off); 737 #endif 738 CHIP_ACCESSTYPE rval; 739 740 rval = *ptr; 741 return (rval & 0xffff); /* XXX BigEndian safe? */ 742 #else /* !CHIP_ACCESSTYPE */ 743 #if CHIP_ALIGN_STRIDE >= 1 744 uint16_t *ptr = (void *)(h + (off << (CHIP_ALIGN_STRIDE - 1))); 745 #else 746 uint16_t *ptr = (void *)(h + off); 747 #endif 748 749 return (*ptr); 750 #endif /* !CHIP_ACCESSTYPE */ 751 } 752 753 inline uint32_t 754 __BS(read_4)(void *v, bus_space_handle_t h, bus_size_t off) 755 { 756 /* XXX XXX XXX should use CHIP_ACCESSTYPE if it's > 32bits */ 757 #if CHIP_ALIGN_STRIDE >= 2 758 uint32_t *ptr = (void *)(h + (off << (CHIP_ALIGN_STRIDE - 2))); 759 #else 760 uint32_t *ptr = (void *)(h + off); 761 #endif 762 763 return (*ptr); 764 } 765 766 inline uint64_t 767 __BS(read_8)(void *v, bus_space_handle_t h, bus_size_t off) 768 { 769 770 /* XXX XXX XXX */ 771 panic("%s not implemented", __S(__BS(read_8))); 772 } 773 774 #define CHIP_read_multi_N(BYTES,TYPE) \ 775 void \ 776 __C(__BS(read_multi_),BYTES)(void *v, bus_space_handle_t h, \ 777 bus_size_t o, TYPE *a, bus_size_t c) \ 778 { \ 779 \ 780 while (c-- > 0) { \ 781 __BS(barrier)(v, h, o, sizeof *a, \ 782 BUS_SPACE_BARRIER_READ); \ 783 *a++ = __C(__BS(read_),BYTES)(v, h, o); \ 784 } \ 785 } 786 CHIP_read_multi_N(1,uint8_t) 787 CHIP_read_multi_N(2,uint16_t) 788 CHIP_read_multi_N(4,uint32_t) 789 CHIP_read_multi_N(8,uint64_t) 790 791 #define CHIP_read_region_N(BYTES,TYPE) \ 792 void \ 793 __C(__BS(read_region_),BYTES)(void *v, bus_space_handle_t h, \ 794 bus_size_t o, TYPE *a, bus_size_t c) \ 795 { \ 796 \ 797 while (c-- > 0) { \ 798 *a++ = __C(__BS(read_),BYTES)(v, h, o); \ 799 o += sizeof *a; \ 800 } \ 801 } 802 CHIP_read_region_N(1,uint8_t) 803 CHIP_read_region_N(2,uint16_t) 804 CHIP_read_region_N(4,uint32_t) 805 CHIP_read_region_N(8,uint64_t) 806 807 inline void 808 __BS(write_1)(void *v, bus_space_handle_t h, bus_size_t off, uint8_t val) 809 { 810 #ifdef CHIP_ACCESSTYPE 811 CHIP_ACCESSTYPE *ptr = (void *)(h + (off << CHIP_ALIGN_STRIDE)); 812 CHIP_ACCESSTYPE wval; 813 814 wval = val & 0xff; /* XXX BigEndian safe? */ 815 *ptr = wval; 816 #else /* !CHIP_ACCESSTYPE */ 817 uint8_t *ptr = (void *)(h + (off << CHIP_ALIGN_STRIDE)); 818 819 *ptr = val; 820 #endif /* !CHIP_ACCESSTYPE */ 821 } 822 823 inline void 824 __BS(write_2)(void *v, bus_space_handle_t h, bus_size_t off, uint16_t val) 825 { 826 #ifdef CHIP_ACCESSTYPE 827 #if CHIP_ALIGN_STRIDE >= 1 828 CHIP_ACCESSTYPE *ptr = (void *)(h + (off << (CHIP_ALIGN_STRIDE - 1))); 829 #else 830 CHIP_ACCESSTYPE *ptr = (void *)(h + off); 831 #endif 832 CHIP_ACCESSTYPE wval; 833 834 wval = val & 0xffff; /* XXX BigEndian safe? */ 835 *ptr = wval; 836 #else /* !CHIP_ACCESSTYPE */ 837 #if CHIP_ALIGN_STRIDE >= 1 838 uint16_t *ptr = (void *)(h + (off << (CHIP_ALIGN_STRIDE - 1))); 839 #else 840 uint16_t *ptr = (void *)(h + off); 841 #endif 842 843 *ptr = val; 844 #endif /* !CHIP_ACCESSTYPE */ 845 } 846 847 inline void 848 __BS(write_4)(void *v, bus_space_handle_t h, bus_size_t off, uint32_t val) 849 { 850 /* XXX XXX XXX should use CHIP_ACCESSTYPE if it's > 32bits */ 851 #if CHIP_ALIGN_STRIDE >= 2 852 uint32_t *ptr = (void *)(h + (off << (CHIP_ALIGN_STRIDE - 2))); 853 #else 854 uint32_t *ptr = (void *)(h + off); 855 #endif 856 857 *ptr = val; 858 } 859 860 inline void 861 __BS(write_8)(void *v, bus_space_handle_t h, bus_size_t off, uint64_t val) 862 { 863 864 /* XXX XXX XXX */ 865 panic("%s not implemented", __S(__BS(write_8))); 866 } 867 868 #define CHIP_write_multi_N(BYTES,TYPE) \ 869 void \ 870 __C(__BS(write_multi_),BYTES)(void *v, bus_space_handle_t h, \ 871 bus_size_t o, const TYPE *a, bus_size_t c) \ 872 { \ 873 \ 874 while (c-- > 0) { \ 875 __C(__BS(write_),BYTES)(v, h, o, *a++); \ 876 __BS(barrier)(v, h, o, sizeof *a, \ 877 BUS_SPACE_BARRIER_WRITE); \ 878 } \ 879 } 880 CHIP_write_multi_N(1,uint8_t) 881 CHIP_write_multi_N(2,uint16_t) 882 CHIP_write_multi_N(4,uint32_t) 883 CHIP_write_multi_N(8,uint64_t) 884 885 #define CHIP_write_region_N(BYTES,TYPE) \ 886 void \ 887 __C(__BS(write_region_),BYTES)(void *v, bus_space_handle_t h, \ 888 bus_size_t o, const TYPE *a, bus_size_t c) \ 889 { \ 890 \ 891 while (c-- > 0) { \ 892 __C(__BS(write_),BYTES)(v, h, o, *a++); \ 893 o += sizeof *a; \ 894 } \ 895 } 896 CHIP_write_region_N(1,uint8_t) 897 CHIP_write_region_N(2,uint16_t) 898 CHIP_write_region_N(4,uint32_t) 899 CHIP_write_region_N(8,uint64_t) 900 901 #define CHIP_set_multi_N(BYTES,TYPE) \ 902 void \ 903 __C(__BS(set_multi_),BYTES)(void *v, bus_space_handle_t h, \ 904 bus_size_t o, TYPE val, bus_size_t c) \ 905 { \ 906 \ 907 while (c-- > 0) { \ 908 __C(__BS(write_),BYTES)(v, h, o, val); \ 909 __BS(barrier)(v, h, o, sizeof val, \ 910 BUS_SPACE_BARRIER_WRITE); \ 911 } \ 912 } 913 CHIP_set_multi_N(1,uint8_t) 914 CHIP_set_multi_N(2,uint16_t) 915 CHIP_set_multi_N(4,uint32_t) 916 CHIP_set_multi_N(8,uint64_t) 917 918 #define CHIP_set_region_N(BYTES,TYPE) \ 919 void \ 920 __C(__BS(set_region_),BYTES)(void *v, bus_space_handle_t h, \ 921 bus_size_t o, TYPE val, bus_size_t c) \ 922 { \ 923 \ 924 while (c-- > 0) { \ 925 __C(__BS(write_),BYTES)(v, h, o, val); \ 926 o += sizeof val; \ 927 } \ 928 } 929 CHIP_set_region_N(1,uint8_t) 930 CHIP_set_region_N(2,uint16_t) 931 CHIP_set_region_N(4,uint32_t) 932 CHIP_set_region_N(8,uint64_t) 933 934 #define CHIP_copy_region_N(BYTES) \ 935 void \ 936 __C(__BS(copy_region_),BYTES)(void *v, bus_space_handle_t h1, \ 937 bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c) \ 938 { \ 939 bus_size_t o; \ 940 \ 941 if ((h1 + o1) >= (h2 + o2)) { \ 942 /* src after dest: copy forward */ \ 943 for (o = 0; c != 0; c--, o += BYTES) \ 944 __C(__BS(write_),BYTES)(v, h2, o2 + o, \ 945 __C(__BS(read_),BYTES)(v, h1, o1 + o)); \ 946 } else { \ 947 /* dest after src: copy backwards */ \ 948 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \ 949 __C(__BS(write_),BYTES)(v, h2, o2 + o, \ 950 __C(__BS(read_),BYTES)(v, h1, o1 + o)); \ 951 } \ 952 } 953 CHIP_copy_region_N(1) 954 CHIP_copy_region_N(2) 955 CHIP_copy_region_N(4) 956 CHIP_copy_region_N(8) 957