1 1.18 tsutsui /* $NetBSD: bus_space.h,v 1.18 2023/01/27 20:03:02 tsutsui Exp $ */ 2 1.2 scw 3 1.2 scw /*- 4 1.2 scw * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 5 1.2 scw * All rights reserved. 6 1.2 scw * 7 1.2 scw * This code is derived from software contributed to The NetBSD Foundation 8 1.2 scw * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 1.2 scw * NASA Ames Research Center. 10 1.2 scw * 11 1.2 scw * Redistribution and use in source and binary forms, with or without 12 1.2 scw * modification, are permitted provided that the following conditions 13 1.2 scw * are met: 14 1.2 scw * 1. Redistributions of source code must retain the above copyright 15 1.2 scw * notice, this list of conditions and the following disclaimer. 16 1.2 scw * 2. Redistributions in binary form must reproduce the above copyright 17 1.2 scw * notice, this list of conditions and the following disclaimer in the 18 1.2 scw * documentation and/or other materials provided with the distribution. 19 1.2 scw * 20 1.2 scw * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.2 scw * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.2 scw * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.2 scw * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.2 scw * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.2 scw * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.2 scw * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.2 scw * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.2 scw * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.2 scw * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.2 scw * POSSIBILITY OF SUCH DAMAGE. 31 1.2 scw */ 32 1.2 scw 33 1.2 scw /* 34 1.2 scw * Copyright (C) 1997 Scott Reynolds. All rights reserved. 35 1.2 scw * 36 1.2 scw * Redistribution and use in source and binary forms, with or without 37 1.2 scw * modification, are permitted provided that the following conditions 38 1.2 scw * are met: 39 1.2 scw * 1. Redistributions of source code must retain the above copyright 40 1.2 scw * notice, this list of conditions and the following disclaimer. 41 1.2 scw * 2. Redistributions in binary form must reproduce the above copyright 42 1.2 scw * notice, this list of conditions and the following disclaimer in the 43 1.2 scw * documentation and/or other materials provided with the distribution. 44 1.2 scw * 3. The name of the author may not be used to endorse or promote products 45 1.2 scw * derived from this software without specific prior written permission 46 1.2 scw * 47 1.2 scw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 48 1.2 scw * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 49 1.2 scw * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50 1.2 scw * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 51 1.2 scw * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 52 1.2 scw * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 53 1.2 scw * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 54 1.2 scw * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 55 1.2 scw * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 56 1.2 scw * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 57 1.2 scw */ 58 1.2 scw 59 1.2 scw /* 60 1.2 scw * Lifted from the Next68k port. 61 1.2 scw * Modified for mvme68k by Steve Woodford. 62 1.2 scw * 63 1.2 scw * TODO: Support for VMEbus... 64 1.2 scw * (Do any existing VME card drivers use bus_space_* ?) 65 1.2 scw */ 66 1.2 scw 67 1.2 scw #ifndef _MVME68K_BUS_SPACE_H_ 68 1.2 scw #define _MVME68K_BUS_SPACE_H_ 69 1.6 scw 70 1.2 scw /* 71 1.2 scw * Addresses (in bus space). 72 1.2 scw */ 73 1.2 scw typedef u_long bus_addr_t; 74 1.2 scw typedef u_long bus_size_t; 75 1.2 scw 76 1.15 skrll #define PRIxBUSADDR "lx" 77 1.15 skrll #define PRIxBUSSIZE "lx" 78 1.15 skrll #define PRIuBUSSIZE "lu" 79 1.15 skrll 80 1.2 scw /* 81 1.2 scw * Access methods for bus resources and address space. 82 1.2 scw */ 83 1.6 scw struct mvme68k_bus_space_tag; 84 1.6 scw typedef struct mvme68k_bus_space_tag *bus_space_tag_t; 85 1.2 scw typedef u_long bus_space_handle_t; 86 1.2 scw 87 1.15 skrll #define PRIxBSH "lx" 88 1.15 skrll 89 1.6 scw struct mvme68k_bus_space_tag { 90 1.6 scw void *bs_cookie; 91 1.6 scw int (*bs_map)(void *, bus_addr_t, bus_size_t, 92 1.6 scw int, bus_space_handle_t *); 93 1.6 scw void (*bs_unmap)(void *, bus_space_handle_t, bus_size_t); 94 1.6 scw int (*bs_peek_1)(void *, bus_space_handle_t, 95 1.12 tsutsui bus_size_t, uint8_t *); 96 1.6 scw int (*bs_peek_2)(void *, bus_space_handle_t, 97 1.12 tsutsui bus_size_t, uint16_t *); 98 1.6 scw int (*bs_peek_4)(void *, bus_space_handle_t, 99 1.12 tsutsui bus_size_t, uint32_t *); 100 1.6 scw #if 0 101 1.6 scw int (*bs_peek_8)(void *, bus_space_handle_t, 102 1.12 tsutsui bus_size_t, uint64_t *); 103 1.6 scw #endif 104 1.6 scw int (*bs_poke_1)(void *, bus_space_handle_t, 105 1.12 tsutsui bus_size_t, uint8_t); 106 1.6 scw int (*bs_poke_2)(void *, bus_space_handle_t, 107 1.12 tsutsui bus_size_t, uint16_t); 108 1.6 scw int (*bs_poke_4)(void *, bus_space_handle_t, 109 1.12 tsutsui bus_size_t, uint32_t); 110 1.6 scw #if 0 111 1.6 scw int (*bs_poke_8)(void *, bus_space_handle_t, 112 1.12 tsutsui bus_size_t, uint64_t); 113 1.6 scw #endif 114 1.6 scw }; 115 1.2 scw 116 1.2 scw /* 117 1.6 scw * int bus_space_map(bus_space_tag_t t, bus_addr_t addr, 118 1.6 scw * bus_size_t size, int flags, 119 1.6 scw * bus_space_handle_t *bshp); 120 1.5 scw * 121 1.5 scw * Map a region of bus space. 122 1.2 scw */ 123 1.6 scw #define bus_space_map(tag, offset, size, flags, handlep) \ 124 1.6 scw (*((tag)->bs_map))((tag)->bs_cookie, (offset), (size), (flags), (handlep)) 125 1.2 scw 126 1.5 scw /* 127 1.5 scw * Possible values for the 'flags' parameter of bus_space_map() 128 1.5 scw */ 129 1.2 scw #define BUS_SPACE_MAP_CACHEABLE 0x01 130 1.2 scw #define BUS_SPACE_MAP_LINEAR 0x02 131 1.4 drochner #define BUS_SPACE_MAP_PREFETCHABLE 0x04 132 1.5 scw 133 1.5 scw /* 134 1.6 scw * void bus_space_unmap(bus_space_tag_t t, 135 1.6 scw * bus_space_handle_t bsh, bus_size_t size); 136 1.5 scw * 137 1.5 scw * Unmap a region of bus space. 138 1.5 scw */ 139 1.6 scw #define bus_space_unmap(tag, handle, size) \ 140 1.6 scw (*((tag)->bs_unmap))((tag)->bs_cookie, (handle), (size)) 141 1.5 scw 142 1.6 scw /* 143 1.6 scw * int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t h 144 1.6 scw * bus_addr_t offset, bus_size_t size, bus_space_handle_t *newh); 145 1.6 scw * 146 1.6 scw * Allocate a sub-region of an existing map 147 1.6 scw */ 148 1.5 scw #define bus_space_subregion(t, h, o, s, hp) \ 149 1.6 scw ((*(hp)=(h)+(o)), 0) 150 1.2 scw 151 1.2 scw /* 152 1.2 scw * Allocation and deallocation operations. 153 1.2 scw */ 154 1.2 scw #define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) \ 155 1.2 scw (-1) 156 1.2 scw 157 1.2 scw #define bus_space_free(t, h, s) 158 1.2 scw 159 1.2 scw /* 160 1.6 scw * int bus_space_peek_N(bus_space_tag_t tag, 161 1.12 tsutsui * bus_space_handle_t bsh, bus_size_t offset, uintN_t *valuep); 162 1.6 scw * 163 1.6 scw * Cautiously read 1, 2, 4 or 8 byte quantity from bus space described 164 1.6 scw * by tag/handle/offset. 165 1.6 scw * If no hardware responds to the read access, the function returns a 166 1.6 scw * non-zero value. Otherwise the value read is placed in `valuep'. 167 1.6 scw */ 168 1.6 scw #define bus_space_peek_1(t, h, o, vp) \ 169 1.6 scw (*((t)->bs_peek_1))((t)->bs_cookie, (h), (o), (vp)) 170 1.6 scw 171 1.6 scw #define bus_space_peek_2(t, h, o, vp) \ 172 1.6 scw (*((t)->bs_peek_2))((t)->bs_cookie, (h), (o), (vp)) 173 1.6 scw 174 1.6 scw #define bus_space_peek_4(t, h, o, vp) \ 175 1.6 scw (*((t)->bs_peek_4))((t)->bs_cookie, (h), (o), (vp)) 176 1.6 scw 177 1.6 scw /* 178 1.6 scw * int bus_space_poke_N(bus_space_tag_t tag, 179 1.12 tsutsui * bus_space_handle_t bsh, bus_size_t offset, uintN_t value); 180 1.6 scw * 181 1.6 scw * Cautiously write 1, 2, 4 or 8 byte quantity to bus space described 182 1.6 scw * by tag/handle/offset. 183 1.6 scw * If no hardware responds to the write access, the function returns a 184 1.6 scw * non-zero value. 185 1.6 scw */ 186 1.6 scw #define bus_space_poke_1(t, h, o, v) \ 187 1.6 scw (*((t)->bs_poke_1))((t)->bs_cookie, (h), (o), (v)) 188 1.6 scw 189 1.6 scw #define bus_space_poke_2(t, h, o, v) \ 190 1.6 scw (*((t)->bs_poke_2))((t)->bs_cookie, (h), (o), (v)) 191 1.6 scw 192 1.6 scw #define bus_space_poke_4(t, h, o, v) \ 193 1.6 scw (*((t)->bs_poke_4))((t)->bs_cookie, (h), (o), (v)) 194 1.6 scw 195 1.6 scw /* 196 1.12 tsutsui * uintN_t bus_space_read_N(bus_space_tag_t tag, 197 1.6 scw * bus_space_handle_t bsh, bus_size_t offset); 198 1.2 scw * 199 1.2 scw * Read a 1, 2, 4, or 8 byte quantity from bus space 200 1.2 scw * described by tag/handle/offset. 201 1.2 scw */ 202 1.8 scw #define bus_space_read_1(t,h,o) \ 203 1.12 tsutsui (*((volatile uint8_t *)(intptr_t)((h) + (o)))) 204 1.8 scw #define bus_space_read_2(t,h,o) \ 205 1.12 tsutsui (*((volatile uint16_t *)(intptr_t)((h) + (o)))) 206 1.8 scw #define bus_space_read_4(t,h,o) \ 207 1.12 tsutsui (*((volatile uint32_t *)(intptr_t)((h) + (o)))) 208 1.2 scw 209 1.2 scw /* 210 1.6 scw * void bus_space_read_multi_N(bus_space_tag_t tag, 211 1.2 scw * bus_space_handle_t bsh, bus_size_t offset, 212 1.12 tsutsui * uintN_t *addr, size_t count); 213 1.2 scw * 214 1.2 scw * Read `count' 1, 2, 4, or 8 byte quantities from bus space 215 1.2 scw * described by tag/handle/offset and copy into buffer provided. 216 1.2 scw */ 217 1.2 scw 218 1.2 scw #define bus_space_read_multi_1(t, h, o, a, c) do { \ 219 1.2 scw (void) t; \ 220 1.10 perry __asm volatile (" \ 221 1.7 scw movl %0,%%a0 ; \ 222 1.7 scw movl %1,%%a1 ; \ 223 1.7 scw movl %2,%%d0 ; \ 224 1.7 scw 1: movb %%a0@,%%a1@+ ; \ 225 1.7 scw subql #1,%%d0 ; \ 226 1.2 scw jne 1b" : \ 227 1.2 scw : \ 228 1.2 scw "r" ((h) + (o)), "g" (a), "g" (c) : \ 229 1.18 tsutsui "a0","a1","d0","memory"); \ 230 1.2 scw } while (0); 231 1.2 scw 232 1.2 scw #define bus_space_read_multi_2(t, h, o, a, c) do { \ 233 1.2 scw (void) t; \ 234 1.10 perry __asm volatile (" \ 235 1.7 scw movl %0,%%a0 ; \ 236 1.7 scw movl %1,%%a1 ; \ 237 1.7 scw movl %2,%%d0 ; \ 238 1.7 scw 1: movw %%a0@,%%a1@+ ; \ 239 1.7 scw subql #1,%%d0 ; \ 240 1.2 scw jne 1b" : \ 241 1.2 scw : \ 242 1.2 scw "r" ((h) + (o)), "g" (a), "g" (c) : \ 243 1.18 tsutsui "a0","a1","d0","memory"); \ 244 1.2 scw } while (0); 245 1.2 scw 246 1.2 scw #define bus_space_read_multi_4(t, h, o, a, c) do { \ 247 1.2 scw (void) t; \ 248 1.10 perry __asm volatile (" \ 249 1.7 scw movl %0,%%a0 ; \ 250 1.7 scw movl %1,%%a1 ; \ 251 1.7 scw movl %2,%%d0 ; \ 252 1.7 scw 1: movl %%a0@,%%a1@+ ; \ 253 1.7 scw subql #1,%%d0 ; \ 254 1.2 scw jne 1b" : \ 255 1.2 scw : \ 256 1.2 scw "r" ((h) + (o)), "g" (a), "g" (c) : \ 257 1.18 tsutsui "a0","a1","d0","memory"); \ 258 1.2 scw } while (0); 259 1.2 scw 260 1.2 scw /* 261 1.6 scw * void bus_space_read_region_N(bus_space_tag_t tag, 262 1.2 scw * bus_space_handle_t bsh, bus_size_t offset, 263 1.12 tsutsui * uintN_t *addr, size_t count); 264 1.2 scw * 265 1.2 scw * Read `count' 1, 2, 4, or 8 byte quantities from bus space 266 1.2 scw * described by tag/handle and starting at `offset' and copy into 267 1.2 scw * buffer provided. 268 1.2 scw */ 269 1.2 scw 270 1.2 scw #define bus_space_read_region_1(t, h, o, a, c) do { \ 271 1.2 scw (void) t; \ 272 1.10 perry __asm volatile (" \ 273 1.7 scw movl %0,%%a0 ; \ 274 1.7 scw movl %1,%%a1 ; \ 275 1.7 scw movl %2,%%d0 ; \ 276 1.7 scw 1: movb %%a0@+,%%a1@+ ; \ 277 1.7 scw subql #1,%%d0 ; \ 278 1.2 scw jne 1b" : \ 279 1.2 scw : \ 280 1.2 scw "r" ((h) + (o)), "g" (a), "g" (c) : \ 281 1.18 tsutsui "a0","a1","d0","memory"); \ 282 1.2 scw } while (0); 283 1.2 scw 284 1.2 scw #define bus_space_read_region_2(t, h, o, a, c) do { \ 285 1.2 scw (void) t; \ 286 1.10 perry __asm volatile (" \ 287 1.7 scw movl %0,%%a0 ; \ 288 1.7 scw movl %1,%%a1 ; \ 289 1.7 scw movl %2,%%d0 ; \ 290 1.7 scw 1: movw %%a0@+,%%a1@+ ; \ 291 1.7 scw subql #1,%%d0 ; \ 292 1.2 scw jne 1b" : \ 293 1.2 scw : \ 294 1.2 scw "r" ((h) + (o)), "g" (a), "g" (c) : \ 295 1.18 tsutsui "a0","a1","d0","memory"); \ 296 1.2 scw } while (0); 297 1.2 scw 298 1.2 scw #define bus_space_read_region_4(t, h, o, a, c) do { \ 299 1.2 scw (void) t; \ 300 1.10 perry __asm volatile (" \ 301 1.7 scw movl %0,%%a0 ; \ 302 1.7 scw movl %1,%%a1 ; \ 303 1.7 scw movl %2,%%d0 ; \ 304 1.7 scw 1: movl %%a0@+,%%a1@+ ; \ 305 1.7 scw subql #1,%%d0 ; \ 306 1.2 scw jne 1b" : \ 307 1.2 scw : \ 308 1.2 scw "r" ((h) + (o)), "g" (a), "g" (c) : \ 309 1.18 tsutsui "a0","a1","d0","memory"); \ 310 1.2 scw } while (0); 311 1.2 scw 312 1.2 scw /* 313 1.6 scw * void bus_space_write_N(bus_space_tag_t tag, 314 1.2 scw * bus_space_handle_t bsh, bus_size_t offset, 315 1.12 tsutsui * uintN_t value); 316 1.2 scw * 317 1.2 scw * Write the 1, 2, 4, or 8 byte value `value' to bus space 318 1.2 scw * described by tag/handle/offset. 319 1.2 scw */ 320 1.8 scw #define bus_space_write_1(t,h,o,v) \ 321 1.8 scw do { \ 322 1.12 tsutsui *((volatile uint8_t *)(intptr_t)((h) + (o))) = (v); \ 323 1.8 scw } while (/*CONSTCOND*/0) 324 1.8 scw #define bus_space_write_2(t,h,o,v) \ 325 1.8 scw do { \ 326 1.12 tsutsui *((volatile uint16_t *)(intptr_t)((h) + (o))) = (v); \ 327 1.8 scw } while (/*CONSTCOND*/0) 328 1.8 scw #define bus_space_write_4(t,h,o,v) \ 329 1.8 scw do { \ 330 1.12 tsutsui *((volatile uint32_t *)(intptr_t)((h) + (o))) = (v); \ 331 1.8 scw } while (/*CONSTCOND*/0) 332 1.2 scw 333 1.2 scw /* 334 1.6 scw * void bus_space_write_multi_N(bus_space_tag_t tag, 335 1.2 scw * bus_space_handle_t bsh, bus_size_t offset, 336 1.12 tsutsui * const uintN_t *addr, size_t count); 337 1.2 scw * 338 1.2 scw * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 339 1.2 scw * provided to bus space described by tag/handle/offset. 340 1.2 scw */ 341 1.2 scw 342 1.2 scw #define bus_space_write_multi_1(t, h, o, a, c) do { \ 343 1.2 scw (void) t; \ 344 1.10 perry __asm volatile (" \ 345 1.7 scw movl %0,%%a0 ; \ 346 1.7 scw movl %1,%%a1 ; \ 347 1.7 scw movl %2,%%d0 ; \ 348 1.7 scw 1: movb %%a1@+,%%a0@ ; \ 349 1.7 scw subql #1,%%d0 ; \ 350 1.2 scw jne 1b" : \ 351 1.2 scw : \ 352 1.2 scw "r" ((h) + (o)), "g" (a), "g" (c) : \ 353 1.2 scw "a0","a1","d0"); \ 354 1.2 scw } while (0); 355 1.2 scw 356 1.2 scw #define bus_space_write_multi_2(t, h, o, a, c) do { \ 357 1.2 scw (void) t; \ 358 1.10 perry __asm volatile (" \ 359 1.7 scw movl %0,%%a0 ; \ 360 1.7 scw movl %1,%%a1 ; \ 361 1.7 scw movl %2,%%d0 ; \ 362 1.7 scw 1: movw %%a1@+,%%a0@ ; \ 363 1.7 scw subql #1,%%d0 ; \ 364 1.2 scw jne 1b" : \ 365 1.2 scw : \ 366 1.2 scw "r" ((h) + (o)), "g" (a), "g" (c) : \ 367 1.2 scw "a0","a1","d0"); \ 368 1.2 scw } while (0); 369 1.2 scw 370 1.2 scw #define bus_space_write_multi_4(t, h, o, a, c) do { \ 371 1.2 scw (void) t; \ 372 1.10 perry __asm volatile (" \ 373 1.7 scw movl %0,%%a0 ; \ 374 1.7 scw movl %1,%%a1 ; \ 375 1.7 scw movl %2,%%d0 ; \ 376 1.7 scw 1: movl a1@+,%%a0@ ; \ 377 1.7 scw subql #1,%%d0 ; \ 378 1.2 scw jne 1b" : \ 379 1.2 scw : \ 380 1.2 scw "r" ((h) + (o)), "g" (a), "g" (c) : \ 381 1.2 scw "a0","a1","d0"); \ 382 1.2 scw } while (0); 383 1.2 scw 384 1.2 scw /* 385 1.6 scw * void bus_space_write_region_N(bus_space_tag_t tag, 386 1.2 scw * bus_space_handle_t bsh, bus_size_t offset, 387 1.12 tsutsui * const uintN_t *addr, size_t count); 388 1.2 scw * 389 1.2 scw * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 390 1.2 scw * to bus space described by tag/handle starting at `offset'. 391 1.2 scw */ 392 1.2 scw 393 1.2 scw #define bus_space_write_region_1(t, h, o, a, c) do { \ 394 1.2 scw (void) t; \ 395 1.10 perry __asm volatile (" \ 396 1.7 scw movl %0,%%a0 ; \ 397 1.7 scw movl %1,%%a1 ; \ 398 1.7 scw movl %2,%%d0 ; \ 399 1.7 scw 1: movb %%a1@+,%%a0@+ ; \ 400 1.7 scw subql #1,%%d0 ; \ 401 1.2 scw jne 1b" : \ 402 1.2 scw : \ 403 1.2 scw "r" ((h) + (o)), "g" (a), "g" (c) : \ 404 1.2 scw "a0","a1","d0"); \ 405 1.2 scw } while (0); 406 1.2 scw 407 1.2 scw #define bus_space_write_region_2(t, h, o, a, c) do { \ 408 1.2 scw (void) t; \ 409 1.10 perry __asm volatile (" \ 410 1.7 scw movl %0,%%a0 ; \ 411 1.7 scw movl %1,%%a1 ; \ 412 1.7 scw movl %2,%%d0 ; \ 413 1.7 scw 1: movw %%a1@+,%%a0@+ ; \ 414 1.7 scw subql #1,%%d0 ; \ 415 1.2 scw jne 1b" : \ 416 1.2 scw : \ 417 1.2 scw "r" ((h) + (o)), "g" (a), "g" (c) : \ 418 1.2 scw "a0","a1","d0"); \ 419 1.2 scw } while (0); 420 1.2 scw 421 1.2 scw #define bus_space_write_region_4(t, h, o, a, c) do { \ 422 1.2 scw (void) t; \ 423 1.10 perry __asm volatile (" \ 424 1.7 scw movl %0,%%a0 ; \ 425 1.7 scw movl %1,%%a1 ; \ 426 1.7 scw movl %2,%%d0 ; \ 427 1.7 scw 1: movl %%a1@+,%%a0@+ ; \ 428 1.7 scw subql #1,%%d0 ; \ 429 1.2 scw jne 1b" : \ 430 1.2 scw : \ 431 1.2 scw "r" ((h) + (o)), "g" (a), "g" (c) : \ 432 1.2 scw "a0","a1","d0"); \ 433 1.2 scw } while (0); 434 1.2 scw 435 1.2 scw /* 436 1.6 scw * void bus_space_set_multi_N(bus_space_tag_t tag, 437 1.12 tsutsui * bus_space_handle_t bsh, bus_size_t offset, uintN_t val, 438 1.6 scw * size_t count); 439 1.2 scw * 440 1.2 scw * Write the 1, 2, 4, or 8 byte value `val' to bus space described 441 1.2 scw * by tag/handle/offset `count' times. 442 1.2 scw */ 443 1.2 scw 444 1.2 scw #define bus_space_set_multi_1(t, h, o, val, c) do { \ 445 1.2 scw (void) t; \ 446 1.10 perry __asm volatile (" \ 447 1.7 scw movl %0,%%a0 ; \ 448 1.7 scw movl %1,%%d1 ; \ 449 1.7 scw movl %2,%%d0 ; \ 450 1.7 scw 1: movb %%d1,%%a0@ ; \ 451 1.7 scw subql #1,%%d0 ; \ 452 1.2 scw jne 1b" : \ 453 1.2 scw : \ 454 1.2 scw "r" ((h) + (o)), "g" (val), "g" (c) : \ 455 1.2 scw "a0","d0","d1"); \ 456 1.2 scw } while (0); 457 1.2 scw 458 1.2 scw #define bus_space_set_multi_2(t, h, o, val, c) do { \ 459 1.2 scw (void) t; \ 460 1.10 perry __asm volatile (" \ 461 1.7 scw movl %0,%%a0 ; \ 462 1.7 scw movl %1,%%d1 ; \ 463 1.7 scw movl %2,%%d0 ; \ 464 1.7 scw 1: movw %%d1,%%a0@ ; \ 465 1.7 scw subql #1,%%d0 ; \ 466 1.2 scw jne 1b" : \ 467 1.2 scw : \ 468 1.2 scw "r" ((h) + (o)), "g" (val), "g" (c) : \ 469 1.2 scw "a0","d0","d1"); \ 470 1.2 scw } while (0); 471 1.2 scw 472 1.2 scw #define bus_space_set_multi_4(t, h, o, val, c) do { \ 473 1.2 scw (void) t; \ 474 1.10 perry __asm volatile (" \ 475 1.7 scw movl %0,%%a0 ; \ 476 1.7 scw movl %1,%%d1 ; \ 477 1.7 scw movl %2,%%d0 ; \ 478 1.7 scw 1: movl %%d1,%%a0@ ; \ 479 1.7 scw subql #1,%%d0 ; \ 480 1.2 scw jne 1b" : \ 481 1.2 scw : \ 482 1.2 scw "r" ((h) + (o)), "g" (val), "g" (c) : \ 483 1.2 scw "a0","d0","d1"); \ 484 1.2 scw } while (0); 485 1.2 scw 486 1.2 scw /* 487 1.6 scw * void bus_space_set_region_N(bus_space_tag_t tag, 488 1.12 tsutsui * bus_space_handle_t bsh, bus_size_t offset, uintN_t val, 489 1.6 scw * size_t count); 490 1.2 scw * 491 1.2 scw * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 492 1.2 scw * by tag/handle starting at `offset'. 493 1.2 scw */ 494 1.2 scw 495 1.2 scw #define bus_space_set_region_1(t, h, o, val, c) do { \ 496 1.2 scw (void) t; \ 497 1.10 perry __asm volatile (" \ 498 1.7 scw movl %0,%%a0 ; \ 499 1.7 scw movl %1,%%d1 ; \ 500 1.7 scw movl %2,%%d0 ; \ 501 1.7 scw 1: movb %%d1,%%a0@+ ; \ 502 1.7 scw subql #1,%%d0 ; \ 503 1.2 scw jne 1b" : \ 504 1.2 scw : \ 505 1.2 scw "r" ((h) + (o)), "g" (val), "g" (c) : \ 506 1.2 scw "a0","d0","d1"); \ 507 1.2 scw } while (0); 508 1.2 scw 509 1.2 scw #define bus_space_set_region_2(t, h, o, val, c) do { \ 510 1.2 scw (void) t; \ 511 1.10 perry __asm volatile (" \ 512 1.7 scw movl %0,%%a0 ; \ 513 1.7 scw movl %1,%%d1 ; \ 514 1.7 scw movl %2,%%d0 ; \ 515 1.7 scw 1: movw %%d1,%%a0@+ ; \ 516 1.7 scw subql #1,%%d0 ; \ 517 1.2 scw jne 1b" : \ 518 1.2 scw : \ 519 1.2 scw "r" ((h) + (o)), "g" (val), "g" (c) : \ 520 1.2 scw "a0","d0","d1"); \ 521 1.2 scw } while (0); 522 1.2 scw 523 1.2 scw #define bus_space_set_region_4(t, h, o, val, c) do { \ 524 1.2 scw (void) t; \ 525 1.10 perry __asm volatile (" \ 526 1.7 scw movl %0,%%a0 ; \ 527 1.7 scw movl %1,%%d1 ; \ 528 1.7 scw movl %2,%%d0 ; \ 529 1.7 scw 1: movl d1,%%a0@+ ; \ 530 1.7 scw subql #1,%%d0 ; \ 531 1.2 scw jne 1b" : \ 532 1.2 scw : \ 533 1.2 scw "r" ((h) + (o)), "g" (val), "g" (c) : \ 534 1.2 scw "a0","d0","d1"); \ 535 1.2 scw } while (0); 536 1.2 scw 537 1.2 scw /* 538 1.6 scw * void bus_space_copy_N(bus_space_tag_t tag, 539 1.2 scw * bus_space_handle_t bsh1, bus_size_t off1, 540 1.2 scw * bus_space_handle_t bsh2, bus_size_t off2, 541 1.6 scw * size_t count); 542 1.2 scw * 543 1.2 scw * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 544 1.2 scw * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 545 1.2 scw */ 546 1.2 scw 547 1.2 scw #define __MVME68K_copy_region_N(BYTES) \ 548 1.11 perry static __inline void __CONCAT(bus_space_copy_region_,BYTES) \ 549 1.12 tsutsui (bus_space_tag_t, \ 550 1.2 scw bus_space_handle_t bsh1, bus_size_t off1, \ 551 1.2 scw bus_space_handle_t bsh2, bus_size_t off2, \ 552 1.12 tsutsui bus_size_t count); \ 553 1.2 scw \ 554 1.11 perry static __inline void \ 555 1.14 matt __CONCAT(bus_space_copy_region_,BYTES)( \ 556 1.14 matt bus_space_tag_t t, \ 557 1.14 matt bus_space_handle_t h1, \ 558 1.14 matt bus_size_t o1, \ 559 1.14 matt bus_space_handle_t h2, \ 560 1.14 matt bus_size_t o2, \ 561 1.14 matt bus_size_t c) \ 562 1.2 scw { \ 563 1.2 scw bus_size_t o; \ 564 1.2 scw \ 565 1.2 scw if ((h1 + o1) >= (h2 + o2)) { \ 566 1.2 scw /* src after dest: copy forward */ \ 567 1.2 scw for (o = 0; c != 0; c--, o += BYTES) \ 568 1.2 scw __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 569 1.2 scw __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 570 1.2 scw } else { \ 571 1.2 scw /* dest after src: copy backwards */ \ 572 1.2 scw for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \ 573 1.2 scw __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 574 1.2 scw __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 575 1.2 scw } \ 576 1.2 scw } 577 1.2 scw __MVME68K_copy_region_N(1) 578 1.2 scw __MVME68K_copy_region_N(2) 579 1.2 scw __MVME68K_copy_region_N(4) 580 1.2 scw 581 1.2 scw #undef __MVME68K_copy_region_N 582 1.2 scw 583 1.2 scw /* 584 1.2 scw * Bus read/write barrier methods. 585 1.2 scw * 586 1.6 scw * void bus_space_barrier(bus_space_tag_t tag, 587 1.2 scw * bus_space_handle_t bsh, bus_size_t offset, 588 1.6 scw * bus_size_t len, int flags); 589 1.2 scw * 590 1.2 scw * Note: the 680x0 does not currently require barriers, but we must 591 1.2 scw * provide the flags to MI code. 592 1.2 scw */ 593 1.2 scw #define bus_space_barrier(t, h, o, l, f) \ 594 1.2 scw ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) 595 1.2 scw #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 596 1.2 scw #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 597 1.3 drochner 598 1.3 drochner #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) 599 1.6 scw 600 1.6 scw 601 1.6 scw #ifdef _MVME68K_BUS_SPACE_PRIVATE 602 1.6 scw extern int _bus_space_map(void *, bus_addr_t, bus_size_t, 603 1.6 scw int, bus_space_handle_t *); 604 1.6 scw extern void _bus_space_unmap(void *, bus_space_handle_t, bus_size_t); 605 1.6 scw extern int _bus_space_peek_1(void *, bus_space_handle_t, 606 1.12 tsutsui bus_size_t, uint8_t *); 607 1.6 scw extern int _bus_space_peek_2(void *, bus_space_handle_t, 608 1.12 tsutsui bus_size_t, uint16_t *); 609 1.6 scw extern int _bus_space_peek_4(void *, bus_space_handle_t, 610 1.12 tsutsui bus_size_t, uint32_t *); 611 1.12 tsutsui extern int _bus_space_poke_1(void *, bus_space_handle_t, bus_size_t, uint8_t); 612 1.12 tsutsui extern int _bus_space_poke_2(void *, bus_space_handle_t, bus_size_t, uint16_t); 613 1.12 tsutsui extern int _bus_space_poke_4(void *, bus_space_handle_t, bus_size_t, uint32_t); 614 1.6 scw #endif /* _MVME68K_BUS_SPACE_PRIVATE */ 615 1.2 scw 616 1.2 scw #endif /* _MVME68K_BUS_SPACE_H_ */ 617