1 /* $NetBSD: bus_space_alignstride_chipdep.c,v 1.12 2009/12/15 06:07:14 rmind 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 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1995, 1996 Carnegie-Mellon University. 35 * All rights reserved. 36 * 37 * Author: Chris G. Demetriou 38 * 39 * Permission to use, copy, modify and distribute this software and 40 * its documentation is hereby granted, provided that both the copyright 41 * notice and this permission notice appear in all copies of the 42 * software, derivative works or modified versions, and any portions 43 * thereof, and that both notices appear in supporting documentation. 44 * 45 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 46 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 47 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 48 * 49 * Carnegie Mellon requests users of this software to return to 50 * 51 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 52 * School of Computer Science 53 * Carnegie Mellon University 54 * Pittsburgh PA 15213-3890 55 * 56 * any improvements or extensions that they make and grant Carnegie the 57 * rights to redistribute these changes. 58 */ 59 60 /* 61 * Common Chipset "bus I/O" functions. 62 * 63 * uses: 64 * CHIP name of the 'chip' it's being compiled for. 65 * CHIP_BASE memory or I/O space base to use. 66 * CHIP_EX_STORE 67 * If defined, device-provided static storage area 68 * for the memory or I/O space extent. If this is 69 * defined, CHIP_EX_STORE_SIZE must also be defined. 70 * If this is not defined, a static area will be 71 * declared. 72 * CHIP_EX_STORE_SIZE 73 * Size of the device-provided static storage area 74 * for the memory or I/O memory space extent. 75 * CHIP_LITTLE_ENDIAN | CHIP_BIG_ENDIAN 76 * For endian-specific busses, like PCI (little). 77 * CHIP_ACCESS_SIZE 78 * Size (in bytes) of minimum bus access, e.g. 4 79 * to indicate all bus cycles are 32-bits. Defaults 80 * to 1, indicating any access size is valid. 81 */ 82 83 #include <sys/cdefs.h> 84 __KERNEL_RCSID(0, "$NetBSD: bus_space_alignstride_chipdep.c,v 1.12 2009/12/15 06:07:14 rmind Exp $"); 85 86 #ifdef CHIP_EXTENT 87 #include <sys/extent.h> 88 #endif 89 #include <sys/malloc.h> 90 91 #include <machine/locore.h> 92 93 #include <uvm/uvm_extern.h> 94 95 #define __C(A,B) __CONCAT(A,B) 96 #define __S(S) __STRING(S) 97 98 #ifdef CHIP_IO 99 #define __BS(A) __C(__C(CHIP,_bus_io_),A) 100 #endif 101 #ifdef CHIP_MEM 102 #define __BS(A) __C(__C(CHIP,_bus_mem_),A) 103 #endif 104 105 #if defined(CHIP_LITTLE_ENDIAN) 106 #define CHIP_SWAP16(x) le16toh(x) 107 #define CHIP_SWAP32(x) le32toh(x) 108 #define CHIP_SWAP64(x) le64toh(x) 109 #define CHIP_NEED_STREAM 1 110 #elif defined(CHIP_BIG_ENDIAN) 111 #define CHIP_SWAP16(x) be16toh(x) 112 #define CHIP_SWAP32(x) be32toh(x) 113 #define CHIP_SWAP64(x) be64toh(x) 114 #define CHIP_NEED_STREAM 1 115 #else 116 #define CHIP_SWAP16(x) (x) 117 #define CHIP_SWAP32(x) (x) 118 #define CHIP_SWAP64(x) (x) 119 #endif 120 121 #ifndef CHIP_ACCESS_SIZE 122 #define CHIP_ACCESS_SIZE 1 123 #endif 124 125 #if CHIP_ACCESS_SIZE==1 126 # define CHIP_SWAP_ACCESS(x) (x) 127 #elif CHIP_ACCESS_SIZE==2 128 # define CHIP_SWAP_ACCESS(x) CHIP_SWAP16(x) 129 #elif CHIP_ACCESS_SIZE==4 130 # define CHIP_SWAP_ACCESS(x) CHIP_SWAP32(x) 131 #elif CHIP_ACCESS_SIZE==8 132 # define CHIP_SWAP_ACCESS(x) CHIP_SWAP64(x) 133 #else 134 # error your access size not implemented 135 #endif 136 137 /* 138 * The logic here determines a few macros to support requirements for 139 * whole-word accesses: 140 * 141 * CHIP_TYPE is a uintXX_t that represents the native access type for the bus. 142 * 143 * CHIP_SHIFTXX is the number of bits to shift a big-endian value to convert 144 * convert between the CHIP_TYPE and uintXX_t. 145 * 146 * The idea is that if we want to do a 16bit load from a bus that only 147 * supports 32-bit accesses, we will access the first 16 bits of the 148 * addressed 32-bit word. 149 * 150 * Obviously (hopefully) this method is inadequate to support addressing the 151 * second half of a 16-bit word, or the upper 3/4 of a 32-bit value, etc. 152 * In other words, the drivers should probably not be relying on this! 153 * 154 * We should probably come back in here some day and handle offsets properly. 155 * to do that, we need to mask off the low order bits of the address, and 156 * then figure out which bits they correspond to. 157 * 158 * If we have fixed access size limitations, we need to make sure that 159 * handle shifting required for big-endian storage. The reality is 160 * that if the bus only supports size "n", then drivers should 161 * probably only access it using "n" sized (or bigger) accesses. 162 */ 163 164 #if CHIP_ACCESS_SIZE == 1 165 #define CHIP_TYPE uint8_t 166 #endif 167 168 #if CHIP_ACCESS_SIZE == 2 169 #define CHIP_TYPE uint16_t 170 #endif 171 172 #if CHIP_ACCESS_SIZE == 4 173 #define CHIP_TYPE uint32_t 174 #endif 175 176 #if CHIP_ACCESS_SIZE == 8 177 #define CHIP_TYPE uint64_t 178 #endif 179 180 #ifndef CHIP_TYPE 181 #error "Invalid chip access size!" 182 #endif 183 184 /* mapping/unmapping */ 185 int __BS(map)(void *, bus_addr_t, bus_size_t, int, 186 bus_space_handle_t *, int); 187 void __BS(unmap)(void *, bus_space_handle_t, bus_size_t, int); 188 int __BS(subregion)(void *, bus_space_handle_t, bus_size_t, 189 bus_size_t, bus_space_handle_t *); 190 191 int __BS(translate)(void *, bus_addr_t, bus_size_t, int, 192 struct mips_bus_space_translation *); 193 int __BS(get_window)(void *, int, 194 struct mips_bus_space_translation *); 195 196 /* allocation/deallocation */ 197 int __BS(alloc)(void *, bus_addr_t, bus_addr_t, bus_size_t, 198 bus_size_t, bus_addr_t, int, bus_addr_t *, 199 bus_space_handle_t *); 200 void __BS(free)(void *, bus_space_handle_t, bus_size_t); 201 202 /* get kernel virtual address */ 203 void * __BS(vaddr)(void *, bus_space_handle_t); 204 205 /* mmap for user */ 206 paddr_t __BS(mmap)(void *, bus_addr_t, off_t, int, int); 207 208 /* barrier */ 209 inline void __BS(barrier)(void *, bus_space_handle_t, bus_size_t, 210 bus_size_t, int); 211 212 /* read (single) */ 213 inline uint8_t __BS(read_1)(void *, bus_space_handle_t, bus_size_t); 214 inline uint16_t __BS(read_2)(void *, bus_space_handle_t, bus_size_t); 215 inline uint32_t __BS(read_4)(void *, bus_space_handle_t, bus_size_t); 216 inline uint64_t __BS(read_8)(void *, bus_space_handle_t, bus_size_t); 217 218 /* read multiple */ 219 void __BS(read_multi_1)(void *, bus_space_handle_t, bus_size_t, 220 uint8_t *, bus_size_t); 221 void __BS(read_multi_2)(void *, bus_space_handle_t, bus_size_t, 222 uint16_t *, bus_size_t); 223 void __BS(read_multi_4)(void *, bus_space_handle_t, bus_size_t, 224 uint32_t *, bus_size_t); 225 void __BS(read_multi_8)(void *, bus_space_handle_t, bus_size_t, 226 uint64_t *, bus_size_t); 227 228 /* read region */ 229 void __BS(read_region_1)(void *, bus_space_handle_t, bus_size_t, 230 uint8_t *, bus_size_t); 231 void __BS(read_region_2)(void *, bus_space_handle_t, bus_size_t, 232 uint16_t *, bus_size_t); 233 void __BS(read_region_4)(void *, bus_space_handle_t, bus_size_t, 234 uint32_t *, bus_size_t); 235 void __BS(read_region_8)(void *, bus_space_handle_t, bus_size_t, 236 uint64_t *, bus_size_t); 237 238 /* write (single) */ 239 inline void __BS(write_1)(void *, bus_space_handle_t, bus_size_t, uint8_t); 240 inline void __BS(write_2)(void *, bus_space_handle_t, bus_size_t, uint16_t); 241 inline void __BS(write_4)(void *, bus_space_handle_t, bus_size_t, uint32_t); 242 inline void __BS(write_8)(void *, bus_space_handle_t, bus_size_t, uint64_t); 243 244 /* write multiple */ 245 void __BS(write_multi_1)(void *, bus_space_handle_t, bus_size_t, 246 const uint8_t *, bus_size_t); 247 void __BS(write_multi_2)(void *, bus_space_handle_t, bus_size_t, 248 const uint16_t *, bus_size_t); 249 void __BS(write_multi_4)(void *, bus_space_handle_t, bus_size_t, 250 const uint32_t *, bus_size_t); 251 void __BS(write_multi_8)(void *, bus_space_handle_t, bus_size_t, 252 const uint64_t *, bus_size_t); 253 254 /* write region */ 255 void __BS(write_region_1)(void *, bus_space_handle_t, bus_size_t, 256 const uint8_t *, bus_size_t); 257 void __BS(write_region_2)(void *, bus_space_handle_t, bus_size_t, 258 const uint16_t *, bus_size_t); 259 void __BS(write_region_4)(void *, bus_space_handle_t, bus_size_t, 260 const uint32_t *, bus_size_t); 261 void __BS(write_region_8)(void *, bus_space_handle_t, bus_size_t, 262 const uint64_t *, bus_size_t); 263 264 /* set multiple */ 265 void __BS(set_multi_1)(void *, bus_space_handle_t, bus_size_t, 266 uint8_t, bus_size_t); 267 void __BS(set_multi_2)(void *, bus_space_handle_t, bus_size_t, 268 uint16_t, bus_size_t); 269 void __BS(set_multi_4)(void *, bus_space_handle_t, bus_size_t, 270 uint32_t, bus_size_t); 271 void __BS(set_multi_8)(void *, bus_space_handle_t, bus_size_t, 272 uint64_t, bus_size_t); 273 274 /* set region */ 275 void __BS(set_region_1)(void *, bus_space_handle_t, bus_size_t, 276 uint8_t, bus_size_t); 277 void __BS(set_region_2)(void *, bus_space_handle_t, bus_size_t, 278 uint16_t, bus_size_t); 279 void __BS(set_region_4)(void *, bus_space_handle_t, bus_size_t, 280 uint32_t, bus_size_t); 281 void __BS(set_region_8)(void *, bus_space_handle_t, bus_size_t, 282 uint64_t, bus_size_t); 283 284 /* copy */ 285 void __BS(copy_region_1)(void *, bus_space_handle_t, bus_size_t, 286 bus_space_handle_t, bus_size_t, bus_size_t); 287 void __BS(copy_region_2)(void *, bus_space_handle_t, bus_size_t, 288 bus_space_handle_t, bus_size_t, bus_size_t); 289 void __BS(copy_region_4)(void *, bus_space_handle_t, bus_size_t, 290 bus_space_handle_t, bus_size_t, bus_size_t); 291 void __BS(copy_region_8)(void *, bus_space_handle_t, bus_size_t, 292 bus_space_handle_t, bus_size_t, bus_size_t); 293 294 #ifdef CHIP_NEED_STREAM 295 296 /* read (single), stream */ 297 inline uint8_t __BS(read_stream_1)(void *, bus_space_handle_t, bus_size_t); 298 inline uint16_t __BS(read_stream_2)(void *, bus_space_handle_t, bus_size_t); 299 inline uint32_t __BS(read_stream_4)(void *, bus_space_handle_t, bus_size_t); 300 inline uint64_t __BS(read_stream_8)(void *, bus_space_handle_t, bus_size_t); 301 302 /* read multiple, stream */ 303 void __BS(read_multi_stream_1)(void *, bus_space_handle_t, bus_size_t, 304 uint8_t *, bus_size_t); 305 void __BS(read_multi_stream_2)(void *, bus_space_handle_t, bus_size_t, 306 uint16_t *, bus_size_t); 307 void __BS(read_multi_stream_4)(void *, bus_space_handle_t, bus_size_t, 308 uint32_t *, bus_size_t); 309 void __BS(read_multi_stream_8)(void *, bus_space_handle_t, bus_size_t, 310 uint64_t *, bus_size_t); 311 312 /* read region, stream */ 313 void __BS(read_region_stream_1)(void *, bus_space_handle_t, bus_size_t, 314 uint8_t *, bus_size_t); 315 void __BS(read_region_stream_2)(void *, bus_space_handle_t, bus_size_t, 316 uint16_t *, bus_size_t); 317 void __BS(read_region_stream_4)(void *, bus_space_handle_t, bus_size_t, 318 uint32_t *, bus_size_t); 319 void __BS(read_region_stream_8)(void *, bus_space_handle_t, bus_size_t, 320 uint64_t *, bus_size_t); 321 322 /* write (single), stream */ 323 inline void __BS(write_stream_1)(void *, bus_space_handle_t, bus_size_t, uint8_t); 324 inline void __BS(write_stream_2)(void *, bus_space_handle_t, bus_size_t, uint16_t); 325 inline void __BS(write_stream_4)(void *, bus_space_handle_t, bus_size_t, uint32_t); 326 inline void __BS(write_stream_8)(void *, bus_space_handle_t, bus_size_t, uint64_t); 327 328 /* write multiple, stream */ 329 void __BS(write_multi_stream_1)(void *, bus_space_handle_t, bus_size_t, 330 const uint8_t *, bus_size_t); 331 void __BS(write_multi_stream_2)(void *, bus_space_handle_t, bus_size_t, 332 const uint16_t *, bus_size_t); 333 void __BS(write_multi_stream_4)(void *, bus_space_handle_t, bus_size_t, 334 const uint32_t *, bus_size_t); 335 void __BS(write_multi_stream_8)(void *, bus_space_handle_t, bus_size_t, 336 const uint64_t *, bus_size_t); 337 338 /* write region, stream */ 339 void __BS(write_region_stream_1)(void *, bus_space_handle_t, bus_size_t, 340 const uint8_t *, bus_size_t); 341 void __BS(write_region_stream_2)(void *, bus_space_handle_t, bus_size_t, 342 const uint16_t *, bus_size_t); 343 void __BS(write_region_stream_4)(void *, bus_space_handle_t, bus_size_t, 344 const uint32_t *, bus_size_t); 345 void __BS(write_region_stream_8)(void *, bus_space_handle_t, bus_size_t, 346 const uint64_t *, bus_size_t); 347 348 #endif /* CHIP_NEED_STREAM */ 349 350 #ifdef CHIP_EXTENT 351 #ifndef CHIP_EX_STORE 352 static long 353 __BS(ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 354 #define CHIP_EX_STORE(v) (__BS(ex_storage)) 355 #define CHIP_EX_STORE_SIZE(v) (sizeof __BS(ex_storage)) 356 #endif 357 #endif /* CHIP_EXTENT */ 358 359 #ifndef CHIP_ALIGN_STRIDE 360 #define CHIP_ALIGN_STRIDE 0 361 #endif 362 363 #if CHIP_ALIGN_STRIDE > 0 364 #define CHIP_OFF8(o) ((o) << (CHIP_ALIGN_STRIDE)) 365 #else 366 #define CHIP_OFF8(o) (o) 367 #endif 368 369 #if CHIP_ALIGN_STRIDE > 1 370 #define CHIP_OFF16(o) ((o) << (CHIP_ALIGN_STRIDE - 1)) 371 #else 372 #define CHIP_OFF16(o) (o) 373 #endif 374 375 #if CHIP_ALIGN_STRIDE > 2 376 #define CHIP_OFF32(o) ((o) << (CHIP_ALIGN_STRIDE - 2)) 377 #else 378 #define CHIP_OFF32(o) (o) 379 #endif 380 381 #if CHIP_ALIGN_STRIDE > 3 382 #define CHIP_OFF64(o) ((o) << (CHIP_ALIGN_STRIDE - 3)) 383 #else 384 #define CHIP_OFF64(o) (o) 385 #endif 386 387 388 void 389 __BS(init)(bus_space_tag_t t, void *v) 390 { 391 #ifdef CHIP_EXTENT 392 struct extent *ex; 393 #endif 394 395 /* 396 * Initialize the bus space tag. 397 */ 398 399 /* cookie */ 400 t->bs_cookie = v; 401 402 /* mapping/unmapping */ 403 t->bs_map = __BS(map); 404 t->bs_unmap = __BS(unmap); 405 t->bs_subregion = __BS(subregion); 406 407 t->bs_translate = __BS(translate); 408 t->bs_get_window = __BS(get_window); 409 410 /* allocation/deallocation */ 411 t->bs_alloc = __BS(alloc); 412 t->bs_free = __BS(free); 413 414 /* get kernel virtual address */ 415 t->bs_vaddr = __BS(vaddr); 416 417 /* mmap for user */ 418 t->bs_mmap = __BS(mmap); 419 420 /* barrier */ 421 t->bs_barrier = __BS(barrier); 422 423 /* read (single) */ 424 t->bs_r_1 = __BS(read_1); 425 t->bs_r_2 = __BS(read_2); 426 t->bs_r_4 = __BS(read_4); 427 t->bs_r_8 = __BS(read_8); 428 429 /* read multiple */ 430 t->bs_rm_1 = __BS(read_multi_1); 431 t->bs_rm_2 = __BS(read_multi_2); 432 t->bs_rm_4 = __BS(read_multi_4); 433 t->bs_rm_8 = __BS(read_multi_8); 434 435 /* read region */ 436 t->bs_rr_1 = __BS(read_region_1); 437 t->bs_rr_2 = __BS(read_region_2); 438 t->bs_rr_4 = __BS(read_region_4); 439 t->bs_rr_8 = __BS(read_region_8); 440 441 /* write (single) */ 442 t->bs_w_1 = __BS(write_1); 443 t->bs_w_2 = __BS(write_2); 444 t->bs_w_4 = __BS(write_4); 445 t->bs_w_8 = __BS(write_8); 446 447 /* write multiple */ 448 t->bs_wm_1 = __BS(write_multi_1); 449 t->bs_wm_2 = __BS(write_multi_2); 450 t->bs_wm_4 = __BS(write_multi_4); 451 t->bs_wm_8 = __BS(write_multi_8); 452 453 /* write region */ 454 t->bs_wr_1 = __BS(write_region_1); 455 t->bs_wr_2 = __BS(write_region_2); 456 t->bs_wr_4 = __BS(write_region_4); 457 t->bs_wr_8 = __BS(write_region_8); 458 459 /* set multiple */ 460 t->bs_sm_1 = __BS(set_multi_1); 461 t->bs_sm_2 = __BS(set_multi_2); 462 t->bs_sm_4 = __BS(set_multi_4); 463 t->bs_sm_8 = __BS(set_multi_8); 464 465 /* set region */ 466 t->bs_sr_1 = __BS(set_region_1); 467 t->bs_sr_2 = __BS(set_region_2); 468 t->bs_sr_4 = __BS(set_region_4); 469 t->bs_sr_8 = __BS(set_region_8); 470 471 /* copy */ 472 t->bs_c_1 = __BS(copy_region_1); 473 t->bs_c_2 = __BS(copy_region_2); 474 t->bs_c_4 = __BS(copy_region_4); 475 t->bs_c_8 = __BS(copy_region_8); 476 477 #ifdef CHIP_NEED_STREAM 478 /* read (single), stream */ 479 t->bs_rs_1 = __BS(read_stream_1); 480 t->bs_rs_2 = __BS(read_stream_2); 481 t->bs_rs_4 = __BS(read_stream_4); 482 t->bs_rs_8 = __BS(read_stream_8); 483 484 /* read multiple, stream */ 485 t->bs_rms_1 = __BS(read_multi_stream_1); 486 t->bs_rms_2 = __BS(read_multi_stream_2); 487 t->bs_rms_4 = __BS(read_multi_stream_4); 488 t->bs_rms_8 = __BS(read_multi_stream_8); 489 490 /* read region, stream */ 491 t->bs_rrs_1 = __BS(read_region_stream_1); 492 t->bs_rrs_2 = __BS(read_region_stream_2); 493 t->bs_rrs_4 = __BS(read_region_stream_4); 494 t->bs_rrs_8 = __BS(read_region_stream_8); 495 496 /* write (single), stream */ 497 t->bs_ws_1 = __BS(write_stream_1); 498 t->bs_ws_2 = __BS(write_stream_2); 499 t->bs_ws_4 = __BS(write_stream_4); 500 t->bs_ws_8 = __BS(write_stream_8); 501 502 /* write multiple, stream */ 503 t->bs_wms_1 = __BS(write_multi_stream_1); 504 t->bs_wms_2 = __BS(write_multi_stream_2); 505 t->bs_wms_4 = __BS(write_multi_stream_4); 506 t->bs_wms_8 = __BS(write_multi_stream_8); 507 508 /* write region, stream */ 509 t->bs_wrs_1 = __BS(write_region_stream_1); 510 t->bs_wrs_2 = __BS(write_region_stream_2); 511 t->bs_wrs_4 = __BS(write_region_stream_4); 512 t->bs_wrs_8 = __BS(write_region_stream_8); 513 514 #else /* CHIP_NEED_STREAM */ 515 516 /* read (single), stream */ 517 t->bs_rs_1 = __BS(read_1); 518 t->bs_rs_2 = __BS(read_2); 519 t->bs_rs_4 = __BS(read_4); 520 t->bs_rs_8 = __BS(read_8); 521 522 /* read multiple, stream */ 523 t->bs_rms_1 = __BS(read_multi_1); 524 t->bs_rms_2 = __BS(read_multi_2); 525 t->bs_rms_4 = __BS(read_multi_4); 526 t->bs_rms_8 = __BS(read_multi_8); 527 528 /* read region, stream */ 529 t->bs_rrs_1 = __BS(read_region_1); 530 t->bs_rrs_2 = __BS(read_region_2); 531 t->bs_rrs_4 = __BS(read_region_4); 532 t->bs_rrs_8 = __BS(read_region_8); 533 534 /* write (single), stream */ 535 t->bs_ws_1 = __BS(write_1); 536 t->bs_ws_2 = __BS(write_2); 537 t->bs_ws_4 = __BS(write_4); 538 t->bs_ws_8 = __BS(write_8); 539 540 /* write multiple, stream */ 541 t->bs_wms_1 = __BS(write_multi_1); 542 t->bs_wms_2 = __BS(write_multi_2); 543 t->bs_wms_4 = __BS(write_multi_4); 544 t->bs_wms_8 = __BS(write_multi_8); 545 546 /* write region, stream */ 547 t->bs_wrs_1 = __BS(write_region_1); 548 t->bs_wrs_2 = __BS(write_region_2); 549 t->bs_wrs_4 = __BS(write_region_4); 550 t->bs_wrs_8 = __BS(write_region_8); 551 #endif /* CHIP_NEED_STREAM */ 552 553 #ifdef CHIP_EXTENT 554 /* XXX WE WANT EXTENT_NOCOALESCE, BUT WE CAN'T USE IT. XXX */ 555 ex = extent_create(__S(__BS(bus)), 0x0UL, ~0UL, M_DEVBUF, 556 (void *)CHIP_EX_STORE(v), CHIP_EX_STORE_SIZE(v), EX_NOWAIT); 557 extent_alloc_region(ex, 0, ~0UL, EX_NOWAIT); 558 559 #ifdef CHIP_W1_BUS_START 560 /* 561 * The window may be disabled. We notice this by seeing 562 * -1 as the bus base address. 563 */ 564 if (CHIP_W1_BUS_START(v) == (bus_addr_t) -1) { 565 #ifdef EXTENT_DEBUG 566 printf("%s: this space is disabled\n", __S(__BS(init))); 567 #endif 568 return; 569 } 570 571 #ifdef EXTENT_DEBUG 572 printf("%s: freeing from %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n", 573 __S(__BS(init)), (bus_addr_t)CHIP_W1_BUS_START(v), 574 (bus_addr_t)CHIP_W1_BUS_END(v)); 575 #endif 576 extent_free(ex, CHIP_W1_BUS_START(v), 577 CHIP_W1_BUS_END(v) - CHIP_W1_BUS_START(v) + 1, EX_NOWAIT); 578 #endif 579 #ifdef CHIP_W2_BUS_START 580 if (CHIP_W2_BUS_START(v) != CHIP_W1_BUS_START(v)) { 581 #ifdef EXTENT_DEBUG 582 printf("xxx: freeing from 0x%lx to 0x%lx\n", 583 (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); 584 #endif 585 extent_free(ex, CHIP_W2_BUS_START(v), 586 CHIP_W2_BUS_END(v) - CHIP_W2_BUS_START(v) + 1, EX_NOWAIT); 587 } else { 588 #ifdef EXTENT_DEBUG 589 printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n", 590 (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); 591 #endif 592 } 593 #endif 594 #ifdef CHIP_W3_BUS_START 595 if (CHIP_W3_BUS_START(v) != CHIP_W1_BUS_START(v) && 596 CHIP_W3_BUS_START(v) != CHIP_W2_BUS_START(v)) { 597 #ifdef EXTENT_DEBUG 598 printf("xxx: freeing from 0x%lx to 0x%lx\n", 599 (u_long)CHIP_W3_BUS_START(v), (u_long)CHIP_W3_BUS_END(v)); 600 #endif 601 extent_free(ex, CHIP_W3_BUS_START(v), 602 CHIP_W3_BUS_END(v) - CHIP_W3_BUS_START(v) + 1, EX_NOWAIT); 603 } else { 604 #ifdef EXTENT_DEBUG 605 printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n", 606 (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); 607 #endif 608 } 609 #endif 610 611 #ifdef EXTENT_DEBUG 612 extent_print(ex); 613 #endif 614 CHIP_EXTENT(v) = ex; 615 #endif /* CHIP_EXTENT */ 616 } 617 618 int 619 __BS(translate)(void *v, bus_addr_t addr, bus_size_t len, int flags, 620 struct mips_bus_space_translation *mbst) 621 { 622 bus_addr_t end = addr + (len - 1); 623 #if CHIP_ALIGN_STRIDE != 0 624 int linear = flags & BUS_SPACE_MAP_LINEAR; 625 626 /* 627 * Can't map xxx space linearly. 628 */ 629 if (linear) 630 return (EOPNOTSUPP); 631 #endif 632 633 #ifdef CHIP_W1_BUS_START 634 if (addr >= CHIP_W1_BUS_START(v) && end <= CHIP_W1_BUS_END(v)) 635 return (__BS(get_window)(v, 0, mbst)); 636 #endif 637 638 #ifdef CHIP_W2_BUS_START 639 if (addr >= CHIP_W2_BUS_START(v) && end <= CHIP_W2_BUS_END(v)) 640 return (__BS(get_window)(v, 1, mbst)); 641 #endif 642 643 #ifdef CHIP_W3_BUS_START 644 if (addr >= CHIP_W3_BUS_START(v) && end <= CHIP_W3_BUS_END(v)) 645 return (__BS(get_window)(v, 2, mbst)); 646 #endif 647 648 #ifdef EXTENT_DEBUG 649 printf("\n"); 650 #ifdef CHIP_W1_BUS_START 651 printf("%s: window[1]=0x%lx-0x%lx\n", __S(__BS(map)), 652 (u_long)CHIP_W1_BUS_START(v), (u_long)CHIP_W1_BUS_END(v)); 653 #endif 654 #ifdef CHIP_W2_BUS_START 655 printf("%s: window[2]=0x%lx-0x%lx\n", __S(__BS(map)), 656 (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); 657 #endif 658 #ifdef CHIP_W3_BUS_START 659 printf("%s: window[3]=0x%lx-0x%lx\n", __S(__BS(map)), 660 (u_long)CHIP_W3_BUS_START(v), (u_long)CHIP_W3_BUS_END(v)); 661 #endif 662 #endif /* EXTENT_DEBUG */ 663 /* No translation. */ 664 return (EINVAL); 665 } 666 667 int 668 __BS(get_window)(void *v, int window, struct mips_bus_space_translation *mbst) 669 { 670 671 switch (window) { 672 #ifdef CHIP_W1_BUS_START 673 case 0: 674 mbst->mbst_bus_start = CHIP_W1_BUS_START(v); 675 mbst->mbst_bus_end = CHIP_W1_BUS_END(v); 676 mbst->mbst_sys_start = CHIP_W1_SYS_START(v); 677 mbst->mbst_sys_end = CHIP_W1_SYS_END(v); 678 mbst->mbst_align_stride = CHIP_ALIGN_STRIDE; 679 mbst->mbst_flags = 0; 680 break; 681 #endif 682 683 #ifdef CHIP_W2_BUS_START 684 case 1: 685 mbst->mbst_bus_start = CHIP_W2_BUS_START(v); 686 mbst->mbst_bus_end = CHIP_W2_BUS_END(v); 687 mbst->mbst_sys_start = CHIP_W2_SYS_START(v); 688 mbst->mbst_sys_end = CHIP_W2_SYS_END(v); 689 mbst->mbst_align_stride = CHIP_ALIGN_STRIDE; 690 mbst->mbst_flags = 0; 691 break; 692 #endif 693 694 #ifdef CHIP_W3_BUS_START 695 case 2: 696 mbst->mbst_bus_start = CHIP_W3_BUS_START(v); 697 mbst->mbst_bus_end = CHIP_W3_BUS_END(v); 698 mbst->mbst_sys_start = CHIP_W3_SYS_START(v); 699 mbst->mbst_sys_end = CHIP_W3_SYS_END(v); 700 mbst->mbst_align_stride = CHIP_ALIGN_STRIDE; 701 mbst->mbst_flags = 0; 702 break; 703 #endif 704 705 default: 706 panic(__S(__BS(get_window)) ": invalid window %d", 707 window); 708 } 709 710 return (0); 711 } 712 713 int 714 __BS(map)(void *v, bus_addr_t addr, bus_size_t size, int flags, 715 bus_space_handle_t *hp, int acct) 716 { 717 struct mips_bus_space_translation mbst; 718 int error; 719 720 /* 721 * Get the translation for this address. 722 */ 723 error = __BS(translate)(v, addr, size, flags, &mbst); 724 if (error) 725 return (error); 726 727 #ifdef CHIP_EXTENT 728 if (acct == 0) 729 goto mapit; 730 731 #ifdef EXTENT_DEBUG 732 printf("%s: allocating %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n", 733 __S(__BS(map)), addr, addr + size - 1); 734 #endif 735 error = extent_alloc_region(CHIP_EXTENT(v), addr, size, 736 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 737 if (error) { 738 #ifdef EXTENT_DEBUG 739 printf("%s: allocation failed (%d)\n", __S(__BS(map)), error); 740 extent_print(CHIP_EXTENT(v)); 741 #endif 742 return (error); 743 } 744 745 mapit: 746 #endif /* CHIP_EXTENT */ 747 748 addr = mbst.mbst_sys_start + (addr - mbst.mbst_bus_start); 749 750 #ifdef _LP64 751 if (flags & BUS_SPACE_MAP_CACHEABLE) 752 *hp = MIPS_PHYS_TO_XKPHYS_CACHED(addr); 753 else 754 *hp = MIPS_PHYS_TO_XKPHYS_UNCACHED(addr); 755 #else 756 if (((addr + size) & ~MIPS_PHYS_MASK) != 0) { 757 vaddr_t va; 758 paddr_t pa; 759 int s; 760 761 size = round_page((addr % PAGE_SIZE) + size); 762 va = uvm_km_alloc(kernel_map, size, PAGE_SIZE, 763 UVM_KMF_VAONLY | UVM_KMF_NOWAIT); 764 if (va == 0) 765 return ENOMEM; 766 767 /* check use of handle_is_kseg2 in BS(unmap) */ 768 KASSERT((va & ~MIPS_PHYS_MASK) == MIPS_KSEG2_START); 769 770 *hp = va + (addr & PAGE_MASK); 771 pa = trunc_page(addr); 772 773 s = splhigh(); 774 while (size != 0) { 775 pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, 0); 776 pa += PAGE_SIZE; 777 va += PAGE_SIZE; 778 size -= PAGE_SIZE; 779 } 780 pmap_update(pmap_kernel()); 781 splx(s); 782 } else { 783 if (flags & BUS_SPACE_MAP_CACHEABLE) 784 *hp = MIPS_PHYS_TO_KSEG0(addr); 785 else 786 *hp = MIPS_PHYS_TO_KSEG1(addr); 787 } 788 #endif 789 790 return (0); 791 } 792 793 void 794 __BS(unmap)(void *v, bus_space_handle_t h, bus_size_t size, int acct) 795 { 796 #if !defined(_LP64) || defined(CHIP_EXTENT) 797 bus_addr_t addr = 0; /* initialize to appease gcc */ 798 #endif 799 #ifndef _LP64 800 bool handle_is_kseg2; 801 802 /* determine if h is addr obtained from uvm_km_alloc */ 803 handle_is_kseg2 = ((h & ~MIPS_PHYS_MASK) == MIPS_KSEG2_START); 804 #if 0 805 printf("%s:%d: is_kseg2 %d\n", __func__, __LINE__, handle_is_kseg2); 806 #endif 807 if (handle_is_kseg2 == true) { 808 paddr_t pa; 809 vaddr_t va = (vaddr_t)trunc_page(h); 810 vsize_t sz = (vsize_t)round_page((h % PAGE_SIZE) + size); 811 int s; 812 813 s = splhigh(); 814 815 if (pmap_extract(pmap_kernel(), (vaddr_t)h, &pa) == false) 816 panic("%s: pmap_extract failed", __func__); 817 addr = (bus_addr_t)pa; 818 #if 0 819 printf("%s:%d: addr %#"PRIxBUSADDR", sz %#"PRIxVSIZE"\n", 820 __func__, __LINE__, addr, sz); 821 #endif 822 /* sanity check: this is why we couldn't map w/ kseg[0,1] */ 823 KASSERT (((addr + sz) & ~MIPS_PHYS_MASK) != 0); 824 825 pmap_kremove(va, sz); 826 pmap_update(pmap_kernel()); 827 uvm_km_free(kernel_map, va, sz, UVM_KMF_VAONLY); 828 829 splx(s); 830 } 831 #endif /* _LP64 */ 832 833 #ifdef CHIP_EXTENT 834 835 if (acct == 0) 836 return; 837 838 #ifdef EXTENT_DEBUG 839 printf("%s: freeing handle %#"PRIxBSH" for %#"PRIxBUSSIZE"\n", 840 __S(__BS(unmap)), h, size); 841 #endif 842 843 #ifdef _LP64 844 KASSERT(MIPS_XKPHYS_P(h)); 845 addr = MIPS_XKPHYS_TO_PHYS(h); 846 #else 847 if (handle_is_kseg2 == false) { 848 if (MIPS_KSEG0_P(h)) 849 addr = MIPS_KSEG0_TO_PHYS(h); 850 else 851 addr = MIPS_KSEG1_TO_PHYS(h); 852 } 853 #endif 854 855 #ifdef CHIP_W1_BUS_START 856 if (addr >= CHIP_W1_SYS_START(v) && addr <= CHIP_W1_SYS_END(v)) { 857 addr = CHIP_W1_BUS_START(v) + (addr - CHIP_W1_SYS_START(v)); 858 } else 859 #endif 860 #ifdef CHIP_W2_BUS_START 861 if (addr >= CHIP_W2_SYS_START(v) && addr <= CHIP_W2_SYS_END(v)) { 862 addr = CHIP_W2_BUS_START(v) + (addr - CHIP_W2_SYS_START(v)); 863 } else 864 #endif 865 #ifdef CHIP_W3_BUS_START 866 if (addr >= CHIP_W3_SYS_START(v) && addr <= CHIP_W3_SYS_END(v)) { 867 addr = CHIP_W3_BUS_START(v) + (addr - CHIP_W3_SYS_START(v)); 868 } else 869 #endif 870 { 871 printf("\n"); 872 #ifdef CHIP_W1_BUS_START 873 printf("%s: sys window[1]=0x%lx-0x%lx\n", 874 __S(__BS(map)), (u_long)CHIP_W1_SYS_START(v), 875 (u_long)CHIP_W1_SYS_END(v)); 876 #endif 877 #ifdef CHIP_W2_BUS_START 878 printf("%s: sys window[2]=0x%lx-0x%lx\n", 879 __S(__BS(map)), (u_long)CHIP_W2_SYS_START(v), 880 (u_long)CHIP_W2_SYS_END(v)); 881 #endif 882 #ifdef CHIP_W3_BUS_START 883 printf("%s: sys window[3]=0x%lx-0x%lx\n", 884 __S(__BS(unmap)), (u_long)CHIP_W3_SYS_START(v), 885 (u_long)CHIP_W3_SYS_END(v)); 886 #endif 887 panic("%s: don't know how to unmap %#"PRIxBSH, __S(__BS(unmap)), h); 888 } 889 890 #ifdef EXTENT_DEBUG 891 printf("%s: freeing %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n", 892 __S(__BS(unmap)), addr, addr + size - 1); 893 #endif 894 int error = extent_free(CHIP_EXTENT(v), addr, size, 895 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 896 if (error) { 897 printf("%s: WARNING: could not unmap" 898 " %#"PRIxBUSADDR"-%#"PRIxBUSADDR" (error %d)\n", 899 __S(__BS(unmap)), addr, addr + size - 1, error); 900 #ifdef EXTENT_DEBUG 901 extent_print(CHIP_EXTENT(v)); 902 #endif 903 } 904 #endif /* CHIP_EXTENT */ 905 } 906 907 int 908 __BS(subregion)(void *v, bus_space_handle_t h, bus_size_t offset, 909 bus_size_t size, bus_space_handle_t *nh) 910 { 911 912 *nh = h + (offset << CHIP_ALIGN_STRIDE); 913 return (0); 914 } 915 916 int 917 __BS(alloc)(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, 918 bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp, 919 bus_space_handle_t *bshp) 920 { 921 #ifdef CHIP_EXTENT 922 struct mips_bus_space_translation mbst; 923 u_long addr; /* bogus but makes extent happy */ 924 int error; 925 #if CHIP_ALIGN_STRIDE != 0 926 int linear = flags & BUS_SPACE_MAP_LINEAR; 927 928 /* 929 * Can't map xxx space linearly. 930 */ 931 if (linear) 932 return (EOPNOTSUPP); 933 #endif 934 935 /* 936 * Do the requested allocation. 937 */ 938 #ifdef EXTENT_DEBUG 939 printf("%s: allocating from %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n", 940 __S(__BS(alloc)), rstart, rend); 941 #endif 942 error = extent_alloc_subregion(CHIP_EXTENT(v), rstart, rend, size, 943 align, boundary, 944 EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0), 945 &addr); 946 if (error) { 947 #ifdef EXTENT_DEBUG 948 printf("%s: allocation failed (%d)\n", __S(__BS(alloc)), error); 949 extent_print(CHIP_EXTENT(v)); 950 #endif 951 return (error); 952 } 953 954 #ifdef EXTENT_DEBUG 955 printf("%s: allocated 0x%lx to %#"PRIxBUSSIZE"\n", 956 __S(__BS(alloc)), addr, addr + size - 1); 957 #endif 958 959 error = __BS(translate)(v, addr, size, flags, &mbst); 960 if (error) { 961 (void) extent_free(CHIP_EXTENT(v), addr, size, 962 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 963 return (error); 964 } 965 966 *addrp = addr; 967 #ifdef _LP64 968 if (flags & BUS_SPACE_MAP_CACHEABLE) 969 *bshp = MIPS_PHYS_TO_XKPHYS_CACHED(mbst.mbst_sys_start + 970 (addr - mbst.mbst_bus_start)); 971 else 972 *bshp = MIPS_PHYS_TO_XKPHYS_UNCACHED(mbst.mbst_sys_start + 973 (addr - mbst.mbst_bus_start)); 974 #else 975 if (flags & BUS_SPACE_MAP_CACHEABLE) 976 *bshp = MIPS_PHYS_TO_KSEG0(mbst.mbst_sys_start + 977 (addr - mbst.mbst_bus_start)); 978 else 979 *bshp = MIPS_PHYS_TO_KSEG1(mbst.mbst_sys_start + 980 (addr - mbst.mbst_bus_start)); 981 #endif 982 983 return (0); 984 #else /* ! CHIP_EXTENT */ 985 return (EOPNOTSUPP); 986 #endif /* CHIP_EXTENT */ 987 } 988 989 void 990 __BS(free)(void *v, bus_space_handle_t bsh, bus_size_t size) 991 { 992 993 /* Unmap does all we need to do. */ 994 __BS(unmap)(v, bsh, size, 1); 995 } 996 997 void * 998 __BS(vaddr)(void *v, bus_space_handle_t bsh) 999 { 1000 1001 #if CHIP_ALIGN_STRIDE != 0 1002 /* Linear mappings not possible. */ 1003 return (NULL); 1004 #else 1005 return ((void *)bsh); 1006 #endif 1007 } 1008 1009 paddr_t 1010 __BS(mmap)(void *v, bus_addr_t addr, off_t off, int prot, int flags) 1011 { 1012 #ifdef CHIP_IO 1013 1014 /* Not supported for I/O space. */ 1015 return (-1); 1016 #elif defined(CHIP_MEM) 1017 struct mips_bus_space_translation mbst; 1018 int error; 1019 1020 /* 1021 * Get the translation for this address. 1022 */ 1023 error = __BS(translate)(v, addr, off + PAGE_SIZE, flags, 1024 &mbst); 1025 if (error) 1026 return (-1); 1027 1028 return (mips_btop(mbst.mbst_sys_start + 1029 (addr - mbst.mbst_bus_start) + off)); 1030 #else 1031 # error must define one of CHIP_IO or CHIP_MEM 1032 #endif 1033 } 1034 1035 inline void 1036 __BS(barrier)(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int f) 1037 { 1038 1039 /* XXX XXX XXX */ 1040 if ((f & BUS_SPACE_BARRIER_WRITE) != 0) 1041 wbflush(); 1042 } 1043 1044 inline uint8_t 1045 __BS(read_1)(void *v, bus_space_handle_t h, bus_size_t off) 1046 { 1047 #if CHIP_ACCESS_SIZE > 1 1048 volatile CHIP_TYPE *ptr; 1049 #else /* CHIP_ACCESS_SIZE > 1 */ 1050 volatile uint8_t *ptr; 1051 #endif /* CHIP_ACCESS_SIZE > 1 */ 1052 uint8_t r; 1053 int shift; 1054 1055 h += CHIP_OFF8(off); 1056 shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8; 1057 ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1))); 1058 r = (uint8_t)(CHIP_SWAP_ACCESS(*ptr) >> shift); 1059 1060 return r; 1061 } 1062 1063 inline uint16_t 1064 __BS(read_2)(void *v, bus_space_handle_t h, bus_size_t off) 1065 { 1066 #if CHIP_ACCESS_SIZE > 2 1067 volatile CHIP_TYPE *ptr; 1068 #else /* CHIP_ACCESS_SIZE > 2 */ 1069 volatile uint16_t *ptr; 1070 #endif /* CHIP_ACCESS_SIZE > 2 */ 1071 uint16_t r; 1072 int shift; 1073 1074 KASSERT((off & 1) == 0); 1075 h += CHIP_OFF16(off); 1076 shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8; 1077 ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1))); 1078 r = (uint16_t)CHIP_SWAP16(*ptr >> shift); 1079 1080 return r; 1081 } 1082 1083 inline uint32_t 1084 __BS(read_4)(void *v, bus_space_handle_t h, bus_size_t off) 1085 { 1086 #if CHIP_ACCESS_SIZE > 4 1087 volatile CHIP_TYPE *ptr; 1088 #else /* CHIP_ACCESS_SIZE > 4 */ 1089 volatile uint32_t *ptr; 1090 #endif 1091 uint32_t r; 1092 int shift; 1093 1094 KASSERT((off & 3) == 0); 1095 h += CHIP_OFF32(off); 1096 shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8; 1097 ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1))); 1098 r = (uint32_t)CHIP_SWAP32(*ptr >> shift); 1099 1100 return r; 1101 } 1102 1103 inline uint64_t 1104 __BS(read_8)(void *v, bus_space_handle_t h, bus_size_t off) 1105 { 1106 volatile uint64_t *ptr; 1107 volatile uint64_t r; 1108 int shift; 1109 1110 KASSERT((off & 7) == 0); 1111 h += CHIP_OFF64(off); 1112 shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8; 1113 ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1))); 1114 r = CHIP_SWAP64(*ptr >> shift); 1115 1116 return r; 1117 } 1118 1119 1120 #define CHIP_read_multi_N(BYTES,TYPE) \ 1121 void \ 1122 __C(__BS(read_multi_),BYTES)(void *v, bus_space_handle_t h, \ 1123 bus_size_t o, TYPE *a, bus_size_t c) \ 1124 { \ 1125 \ 1126 while (c-- > 0) { \ 1127 __BS(barrier)(v, h, o, sizeof *a, \ 1128 BUS_SPACE_BARRIER_READ); \ 1129 *a++ = __C(__BS(read_),BYTES)(v, h, o); \ 1130 } \ 1131 } 1132 CHIP_read_multi_N(1,uint8_t) 1133 CHIP_read_multi_N(2,uint16_t) 1134 CHIP_read_multi_N(4,uint32_t) 1135 CHIP_read_multi_N(8,uint64_t) 1136 1137 #define CHIP_read_region_N(BYTES,TYPE) \ 1138 void \ 1139 __C(__BS(read_region_),BYTES)(void *v, bus_space_handle_t h, \ 1140 bus_size_t o, TYPE *a, bus_size_t c) \ 1141 { \ 1142 \ 1143 while (c-- > 0) { \ 1144 *a++ = __C(__BS(read_),BYTES)(v, h, o); \ 1145 o += sizeof *a; \ 1146 } \ 1147 } 1148 CHIP_read_region_N(1,uint8_t) 1149 CHIP_read_region_N(2,uint16_t) 1150 CHIP_read_region_N(4,uint32_t) 1151 CHIP_read_region_N(8,uint64_t) 1152 1153 1154 inline void 1155 __BS(write_1)(void *v, bus_space_handle_t h, bus_size_t off, uint8_t val) 1156 { 1157 #if CHIP_ACCESS_SIZE > 1 1158 volatile CHIP_TYPE *ptr; 1159 #else /* CHIP_ACCESS_SIZE > 1 */ 1160 volatile uint8_t *ptr; 1161 #endif /* CHIP_ACCESS_SIZE > 1 */ 1162 int shift; 1163 1164 h += CHIP_OFF8(off); 1165 shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8; 1166 ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1))); 1167 *ptr = CHIP_SWAP_ACCESS(((CHIP_TYPE)val) << shift); 1168 } 1169 1170 inline void 1171 __BS(write_2)(void *v, bus_space_handle_t h, bus_size_t off, uint16_t val) 1172 { 1173 #if CHIP_ACCESS_SIZE > 2 1174 volatile CHIP_TYPE *ptr; 1175 #else /* CHIP_ACCESS_SIZE > 2 */ 1176 volatile uint16_t *ptr; 1177 #endif /* CHIP_ACCESS_SIZE > 2 */ 1178 int shift; 1179 1180 KASSERT((off & 1) == 0); 1181 h += CHIP_OFF16(off); 1182 shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8; 1183 ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1))); 1184 if (CHIP_ACCESS_SIZE > 2) 1185 *ptr = (CHIP_TYPE)(CHIP_SWAP16(val)) << shift; 1186 else 1187 *ptr = CHIP_SWAP16(val); 1188 } 1189 1190 inline void 1191 __BS(write_4)(void *v, bus_space_handle_t h, bus_size_t off, uint32_t val) 1192 { 1193 #if CHIP_ACCESS_SIZE > 4 1194 volatile CHIP_TYPE *ptr; 1195 #else /* CHIP_ACCESS_SIZE > 4 */ 1196 volatile uint32_t *ptr; 1197 #endif /* CHIP_ACCESS_SIZE > 4 */ 1198 int shift; 1199 1200 KASSERT((off & 3) == 0); 1201 h += CHIP_OFF32(off); 1202 shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8; 1203 ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1))); 1204 if (CHIP_ACCESS_SIZE > 4) 1205 *ptr = (CHIP_TYPE)(CHIP_SWAP32(val)) << shift; 1206 else 1207 *ptr = CHIP_SWAP32(val); 1208 } 1209 1210 inline void 1211 __BS(write_8)(void *v, bus_space_handle_t h, bus_size_t off, uint64_t val) 1212 { 1213 volatile uint64_t *ptr; 1214 int shift; 1215 1216 KASSERT((off & 7) == 0); 1217 h += CHIP_OFF64(off); 1218 shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8; 1219 ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1))); 1220 *ptr = CHIP_SWAP64(val) << shift; 1221 } 1222 1223 #define CHIP_write_multi_N(BYTES,TYPE) \ 1224 void \ 1225 __C(__BS(write_multi_),BYTES)(void *v, bus_space_handle_t h, \ 1226 bus_size_t o, const TYPE *a, bus_size_t c) \ 1227 { \ 1228 \ 1229 while (c-- > 0) { \ 1230 __C(__BS(write_),BYTES)(v, h, o, *a++); \ 1231 __BS(barrier)(v, h, o, sizeof *a, \ 1232 BUS_SPACE_BARRIER_WRITE); \ 1233 } \ 1234 } 1235 CHIP_write_multi_N(1,uint8_t) 1236 CHIP_write_multi_N(2,uint16_t) 1237 CHIP_write_multi_N(4,uint32_t) 1238 CHIP_write_multi_N(8,uint64_t) 1239 1240 #define CHIP_write_region_N(BYTES,TYPE) \ 1241 void \ 1242 __C(__BS(write_region_),BYTES)(void *v, bus_space_handle_t h, \ 1243 bus_size_t o, const TYPE *a, bus_size_t c) \ 1244 { \ 1245 \ 1246 while (c-- > 0) { \ 1247 __C(__BS(write_),BYTES)(v, h, o, *a++); \ 1248 o += sizeof *a; \ 1249 } \ 1250 } 1251 CHIP_write_region_N(1,uint8_t) 1252 CHIP_write_region_N(2,uint16_t) 1253 CHIP_write_region_N(4,uint32_t) 1254 CHIP_write_region_N(8,uint64_t) 1255 1256 #define CHIP_set_multi_N(BYTES,TYPE) \ 1257 void \ 1258 __C(__BS(set_multi_),BYTES)(void *v, bus_space_handle_t h, \ 1259 bus_size_t o, TYPE val, bus_size_t c) \ 1260 { \ 1261 \ 1262 while (c-- > 0) { \ 1263 __C(__BS(write_),BYTES)(v, h, o, val); \ 1264 __BS(barrier)(v, h, o, sizeof val, \ 1265 BUS_SPACE_BARRIER_WRITE); \ 1266 } \ 1267 } 1268 CHIP_set_multi_N(1,uint8_t) 1269 CHIP_set_multi_N(2,uint16_t) 1270 CHIP_set_multi_N(4,uint32_t) 1271 CHIP_set_multi_N(8,uint64_t) 1272 1273 #define CHIP_set_region_N(BYTES,TYPE) \ 1274 void \ 1275 __C(__BS(set_region_),BYTES)(void *v, bus_space_handle_t h, \ 1276 bus_size_t o, TYPE val, bus_size_t c) \ 1277 { \ 1278 \ 1279 while (c-- > 0) { \ 1280 __C(__BS(write_),BYTES)(v, h, o, val); \ 1281 o += sizeof val; \ 1282 } \ 1283 } 1284 CHIP_set_region_N(1,uint8_t) 1285 CHIP_set_region_N(2,uint16_t) 1286 CHIP_set_region_N(4,uint32_t) 1287 CHIP_set_region_N(8,uint64_t) 1288 1289 #define CHIP_copy_region_N(BYTES) \ 1290 void \ 1291 __C(__BS(copy_region_),BYTES)(void *v, bus_space_handle_t h1, \ 1292 bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c) \ 1293 { \ 1294 bus_size_t o; \ 1295 \ 1296 if ((h1 + o1) >= (h2 + o2)) { \ 1297 /* src after dest: copy forward */ \ 1298 for (o = 0; c != 0; c--, o += BYTES) \ 1299 __C(__BS(write_),BYTES)(v, h2, o2 + o, \ 1300 __C(__BS(read_),BYTES)(v, h1, o1 + o)); \ 1301 } else { \ 1302 /* dest after src: copy backwards */ \ 1303 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \ 1304 __C(__BS(write_),BYTES)(v, h2, o2 + o, \ 1305 __C(__BS(read_),BYTES)(v, h1, o1 + o)); \ 1306 } \ 1307 } 1308 CHIP_copy_region_N(1) 1309 CHIP_copy_region_N(2) 1310 CHIP_copy_region_N(4) 1311 CHIP_copy_region_N(8) 1312 1313 #ifdef CHIP_NEED_STREAM 1314 1315 inline uint8_t 1316 __BS(read_stream_1)(void *v, bus_space_handle_t h, bus_size_t off) 1317 { 1318 #if CHIP_ACCESS_SIZE > 1 1319 volatile CHIP_TYPE *ptr; 1320 #else /* CHIP_ACCESS_SIZE > 1 */ 1321 volatile uint8_t *ptr; 1322 #endif /* CHIP_ACCESS_SIZE > 1 */ 1323 1324 ptr = (void *)(intptr_t)(h + CHIP_OFF8(off)); 1325 return *ptr & 0xff; 1326 } 1327 1328 inline uint16_t 1329 __BS(read_stream_2)(void *v, bus_space_handle_t h, bus_size_t off) 1330 { 1331 #if CHIP_ACCESS_SIZE > 2 1332 volatile CHIP_TYPE *ptr; 1333 #else /* CHIP_ACCESS_SIZE > 2 */ 1334 volatile uint16_t *ptr; 1335 #endif /* CHIP_ACCESS_SIZE > 2 */ 1336 1337 ptr = (void *)(intptr_t)(h + CHIP_OFF16(off)); 1338 return *ptr & 0xffff; 1339 } 1340 1341 inline uint32_t 1342 __BS(read_stream_4)(void *v, bus_space_handle_t h, bus_size_t off) 1343 { 1344 #if CHIP_ACCESS_SIZE > 4 1345 volatile CHIP_TYPE *ptr; 1346 #else /* CHIP_ACCESS_SIZE > 4 */ 1347 volatile uint32_t *ptr; 1348 #endif 1349 1350 ptr = (void *)(intptr_t)(h + CHIP_OFF32(off)); 1351 return *ptr & 0xffffffff; 1352 } 1353 1354 inline uint64_t 1355 __BS(read_stream_8)(void *v, bus_space_handle_t h, bus_size_t off) 1356 { 1357 volatile uint64_t *ptr; 1358 1359 ptr = (void *)(intptr_t)(h + CHIP_OFF64(off)); 1360 return *ptr; 1361 } 1362 1363 #define CHIP_read_multi_stream_N(BYTES,TYPE) \ 1364 void \ 1365 __C(__BS(read_multi_stream_),BYTES)(void *v, bus_space_handle_t h, \ 1366 bus_size_t o, TYPE *a, bus_size_t c) \ 1367 { \ 1368 \ 1369 while (c-- > 0) { \ 1370 __BS(barrier)(v, h, o, sizeof *a, \ 1371 BUS_SPACE_BARRIER_READ); \ 1372 *a++ = __C(__BS(read_stream_),BYTES)(v, h, o); \ 1373 } \ 1374 } 1375 CHIP_read_multi_stream_N(1,uint8_t) 1376 CHIP_read_multi_stream_N(2,uint16_t) 1377 CHIP_read_multi_stream_N(4,uint32_t) 1378 CHIP_read_multi_stream_N(8,uint64_t) 1379 1380 #define CHIP_read_region_stream_N(BYTES,TYPE) \ 1381 void \ 1382 __C(__BS(read_region_stream_),BYTES)(void *v, bus_space_handle_t h, \ 1383 bus_size_t o, TYPE *a, bus_size_t c) \ 1384 { \ 1385 \ 1386 while (c-- > 0) { \ 1387 *a++ = __C(__BS(read_stream_),BYTES)(v, h, o); \ 1388 o += sizeof *a; \ 1389 } \ 1390 } 1391 CHIP_read_region_stream_N(1,uint8_t) 1392 CHIP_read_region_stream_N(2,uint16_t) 1393 CHIP_read_region_stream_N(4,uint32_t) 1394 CHIP_read_region_stream_N(8,uint64_t) 1395 1396 inline void 1397 __BS(write_stream_1)(void *v, bus_space_handle_t h, bus_size_t off, 1398 uint8_t val) 1399 { 1400 #if CHIP_ACCESS_SIZE > 1 1401 volatile CHIP_TYPE *ptr; 1402 #else /* CHIP_ACCESS_SIZE > 1 */ 1403 volatile uint8_t *ptr; 1404 #endif /* CHIP_ACCESS_SIZE > 1 */ 1405 1406 ptr = (void *)(intptr_t)(h + CHIP_OFF8(off)); 1407 *ptr = val; 1408 } 1409 1410 inline void 1411 __BS(write_stream_2)(void *v, bus_space_handle_t h, bus_size_t off, 1412 uint16_t val) 1413 { 1414 #if CHIP_ACCESS_SIZE > 2 1415 volatile CHIP_TYPE *ptr; 1416 #else /* CHIP_ACCESS_SIZE > 2 */ 1417 volatile uint16_t *ptr; 1418 #endif /* CHIP_ACCESS_SIZE > 2 */ 1419 1420 ptr = (void *)(intptr_t)(h + CHIP_OFF16(off)); 1421 *ptr = val; 1422 } 1423 1424 inline void 1425 __BS(write_stream_4)(void *v, bus_space_handle_t h, bus_size_t off, 1426 uint32_t val) 1427 { 1428 #if CHIP_ACCESS_SIZE > 4 1429 volatile CHIP_TYPE *ptr; 1430 #else /* CHIP_ACCESS_SIZE > 4 */ 1431 volatile uint32_t *ptr; 1432 #endif /* CHIP_ACCESS_SIZE > 4 */ 1433 1434 ptr = (void *)(intptr_t)(h + CHIP_OFF32(off)); 1435 *ptr = val; 1436 } 1437 1438 inline void 1439 __BS(write_stream_8)(void *v, bus_space_handle_t h, bus_size_t off, 1440 uint64_t val) 1441 { 1442 volatile uint64_t *ptr; 1443 1444 ptr = (void *)(intptr_t)(h + CHIP_OFF64(off)); 1445 *ptr = val; 1446 } 1447 1448 #define CHIP_write_multi_stream_N(BYTES,TYPE) \ 1449 void \ 1450 __C(__BS(write_multi_stream_),BYTES)(void *v, bus_space_handle_t h, \ 1451 bus_size_t o, const TYPE *a, bus_size_t c) \ 1452 { \ 1453 \ 1454 while (c-- > 0) { \ 1455 __C(__BS(write_stream_),BYTES)(v, h, o, *a++); \ 1456 __BS(barrier)(v, h, o, sizeof *a, \ 1457 BUS_SPACE_BARRIER_WRITE); \ 1458 } \ 1459 } 1460 CHIP_write_multi_stream_N(1,uint8_t) 1461 CHIP_write_multi_stream_N(2,uint16_t) 1462 CHIP_write_multi_stream_N(4,uint32_t) 1463 CHIP_write_multi_stream_N(8,uint64_t) 1464 1465 #define CHIP_write_region_stream_N(BYTES,TYPE) \ 1466 void \ 1467 __C(__BS(write_region_stream_),BYTES)(void *v, bus_space_handle_t h, \ 1468 bus_size_t o, const TYPE *a, bus_size_t c) \ 1469 { \ 1470 \ 1471 while (c-- > 0) { \ 1472 __C(__BS(write_stream_),BYTES)(v, h, o, *a++); \ 1473 o += sizeof *a; \ 1474 } \ 1475 } 1476 CHIP_write_region_stream_N(1,uint8_t) 1477 CHIP_write_region_stream_N(2,uint16_t) 1478 CHIP_write_region_stream_N(4,uint32_t) 1479 CHIP_write_region_stream_N(8,uint64_t) 1480 1481 #endif /* CHIP_NEED_STREAM */ 1482