1 /* $NetBSD: le_bus.c,v 1.5 2000/01/19 13:12:55 leo Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Leo Weppelman. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 #include <sys/types.h> 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/malloc.h> 42 #include <machine/bswap.h> 43 #include <machine/cpu.h> 44 #include <machine/bus.h> 45 46 /* 47 * This file contains the common functions for using a litte endian (linear) 48 * bus on a big endian atari. 49 */ 50 51 /* Autoconf detection stuff */ 52 static int leb_bus_space_peek_1 __P((bus_space_tag_t, 53 bus_space_handle_t, bus_size_t)); 54 static int leb_bus_space_peek_2 __P((bus_space_tag_t, 55 bus_space_handle_t, bus_size_t)); 56 static int leb_bus_space_peek_4 __P((bus_space_tag_t, 57 bus_space_handle_t, bus_size_t)); 58 static int leb_bus_space_peek_8 __P((bus_space_tag_t, 59 bus_space_handle_t, bus_size_t)); 60 61 /* read (single) */ 62 static u_int8_t leb_bus_space_read_1 __P((bus_space_tag_t, 63 bus_space_handle_t, bus_size_t)); 64 static u_int16_t leb_bus_space_read_2 __P((bus_space_tag_t, 65 bus_space_handle_t, bus_size_t)); 66 static u_int32_t leb_bus_space_read_4 __P((bus_space_tag_t, 67 bus_space_handle_t, bus_size_t)); 68 static u_int64_t leb_bus_space_read_8 __P((bus_space_tag_t, 69 bus_space_handle_t, bus_size_t)); 70 71 /* write (single) */ 72 static void leb_bus_space_write_1 __P((bus_space_tag_t, 73 bus_space_handle_t, bus_size_t, u_int8_t)); 74 static void leb_bus_space_write_2 __P((bus_space_tag_t, 75 bus_space_handle_t, bus_size_t, u_int16_t)); 76 static void leb_bus_space_write_4 __P((bus_space_tag_t, 77 bus_space_handle_t, bus_size_t, u_int32_t)); 78 static void leb_bus_space_write_8 __P((bus_space_tag_t, 79 bus_space_handle_t, bus_size_t, u_int64_t)); 80 81 /* read (single) stream */ 82 static u_int16_t leb_bus_space_read_stream_2 __P((bus_space_tag_t, 83 bus_space_handle_t, bus_size_t)); 84 static u_int32_t leb_bus_space_read_stream_4 __P((bus_space_tag_t, 85 bus_space_handle_t, bus_size_t)); 86 static u_int64_t leb_bus_space_read_stream_8 __P((bus_space_tag_t, 87 bus_space_handle_t, bus_size_t)); 88 89 /* write (single) stream */ 90 static void leb_bus_space_write_stream_2 __P((bus_space_tag_t, 91 bus_space_handle_t, bus_size_t, u_int16_t)); 92 static void leb_bus_space_write_stream_4 __P((bus_space_tag_t, 93 bus_space_handle_t, bus_size_t, u_int32_t)); 94 static void leb_bus_space_write_stream_8 __P((bus_space_tag_t, 95 bus_space_handle_t, bus_size_t, u_int64_t)); 96 97 /* read multiple */ 98 static void leb_bus_space_read_multi_1 __P((bus_space_tag_t, 99 bus_space_handle_t, bus_size_t, u_int8_t *, 100 bus_size_t)); 101 static void leb_bus_space_read_multi_2 __P((bus_space_tag_t, 102 bus_space_handle_t, bus_size_t, u_int16_t *, 103 bus_size_t)); 104 static void leb_bus_space_read_multi_4 __P((bus_space_tag_t, 105 bus_space_handle_t, bus_size_t, u_int32_t *, 106 bus_size_t)); 107 static void leb_bus_space_read_multi_8 __P((bus_space_tag_t, 108 bus_space_handle_t, bus_size_t, u_int64_t *, 109 bus_size_t)); 110 111 /* write multiple */ 112 static void leb_bus_space_write_multi_1 __P((bus_space_tag_t, 113 bus_space_handle_t, bus_size_t, 114 const u_int8_t *, bus_size_t)); 115 static void leb_bus_space_write_multi_2 __P((bus_space_tag_t, 116 bus_space_handle_t, bus_size_t, 117 const u_int16_t *, bus_size_t)); 118 static void leb_bus_space_write_multi_4 __P((bus_space_tag_t, 119 bus_space_handle_t, bus_size_t, 120 const u_int32_t *, bus_size_t)); 121 static void leb_bus_space_write_multi_8 __P((bus_space_tag_t, 122 bus_space_handle_t, bus_size_t, 123 const u_int64_t *, bus_size_t)); 124 125 /* read multiple stream */ 126 static void leb_bus_space_read_multi_stream_2 __P((bus_space_tag_t, 127 bus_space_handle_t, bus_size_t, u_int16_t *, 128 bus_size_t)); 129 static void leb_bus_space_read_multi_stream_4 __P((bus_space_tag_t, 130 bus_space_handle_t, bus_size_t, u_int32_t *, 131 bus_size_t)); 132 static void leb_bus_space_read_multi_stream_8 __P((bus_space_tag_t, 133 bus_space_handle_t, bus_size_t, u_int64_t *, 134 bus_size_t)); 135 136 /* write multiple stream */ 137 static void leb_bus_space_write_multi_stream_2 __P((bus_space_tag_t, 138 bus_space_handle_t, bus_size_t, 139 const u_int16_t *, bus_size_t)); 140 static void leb_bus_space_write_multi_stream_4 __P((bus_space_tag_t, 141 bus_space_handle_t, bus_size_t, 142 const u_int32_t *, bus_size_t)); 143 static void leb_bus_space_write_multi_stream_8 __P((bus_space_tag_t, 144 bus_space_handle_t, bus_size_t, 145 const u_int64_t *, bus_size_t)); 146 147 /* read region */ 148 static void leb_bus_space_read_region_1 __P((bus_space_tag_t, 149 bus_space_handle_t, bus_size_t, u_int8_t *, 150 bus_size_t)); 151 static void leb_bus_space_read_region_2 __P((bus_space_tag_t, 152 bus_space_handle_t, bus_size_t, u_int16_t *, 153 bus_size_t)); 154 static void leb_bus_space_read_region_4 __P((bus_space_tag_t, 155 bus_space_handle_t, bus_size_t, u_int32_t *, 156 bus_size_t)); 157 static void leb_bus_space_read_region_8 __P((bus_space_tag_t, 158 bus_space_handle_t, bus_size_t, u_int64_t *, 159 bus_size_t)); 160 161 /* write region */ 162 static void leb_bus_space_write_region_1 __P((bus_space_tag_t, 163 bus_space_handle_t, bus_size_t, 164 const u_int8_t *, bus_size_t)); 165 static void leb_bus_space_write_region_2 __P((bus_space_tag_t, 166 bus_space_handle_t, bus_size_t, 167 const u_int16_t *, bus_size_t)); 168 static void leb_bus_space_write_region_4 __P((bus_space_tag_t, 169 bus_space_handle_t, bus_size_t, 170 const u_int32_t *, bus_size_t)); 171 static void leb_bus_space_write_region_8 __P((bus_space_tag_t, 172 bus_space_handle_t, bus_size_t, 173 const u_int64_t *, bus_size_t)); 174 175 /* read region stream */ 176 static void leb_bus_space_read_region_stream_2 __P(( 177 bus_space_tag_t, bus_space_handle_t, 178 bus_size_t, u_int16_t *, bus_size_t)); 179 static void leb_bus_space_read_region_stream_4 __P(( 180 bus_space_tag_t, bus_space_handle_t, 181 bus_size_t, u_int32_t *, bus_size_t)); 182 static void leb_bus_space_read_region_stream_8 __P(( 183 bus_space_tag_t, bus_space_handle_t, 184 bus_size_t, u_int64_t *, bus_size_t)); 185 186 /* write region */ 187 static void leb_bus_space_write_region_stream_2 __P(( 188 bus_space_tag_t, bus_space_handle_t, 189 bus_size_t, const u_int16_t *, bus_size_t)); 190 static void leb_bus_space_write_region_stream_4 __P(( 191 bus_space_tag_t, bus_space_handle_t, 192 bus_size_t, const u_int32_t *, bus_size_t)); 193 static void leb_bus_space_write_region_stream_8 __P(( 194 bus_space_tag_t, bus_space_handle_t, 195 bus_size_t, const u_int64_t *, bus_size_t)); 196 197 /* set multi */ 198 static void leb_bus_space_set_multi_1 __P((bus_space_tag_t, 199 bus_space_handle_t, bus_size_t, u_int8_t, 200 bus_size_t)); 201 static void leb_bus_space_set_multi_2 __P((bus_space_tag_t, 202 bus_space_handle_t, bus_size_t, u_int16_t, 203 bus_size_t)); 204 static void leb_bus_space_set_multi_4 __P((bus_space_tag_t, 205 bus_space_handle_t, bus_size_t, u_int32_t, 206 bus_size_t)); 207 static void leb_bus_space_set_multi_8 __P((bus_space_tag_t, 208 bus_space_handle_t, bus_size_t, u_int64_t, 209 bus_size_t)); 210 211 /* set region */ 212 static void leb_bus_space_set_region_1 __P((bus_space_tag_t, 213 bus_space_handle_t, bus_size_t, u_int8_t, 214 bus_size_t)); 215 static void leb_bus_space_set_region_2 __P((bus_space_tag_t, 216 bus_space_handle_t, bus_size_t, u_int16_t, 217 bus_size_t)); 218 static void leb_bus_space_set_region_4 __P((bus_space_tag_t, 219 bus_space_handle_t, bus_size_t, u_int32_t, 220 bus_size_t)); 221 static void leb_bus_space_set_region_8 __P((bus_space_tag_t, 222 bus_space_handle_t, bus_size_t, u_int64_t, 223 bus_size_t)); 224 225 /* 226 * Define these inline, to avoid function call overhead. 227 * XXX: Maybe move to an m68k include file? 228 */ 229 static u_int16_t swap16 __P((u_int16_t v)); 230 static u_int32_t swap32 __P((u_int32_t v)); 231 232 static __inline__ u_int16_t swap16(u_int16_t v) 233 { 234 __asm volatile ("rolw #8, %0" : "=d"(v) : "0"(v)); 235 return(v); 236 } 237 238 static __inline__ u_int32_t swap32(u_int32_t v) 239 { 240 __asm volatile (" rolw #8, %0 241 swap %0 242 rolw #8, %0" : "=d"(v) : "0"(v)); 243 return(v); 244 } 245 246 /* 247 * Don't force a function call overhead on these primitives... 248 */ 249 #define __read_1(h, o) *((u_int8_t *)((h) + (o))) 250 #define __read_2(h, o) swap16(*((u_int16_t *)((h) + (o)))) 251 #define __read_4(h, o) swap32(*((u_int32_t *)((h) + (o)))) 252 #define __read_8(h, o) bswap64(*((u_int64_t *)((h) + (o)))) 253 254 #define __write_1(h, o, v) *((u_int8_t *)((h) + (o))) = (v) 255 #define __write_2(h, o, v) *((u_int16_t *)((h) + (o))) = swap16(v) 256 #define __write_4(h, o, v) *((u_int32_t *)((h) + (o))) = swap32(v) 257 #define __write_8(h, o, v) *((u_int64_t *)((h) + (o))) = bswap64(v) 258 259 bus_space_tag_t 260 leb_alloc_bus_space_tag(storage) 261 bus_space_tag_t storage; 262 { 263 bus_space_tag_t leb_t; 264 265 /* 266 * Allow the caller to specify storage space for the tag. This 267 * is used during console config (when malloc() can't be used). 268 */ 269 if (storage != NULL) 270 leb_t = storage; 271 else { 272 if ((leb_t = malloc(sizeof(*leb_t), M_TEMP, M_NOWAIT)) == NULL) 273 return(NULL); 274 } 275 bzero(leb_t, sizeof(*leb_t)); 276 277 leb_t->abs_p_1 = leb_bus_space_peek_1; 278 leb_t->abs_p_2 = leb_bus_space_peek_2; 279 leb_t->abs_p_4 = leb_bus_space_peek_4; 280 leb_t->abs_p_8 = leb_bus_space_peek_8; 281 leb_t->abs_r_1 = leb_bus_space_read_1; 282 leb_t->abs_r_2 = leb_bus_space_read_2; 283 leb_t->abs_r_4 = leb_bus_space_read_4; 284 leb_t->abs_r_8 = leb_bus_space_read_8; 285 leb_t->abs_rs_1 = leb_bus_space_read_1; 286 leb_t->abs_rs_2 = leb_bus_space_read_stream_2; 287 leb_t->abs_rs_4 = leb_bus_space_read_stream_4; 288 leb_t->abs_rs_8 = leb_bus_space_read_stream_8; 289 leb_t->abs_rm_1 = leb_bus_space_read_multi_1; 290 leb_t->abs_rm_2 = leb_bus_space_read_multi_2; 291 leb_t->abs_rm_4 = leb_bus_space_read_multi_4; 292 leb_t->abs_rm_8 = leb_bus_space_read_multi_8; 293 leb_t->abs_rms_1 = leb_bus_space_read_multi_1; 294 leb_t->abs_rms_2 = leb_bus_space_read_multi_stream_2; 295 leb_t->abs_rms_4 = leb_bus_space_read_multi_stream_4; 296 leb_t->abs_rms_8 = leb_bus_space_read_multi_stream_8; 297 leb_t->abs_rr_1 = leb_bus_space_read_region_1; 298 leb_t->abs_rr_2 = leb_bus_space_read_region_2; 299 leb_t->abs_rr_4 = leb_bus_space_read_region_4; 300 leb_t->abs_rr_8 = leb_bus_space_read_region_8; 301 leb_t->abs_rrs_1 = leb_bus_space_read_region_1; 302 leb_t->abs_rrs_2 = leb_bus_space_read_region_stream_2; 303 leb_t->abs_rrs_4 = leb_bus_space_read_region_stream_4; 304 leb_t->abs_rrs_8 = leb_bus_space_read_region_stream_8; 305 leb_t->abs_w_1 = leb_bus_space_write_1; 306 leb_t->abs_w_2 = leb_bus_space_write_2; 307 leb_t->abs_w_4 = leb_bus_space_write_4; 308 leb_t->abs_w_8 = leb_bus_space_write_8; 309 leb_t->abs_ws_1 = leb_bus_space_write_1; 310 leb_t->abs_ws_2 = leb_bus_space_write_stream_2; 311 leb_t->abs_ws_4 = leb_bus_space_write_stream_4; 312 leb_t->abs_ws_8 = leb_bus_space_write_stream_8; 313 leb_t->abs_wm_1 = leb_bus_space_write_multi_1; 314 leb_t->abs_wm_2 = leb_bus_space_write_multi_2; 315 leb_t->abs_wm_4 = leb_bus_space_write_multi_4; 316 leb_t->abs_wm_8 = leb_bus_space_write_multi_8; 317 leb_t->abs_wms_1 = leb_bus_space_write_multi_1; 318 leb_t->abs_wms_2 = leb_bus_space_write_multi_stream_2; 319 leb_t->abs_wms_4 = leb_bus_space_write_multi_stream_4; 320 leb_t->abs_wms_8 = leb_bus_space_write_multi_stream_8; 321 leb_t->abs_wr_1 = leb_bus_space_write_region_1; 322 leb_t->abs_wr_2 = leb_bus_space_write_region_2; 323 leb_t->abs_wr_4 = leb_bus_space_write_region_4; 324 leb_t->abs_wr_8 = leb_bus_space_write_region_8; 325 leb_t->abs_wrs_1 = leb_bus_space_write_region_1; 326 leb_t->abs_wrs_2 = leb_bus_space_write_region_stream_2; 327 leb_t->abs_wrs_4 = leb_bus_space_write_region_stream_4; 328 leb_t->abs_wrs_8 = leb_bus_space_write_region_stream_8; 329 leb_t->abs_sm_1 = leb_bus_space_set_multi_1; 330 leb_t->abs_sm_2 = leb_bus_space_set_multi_2; 331 leb_t->abs_sm_4 = leb_bus_space_set_multi_4; 332 leb_t->abs_sm_8 = leb_bus_space_set_multi_8; 333 leb_t->abs_sr_1 = leb_bus_space_set_region_1; 334 leb_t->abs_sr_2 = leb_bus_space_set_region_2; 335 leb_t->abs_sr_4 = leb_bus_space_set_region_4; 336 leb_t->abs_sr_8 = leb_bus_space_set_region_8; 337 338 return(leb_t); 339 } 340 341 342 /* 343 * The various access functions 344 */ 345 346 /* 347 * int bus_space_peek_N __P((bus_space_tag_t tag, 348 * bus_space_handle_t sh, bus_size_t offset)); 349 * 350 * Check if the address is suitable for reading N-byte quantities. 351 */ 352 static int 353 leb_bus_space_peek_1(t, h, o) 354 bus_space_tag_t t; 355 bus_space_handle_t h; 356 bus_size_t o; 357 { 358 return(!badbaddr((caddr_t)(h + o), 1)); 359 } 360 361 static int 362 leb_bus_space_peek_2(t, h, o) 363 bus_space_tag_t t; 364 bus_space_handle_t h; 365 bus_size_t o; 366 { 367 return(!badbaddr((caddr_t)(h + o), 2)); 368 } 369 370 static int 371 leb_bus_space_peek_4(t, h, o) 372 bus_space_tag_t t; 373 bus_space_handle_t h; 374 bus_size_t o; 375 { 376 return(!badbaddr((caddr_t)(h + o), 4)); 377 } 378 379 static int 380 leb_bus_space_peek_8(t, h, o) 381 bus_space_tag_t t; 382 bus_space_handle_t h; 383 bus_size_t o; 384 { 385 return(!badbaddr((caddr_t)(h + o), 8)); 386 } 387 388 /* 389 * u_intX_t bus_space_read_N __P((bus_space_tag_t tag, 390 * bus_space_handle_t bsh, bus_size_t offset)); 391 * 392 * Return an 1, 2, 4, or 8 byte value read from the bus_space described 393 * by tag/handle at `offset'. The value is converted to host-endian. 394 */ 395 static u_int8_t 396 leb_bus_space_read_1(t, h, o) 397 bus_space_tag_t t; 398 bus_space_handle_t h; 399 bus_size_t o; 400 { 401 return(__read_1(h, o)); 402 } 403 404 static u_int16_t 405 leb_bus_space_read_2(t, h, o) 406 bus_space_tag_t t; 407 bus_space_handle_t h; 408 bus_size_t o; 409 { 410 return(__read_2(h, o)); 411 } 412 413 static u_int32_t 414 leb_bus_space_read_4(t, h, o) 415 bus_space_tag_t t; 416 bus_space_handle_t h; 417 bus_size_t o; 418 { 419 return(__read_4(h, o)); 420 } 421 422 static u_int64_t 423 leb_bus_space_read_8(t, h, o) 424 bus_space_tag_t t; 425 bus_space_handle_t h; 426 bus_size_t o; 427 { 428 return(__read_8(h, o)); 429 } 430 431 /* 432 * u_intX_t bus_space_write_N __P((bus_space_tag_t tag, 433 * bus_space_handle_t bsh, bus_size_t offset, u_intX_t val)); 434 * 435 * Write an 1, 2, 4, or 8 byte value to the bus_space described by tag/handle 436 * at `offset'. The value `val' is converted from host to bus endianness 437 * before being written. 438 */ 439 static void 440 leb_bus_space_write_1(t, h, o, v) 441 bus_space_tag_t t; 442 bus_space_handle_t h; 443 bus_size_t o; 444 u_int8_t v; 445 { 446 __write_1(h, o, v); 447 } 448 449 static void 450 leb_bus_space_write_2(t, h, o, v) 451 bus_space_tag_t t; 452 bus_space_handle_t h; 453 bus_size_t o; 454 u_int16_t v; 455 { 456 __write_2(h, o, v); 457 } 458 459 static void 460 leb_bus_space_write_4(t, h, o, v) 461 bus_space_tag_t t; 462 bus_space_handle_t h; 463 bus_size_t o; 464 u_int32_t v; 465 { 466 __write_4(h, o, v); 467 } 468 469 static void 470 leb_bus_space_write_8(t, h, o, v) 471 bus_space_tag_t t; 472 bus_space_handle_t h; 473 bus_size_t o; 474 u_int64_t v; 475 { 476 __write_8(h, o, v); 477 } 478 479 /* 480 * u_intX_t bus_space_read_stream_N __P((bus_space_tag_t tag, 481 * bus_space_handle_t bsh, bus_size_t offset)); 482 * 483 * Return an 1, 2, 4, or 8 byte value read from the bus_space described 484 * by tag/handle at `offset'. No endian conversion is done. 485 */ 486 static u_int16_t 487 leb_bus_space_read_stream_2(t, h, o) 488 bus_space_tag_t t; 489 bus_space_handle_t h; 490 bus_size_t o; 491 { 492 return(*((u_int16_t *)(h + o))); 493 } 494 495 static u_int32_t 496 leb_bus_space_read_stream_4(t, h, o) 497 bus_space_tag_t t; 498 bus_space_handle_t h; 499 bus_size_t o; 500 { 501 return(*((u_int32_t *)(h + o))); 502 } 503 504 static u_int64_t 505 leb_bus_space_read_stream_8(t, h, o) 506 bus_space_tag_t t; 507 bus_space_handle_t h; 508 bus_size_t o; 509 { 510 return(*((u_int64_t *)(h + o))); 511 } 512 513 /* 514 * u_intX_t bus_space_write_stream_N __P((bus_space_tag_t tag, 515 * bus_space_handle_t bsh, bus_size_t offset, u_intX_t val)); 516 * 517 * Write an 1, 2, 4, or 8 byte value to the bus_space described by tag/handle 518 * at `offset'. No endian conversion is done. 519 */ 520 static void 521 leb_bus_space_write_stream_2(t, h, o, v) 522 bus_space_tag_t t; 523 bus_space_handle_t h; 524 bus_size_t o; 525 u_int16_t v; 526 { 527 *((u_int16_t *)(h + o)) = v; 528 } 529 530 static void 531 leb_bus_space_write_stream_4(t, h, o, v) 532 bus_space_tag_t t; 533 bus_space_handle_t h; 534 bus_size_t o; 535 u_int32_t v; 536 { 537 *((u_int32_t *)(h + o)) = v; 538 } 539 540 static void 541 leb_bus_space_write_stream_8(t, h, o, v) 542 bus_space_tag_t t; 543 bus_space_handle_t h; 544 bus_size_t o; 545 u_int64_t v; 546 { 547 *((u_int64_t *)(h + o)) = v; 548 } 549 550 /* 551 * void bus_space_read_multi_N __P((bus_space_tag_t tag, 552 * bus_space_handle_t bsh, bus_size_t offset, u_intX_t *address, 553 * bus_size_t count)); 554 * 555 * Read 'count' 1, 2, 4, or 8 byte values from the bus_space described by 556 * tag/handle at `offset' and store them in the address range starting at 557 * 'address'. The values are converted to cpu endian order before being 558 * being stored. 559 */ 560 static void 561 leb_bus_space_read_multi_1(t, h, o, a, c) 562 bus_space_tag_t t; 563 bus_space_handle_t h; 564 bus_size_t o, c; 565 u_int8_t *a; 566 { 567 for (; c; a++, c--) 568 *a = __read_1(h, o); 569 } 570 static void 571 leb_bus_space_read_multi_2(t, h, o, a, c) 572 bus_space_tag_t t; 573 bus_space_handle_t h; 574 bus_size_t o, c; 575 u_int16_t *a; 576 { 577 for (; c; a++, c--) 578 *a = __read_2(h, o); 579 } 580 581 static void 582 leb_bus_space_read_multi_4(t, h, o, a, c) 583 bus_space_tag_t t; 584 bus_space_handle_t h; 585 bus_size_t o, c; 586 u_int32_t *a; 587 { 588 for (; c; a++, c--) 589 *a = __read_4(h, o); 590 } 591 592 static void 593 leb_bus_space_read_multi_8(t, h, o, a, c) 594 bus_space_tag_t t; 595 bus_space_handle_t h; 596 bus_size_t o, c; 597 u_int64_t *a; 598 { 599 for (; c; a++, c--) 600 *a = __read_8(h, o); 601 } 602 603 /* 604 * void bus_space_write_multi_N __P((bus_space_tag_t tag, 605 * bus_space_handle_t bsh, bus_size_t offset, 606 * const u_intX_t *address, bus_size_t count)); 607 * 608 * Write 'count' 1, 2, 4, or 8 byte values from the address range starting 609 * at 'address' to the bus_space described by tag/handle at `offset'. 610 * The values are converted to bus endian order before being written to 611 * the bus. 612 */ 613 static void 614 leb_bus_space_write_multi_1(t, h, o, a, c) 615 bus_space_tag_t t; 616 bus_space_handle_t h; 617 bus_size_t o, c; 618 const u_int8_t *a; 619 { 620 for (; c; a++, c--) 621 __write_1(h, o, *a); 622 } 623 624 static void 625 leb_bus_space_write_multi_2(t, h, o, a, c) 626 bus_space_tag_t t; 627 bus_space_handle_t h; 628 bus_size_t o, c; 629 const u_int16_t *a; 630 { 631 for (; c; a++, c--) 632 __write_2(h, o, *a); 633 } 634 635 static void 636 leb_bus_space_write_multi_4(t, h, o, a, c) 637 bus_space_tag_t t; 638 bus_space_handle_t h; 639 bus_size_t o, c; 640 const u_int32_t *a; 641 { 642 for (; c; a++, c--) 643 __write_4(h, o, *a); 644 } 645 646 static void 647 leb_bus_space_write_multi_8(t, h, o, a, c) 648 bus_space_tag_t t; 649 bus_space_handle_t h; 650 bus_size_t o, c; 651 const u_int64_t *a; 652 { 653 for (; c; a++, c--) 654 __write_8(h, o, *a); 655 } 656 657 /* 658 * void bus_space_read_multi_stream_N __P((bus_space_tag_t tag, 659 * bus_space_handle_t bsh, bus_size_t offset, u_intX_t *address, 660 * bus_size_t count)); 661 * 662 * Read 'count' 1, 2, 4, or 8 byte values from the bus_space described by 663 * tag/handle at `offset' and store them in the address range starting at 664 * 'address'. No endian conversion is being done. 665 */ 666 static void 667 leb_bus_space_read_multi_stream_2(t, h, o, a, c) 668 bus_space_tag_t t; 669 bus_space_handle_t h; 670 bus_size_t o, c; 671 u_int16_t *a; 672 { 673 for (; c; a++, c--) 674 *a = *((u_int16_t *)(h + o)); 675 } 676 677 static void 678 leb_bus_space_read_multi_stream_4(t, h, o, a, c) 679 bus_space_tag_t t; 680 bus_space_handle_t h; 681 bus_size_t o, c; 682 u_int32_t *a; 683 { 684 for (; c; a++, c--) 685 *a = *((u_int32_t *)(h + o)); 686 } 687 688 static void 689 leb_bus_space_read_multi_stream_8(t, h, o, a, c) 690 bus_space_tag_t t; 691 bus_space_handle_t h; 692 bus_size_t o, c; 693 u_int64_t *a; 694 { 695 for (; c; a++, c--) 696 *a = *((u_int64_t *)(h + o)); 697 } 698 699 /* 700 * void bus_space_write_multi_stream_N __P((bus_space_tag_t tag, 701 * bus_space_handle_t bsh, bus_size_t offset, 702 * const u_intX_t *address, bus_size_t count)); 703 * 704 * Write 'count' 1, 2, 4, or 8 byte values from the address range starting 705 * at 'address' to the bus_space described by tag/handle at `offset'. 706 * No endian conversion is being done. 707 */ 708 static void 709 leb_bus_space_write_multi_stream_2(t, h, o, a, c) 710 bus_space_tag_t t; 711 bus_space_handle_t h; 712 bus_size_t o, c; 713 const u_int16_t *a; 714 { 715 for (; c; a++, c--) 716 *((u_int16_t *)(h + o)) = *a; 717 } 718 719 static void 720 leb_bus_space_write_multi_stream_4(t, h, o, a, c) 721 bus_space_tag_t t; 722 bus_space_handle_t h; 723 bus_size_t o, c; 724 const u_int32_t *a; 725 { 726 for (; c; a++, c--) 727 *((u_int32_t *)(h + o)) = *a; 728 } 729 730 static void 731 leb_bus_space_write_multi_stream_8(t, h, o, a, c) 732 bus_space_tag_t t; 733 bus_space_handle_t h; 734 bus_size_t o, c; 735 const u_int64_t *a; 736 { 737 for (; c; a++, c--) 738 *((u_int64_t *)(h + o)) = *a; 739 } 740 741 /* 742 * void bus_space_read_region_N __P((bus_space_tag_t tag, 743 * bus_space_handle_t bsh, bus_size_t offset, 744 * u_intN_t *addr, bus_size_t count)); 745 * 746 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 747 * described by tag/handle and starting at `offset' and copy into 748 * buffer provided. 749 */ 750 static void 751 leb_bus_space_read_region_1(t, h, o, a, c) 752 bus_space_tag_t t; 753 bus_space_handle_t h; 754 bus_size_t o, c; 755 u_int8_t *a; 756 { 757 for (; c; a++, o++, c--) 758 *a = __read_1(h, o); 759 } 760 761 static void 762 leb_bus_space_read_region_2(t, h, o, a, c) 763 bus_space_tag_t t; 764 bus_space_handle_t h; 765 bus_size_t o, c; 766 u_int16_t *a; 767 { 768 for (; c; a++, o += 2, c--) 769 *a = __read_2(h, o); 770 } 771 772 static void 773 leb_bus_space_read_region_4(t, h, o, a, c) 774 bus_space_tag_t t; 775 bus_space_handle_t h; 776 bus_size_t o, c; 777 u_int32_t *a; 778 { 779 for (; c; a++, o += 4, c--) 780 *a = __read_4(h, o); 781 } 782 783 static void 784 leb_bus_space_read_region_8(t, h, o, a, c) 785 bus_space_tag_t t; 786 bus_space_handle_t h; 787 bus_size_t o, c; 788 u_int64_t *a; 789 { 790 for (; c; a++, o += 8, c--) 791 *a = __read_8(h, o); 792 } 793 794 /* 795 * void bus_space_write_region_N __P((bus_space_tag_t tag, 796 * bus_space_handle_t bsh, bus_size_t offset, 797 * u_intN_t *addr, bus_size_t count)); 798 * 799 * Copy `count' 1, 2, 4, or 8 byte quantities from the buffer provided 800 * into the bus space described by tag/handle and starting at `offset'. 801 */ 802 static void 803 leb_bus_space_write_region_1(t, h, o, a, c) 804 bus_space_tag_t t; 805 bus_space_handle_t h; 806 bus_size_t o, c; 807 const u_int8_t *a; 808 { 809 for (; c; a++, o++, c--) 810 __write_1(h, o, *a); 811 } 812 813 static void 814 leb_bus_space_write_region_2(t, h, o, a, c) 815 bus_space_tag_t t; 816 bus_space_handle_t h; 817 bus_size_t o, c; 818 const u_int16_t *a; 819 { 820 for (; c; a++, o += 2, c--) 821 __write_2(h, o, *a); 822 } 823 824 static void 825 leb_bus_space_write_region_4(t, h, o, a, c) 826 bus_space_tag_t t; 827 bus_space_handle_t h; 828 bus_size_t o, c; 829 const u_int32_t *a; 830 { 831 for (; c; a++, o += 4, c--) 832 __write_4(h, o, *a); 833 } 834 835 static void 836 leb_bus_space_write_region_8(t, h, o, a, c) 837 bus_space_tag_t t; 838 bus_space_handle_t h; 839 bus_size_t o, c; 840 const u_int64_t *a; 841 { 842 for (; c; a++, o += 8, c--) 843 __write_8(h, o, *a); 844 } 845 846 /* 847 * void bus_space_read_region_stream_N __P((bus_space_tag_t tag, 848 * bus_space_handle_t bsh, bus_size_t offset, 849 * u_intN_t *addr, bus_size_t count)); 850 * 851 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 852 * described by tag/handle and starting at `offset' and copy into 853 * buffer provided. 854 * No endian conversion is being done. 855 */ 856 static void 857 leb_bus_space_read_region_stream_2(t, h, o, a, c) 858 bus_space_tag_t t; 859 bus_space_handle_t h; 860 bus_size_t o, c; 861 u_int16_t *a; 862 { 863 for (; c; a++, o += 2, c--) 864 *a = *(u_int16_t *)(h + o); 865 } 866 867 static void 868 leb_bus_space_read_region_stream_4(t, h, o, a, c) 869 bus_space_tag_t t; 870 bus_space_handle_t h; 871 bus_size_t o, c; 872 u_int32_t *a; 873 { 874 for (; c; a++, o += 4, c--) 875 *a = *(u_int32_t *)(h + o); 876 } 877 878 static void 879 leb_bus_space_read_region_stream_8(t, h, o, a, c) 880 bus_space_tag_t t; 881 bus_space_handle_t h; 882 bus_size_t o, c; 883 u_int64_t *a; 884 { 885 for (; c; a++, o += 8, c--) 886 *a = *(u_int64_t *)(h + o); 887 } 888 889 /* 890 * void bus_space_write_region_stream_N __P((bus_space_tag_t tag, 891 * bus_space_handle_t bsh, bus_size_t offset, 892 * u_intN_t *addr, bus_size_t count)); 893 * 894 * Copy `count' 1, 2, 4, or 8 byte quantities from the buffer provided 895 * into the bus space described by tag/handle and starting at `offset'. 896 * No endian conversion is being done. 897 */ 898 static void 899 leb_bus_space_write_region_stream_2(t, h, o, a, c) 900 bus_space_tag_t t; 901 bus_space_handle_t h; 902 bus_size_t o, c; 903 const u_int16_t *a; 904 { 905 for (; c; a++, o += 2, c--) 906 *((u_int16_t *)(h + o)) = *a; 907 } 908 909 static void 910 leb_bus_space_write_region_stream_4(t, h, o, a, c) 911 bus_space_tag_t t; 912 bus_space_handle_t h; 913 bus_size_t o, c; 914 const u_int32_t *a; 915 { 916 for (; c; a++, o += 4, c--) 917 *((u_int32_t *)(h + o)) = *a; 918 } 919 920 static void 921 leb_bus_space_write_region_stream_8(t, h, o, a, c) 922 bus_space_tag_t t; 923 bus_space_handle_t h; 924 bus_size_t o, c; 925 const u_int64_t *a; 926 { 927 for (; c; a++, o += 8, c--) 928 *((u_int64_t *)(h + o)) = *a; 929 } 930 931 /* 932 * void bus_space_set_multi_N __P((bus_space_tag_t tag, 933 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 934 * bus_size_t count)); 935 * 936 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 937 * by tag/handle/offset `count' times. 938 */ 939 940 static void 941 leb_bus_space_set_multi_1(t, h, o, v, c) 942 bus_space_tag_t t; 943 bus_space_handle_t h; 944 bus_size_t o, c; 945 u_int8_t v; 946 { 947 for (; c; c--) 948 __write_1(h, o, v); 949 } 950 951 static void 952 leb_bus_space_set_multi_2(t, h, o, v, c) 953 bus_space_tag_t t; 954 bus_space_handle_t h; 955 bus_size_t o, c; 956 u_int16_t v; 957 { 958 v = swap16(v); 959 for (; c; c--) 960 *((u_int16_t *)(h + o)) = v; 961 } 962 963 static void 964 leb_bus_space_set_multi_4(t, h, o, v, c) 965 bus_space_tag_t t; 966 bus_space_handle_t h; 967 bus_size_t o, c; 968 u_int32_t v; 969 { 970 v = swap32(v); 971 for (; c; c--) 972 *((u_int32_t *)(h + o)) = v; 973 } 974 975 static void 976 leb_bus_space_set_multi_8(t, h, o, v, c) 977 bus_space_tag_t t; 978 bus_space_handle_t h; 979 bus_size_t o, c; 980 u_int64_t v; 981 { 982 v = bswap64(v); 983 for (; c; c--) 984 *((u_int64_t *)(h + o)) = v; 985 } 986 987 /* 988 * void bus_space_set_region_N __P((bus_space_tag_t tag, 989 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 990 * bus_size_t count)); 991 * 992 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 993 * by tag/handle starting at `offset'. 994 */ 995 static void 996 leb_bus_space_set_region_1(t, h, o, v, c) 997 bus_space_tag_t t; 998 bus_space_handle_t h; 999 bus_size_t o, c; 1000 u_int8_t v; 1001 { 1002 for (; c; o++, c--) 1003 __write_1(h, o, v); 1004 } 1005 1006 static void 1007 leb_bus_space_set_region_2(t, h, o, v, c) 1008 bus_space_tag_t t; 1009 bus_space_handle_t h; 1010 bus_size_t o, c; 1011 u_int16_t v; 1012 { 1013 v = swap16(v); 1014 for (; c; o += 2, c--) 1015 *((u_int16_t *)(h + o)) = v; 1016 } 1017 1018 static void 1019 leb_bus_space_set_region_4(t, h, o, v, c) 1020 bus_space_tag_t t; 1021 bus_space_handle_t h; 1022 bus_size_t o, c; 1023 u_int32_t v; 1024 { 1025 v = swap32(v); 1026 for (; c; o += 4, c--) 1027 *((u_int32_t *)(h + o)) = v; 1028 } 1029 1030 static void 1031 leb_bus_space_set_region_8(t, h, o, v, c) 1032 bus_space_tag_t t; 1033 bus_space_handle_t h; 1034 bus_size_t o, c; 1035 u_int64_t v; 1036 { 1037 v = bswap64(v); 1038 for (; c; o += 8, c--) 1039 *((u_int64_t *)(h + o)) = v; 1040 } 1041