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 87typedef 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 99int au_wired_map(void *, bus_addr_t, bus_size_t, int, 100 bus_space_handle_t *, int); 101void au_wired_unmap(void *, bus_space_handle_t, bus_size_t, int); 102void *au_wired_vaddr(void *, bus_space_handle_t); 103int au_wired_subregion(void *, bus_space_handle_t, bus_size_t, bus_size_t, 104 bus_space_handle_t *); 105paddr_t au_wired_mmap(void *, bus_addr_t, off_t, int, int); 106int 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 *); 108void au_wired_free(void *, bus_space_handle_t, bus_size_t); 109void au_wired_barrier(void *, bus_space_handle_t, bus_size_t, bus_size_t, int); 110uint8_t au_wired_r_1(void *, bus_space_handle_t, bus_size_t); 111uint16_t au_wired_r_2(void *, bus_space_handle_t, bus_size_t); 112uint32_t au_wired_r_4(void *, bus_space_handle_t, bus_size_t); 113uint64_t au_wired_r_8(void *, bus_space_handle_t, bus_size_t); 114void au_wired_rm_1(void *, bus_space_handle_t, bus_size_t, uint8_t *, 115 bus_size_t); 116void au_wired_rm_2(void *, bus_space_handle_t, bus_size_t, uint16_t *, 117 bus_size_t); 118void au_wired_rm_4(void *, bus_space_handle_t, bus_size_t, uint32_t *, 119 bus_size_t); 120void au_wired_rm_8(void *, bus_space_handle_t, bus_size_t, uint64_t *, 121 bus_size_t); 122void au_wired_rr_1(void *, bus_space_handle_t, bus_size_t, uint8_t *, 123 bus_size_t); 124void au_wired_rr_2(void *, bus_space_handle_t, bus_size_t, uint16_t *, 125 bus_size_t); 126void au_wired_rr_4(void *, bus_space_handle_t, bus_size_t, uint32_t *, 127 bus_size_t); 128void au_wired_rr_8(void *, bus_space_handle_t, bus_size_t, uint64_t *, 129 bus_size_t); 130void au_wired_w_1(void *, bus_space_handle_t, bus_size_t, uint8_t); 131void au_wired_w_2(void *, bus_space_handle_t, bus_size_t, uint16_t); 132void au_wired_w_4(void *, bus_space_handle_t, bus_size_t, uint32_t); 133void au_wired_w_8(void *, bus_space_handle_t, bus_size_t, uint64_t); 134void au_wired_wm_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *, 135 bus_size_t); 136void au_wired_wm_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *, 137 bus_size_t); 138void au_wired_wm_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *, 139 bus_size_t); 140void au_wired_wm_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *, 141 bus_size_t); 142void au_wired_wr_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *, 143 bus_size_t); 144void au_wired_wr_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *, 145 bus_size_t); 146void au_wired_wr_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *, 147 bus_size_t); 148void au_wired_wr_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *, 149 bus_size_t); 150void au_wired_sm_1(void *, bus_space_handle_t, bus_size_t, uint8_t, 151 bus_size_t); 152void au_wired_sm_2(void *, bus_space_handle_t, bus_size_t, uint16_t, 153 bus_size_t); 154void au_wired_sm_4(void *, bus_space_handle_t, bus_size_t, uint32_t, 155 bus_size_t); 156void au_wired_sm_8(void *, bus_space_handle_t, bus_size_t, uint64_t, 157 bus_size_t); 158void au_wired_sr_1(void *, bus_space_handle_t, bus_size_t, uint8_t, 159 bus_size_t); 160void au_wired_sr_2(void *, bus_space_handle_t, bus_size_t, uint16_t, 161 bus_size_t); 162void au_wired_sr_4(void *, bus_space_handle_t, bus_size_t, uint32_t, 163 bus_size_t); 164void au_wired_sr_8(void *, bus_space_handle_t, bus_size_t, uint64_t, 165 bus_size_t); 166void au_wired_c_1(void *, bus_space_handle_t, bus_size_t, 167 bus_space_handle_t, bus_size_t, bus_size_t); 168void au_wired_c_2(void *, bus_space_handle_t, bus_size_t, 169 bus_space_handle_t, bus_size_t, bus_size_t); 170void au_wired_c_4(void *, bus_space_handle_t, bus_size_t, 171 bus_space_handle_t, bus_size_t, bus_size_t); 172void au_wired_c_8(void *, bus_space_handle_t, bus_size_t, 173 bus_space_handle_t, bus_size_t, bus_size_t); 174uint16_t au_wired_rs_2(void *, bus_space_handle_t, bus_size_t); 175uint32_t au_wired_rs_4(void *, bus_space_handle_t, bus_size_t); 176uint64_t au_wired_rs_8(void *, bus_space_handle_t, bus_size_t); 177void au_wired_ws_2(void *, bus_space_handle_t, bus_size_t, uint16_t); 178void au_wired_ws_4(void *, bus_space_handle_t, bus_size_t, uint32_t); 179void au_wired_ws_8(void *, bus_space_handle_t, bus_size_t, uint64_t); 180void au_wired_rms_2(void *, bus_space_handle_t, bus_size_t, uint16_t *, 181 bus_size_t); 182void au_wired_rms_4(void *, bus_space_handle_t, bus_size_t, uint32_t *, 183 bus_size_t); 184void au_wired_rms_8(void *, bus_space_handle_t, bus_size_t, uint64_t *, 185 bus_size_t); 186void au_wired_rrs_2(void *, bus_space_handle_t, bus_size_t, uint16_t *, 187 bus_size_t); 188void au_wired_rrs_4(void *, bus_space_handle_t, bus_size_t, uint32_t *, 189 bus_size_t); 190void au_wired_rrs_8(void *, bus_space_handle_t, bus_size_t, uint64_t *, 191 bus_size_t); 192void au_wired_wms_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *, 193 bus_size_t); 194void au_wired_wms_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *, 195 bus_size_t); 196void au_wired_wms_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *, 197 bus_size_t); 198void au_wired_wrs_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *, 199 bus_size_t); 200void au_wired_wrs_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *, 201 bus_size_t); 202void au_wired_wrs_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *, 203 bus_size_t); 204 205int 206au_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 237void 238au_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 247int 248au_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 256void * 257au_wired_vaddr(void *cookie, bus_space_handle_t bsh) 258{ 259 260 return ((void *)bsh); 261} 262 263paddr_t 264au_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 278int 279au_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 309void 310au_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 317inline void 318au_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 326inline uint8_t 327au_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 333inline uint16_t 334au_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 342inline uint32_t 343au_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 351inline uint64_t 352au_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 360inline void 361au_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 367inline void 368au_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 375inline void 376au_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 383inline void 384au_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 391inline uint16_t 392au_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 400inline uint32_t 401au_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 409inline uint64_t 410au_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 418inline void 419au_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 426inline void 427au_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 434inline void 435au_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) \ 443void \ 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} 451AU_WIRED_RM(uint8_t,1) 452AU_WIRED_RM(uint16_t,2) 453AU_WIRED_RM(uint32_t,4) 454AU_WIRED_RM(uint64_t,8) 455 456#define AU_WIRED_RMS(TYPE,BYTES) \ 457void \ 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} 467AU_WIRED_RMS(uint16_t,2) 468AU_WIRED_RMS(uint32_t,4) 469AU_WIRED_RMS(uint64_t,8) 470 471#define AU_WIRED_RR(TYPE,BYTES) \ 472void \ 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} 482AU_WIRED_RR(uint8_t,1) 483AU_WIRED_RR(uint16_t,2) 484AU_WIRED_RR(uint32_t,4) 485AU_WIRED_RR(uint64_t,8) 486 487#define AU_WIRED_RRS(TYPE,BYTES) \ 488void \ 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} 498AU_WIRED_RRS(uint16_t,2) 499AU_WIRED_RRS(uint32_t,4) 500AU_WIRED_RRS(uint64_t,8) 501 502#define AU_WIRED_WM(TYPE,BYTES) \ 503void \ 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} 514AU_WIRED_WM(uint8_t,1) 515AU_WIRED_WM(uint16_t,2) 516AU_WIRED_WM(uint32_t,4) 517AU_WIRED_WM(uint64_t,8) 518 519#define AU_WIRED_WMS(TYPE,BYTES) \ 520void \ 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} 531AU_WIRED_WMS(uint16_t,2) 532AU_WIRED_WMS(uint32_t,4) 533AU_WIRED_WMS(uint64_t,8) 534 535#define AU_WIRED_WR(TYPE,BYTES) \ 536void \ 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} 547AU_WIRED_WR(uint8_t,1) 548AU_WIRED_WR(uint16_t,2) 549AU_WIRED_WR(uint32_t,4) 550AU_WIRED_WR(uint64_t,8) 551 552#define AU_WIRED_WRS(TYPE,BYTES) \ 553void \ 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} 564AU_WIRED_WRS(uint16_t,2) 565AU_WIRED_WRS(uint32_t,4) 566AU_WIRED_WRS(uint64_t,8) 567 568#define AU_WIRED_SM(TYPE,BYTES) \ 569void \ 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} 580AU_WIRED_SM(uint8_t,1) 581AU_WIRED_SM(uint16_t,2) 582AU_WIRED_SM(uint32_t,4) 583AU_WIRED_SM(uint64_t,8) 584 585#define AU_WIRED_SR(TYPE,BYTES) \ 586void \ 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} 597AU_WIRED_SR(uint8_t,1) 598AU_WIRED_SR(uint16_t,2) 599AU_WIRED_SR(uint32_t,4) 600AU_WIRED_SR(uint64_t,8) 601 602 603#define AU_WIRED_C(TYPE,BYTES) \ 604void \ 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} 623AU_WIRED_C(uint8_t,1) 624AU_WIRED_C(uint16_t,2) 625AU_WIRED_C(uint32_t,4) 626AU_WIRED_C(uint64_t,8) 627 628 629void 630au_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