1 /* $NetBSD: pci_swiz_bus_io_chipdep.c,v 1.27 1998/08/30 23:29:10 cgd Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 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 /* allocation/deallocation */ 99 int __C(CHIP,_io_alloc) __P((void *, bus_addr_t, bus_addr_t, 100 bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *, 101 bus_space_handle_t *)); 102 void __C(CHIP,_io_free) __P((void *, bus_space_handle_t, 103 bus_size_t)); 104 105 /* barrier */ 106 inline void __C(CHIP,_io_barrier) __P((void *, bus_space_handle_t, 107 bus_size_t, bus_size_t, int)); 108 109 /* read (single) */ 110 inline u_int8_t __C(CHIP,_io_read_1) __P((void *, bus_space_handle_t, 111 bus_size_t)); 112 inline u_int16_t __C(CHIP,_io_read_2) __P((void *, bus_space_handle_t, 113 bus_size_t)); 114 inline u_int32_t __C(CHIP,_io_read_4) __P((void *, bus_space_handle_t, 115 bus_size_t)); 116 inline u_int64_t __C(CHIP,_io_read_8) __P((void *, bus_space_handle_t, 117 bus_size_t)); 118 119 /* read multiple */ 120 void __C(CHIP,_io_read_multi_1) __P((void *, bus_space_handle_t, 121 bus_size_t, u_int8_t *, bus_size_t)); 122 void __C(CHIP,_io_read_multi_2) __P((void *, bus_space_handle_t, 123 bus_size_t, u_int16_t *, bus_size_t)); 124 void __C(CHIP,_io_read_multi_4) __P((void *, bus_space_handle_t, 125 bus_size_t, u_int32_t *, bus_size_t)); 126 void __C(CHIP,_io_read_multi_8) __P((void *, bus_space_handle_t, 127 bus_size_t, u_int64_t *, bus_size_t)); 128 129 /* read region */ 130 void __C(CHIP,_io_read_region_1) __P((void *, bus_space_handle_t, 131 bus_size_t, u_int8_t *, bus_size_t)); 132 void __C(CHIP,_io_read_region_2) __P((void *, bus_space_handle_t, 133 bus_size_t, u_int16_t *, bus_size_t)); 134 void __C(CHIP,_io_read_region_4) __P((void *, bus_space_handle_t, 135 bus_size_t, u_int32_t *, bus_size_t)); 136 void __C(CHIP,_io_read_region_8) __P((void *, bus_space_handle_t, 137 bus_size_t, u_int64_t *, bus_size_t)); 138 139 /* write (single) */ 140 inline void __C(CHIP,_io_write_1) __P((void *, bus_space_handle_t, 141 bus_size_t, u_int8_t)); 142 inline void __C(CHIP,_io_write_2) __P((void *, bus_space_handle_t, 143 bus_size_t, u_int16_t)); 144 inline void __C(CHIP,_io_write_4) __P((void *, bus_space_handle_t, 145 bus_size_t, u_int32_t)); 146 inline void __C(CHIP,_io_write_8) __P((void *, bus_space_handle_t, 147 bus_size_t, u_int64_t)); 148 149 /* write multiple */ 150 void __C(CHIP,_io_write_multi_1) __P((void *, bus_space_handle_t, 151 bus_size_t, const u_int8_t *, bus_size_t)); 152 void __C(CHIP,_io_write_multi_2) __P((void *, bus_space_handle_t, 153 bus_size_t, const u_int16_t *, bus_size_t)); 154 void __C(CHIP,_io_write_multi_4) __P((void *, bus_space_handle_t, 155 bus_size_t, const u_int32_t *, bus_size_t)); 156 void __C(CHIP,_io_write_multi_8) __P((void *, bus_space_handle_t, 157 bus_size_t, const u_int64_t *, bus_size_t)); 158 159 /* write region */ 160 void __C(CHIP,_io_write_region_1) __P((void *, bus_space_handle_t, 161 bus_size_t, const u_int8_t *, bus_size_t)); 162 void __C(CHIP,_io_write_region_2) __P((void *, bus_space_handle_t, 163 bus_size_t, const u_int16_t *, bus_size_t)); 164 void __C(CHIP,_io_write_region_4) __P((void *, bus_space_handle_t, 165 bus_size_t, const u_int32_t *, bus_size_t)); 166 void __C(CHIP,_io_write_region_8) __P((void *, bus_space_handle_t, 167 bus_size_t, const u_int64_t *, bus_size_t)); 168 169 /* set multiple */ 170 void __C(CHIP,_io_set_multi_1) __P((void *, bus_space_handle_t, 171 bus_size_t, u_int8_t, bus_size_t)); 172 void __C(CHIP,_io_set_multi_2) __P((void *, bus_space_handle_t, 173 bus_size_t, u_int16_t, bus_size_t)); 174 void __C(CHIP,_io_set_multi_4) __P((void *, bus_space_handle_t, 175 bus_size_t, u_int32_t, bus_size_t)); 176 void __C(CHIP,_io_set_multi_8) __P((void *, bus_space_handle_t, 177 bus_size_t, u_int64_t, bus_size_t)); 178 179 /* set region */ 180 void __C(CHIP,_io_set_region_1) __P((void *, bus_space_handle_t, 181 bus_size_t, u_int8_t, bus_size_t)); 182 void __C(CHIP,_io_set_region_2) __P((void *, bus_space_handle_t, 183 bus_size_t, u_int16_t, bus_size_t)); 184 void __C(CHIP,_io_set_region_4) __P((void *, bus_space_handle_t, 185 bus_size_t, u_int32_t, bus_size_t)); 186 void __C(CHIP,_io_set_region_8) __P((void *, bus_space_handle_t, 187 bus_size_t, u_int64_t, bus_size_t)); 188 189 /* copy */ 190 void __C(CHIP,_io_copy_region_1) __P((void *, bus_space_handle_t, 191 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t)); 192 void __C(CHIP,_io_copy_region_2) __P((void *, bus_space_handle_t, 193 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t)); 194 void __C(CHIP,_io_copy_region_4) __P((void *, bus_space_handle_t, 195 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t)); 196 void __C(CHIP,_io_copy_region_8) __P((void *, bus_space_handle_t, 197 bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t)); 198 199 /* Internal */ 200 void __C(CHIP,_io_mapit) __P((void *, bus_addr_t, 201 bus_space_handle_t *)); 202 203 #ifndef CHIP_IO_EX_STORE 204 static long 205 __C(CHIP,_io_ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 206 #define CHIP_IO_EX_STORE(v) (__C(CHIP, _io_ex_storage)) 207 #define CHIP_IO_EX_STORE_SIZE(v) (sizeof __C(CHIP, _io_ex_storage)) 208 #endif 209 210 void 211 __C(CHIP,_bus_io_init)(t, v) 212 bus_space_tag_t t; 213 void *v; 214 { 215 struct extent *ex; 216 217 /* 218 * Initialize the bus space tag. 219 */ 220 221 /* cookie */ 222 t->abs_cookie = v; 223 224 /* mapping/unmapping */ 225 t->abs_map = __C(CHIP,_io_map); 226 t->abs_unmap = __C(CHIP,_io_unmap); 227 t->abs_subregion = __C(CHIP,_io_subregion); 228 229 /* allocation/deallocation */ 230 t->abs_alloc = __C(CHIP,_io_alloc); 231 t->abs_free = __C(CHIP,_io_free); 232 233 /* barrier */ 234 t->abs_barrier = __C(CHIP,_io_barrier); 235 236 /* read (single) */ 237 t->abs_r_1 = __C(CHIP,_io_read_1); 238 t->abs_r_2 = __C(CHIP,_io_read_2); 239 t->abs_r_4 = __C(CHIP,_io_read_4); 240 t->abs_r_8 = __C(CHIP,_io_read_8); 241 242 /* read multiple */ 243 t->abs_rm_1 = __C(CHIP,_io_read_multi_1); 244 t->abs_rm_2 = __C(CHIP,_io_read_multi_2); 245 t->abs_rm_4 = __C(CHIP,_io_read_multi_4); 246 t->abs_rm_8 = __C(CHIP,_io_read_multi_8); 247 248 /* read region */ 249 t->abs_rr_1 = __C(CHIP,_io_read_region_1); 250 t->abs_rr_2 = __C(CHIP,_io_read_region_2); 251 t->abs_rr_4 = __C(CHIP,_io_read_region_4); 252 t->abs_rr_8 = __C(CHIP,_io_read_region_8); 253 254 /* write (single) */ 255 t->abs_w_1 = __C(CHIP,_io_write_1); 256 t->abs_w_2 = __C(CHIP,_io_write_2); 257 t->abs_w_4 = __C(CHIP,_io_write_4); 258 t->abs_w_8 = __C(CHIP,_io_write_8); 259 260 /* write multiple */ 261 t->abs_wm_1 = __C(CHIP,_io_write_multi_1); 262 t->abs_wm_2 = __C(CHIP,_io_write_multi_2); 263 t->abs_wm_4 = __C(CHIP,_io_write_multi_4); 264 t->abs_wm_8 = __C(CHIP,_io_write_multi_8); 265 266 /* write region */ 267 t->abs_wr_1 = __C(CHIP,_io_write_region_1); 268 t->abs_wr_2 = __C(CHIP,_io_write_region_2); 269 t->abs_wr_4 = __C(CHIP,_io_write_region_4); 270 t->abs_wr_8 = __C(CHIP,_io_write_region_8); 271 272 /* set multiple */ 273 t->abs_sm_1 = __C(CHIP,_io_set_multi_1); 274 t->abs_sm_2 = __C(CHIP,_io_set_multi_2); 275 t->abs_sm_4 = __C(CHIP,_io_set_multi_4); 276 t->abs_sm_8 = __C(CHIP,_io_set_multi_8); 277 278 /* set region */ 279 t->abs_sr_1 = __C(CHIP,_io_set_region_1); 280 t->abs_sr_2 = __C(CHIP,_io_set_region_2); 281 t->abs_sr_4 = __C(CHIP,_io_set_region_4); 282 t->abs_sr_8 = __C(CHIP,_io_set_region_8); 283 284 /* copy */ 285 t->abs_c_1 = __C(CHIP,_io_copy_region_1); 286 t->abs_c_2 = __C(CHIP,_io_copy_region_2); 287 t->abs_c_4 = __C(CHIP,_io_copy_region_4); 288 t->abs_c_8 = __C(CHIP,_io_copy_region_8); 289 290 /* XXX WE WANT EXTENT_NOCOALESCE, BUT WE CAN'T USE IT. XXX */ 291 ex = extent_create(__S(__C(CHIP,_bus_io)), 0x0UL, 0xffffffffUL, 292 M_DEVBUF, (caddr_t)CHIP_IO_EX_STORE(v), CHIP_IO_EX_STORE_SIZE(v), 293 EX_NOWAIT); 294 extent_alloc_region(ex, 0, 0xffffffffUL, EX_NOWAIT); 295 296 #ifdef CHIP_IO_W1_BUS_START 297 #ifdef EXTENT_DEBUG 298 printf("io: freeing from 0x%lx to 0x%lx\n", CHIP_IO_W1_BUS_START(v), 299 CHIP_IO_W1_BUS_END(v)); 300 #endif 301 extent_free(ex, CHIP_IO_W1_BUS_START(v), 302 CHIP_IO_W1_BUS_END(v) - CHIP_IO_W1_BUS_START(v) + 1, EX_NOWAIT); 303 #endif 304 #ifdef CHIP_IO_W2_BUS_START 305 #ifdef EXTENT_DEBUG 306 printf("io: freeing from 0x%lx to 0x%lx\n", CHIP_IO_W2_BUS_START(v), 307 CHIP_IO_W2_BUS_END(v)); 308 #endif 309 extent_free(ex, CHIP_IO_W2_BUS_START(v), 310 CHIP_IO_W2_BUS_END(v) - CHIP_IO_W2_BUS_START(v) + 1, EX_NOWAIT); 311 #endif 312 313 #ifdef EXTENT_DEBUG 314 extent_print(ex); 315 #endif 316 CHIP_IO_EXTENT(v) = ex; 317 } 318 319 void 320 __C(CHIP,_io_mapit)(v, ioaddr, iohp) 321 void *v; 322 bus_addr_t ioaddr; 323 bus_space_handle_t *iohp; 324 { 325 326 #ifdef CHIP_IO_W1_BUS_START 327 if (ioaddr >= CHIP_IO_W1_BUS_START(v) && 328 ioaddr <= CHIP_IO_W1_BUS_END(v)) { 329 *iohp = (ALPHA_PHYS_TO_K0SEG(CHIP_IO_W1_SYS_START(v)) >> 5) + 330 (ioaddr - CHIP_IO_W1_BUS_START(v)); 331 } else 332 #endif 333 #ifdef CHIP_IO_W2_BUS_START 334 if (ioaddr >= CHIP_IO_W2_BUS_START(v) && 335 ioaddr <= CHIP_IO_W2_BUS_END(v)) { 336 *iohp = (ALPHA_PHYS_TO_K0SEG(CHIP_IO_W2_SYS_START(v)) >> 5) + 337 (ioaddr - CHIP_IO_W2_BUS_START(v)); 338 } else 339 #endif 340 { 341 printf("\n"); 342 #ifdef CHIP_IO_W1_BUS_START 343 printf("%s: window[1]=0x%lx-0x%lx\n", 344 __S(__C(CHIP,_io_map)), CHIP_IO_W1_BUS_START(v), 345 CHIP_IO_W1_BUS_END(v)); 346 #endif 347 #ifdef CHIP_IO_W2_BUS_START 348 printf("%s: window[2]=0x%lx-0x%lx\n", 349 __S(__C(CHIP,_io_map)), CHIP_IO_W2_BUS_START(v), 350 CHIP_IO_W2_BUS_END(v)); 351 #endif 352 panic("%s: don't know how to map %lx", 353 __S(__C(CHIP,_io_mapit)), ioaddr); 354 } 355 } 356 357 int 358 __C(CHIP,_io_map)(v, ioaddr, iosize, flags, iohp, acct) 359 void *v; 360 bus_addr_t ioaddr; 361 bus_size_t iosize; 362 int flags; 363 bus_space_handle_t *iohp; 364 int acct; 365 { 366 int linear = flags & BUS_SPACE_MAP_LINEAR; 367 int error; 368 369 /* 370 * Can't map i/o space linearly. 371 */ 372 if (linear) 373 return (EOPNOTSUPP); 374 375 if (acct == 0) { 376 /* 377 * XXX We should ensure that the region is actually 378 * XXX mappable, but nothing should really be using 379 * XXX this interface (only ISA PnP does, and only 380 * XXX via a machine-dependent hook), so we don't 381 * XXX bother. 382 */ 383 goto mapit; 384 } 385 386 #ifdef EXTENT_DEBUG 387 printf("io: allocating 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1); 388 #endif 389 error = extent_alloc_region(CHIP_IO_EXTENT(v), ioaddr, iosize, 390 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 391 if (error) { 392 #ifdef EXTENT_DEBUG 393 printf("io: allocation failed (%d)\n", error); 394 extent_print(CHIP_IO_EXTENT(v)); 395 #endif 396 return (error); 397 } 398 399 mapit: 400 __C(CHIP,_io_mapit)(v, ioaddr, iohp); 401 402 return (0); 403 } 404 405 void 406 __C(CHIP,_io_unmap)(v, ioh, iosize, acct) 407 void *v; 408 bus_space_handle_t ioh; 409 bus_size_t iosize; 410 int acct; 411 { 412 bus_addr_t ioaddr; 413 int error; 414 415 if (acct == 0) 416 return; 417 418 #ifdef EXTENT_DEBUG 419 printf("io: freeing handle 0x%lx for 0x%lx\n", ioh, iosize); 420 #endif 421 422 ioh = ALPHA_K0SEG_TO_PHYS(ioh << 5) >> 5; 423 424 #ifdef CHIP_IO_W1_BUS_START 425 if ((ioh << 5) >= CHIP_IO_W1_SYS_START(v) && 426 (ioh << 5) <= CHIP_IO_W1_SYS_END(v)) { 427 ioaddr = CHIP_IO_W1_BUS_START(v) + 428 (ioh - (CHIP_IO_W1_SYS_START(v) >> 5)); 429 } else 430 #endif 431 #ifdef CHIP_IO_W2_BUS_START 432 if ((ioh << 5) >= CHIP_IO_W2_SYS_START(v) && 433 (ioh << 5) <= CHIP_IO_W2_SYS_END(v)) { 434 ioaddr = CHIP_IO_W2_BUS_START(v) + 435 (ioh - (CHIP_IO_W2_SYS_START(v) >> 5)); 436 } else 437 #endif 438 { 439 printf("\n"); 440 #ifdef CHIP_IO_W1_BUS_START 441 printf("%s: sys window[1]=0x%lx-0x%lx\n", 442 __S(__C(CHIP,_io_map)), CHIP_IO_W1_SYS_START(v), 443 CHIP_IO_W1_SYS_END(v)); 444 #endif 445 #ifdef CHIP_IO_W2_BUS_START 446 printf("%s: sys window[2]=0x%lx-0x%lx\n", 447 __S(__C(CHIP,_io_map)), CHIP_IO_W2_SYS_START(v), 448 CHIP_IO_W2_SYS_END(v)); 449 #endif 450 panic("%s: don't know how to unmap %lx", 451 __S(__C(CHIP,_io_unmap)), (ioh << 5)); 452 } 453 454 #ifdef EXTENT_DEBUG 455 printf("io: freeing 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1); 456 #endif 457 error = extent_free(CHIP_IO_EXTENT(v), ioaddr, iosize, 458 EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); 459 if (error) { 460 printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n", 461 __S(__C(CHIP,_io_unmap)), ioaddr, ioaddr + iosize - 1, 462 error); 463 #ifdef EXTENT_DEBUG 464 extent_print(CHIP_IO_EXTENT(v)); 465 #endif 466 } 467 } 468 469 int 470 __C(CHIP,_io_subregion)(v, ioh, offset, size, nioh) 471 void *v; 472 bus_space_handle_t ioh, *nioh; 473 bus_size_t offset, size; 474 { 475 476 *nioh = ioh + offset; 477 return (0); 478 } 479 480 int 481 __C(CHIP,_io_alloc)(v, rstart, rend, size, align, boundary, flags, 482 addrp, bshp) 483 void *v; 484 bus_addr_t rstart, rend, *addrp; 485 bus_size_t size, align, boundary; 486 int flags; 487 bus_space_handle_t *bshp; 488 { 489 int linear = flags & BUS_SPACE_MAP_LINEAR; 490 bus_addr_t ioaddr; 491 int error; 492 493 /* 494 * Can't map i/o space linearly. 495 */ 496 if (linear) 497 return (EOPNOTSUPP); 498 499 /* 500 * Do the requested allocation. 501 */ 502 #ifdef EXTENT_DEBUG 503 printf("io: allocating from 0x%lx to 0x%lx\n", rstart, rend); 504 #endif 505 error = extent_alloc_subregion(CHIP_IO_EXTENT(v), rstart, rend, 506 size, align, boundary, 507 EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0), 508 &ioaddr); 509 if (error) { 510 #ifdef EXTENT_DEBUG 511 printf("io: allocation failed (%d)\n", error); 512 extent_print(CHIP_IO_EXTENT(v)); 513 #endif 514 return (error); 515 } 516 517 #ifdef EXTENT_DEBUG 518 printf("io: allocated 0x%lx to 0x%lx\n", ioaddr, ioaddr + size - 1); 519 #endif 520 521 *addrp = ioaddr; 522 __C(CHIP,_io_mapit)(v, ioaddr, bshp); 523 524 return (0); 525 } 526 527 void 528 __C(CHIP,_io_free)(v, bsh, size) 529 void *v; 530 bus_space_handle_t bsh; 531 bus_size_t size; 532 { 533 534 /* Unmap does all we need to do. */ 535 __C(CHIP,_io_unmap)(v, bsh, size, 1); 536 } 537 538 inline void 539 __C(CHIP,_io_barrier)(v, h, o, l, f) 540 void *v; 541 bus_space_handle_t h; 542 bus_size_t o, l; 543 int f; 544 { 545 546 if ((f & BUS_SPACE_BARRIER_READ) != 0) 547 alpha_mb(); 548 else if ((f & BUS_SPACE_BARRIER_WRITE) != 0) 549 alpha_wmb(); 550 } 551 552 inline u_int8_t 553 __C(CHIP,_io_read_1)(v, ioh, off) 554 void *v; 555 bus_space_handle_t ioh; 556 bus_size_t off; 557 { 558 register bus_space_handle_t tmpioh; 559 register u_int32_t *port, val; 560 register u_int8_t rval; 561 register int offset; 562 563 alpha_mb(); 564 565 tmpioh = ioh + off; 566 offset = tmpioh & 3; 567 port = (u_int32_t *)((tmpioh << 5) | (0 << 3)); 568 val = *port; 569 rval = ((val) >> (8 * offset)) & 0xff; 570 571 return rval; 572 } 573 574 inline u_int16_t 575 __C(CHIP,_io_read_2)(v, ioh, off) 576 void *v; 577 bus_space_handle_t ioh; 578 bus_size_t off; 579 { 580 register bus_space_handle_t tmpioh; 581 register u_int32_t *port, val; 582 register u_int16_t rval; 583 register int offset; 584 585 alpha_mb(); 586 587 tmpioh = ioh + off; 588 offset = tmpioh & 3; 589 port = (u_int32_t *)((tmpioh << 5) | (1 << 3)); 590 val = *port; 591 rval = ((val) >> (8 * offset)) & 0xffff; 592 593 return rval; 594 } 595 596 inline u_int32_t 597 __C(CHIP,_io_read_4)(v, ioh, off) 598 void *v; 599 bus_space_handle_t ioh; 600 bus_size_t off; 601 { 602 register bus_space_handle_t tmpioh; 603 register u_int32_t *port, val; 604 register u_int32_t rval; 605 register int offset; 606 607 alpha_mb(); 608 609 tmpioh = ioh + off; 610 offset = tmpioh & 3; 611 port = (u_int32_t *)((tmpioh << 5) | (3 << 3)); 612 val = *port; 613 #if 0 614 rval = ((val) >> (8 * offset)) & 0xffffffff; 615 #else 616 rval = val; 617 #endif 618 619 return rval; 620 } 621 622 inline u_int64_t 623 __C(CHIP,_io_read_8)(v, ioh, off) 624 void *v; 625 bus_space_handle_t ioh; 626 bus_size_t off; 627 { 628 629 /* XXX XXX XXX */ 630 panic("%s not implemented", __S(__C(CHIP,_io_read_8))); 631 } 632 633 #define CHIP_io_read_multi_N(BYTES,TYPE) \ 634 void \ 635 __C(__C(CHIP,_io_read_multi_),BYTES)(v, h, o, a, c) \ 636 void *v; \ 637 bus_space_handle_t h; \ 638 bus_size_t o, c; \ 639 TYPE *a; \ 640 { \ 641 \ 642 while (c-- > 0) { \ 643 __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \ 644 BUS_SPACE_BARRIER_READ); \ 645 *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \ 646 } \ 647 } 648 CHIP_io_read_multi_N(1,u_int8_t) 649 CHIP_io_read_multi_N(2,u_int16_t) 650 CHIP_io_read_multi_N(4,u_int32_t) 651 CHIP_io_read_multi_N(8,u_int64_t) 652 653 #define CHIP_io_read_region_N(BYTES,TYPE) \ 654 void \ 655 __C(__C(CHIP,_io_read_region_),BYTES)(v, h, o, a, c) \ 656 void *v; \ 657 bus_space_handle_t h; \ 658 bus_size_t o, c; \ 659 TYPE *a; \ 660 { \ 661 \ 662 while (c-- > 0) { \ 663 *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \ 664 o += sizeof *a; \ 665 } \ 666 } 667 CHIP_io_read_region_N(1,u_int8_t) 668 CHIP_io_read_region_N(2,u_int16_t) 669 CHIP_io_read_region_N(4,u_int32_t) 670 CHIP_io_read_region_N(8,u_int64_t) 671 672 inline void 673 __C(CHIP,_io_write_1)(v, ioh, off, val) 674 void *v; 675 bus_space_handle_t ioh; 676 bus_size_t off; 677 u_int8_t val; 678 { 679 register bus_space_handle_t tmpioh; 680 register u_int32_t *port, nval; 681 register int offset; 682 683 tmpioh = ioh + off; 684 offset = tmpioh & 3; 685 nval = val << (8 * offset); 686 port = (u_int32_t *)((tmpioh << 5) | (0 << 3)); 687 *port = nval; 688 alpha_mb(); 689 } 690 691 inline void 692 __C(CHIP,_io_write_2)(v, ioh, off, val) 693 void *v; 694 bus_space_handle_t ioh; 695 bus_size_t off; 696 u_int16_t val; 697 { 698 register bus_space_handle_t tmpioh; 699 register u_int32_t *port, nval; 700 register int offset; 701 702 tmpioh = ioh + off; 703 offset = tmpioh & 3; 704 nval = val << (8 * offset); 705 port = (u_int32_t *)((tmpioh << 5) | (1 << 3)); 706 *port = nval; 707 alpha_mb(); 708 } 709 710 inline void 711 __C(CHIP,_io_write_4)(v, ioh, off, val) 712 void *v; 713 bus_space_handle_t ioh; 714 bus_size_t off; 715 u_int32_t val; 716 { 717 register bus_space_handle_t tmpioh; 718 register u_int32_t *port, nval; 719 register int offset; 720 721 tmpioh = ioh + off; 722 offset = tmpioh & 3; 723 nval = val /*<< (8 * offset)*/; 724 port = (u_int32_t *)((tmpioh << 5) | (3 << 3)); 725 *port = nval; 726 alpha_mb(); 727 } 728 729 inline void 730 __C(CHIP,_io_write_8)(v, ioh, off, val) 731 void *v; 732 bus_space_handle_t ioh; 733 bus_size_t off; 734 u_int64_t val; 735 { 736 737 /* XXX XXX XXX */ 738 panic("%s not implemented", __S(__C(CHIP,_io_write_8))); 739 alpha_mb(); 740 } 741 742 #define CHIP_io_write_multi_N(BYTES,TYPE) \ 743 void \ 744 __C(__C(CHIP,_io_write_multi_),BYTES)(v, h, o, a, c) \ 745 void *v; \ 746 bus_space_handle_t h; \ 747 bus_size_t o, c; \ 748 const TYPE *a; \ 749 { \ 750 \ 751 while (c-- > 0) { \ 752 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \ 753 __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \ 754 BUS_SPACE_BARRIER_WRITE); \ 755 } \ 756 } 757 CHIP_io_write_multi_N(1,u_int8_t) 758 CHIP_io_write_multi_N(2,u_int16_t) 759 CHIP_io_write_multi_N(4,u_int32_t) 760 CHIP_io_write_multi_N(8,u_int64_t) 761 762 #define CHIP_io_write_region_N(BYTES,TYPE) \ 763 void \ 764 __C(__C(CHIP,_io_write_region_),BYTES)(v, h, o, a, c) \ 765 void *v; \ 766 bus_space_handle_t h; \ 767 bus_size_t o, c; \ 768 const TYPE *a; \ 769 { \ 770 \ 771 while (c-- > 0) { \ 772 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \ 773 o += sizeof *a; \ 774 } \ 775 } 776 CHIP_io_write_region_N(1,u_int8_t) 777 CHIP_io_write_region_N(2,u_int16_t) 778 CHIP_io_write_region_N(4,u_int32_t) 779 CHIP_io_write_region_N(8,u_int64_t) 780 781 #define CHIP_io_set_multi_N(BYTES,TYPE) \ 782 void \ 783 __C(__C(CHIP,_io_set_multi_),BYTES)(v, h, o, val, c) \ 784 void *v; \ 785 bus_space_handle_t h; \ 786 bus_size_t o, c; \ 787 TYPE val; \ 788 { \ 789 \ 790 while (c-- > 0) { \ 791 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, val); \ 792 __C(CHIP,_io_barrier)(v, h, o, sizeof val, \ 793 BUS_SPACE_BARRIER_WRITE); \ 794 } \ 795 } 796 CHIP_io_set_multi_N(1,u_int8_t) 797 CHIP_io_set_multi_N(2,u_int16_t) 798 CHIP_io_set_multi_N(4,u_int32_t) 799 CHIP_io_set_multi_N(8,u_int64_t) 800 801 #define CHIP_io_set_region_N(BYTES,TYPE) \ 802 void \ 803 __C(__C(CHIP,_io_set_region_),BYTES)(v, h, o, val, c) \ 804 void *v; \ 805 bus_space_handle_t h; \ 806 bus_size_t o, c; \ 807 TYPE val; \ 808 { \ 809 \ 810 while (c-- > 0) { \ 811 __C(__C(CHIP,_io_write_),BYTES)(v, h, o, val); \ 812 o += sizeof val; \ 813 } \ 814 } 815 CHIP_io_set_region_N(1,u_int8_t) 816 CHIP_io_set_region_N(2,u_int16_t) 817 CHIP_io_set_region_N(4,u_int32_t) 818 CHIP_io_set_region_N(8,u_int64_t) 819 820 #define CHIP_io_copy_region_N(BYTES) \ 821 void \ 822 __C(__C(CHIP,_io_copy_region_),BYTES)(v, h1, o1, h2, o2, c) \ 823 void *v; \ 824 bus_space_handle_t h1, h2; \ 825 bus_size_t o1, o2, c; \ 826 { \ 827 bus_size_t o; \ 828 \ 829 if ((h1 + o1) >= (h2 + o2)) { \ 830 /* src after dest: copy forward */ \ 831 for (o = 0; c != 0; c--, o += BYTES) \ 832 __C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o, \ 833 __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \ 834 } else { \ 835 /* dest after src: copy backwards */ \ 836 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \ 837 __C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o, \ 838 __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \ 839 } \ 840 } 841 CHIP_io_copy_region_N(1) 842 CHIP_io_copy_region_N(2) 843 CHIP_io_copy_region_N(4) 844 CHIP_io_copy_region_N(8) 845