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