1/* $NetBSD: pci_bwx_bus_io_chipdep.c,v 1.20 2012/01/27 18:52:49 para 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.20 2012/01/27 18:52:49 para 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 */ 89int __C(CHIP,_io_map)(void *, bus_addr_t, bus_size_t, int, 90 bus_space_handle_t *, int); 91void __C(CHIP,_io_unmap)(void *, bus_space_handle_t, 92 bus_size_t, int); 93int __C(CHIP,_io_subregion)(void *, bus_space_handle_t, 94 bus_size_t, bus_size_t, bus_space_handle_t *); 95 96int __C(CHIP,_io_translate)(void *, bus_addr_t, bus_size_t, 97 int, struct alpha_bus_space_translation *); 98int __C(CHIP,_io_get_window)(void *, int, 99 struct alpha_bus_space_translation *); 100 101/* allocation/deallocation */ 102int __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 *); 105void __C(CHIP,_io_free)(void *, bus_space_handle_t, 106 bus_size_t); 107 108/* get kernel virtual address */ 109void * __C(CHIP,_io_vaddr)(void *, bus_space_handle_t); 110 111/* mmap for user */ 112paddr_t __C(CHIP,_io_mmap)(void *, bus_addr_t, off_t, int, int); 113 114/* barrier */ 115static inline void __C(CHIP,_io_barrier)(void *, bus_space_handle_t, 116 bus_size_t, bus_size_t, int); 117 118/* read (single) */ 119static inline uint8_t __C(CHIP,_io_read_1)(void *, bus_space_handle_t, 120 bus_size_t); 121static inline uint16_t __C(CHIP,_io_read_2)(void *, bus_space_handle_t, 122 bus_size_t); 123static inline uint32_t __C(CHIP,_io_read_4)(void *, bus_space_handle_t, 124 bus_size_t); 125static inline uint64_t __C(CHIP,_io_read_8)(void *, bus_space_handle_t, 126 bus_size_t); 127 128/* read multiple */ 129void __C(CHIP,_io_read_multi_1)(void *, bus_space_handle_t, 130 bus_size_t, uint8_t *, bus_size_t); 131void __C(CHIP,_io_read_multi_2)(void *, bus_space_handle_t, 132 bus_size_t, uint16_t *, bus_size_t); 133void __C(CHIP,_io_read_multi_4)(void *, bus_space_handle_t, 134 bus_size_t, uint32_t *, bus_size_t); 135void __C(CHIP,_io_read_multi_8)(void *, bus_space_handle_t, 136 bus_size_t, uint64_t *, bus_size_t); 137 138/* read region */ 139void __C(CHIP,_io_read_region_1)(void *, bus_space_handle_t, 140 bus_size_t, uint8_t *, bus_size_t); 141void __C(CHIP,_io_read_region_2)(void *, bus_space_handle_t, 142 bus_size_t, uint16_t *, bus_size_t); 143void __C(CHIP,_io_read_region_4)(void *, bus_space_handle_t, 144 bus_size_t, uint32_t *, bus_size_t); 145void __C(CHIP,_io_read_region_8)(void *, bus_space_handle_t, 146 bus_size_t, uint64_t *, bus_size_t); 147 148/* write (single) */ 149static inline void __C(CHIP,_io_write_1)(void *, bus_space_handle_t, 150 bus_size_t, uint8_t); 151static inline void __C(CHIP,_io_write_2)(void *, bus_space_handle_t, 152 bus_size_t, uint16_t); 153static inline void __C(CHIP,_io_write_4)(void *, bus_space_handle_t, 154 bus_size_t, uint32_t); 155static inline void __C(CHIP,_io_write_8)(void *, bus_space_handle_t, 156 bus_size_t, uint64_t); 157 158/* write multiple */ 159void __C(CHIP,_io_write_multi_1)(void *, bus_space_handle_t, 160 bus_size_t, const uint8_t *, bus_size_t); 161void __C(CHIP,_io_write_multi_2)(void *, bus_space_handle_t, 162 bus_size_t, const uint16_t *, bus_size_t); 163void __C(CHIP,_io_write_multi_4)(void *, bus_space_handle_t, 164 bus_size_t, const uint32_t *, bus_size_t); 165void __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 */ 169void __C(CHIP,_io_write_region_1)(void *, bus_space_handle_t, 170 bus_size_t, const uint8_t *, bus_size_t); 171void __C(CHIP,_io_write_region_2)(void *, bus_space_handle_t, 172 bus_size_t, const uint16_t *, bus_size_t); 173void __C(CHIP,_io_write_region_4)(void *, bus_space_handle_t, 174 bus_size_t, const uint32_t *, bus_size_t); 175void __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 */ 179void __C(CHIP,_io_set_multi_1)(void *, bus_space_handle_t, 180 bus_size_t, uint8_t, bus_size_t); 181void __C(CHIP,_io_set_multi_2)(void *, bus_space_handle_t, 182 bus_size_t, uint16_t, bus_size_t); 183void __C(CHIP,_io_set_multi_4)(void *, bus_space_handle_t, 184 bus_size_t, uint32_t, bus_size_t); 185void __C(CHIP,_io_set_multi_8)(void *, bus_space_handle_t, 186 bus_size_t, uint64_t, bus_size_t); 187 188/* set region */ 189void __C(CHIP,_io_set_region_1)(void *, bus_space_handle_t, 190 bus_size_t, uint8_t, bus_size_t); 191void __C(CHIP,_io_set_region_2)(void *, bus_space_handle_t, 192 bus_size_t, uint16_t, bus_size_t); 193void __C(CHIP,_io_set_region_4)(void *, bus_space_handle_t, 194 bus_size_t, uint32_t, bus_size_t); 195void __C(CHIP,_io_set_region_8)(void *, bus_space_handle_t, 196 bus_size_t, uint64_t, bus_size_t); 197 198/* copy */ 199void __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); 201void __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); 203void __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); 205void __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 209static 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 215void 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 311int 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 330int 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 356int 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 397void 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 431int 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 444int 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 502void 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 513void * 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 525paddr_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 538static 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 553static 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 566static 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 584static 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 602static 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) \ 614void \ 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} 629CHIP_io_read_multi_N(1,uint8_t) 630CHIP_io_read_multi_N(2,uint16_t) 631CHIP_io_read_multi_N(4,uint32_t) 632CHIP_io_read_multi_N(8,uint64_t) 633 634#define CHIP_io_read_region_N(BYTES,TYPE) \ 635void \ 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} 649CHIP_io_read_region_N(1,uint8_t) 650CHIP_io_read_region_N(2,uint16_t) 651CHIP_io_read_region_N(4,uint32_t) 652CHIP_io_read_region_N(8,uint64_t) 653 654static 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 668static 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 687static 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 706static 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) \ 720void \ 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} 735CHIP_io_write_multi_N(1,uint8_t) 736CHIP_io_write_multi_N(2,uint16_t) 737CHIP_io_write_multi_N(4,uint32_t) 738CHIP_io_write_multi_N(8,uint64_t) 739 740#define CHIP_io_write_region_N(BYTES,TYPE) \ 741void \ 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} 755CHIP_io_write_region_N(1,uint8_t) 756CHIP_io_write_region_N(2,uint16_t) 757CHIP_io_write_region_N(4,uint32_t) 758CHIP_io_write_region_N(8,uint64_t) 759 760#define CHIP_io_set_multi_N(BYTES,TYPE) \ 761void \ 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} 776CHIP_io_set_multi_N(1,uint8_t) 777CHIP_io_set_multi_N(2,uint16_t) 778CHIP_io_set_multi_N(4,uint32_t) 779CHIP_io_set_multi_N(8,uint64_t) 780 781#define CHIP_io_set_region_N(BYTES,TYPE) \ 782void \ 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} 796CHIP_io_set_region_N(1,uint8_t) 797CHIP_io_set_region_N(2,uint16_t) 798CHIP_io_set_region_N(4,uint32_t) 799CHIP_io_set_region_N(8,uint64_t) 800 801#define CHIP_io_copy_region_N(BYTES) \ 802void \ 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} 827CHIP_io_copy_region_N(1) 828CHIP_io_copy_region_N(2) 829CHIP_io_copy_region_N(4) 830CHIP_io_copy_region_N(8) 831