1 1.24 tsutsui /* $NetBSD: bus.h,v 1.24 2023/01/27 19:48:00 tsutsui Exp $ */ 2 1.1 thorpej 3 1.1 thorpej /*- 4 1.1 thorpej * Copyright (c) 1996, 1997, 1998 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) 1997 Scott Reynolds. All rights reserved. 35 1.1 thorpej * 36 1.1 thorpej * Redistribution and use in source and binary forms, with or without 37 1.1 thorpej * modification, are permitted provided that the following conditions 38 1.1 thorpej * are met: 39 1.1 thorpej * 1. Redistributions of source code must retain the above copyright 40 1.1 thorpej * notice, this list of conditions and the following disclaimer. 41 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright 42 1.1 thorpej * notice, this list of conditions and the following disclaimer in the 43 1.1 thorpej * documentation and/or other materials provided with the distribution. 44 1.1 thorpej * 3. The name of the author may not be used to endorse or promote products 45 1.1 thorpej * derived from this software without specific prior written permission 46 1.1 thorpej * 47 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 48 1.1 thorpej * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 49 1.1 thorpej * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50 1.1 thorpej * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 51 1.1 thorpej * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 52 1.1 thorpej * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 53 1.1 thorpej * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 54 1.1 thorpej * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 55 1.1 thorpej * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 56 1.1 thorpej * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 57 1.1 thorpej */ 58 1.1 thorpej 59 1.1 thorpej #ifndef _HP300_BUS_H_ 60 1.1 thorpej #define _HP300_BUS_H_ 61 1.1 thorpej 62 1.1 thorpej /* 63 1.1 thorpej * Values for the hp300 bus space tag, not to be used directly by MI code. 64 1.1 thorpej */ 65 1.1 thorpej #define HP300_BUS_SPACE_INTIO 0 /* space is intio space */ 66 1.1 thorpej #define HP300_BUS_SPACE_DIO 1 /* space is dio space */ 67 1.16 tsutsui #define HP300_BUS_SPACE_SGC 2 /* space is sgc space */ 68 1.1 thorpej 69 1.1 thorpej /* 70 1.1 thorpej * Bus address and size types 71 1.1 thorpej */ 72 1.1 thorpej typedef u_long bus_addr_t; 73 1.1 thorpej typedef u_long bus_size_t; 74 1.1 thorpej 75 1.19 skrll #define PRIxBUSADDR "lx" 76 1.19 skrll #define PRIxBUSSIZE "lx" 77 1.19 skrll #define PRIuBUSSIZE "lu" 78 1.19 skrll 79 1.1 thorpej /* 80 1.1 thorpej * Access methods for bus resources and address space. 81 1.1 thorpej */ 82 1.7 tsutsui typedef struct bus_space_tag *bus_space_tag_t; 83 1.7 tsutsui typedef u_long bus_space_handle_t; 84 1.7 tsutsui 85 1.19 skrll #define PRIxBSH "lx" 86 1.19 skrll 87 1.7 tsutsui /* 88 1.7 tsutsui * Implementation specific structures. 89 1.7 tsutsui * XXX Don't use outside of bus_space definitions! 90 1.7 tsutsui * XXX maybe this should be encapsuled in a non-global .h file? 91 1.8 tsutsui */ 92 1.7 tsutsui 93 1.7 tsutsui struct bus_space_tag { 94 1.7 tsutsui u_int bustype; 95 1.7 tsutsui 96 1.10 tsutsui uint8_t (*bsr1)(bus_space_tag_t, bus_space_handle_t, 97 1.9 thorpej bus_size_t); 98 1.10 tsutsui uint16_t (*bsr2)(bus_space_tag_t, bus_space_handle_t, 99 1.9 thorpej bus_size_t); 100 1.10 tsutsui uint32_t (*bsr4)(bus_space_tag_t, bus_space_handle_t, 101 1.9 thorpej bus_size_t); 102 1.9 thorpej void (*bsrm1)(bus_space_tag_t, bus_space_handle_t, 103 1.10 tsutsui bus_size_t, uint8_t *, bus_size_t); 104 1.9 thorpej void (*bsrm2)(bus_space_tag_t, bus_space_handle_t, 105 1.10 tsutsui bus_size_t, uint16_t *, bus_size_t); 106 1.9 thorpej void (*bsrm4)(bus_space_tag_t, bus_space_handle_t, 107 1.10 tsutsui bus_size_t, uint32_t *, bus_size_t); 108 1.9 thorpej void (*bsrr1)(bus_space_tag_t, bus_space_handle_t, 109 1.10 tsutsui bus_size_t, uint8_t *, bus_size_t); 110 1.9 thorpej void (*bsrr2)(bus_space_tag_t, bus_space_handle_t, 111 1.10 tsutsui bus_size_t, uint16_t *, bus_size_t); 112 1.9 thorpej void (*bsrr4)(bus_space_tag_t, bus_space_handle_t, 113 1.10 tsutsui bus_size_t, uint32_t *, bus_size_t); 114 1.9 thorpej void (*bsw1)(bus_space_tag_t, bus_space_handle_t, 115 1.10 tsutsui bus_size_t, uint8_t); 116 1.9 thorpej void (*bsw2)(bus_space_tag_t, bus_space_handle_t, 117 1.10 tsutsui bus_size_t, uint16_t); 118 1.9 thorpej void (*bsw4)(bus_space_tag_t, bus_space_handle_t, 119 1.10 tsutsui bus_size_t, uint32_t); 120 1.9 thorpej void (*bswm1)(bus_space_tag_t, bus_space_handle_t, 121 1.10 tsutsui bus_size_t, const uint8_t *, bus_size_t); 122 1.9 thorpej void (*bswm2)(bus_space_tag_t, bus_space_handle_t, 123 1.10 tsutsui bus_size_t, const uint16_t *, bus_size_t); 124 1.9 thorpej void (*bswm4)(bus_space_tag_t, bus_space_handle_t, 125 1.10 tsutsui bus_size_t, const uint32_t *, bus_size_t); 126 1.9 thorpej void (*bswr1)(bus_space_tag_t, bus_space_handle_t , 127 1.10 tsutsui bus_size_t, const uint8_t *, bus_size_t); 128 1.9 thorpej void (*bswr2)(bus_space_tag_t, bus_space_handle_t, 129 1.10 tsutsui bus_size_t, const uint16_t *, bus_size_t); 130 1.9 thorpej void (*bswr4)(bus_space_tag_t, bus_space_handle_t, 131 1.10 tsutsui bus_size_t, const uint32_t *, bus_size_t); 132 1.9 thorpej void (*bssm1)(bus_space_tag_t, bus_space_handle_t, 133 1.10 tsutsui bus_size_t, uint8_t, bus_size_t); 134 1.9 thorpej void (*bssm2)(bus_space_tag_t, bus_space_handle_t, 135 1.10 tsutsui bus_size_t, uint16_t, bus_size_t); 136 1.9 thorpej void (*bssm4)(bus_space_tag_t, bus_space_handle_t, 137 1.10 tsutsui bus_size_t, uint32_t, bus_size_t); 138 1.9 thorpej void (*bssr1)(bus_space_tag_t, bus_space_handle_t, 139 1.10 tsutsui bus_size_t, uint8_t, bus_size_t); 140 1.9 thorpej void (*bssr2)(bus_space_tag_t, bus_space_handle_t, 141 1.10 tsutsui bus_size_t, uint16_t, bus_size_t); 142 1.9 thorpej void (*bssr4)(bus_space_tag_t, bus_space_handle_t, 143 1.10 tsutsui bus_size_t, uint32_t, bus_size_t); 144 1.7 tsutsui }; 145 1.1 thorpej 146 1.1 thorpej /* 147 1.9 thorpej * int bus_space_map(bus_space_tag_t t, bus_addr_t addr, 148 1.9 thorpej * bus_size_t size, int flags, bus_space_handle_t *bshp); 149 1.1 thorpej * 150 1.1 thorpej * Map a region of bus space. 151 1.1 thorpej */ 152 1.1 thorpej 153 1.1 thorpej #define BUS_SPACE_MAP_CACHEABLE 0x01 154 1.1 thorpej #define BUS_SPACE_MAP_LINEAR 0x02 155 1.7 tsutsui #define BUS_SPACE_MAP_PREFETCHABLE 0x04 156 1.1 thorpej 157 1.9 thorpej int bus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, 158 1.9 thorpej int, bus_space_handle_t *); 159 1.1 thorpej 160 1.1 thorpej /* 161 1.9 thorpej * void bus_space_unmap(bus_space_tag_t t, 162 1.9 thorpej * bus_space_handle_t bsh, bus_size_t size); 163 1.1 thorpej * 164 1.1 thorpej * Unmap a region of bus space. 165 1.1 thorpej */ 166 1.1 thorpej 167 1.9 thorpej void bus_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t); 168 1.1 thorpej 169 1.1 thorpej /* 170 1.22 skrll * paddr_t bus_space_mmap(bus_space_tag_t t, 171 1.22 skrll * bus_addr_t addr, off_t off, int prot, int flags); 172 1.22 skrll * 173 1.22 skrll * Provide a cookie for pmap_phys_address/pmap_mmap_flags for bus_space address at 174 1.22 skrll * addr + offset and flags. 175 1.22 skrll */ 176 1.22 skrll static __inline paddr_t 177 1.22 skrll bus_space_mmap(bus_space_tag_t t, bus_addr_t addr, off_t off, int prot, int flags) 178 1.22 skrll { 179 1.22 skrll /* Always fail for now */ 180 1.22 skrll return -1; 181 1.22 skrll } 182 1.22 skrll 183 1.22 skrll /* 184 1.9 thorpej * int bus_space_subregion(bus_space_tag_t t, 185 1.1 thorpej * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, 186 1.9 thorpej * bus_space_handle_t *nbshp); 187 1.1 thorpej * 188 1.1 thorpej * Get a new handle for a subregion of an already-mapped area of bus space. 189 1.1 thorpej */ 190 1.1 thorpej 191 1.9 thorpej int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh, 192 1.9 thorpej bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp); 193 1.1 thorpej 194 1.1 thorpej /* 195 1.9 thorpej * int bus_space_alloc(bus_space_tag_t t, bus_addr_t, rstart, 196 1.1 thorpej * bus_addr_t rend, bus_size_t size, bus_size_t align, 197 1.1 thorpej * bus_size_t boundary, int flags, bus_addr_t *addrp, 198 1.9 thorpej * bus_space_handle_t *bshp); 199 1.1 thorpej * 200 1.1 thorpej * Allocate a region of bus space. 201 1.1 thorpej */ 202 1.1 thorpej 203 1.9 thorpej int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, 204 1.1 thorpej bus_addr_t rend, bus_size_t size, bus_size_t align, 205 1.1 thorpej bus_size_t boundary, int cacheable, bus_addr_t *addrp, 206 1.9 thorpej bus_space_handle_t *bshp); 207 1.1 thorpej 208 1.1 thorpej /* 209 1.9 thorpej * int bus_space_free(bus_space_tag_t t, 210 1.9 thorpej * bus_space_handle_t bsh, bus_size_t size); 211 1.1 thorpej * 212 1.1 thorpej * Free a region of bus space. 213 1.1 thorpej */ 214 1.1 thorpej 215 1.9 thorpej void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, 216 1.9 thorpej bus_size_t size); 217 1.5 gmcgarry 218 1.5 gmcgarry /* 219 1.9 thorpej * void *bus_space_vaddr(bus_space_tag_t, bus_space_handle_t); 220 1.5 gmcgarry * 221 1.5 gmcgarry * Get the kernel virtual address for the mapped bus space. 222 1.5 gmcgarry * Only allowed for regions mapped with BUS_SPACE_MAP_LINEAR. 223 1.5 gmcgarry * (XXX not enforced) 224 1.5 gmcgarry */ 225 1.6 gmcgarry #define bus_space_vaddr(t, h) (void *)(h) 226 1.1 thorpej 227 1.1 thorpej /* 228 1.9 thorpej * int hp300_bus_space_probe(bus_space_tag_t t, 229 1.9 thorpej * bus_space_handle_t bsh, bus_size_t offset, int sz); 230 1.1 thorpej * 231 1.1 thorpej * Probe the bus at t/bsh/offset, using sz as the size of the load. 232 1.1 thorpej * 233 1.1 thorpej * This is a machine-dependent extension, and is not to be used by 234 1.1 thorpej * machine-independent code. 235 1.1 thorpej */ 236 1.1 thorpej 237 1.9 thorpej int hp300_bus_space_probe(bus_space_tag_t t, 238 1.9 thorpej bus_space_handle_t bsh, bus_size_t offset, int sz); 239 1.1 thorpej 240 1.1 thorpej /* 241 1.9 thorpej * u_intN_t bus_space_read_N(bus_space_tag_t tag, 242 1.9 thorpej * bus_space_handle_t bsh, bus_size_t offset); 243 1.1 thorpej * 244 1.1 thorpej * Read a 1, 2, 4, or 8 byte quantity from bus space 245 1.1 thorpej * described by tag/handle/offset. 246 1.1 thorpej */ 247 1.1 thorpej 248 1.1 thorpej #define bus_space_read_1(t, h, o) \ 249 1.7 tsutsui (((t)->bsr1 != NULL) ? ((t)->bsr1)(t, h, o) : \ 250 1.10 tsutsui (*(volatile uint8_t *)((h) + (o)))) 251 1.1 thorpej 252 1.1 thorpej #define bus_space_read_2(t, h, o) \ 253 1.7 tsutsui (((t)->bsr2 != NULL) ? ((t)->bsr2)(t, h, o) : \ 254 1.10 tsutsui (*(volatile uint16_t *)((h) + (o)))) 255 1.1 thorpej 256 1.1 thorpej #define bus_space_read_4(t, h, o) \ 257 1.7 tsutsui (((t)->bsr4 != NULL) ? ((t)->bsr4)(t, h, o) : \ 258 1.10 tsutsui (*(volatile uint32_t *)((h) + (o)))) 259 1.1 thorpej 260 1.1 thorpej /* 261 1.9 thorpej * void bus_space_read_multi_N(bus_space_tag_t tag, 262 1.1 thorpej * bus_space_handle_t bsh, bus_size_t offset, 263 1.9 thorpej * u_intN_t *addr, size_t count); 264 1.1 thorpej * 265 1.1 thorpej * Read `count' 1, 2, 4, or 8 byte quantities from bus space 266 1.1 thorpej * described by tag/handle/offset and copy into buffer provided. 267 1.1 thorpej */ 268 1.1 thorpej 269 1.7 tsutsui #define bus_space_read_multi_1(t, h, o, a, c) \ 270 1.7 tsutsui do { \ 271 1.7 tsutsui if ((t)->bsrm1 != NULL) \ 272 1.7 tsutsui ((t)->bsrm1)(t, h, o, a, c); \ 273 1.7 tsutsui else { \ 274 1.12 perry __asm volatile (" \ 275 1.7 tsutsui movl %0,%%a0 ; \ 276 1.7 tsutsui movl %1,%%a1 ; \ 277 1.7 tsutsui movl %2,%%d0 ; \ 278 1.7 tsutsui 1: movb %%a0@,%%a1@+ ; \ 279 1.7 tsutsui subql #1,%%d0 ; \ 280 1.7 tsutsui jne 1b" : \ 281 1.7 tsutsui : \ 282 1.7 tsutsui "r" ((h) + (o)), "g" (a), "g" (c) : \ 283 1.24 tsutsui "a0","a1","d0","memory"); \ 284 1.7 tsutsui } \ 285 1.7 tsutsui } while (/* CONSTCOND */ 0) 286 1.7 tsutsui 287 1.7 tsutsui #define bus_space_read_multi_2(t, h, o, a, c) \ 288 1.7 tsutsui do { \ 289 1.7 tsutsui if ((t)->bsrm2 != NULL) \ 290 1.7 tsutsui ((t)->bsrm2)(t, h, o, a, c); \ 291 1.7 tsutsui else { \ 292 1.12 perry __asm volatile (" \ 293 1.7 tsutsui movl %0,%%a0 ; \ 294 1.7 tsutsui movl %1,%%a1 ; \ 295 1.7 tsutsui movl %2,%%d0 ; \ 296 1.7 tsutsui 1: movw %%a0@,%%a1@+ ; \ 297 1.7 tsutsui subql #1,%%d0 ; \ 298 1.7 tsutsui jne 1b" : \ 299 1.7 tsutsui : \ 300 1.7 tsutsui "r" ((h) + (o)), "g" (a), "g" (c) : \ 301 1.24 tsutsui "a0","a1","d0","memory"); \ 302 1.7 tsutsui } \ 303 1.7 tsutsui } while (/* CONSTCOND */ 0) 304 1.1 thorpej 305 1.1 thorpej #define bus_space_read_multi_4(t, h, o, a, c) do { \ 306 1.7 tsutsui if ((t)->bsrm4 != NULL) \ 307 1.7 tsutsui ((t)->bsrm4)(t, h, o, a, c); \ 308 1.7 tsutsui else { \ 309 1.12 perry __asm volatile (" \ 310 1.7 tsutsui movl %0,%%a0 ; \ 311 1.7 tsutsui movl %1,%%a1 ; \ 312 1.7 tsutsui movl %2,%%d0 ; \ 313 1.7 tsutsui 1: movl %%a0@,%%a1@+ ; \ 314 1.7 tsutsui subql #1,%%d0 ; \ 315 1.7 tsutsui jne 1b" : \ 316 1.7 tsutsui : \ 317 1.7 tsutsui "r" ((h) + (o)), "g" (a), "g" (c) : \ 318 1.24 tsutsui "a0","a1","d0","memory"); \ 319 1.7 tsutsui } \ 320 1.7 tsutsui } while (/* CONSTCOND */ 0) 321 1.1 thorpej 322 1.1 thorpej /* 323 1.9 thorpej * void bus_space_read_region_N(bus_space_tag_t tag, 324 1.1 thorpej * bus_space_handle_t bsh, bus_size_t offset, 325 1.9 thorpej * u_intN_t *addr, size_t count); 326 1.1 thorpej * 327 1.1 thorpej * Read `count' 1, 2, 4, or 8 byte quantities from bus space 328 1.1 thorpej * described by tag/handle and starting at `offset' and copy into 329 1.1 thorpej * buffer provided. 330 1.1 thorpej */ 331 1.1 thorpej 332 1.7 tsutsui #define bus_space_read_region_1(t, h, o, a, c) \ 333 1.7 tsutsui do { \ 334 1.7 tsutsui if ((t)->bsrr1 != NULL) \ 335 1.7 tsutsui ((t)->bsrr1)(t, h, o, a, c); \ 336 1.7 tsutsui else { \ 337 1.12 perry __asm volatile (" \ 338 1.7 tsutsui movl %0,%%a0 ; \ 339 1.7 tsutsui movl %1,%%a1 ; \ 340 1.7 tsutsui movl %2,%%d0 ; \ 341 1.7 tsutsui 1: movb %%a0@+,%%a1@+ ; \ 342 1.7 tsutsui subql #1,%%d0 ; \ 343 1.7 tsutsui jne 1b" : \ 344 1.7 tsutsui : \ 345 1.7 tsutsui "r" ((h) + (o)), "g" (a), "g" (c) : \ 346 1.24 tsutsui "a0","a1","d0","memory"); \ 347 1.7 tsutsui } \ 348 1.7 tsutsui } while (/* CONSTCOND */ 0) 349 1.7 tsutsui 350 1.7 tsutsui #define bus_space_read_region_2(t, h, o, a, c) \ 351 1.7 tsutsui do { \ 352 1.7 tsutsui if ((t)->bsrr2 != NULL) \ 353 1.7 tsutsui ((t)->bsrr2)(t, h, o, a, c); \ 354 1.7 tsutsui else { \ 355 1.12 perry __asm volatile (" \ 356 1.7 tsutsui movl %0,%%a0 ; \ 357 1.7 tsutsui movl %1,%%a1 ; \ 358 1.7 tsutsui movl %2,%%d0 ; \ 359 1.7 tsutsui 1: movw %%a0@+,%%a1@+ ; \ 360 1.7 tsutsui subql #1,%%d0 ; \ 361 1.7 tsutsui jne 1b" : \ 362 1.7 tsutsui : \ 363 1.7 tsutsui "r" ((h) + (o)), "g" (a), "g" (c) : \ 364 1.24 tsutsui "a0","a1","d0","memory"); \ 365 1.7 tsutsui } \ 366 1.7 tsutsui } while (/* CONSTCOND */ 0) 367 1.7 tsutsui 368 1.7 tsutsui #define bus_space_read_region_4(t, h, o, a, c) \ 369 1.7 tsutsui do { \ 370 1.7 tsutsui if ((t)->bsrr4 != NULL) \ 371 1.7 tsutsui ((t)->bsrr4)(t, h, o, a, c); \ 372 1.7 tsutsui else { \ 373 1.12 perry __asm volatile (" \ 374 1.7 tsutsui movl %0,%%a0 ; \ 375 1.7 tsutsui movl %1,%%a1 ; \ 376 1.7 tsutsui movl %2,%%d0 ; \ 377 1.7 tsutsui 1: movl %%a0@+,%%a1@+ ; \ 378 1.7 tsutsui subql #1,%%d0 ; \ 379 1.7 tsutsui jne 1b" : \ 380 1.7 tsutsui : \ 381 1.7 tsutsui "r" ((h) + (o)), "g" (a), "g" (c) : \ 382 1.24 tsutsui "a0","a1","d0","memory"); \ 383 1.7 tsutsui } \ 384 1.7 tsutsui } while (/* CONSTCOND */ 0) 385 1.1 thorpej 386 1.1 thorpej /* 387 1.9 thorpej * void bus_space_write_N(bus_space_tag_t tag, 388 1.1 thorpej * bus_space_handle_t bsh, bus_size_t offset, 389 1.9 thorpej * u_intN_t value); 390 1.1 thorpej * 391 1.1 thorpej * Write the 1, 2, 4, or 8 byte value `value' to bus space 392 1.1 thorpej * described by tag/handle/offset. 393 1.1 thorpej */ 394 1.1 thorpej 395 1.1 thorpej #define bus_space_write_1(t, h, o, v) \ 396 1.7 tsutsui do { \ 397 1.7 tsutsui if ((t)->bsw1 != NULL) \ 398 1.7 tsutsui ((t)->bsw1)(t, h, o, v); \ 399 1.7 tsutsui else \ 400 1.10 tsutsui ((void)(*(volatile uint8_t *)((h) + (o)) = (v))); \ 401 1.7 tsutsui } while (/* CONSTCOND */ 0) 402 1.1 thorpej 403 1.1 thorpej #define bus_space_write_2(t, h, o, v) \ 404 1.7 tsutsui do { \ 405 1.7 tsutsui if ((t)->bsw2 != NULL) \ 406 1.7 tsutsui ((t)->bsw2)(t, h, o, v); \ 407 1.7 tsutsui else \ 408 1.10 tsutsui ((void)(*(volatile uint16_t *)((h) + (o)) = (v))); \ 409 1.7 tsutsui } while (/* CONSTCOND */ 0) 410 1.1 thorpej 411 1.1 thorpej #define bus_space_write_4(t, h, o, v) \ 412 1.7 tsutsui do { \ 413 1.7 tsutsui if ((t)->bsw4 != NULL) \ 414 1.7 tsutsui ((t)->bsw4)(t, h, o, v); \ 415 1.7 tsutsui else \ 416 1.10 tsutsui ((void)(*(volatile uint32_t *)((h) + (o)) = (v))); \ 417 1.7 tsutsui } while (/* CONSTCOND */ 0) 418 1.1 thorpej 419 1.1 thorpej /* 420 1.9 thorpej * void bus_space_write_multi_N(bus_space_tag_t tag, 421 1.1 thorpej * bus_space_handle_t bsh, bus_size_t offset, 422 1.9 thorpej * const u_intN_t *addr, size_t count); 423 1.1 thorpej * 424 1.1 thorpej * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 425 1.1 thorpej * provided to bus space described by tag/handle/offset. 426 1.1 thorpej */ 427 1.1 thorpej 428 1.7 tsutsui #define bus_space_write_multi_1(t, h, o, a, c) \ 429 1.7 tsutsui do { \ 430 1.7 tsutsui if ((t)->bswm1 != NULL) \ 431 1.7 tsutsui ((t)->bswm1)(t, h, o, a, c); \ 432 1.7 tsutsui else { \ 433 1.12 perry __asm volatile (" \ 434 1.7 tsutsui movl %0,%%a0 ; \ 435 1.7 tsutsui movl %1,%%a1 ; \ 436 1.7 tsutsui movl %2,%%d0 ; \ 437 1.7 tsutsui 1: movb %%a1@+,%%a0@ ; \ 438 1.7 tsutsui subql #1,%%d0 ; \ 439 1.7 tsutsui jne 1b" : \ 440 1.7 tsutsui : \ 441 1.7 tsutsui "r" ((h) + (o)), "g" (a), "g" (c) : \ 442 1.24 tsutsui "a0","a1","d0"); \ 443 1.7 tsutsui } \ 444 1.7 tsutsui } while (/* CONSTCOND */ 0) 445 1.7 tsutsui 446 1.7 tsutsui #define bus_space_write_multi_2(t, h, o, a, c) \ 447 1.7 tsutsui do { \ 448 1.7 tsutsui if ((t)->bswm2 != NULL) \ 449 1.7 tsutsui ((t)->bswm2)(t, h, o, a, c); \ 450 1.7 tsutsui else { \ 451 1.12 perry __asm volatile (" \ 452 1.7 tsutsui movl %0,%%a0 ; \ 453 1.7 tsutsui movl %1,%%a1 ; \ 454 1.7 tsutsui movl %2,%%d0 ; \ 455 1.7 tsutsui 1: movw %%a1@+,%%a0@ ; \ 456 1.7 tsutsui subql #1,%%d0 ; \ 457 1.7 tsutsui jne 1b" : \ 458 1.7 tsutsui : \ 459 1.7 tsutsui "r" ((h) + (o)), "g" (a), "g" (c) : \ 460 1.24 tsutsui "a0","a1","d0"); \ 461 1.7 tsutsui } \ 462 1.7 tsutsui } while (/* CONSTCOND */ 0) 463 1.7 tsutsui 464 1.7 tsutsui #define bus_space_write_multi_4(t, h, o, a, c) \ 465 1.7 tsutsui do { \ 466 1.7 tsutsui (void) t; \ 467 1.7 tsutsui if ((t)->bswm4 != NULL) \ 468 1.7 tsutsui ((t)->bswm4)(t, h, o, a, c); \ 469 1.7 tsutsui else { \ 470 1.12 perry __asm volatile (" \ 471 1.7 tsutsui movl %0,%%a0 ; \ 472 1.7 tsutsui movl %1,%%a1 ; \ 473 1.7 tsutsui movl %2,%%d0 ; \ 474 1.7 tsutsui 1: movl %%a1@+,%%a0@ ; \ 475 1.7 tsutsui subql #1,%%d0 ; \ 476 1.7 tsutsui jne 1b" : \ 477 1.7 tsutsui : \ 478 1.7 tsutsui "r" ((h) + (o)), "g" (a), "g" (c) : \ 479 1.24 tsutsui "a0","a1","d0"); \ 480 1.7 tsutsui } \ 481 1.7 tsutsui } while (/* CONSTCOND */ 0) 482 1.1 thorpej 483 1.1 thorpej /* 484 1.9 thorpej * void bus_space_write_region_N(bus_space_tag_t tag, 485 1.1 thorpej * bus_space_handle_t bsh, bus_size_t offset, 486 1.9 thorpej * const u_intN_t *addr, size_t count); 487 1.1 thorpej * 488 1.1 thorpej * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 489 1.1 thorpej * to bus space described by tag/handle starting at `offset'. 490 1.1 thorpej */ 491 1.1 thorpej 492 1.7 tsutsui #define bus_space_write_region_1(t, h, o, a, c) \ 493 1.7 tsutsui do { \ 494 1.7 tsutsui if ((t)->bswr1 != NULL) \ 495 1.7 tsutsui ((t)->bswr1)(t, h, o, a, c); \ 496 1.7 tsutsui else { \ 497 1.12 perry __asm volatile (" \ 498 1.7 tsutsui movl %0,%%a0 ; \ 499 1.7 tsutsui movl %1,%%a1 ; \ 500 1.7 tsutsui movl %2,%%d0 ; \ 501 1.7 tsutsui 1: movb %%a1@+,%%a0@+ ; \ 502 1.7 tsutsui subql #1,%%d0 ; \ 503 1.7 tsutsui jne 1b" : \ 504 1.7 tsutsui : \ 505 1.7 tsutsui "r" ((h) + (o)), "g" (a), "g" (c) : \ 506 1.24 tsutsui "a0","a1","d0"); \ 507 1.7 tsutsui } \ 508 1.7 tsutsui } while (/* CONSTCOND */ 0) 509 1.7 tsutsui 510 1.7 tsutsui #define bus_space_write_region_2(t, h, o, a, c) \ 511 1.7 tsutsui do { \ 512 1.7 tsutsui if ((t)->bswr2) != NULL) \ 513 1.7 tsutsui ((t)->bswr2)(t, h, o, a, c); \ 514 1.7 tsutsui else { \ 515 1.12 perry __asm volatile (" \ 516 1.7 tsutsui movl %0,%%a0 ; \ 517 1.7 tsutsui movl %1,%%a1 ; \ 518 1.7 tsutsui movl %2,%%d0 ; \ 519 1.7 tsutsui 1: movw %%a1@+,%%a0@+ ; \ 520 1.7 tsutsui subql #1,%%d0 ; \ 521 1.7 tsutsui jne 1b" : \ 522 1.7 tsutsui : \ 523 1.7 tsutsui "r" ((h) + (o)), "g" (a), "g" (c) : \ 524 1.24 tsutsui "a0","a1","d0"); \ 525 1.7 tsutsui } \ 526 1.7 tsutsui } while (/* CONSTCOND */ 0) 527 1.7 tsutsui 528 1.7 tsutsui #define bus_space_write_region_4(t, h, o, a, c) \ 529 1.7 tsutsui do { \ 530 1.7 tsutsui if ((t)->bswr4) != NULL) \ 531 1.7 tsutsui ((t)->bswr4)(t, h, o, a, c); \ 532 1.7 tsutsui else { \ 533 1.12 perry __asm volatile (" \ 534 1.7 tsutsui movl %0,%%a0 ; \ 535 1.7 tsutsui movl %1,%%a1 ; \ 536 1.7 tsutsui movl %2,%%d0 ; \ 537 1.7 tsutsui 1: movl %%a1@+,%%a0@+ ; \ 538 1.7 tsutsui subql #1,%%d0 ; \ 539 1.7 tsutsui jne 1b" : \ 540 1.7 tsutsui : \ 541 1.7 tsutsui "r" ((h) + (o)), "g" (a), "g" (c) : \ 542 1.24 tsutsui "a0","a1","d0"); \ 543 1.7 tsutsui } \ 544 1.7 tsutsui } while (/* CONSTCOND */ 0) 545 1.1 thorpej 546 1.1 thorpej /* 547 1.9 thorpej * void bus_space_set_multi_N(bus_space_tag_t tag, 548 1.1 thorpej * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 549 1.9 thorpej * size_t count); 550 1.1 thorpej * 551 1.1 thorpej * Write the 1, 2, 4, or 8 byte value `val' to bus space described 552 1.1 thorpej * by tag/handle/offset `count' times. 553 1.1 thorpej */ 554 1.1 thorpej 555 1.7 tsutsui #define bus_space_set_multi_1(t, h, o, val, c) \ 556 1.7 tsutsui do { \ 557 1.7 tsutsui if ((t)->bssm1 != NULL) \ 558 1.7 tsutsui ((t)->bssm1)(t, h, o, val, c); \ 559 1.7 tsutsui else { \ 560 1.12 perry __asm volatile (" \ 561 1.7 tsutsui movl %0,%%a0 ; \ 562 1.7 tsutsui movl %1,%%d1 ; \ 563 1.7 tsutsui movl %2,%%d0 ; \ 564 1.7 tsutsui 1: movb %%d1,%%a0@ ; \ 565 1.7 tsutsui subql #1,%%d0 ; \ 566 1.7 tsutsui jne 1b" : \ 567 1.7 tsutsui : \ 568 1.7 tsutsui "r" ((h) + (o)), "g" (val), "g" (c) : \ 569 1.24 tsutsui "a0","d0","d1"); \ 570 1.7 tsutsui } \ 571 1.7 tsutsui } while (/* CONSTCOND */ 0) 572 1.7 tsutsui 573 1.7 tsutsui #define bus_space_set_multi_2(t, h, o, val, c) \ 574 1.7 tsutsui do { \ 575 1.7 tsutsui if ((t)->bssm2 != NULL) \ 576 1.7 tsutsui ((t)->bssm2)(t, h, o, val, c); \ 577 1.7 tsutsui else { \ 578 1.12 perry __asm volatile (" \ 579 1.7 tsutsui movl %0,%%a0 ; \ 580 1.7 tsutsui movl %1,%%d1 ; \ 581 1.7 tsutsui movl %2,%%d0 ; \ 582 1.7 tsutsui 1: movw %%d1,%%a0@ ; \ 583 1.7 tsutsui subql #1,%%d0 ; \ 584 1.7 tsutsui jne 1b" : \ 585 1.7 tsutsui : \ 586 1.7 tsutsui "r" ((h) + (o)), "g" (val), "g" (c) : \ 587 1.24 tsutsui "a0","d0","d1"); \ 588 1.7 tsutsui } \ 589 1.7 tsutsui } while (/* CONSTCOND */ 0) 590 1.7 tsutsui 591 1.7 tsutsui #define bus_space_set_multi_4(t, h, o, val, c) \ 592 1.7 tsutsui do { \ 593 1.7 tsutsui if ((t)->bssm4 != NULL) \ 594 1.7 tsutsui ((t)->bssm4)(t, h, o, val, c); \ 595 1.7 tsutsui else { \ 596 1.12 perry __asm volatile (" \ 597 1.7 tsutsui movl %0,%%a0 ; \ 598 1.7 tsutsui movl %1,%%d1 ; \ 599 1.7 tsutsui movl %2,%%d0 ; \ 600 1.7 tsutsui 1: movl %%d1,%%a0@ ; \ 601 1.7 tsutsui subql #1,%%d0 ; \ 602 1.7 tsutsui jne 1b" : \ 603 1.7 tsutsui : \ 604 1.7 tsutsui "r" ((h) + (o)), "g" (val), "g" (c) : \ 605 1.24 tsutsui "a0","d0","d1"); \ 606 1.7 tsutsui } \ 607 1.7 tsutsui } while (/* CONSTCOND */ 0) 608 1.1 thorpej 609 1.1 thorpej /* 610 1.9 thorpej * void bus_space_set_region_N(bus_space_tag_t tag, 611 1.1 thorpej * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 612 1.9 thorpej * size_t count); 613 1.1 thorpej * 614 1.1 thorpej * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 615 1.1 thorpej * by tag/handle starting at `offset'. 616 1.1 thorpej */ 617 1.1 thorpej 618 1.7 tsutsui #define bus_space_set_region_1(t, h, o, val, c) \ 619 1.7 tsutsui do { \ 620 1.7 tsutsui if ((t)->bssr1 != NULL) \ 621 1.7 tsutsui ((t)->bssr1)(t, h, o, val, c); \ 622 1.7 tsutsui else { \ 623 1.12 perry __asm volatile (" \ 624 1.7 tsutsui movl %0,%%a0 ; \ 625 1.7 tsutsui movl %1,%%d1 ; \ 626 1.7 tsutsui movl %2,%%d0 ; \ 627 1.7 tsutsui 1: movb %%d1,%%a0@+ ; \ 628 1.7 tsutsui subql #1,%%d0 ; \ 629 1.7 tsutsui jne 1b" : \ 630 1.7 tsutsui : \ 631 1.7 tsutsui "r" ((h) + (o)), "g" (val), "g" (c) : \ 632 1.24 tsutsui "a0","d0","d1"); \ 633 1.7 tsutsui } \ 634 1.7 tsutsui } while (/* CONSTCOND */ 0) 635 1.7 tsutsui 636 1.7 tsutsui #define bus_space_set_region_2(t, h, o, val, c) \ 637 1.7 tsutsui do { \ 638 1.7 tsutsui if ((t)->bssr2 != NULL) \ 639 1.7 tsutsui ((t)->bssr2)(t, h, o, val, c); \ 640 1.7 tsutsui else { \ 641 1.12 perry __asm volatile (" \ 642 1.7 tsutsui movl %0,%%a0 ; \ 643 1.7 tsutsui movl %1,%%d1 ; \ 644 1.7 tsutsui movl %2,%%d0 ; \ 645 1.7 tsutsui 1: movw %%d1,%%a0@+ ; \ 646 1.7 tsutsui subql #1,%%d0 ; \ 647 1.7 tsutsui jne 1b" : \ 648 1.7 tsutsui : \ 649 1.7 tsutsui "r" ((h) + (o)), "g" (val), "g" (c) : \ 650 1.24 tsutsui "a0","d0","d1"); \ 651 1.7 tsutsui } \ 652 1.7 tsutsui } while (/* CONSTCOND */ 0) 653 1.7 tsutsui 654 1.7 tsutsui #define bus_space_set_region_4(t, h, o, val, c) \ 655 1.7 tsutsui do { \ 656 1.7 tsutsui (void) t; \ 657 1.7 tsutsui if ((t)->bssr4 != NULL) \ 658 1.7 tsutsui ((t)->bssr4)(t, h, o, val, c); \ 659 1.7 tsutsui else { \ 660 1.12 perry __asm volatile (" \ 661 1.7 tsutsui movl %0,%%a0 ; \ 662 1.7 tsutsui movl %1,%%d1 ; \ 663 1.7 tsutsui movl %2,%%d0 ; \ 664 1.7 tsutsui 1: movl %%d1,%%a0@+ ; \ 665 1.7 tsutsui subql #1,%%d0 ; \ 666 1.7 tsutsui jne 1b" : \ 667 1.7 tsutsui : \ 668 1.7 tsutsui "r" ((h) + (o)), "g" (val), "g" (c) : \ 669 1.24 tsutsui "a0","d0","d1"); \ 670 1.7 tsutsui } \ 671 1.7 tsutsui } while (/* CONSTCOND */ 0) 672 1.1 thorpej 673 1.1 thorpej /* 674 1.9 thorpej * void bus_space_copy_region_N(bus_space_tag_t tag, 675 1.1 thorpej * bus_space_handle_t bsh1, bus_size_t off1, 676 1.1 thorpej * bus_space_handle_t bsh2, bus_size_t off2, 677 1.9 thorpej * bus_size_t count); 678 1.1 thorpej * 679 1.1 thorpej * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 680 1.1 thorpej * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 681 1.1 thorpej */ 682 1.1 thorpej 683 1.1 thorpej #define __HP300_copy_region_N(BYTES) \ 684 1.14 christos static __inline void \ 685 1.9 thorpej __CONCAT(bus_space_copy_region_,BYTES)(bus_space_tag_t t, \ 686 1.9 thorpej bus_space_handle_t h1, bus_size_t o1, bus_space_handle_t h2, \ 687 1.9 thorpej bus_size_t o2, bus_size_t c) \ 688 1.1 thorpej { \ 689 1.1 thorpej bus_size_t o; \ 690 1.1 thorpej \ 691 1.1 thorpej if ((h1 + o1) >= (h2 + o2)) { \ 692 1.1 thorpej /* src after dest: copy forward */ \ 693 1.1 thorpej for (o = 0; c != 0; c--, o += BYTES) \ 694 1.1 thorpej __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 695 1.1 thorpej __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 696 1.1 thorpej } else { \ 697 1.1 thorpej /* dest after src: copy backwards */ \ 698 1.1 thorpej for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \ 699 1.1 thorpej __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 700 1.1 thorpej __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 701 1.1 thorpej } \ 702 1.1 thorpej } 703 1.1 thorpej __HP300_copy_region_N(1) 704 1.1 thorpej __HP300_copy_region_N(2) 705 1.1 thorpej __HP300_copy_region_N(4) 706 1.1 thorpej 707 1.1 thorpej #undef __HP300_copy_region_N 708 1.1 thorpej 709 1.1 thorpej /* 710 1.17 tsutsui * Bus stream operations--defined in terms of non-stream counterparts 711 1.17 tsutsui */ 712 1.17 tsutsui #define __BUS_SPACE_HAS_STREAM_METHODS 1 713 1.17 tsutsui #define bus_space_read_stream_1 bus_space_read_1 714 1.17 tsutsui #define bus_space_read_stream_2 bus_space_read_2 715 1.17 tsutsui #define bus_space_read_stream_4 bus_space_read_4 716 1.17 tsutsui #define bus_space_read_stream_8 bus_space_read_8 717 1.17 tsutsui #define bus_space_read_multi_stream_1 bus_space_read_multi_1 718 1.17 tsutsui #define bus_space_read_multi_stream_2 bus_space_read_multi_2 719 1.17 tsutsui #define bus_space_read_multi_stream_4 bus_space_read_multi_4 720 1.17 tsutsui #define bus_space_read_multi_stream_8 bus_space_read_multi_8 721 1.17 tsutsui #define bus_space_read_region_stream_1 bus_space_read_region_1 722 1.17 tsutsui #define bus_space_read_region_stream_2 bus_space_read_region_2 723 1.17 tsutsui #define bus_space_read_region_stream_4 bus_space_read_region_4 724 1.17 tsutsui #define bus_space_read_region_stream_8 bus_space_read_region_8 725 1.17 tsutsui #define bus_space_write_stream_1 bus_space_write_1 726 1.17 tsutsui #define bus_space_write_stream_2 bus_space_write_2 727 1.17 tsutsui #define bus_space_write_stream_4 bus_space_write_4 728 1.17 tsutsui #define bus_space_write_stream_8 bus_space_write_8 729 1.17 tsutsui #define bus_space_write_multi_stream_1 bus_space_write_multi_1 730 1.17 tsutsui #define bus_space_write_multi_stream_2 bus_space_write_multi_2 731 1.17 tsutsui #define bus_space_write_multi_stream_4 bus_space_write_multi_4 732 1.17 tsutsui #define bus_space_write_multi_stream_8 bus_space_write_multi_8 733 1.17 tsutsui #define bus_space_write_region_stream_1 bus_space_write_region_1 734 1.17 tsutsui #define bus_space_write_region_stream_2 bus_space_write_region_2 735 1.17 tsutsui #define bus_space_write_region_stream_4 bus_space_write_region_4 736 1.17 tsutsui #define bus_space_write_region_stream_8 bus_space_write_region_8 737 1.17 tsutsui 738 1.17 tsutsui /* 739 1.1 thorpej * Bus read/write barrier methods. 740 1.1 thorpej * 741 1.9 thorpej * void bus_space_barrier(bus_space_tag_t tag, 742 1.1 thorpej * bus_space_handle_t bsh, bus_size_t offset, 743 1.9 thorpej * bus_size_t len, int flags); 744 1.1 thorpej * 745 1.1 thorpej * Note: the 680x0 does not currently require barriers, but we must 746 1.1 thorpej * provide the flags to MI code. 747 1.1 thorpej */ 748 1.1 thorpej #define bus_space_barrier(t, h, o, l, f) \ 749 1.1 thorpej ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) 750 1.1 thorpej #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 751 1.1 thorpej #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 752 1.2 drochner 753 1.2 drochner #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) 754 1.1 thorpej 755 1.18 tsutsui /* 756 1.18 tsutsui * There is no bus_dma(9)'fied bus drivers on this port. 757 1.18 tsutsui */ 758 1.18 tsutsui #define __HAVE_NO_BUS_DMA 759 1.23 tsutsui 760 1.1 thorpej #endif /* _HP300_BUS_H_ */ 761