1 /* $NetBSD: pci_bwx_bus_io_chipdep.c,v 1.21 2012/02/06 02:14:15 matt 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.21 2012/02/06 02:14:15 matt 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 static inline void __C(CHIP,_io_barrier)(void *, bus_space_handle_t, 116 bus_size_t, bus_size_t, int); 117 118 /* read (single) */ 119 static inline uint8_t __C(CHIP,_io_read_1)(void *, bus_space_handle_t, 120 bus_size_t); 121 static inline uint16_t __C(CHIP,_io_read_2)(void *, bus_space_handle_t, 122 bus_size_t); 123 static inline uint32_t __C(CHIP,_io_read_4)(void *, bus_space_handle_t, 124 bus_size_t); 125 static inline uint64_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, uint8_t *, bus_size_t); 131 void __C(CHIP,_io_read_multi_2)(void *, bus_space_handle_t, 132 bus_size_t, uint16_t *, bus_size_t); 133 void __C(CHIP,_io_read_multi_4)(void *, bus_space_handle_t, 134 bus_size_t, uint32_t *, bus_size_t); 135 void __C(CHIP,_io_read_multi_8)(void *, bus_space_handle_t, 136 bus_size_t, uint64_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, uint8_t *, bus_size_t); 141 void __C(CHIP,_io_read_region_2)(void *, bus_space_handle_t, 142 bus_size_t, uint16_t *, bus_size_t); 143 void __C(CHIP,_io_read_region_4)(void *, bus_space_handle_t, 144 bus_size_t, uint32_t *, bus_size_t); 145 void __C(CHIP,_io_read_region_8)(void *, bus_space_handle_t, 146 bus_size_t, uint64_t *, bus_size_t); 147 148 /* write (single) */ 149 static inline void __C(CHIP,_io_write_1)(void *, bus_space_handle_t, 150 bus_size_t, uint8_t); 151 static inline void __C(CHIP,_io_write_2)(void *, bus_space_handle_t, 152 bus_size_t, uint16_t); 153 static inline void __C(CHIP,_io_write_4)(void *, bus_space_handle_t, 154 bus_size_t, uint32_t); 155 static inline void __C(CHIP,_io_write_8)(void *, bus_space_handle_t, 156 bus_size_t, uint64_t); 157 158 /* write multiple */ 159 void __C(CHIP,_io_write_multi_1)(void *, bus_space_handle_t, 160 bus_size_t, const uint8_t *, bus_size_t); 161 void __C(CHIP,_io_write_multi_2)(void *, bus_space_handle_t, 162 bus_size_t, const uint16_t *, bus_size_t); 163 void __C(CHIP,_io_write_multi_4)(void *, bus_space_handle_t, 164 bus_size_t, const uint32_t *, bus_size_t); 165 void __C(CHIP,_io_write_multi_8)(void *, bus_space_handle_t, 166 bus_size_t, const uint64_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 uint8_t *, bus_size_t); 171 void __C(CHIP,_io_write_region_2)(void *, bus_space_handle_t, 172 bus_size_t, const uint16_t *, bus_size_t); 173 void __C(CHIP,_io_write_region_4)(void *, bus_space_handle_t, 174 bus_size_t, const uint32_t *, bus_size_t); 175 void __C(CHIP,_io_write_region_8)(void *, bus_space_handle_t, 176 bus_size_t, const uint64_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, uint8_t, bus_size_t); 181 void __C(CHIP,_io_set_multi_2)(void *, bus_space_handle_t, 182 bus_size_t, uint16_t, bus_size_t); 183 void __C(CHIP,_io_set_multi_4)(void *, bus_space_handle_t, 184 bus_size_t, uint32_t, bus_size_t); 185 void __C(CHIP,_io_set_multi_8)(void *, bus_space_handle_t, 186 bus_size_t, uint64_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, uint8_t, bus_size_t); 191 void __C(CHIP,_io_set_region_2)(void *, bus_space_handle_t, 192 bus_size_t, uint16_t, bus_size_t); 193 void __C(CHIP,_io_set_region_4)(void *, bus_space_handle_t, 194 bus_size_t, uint32_t, bus_size_t); 195 void __C(CHIP,_io_set_region_8)(void *, bus_space_handle_t, 196 bus_size_t, uint64_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)( 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 (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)( 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)( 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)( 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)( 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)( 433 void *v, 434 bus_space_handle_t ioh, 435 bus_size_t offset, 436 bus_size_t size, 437 bus_space_handle_t *nioh) 438 { 439 440 *nioh = ioh + offset; 441 return (0); 442 } 443 444 int 445 __C(CHIP,_io_alloc)( 446 void *v, 447 bus_addr_t rstart, 448 bus_addr_t rend, 449 bus_size_t size, 450 bus_size_t align, 451 bus_size_t boundary, 452 int flags, 453 bus_addr_t *addrp, 454 bus_space_handle_t *bshp) 455 { 456 struct alpha_bus_space_translation abst; 457 int linear = flags & BUS_SPACE_MAP_LINEAR; 458 bus_addr_t ioaddr; 459 int error; 460 461 /* 462 * Can't map i/o space linearly. 463 */ 464 if (linear) 465 return (EOPNOTSUPP); 466 467 /* 468 * Do the requested allocation. 469 */ 470 #ifdef EXTENT_DEBUG 471 printf("io: allocating from 0x%lx to 0x%lx\n", rstart, rend); 472 #endif 473 error = extent_alloc_subregion(CHIP_IO_EXTENT(v), rstart, rend, 474 size, align, boundary, 475 EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0), 476 &ioaddr); 477 if (error) { 478 #ifdef EXTENT_DEBUG 479 printf("io: allocation failed (%d)\n", error); 480 extent_print(CHIP_IO_EXTENT(v)); 481 #endif 482 return (error); 483 } 484 485 #ifdef EXTENT_DEBUG 486 printf("io: allocated 0x%lx to 0x%lx\n", ioaddr, ioaddr + size - 1); 487 #endif 488 489 error = __C(CHIP,_io_translate)(v, ioaddr, size, flags, &abst); 490 if (error) { 491 (void) extent_free(CHIP_IO_EXTENT(v), ioaddr, size, 492 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 493 return (error); 494 } 495 496 *addrp = ioaddr; 497 *bshp = ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start + ioaddr); 498 499 return (0); 500 } 501 502 void 503 __C(CHIP,_io_free)( 504 void *v, 505 bus_space_handle_t bsh, 506 bus_size_t size) 507 { 508 509 /* Unmap does all we need to do. */ 510 __C(CHIP,_io_unmap)(v, bsh, size, 1); 511 } 512 513 void * 514 __C(CHIP,_io_vaddr)( 515 void *v, 516 bus_space_handle_t bsh) 517 { 518 /* 519 * _io_translate() catches BUS_SPACE_MAP_LINEAR, 520 * so we shouldn't get here 521 */ 522 panic("_io_vaddr"); 523 } 524 525 paddr_t 526 __C(CHIP,_io_mmap)( 527 void *v, 528 bus_addr_t addr, 529 off_t off, 530 int prot, 531 int flags) 532 { 533 534 /* Not supported for I/O space. */ 535 return (-1); 536 } 537 538 static inline void 539 __C(CHIP,_io_barrier)( 540 void *v, 541 bus_space_handle_t h, 542 bus_size_t o, 543 bus_size_t l, 544 int f) 545 { 546 547 if ((f & BUS_SPACE_BARRIER_READ) != 0) 548 alpha_mb(); 549 else if ((f & BUS_SPACE_BARRIER_WRITE) != 0) 550 alpha_wmb(); 551 } 552 553 static inline uint8_t 554 __C(CHIP,_io_read_1)( 555 void *v, 556 bus_space_handle_t ioh, 557 bus_size_t off) 558 { 559 bus_addr_t addr; 560 561 addr = ioh + off; 562 alpha_mb(); 563 return (alpha_ldbu((uint8_t *)addr)); 564 } 565 566 static inline uint16_t 567 __C(CHIP,_io_read_2)( 568 void *v, 569 bus_space_handle_t ioh, 570 bus_size_t off) 571 { 572 bus_addr_t addr; 573 574 addr = ioh + off; 575 #ifdef DIAGNOSTIC 576 if (addr & 1) 577 panic(__S(__C(CHIP,_io_read_2)) ": addr 0x%lx not aligned", 578 addr); 579 #endif 580 alpha_mb(); 581 return (alpha_ldwu((uint16_t *)addr)); 582 } 583 584 static inline uint32_t 585 __C(CHIP,_io_read_4)( 586 void *v, 587 bus_space_handle_t ioh, 588 bus_size_t off) 589 { 590 bus_addr_t addr; 591 592 addr = ioh + off; 593 #ifdef DIAGNOSTIC 594 if (addr & 3) 595 panic(__S(__C(CHIP,_io_read_4)) ": addr 0x%lx not aligned", 596 addr); 597 #endif 598 alpha_mb(); 599 return (*(uint32_t *)addr); 600 } 601 602 static inline uint64_t 603 __C(CHIP,_io_read_8)( 604 void *v, 605 bus_space_handle_t ioh, 606 bus_size_t off) 607 { 608 609 /* XXX XXX XXX */ 610 panic("%s not implemented", __S(__C(CHIP,_io_read_8))); 611 } 612 613 #define CHIP_io_read_multi_N(BYTES,TYPE) \ 614 void \ 615 __C(__C(CHIP,_io_read_multi_),BYTES)( \ 616 void *v, \ 617 bus_space_handle_t h, \ 618 bus_size_t o, \ 619 TYPE *a, \ 620 bus_size_t c) \ 621 { \ 622 \ 623 while (c-- > 0) { \ 624 __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \ 625 BUS_SPACE_BARRIER_READ); \ 626 *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \ 627 } \ 628 } 629 CHIP_io_read_multi_N(1,uint8_t) 630 CHIP_io_read_multi_N(2,uint16_t) 631 CHIP_io_read_multi_N(4,uint32_t) 632 CHIP_io_read_multi_N(8,uint64_t) 633 634 #define CHIP_io_read_region_N(BYTES,TYPE) \ 635 void \ 636 __C(__C(CHIP,_io_read_region_),BYTES)( \ 637 void *v, \ 638 bus_space_handle_t h, \ 639 bus_size_t o, \ 640 TYPE *a, \ 641 bus_size_t c) \ 642 { \ 643 \ 644 while (c-- > 0) { \ 645 *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \ 646 o += sizeof *a; \ 647 } \ 648 } 649 CHIP_io_read_region_N(1,uint8_t) 650 CHIP_io_read_region_N(2,uint16_t) 651 CHIP_io_read_region_N(4,uint32_t) 652 CHIP_io_read_region_N(8,uint64_t) 653 654 static inline void 655 __C(CHIP,_io_write_1)( 656 void *v, 657 bus_space_handle_t ioh, 658 bus_size_t off, 659 uint8_t val) 660 { 661 bus_addr_t addr; 662 663 addr = ioh + off; 664 alpha_stb((uint8_t *)addr, val); 665 alpha_mb(); 666 } 667 668 static inline void 669 __C(CHIP,_io_write_2)( 670 void *v, 671 bus_space_handle_t ioh, 672 bus_size_t off, 673 uint16_t val) 674 { 675 bus_addr_t addr; 676 677 addr = ioh + off; 678 #ifdef DIAGNOSTIC 679 if (addr & 1) 680 panic(__S(__C(CHIP,_io_write_2)) ": addr 0x%lx not aligned", 681 addr); 682 #endif 683 alpha_stw((uint16_t *)addr, val); 684 alpha_mb(); 685 } 686 687 static inline void 688 __C(CHIP,_io_write_4)( 689 void *v, 690 bus_space_handle_t ioh, 691 bus_size_t off, 692 uint32_t val) 693 { 694 bus_addr_t addr; 695 696 addr = ioh + off; 697 #ifdef DIAGNOSTIC 698 if (addr & 3) 699 panic(__S(__C(CHIP,_io_write_4)) ": addr 0x%lx not aligned", 700 addr); 701 #endif 702 *(uint32_t *)addr = val; 703 alpha_mb(); 704 } 705 706 static inline void 707 __C(CHIP,_io_write_8)( 708 void *v, 709 bus_space_handle_t ioh, 710 bus_size_t off, 711 uint64_t val) 712 { 713 714 /* XXX XXX XXX */ 715 panic("%s not implemented", __S(__C(CHIP,_io_write_8))); 716 alpha_mb(); 717 } 718 719 #define CHIP_io_write_multi_N(BYTES,TYPE) \ 720 void \ 721 __C(__C(CHIP,_io_write_multi_),BYTES)( \ 722 void *v, \ 723 bus_space_handle_t h, \ 724 bus_size_t o, \ 725 const TYPE *a, \ 726 bus_size_t c) \ 727 { \ 728 \ 729 while (c-- > 0) { \ 730 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \ 731 __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \ 732 BUS_SPACE_BARRIER_WRITE); \ 733 } \ 734 } 735 CHIP_io_write_multi_N(1,uint8_t) 736 CHIP_io_write_multi_N(2,uint16_t) 737 CHIP_io_write_multi_N(4,uint32_t) 738 CHIP_io_write_multi_N(8,uint64_t) 739 740 #define CHIP_io_write_region_N(BYTES,TYPE) \ 741 void \ 742 __C(__C(CHIP,_io_write_region_),BYTES)( \ 743 void *v, \ 744 bus_space_handle_t h, \ 745 bus_size_t o, \ 746 const TYPE *a, \ 747 bus_size_t c) \ 748 { \ 749 \ 750 while (c-- > 0) { \ 751 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \ 752 o += sizeof *a; \ 753 } \ 754 } 755 CHIP_io_write_region_N(1,uint8_t) 756 CHIP_io_write_region_N(2,uint16_t) 757 CHIP_io_write_region_N(4,uint32_t) 758 CHIP_io_write_region_N(8,uint64_t) 759 760 #define CHIP_io_set_multi_N(BYTES,TYPE) \ 761 void \ 762 __C(__C(CHIP,_io_set_multi_),BYTES)( \ 763 void *v, \ 764 bus_space_handle_t h, \ 765 bus_size_t o, \ 766 TYPE val, \ 767 bus_size_t c) \ 768 { \ 769 \ 770 while (c-- > 0) { \ 771 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, val); \ 772 __C(CHIP,_io_barrier)(v, h, o, sizeof val, \ 773 BUS_SPACE_BARRIER_WRITE); \ 774 } \ 775 } 776 CHIP_io_set_multi_N(1,uint8_t) 777 CHIP_io_set_multi_N(2,uint16_t) 778 CHIP_io_set_multi_N(4,uint32_t) 779 CHIP_io_set_multi_N(8,uint64_t) 780 781 #define CHIP_io_set_region_N(BYTES,TYPE) \ 782 void \ 783 __C(__C(CHIP,_io_set_region_),BYTES)( \ 784 void *v, \ 785 bus_space_handle_t h, \ 786 bus_size_t o, \ 787 TYPE val, \ 788 bus_size_t c) \ 789 { \ 790 \ 791 while (c-- > 0) { \ 792 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, val); \ 793 o += sizeof val; \ 794 } \ 795 } 796 CHIP_io_set_region_N(1,uint8_t) 797 CHIP_io_set_region_N(2,uint16_t) 798 CHIP_io_set_region_N(4,uint32_t) 799 CHIP_io_set_region_N(8,uint64_t) 800 801 #define CHIP_io_copy_region_N(BYTES) \ 802 void \ 803 __C(__C(CHIP,_io_copy_region_),BYTES)( \ 804 void *v, \ 805 bus_space_handle_t h1, \ 806 bus_size_t o1, \ 807 bus_space_handle_t h2, \ 808 bus_size_t o2, \ 809 bus_size_t c) \ 810 { \ 811 bus_size_t o; \ 812 \ 813 if ((h1 + o1) >= (h2 + o2)) { \ 814 /* src after dest: copy forward */ \ 815 for (o = 0; c != 0; c--, o += BYTES) { \ 816 __C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o, \ 817 __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \ 818 } \ 819 } else { \ 820 /* dest after src: copy backwards */ \ 821 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) { \ 822 __C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o, \ 823 __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \ 824 } \ 825 } \ 826 } 827 CHIP_io_copy_region_N(1) 828 CHIP_io_copy_region_N(2) 829 CHIP_io_copy_region_N(4) 830 CHIP_io_copy_region_N(8) 831