1 1.24 thorpej /* $NetBSD: pci_bwx_bus_io_chipdep.c,v 1.24 2023/12/06 01:46:34 thorpej Exp $ */ 2 1.1 thorpej 3 1.1 thorpej /*- 4 1.7 thorpej * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc. 5 1.1 thorpej * All rights reserved. 6 1.1 thorpej * 7 1.1 thorpej * This code is derived from software contributed to The NetBSD Foundation 8 1.1 thorpej * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 1.1 thorpej * NASA Ames Research Center. 10 1.1 thorpej * 11 1.1 thorpej * Redistribution and use in source and binary forms, with or without 12 1.1 thorpej * modification, are permitted provided that the following conditions 13 1.1 thorpej * are met: 14 1.1 thorpej * 1. Redistributions of source code must retain the above copyright 15 1.1 thorpej * notice, this list of conditions and the following disclaimer. 16 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright 17 1.1 thorpej * notice, this list of conditions and the following disclaimer in the 18 1.1 thorpej * documentation and/or other materials provided with the distribution. 19 1.1 thorpej * 20 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.1 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.1 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.1 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.1 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.1 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.1 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.1 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.1 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.1 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.1 thorpej * POSSIBILITY OF SUCH DAMAGE. 31 1.1 thorpej */ 32 1.1 thorpej 33 1.1 thorpej /* 34 1.1 thorpej * Copyright (c) 1995, 1996 Carnegie-Mellon University. 35 1.1 thorpej * All rights reserved. 36 1.1 thorpej * 37 1.1 thorpej * Author: Chris G. Demetriou 38 1.21 matt * 39 1.1 thorpej * Permission to use, copy, modify and distribute this software and 40 1.1 thorpej * its documentation is hereby granted, provided that both the copyright 41 1.1 thorpej * notice and this permission notice appear in all copies of the 42 1.1 thorpej * software, derivative works or modified versions, and any portions 43 1.1 thorpej * thereof, and that both notices appear in supporting documentation. 44 1.21 matt * 45 1.21 matt * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 46 1.21 matt * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 47 1.1 thorpej * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 48 1.21 matt * 49 1.1 thorpej * Carnegie Mellon requests users of this software to return to 50 1.1 thorpej * 51 1.1 thorpej * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU 52 1.1 thorpej * School of Computer Science 53 1.1 thorpej * Carnegie Mellon University 54 1.1 thorpej * Pittsburgh PA 15213-3890 55 1.1 thorpej * 56 1.1 thorpej * any improvements or extensions that they make and grant Carnegie the 57 1.1 thorpej * rights to redistribute these changes. 58 1.1 thorpej */ 59 1.1 thorpej 60 1.1 thorpej /* 61 1.1 thorpej * Common PCI Chipset "bus I/O" functions, for chipsets which have to 62 1.1 thorpej * deal with only a single PCI interface chip in a machine. 63 1.1 thorpej * 64 1.1 thorpej * uses: 65 1.1 thorpej * CHIP name of the 'chip' it's being compiled for. 66 1.1 thorpej * CHIP_IO_BASE I/O space base to use. 67 1.23 thorpej * CHIP_IO_ARENA_STORE 68 1.1 thorpej * If defined, device-provided static storage area 69 1.23 thorpej * for the I/O space arena. If this is defined, 70 1.23 thorpej * CHIP_IO_BTAG_STORE and CHIP_IO_BTAG_COUNT must 71 1.23 thorpej * also be defined. If this is not defined, a 72 1.23 thorpej * static area will be declared. 73 1.23 thorpej * CHIP_IO_BTAG_STORE 74 1.23 thorpej * Device-provided static storage area for the 75 1.23 thorpej * I/O space arena's boundary tags. Ignored 76 1.23 thorpej * unless CHIP_IO_ARENA_STORE is defined. 77 1.23 thorpej * CHIP_IO_BTAG_COUNT 78 1.23 thorpej * The number of device-provided static I/O 79 1.23 thorpej * space boundary tags. Ignored unless 80 1.23 thorpej * CHIP_IO_ARENA_STORE is defined. 81 1.1 thorpej */ 82 1.14 lukem 83 1.14 lukem #include <sys/cdefs.h> 84 1.24 thorpej __KERNEL_RCSID(1, "$NetBSD: pci_bwx_bus_io_chipdep.c,v 1.24 2023/12/06 01:46:34 thorpej Exp $"); 85 1.1 thorpej 86 1.23 thorpej #include <sys/vmem_impl.h> 87 1.6 thorpej 88 1.6 thorpej #include <machine/bwx.h> 89 1.1 thorpej 90 1.1 thorpej #define __C(A,B) __CONCAT(A,B) 91 1.1 thorpej #define __S(S) __STRING(S) 92 1.1 thorpej 93 1.1 thorpej /* mapping/unmapping */ 94 1.22 thorpej static int __C(CHIP,_io_map)(void *, bus_addr_t, bus_size_t, int, 95 1.18 dsl bus_space_handle_t *, int); 96 1.22 thorpej static void __C(CHIP,_io_unmap)(void *, bus_space_handle_t, 97 1.18 dsl bus_size_t, int); 98 1.22 thorpej static int __C(CHIP,_io_subregion)(void *, bus_space_handle_t, 99 1.18 dsl bus_size_t, bus_size_t, bus_space_handle_t *); 100 1.18 dsl 101 1.22 thorpej static int __C(CHIP,_io_translate)(void *, bus_addr_t, bus_size_t, 102 1.18 dsl int, struct alpha_bus_space_translation *); 103 1.22 thorpej static int __C(CHIP,_io_get_window)(void *, int, 104 1.18 dsl struct alpha_bus_space_translation *); 105 1.7 thorpej 106 1.1 thorpej /* allocation/deallocation */ 107 1.22 thorpej static int __C(CHIP,_io_alloc)(void *, bus_addr_t, bus_addr_t, 108 1.1 thorpej bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *, 109 1.21 matt bus_space_handle_t *); 110 1.22 thorpej static void __C(CHIP,_io_free)(void *, bus_space_handle_t, 111 1.18 dsl bus_size_t); 112 1.1 thorpej 113 1.9 drochner /* get kernel virtual address */ 114 1.22 thorpej static void * __C(CHIP,_io_vaddr)(void *, bus_space_handle_t); 115 1.9 drochner 116 1.12 thorpej /* mmap for user */ 117 1.22 thorpej static paddr_t __C(CHIP,_io_mmap)(void *, bus_addr_t, off_t, int, int); 118 1.12 thorpej 119 1.1 thorpej /* barrier */ 120 1.22 thorpej static inline void __C(CHIP,_io_barrier)(void *, bus_space_handle_t, 121 1.18 dsl bus_size_t, bus_size_t, int); 122 1.1 thorpej 123 1.1 thorpej /* read (single) */ 124 1.22 thorpej static inline uint8_t __C(CHIP,_io_read_1)(void *, bus_space_handle_t, 125 1.18 dsl bus_size_t); 126 1.21 matt static inline uint16_t __C(CHIP,_io_read_2)(void *, bus_space_handle_t, 127 1.18 dsl bus_size_t); 128 1.21 matt static inline uint32_t __C(CHIP,_io_read_4)(void *, bus_space_handle_t, 129 1.18 dsl bus_size_t); 130 1.21 matt static inline uint64_t __C(CHIP,_io_read_8)(void *, bus_space_handle_t, 131 1.18 dsl bus_size_t); 132 1.1 thorpej 133 1.1 thorpej /* read multiple */ 134 1.22 thorpej static void __C(CHIP,_io_read_multi_1)(void *, bus_space_handle_t, 135 1.21 matt bus_size_t, uint8_t *, bus_size_t); 136 1.22 thorpej static void __C(CHIP,_io_read_multi_2)(void *, bus_space_handle_t, 137 1.21 matt bus_size_t, uint16_t *, bus_size_t); 138 1.22 thorpej static void __C(CHIP,_io_read_multi_4)(void *, bus_space_handle_t, 139 1.21 matt bus_size_t, uint32_t *, bus_size_t); 140 1.22 thorpej static void __C(CHIP,_io_read_multi_8)(void *, bus_space_handle_t, 141 1.21 matt bus_size_t, uint64_t *, bus_size_t); 142 1.1 thorpej 143 1.1 thorpej /* read region */ 144 1.22 thorpej static void __C(CHIP,_io_read_region_1)(void *, bus_space_handle_t, 145 1.21 matt bus_size_t, uint8_t *, bus_size_t); 146 1.22 thorpej static void __C(CHIP,_io_read_region_2)(void *, bus_space_handle_t, 147 1.21 matt bus_size_t, uint16_t *, bus_size_t); 148 1.22 thorpej static void __C(CHIP,_io_read_region_4)(void *, bus_space_handle_t, 149 1.21 matt bus_size_t, uint32_t *, bus_size_t); 150 1.22 thorpej static void __C(CHIP,_io_read_region_8)(void *, bus_space_handle_t, 151 1.21 matt bus_size_t, uint64_t *, bus_size_t); 152 1.1 thorpej 153 1.1 thorpej /* write (single) */ 154 1.22 thorpej static inline void __C(CHIP,_io_write_1)(void *, bus_space_handle_t, 155 1.21 matt bus_size_t, uint8_t); 156 1.22 thorpej static inline void __C(CHIP,_io_write_2)(void *, bus_space_handle_t, 157 1.21 matt bus_size_t, uint16_t); 158 1.22 thorpej static inline void __C(CHIP,_io_write_4)(void *, bus_space_handle_t, 159 1.21 matt bus_size_t, uint32_t); 160 1.22 thorpej static inline void __C(CHIP,_io_write_8)(void *, bus_space_handle_t, 161 1.21 matt bus_size_t, uint64_t); 162 1.1 thorpej 163 1.1 thorpej /* write multiple */ 164 1.22 thorpej static void __C(CHIP,_io_write_multi_1)(void *, bus_space_handle_t, 165 1.21 matt bus_size_t, const uint8_t *, bus_size_t); 166 1.22 thorpej static void __C(CHIP,_io_write_multi_2)(void *, bus_space_handle_t, 167 1.21 matt bus_size_t, const uint16_t *, bus_size_t); 168 1.22 thorpej static void __C(CHIP,_io_write_multi_4)(void *, bus_space_handle_t, 169 1.21 matt bus_size_t, const uint32_t *, bus_size_t); 170 1.22 thorpej static void __C(CHIP,_io_write_multi_8)(void *, bus_space_handle_t, 171 1.21 matt bus_size_t, const uint64_t *, bus_size_t); 172 1.1 thorpej 173 1.1 thorpej /* write region */ 174 1.22 thorpej static void __C(CHIP,_io_write_region_1)(void *, bus_space_handle_t, 175 1.21 matt bus_size_t, const uint8_t *, bus_size_t); 176 1.22 thorpej static void __C(CHIP,_io_write_region_2)(void *, bus_space_handle_t, 177 1.21 matt bus_size_t, const uint16_t *, bus_size_t); 178 1.22 thorpej static void __C(CHIP,_io_write_region_4)(void *, bus_space_handle_t, 179 1.21 matt bus_size_t, const uint32_t *, bus_size_t); 180 1.22 thorpej static void __C(CHIP,_io_write_region_8)(void *, bus_space_handle_t, 181 1.21 matt bus_size_t, const uint64_t *, bus_size_t); 182 1.1 thorpej 183 1.1 thorpej /* set multiple */ 184 1.22 thorpej static void __C(CHIP,_io_set_multi_1)(void *, bus_space_handle_t, 185 1.21 matt bus_size_t, uint8_t, bus_size_t); 186 1.22 thorpej static void __C(CHIP,_io_set_multi_2)(void *, bus_space_handle_t, 187 1.21 matt bus_size_t, uint16_t, bus_size_t); 188 1.22 thorpej static void __C(CHIP,_io_set_multi_4)(void *, bus_space_handle_t, 189 1.21 matt bus_size_t, uint32_t, bus_size_t); 190 1.22 thorpej static void __C(CHIP,_io_set_multi_8)(void *, bus_space_handle_t, 191 1.21 matt bus_size_t, uint64_t, bus_size_t); 192 1.1 thorpej 193 1.1 thorpej /* set region */ 194 1.22 thorpej static void __C(CHIP,_io_set_region_1)(void *, bus_space_handle_t, 195 1.21 matt bus_size_t, uint8_t, bus_size_t); 196 1.22 thorpej static void __C(CHIP,_io_set_region_2)(void *, bus_space_handle_t, 197 1.21 matt bus_size_t, uint16_t, bus_size_t); 198 1.22 thorpej static void __C(CHIP,_io_set_region_4)(void *, bus_space_handle_t, 199 1.21 matt bus_size_t, uint32_t, bus_size_t); 200 1.22 thorpej static void __C(CHIP,_io_set_region_8)(void *, bus_space_handle_t, 201 1.21 matt bus_size_t, uint64_t, bus_size_t); 202 1.1 thorpej 203 1.1 thorpej /* copy */ 204 1.22 thorpej static void __C(CHIP,_io_copy_region_1)(void *, bus_space_handle_t, 205 1.18 dsl bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t); 206 1.22 thorpej static void __C(CHIP,_io_copy_region_2)(void *, bus_space_handle_t, 207 1.18 dsl bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t); 208 1.22 thorpej static void __C(CHIP,_io_copy_region_4)(void *, bus_space_handle_t, 209 1.18 dsl bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t); 210 1.22 thorpej static void __C(CHIP,_io_copy_region_8)(void *, bus_space_handle_t, 211 1.18 dsl bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t); 212 1.1 thorpej 213 1.23 thorpej #ifndef CHIP_IO_ARENA_STORE 214 1.23 thorpej #define CHIP_IO_BTAG_COUNT(v) VMEM_EST_BTCOUNT(1, 8) 215 1.23 thorpej #define CHIP_IO_BTAG_STORE(v) __C(CHIP,_io_btag_store) 216 1.23 thorpej #define CHIP_IO_ARENA_STORE(v) (&(__C(CHIP,_io_arena_store))) 217 1.23 thorpej 218 1.23 thorpej static struct vmem __C(CHIP,_io_arena_store); 219 1.23 thorpej static struct vmem_btag __C(CHIP,_io_btag_store)[CHIP_IO_BTAG_COUNT(xxx)]; 220 1.23 thorpej #endif /* CHIP_IO_ARENA_STORE */ 221 1.1 thorpej 222 1.1 thorpej void 223 1.21 matt __C(CHIP,_bus_io_init)( 224 1.21 matt bus_space_tag_t t, 225 1.21 matt void *v) 226 1.1 thorpej { 227 1.23 thorpej vmem_t *vm; 228 1.23 thorpej int error __diagused; 229 1.1 thorpej 230 1.1 thorpej /* 231 1.1 thorpej * Initialize the bus space tag. 232 1.1 thorpej */ 233 1.1 thorpej 234 1.1 thorpej /* cookie */ 235 1.1 thorpej t->abs_cookie = v; 236 1.1 thorpej 237 1.1 thorpej /* mapping/unmapping */ 238 1.1 thorpej t->abs_map = __C(CHIP,_io_map); 239 1.1 thorpej t->abs_unmap = __C(CHIP,_io_unmap); 240 1.1 thorpej t->abs_subregion = __C(CHIP,_io_subregion); 241 1.1 thorpej 242 1.7 thorpej t->abs_translate = __C(CHIP,_io_translate); 243 1.8 thorpej t->abs_get_window = __C(CHIP,_io_get_window); 244 1.7 thorpej 245 1.1 thorpej /* allocation/deallocation */ 246 1.1 thorpej t->abs_alloc = __C(CHIP,_io_alloc); 247 1.1 thorpej t->abs_free = __C(CHIP,_io_free); 248 1.1 thorpej 249 1.9 drochner /* get kernel virtual address */ 250 1.9 drochner t->abs_vaddr = __C(CHIP,_io_vaddr); 251 1.9 drochner 252 1.12 thorpej /* mmap for user */ 253 1.12 thorpej t->abs_mmap = __C(CHIP,_io_mmap); 254 1.12 thorpej 255 1.1 thorpej /* barrier */ 256 1.1 thorpej t->abs_barrier = __C(CHIP,_io_barrier); 257 1.1 thorpej 258 1.1 thorpej /* read (single) */ 259 1.1 thorpej t->abs_r_1 = __C(CHIP,_io_read_1); 260 1.1 thorpej t->abs_r_2 = __C(CHIP,_io_read_2); 261 1.1 thorpej t->abs_r_4 = __C(CHIP,_io_read_4); 262 1.1 thorpej t->abs_r_8 = __C(CHIP,_io_read_8); 263 1.1 thorpej 264 1.1 thorpej /* read multiple */ 265 1.1 thorpej t->abs_rm_1 = __C(CHIP,_io_read_multi_1); 266 1.1 thorpej t->abs_rm_2 = __C(CHIP,_io_read_multi_2); 267 1.1 thorpej t->abs_rm_4 = __C(CHIP,_io_read_multi_4); 268 1.1 thorpej t->abs_rm_8 = __C(CHIP,_io_read_multi_8); 269 1.1 thorpej 270 1.1 thorpej /* read region */ 271 1.1 thorpej t->abs_rr_1 = __C(CHIP,_io_read_region_1); 272 1.1 thorpej t->abs_rr_2 = __C(CHIP,_io_read_region_2); 273 1.1 thorpej t->abs_rr_4 = __C(CHIP,_io_read_region_4); 274 1.1 thorpej t->abs_rr_8 = __C(CHIP,_io_read_region_8); 275 1.1 thorpej 276 1.1 thorpej /* write (single) */ 277 1.1 thorpej t->abs_w_1 = __C(CHIP,_io_write_1); 278 1.1 thorpej t->abs_w_2 = __C(CHIP,_io_write_2); 279 1.1 thorpej t->abs_w_4 = __C(CHIP,_io_write_4); 280 1.1 thorpej t->abs_w_8 = __C(CHIP,_io_write_8); 281 1.1 thorpej 282 1.1 thorpej /* write multiple */ 283 1.1 thorpej t->abs_wm_1 = __C(CHIP,_io_write_multi_1); 284 1.1 thorpej t->abs_wm_2 = __C(CHIP,_io_write_multi_2); 285 1.1 thorpej t->abs_wm_4 = __C(CHIP,_io_write_multi_4); 286 1.1 thorpej t->abs_wm_8 = __C(CHIP,_io_write_multi_8); 287 1.1 thorpej 288 1.1 thorpej /* write region */ 289 1.1 thorpej t->abs_wr_1 = __C(CHIP,_io_write_region_1); 290 1.1 thorpej t->abs_wr_2 = __C(CHIP,_io_write_region_2); 291 1.1 thorpej t->abs_wr_4 = __C(CHIP,_io_write_region_4); 292 1.1 thorpej t->abs_wr_8 = __C(CHIP,_io_write_region_8); 293 1.1 thorpej 294 1.1 thorpej /* set multiple */ 295 1.1 thorpej t->abs_sm_1 = __C(CHIP,_io_set_multi_1); 296 1.1 thorpej t->abs_sm_2 = __C(CHIP,_io_set_multi_2); 297 1.1 thorpej t->abs_sm_4 = __C(CHIP,_io_set_multi_4); 298 1.1 thorpej t->abs_sm_8 = __C(CHIP,_io_set_multi_8); 299 1.1 thorpej 300 1.1 thorpej /* set region */ 301 1.1 thorpej t->abs_sr_1 = __C(CHIP,_io_set_region_1); 302 1.1 thorpej t->abs_sr_2 = __C(CHIP,_io_set_region_2); 303 1.1 thorpej t->abs_sr_4 = __C(CHIP,_io_set_region_4); 304 1.1 thorpej t->abs_sr_8 = __C(CHIP,_io_set_region_8); 305 1.1 thorpej 306 1.1 thorpej /* copy */ 307 1.1 thorpej t->abs_c_1 = __C(CHIP,_io_copy_region_1); 308 1.1 thorpej t->abs_c_2 = __C(CHIP,_io_copy_region_2); 309 1.1 thorpej t->abs_c_4 = __C(CHIP,_io_copy_region_4); 310 1.1 thorpej t->abs_c_8 = __C(CHIP,_io_copy_region_8); 311 1.1 thorpej 312 1.23 thorpej vm = vmem_init(CHIP_IO_ARENA_STORE(v), 313 1.23 thorpej __S(__C(CHIP,_bus_io)), /* name */ 314 1.23 thorpej 0, /* addr */ 315 1.23 thorpej 0, /* size */ 316 1.23 thorpej 1, /* quantum */ 317 1.23 thorpej NULL, /* importfn */ 318 1.23 thorpej NULL, /* releasefn */ 319 1.23 thorpej NULL, /* source */ 320 1.23 thorpej 0, /* qcache_max */ 321 1.23 thorpej VM_NOSLEEP | VM_PRIVTAGS, 322 1.23 thorpej IPL_NONE); 323 1.23 thorpej KASSERT(vm != NULL); 324 1.23 thorpej 325 1.23 thorpej vmem_add_bts(vm, CHIP_IO_BTAG_STORE(v), CHIP_IO_BTAG_COUNT(v)); 326 1.23 thorpej error = vmem_add(vm, 0, 0x100000000UL, VM_NOSLEEP); 327 1.23 thorpej KASSERT(error == 0); 328 1.1 thorpej 329 1.23 thorpej CHIP_IO_ARENA(v) = vm; 330 1.1 thorpej } 331 1.1 thorpej 332 1.22 thorpej static int 333 1.21 matt __C(CHIP,_io_translate)( 334 1.21 matt void *v, 335 1.21 matt bus_addr_t ioaddr, 336 1.21 matt bus_size_t iolen, 337 1.21 matt int flags, 338 1.21 matt struct alpha_bus_space_translation *abst) 339 1.7 thorpej { 340 1.7 thorpej int linear = flags & BUS_SPACE_MAP_LINEAR; 341 1.7 thorpej 342 1.7 thorpej /* 343 1.7 thorpej * Can't map i/o space linearly. 344 1.7 thorpej */ 345 1.7 thorpej if (linear) 346 1.7 thorpej return (EOPNOTSUPP); 347 1.7 thorpej 348 1.8 thorpej return (__C(CHIP,_io_get_window)(v, 0, abst)); 349 1.8 thorpej } 350 1.8 thorpej 351 1.22 thorpej static int 352 1.21 matt __C(CHIP,_io_get_window)( 353 1.21 matt void *v, 354 1.21 matt int window, 355 1.21 matt struct alpha_bus_space_translation *abst) 356 1.8 thorpej { 357 1.8 thorpej 358 1.8 thorpej switch (window) { 359 1.8 thorpej case 0: 360 1.8 thorpej abst->abst_bus_start = 0; 361 1.8 thorpej abst->abst_bus_end = 0xffffffffUL; 362 1.11 thorpej abst->abst_sys_start = CHIP_IO_SYS_START(v); 363 1.11 thorpej abst->abst_sys_end = CHIP_IO_SYS_START(v) + abst->abst_bus_end; 364 1.8 thorpej abst->abst_addr_shift = 0; 365 1.8 thorpej abst->abst_size_shift = 0; 366 1.8 thorpej abst->abst_flags = ABST_DENSE|ABST_BWX; 367 1.8 thorpej break; 368 1.8 thorpej 369 1.8 thorpej default: 370 1.8 thorpej panic(__S(__C(CHIP,_io_get_window)) ": invalid window %d", 371 1.8 thorpej window); 372 1.8 thorpej } 373 1.8 thorpej 374 1.7 thorpej return (0); 375 1.7 thorpej } 376 1.7 thorpej 377 1.22 thorpej static int 378 1.21 matt __C(CHIP,_io_map)( 379 1.21 matt void *v, 380 1.21 matt bus_addr_t ioaddr, 381 1.21 matt bus_size_t iosize, 382 1.21 matt int flags, 383 1.21 matt bus_space_handle_t *iohp, 384 1.21 matt int acct) 385 1.1 thorpej { 386 1.7 thorpej struct alpha_bus_space_translation abst; 387 1.1 thorpej int error; 388 1.1 thorpej 389 1.1 thorpej /* 390 1.7 thorpej * Get the translation for this address. 391 1.1 thorpej */ 392 1.7 thorpej error = __C(CHIP,_io_translate)(v, ioaddr, iosize, flags, &abst); 393 1.7 thorpej if (error) 394 1.7 thorpej return (error); 395 1.1 thorpej 396 1.4 thorpej if (acct == 0) 397 1.4 thorpej goto mapit; 398 1.4 thorpej 399 1.1 thorpej #ifdef EXTENT_DEBUG 400 1.1 thorpej printf("io: allocating 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1); 401 1.1 thorpej #endif 402 1.23 thorpej error = vmem_xalloc_addr(CHIP_IO_ARENA(v), ioaddr, iosize, VM_NOSLEEP); 403 1.1 thorpej if (error) { 404 1.1 thorpej #ifdef EXTENT_DEBUG 405 1.1 thorpej printf("io: allocation failed (%d)\n", error); 406 1.23 thorpej /* vmem_print(CHIP_IO_ARENA(v)); XXX */ 407 1.1 thorpej #endif 408 1.1 thorpej return (error); 409 1.1 thorpej } 410 1.1 thorpej 411 1.4 thorpej mapit: 412 1.7 thorpej *iohp = ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start + ioaddr); 413 1.1 thorpej 414 1.1 thorpej return (0); 415 1.1 thorpej } 416 1.1 thorpej 417 1.22 thorpej static void 418 1.21 matt __C(CHIP,_io_unmap)( 419 1.21 matt void *v, 420 1.21 matt bus_space_handle_t ioh, 421 1.21 matt bus_size_t iosize, 422 1.21 matt int acct) 423 1.1 thorpej { 424 1.1 thorpej bus_addr_t ioaddr; 425 1.1 thorpej 426 1.4 thorpej if (acct == 0) 427 1.4 thorpej return; 428 1.4 thorpej 429 1.1 thorpej #ifdef EXTENT_DEBUG 430 1.1 thorpej printf("io: freeing handle 0x%lx for 0x%lx\n", ioh, iosize); 431 1.1 thorpej #endif 432 1.1 thorpej 433 1.1 thorpej ioaddr = ioh - ALPHA_PHYS_TO_K0SEG(CHIP_IO_SYS_START(v)); 434 1.1 thorpej 435 1.1 thorpej #ifdef EXTENT_DEBUG 436 1.1 thorpej printf("io: freeing 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1); 437 1.1 thorpej #endif 438 1.23 thorpej vmem_xfree(CHIP_IO_ARENA(v), ioaddr, iosize); 439 1.1 thorpej } 440 1.1 thorpej 441 1.22 thorpej static int 442 1.21 matt __C(CHIP,_io_subregion)( 443 1.21 matt void *v, 444 1.21 matt bus_space_handle_t ioh, 445 1.21 matt bus_size_t offset, 446 1.21 matt bus_size_t size, 447 1.21 matt bus_space_handle_t *nioh) 448 1.1 thorpej { 449 1.1 thorpej 450 1.1 thorpej *nioh = ioh + offset; 451 1.1 thorpej return (0); 452 1.1 thorpej } 453 1.1 thorpej 454 1.22 thorpej static int 455 1.21 matt __C(CHIP,_io_alloc)( 456 1.21 matt void *v, 457 1.21 matt bus_addr_t rstart, 458 1.21 matt bus_addr_t rend, 459 1.21 matt bus_size_t size, 460 1.21 matt bus_size_t align, 461 1.21 matt bus_size_t boundary, 462 1.21 matt int flags, 463 1.21 matt bus_addr_t *addrp, 464 1.21 matt bus_space_handle_t *bshp) 465 1.1 thorpej { 466 1.7 thorpej struct alpha_bus_space_translation abst; 467 1.2 thorpej int linear = flags & BUS_SPACE_MAP_LINEAR; 468 1.23 thorpej vmem_addr_t ioaddr; 469 1.21 matt int error; 470 1.1 thorpej 471 1.2 thorpej /* 472 1.2 thorpej * Can't map i/o space linearly. 473 1.2 thorpej */ 474 1.2 thorpej if (linear) 475 1.2 thorpej return (EOPNOTSUPP); 476 1.2 thorpej 477 1.2 thorpej /* 478 1.2 thorpej * Do the requested allocation. 479 1.2 thorpej */ 480 1.2 thorpej #ifdef EXTENT_DEBUG 481 1.2 thorpej printf("io: allocating from 0x%lx to 0x%lx\n", rstart, rend); 482 1.2 thorpej #endif 483 1.23 thorpej error = vmem_xalloc(CHIP_IO_ARENA(v), size, 484 1.23 thorpej align, /* align */ 485 1.23 thorpej 0, /* phase */ 486 1.23 thorpej boundary, /* nocross */ 487 1.23 thorpej rstart, /* minaddr */ 488 1.23 thorpej rend, /* maxaddr */ 489 1.24 thorpej VM_BESTFIT | VM_NOSLEEP, 490 1.23 thorpej &ioaddr); 491 1.2 thorpej if (error) { 492 1.2 thorpej #ifdef EXTENT_DEBUG 493 1.2 thorpej printf("io: allocation failed (%d)\n", error); 494 1.23 thorpej /* vmem_print(CHIP_IO_ARENA(v)); XXX */ 495 1.2 thorpej #endif 496 1.2 thorpej return (error); 497 1.2 thorpej } 498 1.2 thorpej 499 1.2 thorpej #ifdef EXTENT_DEBUG 500 1.2 thorpej printf("io: allocated 0x%lx to 0x%lx\n", ioaddr, ioaddr + size - 1); 501 1.2 thorpej #endif 502 1.2 thorpej 503 1.7 thorpej error = __C(CHIP,_io_translate)(v, ioaddr, size, flags, &abst); 504 1.7 thorpej if (error) { 505 1.23 thorpej vmem_xfree(CHIP_IO_ARENA(v), ioaddr, size); 506 1.7 thorpej return (error); 507 1.7 thorpej } 508 1.7 thorpej 509 1.3 thorpej *addrp = ioaddr; 510 1.7 thorpej *bshp = ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start + ioaddr); 511 1.2 thorpej 512 1.2 thorpej return (0); 513 1.1 thorpej } 514 1.1 thorpej 515 1.22 thorpej static void 516 1.21 matt __C(CHIP,_io_free)( 517 1.21 matt void *v, 518 1.21 matt bus_space_handle_t bsh, 519 1.21 matt bus_size_t size) 520 1.1 thorpej { 521 1.1 thorpej 522 1.2 thorpej /* Unmap does all we need to do. */ 523 1.4 thorpej __C(CHIP,_io_unmap)(v, bsh, size, 1); 524 1.9 drochner } 525 1.9 drochner 526 1.22 thorpej static void * 527 1.21 matt __C(CHIP,_io_vaddr)( 528 1.21 matt void *v, 529 1.21 matt bus_space_handle_t bsh) 530 1.9 drochner { 531 1.9 drochner /* 532 1.9 drochner * _io_translate() catches BUS_SPACE_MAP_LINEAR, 533 1.9 drochner * so we shouldn't get here 534 1.9 drochner */ 535 1.9 drochner panic("_io_vaddr"); 536 1.12 thorpej } 537 1.12 thorpej 538 1.22 thorpej static paddr_t 539 1.21 matt __C(CHIP,_io_mmap)( 540 1.21 matt void *v, 541 1.21 matt bus_addr_t addr, 542 1.21 matt off_t off, 543 1.21 matt int prot, 544 1.21 matt int flags) 545 1.12 thorpej { 546 1.12 thorpej 547 1.12 thorpej /* Not supported for I/O space. */ 548 1.12 thorpej return (-1); 549 1.1 thorpej } 550 1.1 thorpej 551 1.19 chs static inline void 552 1.21 matt __C(CHIP,_io_barrier)( 553 1.21 matt void *v, 554 1.21 matt bus_space_handle_t h, 555 1.21 matt bus_size_t o, 556 1.21 matt bus_size_t l, 557 1.21 matt int f) 558 1.1 thorpej { 559 1.1 thorpej 560 1.1 thorpej if ((f & BUS_SPACE_BARRIER_READ) != 0) 561 1.1 thorpej alpha_mb(); 562 1.1 thorpej else if ((f & BUS_SPACE_BARRIER_WRITE) != 0) 563 1.1 thorpej alpha_wmb(); 564 1.1 thorpej } 565 1.1 thorpej 566 1.21 matt static inline uint8_t 567 1.21 matt __C(CHIP,_io_read_1)( 568 1.21 matt void *v, 569 1.21 matt bus_space_handle_t ioh, 570 1.21 matt bus_size_t off) 571 1.1 thorpej { 572 1.1 thorpej bus_addr_t addr; 573 1.1 thorpej 574 1.1 thorpej addr = ioh + off; 575 1.1 thorpej alpha_mb(); 576 1.21 matt return (alpha_ldbu((uint8_t *)addr)); 577 1.1 thorpej } 578 1.1 thorpej 579 1.21 matt static inline uint16_t 580 1.21 matt __C(CHIP,_io_read_2)( 581 1.21 matt void *v, 582 1.21 matt bus_space_handle_t ioh, 583 1.21 matt bus_size_t off) 584 1.1 thorpej { 585 1.1 thorpej bus_addr_t addr; 586 1.1 thorpej 587 1.1 thorpej addr = ioh + off; 588 1.1 thorpej #ifdef DIAGNOSTIC 589 1.1 thorpej if (addr & 1) 590 1.1 thorpej panic(__S(__C(CHIP,_io_read_2)) ": addr 0x%lx not aligned", 591 1.1 thorpej addr); 592 1.1 thorpej #endif 593 1.1 thorpej alpha_mb(); 594 1.21 matt return (alpha_ldwu((uint16_t *)addr)); 595 1.1 thorpej } 596 1.1 thorpej 597 1.21 matt static inline uint32_t 598 1.21 matt __C(CHIP,_io_read_4)( 599 1.21 matt void *v, 600 1.21 matt bus_space_handle_t ioh, 601 1.21 matt bus_size_t off) 602 1.1 thorpej { 603 1.1 thorpej bus_addr_t addr; 604 1.1 thorpej 605 1.1 thorpej addr = ioh + off; 606 1.1 thorpej #ifdef DIAGNOSTIC 607 1.1 thorpej if (addr & 3) 608 1.1 thorpej panic(__S(__C(CHIP,_io_read_4)) ": addr 0x%lx not aligned", 609 1.1 thorpej addr); 610 1.1 thorpej #endif 611 1.1 thorpej alpha_mb(); 612 1.21 matt return (*(uint32_t *)addr); 613 1.1 thorpej } 614 1.1 thorpej 615 1.21 matt static inline uint64_t 616 1.21 matt __C(CHIP,_io_read_8)( 617 1.21 matt void *v, 618 1.21 matt bus_space_handle_t ioh, 619 1.21 matt bus_size_t off) 620 1.1 thorpej { 621 1.1 thorpej 622 1.1 thorpej /* XXX XXX XXX */ 623 1.1 thorpej panic("%s not implemented", __S(__C(CHIP,_io_read_8))); 624 1.1 thorpej } 625 1.1 thorpej 626 1.1 thorpej #define CHIP_io_read_multi_N(BYTES,TYPE) \ 627 1.22 thorpej static void \ 628 1.21 matt __C(__C(CHIP,_io_read_multi_),BYTES)( \ 629 1.21 matt void *v, \ 630 1.21 matt bus_space_handle_t h, \ 631 1.21 matt bus_size_t o, \ 632 1.21 matt TYPE *a, \ 633 1.21 matt bus_size_t c) \ 634 1.1 thorpej { \ 635 1.1 thorpej \ 636 1.1 thorpej while (c-- > 0) { \ 637 1.1 thorpej __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \ 638 1.5 cgd BUS_SPACE_BARRIER_READ); \ 639 1.1 thorpej *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \ 640 1.1 thorpej } \ 641 1.1 thorpej } 642 1.21 matt CHIP_io_read_multi_N(1,uint8_t) 643 1.21 matt CHIP_io_read_multi_N(2,uint16_t) 644 1.21 matt CHIP_io_read_multi_N(4,uint32_t) 645 1.21 matt CHIP_io_read_multi_N(8,uint64_t) 646 1.1 thorpej 647 1.1 thorpej #define CHIP_io_read_region_N(BYTES,TYPE) \ 648 1.22 thorpej static void \ 649 1.21 matt __C(__C(CHIP,_io_read_region_),BYTES)( \ 650 1.21 matt void *v, \ 651 1.21 matt bus_space_handle_t h, \ 652 1.21 matt bus_size_t o, \ 653 1.21 matt TYPE *a, \ 654 1.21 matt bus_size_t c) \ 655 1.1 thorpej { \ 656 1.1 thorpej \ 657 1.1 thorpej while (c-- > 0) { \ 658 1.1 thorpej *a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o); \ 659 1.1 thorpej o += sizeof *a; \ 660 1.1 thorpej } \ 661 1.1 thorpej } 662 1.21 matt CHIP_io_read_region_N(1,uint8_t) 663 1.21 matt CHIP_io_read_region_N(2,uint16_t) 664 1.21 matt CHIP_io_read_region_N(4,uint32_t) 665 1.21 matt CHIP_io_read_region_N(8,uint64_t) 666 1.1 thorpej 667 1.19 chs static inline void 668 1.21 matt __C(CHIP,_io_write_1)( 669 1.21 matt void *v, 670 1.21 matt bus_space_handle_t ioh, 671 1.21 matt bus_size_t off, 672 1.21 matt uint8_t val) 673 1.1 thorpej { 674 1.1 thorpej bus_addr_t addr; 675 1.1 thorpej 676 1.1 thorpej addr = ioh + off; 677 1.21 matt alpha_stb((uint8_t *)addr, val); 678 1.1 thorpej alpha_mb(); 679 1.1 thorpej } 680 1.1 thorpej 681 1.19 chs static inline void 682 1.21 matt __C(CHIP,_io_write_2)( 683 1.21 matt void *v, 684 1.21 matt bus_space_handle_t ioh, 685 1.21 matt bus_size_t off, 686 1.21 matt uint16_t val) 687 1.1 thorpej { 688 1.1 thorpej bus_addr_t addr; 689 1.1 thorpej 690 1.1 thorpej addr = ioh + off; 691 1.1 thorpej #ifdef DIAGNOSTIC 692 1.1 thorpej if (addr & 1) 693 1.1 thorpej panic(__S(__C(CHIP,_io_write_2)) ": addr 0x%lx not aligned", 694 1.1 thorpej addr); 695 1.1 thorpej #endif 696 1.21 matt alpha_stw((uint16_t *)addr, val); 697 1.1 thorpej alpha_mb(); 698 1.1 thorpej } 699 1.1 thorpej 700 1.19 chs static inline void 701 1.21 matt __C(CHIP,_io_write_4)( 702 1.21 matt void *v, 703 1.21 matt bus_space_handle_t ioh, 704 1.21 matt bus_size_t off, 705 1.21 matt uint32_t val) 706 1.1 thorpej { 707 1.1 thorpej bus_addr_t addr; 708 1.1 thorpej 709 1.1 thorpej addr = ioh + off; 710 1.1 thorpej #ifdef DIAGNOSTIC 711 1.1 thorpej if (addr & 3) 712 1.1 thorpej panic(__S(__C(CHIP,_io_write_4)) ": addr 0x%lx not aligned", 713 1.1 thorpej addr); 714 1.1 thorpej #endif 715 1.21 matt *(uint32_t *)addr = val; 716 1.1 thorpej alpha_mb(); 717 1.1 thorpej } 718 1.1 thorpej 719 1.19 chs static inline void 720 1.21 matt __C(CHIP,_io_write_8)( 721 1.21 matt void *v, 722 1.21 matt bus_space_handle_t ioh, 723 1.21 matt bus_size_t off, 724 1.21 matt uint64_t val) 725 1.1 thorpej { 726 1.1 thorpej 727 1.1 thorpej /* XXX XXX XXX */ 728 1.1 thorpej panic("%s not implemented", __S(__C(CHIP,_io_write_8))); 729 1.1 thorpej alpha_mb(); 730 1.1 thorpej } 731 1.1 thorpej 732 1.1 thorpej #define CHIP_io_write_multi_N(BYTES,TYPE) \ 733 1.22 thorpej static void \ 734 1.21 matt __C(__C(CHIP,_io_write_multi_),BYTES)( \ 735 1.21 matt void *v, \ 736 1.21 matt bus_space_handle_t h, \ 737 1.21 matt bus_size_t o, \ 738 1.21 matt const TYPE *a, \ 739 1.21 matt bus_size_t c) \ 740 1.1 thorpej { \ 741 1.1 thorpej \ 742 1.1 thorpej while (c-- > 0) { \ 743 1.1 thorpej __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \ 744 1.1 thorpej __C(CHIP,_io_barrier)(v, h, o, sizeof *a, \ 745 1.5 cgd BUS_SPACE_BARRIER_WRITE); \ 746 1.1 thorpej } \ 747 1.1 thorpej } 748 1.21 matt CHIP_io_write_multi_N(1,uint8_t) 749 1.21 matt CHIP_io_write_multi_N(2,uint16_t) 750 1.21 matt CHIP_io_write_multi_N(4,uint32_t) 751 1.21 matt CHIP_io_write_multi_N(8,uint64_t) 752 1.1 thorpej 753 1.1 thorpej #define CHIP_io_write_region_N(BYTES,TYPE) \ 754 1.22 thorpej static void \ 755 1.21 matt __C(__C(CHIP,_io_write_region_),BYTES)( \ 756 1.21 matt void *v, \ 757 1.21 matt bus_space_handle_t h, \ 758 1.21 matt bus_size_t o, \ 759 1.21 matt const TYPE *a, \ 760 1.21 matt bus_size_t c) \ 761 1.1 thorpej { \ 762 1.1 thorpej \ 763 1.1 thorpej while (c-- > 0) { \ 764 1.1 thorpej __C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++); \ 765 1.1 thorpej o += sizeof *a; \ 766 1.1 thorpej } \ 767 1.1 thorpej } 768 1.21 matt CHIP_io_write_region_N(1,uint8_t) 769 1.21 matt CHIP_io_write_region_N(2,uint16_t) 770 1.21 matt CHIP_io_write_region_N(4,uint32_t) 771 1.21 matt CHIP_io_write_region_N(8,uint64_t) 772 1.1 thorpej 773 1.1 thorpej #define CHIP_io_set_multi_N(BYTES,TYPE) \ 774 1.22 thorpej static void \ 775 1.21 matt __C(__C(CHIP,_io_set_multi_),BYTES)( \ 776 1.21 matt void *v, \ 777 1.21 matt bus_space_handle_t h, \ 778 1.21 matt bus_size_t o, \ 779 1.21 matt TYPE val, \ 780 1.21 matt bus_size_t c) \ 781 1.1 thorpej { \ 782 1.1 thorpej \ 783 1.1 thorpej while (c-- > 0) { \ 784 1.1 thorpej __C(__C(CHIP,_io_write_),BYTES)(v, h, o, val); \ 785 1.1 thorpej __C(CHIP,_io_barrier)(v, h, o, sizeof val, \ 786 1.5 cgd BUS_SPACE_BARRIER_WRITE); \ 787 1.1 thorpej } \ 788 1.1 thorpej } 789 1.21 matt CHIP_io_set_multi_N(1,uint8_t) 790 1.21 matt CHIP_io_set_multi_N(2,uint16_t) 791 1.21 matt CHIP_io_set_multi_N(4,uint32_t) 792 1.21 matt CHIP_io_set_multi_N(8,uint64_t) 793 1.1 thorpej 794 1.1 thorpej #define CHIP_io_set_region_N(BYTES,TYPE) \ 795 1.22 thorpej static void \ 796 1.21 matt __C(__C(CHIP,_io_set_region_),BYTES)( \ 797 1.21 matt void *v, \ 798 1.21 matt bus_space_handle_t h, \ 799 1.21 matt bus_size_t o, \ 800 1.21 matt TYPE val, \ 801 1.21 matt bus_size_t c) \ 802 1.1 thorpej { \ 803 1.1 thorpej \ 804 1.1 thorpej while (c-- > 0) { \ 805 1.1 thorpej __C(__C(CHIP,_io_write_),BYTES)(v, h, o, val); \ 806 1.1 thorpej o += sizeof val; \ 807 1.1 thorpej } \ 808 1.1 thorpej } 809 1.21 matt CHIP_io_set_region_N(1,uint8_t) 810 1.21 matt CHIP_io_set_region_N(2,uint16_t) 811 1.21 matt CHIP_io_set_region_N(4,uint32_t) 812 1.21 matt CHIP_io_set_region_N(8,uint64_t) 813 1.1 thorpej 814 1.1 thorpej #define CHIP_io_copy_region_N(BYTES) \ 815 1.22 thorpej static void \ 816 1.21 matt __C(__C(CHIP,_io_copy_region_),BYTES)( \ 817 1.21 matt void *v, \ 818 1.21 matt bus_space_handle_t h1, \ 819 1.21 matt bus_size_t o1, \ 820 1.21 matt bus_space_handle_t h2, \ 821 1.21 matt bus_size_t o2, \ 822 1.21 matt bus_size_t c) \ 823 1.1 thorpej { \ 824 1.1 thorpej bus_size_t o; \ 825 1.1 thorpej \ 826 1.1 thorpej if ((h1 + o1) >= (h2 + o2)) { \ 827 1.1 thorpej /* src after dest: copy forward */ \ 828 1.1 thorpej for (o = 0; c != 0; c--, o += BYTES) { \ 829 1.1 thorpej __C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o, \ 830 1.1 thorpej __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \ 831 1.1 thorpej } \ 832 1.1 thorpej } else { \ 833 1.1 thorpej /* dest after src: copy backwards */ \ 834 1.1 thorpej for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) { \ 835 1.1 thorpej __C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o, \ 836 1.1 thorpej __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \ 837 1.1 thorpej } \ 838 1.1 thorpej } \ 839 1.1 thorpej } 840 1.1 thorpej CHIP_io_copy_region_N(1) 841 1.1 thorpej CHIP_io_copy_region_N(2) 842 1.1 thorpej CHIP_io_copy_region_N(4) 843 1.1 thorpej CHIP_io_copy_region_N(8) 844