1/* $NetBSD: pci_bwx_bus_mem_chipdep.c,v 1.24 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_MEM_BASE Mem space base to use. 67 * CHIP_MEM_EX_STORE 68 * If defined, device-provided static storage area 69 * for the memory space extent. If this is 70 * defined, CHIP_MEM_EX_STORE_SIZE must also be 71 * defined. If this is not defined, a static area 72 * will be declared. 73 * CHIP_MEM_EX_STORE_SIZE 74 * Size of the device-provided static storage area 75 * for the memory space extent. 76 */ 77 78#include <sys/cdefs.h> 79__KERNEL_RCSID(1, "$NetBSD: pci_bwx_bus_mem_chipdep.c,v 1.24 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,_mem_map)(void *, bus_addr_t, bus_size_t, int, 90 bus_space_handle_t *, int); 91void __C(CHIP,_mem_unmap)(void *, bus_space_handle_t, 92 bus_size_t, int); 93int __C(CHIP,_mem_subregion)(void *, bus_space_handle_t, 94 bus_size_t, bus_size_t, bus_space_handle_t *); 95 96int __C(CHIP,_mem_translate)(void *, bus_addr_t, bus_size_t, 97 int, struct alpha_bus_space_translation *); 98int __C(CHIP,_mem_get_window)(void *, int, 99 struct alpha_bus_space_translation *); 100 101/* allocation/deallocation */ 102int __C(CHIP,_mem_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,_mem_free)(void *, bus_space_handle_t, 106 bus_size_t); 107 108/* get kernel virtual address */ 109void * __C(CHIP,_mem_vaddr)(void *, bus_space_handle_t); 110 111/* mmap for user */ 112paddr_t __C(CHIP,_mem_mmap)(void *, bus_addr_t, off_t, int, int); 113 114/* barrier */ 115static inline void __C(CHIP,_mem_barrier)(void *, bus_space_handle_t, 116 bus_size_t, bus_size_t, int); 117 118/* read (single) */ 119static inline uint8_t __C(CHIP,_mem_read_1)(void *, bus_space_handle_t, 120 bus_size_t); 121static inline uint16_t __C(CHIP,_mem_read_2)(void *, bus_space_handle_t, 122 bus_size_t); 123static inline uint32_t __C(CHIP,_mem_read_4)(void *, bus_space_handle_t, 124 bus_size_t); 125static inline uint64_t __C(CHIP,_mem_read_8)(void *, bus_space_handle_t, 126 bus_size_t); 127 128/* read multiple */ 129void __C(CHIP,_mem_read_multi_1)(void *, bus_space_handle_t, 130 bus_size_t, uint8_t *, bus_size_t); 131void __C(CHIP,_mem_read_multi_2)(void *, bus_space_handle_t, 132 bus_size_t, uint16_t *, bus_size_t); 133void __C(CHIP,_mem_read_multi_4)(void *, bus_space_handle_t, 134 bus_size_t, uint32_t *, bus_size_t); 135void __C(CHIP,_mem_read_multi_8)(void *, bus_space_handle_t, 136 bus_size_t, uint64_t *, bus_size_t); 137 138/* read region */ 139void __C(CHIP,_mem_read_region_1)(void *, bus_space_handle_t, 140 bus_size_t, uint8_t *, bus_size_t); 141void __C(CHIP,_mem_read_region_2)(void *, bus_space_handle_t, 142 bus_size_t, uint16_t *, bus_size_t); 143void __C(CHIP,_mem_read_region_4)(void *, bus_space_handle_t, 144 bus_size_t, uint32_t *, bus_size_t); 145void __C(CHIP,_mem_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,_mem_write_1)(void *, bus_space_handle_t, 150 bus_size_t, uint8_t); 151static inline void __C(CHIP,_mem_write_2)(void *, bus_space_handle_t, 152 bus_size_t, uint16_t); 153static inline void __C(CHIP,_mem_write_4)(void *, bus_space_handle_t, 154 bus_size_t, uint32_t); 155static inline void __C(CHIP,_mem_write_8)(void *, bus_space_handle_t, 156 bus_size_t, uint64_t); 157 158/* write multiple */ 159void __C(CHIP,_mem_write_multi_1)(void *, bus_space_handle_t, 160 bus_size_t, const uint8_t *, bus_size_t); 161void __C(CHIP,_mem_write_multi_2)(void *, bus_space_handle_t, 162 bus_size_t, const uint16_t *, bus_size_t); 163void __C(CHIP,_mem_write_multi_4)(void *, bus_space_handle_t, 164 bus_size_t, const uint32_t *, bus_size_t); 165void __C(CHIP,_mem_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,_mem_write_region_1)(void *, bus_space_handle_t, 170 bus_size_t, const uint8_t *, bus_size_t); 171void __C(CHIP,_mem_write_region_2)(void *, bus_space_handle_t, 172 bus_size_t, const uint16_t *, bus_size_t); 173void __C(CHIP,_mem_write_region_4)(void *, bus_space_handle_t, 174 bus_size_t, const uint32_t *, bus_size_t); 175void __C(CHIP,_mem_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,_mem_set_multi_1)(void *, bus_space_handle_t, 180 bus_size_t, uint8_t, bus_size_t); 181void __C(CHIP,_mem_set_multi_2)(void *, bus_space_handle_t, 182 bus_size_t, uint16_t, bus_size_t); 183void __C(CHIP,_mem_set_multi_4)(void *, bus_space_handle_t, 184 bus_size_t, uint32_t, bus_size_t); 185void __C(CHIP,_mem_set_multi_8)(void *, bus_space_handle_t, 186 bus_size_t, uint64_t, bus_size_t); 187 188/* set region */ 189void __C(CHIP,_mem_set_region_1)(void *, bus_space_handle_t, 190 bus_size_t, uint8_t, bus_size_t); 191void __C(CHIP,_mem_set_region_2)(void *, bus_space_handle_t, 192 bus_size_t, uint16_t, bus_size_t); 193void __C(CHIP,_mem_set_region_4)(void *, bus_space_handle_t, 194 bus_size_t, uint32_t, bus_size_t); 195void __C(CHIP,_mem_set_region_8)(void *, bus_space_handle_t, 196 bus_size_t, uint64_t, bus_size_t); 197 198/* copy */ 199void __C(CHIP,_mem_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,_mem_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,_mem_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,_mem_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_MEM_EX_STORE 209static long 210 __C(CHIP,_mem_ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 211#define CHIP_MEM_EX_STORE(v) (__C(CHIP,_mem_ex_storage)) 212#define CHIP_MEM_EX_STORE_SIZE(v) (sizeof __C(CHIP,_mem_ex_storage)) 213#endif 214 215void 216__C(CHIP,_bus_mem_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,_mem_map); 231 t->abs_unmap = __C(CHIP,_mem_unmap); 232 t->abs_subregion = __C(CHIP,_mem_subregion); 233 234 t->abs_translate = __C(CHIP,_mem_translate); 235 t->abs_get_window = __C(CHIP,_mem_get_window); 236 237 /* allocation/deallocation */ 238 t->abs_alloc = __C(CHIP,_mem_alloc); 239 t->abs_free = __C(CHIP,_mem_free); 240 241 /* get kernel virtual address */ 242 t->abs_vaddr = __C(CHIP,_mem_vaddr); 243 244 /* mmap for user */ 245 t->abs_mmap = __C(CHIP,_mem_mmap); 246 247 /* barrier */ 248 t->abs_barrier = __C(CHIP,_mem_barrier); 249 250 /* read (single) */ 251 t->abs_r_1 = __C(CHIP,_mem_read_1); 252 t->abs_r_2 = __C(CHIP,_mem_read_2); 253 t->abs_r_4 = __C(CHIP,_mem_read_4); 254 t->abs_r_8 = __C(CHIP,_mem_read_8); 255 256 /* read multiple */ 257 t->abs_rm_1 = __C(CHIP,_mem_read_multi_1); 258 t->abs_rm_2 = __C(CHIP,_mem_read_multi_2); 259 t->abs_rm_4 = __C(CHIP,_mem_read_multi_4); 260 t->abs_rm_8 = __C(CHIP,_mem_read_multi_8); 261 262 /* read region */ 263 t->abs_rr_1 = __C(CHIP,_mem_read_region_1); 264 t->abs_rr_2 = __C(CHIP,_mem_read_region_2); 265 t->abs_rr_4 = __C(CHIP,_mem_read_region_4); 266 t->abs_rr_8 = __C(CHIP,_mem_read_region_8); 267 268 /* write (single) */ 269 t->abs_w_1 = __C(CHIP,_mem_write_1); 270 t->abs_w_2 = __C(CHIP,_mem_write_2); 271 t->abs_w_4 = __C(CHIP,_mem_write_4); 272 t->abs_w_8 = __C(CHIP,_mem_write_8); 273 274 /* write multiple */ 275 t->abs_wm_1 = __C(CHIP,_mem_write_multi_1); 276 t->abs_wm_2 = __C(CHIP,_mem_write_multi_2); 277 t->abs_wm_4 = __C(CHIP,_mem_write_multi_4); 278 t->abs_wm_8 = __C(CHIP,_mem_write_multi_8); 279 280 /* write region */ 281 t->abs_wr_1 = __C(CHIP,_mem_write_region_1); 282 t->abs_wr_2 = __C(CHIP,_mem_write_region_2); 283 t->abs_wr_4 = __C(CHIP,_mem_write_region_4); 284 t->abs_wr_8 = __C(CHIP,_mem_write_region_8); 285 286 /* set multiple */ 287 t->abs_sm_1 = __C(CHIP,_mem_set_multi_1); 288 t->abs_sm_2 = __C(CHIP,_mem_set_multi_2); 289 t->abs_sm_4 = __C(CHIP,_mem_set_multi_4); 290 t->abs_sm_8 = __C(CHIP,_mem_set_multi_8); 291 292 /* set region */ 293 t->abs_sr_1 = __C(CHIP,_mem_set_region_1); 294 t->abs_sr_2 = __C(CHIP,_mem_set_region_2); 295 t->abs_sr_4 = __C(CHIP,_mem_set_region_4); 296 t->abs_sr_8 = __C(CHIP,_mem_set_region_8); 297 298 /* copy */ 299 t->abs_c_1 = __C(CHIP,_mem_copy_region_1); 300 t->abs_c_2 = __C(CHIP,_mem_copy_region_2); 301 t->abs_c_4 = __C(CHIP,_mem_copy_region_4); 302 t->abs_c_8 = __C(CHIP,_mem_copy_region_8); 303 304 ex = extent_create(__S(__C(CHIP,_bus_mem)), 0x0UL, 0xffffffffUL, 305 (void *)CHIP_MEM_EX_STORE(v), CHIP_MEM_EX_STORE_SIZE(v), 306 EX_NOWAIT|EX_NOCOALESCE); 307 308 CHIP_MEM_EXTENT(v) = ex; 309} 310 311int 312__C(CHIP,_mem_translate)( 313 void *v, 314 bus_addr_t memaddr, 315 bus_size_t memlen, 316 int flags, 317 struct alpha_bus_space_translation *abst) 318{ 319 320 /* XXX */ 321 return (EOPNOTSUPP); 322} 323 324int 325__C(CHIP,_mem_get_window)( 326 void *v, 327 int window, 328 struct alpha_bus_space_translation *abst) 329{ 330 331 switch (window) { 332 case 0: 333 abst->abst_bus_start = 0; 334 abst->abst_bus_end = 0xffffffffUL; 335 abst->abst_sys_start = CHIP_MEM_SYS_START(v); 336 abst->abst_sys_end = CHIP_MEM_SYS_START(v) + abst->abst_bus_end; 337 abst->abst_addr_shift = 0; 338 abst->abst_size_shift = 0; 339 abst->abst_flags = ABST_DENSE|ABST_BWX; 340 break; 341 342 default: 343 panic(__S(__C(CHIP,_mem_get_window)) ": invalid window %d", 344 window); 345 } 346 347 return (0); 348} 349 350int 351__C(CHIP,_mem_map)( 352 void *v, 353 bus_addr_t memaddr, 354 bus_size_t memsize, 355 int flags, 356 bus_space_handle_t *memhp, 357 int acct) 358{ 359 int error; 360 361 if (acct == 0) 362 goto mapit; 363 364#ifdef EXTENT_DEBUG 365 printf("mem: allocating 0x%lx to 0x%lx\n", memaddr, 366 memaddr + memsize - 1); 367#endif 368 error = extent_alloc_region(CHIP_MEM_EXTENT(v), memaddr, memsize, 369 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 370 if (error) { 371#ifdef EXTENT_DEBUG 372 printf("mem: allocation failed (%d)\n", error); 373 extent_print(CHIP_MEM_EXTENT(v)); 374#endif 375 return (error); 376 } 377 378 mapit: 379 *memhp = ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v)) + memaddr; 380 381 return (0); 382} 383 384void 385__C(CHIP,_mem_unmap)( 386 void *v, 387 bus_space_handle_t memh, 388 bus_size_t memsize, 389 int acct) 390{ 391 bus_addr_t memaddr; 392 int error; 393 394 if (acct == 0) 395 return; 396 397#ifdef EXTENT_DEBUG 398 printf("mem: freeing handle 0x%lx for 0x%lx\n", memh, memsize); 399#endif 400 401 memaddr = memh - ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v)); 402 403#ifdef EXTENT_DEBUG 404 printf("mem: freeing 0x%lx to 0x%lx\n", memaddr, memaddr + memsize - 1); 405#endif 406 407 error = extent_free(CHIP_MEM_EXTENT(v), memaddr, memsize, 408 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 409 if (error) { 410 printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n", 411 __S(__C(CHIP,_mem_unmap)), memaddr, memaddr + memsize - 1, 412 error); 413#ifdef EXTENT_DEBUG 414 extent_print(CHIP_MEM_EXTENT(v)); 415#endif 416 } 417} 418 419int 420__C(CHIP,_mem_subregion)( 421 void *v, 422 bus_space_handle_t memh, 423 bus_size_t offset, 424 bus_size_t size, 425 bus_space_handle_t *nmemh) 426{ 427 428 *nmemh = memh + offset; 429 return (0); 430} 431 432int 433__C(CHIP,_mem_alloc)( 434 void *v, 435 bus_addr_t rstart, 436 bus_addr_t rend, 437 bus_size_t size, 438 bus_size_t align, 439 bus_size_t boundary, 440 int flags, 441 bus_addr_t *addrp, 442 bus_space_handle_t *bshp) 443{ 444 bus_addr_t memaddr; 445 int error; 446 447 /* 448 * Do the requested allocation. 449 */ 450#ifdef EXTENT_DEBUG 451 printf("mem: allocating from 0x%lx to 0x%lx\n", rstart, rend); 452#endif 453 error = extent_alloc_subregion(CHIP_MEM_EXTENT(v), rstart, rend, 454 size, align, boundary, 455 EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0), 456 &memaddr); 457 if (error) { 458#ifdef EXTENT_DEBUG 459 printf("mem: allocation failed (%d)\n", error); 460 extent_print(CHIP_MEM_EXTENT(v)); 461#endif 462 } 463 464#ifdef EXTENT_DEBUG 465 printf("mem: allocated 0x%lx to 0x%lx\n", memaddr, memaddr + size - 1); 466#endif 467 468 *addrp = memaddr; 469 *bshp = ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v)) + memaddr; 470 471 return (0); 472} 473 474void 475__C(CHIP,_mem_free)( 476 void *v, 477 bus_space_handle_t bsh, 478 bus_size_t size) 479{ 480 481 /* Unmap does all we need to do. */ 482 __C(CHIP,_mem_unmap)(v, bsh, size, 1); 483} 484 485void * 486__C(CHIP,_mem_vaddr)( 487 void *v, 488 bus_space_handle_t bsh) 489{ 490 491 return ((void *)bsh); 492} 493 494paddr_t 495__C(CHIP,_mem_mmap)( 496 void *v, 497 bus_addr_t addr, 498 off_t off, 499 int prot, 500 int flags) 501{ 502 503 return (alpha_btop(CHIP_MEM_SYS_START(v) + addr + off)); 504} 505 506static inline void 507__C(CHIP,_mem_barrier)( 508 void *v, 509 bus_space_handle_t h, 510 bus_size_t o, 511 bus_size_t l, 512 int f) 513{ 514 515 if ((f & BUS_SPACE_BARRIER_READ) != 0) 516 alpha_mb(); 517 else if ((f & BUS_SPACE_BARRIER_WRITE) != 0) 518 alpha_wmb(); 519} 520 521static inline uint8_t 522__C(CHIP,_mem_read_1)( 523 void *v, 524 bus_space_handle_t memh, 525 bus_size_t off) 526{ 527 bus_addr_t addr; 528 529 addr = memh + off; 530 alpha_mb(); 531 return (alpha_ldbu((uint8_t *)addr)); 532} 533 534static inline uint16_t 535__C(CHIP,_mem_read_2)( 536 void *v, 537 bus_space_handle_t memh, 538 bus_size_t off) 539{ 540 bus_addr_t addr; 541 542 addr = memh + off; 543#ifdef DIAGNOSTIC 544 if (addr & 1) 545 panic(__S(__C(CHIP,_mem_read_2)) ": addr 0x%lx not aligned", 546 addr); 547#endif 548 alpha_mb(); 549 return (alpha_ldwu((uint16_t *)addr)); 550} 551 552static inline uint32_t 553__C(CHIP,_mem_read_4)( 554 void *v, 555 bus_space_handle_t memh, 556 bus_size_t off) 557{ 558 bus_addr_t addr; 559 560 addr = memh + off; 561#ifdef DIAGNOSTIC 562 if (addr & 3) 563 panic(__S(__C(CHIP,_mem_read_4)) ": addr 0x%lx not aligned", 564 addr); 565#endif 566 alpha_mb(); 567 return (*(uint32_t *)addr); 568} 569 570static inline uint64_t 571__C(CHIP,_mem_read_8)( 572 void *v, 573 bus_space_handle_t memh, 574 bus_size_t off) 575{ 576 577 alpha_mb(); 578 579 /* XXX XXX XXX */ 580 panic("%s not implemented", __S(__C(CHIP,_mem_read_8))); 581} 582 583#define CHIP_mem_read_multi_N(BYTES,TYPE) \ 584void \ 585__C(__C(CHIP,_mem_read_multi_),BYTES)( \ 586 void *v, \ 587 bus_space_handle_t h, \ 588 bus_size_t o, \ 589 TYPE *a, \ 590 bus_size_t c) \ 591{ \ 592 \ 593 while (c-- > 0) { \ 594 __C(CHIP,_mem_barrier)(v, h, o, sizeof *a, \ 595 BUS_SPACE_BARRIER_READ); \ 596 *a++ = __C(__C(CHIP,_mem_read_),BYTES)(v, h, o); \ 597 } \ 598} 599CHIP_mem_read_multi_N(1,uint8_t) 600CHIP_mem_read_multi_N(2,uint16_t) 601CHIP_mem_read_multi_N(4,uint32_t) 602CHIP_mem_read_multi_N(8,uint64_t) 603 604#define CHIP_mem_read_region_N(BYTES,TYPE) \ 605void \ 606__C(__C(CHIP,_mem_read_region_),BYTES)( \ 607 void *v, \ 608 bus_space_handle_t h, \ 609 bus_size_t o, \ 610 TYPE *a, \ 611 bus_size_t c) \ 612{ \ 613 \ 614 while (c-- > 0) { \ 615 *a++ = __C(__C(CHIP,_mem_read_),BYTES)(v, h, o); \ 616 o += sizeof *a; \ 617 } \ 618} 619CHIP_mem_read_region_N(1,uint8_t) 620CHIP_mem_read_region_N(2,uint16_t) 621CHIP_mem_read_region_N(4,uint32_t) 622CHIP_mem_read_region_N(8,uint64_t) 623 624static inline void 625__C(CHIP,_mem_write_1)( 626 void *v, 627 bus_space_handle_t memh, 628 bus_size_t off, 629 uint8_t val) 630{ 631 bus_addr_t addr; 632 633 addr = memh + off; 634 alpha_stb((uint8_t *)addr, val); 635 alpha_mb(); 636} 637 638static inline void 639__C(CHIP,_mem_write_2)( 640 void *v, 641 bus_space_handle_t memh, 642 bus_size_t off, 643 uint16_t val) 644{ 645 bus_addr_t addr; 646 647 addr = memh + off; 648#ifdef DIAGNOSTIC 649 if (addr & 1) 650 panic(__S(__C(CHIP,_mem_write_2)) ": addr 0x%lx not aligned", 651 addr); 652#endif 653 alpha_stw((uint16_t *)addr, val); 654 alpha_mb(); 655} 656 657static inline void 658__C(CHIP,_mem_write_4)( 659 void *v, 660 bus_space_handle_t memh, 661 bus_size_t off, 662 uint32_t val) 663{ 664 bus_addr_t addr; 665 666 addr = memh + off; 667#ifdef DIAGNOSTIC 668 if (addr & 3) 669 panic(__S(__C(CHIP,_mem_write_4)) ": addr 0x%lx not aligned", 670 addr); 671#endif 672 *(uint32_t *)addr = val; 673 alpha_mb(); 674} 675 676static inline void 677__C(CHIP,_mem_write_8)( 678 void *v, 679 bus_space_handle_t memh, 680 bus_size_t off, 681 uint64_t val) 682{ 683 684 /* XXX XXX XXX */ 685 panic("%s not implemented", __S(__C(CHIP,_mem_write_8))); 686 alpha_mb(); 687} 688 689#define CHIP_mem_write_multi_N(BYTES,TYPE) \ 690void \ 691__C(__C(CHIP,_mem_write_multi_),BYTES)( \ 692 void *v, \ 693 bus_space_handle_t h, \ 694 bus_size_t o, \ 695 const TYPE *a, \ 696 bus_size_t c) \ 697{ \ 698 \ 699 while (c-- > 0) { \ 700 __C(__C(CHIP,_mem_write_),BYTES)(v, h, o, *a++); \ 701 __C(CHIP,_mem_barrier)(v, h, o, sizeof *a, \ 702 BUS_SPACE_BARRIER_WRITE); \ 703 } \ 704} 705CHIP_mem_write_multi_N(1,uint8_t) 706CHIP_mem_write_multi_N(2,uint16_t) 707CHIP_mem_write_multi_N(4,uint32_t) 708CHIP_mem_write_multi_N(8,uint64_t) 709 710#define CHIP_mem_write_region_N(BYTES,TYPE) \ 711void \ 712__C(__C(CHIP,_mem_write_region_),BYTES)( \ 713 void *v, \ 714 bus_space_handle_t h, \ 715 bus_size_t o, \ 716 const TYPE *a, \ 717 bus_size_t c) \ 718{ \ 719 \ 720 while (c-- > 0) { \ 721 __C(__C(CHIP,_mem_write_),BYTES)(v, h, o, *a++); \ 722 o += sizeof *a; \ 723 } \ 724} 725CHIP_mem_write_region_N(1,uint8_t) 726CHIP_mem_write_region_N(2,uint16_t) 727CHIP_mem_write_region_N(4,uint32_t) 728CHIP_mem_write_region_N(8,uint64_t) 729 730#define CHIP_mem_set_multi_N(BYTES,TYPE) \ 731void \ 732__C(__C(CHIP,_mem_set_multi_),BYTES)( \ 733 void *v, \ 734 bus_space_handle_t h, \ 735 bus_size_t o, \ 736 TYPE val, \ 737 bus_size_t c) \ 738{ \ 739 \ 740 while (c-- > 0) { \ 741 __C(__C(CHIP,_mem_write_),BYTES)(v, h, o, val); \ 742 __C(CHIP,_mem_barrier)(v, h, o, sizeof val, \ 743 BUS_SPACE_BARRIER_WRITE); \ 744 } \ 745} 746CHIP_mem_set_multi_N(1,uint8_t) 747CHIP_mem_set_multi_N(2,uint16_t) 748CHIP_mem_set_multi_N(4,uint32_t) 749CHIP_mem_set_multi_N(8,uint64_t) 750 751#define CHIP_mem_set_region_N(BYTES,TYPE) \ 752void \ 753__C(__C(CHIP,_mem_set_region_),BYTES)( \ 754 void *v, \ 755 bus_space_handle_t h, \ 756 bus_size_t o, \ 757 TYPE val, \ 758 bus_size_t c) \ 759{ \ 760 \ 761 while (c-- > 0) { \ 762 __C(__C(CHIP,_mem_write_),BYTES)(v, h, o, val); \ 763 o += sizeof val; \ 764 } \ 765} 766CHIP_mem_set_region_N(1,uint8_t) 767CHIP_mem_set_region_N(2,uint16_t) 768CHIP_mem_set_region_N(4,uint32_t) 769CHIP_mem_set_region_N(8,uint64_t) 770 771#define CHIP_mem_copy_region_N(BYTES) \ 772void \ 773__C(__C(CHIP,_mem_copy_region_),BYTES)( \ 774 void *v, \ 775 bus_space_handle_t h1, \ 776 bus_size_t o1, \ 777 bus_space_handle_t h2, \ 778 bus_size_t o2, \ 779 bus_size_t c) \ 780{ \ 781 bus_size_t o; \ 782 \ 783 if ((h1 + o1) >= (h2 + o2)) { \ 784 /* src after dest: copy forward */ \ 785 for (o = 0; c != 0; c--, o += BYTES) { \ 786 __C(__C(CHIP,_mem_write_),BYTES)(v, h2, o2 + o, \ 787 __C(__C(CHIP,_mem_read_),BYTES)(v, h1, o1 + o)); \ 788 } \ 789 } else { \ 790 /* dest after src: copy backwards */ \ 791 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) { \ 792 __C(__C(CHIP,_mem_write_),BYTES)(v, h2, o2 + o, \ 793 __C(__C(CHIP,_mem_read_),BYTES)(v, h1, o1 + o)); \ 794 } \ 795 } \ 796} 797CHIP_mem_copy_region_N(1) 798CHIP_mem_copy_region_N(2) 799CHIP_mem_copy_region_N(4) 800CHIP_mem_copy_region_N(8) 801