1 /* $NetBSD: pci_bwx_bus_io_chipdep.c,v 1.18 2009/03/14 14:45:53 dsl Exp $ */ 2 3 /*- 4 * Copyright (c) 1997, 1998, 2000 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 PCI Chipset "bus I/O" functions, for chipsets which have to 62 * deal with only a single PCI interface chip in a machine. 63 * 64 * uses: 65 * CHIP name of the 'chip' it's being compiled for. 66 * CHIP_IO_BASE I/O space base to use. 67 * CHIP_IO_EX_STORE 68 * If defined, device-provided static storage area 69 * for the I/O space extent. If this is defined, 70 * CHIP_IO_EX_STORE_SIZE must also be defined. If 71 * this is not defined, a static area will be 72 * declared. 73 * CHIP_IO_EX_STORE_SIZE 74 * Size of the device-provided static storage area 75 * for the I/O memory space extent. 76 */ 77 78 #include <sys/cdefs.h> 79 __KERNEL_RCSID(1, "$NetBSD: pci_bwx_bus_io_chipdep.c,v 1.18 2009/03/14 14:45:53 dsl Exp $"); 80 81 #include <sys/extent.h> 82 83 #include <machine/bwx.h> 84 85 #define __C(A,B) __CONCAT(A,B) 86 #define __S(S) __STRING(S) 87 88 /* mapping/unmapping */ 89 int __C(CHIP,_io_map)(void *, bus_addr_t, bus_size_t, int, 90 bus_space_handle_t *, int); 91 void __C(CHIP,_io_unmap)(void *, bus_space_handle_t, 92 bus_size_t, int); 93 int __C(CHIP,_io_subregion)(void *, bus_space_handle_t, 94 bus_size_t, bus_size_t, bus_space_handle_t *); 95 96 int __C(CHIP,_io_translate)(void *, bus_addr_t, bus_size_t, 97 int, struct alpha_bus_space_translation *); 98 int __C(CHIP,_io_get_window)(void *, int, 99 struct alpha_bus_space_translation *); 100 101 /* allocation/deallocation */ 102 int __C(CHIP,_io_alloc)(void *, bus_addr_t, bus_addr_t, 103 bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *, 104 bus_space_handle_t *); 105 void __C(CHIP,_io_free)(void *, bus_space_handle_t, 106 bus_size_t); 107 108 /* get kernel virtual address */ 109 void * __C(CHIP,_io_vaddr)(void *, bus_space_handle_t); 110 111 /* mmap for user */ 112 paddr_t __C(CHIP,_io_mmap)(void *, bus_addr_t, off_t, int, int); 113 114 /* barrier */ 115 inline void __C(CHIP,_io_barrier)(void *, bus_space_handle_t, 116 bus_size_t, bus_size_t, int); 117 118 /* read (single) */ 119 inline u_int8_t __C(CHIP,_io_read_1)(void *, bus_space_handle_t, 120 bus_size_t); 121 inline u_int16_t __C(CHIP,_io_read_2)(void *, bus_space_handle_t, 122 bus_size_t); 123 inline u_int32_t __C(CHIP,_io_read_4)(void *, bus_space_handle_t, 124 bus_size_t); 125 inline u_int64_t __C(CHIP,_io_read_8)(void *, bus_space_handle_t, 126 bus_size_t); 127 128 /* read multiple */ 129 void __C(CHIP,_io_read_multi_1)(void *, bus_space_handle_t, 130 bus_size_t, u_int8_t *, bus_size_t); 131 void __C(CHIP,_io_read_multi_2)(void *, bus_space_handle_t, 132 bus_size_t, u_int16_t *, bus_size_t); 133 void __C(CHIP,_io_read_multi_4)(void *, bus_space_handle_t, 134 bus_size_t, u_int32_t *, bus_size_t); 135 void __C(CHIP,_io_read_multi_8)(void *, bus_space_handle_t, 136 bus_size_t, u_int64_t *, bus_size_t); 137 138 /* read region */ 139 void __C(CHIP,_io_read_region_1)(void *, bus_space_handle_t, 140 bus_size_t, u_int8_t *, bus_size_t); 141 void __C(CHIP,_io_read_region_2)(void *, bus_space_handle_t, 142 bus_size_t, u_int16_t *, bus_size_t); 143 void __C(CHIP,_io_read_region_4)(void *, bus_space_handle_t, 144 bus_size_t, u_int32_t *, bus_size_t); 145 void __C(CHIP,_io_read_region_8)(void *, bus_space_handle_t, 146 bus_size_t, u_int64_t *, bus_size_t); 147 148 /* write (single) */ 149 inline void __C(CHIP,_io_write_1)(void *, bus_space_handle_t, 150 bus_size_t, u_int8_t); 151 inline void __C(CHIP,_io_write_2)(void *, bus_space_handle_t, 152 bus_size_t, u_int16_t); 153 inline void __C(CHIP,_io_write_4)(void *, bus_space_handle_t, 154 bus_size_t, u_int32_t); 155 inline void __C(CHIP,_io_write_8)(void *, bus_space_handle_t, 156 bus_size_t, u_int64_t); 157 158 /* write multiple */ 159 void __C(CHIP,_io_write_multi_1)(void *, bus_space_handle_t, 160 bus_size_t, const u_int8_t *, bus_size_t); 161 void __C(CHIP,_io_write_multi_2)(void *, bus_space_handle_t, 162 bus_size_t, const u_int16_t *, bus_size_t); 163 void __C(CHIP,_io_write_multi_4)(void *, bus_space_handle_t, 164 bus_size_t, const u_int32_t *, bus_size_t); 165 void __C(CHIP,_io_write_multi_8)(void *, bus_space_handle_t, 166 bus_size_t, const u_int64_t *, bus_size_t); 167 168 /* write region */ 169 void __C(CHIP,_io_write_region_1)(void *, bus_space_handle_t, 170 bus_size_t, const u_int8_t *, bus_size_t); 171 void __C(CHIP,_io_write_region_2)(void *, bus_space_handle_t, 172 bus_size_t, const u_int16_t *, bus_size_t); 173 void __C(CHIP,_io_write_region_4)(void *, bus_space_handle_t, 174 bus_size_t, const u_int32_t *, bus_size_t); 175 void __C(CHIP,_io_write_region_8)(void *, bus_space_handle_t, 176 bus_size_t, const u_int64_t *, bus_size_t); 177 178 /* set multiple */ 179 void __C(CHIP,_io_set_multi_1)(void *, bus_space_handle_t, 180 bus_size_t, u_int8_t, bus_size_t); 181 void __C(CHIP,_io_set_multi_2)(void *, bus_space_handle_t, 182 bus_size_t, u_int16_t, bus_size_t); 183 void __C(CHIP,_io_set_multi_4)(void *, bus_space_handle_t, 184 bus_size_t, u_int32_t, bus_size_t); 185 void __C(CHIP,_io_set_multi_8)(void *, bus_space_handle_t, 186 bus_size_t, u_int64_t, bus_size_t); 187 188 /* set region */ 189 void __C(CHIP,_io_set_region_1)(void *, bus_space_handle_t, 190 bus_size_t, u_int8_t, bus_size_t); 191 void __C(CHIP,_io_set_region_2)(void *, bus_space_handle_t, 192 bus_size_t, u_int16_t, bus_size_t); 193 void __C(CHIP,_io_set_region_4)(void *, bus_space_handle_t, 194 bus_size_t, u_int32_t, bus_size_t); 195 void __C(CHIP,_io_set_region_8)(void *, bus_space_handle_t, 196 bus_size_t, u_int64_t, bus_size_t); 197 198 /* copy */ 199 void __C(CHIP,_io_copy_region_1)(void *, bus_space_handle_t, 200 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t); 201 void __C(CHIP,_io_copy_region_2)(void *, bus_space_handle_t, 202 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t); 203 void __C(CHIP,_io_copy_region_4)(void *, bus_space_handle_t, 204 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t); 205 void __C(CHIP,_io_copy_region_8)(void *, bus_space_handle_t, 206 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t); 207 208 #ifndef CHIP_IO_EX_STORE 209 static long 210 __C(CHIP,_io_ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 211 #define CHIP_IO_EX_STORE(v) (__C(CHIP, _io_ex_storage)) 212 #define CHIP_IO_EX_STORE_SIZE(v) (sizeof __C(CHIP, _io_ex_storage)) 213 #endif 214 215 void 216 __C(CHIP,_bus_io_init)(t, v) 217 bus_space_tag_t t; 218 void *v; 219 { 220 struct extent *ex; 221 222 /* 223 * Initialize the bus space tag. 224 */ 225 226 /* cookie */ 227 t->abs_cookie = v; 228 229 /* mapping/unmapping */ 230 t->abs_map = __C(CHIP,_io_map); 231 t->abs_unmap = __C(CHIP,_io_unmap); 232 t->abs_subregion = __C(CHIP,_io_subregion); 233 234 t->abs_translate = __C(CHIP,_io_translate); 235 t->abs_get_window = __C(CHIP,_io_get_window); 236 237 /* allocation/deallocation */ 238 t->abs_alloc = __C(CHIP,_io_alloc); 239 t->abs_free = __C(CHIP,_io_free); 240 241 /* get kernel virtual address */ 242 t->abs_vaddr = __C(CHIP,_io_vaddr); 243 244 /* mmap for user */ 245 t->abs_mmap = __C(CHIP,_io_mmap); 246 247 /* barrier */ 248 t->abs_barrier = __C(CHIP,_io_barrier); 249 250 /* read (single) */ 251 t->abs_r_1 = __C(CHIP,_io_read_1); 252 t->abs_r_2 = __C(CHIP,_io_read_2); 253 t->abs_r_4 = __C(CHIP,_io_read_4); 254 t->abs_r_8 = __C(CHIP,_io_read_8); 255 256 /* read multiple */ 257 t->abs_rm_1 = __C(CHIP,_io_read_multi_1); 258 t->abs_rm_2 = __C(CHIP,_io_read_multi_2); 259 t->abs_rm_4 = __C(CHIP,_io_read_multi_4); 260 t->abs_rm_8 = __C(CHIP,_io_read_multi_8); 261 262 /* read region */ 263 t->abs_rr_1 = __C(CHIP,_io_read_region_1); 264 t->abs_rr_2 = __C(CHIP,_io_read_region_2); 265 t->abs_rr_4 = __C(CHIP,_io_read_region_4); 266 t->abs_rr_8 = __C(CHIP,_io_read_region_8); 267 268 /* write (single) */ 269 t->abs_w_1 = __C(CHIP,_io_write_1); 270 t->abs_w_2 = __C(CHIP,_io_write_2); 271 t->abs_w_4 = __C(CHIP,_io_write_4); 272 t->abs_w_8 = __C(CHIP,_io_write_8); 273 274 /* write multiple */ 275 t->abs_wm_1 = __C(CHIP,_io_write_multi_1); 276 t->abs_wm_2 = __C(CHIP,_io_write_multi_2); 277 t->abs_wm_4 = __C(CHIP,_io_write_multi_4); 278 t->abs_wm_8 = __C(CHIP,_io_write_multi_8); 279 280 /* write region */ 281 t->abs_wr_1 = __C(CHIP,_io_write_region_1); 282 t->abs_wr_2 = __C(CHIP,_io_write_region_2); 283 t->abs_wr_4 = __C(CHIP,_io_write_region_4); 284 t->abs_wr_8 = __C(CHIP,_io_write_region_8); 285 286 /* set multiple */ 287 t->abs_sm_1 = __C(CHIP,_io_set_multi_1); 288 t->abs_sm_2 = __C(CHIP,_io_set_multi_2); 289 t->abs_sm_4 = __C(CHIP,_io_set_multi_4); 290 t->abs_sm_8 = __C(CHIP,_io_set_multi_8); 291 292 /* set region */ 293 t->abs_sr_1 = __C(CHIP,_io_set_region_1); 294 t->abs_sr_2 = __C(CHIP,_io_set_region_2); 295 t->abs_sr_4 = __C(CHIP,_io_set_region_4); 296 t->abs_sr_8 = __C(CHIP,_io_set_region_8); 297 298 /* copy */ 299 t->abs_c_1 = __C(CHIP,_io_copy_region_1); 300 t->abs_c_2 = __C(CHIP,_io_copy_region_2); 301 t->abs_c_4 = __C(CHIP,_io_copy_region_4); 302 t->abs_c_8 = __C(CHIP,_io_copy_region_8); 303 304 ex = extent_create(__S(__C(CHIP,_bus_io)), 0x0UL, 0xffffffffUL, 305 M_DEVBUF, (void *)CHIP_IO_EX_STORE(v), CHIP_IO_EX_STORE_SIZE(v), 306 EX_NOWAIT|EX_NOCOALESCE); 307 308 CHIP_IO_EXTENT(v) = ex; 309 } 310 311 int 312 __C(CHIP,_io_translate)(v, ioaddr, iolen, flags, abst) 313 void *v; 314 bus_addr_t ioaddr; 315 bus_size_t iolen; 316 int flags; 317 struct alpha_bus_space_translation *abst; 318 { 319 int linear = flags & BUS_SPACE_MAP_LINEAR; 320 321 /* 322 * Can't map i/o space linearly. 323 */ 324 if (linear) 325 return (EOPNOTSUPP); 326 327 return (__C(CHIP,_io_get_window)(v, 0, abst)); 328 } 329 330 int 331 __C(CHIP,_io_get_window)(v, window, abst) 332 void *v; 333 int window; 334 struct alpha_bus_space_translation *abst; 335 { 336 337 switch (window) { 338 case 0: 339 abst->abst_bus_start = 0; 340 abst->abst_bus_end = 0xffffffffUL; 341 abst->abst_sys_start = CHIP_IO_SYS_START(v); 342 abst->abst_sys_end = CHIP_IO_SYS_START(v) + abst->abst_bus_end; 343 abst->abst_addr_shift = 0; 344 abst->abst_size_shift = 0; 345 abst->abst_flags = ABST_DENSE|ABST_BWX; 346 break; 347 348 default: 349 panic(__S(__C(CHIP,_io_get_window)) ": invalid window %d", 350 window); 351 } 352 353 return (0); 354 } 355 356 int 357 __C(CHIP,_io_map)(v, ioaddr, iosize, flags, iohp, acct) 358 void *v; 359 bus_addr_t ioaddr; 360 bus_size_t iosize; 361 int flags; 362 bus_space_handle_t *iohp; 363 int acct; 364 { 365 struct alpha_bus_space_translation abst; 366 int error; 367 368 /* 369 * Get the translation for this address. 370 */ 371 error = __C(CHIP,_io_translate)(v, ioaddr, iosize, flags, &abst); 372 if (error) 373 return (error); 374 375 if (acct == 0) 376 goto mapit; 377 378 #ifdef EXTENT_DEBUG 379 printf("io: allocating 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1); 380 #endif 381 error = extent_alloc_region(CHIP_IO_EXTENT(v), ioaddr, iosize, 382 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 383 if (error) { 384 #ifdef EXTENT_DEBUG 385 printf("io: allocation failed (%d)\n", error); 386 extent_print(CHIP_IO_EXTENT(v)); 387 #endif 388 return (error); 389 } 390 391 mapit: 392 *iohp = ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start + ioaddr); 393 394 return (0); 395 } 396 397 void 398 __C(CHIP,_io_unmap)(v, ioh, iosize, acct) 399 void *v; 400 bus_space_handle_t ioh; 401 bus_size_t iosize; 402 int acct; 403 { 404 bus_addr_t ioaddr; 405 int error; 406 407 if (acct == 0) 408 return; 409 410 #ifdef EXTENT_DEBUG 411 printf("io: freeing handle 0x%lx for 0x%lx\n", ioh, iosize); 412 #endif 413 414 ioaddr = ioh - ALPHA_PHYS_TO_K0SEG(CHIP_IO_SYS_START(v)); 415 416 #ifdef EXTENT_DEBUG 417 printf("io: freeing 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1); 418 #endif 419 error = extent_free(CHIP_IO_EXTENT(v), ioaddr, iosize, 420 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 421 if (error) { 422 printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n", 423 __S(__C(CHIP,_io_unmap)), ioaddr, ioaddr + iosize - 1, 424 error); 425 #ifdef EXTENT_DEBUG 426 extent_print(CHIP_IO_EXTENT(v)); 427 #endif 428 } 429 } 430 431 int 432 __C(CHIP,_io_subregion)(v, ioh, offset, size, nioh) 433 void *v; 434 bus_space_handle_t ioh, *nioh; 435 bus_size_t offset, size; 436 { 437 438 *nioh = ioh + offset; 439 return (0); 440 } 441 442 int 443 __C(CHIP,_io_alloc)(v, rstart, rend, size, align, boundary, flags, 444 addrp, bshp) 445 void *v; 446 bus_addr_t rstart, rend, *addrp; 447 bus_size_t size, align, boundary; 448 int flags; 449 bus_space_handle_t *bshp; 450 { 451 struct alpha_bus_space_translation abst; 452 int linear = flags & BUS_SPACE_MAP_LINEAR; 453 bus_addr_t ioaddr; 454 int error; 455 456 /* 457 * Can't map i/o space linearly. 458 */ 459 if (linear) 460 return (EOPNOTSUPP); 461 462 /* 463 * Do the requested allocation. 464 */ 465 #ifdef EXTENT_DEBUG 466 printf("io: allocating from 0x%lx to 0x%lx\n", rstart, rend); 467 #endif 468 error = extent_alloc_subregion(CHIP_IO_EXTENT(v), rstart, rend, 469 size, align, boundary, 470 EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0), 471 &ioaddr); 472 if (error) { 473 #ifdef EXTENT_DEBUG 474 printf("io: allocation failed (%d)\n", error); 475 extent_print(CHIP_IO_EXTENT(v)); 476 #endif 477 return (error); 478 } 479 480 #ifdef EXTENT_DEBUG 481 printf("io: allocated 0x%lx to 0x%lx\n", ioaddr, ioaddr + size - 1); 482 #endif 483 484 error = __C(CHIP,_io_translate)(v, ioaddr, size, flags, &abst); 485 if (error) { 486 (void) extent_free(CHIP_IO_EXTENT(v), ioaddr, size, 487 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 488 return (error); 489 } 490 491 *addrp = ioaddr; 492 *bshp = ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start + ioaddr); 493 494 return (0); 495 } 496 497 void 498 __C(CHIP,_io_free)(v, bsh, size) 499 void *v; 500 bus_space_handle_t bsh; 501 bus_size_t size; 502 { 503 504 /* Unmap does all we need to do. */ 505 __C(CHIP,_io_unmap)(v, bsh, size, 1); 506 } 507 508 void * 509 __C(CHIP,_io_vaddr)(v, bsh) 510 void *v; 511 bus_space_handle_t bsh; 512 { 513 /* 514 * _io_translate() catches BUS_SPACE_MAP_LINEAR, 515 * so we shouldn't get here 516 */ 517 panic("_io_vaddr"); 518 } 519 520 paddr_t 521 __C(CHIP,_io_mmap)(v, addr, off, prot, flags) 522 void *v; 523 bus_addr_t addr; 524 off_t off; 525 int prot; 526 int flags; 527 { 528 529 /* Not supported for I/O space. */ 530 return (-1); 531 } 532 533 inline void 534 __C(CHIP,_io_barrier)(v, h, o, l, f) 535 void *v; 536 bus_space_handle_t h; 537 bus_size_t o, l; 538 int f; 539 { 540 541 if ((f & BUS_SPACE_BARRIER_READ) != 0) 542 alpha_mb(); 543 else if ((f & BUS_SPACE_BARRIER_WRITE) != 0) 544 alpha_wmb(); 545 } 546 547 inline u_int8_t 548 __C(CHIP,_io_read_1)(v, ioh, off) 549 void *v; 550 bus_space_handle_t ioh; 551 bus_size_t off; 552 { 553 bus_addr_t addr; 554 555 addr = ioh + off; 556 alpha_mb(); 557 return (alpha_ldbu((u_int8_t *)addr)); 558 } 559 560 inline u_int16_t 561 __C(CHIP,_io_read_2)(v, ioh, off) 562 void *v; 563 bus_space_handle_t ioh; 564 bus_size_t off; 565 { 566 bus_addr_t addr; 567 568 addr = ioh + off; 569 #ifdef DIAGNOSTIC 570 if (addr & 1) 571 panic(__S(__C(CHIP,_io_read_2)) ": addr 0x%lx not aligned", 572 addr); 573 #endif 574 alpha_mb(); 575 return (alpha_ldwu((u_int16_t *)addr)); 576 } 577 578 inline u_int32_t 579 __C(CHIP,_io_read_4)(v, ioh, off) 580 void *v; 581 bus_space_handle_t ioh; 582 bus_size_t off; 583 { 584 bus_addr_t addr; 585 586 addr = ioh + off; 587 #ifdef DIAGNOSTIC 588 if (addr & 3) 589 panic(__S(__C(CHIP,_io_read_4)) ": addr 0x%lx not aligned", 590 addr); 591 #endif 592 alpha_mb(); 593 return (*(u_int32_t *)addr); 594 } 595 596 inline u_int64_t 597 __C(CHIP,_io_read_8)(v, ioh, off) 598 void *v; 599 bus_space_handle_t ioh; 600 bus_size_t off; 601 { 602 603 /* XXX XXX XXX */ 604 panic("%s not implemented", __S(__C(CHIP,_io_read_8))); 605 } 606 607 #define CHIP_io_read_multi_N(BYTES,TYPE) \ 608 void \ 609 __C(__C(CHIP,_io_read_multi_),BYTES)(v, h, o, a, c) \ 610 void *v; \ 611 bus_space_handle_t h; \ 612 bus_size_t o, c; \ 613 TYPE *a; \ 614 { \ 615 \ 616 while (c-- > 0) { \ 617 __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \ 618 BUS_SPACE_BARRIER_READ); \ 619 *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \ 620 } \ 621 } 622 CHIP_io_read_multi_N(1,u_int8_t) 623 CHIP_io_read_multi_N(2,u_int16_t) 624 CHIP_io_read_multi_N(4,u_int32_t) 625 CHIP_io_read_multi_N(8,u_int64_t) 626 627 #define CHIP_io_read_region_N(BYTES,TYPE) \ 628 void \ 629 __C(__C(CHIP,_io_read_region_),BYTES)(v, h, o, a, c) \ 630 void *v; \ 631 bus_space_handle_t h; \ 632 bus_size_t o, c; \ 633 TYPE *a; \ 634 { \ 635 \ 636 while (c-- > 0) { \ 637 *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \ 638 o += sizeof *a; \ 639 } \ 640 } 641 CHIP_io_read_region_N(1,u_int8_t) 642 CHIP_io_read_region_N(2,u_int16_t) 643 CHIP_io_read_region_N(4,u_int32_t) 644 CHIP_io_read_region_N(8,u_int64_t) 645 646 inline void 647 __C(CHIP,_io_write_1)(v, ioh, off, val) 648 void *v; 649 bus_space_handle_t ioh; 650 bus_size_t off; 651 u_int8_t val; 652 { 653 bus_addr_t addr; 654 655 addr = ioh + off; 656 alpha_stb((u_int8_t *)addr, val); 657 alpha_mb(); 658 } 659 660 inline void 661 __C(CHIP,_io_write_2)(v, ioh, off, val) 662 void *v; 663 bus_space_handle_t ioh; 664 bus_size_t off; 665 u_int16_t val; 666 { 667 bus_addr_t addr; 668 669 addr = ioh + off; 670 #ifdef DIAGNOSTIC 671 if (addr & 1) 672 panic(__S(__C(CHIP,_io_write_2)) ": addr 0x%lx not aligned", 673 addr); 674 #endif 675 alpha_stw((u_int16_t *)addr, val); 676 alpha_mb(); 677 } 678 679 inline void 680 __C(CHIP,_io_write_4)(v, ioh, off, val) 681 void *v; 682 bus_space_handle_t ioh; 683 bus_size_t off; 684 u_int32_t val; 685 { 686 bus_addr_t addr; 687 688 addr = ioh + off; 689 #ifdef DIAGNOSTIC 690 if (addr & 3) 691 panic(__S(__C(CHIP,_io_write_4)) ": addr 0x%lx not aligned", 692 addr); 693 #endif 694 *(u_int32_t *)addr = val; 695 alpha_mb(); 696 } 697 698 inline void 699 __C(CHIP,_io_write_8)(v, ioh, off, val) 700 void *v; 701 bus_space_handle_t ioh; 702 bus_size_t off; 703 u_int64_t val; 704 { 705 706 /* XXX XXX XXX */ 707 panic("%s not implemented", __S(__C(CHIP,_io_write_8))); 708 alpha_mb(); 709 } 710 711 #define CHIP_io_write_multi_N(BYTES,TYPE) \ 712 void \ 713 __C(__C(CHIP,_io_write_multi_),BYTES)(v, h, o, a, c) \ 714 void *v; \ 715 bus_space_handle_t h; \ 716 bus_size_t o, c; \ 717 const TYPE *a; \ 718 { \ 719 \ 720 while (c-- > 0) { \ 721 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \ 722 __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \ 723 BUS_SPACE_BARRIER_WRITE); \ 724 } \ 725 } 726 CHIP_io_write_multi_N(1,u_int8_t) 727 CHIP_io_write_multi_N(2,u_int16_t) 728 CHIP_io_write_multi_N(4,u_int32_t) 729 CHIP_io_write_multi_N(8,u_int64_t) 730 731 #define CHIP_io_write_region_N(BYTES,TYPE) \ 732 void \ 733 __C(__C(CHIP,_io_write_region_),BYTES)(v, h, o, a, c) \ 734 void *v; \ 735 bus_space_handle_t h; \ 736 bus_size_t o, c; \ 737 const TYPE *a; \ 738 { \ 739 \ 740 while (c-- > 0) { \ 741 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \ 742 o += sizeof *a; \ 743 } \ 744 } 745 CHIP_io_write_region_N(1,u_int8_t) 746 CHIP_io_write_region_N(2,u_int16_t) 747 CHIP_io_write_region_N(4,u_int32_t) 748 CHIP_io_write_region_N(8,u_int64_t) 749 750 #define CHIP_io_set_multi_N(BYTES,TYPE) \ 751 void \ 752 __C(__C(CHIP,_io_set_multi_),BYTES)(v, h, o, val, c) \ 753 void *v; \ 754 bus_space_handle_t h; \ 755 bus_size_t o, c; \ 756 TYPE val; \ 757 { \ 758 \ 759 while (c-- > 0) { \ 760 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, val); \ 761 __C(CHIP,_io_barrier)(v, h, o, sizeof val, \ 762 BUS_SPACE_BARRIER_WRITE); \ 763 } \ 764 } 765 CHIP_io_set_multi_N(1,u_int8_t) 766 CHIP_io_set_multi_N(2,u_int16_t) 767 CHIP_io_set_multi_N(4,u_int32_t) 768 CHIP_io_set_multi_N(8,u_int64_t) 769 770 #define CHIP_io_set_region_N(BYTES,TYPE) \ 771 void \ 772 __C(__C(CHIP,_io_set_region_),BYTES)(v, h, o, val, c) \ 773 void *v; \ 774 bus_space_handle_t h; \ 775 bus_size_t o, c; \ 776 TYPE val; \ 777 { \ 778 \ 779 while (c-- > 0) { \ 780 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, val); \ 781 o += sizeof val; \ 782 } \ 783 } 784 CHIP_io_set_region_N(1,u_int8_t) 785 CHIP_io_set_region_N(2,u_int16_t) 786 CHIP_io_set_region_N(4,u_int32_t) 787 CHIP_io_set_region_N(8,u_int64_t) 788 789 #define CHIP_io_copy_region_N(BYTES) \ 790 void \ 791 __C(__C(CHIP,_io_copy_region_),BYTES)(v, h1, o1, h2, o2, c) \ 792 void *v; \ 793 bus_space_handle_t h1, h2; \ 794 bus_size_t o1, o2, c; \ 795 { \ 796 bus_size_t o; \ 797 \ 798 if ((h1 + o1) >= (h2 + o2)) { \ 799 /* src after dest: copy forward */ \ 800 for (o = 0; c != 0; c--, o += BYTES) { \ 801 __C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o, \ 802 __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \ 803 } \ 804 } else { \ 805 /* dest after src: copy backwards */ \ 806 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) { \ 807 __C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o, \ 808 __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \ 809 } \ 810 } \ 811 } 812 CHIP_io_copy_region_N(1) 813 CHIP_io_copy_region_N(2) 814 CHIP_io_copy_region_N(4) 815 CHIP_io_copy_region_N(8) 816