1 /* $NetBSD: au_wired_space.c,v 1.5 2007/03/04 06:00:11 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 Itronix Inc. 5 * All rights reserved. 6 * 7 * Written by Garrett D'Amore for Itronix Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of Itronix Inc. may not be used to endorse 18 * or promote products derived from this software without specific 19 * prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28 * ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 /* 34 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 35 * All rights reserved. 36 * 37 * This code is derived from software contributed to The NetBSD Foundation 38 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace 39 * Simulation Facility, NASA Ames Research Center. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 3. All advertising materials mentioning features or use of this software 50 * must display the following acknowledgement: 51 * This product includes software developed by the NetBSD 52 * Foundation, Inc. and its contributors. 53 * 4. Neither the name of The NetBSD Foundation nor the names of its 54 * contributors may be used to endorse or promote products derived 55 * from this software without specific prior written permission. 56 * 57 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 58 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 59 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 60 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 61 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 62 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 63 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 64 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 65 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 66 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 67 * POSSIBILITY OF SUCH DAMAGE. 68 */ 69 70 #include <sys/cdefs.h> 71 __KERNEL_RCSID(0, "$NetBSD: au_wired_space.c,v 1.5 2007/03/04 06:00:11 christos Exp $"); 72 73 /* 74 * This provides mappings for the upper I/O regions used on some 75 * Alchemy parts, e.g. PCI and PCMCIA spaces. These spaces can be 76 * accessed using wired TLB entries. 77 */ 78 79 #include <sys/param.h> 80 #include <sys/systm.h> 81 #include <sys/extent.h> 82 #include <sys/malloc.h> 83 #include <sys/endian.h> 84 85 #include <machine/bus.h> 86 #include <machine/locore.h> 87 #include <machine/wired_map.h> 88 #include <mips/alchemy/include/au_wired_space.h> 89 90 #ifndef AU_WIRED_EXTENT_SZ 91 #define AU_WIRED_EXTENT_SZ EXTENT_FIXED_STORAGE_SIZE(10) 92 #endif 93 94 typedef struct au_wired_cookie { 95 const char *c_name; 96 bus_addr_t c_start; 97 bus_size_t c_size; 98 paddr_t c_pbase; 99 int c_flags; 100 int c_swswap; 101 bool c_hwswap; 102 struct extent *c_extent; 103 long c_exstore[AU_WIRED_EXTENT_SZ/sizeof (long)]; 104 } au_wired_cookie_t; 105 106 int au_wired_map(void *, bus_addr_t, bus_size_t, int, 107 bus_space_handle_t *, int); 108 void au_wired_unmap(void *, bus_space_handle_t, bus_size_t, int); 109 void *au_wired_vaddr(void *, bus_space_handle_t); 110 int au_wired_subregion(void *, bus_space_handle_t, bus_size_t, bus_size_t, 111 bus_space_handle_t *); 112 paddr_t au_wired_mmap(void *, bus_addr_t, off_t, int, int); 113 int au_wired_alloc(void *, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t, 114 bus_size_t, int, bus_addr_t *, bus_space_handle_t *); 115 void au_wired_free(void *, bus_space_handle_t, bus_size_t); 116 void au_wired_barrier(void *, bus_space_handle_t, bus_size_t, bus_size_t, int); 117 uint8_t au_wired_r_1(void *, bus_space_handle_t, bus_size_t); 118 uint16_t au_wired_r_2(void *, bus_space_handle_t, bus_size_t); 119 uint32_t au_wired_r_4(void *, bus_space_handle_t, bus_size_t); 120 uint64_t au_wired_r_8(void *, bus_space_handle_t, bus_size_t); 121 void au_wired_rm_1(void *, bus_space_handle_t, bus_size_t, uint8_t *, 122 bus_size_t); 123 void au_wired_rm_2(void *, bus_space_handle_t, bus_size_t, uint16_t *, 124 bus_size_t); 125 void au_wired_rm_4(void *, bus_space_handle_t, bus_size_t, uint32_t *, 126 bus_size_t); 127 void au_wired_rm_8(void *, bus_space_handle_t, bus_size_t, uint64_t *, 128 bus_size_t); 129 void au_wired_rr_1(void *, bus_space_handle_t, bus_size_t, uint8_t *, 130 bus_size_t); 131 void au_wired_rr_2(void *, bus_space_handle_t, bus_size_t, uint16_t *, 132 bus_size_t); 133 void au_wired_rr_4(void *, bus_space_handle_t, bus_size_t, uint32_t *, 134 bus_size_t); 135 void au_wired_rr_8(void *, bus_space_handle_t, bus_size_t, uint64_t *, 136 bus_size_t); 137 void au_wired_w_1(void *, bus_space_handle_t, bus_size_t, uint8_t); 138 void au_wired_w_2(void *, bus_space_handle_t, bus_size_t, uint16_t); 139 void au_wired_w_4(void *, bus_space_handle_t, bus_size_t, uint32_t); 140 void au_wired_w_8(void *, bus_space_handle_t, bus_size_t, uint64_t); 141 void au_wired_wm_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *, 142 bus_size_t); 143 void au_wired_wm_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *, 144 bus_size_t); 145 void au_wired_wm_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *, 146 bus_size_t); 147 void au_wired_wm_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *, 148 bus_size_t); 149 void au_wired_wr_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *, 150 bus_size_t); 151 void au_wired_wr_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *, 152 bus_size_t); 153 void au_wired_wr_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *, 154 bus_size_t); 155 void au_wired_wr_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *, 156 bus_size_t); 157 void au_wired_sm_1(void *, bus_space_handle_t, bus_size_t, uint8_t, 158 bus_size_t); 159 void au_wired_sm_2(void *, bus_space_handle_t, bus_size_t, uint16_t, 160 bus_size_t); 161 void au_wired_sm_4(void *, bus_space_handle_t, bus_size_t, uint32_t, 162 bus_size_t); 163 void au_wired_sm_8(void *, bus_space_handle_t, bus_size_t, uint64_t, 164 bus_size_t); 165 void au_wired_sr_1(void *, bus_space_handle_t, bus_size_t, uint8_t, 166 bus_size_t); 167 void au_wired_sr_2(void *, bus_space_handle_t, bus_size_t, uint16_t, 168 bus_size_t); 169 void au_wired_sr_4(void *, bus_space_handle_t, bus_size_t, uint32_t, 170 bus_size_t); 171 void au_wired_sr_8(void *, bus_space_handle_t, bus_size_t, uint64_t, 172 bus_size_t); 173 void au_wired_c_1(void *, bus_space_handle_t, bus_size_t, 174 bus_space_handle_t, bus_size_t, bus_size_t); 175 void au_wired_c_2(void *, bus_space_handle_t, bus_size_t, 176 bus_space_handle_t, bus_size_t, bus_size_t); 177 void au_wired_c_4(void *, bus_space_handle_t, bus_size_t, 178 bus_space_handle_t, bus_size_t, bus_size_t); 179 void au_wired_c_8(void *, bus_space_handle_t, bus_size_t, 180 bus_space_handle_t, bus_size_t, bus_size_t); 181 uint16_t au_wired_rs_2(void *, bus_space_handle_t, bus_size_t); 182 uint32_t au_wired_rs_4(void *, bus_space_handle_t, bus_size_t); 183 uint64_t au_wired_rs_8(void *, bus_space_handle_t, bus_size_t); 184 void au_wired_ws_2(void *, bus_space_handle_t, bus_size_t, uint16_t); 185 void au_wired_ws_4(void *, bus_space_handle_t, bus_size_t, uint32_t); 186 void au_wired_ws_8(void *, bus_space_handle_t, bus_size_t, uint64_t); 187 void au_wired_rms_2(void *, bus_space_handle_t, bus_size_t, uint16_t *, 188 bus_size_t); 189 void au_wired_rms_4(void *, bus_space_handle_t, bus_size_t, uint32_t *, 190 bus_size_t); 191 void au_wired_rms_8(void *, bus_space_handle_t, bus_size_t, uint64_t *, 192 bus_size_t); 193 void au_wired_rrs_2(void *, bus_space_handle_t, bus_size_t, uint16_t *, 194 bus_size_t); 195 void au_wired_rrs_4(void *, bus_space_handle_t, bus_size_t, uint32_t *, 196 bus_size_t); 197 void au_wired_rrs_8(void *, bus_space_handle_t, bus_size_t, uint64_t *, 198 bus_size_t); 199 void au_wired_wms_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *, 200 bus_size_t); 201 void au_wired_wms_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *, 202 bus_size_t); 203 void au_wired_wms_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *, 204 bus_size_t); 205 void au_wired_wrs_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *, 206 bus_size_t); 207 void au_wired_wrs_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *, 208 bus_size_t); 209 void au_wired_wrs_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *, 210 bus_size_t); 211 212 int 213 au_wired_map(void *cookie, bus_addr_t addr, bus_size_t size, 214 int flags, bus_space_handle_t *bshp, int acct) 215 { 216 int err; 217 au_wired_cookie_t *c = (au_wired_cookie_t *)cookie; 218 paddr_t pa; 219 220 /* make sure we can map this bus address */ 221 if (addr < c->c_start || 222 addr + size > c->c_start + c->c_size) 223 return EINVAL; 224 225 pa = c->c_pbase + (addr - c->c_start); 226 227 if (!mips3_wired_enter_region(addr, pa, size)) 228 return ENOMEM; 229 230 /* 231 * bus addresses are taken from virtual address space. 232 */ 233 if (acct && c->c_extent != NULL) { 234 err = extent_alloc_region(c->c_extent, addr, size, EX_NOWAIT); 235 if (err) 236 return err; 237 } 238 239 *bshp = addr; 240 241 return 0; 242 } 243 244 void 245 au_wired_unmap(void *cookie, bus_space_handle_t bsh, bus_size_t size, int acct) 246 { 247 au_wired_cookie_t *c = (au_wired_cookie_t *)cookie; 248 249 if (acct != 0 && c->c_extent != NULL) { 250 extent_free(c->c_extent, (vaddr_t)bsh, size, EX_NOWAIT); 251 } 252 } 253 254 int 255 au_wired_subregion(void *cookie, bus_space_handle_t bsh, 256 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp) 257 { 258 259 *nbshp = bsh + offset; 260 return 0; 261 } 262 263 void * 264 au_wired_vaddr(void *cookie, bus_space_handle_t bsh) 265 { 266 267 return ((void *)bsh); 268 } 269 270 paddr_t 271 au_wired_mmap(void *cookie, bus_addr_t addr, off_t off, int prot, int flags) 272 { 273 au_wired_cookie_t *c = (au_wired_cookie_t *)cookie; 274 275 /* I/O spaces should not be directly mmap'ed */ 276 if (c->c_flags & AU_WIRED_SPACE_IO) 277 return -1; 278 279 if (addr < c->c_start || (addr + off) >= (c->c_start + c->c_size)) 280 return -1; 281 282 return mips_btop(c->c_pbase + (addr - c->c_start) + off); 283 } 284 285 int 286 au_wired_alloc(void *cookie, bus_addr_t start, bus_addr_t end, 287 bus_size_t size, bus_size_t align, bus_size_t boundary, int flags, 288 bus_addr_t *addrp, bus_space_handle_t *bshp) 289 { 290 au_wired_cookie_t *c = (au_wired_cookie_t *)cookie; 291 vaddr_t addr; 292 int err; 293 paddr_t pa; 294 295 if (c->c_extent == NULL) 296 panic("au_wired_alloc: extent map %s not avail", c->c_name); 297 298 if (start < c->c_start || ((start + size) > (c->c_start + c->c_size))) 299 return EINVAL; 300 301 err = extent_alloc_subregion(c->c_extent, start, end, size, 302 align, boundary, EX_FAST | EX_NOWAIT, &addr); 303 if (err) 304 return err; 305 306 pa = c->c_pbase + (addr - c->c_start); 307 308 if (!mips3_wired_enter_region(addr, pa, size)) 309 return ENOMEM; 310 311 *bshp = addr; 312 *addrp = addr; 313 return 0; 314 } 315 316 void 317 au_wired_free(void *cookie, bus_space_handle_t bsh, bus_size_t size) 318 { 319 320 /* unmap takes care of it all */ 321 au_wired_unmap(cookie, bsh, size, 1); 322 } 323 324 inline void 325 au_wired_barrier(void *cookie, bus_space_handle_t bsh, bus_size_t o, 326 bus_size_t l, int f) 327 { 328 329 if (f & BUS_SPACE_BARRIER_WRITE) 330 wbflush(); 331 } 332 333 inline uint8_t 334 au_wired_r_1(void *v, bus_space_handle_t h, bus_size_t o) 335 { 336 337 return (*(volatile uint8_t *)(h + o)); 338 } 339 340 inline uint16_t 341 au_wired_r_2(void *v, bus_space_handle_t h, bus_size_t o) 342 { 343 uint16_t val = (*(volatile uint16_t *)(h + o)); 344 au_wired_cookie_t *c = (au_wired_cookie_t *)v; 345 346 return (c->c_swswap ? bswap16(val) : val); 347 } 348 349 inline uint32_t 350 au_wired_r_4(void *v, bus_space_handle_t h, bus_size_t o) 351 { 352 uint32_t val = (*(volatile uint32_t *)(h + o)); 353 au_wired_cookie_t *c = (au_wired_cookie_t *)v; 354 355 return (c->c_swswap ? bswap32(val) : val); 356 } 357 358 inline uint64_t 359 au_wired_r_8(void *v, bus_space_handle_t h, bus_size_t o) 360 { 361 uint64_t val = (*(volatile uint64_t *)(h + o)); 362 au_wired_cookie_t *c = (au_wired_cookie_t *)v; 363 364 return (c->c_swswap ? bswap64(val) : val); 365 } 366 367 inline void 368 au_wired_w_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t val) 369 { 370 371 *(volatile uint8_t *)(h + o) = val; 372 } 373 374 inline void 375 au_wired_w_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t val) 376 { 377 au_wired_cookie_t *c = (au_wired_cookie_t *)v; 378 379 *(volatile uint16_t *)(h + o) = c->c_swswap ? bswap16(val) : val; 380 } 381 382 inline void 383 au_wired_w_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t val) 384 { 385 au_wired_cookie_t *c = (au_wired_cookie_t *)v; 386 387 *(volatile uint32_t *)(h + o) = c->c_swswap ? bswap32(val) : val; 388 } 389 390 inline void 391 au_wired_w_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t val) 392 { 393 au_wired_cookie_t *c = (au_wired_cookie_t *)v; 394 395 *(volatile uint64_t *)(h + o) = c->c_swswap ? bswap64(val) : val; 396 } 397 398 inline uint16_t 399 au_wired_rs_2(void *v, bus_space_handle_t h, bus_size_t o) 400 { 401 uint16_t val = (*(volatile uint16_t *)(h + o)); 402 au_wired_cookie_t *c = (au_wired_cookie_t *)v; 403 404 return (c->c_hwswap ? bswap16(val) : val); 405 } 406 407 inline uint32_t 408 au_wired_rs_4(void *v, bus_space_handle_t h, bus_size_t o) 409 { 410 uint32_t val = (*(volatile uint32_t *)(h + o)); 411 au_wired_cookie_t *c = (au_wired_cookie_t *)v; 412 413 return (c->c_hwswap ? bswap32(val) : val); 414 } 415 416 inline uint64_t 417 au_wired_rs_8(void *v, bus_space_handle_t h, bus_size_t o) 418 { 419 uint64_t val = (*(volatile uint64_t *)(h + o)); 420 au_wired_cookie_t *c = (au_wired_cookie_t *)v; 421 422 return (c->c_hwswap ? bswap64(val) : val); 423 } 424 425 inline void 426 au_wired_ws_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t val) 427 { 428 au_wired_cookie_t *c = (au_wired_cookie_t *)v; 429 430 *(volatile uint16_t *)(h + o) = c->c_hwswap ? bswap16(val) : val; 431 } 432 433 inline void 434 au_wired_ws_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t val) 435 { 436 au_wired_cookie_t *c = (au_wired_cookie_t *)v; 437 438 *(volatile uint32_t *)(h + o) = c->c_hwswap ? bswap32(val) : val; 439 } 440 441 inline void 442 au_wired_ws_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t val) 443 { 444 au_wired_cookie_t *c = (au_wired_cookie_t *)v; 445 446 *(volatile uint64_t *)(h + o) = c->c_hwswap ? bswap64(val) : val; 447 } 448 449 #define AU_WIRED_RM(TYPE,BYTES) \ 450 void \ 451 __CONCAT(au_wired_rm_,BYTES)(void *v, \ 452 bus_space_handle_t h, bus_size_t o, TYPE *dst, bus_size_t cnt) \ 453 { \ 454 \ 455 while (cnt-- > 0) \ 456 *dst ++ = __CONCAT(au_wired_r_,BYTES)(v, h, o); \ 457 } 458 AU_WIRED_RM(uint8_t,1) 459 AU_WIRED_RM(uint16_t,2) 460 AU_WIRED_RM(uint32_t,4) 461 AU_WIRED_RM(uint64_t,8) 462 463 #define AU_WIRED_RMS(TYPE,BYTES) \ 464 void \ 465 __CONCAT(au_wired_rms_,BYTES)(void *v, \ 466 bus_space_handle_t h, bus_size_t o, TYPE *dst, bus_size_t cnt) \ 467 { \ 468 \ 469 while (cnt-- > 0) { \ 470 wbflush(); \ 471 *dst++ = __CONCAT(au_wired_rs_,BYTES)(v, h, o); \ 472 } \ 473 } 474 AU_WIRED_RMS(uint16_t,2) 475 AU_WIRED_RMS(uint32_t,4) 476 AU_WIRED_RMS(uint64_t,8) 477 478 #define AU_WIRED_RR(TYPE,BYTES) \ 479 void \ 480 __CONCAT(au_wired_rr_,BYTES)(void *v, \ 481 bus_space_handle_t h, bus_size_t o, TYPE *dst, bus_size_t cnt) \ 482 { \ 483 \ 484 while (cnt-- > 0) { \ 485 *dst++ = __CONCAT(au_wired_r_,BYTES)(v, h, o); \ 486 o += BYTES; \ 487 } \ 488 } 489 AU_WIRED_RR(uint8_t,1) 490 AU_WIRED_RR(uint16_t,2) 491 AU_WIRED_RR(uint32_t,4) 492 AU_WIRED_RR(uint64_t,8) 493 494 #define AU_WIRED_RRS(TYPE,BYTES) \ 495 void \ 496 __CONCAT(au_wired_rrs_,BYTES)(void *v, \ 497 bus_space_handle_t h, bus_size_t o, TYPE *dst, bus_size_t cnt) \ 498 { \ 499 \ 500 while (cnt-- > 0) { \ 501 *dst++ = __CONCAT(au_wired_rs_,BYTES)(v, h, o); \ 502 o += BYTES; \ 503 } \ 504 } 505 AU_WIRED_RRS(uint16_t,2) 506 AU_WIRED_RRS(uint32_t,4) 507 AU_WIRED_RRS(uint64_t,8) 508 509 #define AU_WIRED_WM(TYPE,BYTES) \ 510 void \ 511 __CONCAT(au_wired_wm_,BYTES)(void *v, \ 512 bus_space_handle_t h, bus_size_t o, const TYPE *src, \ 513 bus_size_t cnt) \ 514 { \ 515 \ 516 while (cnt-- > 0) { \ 517 __CONCAT(au_wired_w_,BYTES)(v, h, o, *src++); \ 518 wbflush(); \ 519 } \ 520 } 521 AU_WIRED_WM(uint8_t,1) 522 AU_WIRED_WM(uint16_t,2) 523 AU_WIRED_WM(uint32_t,4) 524 AU_WIRED_WM(uint64_t,8) 525 526 #define AU_WIRED_WMS(TYPE,BYTES) \ 527 void \ 528 __CONCAT(au_wired_wms_,BYTES)(void *v, \ 529 bus_space_handle_t h, bus_size_t o, const TYPE *src, \ 530 bus_size_t cnt) \ 531 { \ 532 \ 533 while (cnt-- > 0) { \ 534 __CONCAT(au_wired_ws_,BYTES)(v, h, o, *src++); \ 535 wbflush(); \ 536 } \ 537 } 538 AU_WIRED_WMS(uint16_t,2) 539 AU_WIRED_WMS(uint32_t,4) 540 AU_WIRED_WMS(uint64_t,8) 541 542 #define AU_WIRED_WR(TYPE,BYTES) \ 543 void \ 544 __CONCAT(au_wired_wr_,BYTES)(void *v, \ 545 bus_space_handle_t h, bus_size_t o, const TYPE *src, \ 546 bus_size_t cnt) \ 547 { \ 548 \ 549 while (cnt-- > 0) { \ 550 __CONCAT(au_wired_w_,BYTES)(v, h, o, *src++); \ 551 o += BYTES; \ 552 } \ 553 } 554 AU_WIRED_WR(uint8_t,1) 555 AU_WIRED_WR(uint16_t,2) 556 AU_WIRED_WR(uint32_t,4) 557 AU_WIRED_WR(uint64_t,8) 558 559 #define AU_WIRED_WRS(TYPE,BYTES) \ 560 void \ 561 __CONCAT(au_wired_wrs_,BYTES)(void *v, \ 562 bus_space_handle_t h, bus_size_t o, const TYPE *src, \ 563 bus_size_t cnt) \ 564 { \ 565 \ 566 while (cnt-- > 0) { \ 567 __CONCAT(au_wired_ws_,BYTES)(v, h, o, *src++); \ 568 o += BYTES; \ 569 } \ 570 } 571 AU_WIRED_WRS(uint16_t,2) 572 AU_WIRED_WRS(uint32_t,4) 573 AU_WIRED_WRS(uint64_t,8) 574 575 #define AU_WIRED_SM(TYPE,BYTES) \ 576 void \ 577 __CONCAT(au_wired_sm_,BYTES)(void *v, \ 578 bus_space_handle_t h, bus_size_t o, TYPE val, \ 579 bus_size_t cnt) \ 580 { \ 581 \ 582 while (cnt-- > 0) { \ 583 __CONCAT(au_wired_w_,BYTES)(v, h, o, val); \ 584 wbflush(); \ 585 } \ 586 } 587 AU_WIRED_SM(uint8_t,1) 588 AU_WIRED_SM(uint16_t,2) 589 AU_WIRED_SM(uint32_t,4) 590 AU_WIRED_SM(uint64_t,8) 591 592 #define AU_WIRED_SR(TYPE,BYTES) \ 593 void \ 594 __CONCAT(au_wired_sr_,BYTES)(void *v, \ 595 bus_space_handle_t h, bus_size_t o, TYPE val, \ 596 bus_size_t cnt) \ 597 { \ 598 \ 599 while (cnt-- > 0) { \ 600 __CONCAT(au_wired_w_,BYTES)(v, h, o, val); \ 601 o += BYTES; \ 602 } \ 603 } 604 AU_WIRED_SR(uint8_t,1) 605 AU_WIRED_SR(uint16_t,2) 606 AU_WIRED_SR(uint32_t,4) 607 AU_WIRED_SR(uint64_t,8) 608 609 610 #define AU_WIRED_C(TYPE,BYTES) \ 611 void \ 612 __CONCAT(au_wired_c_,BYTES)(void *v, \ 613 bus_space_handle_t h1, bus_size_t o1, bus_space_handle_t h2, \ 614 bus_space_handle_t o2, bus_size_t cnt) \ 615 { \ 616 volatile TYPE *src, *dst; \ 617 src = (volatile TYPE *)(h1 + o1); \ 618 dst = (volatile TYPE *)(h2 + o2); \ 619 \ 620 if (src >= dst) { \ 621 while (cnt-- > 0) \ 622 *dst++ = *src++; \ 623 } else { \ 624 src += cnt - 1; \ 625 dst += cnt - 1; \ 626 while (cnt-- > 0) \ 627 *dst-- = *src--; \ 628 } \ 629 } 630 AU_WIRED_C(uint8_t,1) 631 AU_WIRED_C(uint16_t,2) 632 AU_WIRED_C(uint32_t,4) 633 AU_WIRED_C(uint64_t,8) 634 635 636 void 637 au_wired_space_init(bus_space_tag_t bst, const char *name, 638 paddr_t paddr, bus_addr_t start, bus_size_t size, int flags) 639 { 640 au_wired_cookie_t *c; 641 642 c = malloc(sizeof (struct au_wired_cookie), M_DEVBUF, 643 M_NOWAIT | M_ZERO); 644 645 c->c_pbase = paddr; 646 c->c_name = name; 647 c->c_start = start; 648 c->c_size = size; 649 650 /* allocate extent manager */ 651 c->c_extent = extent_create(name, start, start + size, M_DEVBUF, 652 (void *)c->c_exstore, sizeof (c->c_exstore), EX_NOWAIT); 653 if (c->c_extent == NULL) 654 panic("au_wired_space_init: %s: cannot create extent", name); 655 656 #if _BYTE_ORDER == _BIG_ENDIAN 657 if (flags & AU_WIRED_SPACE_LITTLE_ENDIAN) { 658 if (flags & AU_WIRED_SPACE_SWAP_HW) 659 c->c_hwswap = 1; 660 else 661 c->c_swswap = 1; 662 } 663 664 #elif _BYTE_ORDER == _LITTLE_ENDIAN 665 if (flags & AU_WIRED_SPACE_BIG_ENDIAN) { 666 if (flags & AU_WIRED_SPACE_SWAP_HW) 667 c->c_hwswap = 1; 668 else 669 c->c_swswap = 1; 670 } 671 #endif 672 673 bst->bs_cookie = c; 674 bst->bs_map = au_wired_map; 675 bst->bs_unmap = au_wired_unmap; 676 bst->bs_subregion = au_wired_subregion; 677 bst->bs_translate = NULL; /* we don't use these */ 678 bst->bs_get_window = NULL; /* we don't use these */ 679 bst->bs_alloc = au_wired_alloc; 680 bst->bs_free = au_wired_free; 681 bst->bs_vaddr = au_wired_vaddr; 682 bst->bs_mmap = au_wired_mmap; 683 bst->bs_barrier = au_wired_barrier; 684 bst->bs_r_1 = au_wired_r_1; 685 bst->bs_w_1 = au_wired_w_1; 686 bst->bs_r_2 = au_wired_r_2; 687 bst->bs_r_4 = au_wired_r_4; 688 bst->bs_r_8 = au_wired_r_8; 689 bst->bs_w_2 = au_wired_w_2; 690 bst->bs_w_4 = au_wired_w_4; 691 bst->bs_w_8 = au_wired_w_8; 692 bst->bs_rm_1 = au_wired_rm_1; 693 bst->bs_rm_2 = au_wired_rm_2; 694 bst->bs_rm_4 = au_wired_rm_4; 695 bst->bs_rm_8 = au_wired_rm_8; 696 bst->bs_rr_1 = au_wired_rr_1; 697 bst->bs_rr_2 = au_wired_rr_2; 698 bst->bs_rr_4 = au_wired_rr_4; 699 bst->bs_rr_8 = au_wired_rr_8; 700 bst->bs_wm_1 = au_wired_wm_1; 701 bst->bs_wm_2 = au_wired_wm_2; 702 bst->bs_wm_4 = au_wired_wm_4; 703 bst->bs_wm_8 = au_wired_wm_8; 704 bst->bs_wr_1 = au_wired_wr_1; 705 bst->bs_wr_2 = au_wired_wr_2; 706 bst->bs_wr_4 = au_wired_wr_4; 707 bst->bs_wr_8 = au_wired_wr_8; 708 bst->bs_sm_1 = au_wired_sm_1; 709 bst->bs_sm_2 = au_wired_sm_2; 710 bst->bs_sm_4 = au_wired_sm_4; 711 bst->bs_sm_8 = au_wired_sm_8; 712 bst->bs_sr_1 = au_wired_sr_1; 713 bst->bs_sr_2 = au_wired_sr_2; 714 bst->bs_sr_4 = au_wired_sr_4; 715 bst->bs_sr_8 = au_wired_sr_8; 716 bst->bs_c_1 = au_wired_c_1; 717 bst->bs_c_2 = au_wired_c_2; 718 bst->bs_c_4 = au_wired_c_4; 719 bst->bs_c_8 = au_wired_c_8; 720 721 bst->bs_rs_1 = au_wired_r_1; 722 bst->bs_rs_2 = au_wired_rs_2; 723 bst->bs_rs_4 = au_wired_rs_4; 724 bst->bs_rs_8 = au_wired_rs_8; 725 bst->bs_rms_1 = au_wired_rm_1; 726 bst->bs_rms_2 = au_wired_rms_2; 727 bst->bs_rms_4 = au_wired_rms_4; 728 bst->bs_rms_8 = au_wired_rms_8; 729 bst->bs_rrs_1 = au_wired_rr_1; 730 bst->bs_rrs_2 = au_wired_rrs_2; 731 bst->bs_rrs_4 = au_wired_rrs_4; 732 bst->bs_rrs_8 = au_wired_rrs_8; 733 bst->bs_ws_1 = au_wired_w_1; 734 bst->bs_ws_2 = au_wired_ws_2; 735 bst->bs_ws_4 = au_wired_ws_4; 736 bst->bs_ws_8 = au_wired_ws_8; 737 bst->bs_wms_1 = au_wired_wm_1; 738 bst->bs_wms_2 = au_wired_wms_2; 739 bst->bs_wms_4 = au_wired_wms_4; 740 bst->bs_wms_8 = au_wired_wms_8; 741 bst->bs_wrs_1 = au_wired_wr_1; 742 bst->bs_wrs_2 = au_wired_wrs_2; 743 bst->bs_wrs_4 = au_wired_wrs_4; 744 bst->bs_wrs_8 = au_wired_wrs_8; 745 } 746