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