1*267f2993Schristos /* $NetBSD: bus_space.h,v 1.5 2021/01/23 19:38:07 christos Exp $ */ 27168dfe8Smatt 37168dfe8Smatt /*- 47168dfe8Smatt * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 57168dfe8Smatt * All rights reserved. 67168dfe8Smatt * 77168dfe8Smatt * This code is derived from software contributed to The NetBSD Foundation 87168dfe8Smatt * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 97168dfe8Smatt * NASA Ames Research Center. 107168dfe8Smatt * 117168dfe8Smatt * Redistribution and use in source and binary forms, with or without 127168dfe8Smatt * modification, are permitted provided that the following conditions 137168dfe8Smatt * are met: 147168dfe8Smatt * 1. Redistributions of source code must retain the above copyright 157168dfe8Smatt * notice, this list of conditions and the following disclaimer. 167168dfe8Smatt * 2. Redistributions in binary form must reproduce the above copyright 177168dfe8Smatt * notice, this list of conditions and the following disclaimer in the 187168dfe8Smatt * documentation and/or other materials provided with the distribution. 197168dfe8Smatt * 207168dfe8Smatt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 217168dfe8Smatt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 227168dfe8Smatt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 237168dfe8Smatt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 247168dfe8Smatt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 257168dfe8Smatt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 267168dfe8Smatt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 277168dfe8Smatt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 287168dfe8Smatt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 297168dfe8Smatt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 307168dfe8Smatt * POSSIBILITY OF SUCH DAMAGE. 317168dfe8Smatt */ 327168dfe8Smatt 337168dfe8Smatt /* 347168dfe8Smatt * Copyright (C) 1997 Scott Reynolds. All rights reserved. 357168dfe8Smatt * 367168dfe8Smatt * Redistribution and use in source and binary forms, with or without 377168dfe8Smatt * modification, are permitted provided that the following conditions 387168dfe8Smatt * are met: 397168dfe8Smatt * 1. Redistributions of source code must retain the above copyright 407168dfe8Smatt * notice, this list of conditions and the following disclaimer. 417168dfe8Smatt * 2. Redistributions in binary form must reproduce the above copyright 427168dfe8Smatt * notice, this list of conditions and the following disclaimer in the 437168dfe8Smatt * documentation and/or other materials provided with the distribution. 447168dfe8Smatt * 3. The name of the author may not be used to endorse or promote products 457168dfe8Smatt * derived from this software without specific prior written permission 467168dfe8Smatt * 477168dfe8Smatt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 487168dfe8Smatt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 497168dfe8Smatt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 507168dfe8Smatt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 517168dfe8Smatt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 527168dfe8Smatt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 537168dfe8Smatt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 547168dfe8Smatt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 557168dfe8Smatt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 567168dfe8Smatt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 577168dfe8Smatt */ 587168dfe8Smatt 597168dfe8Smatt /* 607168dfe8Smatt * Lifted from the Next68k port. 617168dfe8Smatt * Modified for mvme68k by Steve Woodford. 627168dfe8Smatt * Modified for evbcf by Steve Woodford. 637168dfe8Smatt */ 647168dfe8Smatt 657168dfe8Smatt #ifndef _EVBCF_BUS_SPACE_H_ 667168dfe8Smatt #define _EVBCF_BUS_SPACE_H_ 677168dfe8Smatt 687168dfe8Smatt /* 697168dfe8Smatt * Addresses (in bus space). 707168dfe8Smatt */ 717168dfe8Smatt typedef u_long bus_addr_t; 727168dfe8Smatt typedef u_long bus_size_t; 737168dfe8Smatt 748a06b90dSskrll #define PRIxBUSADDR "lx" 758a06b90dSskrll #define PRIxBUSSIZE "lx" 768a06b90dSskrll #define PRIuBUSSIZE "lu" 777168dfe8Smatt /* 787168dfe8Smatt * Access methods for bus resources and address space. 797168dfe8Smatt */ 807168dfe8Smatt struct mvme68k_bus_space_tag; 817168dfe8Smatt typedef struct mvme68k_bus_space_tag *bus_space_tag_t; 827168dfe8Smatt typedef u_long bus_space_handle_t; 837168dfe8Smatt 848a06b90dSskrll #define PRIxBSH "lx" 858a06b90dSskrll 867168dfe8Smatt struct mvme68k_bus_space_tag { 877168dfe8Smatt void *bs_cookie; 887168dfe8Smatt int (*bs_map)(void *, bus_addr_t, bus_size_t, 897168dfe8Smatt int, bus_space_handle_t *); 907168dfe8Smatt void (*bs_unmap)(void *, bus_space_handle_t, bus_size_t); 917168dfe8Smatt int (*bs_peek_1)(void *, bus_space_handle_t, 927168dfe8Smatt bus_size_t, uint8_t *); 937168dfe8Smatt int (*bs_peek_2)(void *, bus_space_handle_t, 947168dfe8Smatt bus_size_t, uint16_t *); 957168dfe8Smatt int (*bs_peek_4)(void *, bus_space_handle_t, 967168dfe8Smatt bus_size_t, uint32_t *); 977168dfe8Smatt #if 0 987168dfe8Smatt int (*bs_peek_8)(void *, bus_space_handle_t, 997168dfe8Smatt bus_size_t, uint64_t *); 1007168dfe8Smatt #endif 1017168dfe8Smatt int (*bs_poke_1)(void *, bus_space_handle_t, 1027168dfe8Smatt bus_size_t, uint8_t); 1037168dfe8Smatt int (*bs_poke_2)(void *, bus_space_handle_t, 1047168dfe8Smatt bus_size_t, uint16_t); 1057168dfe8Smatt int (*bs_poke_4)(void *, bus_space_handle_t, 1067168dfe8Smatt bus_size_t, uint32_t); 1077168dfe8Smatt #if 0 1087168dfe8Smatt int (*bs_poke_8)(void *, bus_space_handle_t, 1097168dfe8Smatt bus_size_t, uint64_t); 1107168dfe8Smatt #endif 1117168dfe8Smatt }; 1127168dfe8Smatt 1137168dfe8Smatt /* 1147168dfe8Smatt * int bus_space_map(bus_space_tag_t t, bus_addr_t addr, 1157168dfe8Smatt * bus_size_t size, int flags, 1167168dfe8Smatt * bus_space_handle_t *bshp); 1177168dfe8Smatt * 1187168dfe8Smatt * Map a region of bus space. 1197168dfe8Smatt */ 1207168dfe8Smatt #define bus_space_map(tag, offset, size, flags, handlep) \ 1217168dfe8Smatt (*((tag)->bs_map))((tag)->bs_cookie, (offset), (size), (flags), (handlep)) 1227168dfe8Smatt 1237168dfe8Smatt /* 1247168dfe8Smatt * Possible values for the 'flags' parameter of bus_space_map() 1257168dfe8Smatt */ 1267168dfe8Smatt #define BUS_SPACE_MAP_CACHEABLE 0x01 1277168dfe8Smatt #define BUS_SPACE_MAP_LINEAR 0x02 1287168dfe8Smatt #define BUS_SPACE_MAP_PREFETCHABLE 0x04 1297168dfe8Smatt 1307168dfe8Smatt /* 1317168dfe8Smatt * void bus_space_unmap(bus_space_tag_t t, 1327168dfe8Smatt * bus_space_handle_t bsh, bus_size_t size); 1337168dfe8Smatt * 1347168dfe8Smatt * Unmap a region of bus space. 1357168dfe8Smatt */ 1367168dfe8Smatt #define bus_space_unmap(tag, handle, size) \ 1377168dfe8Smatt (*((tag)->bs_unmap))((tag)->bs_cookie, (handle), (size)) 1387168dfe8Smatt 1397168dfe8Smatt /* 1407168dfe8Smatt * int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t h 1417168dfe8Smatt * bus_addr_t offset, bus_size_t size, bus_space_handle_t *newh); 1427168dfe8Smatt * 1437168dfe8Smatt * Allocate a sub-region of an existing map 1447168dfe8Smatt */ 1457168dfe8Smatt #define bus_space_subregion(t, h, o, s, hp) \ 1467168dfe8Smatt ((*(hp)=(h)+(o)), 0) 1477168dfe8Smatt 1487168dfe8Smatt /* 1497168dfe8Smatt * Allocation and deallocation operations. 1507168dfe8Smatt */ 1517168dfe8Smatt #define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) \ 1527168dfe8Smatt (-1) 1537168dfe8Smatt 1547168dfe8Smatt #define bus_space_free(t, h, s) 1557168dfe8Smatt 1567168dfe8Smatt /* 1577168dfe8Smatt * int bus_space_peek_N(bus_space_tag_t tag, 1587168dfe8Smatt * bus_space_handle_t bsh, bus_size_t offset, uintN_t *valuep); 1597168dfe8Smatt * 1607168dfe8Smatt * Cautiously read 1, 2, 4 or 8 byte quantity from bus space described 1617168dfe8Smatt * by tag/handle/offset. 1627168dfe8Smatt * If no hardware responds to the read access, the function returns a 1637168dfe8Smatt * non-zero value. Otherwise the value read is placed in `valuep'. 1647168dfe8Smatt */ 1657168dfe8Smatt #define bus_space_peek_1(t, h, o, vp) \ 1667168dfe8Smatt (*((t)->bs_peek_1))((t)->bs_cookie, (h), (o), (vp)) 1677168dfe8Smatt 1687168dfe8Smatt #define bus_space_peek_2(t, h, o, vp) \ 1697168dfe8Smatt (*((t)->bs_peek_2))((t)->bs_cookie, (h), (o), (vp)) 1707168dfe8Smatt 1717168dfe8Smatt #define bus_space_peek_4(t, h, o, vp) \ 1727168dfe8Smatt (*((t)->bs_peek_4))((t)->bs_cookie, (h), (o), (vp)) 1737168dfe8Smatt 1747168dfe8Smatt /* 1757168dfe8Smatt * int bus_space_poke_N(bus_space_tag_t tag, 1767168dfe8Smatt * bus_space_handle_t bsh, bus_size_t offset, uintN_t value); 1777168dfe8Smatt * 1787168dfe8Smatt * Cautiously write 1, 2, 4 or 8 byte quantity to bus space described 1797168dfe8Smatt * by tag/handle/offset. 1807168dfe8Smatt * If no hardware responds to the write access, the function returns a 1817168dfe8Smatt * non-zero value. 1827168dfe8Smatt */ 1837168dfe8Smatt #define bus_space_poke_1(t, h, o, v) \ 1847168dfe8Smatt (*((t)->bs_poke_1))((t)->bs_cookie, (h), (o), (v)) 1857168dfe8Smatt 1867168dfe8Smatt #define bus_space_poke_2(t, h, o, v) \ 1877168dfe8Smatt (*((t)->bs_poke_2))((t)->bs_cookie, (h), (o), (v)) 1887168dfe8Smatt 1897168dfe8Smatt #define bus_space_poke_4(t, h, o, v) \ 1907168dfe8Smatt (*((t)->bs_poke_4))((t)->bs_cookie, (h), (o), (v)) 1917168dfe8Smatt 1927168dfe8Smatt /* 1937168dfe8Smatt * uintN_t bus_space_read_N(bus_space_tag_t tag, 1947168dfe8Smatt * bus_space_handle_t bsh, bus_size_t offset); 1957168dfe8Smatt * 1967168dfe8Smatt * Read a 1, 2, 4, or 8 byte quantity from bus space 1977168dfe8Smatt * described by tag/handle/offset. 1987168dfe8Smatt */ 1997168dfe8Smatt #define bus_space_read_1(t,h,o) \ 2007168dfe8Smatt (*((volatile uint8_t *)(intptr_t)((h) + (o)))) 2017168dfe8Smatt #define bus_space_read_2(t,h,o) \ 2027168dfe8Smatt (*((volatile uint16_t *)(intptr_t)((h) + (o)))) 2037168dfe8Smatt #define bus_space_read_4(t,h,o) \ 2047168dfe8Smatt (*((volatile uint32_t *)(intptr_t)((h) + (o)))) 2057168dfe8Smatt 2067168dfe8Smatt /* 2077168dfe8Smatt * void bus_space_read_multi_N(bus_space_tag_t tag, 2087168dfe8Smatt * bus_space_handle_t bsh, bus_size_t offset, 2097168dfe8Smatt * uintN_t *addr, size_t count); 2107168dfe8Smatt * 2117168dfe8Smatt * Read `count' 1, 2, 4, or 8 byte quantities from bus space 2127168dfe8Smatt * described by tag/handle/offset and copy into buffer provided. 2137168dfe8Smatt */ 2147168dfe8Smatt 2157168dfe8Smatt #define bus_space_read_multi_1(t, h, o, a, c) do { \ 2167168dfe8Smatt (void) t; \ 2177168dfe8Smatt __asm volatile (" \ 2187168dfe8Smatt movl %0,%%a0 ; \ 2197168dfe8Smatt movl %1,%%a1 ; \ 2207168dfe8Smatt movl %2,%%d0 ; \ 2217168dfe8Smatt 1: movb %%a0@,%%a1@+ ; \ 2227168dfe8Smatt subql #1,%%d0 ; \ 2237168dfe8Smatt jne 1b" : \ 2247168dfe8Smatt : \ 2257168dfe8Smatt "r" ((h) + (o)), "g" (a), "g" (c) : \ 2267168dfe8Smatt "a0","a1","d0"); \ 2277168dfe8Smatt } while (0); 2287168dfe8Smatt 2297168dfe8Smatt #define bus_space_read_multi_2(t, h, o, a, c) do { \ 2307168dfe8Smatt (void) t; \ 2317168dfe8Smatt __asm volatile (" \ 2327168dfe8Smatt movl %0,%%a0 ; \ 2337168dfe8Smatt movl %1,%%a1 ; \ 2347168dfe8Smatt movl %2,%%d0 ; \ 2357168dfe8Smatt 1: movw %%a0@,%%a1@+ ; \ 2367168dfe8Smatt subql #1,%%d0 ; \ 2377168dfe8Smatt jne 1b" : \ 2387168dfe8Smatt : \ 2397168dfe8Smatt "r" ((h) + (o)), "g" (a), "g" (c) : \ 2407168dfe8Smatt "a0","a1","d0"); \ 2417168dfe8Smatt } while (0); 2427168dfe8Smatt 2437168dfe8Smatt #define bus_space_read_multi_4(t, h, o, a, c) do { \ 2447168dfe8Smatt (void) t; \ 2457168dfe8Smatt __asm volatile (" \ 2467168dfe8Smatt movl %0,%%a0 ; \ 2477168dfe8Smatt movl %1,%%a1 ; \ 2487168dfe8Smatt movl %2,%%d0 ; \ 2497168dfe8Smatt 1: movl %%a0@,%%a1@+ ; \ 2507168dfe8Smatt subql #1,%%d0 ; \ 2517168dfe8Smatt jne 1b" : \ 2527168dfe8Smatt : \ 2537168dfe8Smatt "r" ((h) + (o)), "g" (a), "g" (c) : \ 2547168dfe8Smatt "a0","a1","d0"); \ 2557168dfe8Smatt } while (0); 2567168dfe8Smatt 2577168dfe8Smatt /* 2587168dfe8Smatt * void bus_space_read_region_N(bus_space_tag_t tag, 2597168dfe8Smatt * bus_space_handle_t bsh, bus_size_t offset, 2607168dfe8Smatt * uintN_t *addr, size_t count); 2617168dfe8Smatt * 2627168dfe8Smatt * Read `count' 1, 2, 4, or 8 byte quantities from bus space 2637168dfe8Smatt * described by tag/handle and starting at `offset' and copy into 2647168dfe8Smatt * buffer provided. 2657168dfe8Smatt */ 2667168dfe8Smatt 2677168dfe8Smatt #define bus_space_read_region_1(t, h, o, a, c) do { \ 2687168dfe8Smatt (void) t; \ 2697168dfe8Smatt __asm volatile (" \ 2707168dfe8Smatt movl %0,%%a0 ; \ 2717168dfe8Smatt movl %1,%%a1 ; \ 2727168dfe8Smatt movl %2,%%d0 ; \ 2737168dfe8Smatt 1: movb %%a0@+,%%a1@+ ; \ 2747168dfe8Smatt subql #1,%%d0 ; \ 2757168dfe8Smatt jne 1b" : \ 2767168dfe8Smatt : \ 2777168dfe8Smatt "r" ((h) + (o)), "g" (a), "g" (c) : \ 2787168dfe8Smatt "a0","a1","d0"); \ 2797168dfe8Smatt } while (0); 2807168dfe8Smatt 2817168dfe8Smatt #define bus_space_read_region_2(t, h, o, a, c) do { \ 2827168dfe8Smatt (void) t; \ 2837168dfe8Smatt __asm volatile (" \ 2847168dfe8Smatt movl %0,%%a0 ; \ 2857168dfe8Smatt movl %1,%%a1 ; \ 2867168dfe8Smatt movl %2,%%d0 ; \ 2877168dfe8Smatt 1: movw %%a0@+,%%a1@+ ; \ 2887168dfe8Smatt subql #1,%%d0 ; \ 2897168dfe8Smatt jne 1b" : \ 2907168dfe8Smatt : \ 2917168dfe8Smatt "r" ((h) + (o)), "g" (a), "g" (c) : \ 2927168dfe8Smatt "a0","a1","d0"); \ 2937168dfe8Smatt } while (0); 2947168dfe8Smatt 2957168dfe8Smatt #define bus_space_read_region_4(t, h, o, a, c) do { \ 2967168dfe8Smatt (void) t; \ 2977168dfe8Smatt __asm volatile (" \ 2987168dfe8Smatt movl %0,%%a0 ; \ 2997168dfe8Smatt movl %1,%%a1 ; \ 3007168dfe8Smatt movl %2,%%d0 ; \ 3017168dfe8Smatt 1: movl %%a0@+,%%a1@+ ; \ 3027168dfe8Smatt subql #1,%%d0 ; \ 3037168dfe8Smatt jne 1b" : \ 3047168dfe8Smatt : \ 3057168dfe8Smatt "r" ((h) + (o)), "g" (a), "g" (c) : \ 3067168dfe8Smatt "a0","a1","d0"); \ 3077168dfe8Smatt } while (0); 3087168dfe8Smatt 3097168dfe8Smatt /* 3107168dfe8Smatt * void bus_space_write_N(bus_space_tag_t tag, 3117168dfe8Smatt * bus_space_handle_t bsh, bus_size_t offset, 3127168dfe8Smatt * uintN_t value); 3137168dfe8Smatt * 3147168dfe8Smatt * Write the 1, 2, 4, or 8 byte value `value' to bus space 3157168dfe8Smatt * described by tag/handle/offset. 3167168dfe8Smatt */ 3177168dfe8Smatt #define bus_space_write_1(t,h,o,v) \ 3187168dfe8Smatt do { \ 3197168dfe8Smatt *((volatile uint8_t *)(intptr_t)((h) + (o))) = (v); \ 3207168dfe8Smatt } while (/*CONSTCOND*/0) 3217168dfe8Smatt #define bus_space_write_2(t,h,o,v) \ 3227168dfe8Smatt do { \ 3237168dfe8Smatt *((volatile uint16_t *)(intptr_t)((h) + (o))) = (v); \ 3247168dfe8Smatt } while (/*CONSTCOND*/0) 3257168dfe8Smatt #define bus_space_write_4(t,h,o,v) \ 3267168dfe8Smatt do { \ 3277168dfe8Smatt *((volatile uint32_t *)(intptr_t)((h) + (o))) = (v); \ 3287168dfe8Smatt } while (/*CONSTCOND*/0) 3297168dfe8Smatt 3307168dfe8Smatt /* 3317168dfe8Smatt * void bus_space_write_multi_N(bus_space_tag_t tag, 3327168dfe8Smatt * bus_space_handle_t bsh, bus_size_t offset, 3337168dfe8Smatt * const uintN_t *addr, size_t count); 3347168dfe8Smatt * 3357168dfe8Smatt * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 3367168dfe8Smatt * provided to bus space described by tag/handle/offset. 3377168dfe8Smatt */ 3387168dfe8Smatt 3397168dfe8Smatt #define bus_space_write_multi_1(t, h, o, a, c) do { \ 3407168dfe8Smatt (void) t; \ 3417168dfe8Smatt __asm volatile (" \ 3427168dfe8Smatt movl %0,%%a0 ; \ 3437168dfe8Smatt movl %1,%%a1 ; \ 3447168dfe8Smatt movl %2,%%d0 ; \ 3457168dfe8Smatt 1: movb %%a1@+,%%a0@ ; \ 3467168dfe8Smatt subql #1,%%d0 ; \ 3477168dfe8Smatt jne 1b" : \ 3487168dfe8Smatt : \ 3497168dfe8Smatt "r" ((h) + (o)), "g" (a), "g" (c) : \ 3507168dfe8Smatt "a0","a1","d0"); \ 3517168dfe8Smatt } while (0); 3527168dfe8Smatt 3537168dfe8Smatt #define bus_space_write_multi_2(t, h, o, a, c) do { \ 3547168dfe8Smatt (void) t; \ 3557168dfe8Smatt __asm volatile (" \ 3567168dfe8Smatt movl %0,%%a0 ; \ 3577168dfe8Smatt movl %1,%%a1 ; \ 3587168dfe8Smatt movl %2,%%d0 ; \ 3597168dfe8Smatt 1: movw %%a1@+,%%a0@ ; \ 3607168dfe8Smatt subql #1,%%d0 ; \ 3617168dfe8Smatt jne 1b" : \ 3627168dfe8Smatt : \ 3637168dfe8Smatt "r" ((h) + (o)), "g" (a), "g" (c) : \ 3647168dfe8Smatt "a0","a1","d0"); \ 3657168dfe8Smatt } while (0); 3667168dfe8Smatt 3677168dfe8Smatt #define bus_space_write_multi_4(t, h, o, a, c) do { \ 3687168dfe8Smatt (void) t; \ 3697168dfe8Smatt __asm volatile (" \ 3707168dfe8Smatt movl %0,%%a0 ; \ 3717168dfe8Smatt movl %1,%%a1 ; \ 3727168dfe8Smatt movl %2,%%d0 ; \ 3737168dfe8Smatt 1: movl a1@+,%%a0@ ; \ 3747168dfe8Smatt subql #1,%%d0 ; \ 3757168dfe8Smatt jne 1b" : \ 3767168dfe8Smatt : \ 3777168dfe8Smatt "r" ((h) + (o)), "g" (a), "g" (c) : \ 3787168dfe8Smatt "a0","a1","d0"); \ 3797168dfe8Smatt } while (0); 3807168dfe8Smatt 3817168dfe8Smatt /* 3827168dfe8Smatt * void bus_space_write_region_N(bus_space_tag_t tag, 3837168dfe8Smatt * bus_space_handle_t bsh, bus_size_t offset, 3847168dfe8Smatt * const uintN_t *addr, size_t count); 3857168dfe8Smatt * 3867168dfe8Smatt * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 3877168dfe8Smatt * to bus space described by tag/handle starting at `offset'. 3887168dfe8Smatt */ 3897168dfe8Smatt 3907168dfe8Smatt #define bus_space_write_region_1(t, h, o, a, c) do { \ 3917168dfe8Smatt (void) t; \ 3927168dfe8Smatt __asm volatile (" \ 3937168dfe8Smatt movl %0,%%a0 ; \ 3947168dfe8Smatt movl %1,%%a1 ; \ 3957168dfe8Smatt movl %2,%%d0 ; \ 3967168dfe8Smatt 1: movb %%a1@+,%%a0@+ ; \ 3977168dfe8Smatt subql #1,%%d0 ; \ 3987168dfe8Smatt jne 1b" : \ 3997168dfe8Smatt : \ 4007168dfe8Smatt "r" ((h) + (o)), "g" (a), "g" (c) : \ 4017168dfe8Smatt "a0","a1","d0"); \ 4027168dfe8Smatt } while (0); 4037168dfe8Smatt 4047168dfe8Smatt #define bus_space_write_region_2(t, h, o, a, c) do { \ 4057168dfe8Smatt (void) t; \ 4067168dfe8Smatt __asm volatile (" \ 4077168dfe8Smatt movl %0,%%a0 ; \ 4087168dfe8Smatt movl %1,%%a1 ; \ 4097168dfe8Smatt movl %2,%%d0 ; \ 4107168dfe8Smatt 1: movw %%a1@+,%%a0@+ ; \ 4117168dfe8Smatt subql #1,%%d0 ; \ 4127168dfe8Smatt jne 1b" : \ 4137168dfe8Smatt : \ 4147168dfe8Smatt "r" ((h) + (o)), "g" (a), "g" (c) : \ 4157168dfe8Smatt "a0","a1","d0"); \ 4167168dfe8Smatt } while (0); 4177168dfe8Smatt 4187168dfe8Smatt #define bus_space_write_region_4(t, h, o, a, c) do { \ 4197168dfe8Smatt (void) t; \ 4207168dfe8Smatt __asm volatile (" \ 4217168dfe8Smatt movl %0,%%a0 ; \ 4227168dfe8Smatt movl %1,%%a1 ; \ 4237168dfe8Smatt movl %2,%%d0 ; \ 4247168dfe8Smatt 1: movl %%a1@+,%%a0@+ ; \ 4257168dfe8Smatt subql #1,%%d0 ; \ 4267168dfe8Smatt jne 1b" : \ 4277168dfe8Smatt : \ 4287168dfe8Smatt "r" ((h) + (o)), "g" (a), "g" (c) : \ 4297168dfe8Smatt "a0","a1","d0"); \ 4307168dfe8Smatt } while (0); 4317168dfe8Smatt 4327168dfe8Smatt /* 4337168dfe8Smatt * void bus_space_set_multi_N(bus_space_tag_t tag, 4347168dfe8Smatt * bus_space_handle_t bsh, bus_size_t offset, uintN_t val, 4357168dfe8Smatt * size_t count); 4367168dfe8Smatt * 4377168dfe8Smatt * Write the 1, 2, 4, or 8 byte value `val' to bus space described 4387168dfe8Smatt * by tag/handle/offset `count' times. 4397168dfe8Smatt */ 4407168dfe8Smatt 4417168dfe8Smatt #define bus_space_set_multi_1(t, h, o, val, c) do { \ 4427168dfe8Smatt (void) t; \ 4437168dfe8Smatt __asm volatile (" \ 4447168dfe8Smatt movl %0,%%a0 ; \ 4457168dfe8Smatt movl %1,%%d1 ; \ 4467168dfe8Smatt movl %2,%%d0 ; \ 4477168dfe8Smatt 1: movb %%d1,%%a0@ ; \ 4487168dfe8Smatt subql #1,%%d0 ; \ 4497168dfe8Smatt jne 1b" : \ 4507168dfe8Smatt : \ 4517168dfe8Smatt "r" ((h) + (o)), "g" (val), "g" (c) : \ 4527168dfe8Smatt "a0","d0","d1"); \ 4537168dfe8Smatt } while (0); 4547168dfe8Smatt 4557168dfe8Smatt #define bus_space_set_multi_2(t, h, o, val, c) do { \ 4567168dfe8Smatt (void) t; \ 4577168dfe8Smatt __asm volatile (" \ 4587168dfe8Smatt movl %0,%%a0 ; \ 4597168dfe8Smatt movl %1,%%d1 ; \ 4607168dfe8Smatt movl %2,%%d0 ; \ 4617168dfe8Smatt 1: movw %%d1,%%a0@ ; \ 4627168dfe8Smatt subql #1,%%d0 ; \ 4637168dfe8Smatt jne 1b" : \ 4647168dfe8Smatt : \ 4657168dfe8Smatt "r" ((h) + (o)), "g" (val), "g" (c) : \ 4667168dfe8Smatt "a0","d0","d1"); \ 4677168dfe8Smatt } while (0); 4687168dfe8Smatt 4697168dfe8Smatt #define bus_space_set_multi_4(t, h, o, val, c) do { \ 4707168dfe8Smatt (void) t; \ 4717168dfe8Smatt __asm volatile (" \ 4727168dfe8Smatt movl %0,%%a0 ; \ 4737168dfe8Smatt movl %1,%%d1 ; \ 4747168dfe8Smatt movl %2,%%d0 ; \ 4757168dfe8Smatt 1: movl %%d1,%%a0@ ; \ 4767168dfe8Smatt subql #1,%%d0 ; \ 4777168dfe8Smatt jne 1b" : \ 4787168dfe8Smatt : \ 4797168dfe8Smatt "r" ((h) + (o)), "g" (val), "g" (c) : \ 4807168dfe8Smatt "a0","d0","d1"); \ 4817168dfe8Smatt } while (0); 4827168dfe8Smatt 4837168dfe8Smatt /* 4847168dfe8Smatt * void bus_space_set_region_N(bus_space_tag_t tag, 4857168dfe8Smatt * bus_space_handle_t bsh, bus_size_t offset, uintN_t val, 4867168dfe8Smatt * size_t count); 4877168dfe8Smatt * 4887168dfe8Smatt * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 4897168dfe8Smatt * by tag/handle starting at `offset'. 4907168dfe8Smatt */ 4917168dfe8Smatt 4927168dfe8Smatt #define bus_space_set_region_1(t, h, o, val, c) do { \ 4937168dfe8Smatt (void) t; \ 4947168dfe8Smatt __asm volatile (" \ 4957168dfe8Smatt movl %0,%%a0 ; \ 4967168dfe8Smatt movl %1,%%d1 ; \ 4977168dfe8Smatt movl %2,%%d0 ; \ 4987168dfe8Smatt 1: movb %%d1,%%a0@+ ; \ 4997168dfe8Smatt subql #1,%%d0 ; \ 5007168dfe8Smatt jne 1b" : \ 5017168dfe8Smatt : \ 5027168dfe8Smatt "r" ((h) + (o)), "g" (val), "g" (c) : \ 5037168dfe8Smatt "a0","d0","d1"); \ 5047168dfe8Smatt } while (0); 5057168dfe8Smatt 5067168dfe8Smatt #define bus_space_set_region_2(t, h, o, val, c) do { \ 5077168dfe8Smatt (void) t; \ 5087168dfe8Smatt __asm volatile (" \ 5097168dfe8Smatt movl %0,%%a0 ; \ 5107168dfe8Smatt movl %1,%%d1 ; \ 5117168dfe8Smatt movl %2,%%d0 ; \ 5127168dfe8Smatt 1: movw %%d1,%%a0@+ ; \ 5137168dfe8Smatt subql #1,%%d0 ; \ 5147168dfe8Smatt jne 1b" : \ 5157168dfe8Smatt : \ 5167168dfe8Smatt "r" ((h) + (o)), "g" (val), "g" (c) : \ 5177168dfe8Smatt "a0","d0","d1"); \ 5187168dfe8Smatt } while (0); 5197168dfe8Smatt 5207168dfe8Smatt #define bus_space_set_region_4(t, h, o, val, c) do { \ 5217168dfe8Smatt (void) t; \ 5227168dfe8Smatt __asm volatile (" \ 5237168dfe8Smatt movl %0,%%a0 ; \ 5247168dfe8Smatt movl %1,%%d1 ; \ 5257168dfe8Smatt movl %2,%%d0 ; \ 5267168dfe8Smatt 1: movl d1,%%a0@+ ; \ 5277168dfe8Smatt subql #1,%%d0 ; \ 5287168dfe8Smatt jne 1b" : \ 5297168dfe8Smatt : \ 5307168dfe8Smatt "r" ((h) + (o)), "g" (val), "g" (c) : \ 5317168dfe8Smatt "a0","d0","d1"); \ 5327168dfe8Smatt } while (0); 5337168dfe8Smatt 5347168dfe8Smatt /* 5357168dfe8Smatt * void bus_space_copy_N(bus_space_tag_t tag, 5367168dfe8Smatt * bus_space_handle_t bsh1, bus_size_t off1, 5377168dfe8Smatt * bus_space_handle_t bsh2, bus_size_t off2, 5387168dfe8Smatt * size_t count); 5397168dfe8Smatt * 5407168dfe8Smatt * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 5417168dfe8Smatt * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 5427168dfe8Smatt */ 5437168dfe8Smatt 5447168dfe8Smatt #define __COLDFIRE_copy_region_N(BYTES) \ 5457168dfe8Smatt static __inline void __CONCAT(bus_space_copy_region_,BYTES) \ 5467168dfe8Smatt (bus_space_tag_t, \ 5477168dfe8Smatt bus_space_handle_t bsh1, bus_size_t off1, \ 5487168dfe8Smatt bus_space_handle_t bsh2, bus_size_t off2, \ 5497168dfe8Smatt bus_size_t count); \ 5507168dfe8Smatt \ 5517168dfe8Smatt static __inline void \ 5527168dfe8Smatt __CONCAT(bus_space_copy_region_,BYTES)( \ 5537168dfe8Smatt bus_space_tag_t t, \ 5547168dfe8Smatt bus_space_handle_t h1, \ 5557168dfe8Smatt bus_size_t o1, \ 5567168dfe8Smatt bus_space_handle_t h2, \ 5577168dfe8Smatt bus_size_t o2, \ 5587168dfe8Smatt bus_size_t c) \ 5597168dfe8Smatt { \ 5607168dfe8Smatt bus_size_t o; \ 5617168dfe8Smatt \ 5627168dfe8Smatt if ((h1 + o1) >= (h2 + o2)) { \ 5637168dfe8Smatt /* src after dest: copy forward */ \ 5647168dfe8Smatt for (o = 0; c != 0; c--, o += BYTES) \ 5657168dfe8Smatt __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 5667168dfe8Smatt __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 5677168dfe8Smatt } else { \ 5687168dfe8Smatt /* dest after src: copy backwards */ \ 5697168dfe8Smatt for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \ 5707168dfe8Smatt __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 5717168dfe8Smatt __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 5727168dfe8Smatt } \ 5737168dfe8Smatt } 5747168dfe8Smatt __COLDFIRE_copy_region_N(1) 5757168dfe8Smatt __COLDFIRE_copy_region_N(2) 5767168dfe8Smatt __COLDFIRE_copy_region_N(4) 5777168dfe8Smatt 5787168dfe8Smatt #undef __COLDFIRE_copy_region_N 5797168dfe8Smatt 5807168dfe8Smatt /* 5817168dfe8Smatt * Bus read/write barrier methods. 5827168dfe8Smatt * 5837168dfe8Smatt * void bus_space_barrier(bus_space_tag_t tag, 5847168dfe8Smatt * bus_space_handle_t bsh, bus_size_t offset, 5857168dfe8Smatt * bus_size_t len, int flags); 5867168dfe8Smatt * 5877168dfe8Smatt * Note: Coldfire does not currently require barriers, but we must 5887168dfe8Smatt * provide the flags to MI code. 5897168dfe8Smatt */ 5907168dfe8Smatt #define bus_space_barrier(t, h, o, l, f) \ 5917168dfe8Smatt ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) 5927168dfe8Smatt #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 5937168dfe8Smatt #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 5947168dfe8Smatt 5957168dfe8Smatt #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) 5967168dfe8Smatt 5977168dfe8Smatt 5987168dfe8Smatt #ifdef _COLDFIRE_BUS_SPACE_PRIVATE 5997168dfe8Smatt extern int _bus_space_map(void *, bus_addr_t, bus_size_t, 6007168dfe8Smatt int, bus_space_handle_t *); 6017168dfe8Smatt extern void _bus_space_unmap(void *, bus_space_handle_t, bus_size_t); 6027168dfe8Smatt extern int _bus_space_peek_1(void *, bus_space_handle_t, 6037168dfe8Smatt bus_size_t, uint8_t *); 6047168dfe8Smatt extern int _bus_space_peek_2(void *, bus_space_handle_t, 6057168dfe8Smatt bus_size_t, uint16_t *); 6067168dfe8Smatt extern int _bus_space_peek_4(void *, bus_space_handle_t, 6077168dfe8Smatt bus_size_t, uint32_t *); 6087168dfe8Smatt extern int _bus_space_poke_1(void *, bus_space_handle_t, bus_size_t, uint8_t); 6097168dfe8Smatt extern int _bus_space_poke_2(void *, bus_space_handle_t, bus_size_t, uint16_t); 6107168dfe8Smatt extern int _bus_space_poke_4(void *, bus_space_handle_t, bus_size_t, uint32_t); 6117168dfe8Smatt #endif /* _COLDFIRE_BUS_SPACE_PRIVATE */ 6127168dfe8Smatt 6137168dfe8Smatt #endif /* _EVBCF_BUS_SPACE_H_ */ 614