1 /* $NetBSD: pci_swiz_bus_io_chipdep.c,v 1.32 2001/09/04 05:31:28 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 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * Copyright (c) 1995, 1996 Carnegie-Mellon University. 42 * All rights reserved. 43 * 44 * Author: Chris G. Demetriou 45 * 46 * Permission to use, copy, modify and distribute this software and 47 * its documentation is hereby granted, provided that both the copyright 48 * notice and this permission notice appear in all copies of the 49 * software, derivative works or modified versions, and any portions 50 * thereof, and that both notices appear in supporting documentation. 51 * 52 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 53 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 54 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 55 * 56 * Carnegie Mellon requests users of this software to return to 57 * 58 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 59 * School of Computer Science 60 * Carnegie Mellon University 61 * Pittsburgh PA 15213-3890 62 * 63 * any improvements or extensions that they make and grant Carnegie the 64 * rights to redistribute these changes. 65 */ 66 67 /* 68 * Common PCI Chipset "bus I/O" functions, for chipsets which have to 69 * deal with only a single PCI interface chip in a machine. 70 * 71 * uses: 72 * CHIP name of the 'chip' it's being compiled for. 73 * CHIP_IO_BASE Sparse I/O space base to use. 74 * CHIP_IO_EX_STORE 75 * If defined, device-provided static storage area 76 * for the I/O space extent. If this is defined, 77 * CHIP_IO_EX_STORE_SIZE must also be defined. If 78 * this is not defined, a static area will be 79 * declared. 80 * CHIP_IO_EX_STORE_SIZE 81 * Size of the device-provided static storage area 82 * for the I/O memory space extent. 83 */ 84 85 #include <sys/extent.h> 86 87 #define __C(A,B) __CONCAT(A,B) 88 #define __S(S) __STRING(S) 89 90 /* mapping/unmapping */ 91 int __C(CHIP,_io_map) __P((void *, bus_addr_t, bus_size_t, int, 92 bus_space_handle_t *, int)); 93 void __C(CHIP,_io_unmap) __P((void *, bus_space_handle_t, 94 bus_size_t, int)); 95 int __C(CHIP,_io_subregion) __P((void *, bus_space_handle_t, 96 bus_size_t, bus_size_t, bus_space_handle_t *)); 97 98 int __C(CHIP,_io_translate) __P((void *, bus_addr_t, bus_size_t, 99 int, struct alpha_bus_space_translation *)); 100 int __C(CHIP,_io_get_window) __P((void *, int, 101 struct alpha_bus_space_translation *)); 102 103 /* allocation/deallocation */ 104 int __C(CHIP,_io_alloc) __P((void *, bus_addr_t, bus_addr_t, 105 bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *, 106 bus_space_handle_t *)); 107 void __C(CHIP,_io_free) __P((void *, bus_space_handle_t, 108 bus_size_t)); 109 110 /* get kernel virtual address */ 111 void * __C(CHIP,_io_vaddr) __P((void *, bus_space_handle_t)); 112 113 /* mmap for user */ 114 paddr_t __C(CHIP,_io_mmap) __P((void *, bus_addr_t, off_t, int, int)); 115 116 /* barrier */ 117 inline void __C(CHIP,_io_barrier) __P((void *, bus_space_handle_t, 118 bus_size_t, bus_size_t, int)); 119 120 /* read (single) */ 121 inline u_int8_t __C(CHIP,_io_read_1) __P((void *, bus_space_handle_t, 122 bus_size_t)); 123 inline u_int16_t __C(CHIP,_io_read_2) __P((void *, bus_space_handle_t, 124 bus_size_t)); 125 inline u_int32_t __C(CHIP,_io_read_4) __P((void *, bus_space_handle_t, 126 bus_size_t)); 127 inline u_int64_t __C(CHIP,_io_read_8) __P((void *, bus_space_handle_t, 128 bus_size_t)); 129 130 /* read multiple */ 131 void __C(CHIP,_io_read_multi_1) __P((void *, bus_space_handle_t, 132 bus_size_t, u_int8_t *, bus_size_t)); 133 void __C(CHIP,_io_read_multi_2) __P((void *, bus_space_handle_t, 134 bus_size_t, u_int16_t *, bus_size_t)); 135 void __C(CHIP,_io_read_multi_4) __P((void *, bus_space_handle_t, 136 bus_size_t, u_int32_t *, bus_size_t)); 137 void __C(CHIP,_io_read_multi_8) __P((void *, bus_space_handle_t, 138 bus_size_t, u_int64_t *, bus_size_t)); 139 140 /* read region */ 141 void __C(CHIP,_io_read_region_1) __P((void *, bus_space_handle_t, 142 bus_size_t, u_int8_t *, bus_size_t)); 143 void __C(CHIP,_io_read_region_2) __P((void *, bus_space_handle_t, 144 bus_size_t, u_int16_t *, bus_size_t)); 145 void __C(CHIP,_io_read_region_4) __P((void *, bus_space_handle_t, 146 bus_size_t, u_int32_t *, bus_size_t)); 147 void __C(CHIP,_io_read_region_8) __P((void *, bus_space_handle_t, 148 bus_size_t, u_int64_t *, bus_size_t)); 149 150 /* write (single) */ 151 inline void __C(CHIP,_io_write_1) __P((void *, bus_space_handle_t, 152 bus_size_t, u_int8_t)); 153 inline void __C(CHIP,_io_write_2) __P((void *, bus_space_handle_t, 154 bus_size_t, u_int16_t)); 155 inline void __C(CHIP,_io_write_4) __P((void *, bus_space_handle_t, 156 bus_size_t, u_int32_t)); 157 inline void __C(CHIP,_io_write_8) __P((void *, bus_space_handle_t, 158 bus_size_t, u_int64_t)); 159 160 /* write multiple */ 161 void __C(CHIP,_io_write_multi_1) __P((void *, bus_space_handle_t, 162 bus_size_t, const u_int8_t *, bus_size_t)); 163 void __C(CHIP,_io_write_multi_2) __P((void *, bus_space_handle_t, 164 bus_size_t, const u_int16_t *, bus_size_t)); 165 void __C(CHIP,_io_write_multi_4) __P((void *, bus_space_handle_t, 166 bus_size_t, const u_int32_t *, bus_size_t)); 167 void __C(CHIP,_io_write_multi_8) __P((void *, bus_space_handle_t, 168 bus_size_t, const u_int64_t *, bus_size_t)); 169 170 /* write region */ 171 void __C(CHIP,_io_write_region_1) __P((void *, bus_space_handle_t, 172 bus_size_t, const u_int8_t *, bus_size_t)); 173 void __C(CHIP,_io_write_region_2) __P((void *, bus_space_handle_t, 174 bus_size_t, const u_int16_t *, bus_size_t)); 175 void __C(CHIP,_io_write_region_4) __P((void *, bus_space_handle_t, 176 bus_size_t, const u_int32_t *, bus_size_t)); 177 void __C(CHIP,_io_write_region_8) __P((void *, bus_space_handle_t, 178 bus_size_t, const u_int64_t *, bus_size_t)); 179 180 /* set multiple */ 181 void __C(CHIP,_io_set_multi_1) __P((void *, bus_space_handle_t, 182 bus_size_t, u_int8_t, bus_size_t)); 183 void __C(CHIP,_io_set_multi_2) __P((void *, bus_space_handle_t, 184 bus_size_t, u_int16_t, bus_size_t)); 185 void __C(CHIP,_io_set_multi_4) __P((void *, bus_space_handle_t, 186 bus_size_t, u_int32_t, bus_size_t)); 187 void __C(CHIP,_io_set_multi_8) __P((void *, bus_space_handle_t, 188 bus_size_t, u_int64_t, bus_size_t)); 189 190 /* set region */ 191 void __C(CHIP,_io_set_region_1) __P((void *, bus_space_handle_t, 192 bus_size_t, u_int8_t, bus_size_t)); 193 void __C(CHIP,_io_set_region_2) __P((void *, bus_space_handle_t, 194 bus_size_t, u_int16_t, bus_size_t)); 195 void __C(CHIP,_io_set_region_4) __P((void *, bus_space_handle_t, 196 bus_size_t, u_int32_t, bus_size_t)); 197 void __C(CHIP,_io_set_region_8) __P((void *, bus_space_handle_t, 198 bus_size_t, u_int64_t, bus_size_t)); 199 200 /* copy */ 201 void __C(CHIP,_io_copy_region_1) __P((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_2) __P((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_4) __P((void *, bus_space_handle_t, 206 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t)); 207 void __C(CHIP,_io_copy_region_8) __P((void *, bus_space_handle_t, 208 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t)); 209 210 #ifndef CHIP_IO_EX_STORE 211 static long 212 __C(CHIP,_io_ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 213 #define CHIP_IO_EX_STORE(v) (__C(CHIP, _io_ex_storage)) 214 #define CHIP_IO_EX_STORE_SIZE(v) (sizeof __C(CHIP, _io_ex_storage)) 215 #endif 216 217 #ifndef CHIP_ADDR_SHIFT 218 #define CHIP_ADDR_SHIFT 5 219 #endif 220 221 #ifndef CHIP_SIZE_SHIFT 222 #define CHIP_SIZE_SHIFT 3 223 #endif 224 225 void 226 __C(CHIP,_bus_io_init)(t, v) 227 bus_space_tag_t t; 228 void *v; 229 { 230 struct extent *ex; 231 232 /* 233 * Initialize the bus space tag. 234 */ 235 236 /* cookie */ 237 t->abs_cookie = v; 238 239 /* mapping/unmapping */ 240 t->abs_map = __C(CHIP,_io_map); 241 t->abs_unmap = __C(CHIP,_io_unmap); 242 t->abs_subregion = __C(CHIP,_io_subregion); 243 244 t->abs_translate = __C(CHIP,_io_translate); 245 t->abs_get_window = __C(CHIP,_io_get_window); 246 247 /* allocation/deallocation */ 248 t->abs_alloc = __C(CHIP,_io_alloc); 249 t->abs_free = __C(CHIP,_io_free); 250 251 /* get kernel virtual address */ 252 t->abs_vaddr = __C(CHIP,_io_vaddr); 253 254 /* mmap for user */ 255 t->abs_mmap = __C(CHIP,_io_mmap); 256 257 /* barrier */ 258 t->abs_barrier = __C(CHIP,_io_barrier); 259 260 /* read (single) */ 261 t->abs_r_1 = __C(CHIP,_io_read_1); 262 t->abs_r_2 = __C(CHIP,_io_read_2); 263 t->abs_r_4 = __C(CHIP,_io_read_4); 264 t->abs_r_8 = __C(CHIP,_io_read_8); 265 266 /* read multiple */ 267 t->abs_rm_1 = __C(CHIP,_io_read_multi_1); 268 t->abs_rm_2 = __C(CHIP,_io_read_multi_2); 269 t->abs_rm_4 = __C(CHIP,_io_read_multi_4); 270 t->abs_rm_8 = __C(CHIP,_io_read_multi_8); 271 272 /* read region */ 273 t->abs_rr_1 = __C(CHIP,_io_read_region_1); 274 t->abs_rr_2 = __C(CHIP,_io_read_region_2); 275 t->abs_rr_4 = __C(CHIP,_io_read_region_4); 276 t->abs_rr_8 = __C(CHIP,_io_read_region_8); 277 278 /* write (single) */ 279 t->abs_w_1 = __C(CHIP,_io_write_1); 280 t->abs_w_2 = __C(CHIP,_io_write_2); 281 t->abs_w_4 = __C(CHIP,_io_write_4); 282 t->abs_w_8 = __C(CHIP,_io_write_8); 283 284 /* write multiple */ 285 t->abs_wm_1 = __C(CHIP,_io_write_multi_1); 286 t->abs_wm_2 = __C(CHIP,_io_write_multi_2); 287 t->abs_wm_4 = __C(CHIP,_io_write_multi_4); 288 t->abs_wm_8 = __C(CHIP,_io_write_multi_8); 289 290 /* write region */ 291 t->abs_wr_1 = __C(CHIP,_io_write_region_1); 292 t->abs_wr_2 = __C(CHIP,_io_write_region_2); 293 t->abs_wr_4 = __C(CHIP,_io_write_region_4); 294 t->abs_wr_8 = __C(CHIP,_io_write_region_8); 295 296 /* set multiple */ 297 t->abs_sm_1 = __C(CHIP,_io_set_multi_1); 298 t->abs_sm_2 = __C(CHIP,_io_set_multi_2); 299 t->abs_sm_4 = __C(CHIP,_io_set_multi_4); 300 t->abs_sm_8 = __C(CHIP,_io_set_multi_8); 301 302 /* set region */ 303 t->abs_sr_1 = __C(CHIP,_io_set_region_1); 304 t->abs_sr_2 = __C(CHIP,_io_set_region_2); 305 t->abs_sr_4 = __C(CHIP,_io_set_region_4); 306 t->abs_sr_8 = __C(CHIP,_io_set_region_8); 307 308 /* copy */ 309 t->abs_c_1 = __C(CHIP,_io_copy_region_1); 310 t->abs_c_2 = __C(CHIP,_io_copy_region_2); 311 t->abs_c_4 = __C(CHIP,_io_copy_region_4); 312 t->abs_c_8 = __C(CHIP,_io_copy_region_8); 313 314 /* XXX WE WANT EXTENT_NOCOALESCE, BUT WE CAN'T USE IT. XXX */ 315 ex = extent_create(__S(__C(CHIP,_bus_io)), 0x0UL, 0xffffffffUL, 316 M_DEVBUF, (caddr_t)CHIP_IO_EX_STORE(v), CHIP_IO_EX_STORE_SIZE(v), 317 EX_NOWAIT); 318 extent_alloc_region(ex, 0, 0xffffffffUL, EX_NOWAIT); 319 320 #ifdef CHIP_IO_W1_BUS_START 321 #ifdef EXTENT_DEBUG 322 printf("io: freeing from 0x%lx to 0x%lx\n", CHIP_IO_W1_BUS_START(v), 323 CHIP_IO_W1_BUS_END(v)); 324 #endif 325 extent_free(ex, CHIP_IO_W1_BUS_START(v), 326 CHIP_IO_W1_BUS_END(v) - CHIP_IO_W1_BUS_START(v) + 1, EX_NOWAIT); 327 #endif 328 #ifdef CHIP_IO_W2_BUS_START 329 #ifdef EXTENT_DEBUG 330 printf("io: freeing from 0x%lx to 0x%lx\n", CHIP_IO_W2_BUS_START(v), 331 CHIP_IO_W2_BUS_END(v)); 332 #endif 333 extent_free(ex, CHIP_IO_W2_BUS_START(v), 334 CHIP_IO_W2_BUS_END(v) - CHIP_IO_W2_BUS_START(v) + 1, EX_NOWAIT); 335 #endif 336 337 #ifdef EXTENT_DEBUG 338 extent_print(ex); 339 #endif 340 CHIP_IO_EXTENT(v) = ex; 341 } 342 343 int 344 __C(CHIP,_io_translate)(v, ioaddr, iolen, flags, abst) 345 void *v; 346 bus_addr_t ioaddr; 347 bus_size_t iolen; 348 int flags; 349 struct alpha_bus_space_translation *abst; 350 { 351 bus_addr_t ioend = ioaddr + (iolen - 1); 352 int linear = flags & BUS_SPACE_MAP_LINEAR; 353 354 /* 355 * Can't map i/o space linearly. 356 */ 357 if (linear) 358 return (EOPNOTSUPP); 359 360 #ifdef CHIP_IO_W1_BUS_START 361 if (ioaddr >= CHIP_IO_W1_BUS_START(v) && 362 ioend <= CHIP_IO_W1_BUS_END(v)) 363 return (__C(CHIP,_io_get_window)(v, 0, abst)); 364 #endif 365 366 #ifdef CHIP_IO_W2_BUS_START 367 if (ioaddr >= CHIP_IO_W2_BUS_START(v) && 368 ioend <= CHIP_IO_W2_BUS_END(v)) 369 return (__C(CHIP,_io_get_window)(v, 1, abst)); 370 #endif 371 372 #ifdef EXTENT_DEBUG 373 printf("\n"); 374 #ifdef CHIP_IO_W1_BUS_START 375 printf("%s: window[1]=0x%lx-0x%lx\n", 376 __S(__C(CHIP,_io_map)), CHIP_IO_W1_BUS_START(v), 377 CHIP_IO_W1_BUS_END(v)); 378 #endif 379 #ifdef CHIP_IO_W2_BUS_START 380 printf("%s: window[2]=0x%lx-0x%lx\n", 381 __S(__C(CHIP,_io_map)), CHIP_IO_W2_BUS_START(v), 382 CHIP_IO_W2_BUS_END(v)); 383 #endif 384 #endif /* EXTENT_DEBUG */ 385 /* No translation. */ 386 return (EINVAL); 387 } 388 389 int 390 __C(CHIP,_io_get_window)(v, window, abst) 391 void *v; 392 int window; 393 struct alpha_bus_space_translation *abst; 394 { 395 396 switch (window) { 397 #ifdef CHIP_IO_W1_BUS_START 398 case 0: 399 abst->abst_bus_start = CHIP_IO_W1_BUS_START(v); 400 abst->abst_bus_end = CHIP_IO_W1_BUS_END(v); 401 abst->abst_sys_start = CHIP_IO_W1_SYS_START(v); 402 abst->abst_sys_end = CHIP_IO_W1_SYS_END(v); 403 abst->abst_addr_shift = CHIP_ADDR_SHIFT; 404 abst->abst_size_shift = CHIP_SIZE_SHIFT; 405 abst->abst_flags = 0; 406 break; 407 #endif 408 409 #ifdef CHIP_IO_W2_BUS_START 410 case 1: 411 abst->abst_bus_start = CHIP_IO_W2_BUS_START(v); 412 abst->abst_bus_end = CHIP_IO_W2_BUS_END(v); 413 abst->abst_sys_start = CHIP_IO_W2_SYS_START(v); 414 abst->abst_sys_end = CHIP_IO_W2_SYS_END(v); 415 abst->abst_addr_shift = CHIP_ADDR_SHIFT; 416 abst->abst_size_shift = CHIP_SIZE_SHIFT; 417 abst->abst_flags = 0; 418 break; 419 #endif 420 421 default: 422 panic(__S(__C(CHIP,_io_get_window)) ": invalid window %d", 423 window); 424 } 425 426 return (0); 427 } 428 429 int 430 __C(CHIP,_io_map)(v, ioaddr, iosize, flags, iohp, acct) 431 void *v; 432 bus_addr_t ioaddr; 433 bus_size_t iosize; 434 int flags; 435 bus_space_handle_t *iohp; 436 int acct; 437 { 438 struct alpha_bus_space_translation abst; 439 int error; 440 441 /* 442 * Get the translation for this address. 443 */ 444 error = __C(CHIP,_io_translate)(v, ioaddr, iosize, flags, &abst); 445 if (error) 446 return (error); 447 448 if (acct == 0) 449 goto mapit; 450 451 #ifdef EXTENT_DEBUG 452 printf("io: allocating 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1); 453 #endif 454 error = extent_alloc_region(CHIP_IO_EXTENT(v), ioaddr, iosize, 455 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 456 if (error) { 457 #ifdef EXTENT_DEBUG 458 printf("io: allocation failed (%d)\n", error); 459 extent_print(CHIP_IO_EXTENT(v)); 460 #endif 461 return (error); 462 } 463 464 mapit: 465 *iohp = (ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start) >> 466 CHIP_ADDR_SHIFT) + (ioaddr - abst.abst_bus_start); 467 468 return (0); 469 } 470 471 void 472 __C(CHIP,_io_unmap)(v, ioh, iosize, acct) 473 void *v; 474 bus_space_handle_t ioh; 475 bus_size_t iosize; 476 int acct; 477 { 478 bus_addr_t ioaddr; 479 int error; 480 481 if (acct == 0) 482 return; 483 484 #ifdef EXTENT_DEBUG 485 printf("io: freeing handle 0x%lx for 0x%lx\n", ioh, iosize); 486 #endif 487 488 ioh = ALPHA_K0SEG_TO_PHYS(ioh << CHIP_ADDR_SHIFT) >> CHIP_ADDR_SHIFT; 489 490 #ifdef CHIP_IO_W1_BUS_START 491 if ((ioh << CHIP_ADDR_SHIFT) >= CHIP_IO_W1_SYS_START(v) && 492 (ioh << CHIP_ADDR_SHIFT) <= CHIP_IO_W1_SYS_END(v)) { 493 ioaddr = CHIP_IO_W1_BUS_START(v) + 494 (ioh - (CHIP_IO_W1_SYS_START(v) >> CHIP_ADDR_SHIFT)); 495 } else 496 #endif 497 #ifdef CHIP_IO_W2_BUS_START 498 if ((ioh << CHIP_ADDR_SHIFT) >= CHIP_IO_W2_SYS_START(v) && 499 (ioh << CHIP_ADDR_SHIFT) <= CHIP_IO_W2_SYS_END(v)) { 500 ioaddr = CHIP_IO_W2_BUS_START(v) + 501 (ioh - (CHIP_IO_W2_SYS_START(v) >> CHIP_ADDR_SHIFT)); 502 } else 503 #endif 504 { 505 printf("\n"); 506 #ifdef CHIP_IO_W1_BUS_START 507 printf("%s: sys window[1]=0x%lx-0x%lx\n", 508 __S(__C(CHIP,_io_map)), CHIP_IO_W1_SYS_START(v), 509 CHIP_IO_W1_SYS_END(v)); 510 #endif 511 #ifdef CHIP_IO_W2_BUS_START 512 printf("%s: sys window[2]=0x%lx-0x%lx\n", 513 __S(__C(CHIP,_io_map)), CHIP_IO_W2_SYS_START(v), 514 CHIP_IO_W2_SYS_END(v)); 515 #endif 516 panic("%s: don't know how to unmap %lx", 517 __S(__C(CHIP,_io_unmap)), (ioh << CHIP_ADDR_SHIFT)); 518 } 519 520 #ifdef EXTENT_DEBUG 521 printf("io: freeing 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1); 522 #endif 523 error = extent_free(CHIP_IO_EXTENT(v), ioaddr, iosize, 524 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 525 if (error) { 526 printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n", 527 __S(__C(CHIP,_io_unmap)), ioaddr, ioaddr + iosize - 1, 528 error); 529 #ifdef EXTENT_DEBUG 530 extent_print(CHIP_IO_EXTENT(v)); 531 #endif 532 } 533 } 534 535 int 536 __C(CHIP,_io_subregion)(v, ioh, offset, size, nioh) 537 void *v; 538 bus_space_handle_t ioh, *nioh; 539 bus_size_t offset, size; 540 { 541 542 *nioh = ioh + offset; 543 return (0); 544 } 545 546 int 547 __C(CHIP,_io_alloc)(v, rstart, rend, size, align, boundary, flags, 548 addrp, bshp) 549 void *v; 550 bus_addr_t rstart, rend, *addrp; 551 bus_size_t size, align, boundary; 552 int flags; 553 bus_space_handle_t *bshp; 554 { 555 struct alpha_bus_space_translation abst; 556 int linear = flags & BUS_SPACE_MAP_LINEAR; 557 bus_addr_t ioaddr; 558 int error; 559 560 /* 561 * Can't map i/o space linearly. 562 */ 563 if (linear) 564 return (EOPNOTSUPP); 565 566 /* 567 * Do the requested allocation. 568 */ 569 #ifdef EXTENT_DEBUG 570 printf("io: allocating from 0x%lx to 0x%lx\n", rstart, rend); 571 #endif 572 error = extent_alloc_subregion(CHIP_IO_EXTENT(v), rstart, rend, 573 size, align, boundary, 574 EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0), 575 &ioaddr); 576 if (error) { 577 #ifdef EXTENT_DEBUG 578 printf("io: allocation failed (%d)\n", error); 579 extent_print(CHIP_IO_EXTENT(v)); 580 #endif 581 return (error); 582 } 583 584 #ifdef EXTENT_DEBUG 585 printf("io: allocated 0x%lx to 0x%lx\n", ioaddr, ioaddr + size - 1); 586 #endif 587 588 error = __C(CHIP,_io_translate)(v, ioaddr, size, flags, &abst); 589 if (error) { 590 (void) extent_free(CHIP_IO_EXTENT(v), ioaddr, size, 591 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 592 return (error); 593 } 594 595 *addrp = ioaddr; 596 *bshp = (ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start) >> 597 CHIP_ADDR_SHIFT) + (ioaddr - abst.abst_bus_start); 598 599 return (0); 600 } 601 602 void 603 __C(CHIP,_io_free)(v, bsh, size) 604 void *v; 605 bus_space_handle_t bsh; 606 bus_size_t size; 607 { 608 609 /* Unmap does all we need to do. */ 610 __C(CHIP,_io_unmap)(v, bsh, size, 1); 611 } 612 613 void * 614 __C(CHIP,_io_vaddr)(v, bsh) 615 void *v; 616 bus_space_handle_t bsh; 617 { 618 /* 619 * _io_translate() catches BUS_SPACE_MAP_LINEAR, 620 * so we shouldn't get here 621 */ 622 panic("_io_vaddr"); 623 } 624 625 paddr_t 626 __C(CHIP,_io_mmap)(v, addr, off, prot, flags) 627 void *v; 628 bus_addr_t addr; 629 off_t off; 630 int prot; 631 int flags; 632 { 633 634 /* Not supported for I/O space. */ 635 return (-1); 636 } 637 638 inline void 639 __C(CHIP,_io_barrier)(v, h, o, l, f) 640 void *v; 641 bus_space_handle_t h; 642 bus_size_t o, l; 643 int f; 644 { 645 646 if ((f & BUS_SPACE_BARRIER_READ) != 0) 647 alpha_mb(); 648 else if ((f & BUS_SPACE_BARRIER_WRITE) != 0) 649 alpha_wmb(); 650 } 651 652 inline u_int8_t 653 __C(CHIP,_io_read_1)(v, ioh, off) 654 void *v; 655 bus_space_handle_t ioh; 656 bus_size_t off; 657 { 658 register bus_space_handle_t tmpioh; 659 register u_int32_t *port, val; 660 register u_int8_t rval; 661 register int offset; 662 663 alpha_mb(); 664 665 tmpioh = ioh + off; 666 offset = tmpioh & 3; 667 port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) | 668 (0 << CHIP_SIZE_SHIFT)); 669 val = *port; 670 rval = ((val) >> (8 * offset)) & 0xff; 671 672 return rval; 673 } 674 675 inline u_int16_t 676 __C(CHIP,_io_read_2)(v, ioh, off) 677 void *v; 678 bus_space_handle_t ioh; 679 bus_size_t off; 680 { 681 register bus_space_handle_t tmpioh; 682 register u_int32_t *port, val; 683 register u_int16_t rval; 684 register int offset; 685 686 alpha_mb(); 687 688 tmpioh = ioh + off; 689 offset = tmpioh & 3; 690 port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) | 691 (1 << CHIP_SIZE_SHIFT)); 692 val = *port; 693 rval = ((val) >> (8 * offset)) & 0xffff; 694 695 return rval; 696 } 697 698 inline u_int32_t 699 __C(CHIP,_io_read_4)(v, ioh, off) 700 void *v; 701 bus_space_handle_t ioh; 702 bus_size_t off; 703 { 704 register bus_space_handle_t tmpioh; 705 register u_int32_t *port, val; 706 register u_int32_t rval; 707 register int offset; 708 709 alpha_mb(); 710 711 tmpioh = ioh + off; 712 offset = tmpioh & 3; 713 port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) | 714 (3 << CHIP_SIZE_SHIFT)); 715 val = *port; 716 #if 0 717 rval = ((val) >> (8 * offset)) & 0xffffffff; 718 #else 719 rval = val; 720 #endif 721 722 return rval; 723 } 724 725 inline u_int64_t 726 __C(CHIP,_io_read_8)(v, ioh, off) 727 void *v; 728 bus_space_handle_t ioh; 729 bus_size_t off; 730 { 731 732 /* XXX XXX XXX */ 733 panic("%s not implemented", __S(__C(CHIP,_io_read_8))); 734 } 735 736 #define CHIP_io_read_multi_N(BYTES,TYPE) \ 737 void \ 738 __C(__C(CHIP,_io_read_multi_),BYTES)(v, h, o, a, c) \ 739 void *v; \ 740 bus_space_handle_t h; \ 741 bus_size_t o, c; \ 742 TYPE *a; \ 743 { \ 744 \ 745 while (c-- > 0) { \ 746 __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \ 747 BUS_SPACE_BARRIER_READ); \ 748 *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \ 749 } \ 750 } 751 CHIP_io_read_multi_N(1,u_int8_t) 752 CHIP_io_read_multi_N(2,u_int16_t) 753 CHIP_io_read_multi_N(4,u_int32_t) 754 CHIP_io_read_multi_N(8,u_int64_t) 755 756 #define CHIP_io_read_region_N(BYTES,TYPE) \ 757 void \ 758 __C(__C(CHIP,_io_read_region_),BYTES)(v, h, o, a, c) \ 759 void *v; \ 760 bus_space_handle_t h; \ 761 bus_size_t o, c; \ 762 TYPE *a; \ 763 { \ 764 \ 765 while (c-- > 0) { \ 766 *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \ 767 o += sizeof *a; \ 768 } \ 769 } 770 CHIP_io_read_region_N(1,u_int8_t) 771 CHIP_io_read_region_N(2,u_int16_t) 772 CHIP_io_read_region_N(4,u_int32_t) 773 CHIP_io_read_region_N(8,u_int64_t) 774 775 inline void 776 __C(CHIP,_io_write_1)(v, ioh, off, val) 777 void *v; 778 bus_space_handle_t ioh; 779 bus_size_t off; 780 u_int8_t val; 781 { 782 register bus_space_handle_t tmpioh; 783 register u_int32_t *port, nval; 784 register int offset; 785 786 tmpioh = ioh + off; 787 offset = tmpioh & 3; 788 nval = val << (8 * offset); 789 port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) | 790 (0 << CHIP_SIZE_SHIFT)); 791 *port = nval; 792 alpha_mb(); 793 } 794 795 inline void 796 __C(CHIP,_io_write_2)(v, ioh, off, val) 797 void *v; 798 bus_space_handle_t ioh; 799 bus_size_t off; 800 u_int16_t val; 801 { 802 register bus_space_handle_t tmpioh; 803 register u_int32_t *port, nval; 804 register int offset; 805 806 tmpioh = ioh + off; 807 offset = tmpioh & 3; 808 nval = val << (8 * offset); 809 port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) | 810 (1 << CHIP_SIZE_SHIFT)); 811 *port = nval; 812 alpha_mb(); 813 } 814 815 inline void 816 __C(CHIP,_io_write_4)(v, ioh, off, val) 817 void *v; 818 bus_space_handle_t ioh; 819 bus_size_t off; 820 u_int32_t val; 821 { 822 register bus_space_handle_t tmpioh; 823 register u_int32_t *port, nval; 824 register int offset; 825 826 tmpioh = ioh + off; 827 offset = tmpioh & 3; 828 nval = val /*<< (8 * offset)*/; 829 port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) | 830 (3 << CHIP_SIZE_SHIFT)); 831 *port = nval; 832 alpha_mb(); 833 } 834 835 inline void 836 __C(CHIP,_io_write_8)(v, ioh, off, val) 837 void *v; 838 bus_space_handle_t ioh; 839 bus_size_t off; 840 u_int64_t val; 841 { 842 843 /* XXX XXX XXX */ 844 panic("%s not implemented", __S(__C(CHIP,_io_write_8))); 845 alpha_mb(); 846 } 847 848 #define CHIP_io_write_multi_N(BYTES,TYPE) \ 849 void \ 850 __C(__C(CHIP,_io_write_multi_),BYTES)(v, h, o, a, c) \ 851 void *v; \ 852 bus_space_handle_t h; \ 853 bus_size_t o, c; \ 854 const TYPE *a; \ 855 { \ 856 \ 857 while (c-- > 0) { \ 858 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \ 859 __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \ 860 BUS_SPACE_BARRIER_WRITE); \ 861 } \ 862 } 863 CHIP_io_write_multi_N(1,u_int8_t) 864 CHIP_io_write_multi_N(2,u_int16_t) 865 CHIP_io_write_multi_N(4,u_int32_t) 866 CHIP_io_write_multi_N(8,u_int64_t) 867 868 #define CHIP_io_write_region_N(BYTES,TYPE) \ 869 void \ 870 __C(__C(CHIP,_io_write_region_),BYTES)(v, h, o, a, c) \ 871 void *v; \ 872 bus_space_handle_t h; \ 873 bus_size_t o, c; \ 874 const TYPE *a; \ 875 { \ 876 \ 877 while (c-- > 0) { \ 878 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \ 879 o += sizeof *a; \ 880 } \ 881 } 882 CHIP_io_write_region_N(1,u_int8_t) 883 CHIP_io_write_region_N(2,u_int16_t) 884 CHIP_io_write_region_N(4,u_int32_t) 885 CHIP_io_write_region_N(8,u_int64_t) 886 887 #define CHIP_io_set_multi_N(BYTES,TYPE) \ 888 void \ 889 __C(__C(CHIP,_io_set_multi_),BYTES)(v, h, o, val, c) \ 890 void *v; \ 891 bus_space_handle_t h; \ 892 bus_size_t o, c; \ 893 TYPE val; \ 894 { \ 895 \ 896 while (c-- > 0) { \ 897 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, val); \ 898 __C(CHIP,_io_barrier)(v, h, o, sizeof val, \ 899 BUS_SPACE_BARRIER_WRITE); \ 900 } \ 901 } 902 CHIP_io_set_multi_N(1,u_int8_t) 903 CHIP_io_set_multi_N(2,u_int16_t) 904 CHIP_io_set_multi_N(4,u_int32_t) 905 CHIP_io_set_multi_N(8,u_int64_t) 906 907 #define CHIP_io_set_region_N(BYTES,TYPE) \ 908 void \ 909 __C(__C(CHIP,_io_set_region_),BYTES)(v, h, o, val, c) \ 910 void *v; \ 911 bus_space_handle_t h; \ 912 bus_size_t o, c; \ 913 TYPE val; \ 914 { \ 915 \ 916 while (c-- > 0) { \ 917 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, val); \ 918 o += sizeof val; \ 919 } \ 920 } 921 CHIP_io_set_region_N(1,u_int8_t) 922 CHIP_io_set_region_N(2,u_int16_t) 923 CHIP_io_set_region_N(4,u_int32_t) 924 CHIP_io_set_region_N(8,u_int64_t) 925 926 #define CHIP_io_copy_region_N(BYTES) \ 927 void \ 928 __C(__C(CHIP,_io_copy_region_),BYTES)(v, h1, o1, h2, o2, c) \ 929 void *v; \ 930 bus_space_handle_t h1, h2; \ 931 bus_size_t o1, o2, c; \ 932 { \ 933 bus_size_t o; \ 934 \ 935 if ((h1 + o1) >= (h2 + o2)) { \ 936 /* src after dest: copy forward */ \ 937 for (o = 0; c != 0; c--, o += BYTES) \ 938 __C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o, \ 939 __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \ 940 } else { \ 941 /* dest after src: copy backwards */ \ 942 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \ 943 __C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o, \ 944 __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \ 945 } \ 946 } 947 CHIP_io_copy_region_N(1) 948 CHIP_io_copy_region_N(2) 949 CHIP_io_copy_region_N(4) 950 CHIP_io_copy_region_N(8) 951