1*e603bf95Stsutsui /* $NetBSD: bus.h,v 1.18 2023/01/27 19:49:21 tsutsui Exp $ */ 295d00ea7Snisimura 395d00ea7Snisimura /*- 495d00ea7Snisimura * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 595d00ea7Snisimura * All rights reserved. 695d00ea7Snisimura * 795d00ea7Snisimura * This code is derived from software contributed to The NetBSD Foundation 895d00ea7Snisimura * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 995d00ea7Snisimura * NASA Ames Research Center. 1095d00ea7Snisimura * 1195d00ea7Snisimura * Redistribution and use in source and binary forms, with or without 1295d00ea7Snisimura * modification, are permitted provided that the following conditions 1395d00ea7Snisimura * are met: 1495d00ea7Snisimura * 1. Redistributions of source code must retain the above copyright 1595d00ea7Snisimura * notice, this list of conditions and the following disclaimer. 1695d00ea7Snisimura * 2. Redistributions in binary form must reproduce the above copyright 1795d00ea7Snisimura * notice, this list of conditions and the following disclaimer in the 1895d00ea7Snisimura * documentation and/or other materials provided with the distribution. 1995d00ea7Snisimura * 2095d00ea7Snisimura * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 2195d00ea7Snisimura * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2295d00ea7Snisimura * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2395d00ea7Snisimura * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2495d00ea7Snisimura * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2595d00ea7Snisimura * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2695d00ea7Snisimura * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2795d00ea7Snisimura * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2895d00ea7Snisimura * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2995d00ea7Snisimura * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3095d00ea7Snisimura * POSSIBILITY OF SUCH DAMAGE. 3195d00ea7Snisimura */ 3295d00ea7Snisimura 3395d00ea7Snisimura /* 3495d00ea7Snisimura * Copyright (C) 1997 Scott Reynolds. All rights reserved. 3595d00ea7Snisimura * 3695d00ea7Snisimura * Redistribution and use in source and binary forms, with or without 3795d00ea7Snisimura * modification, are permitted provided that the following conditions 3895d00ea7Snisimura * are met: 3995d00ea7Snisimura * 1. Redistributions of source code must retain the above copyright 4095d00ea7Snisimura * notice, this list of conditions and the following disclaimer. 4195d00ea7Snisimura * 2. Redistributions in binary form must reproduce the above copyright 4295d00ea7Snisimura * notice, this list of conditions and the following disclaimer in the 4395d00ea7Snisimura * documentation and/or other materials provided with the distribution. 4495d00ea7Snisimura * 3. The name of the author may not be used to endorse or promote products 4595d00ea7Snisimura * derived from this software without specific prior written permission 4695d00ea7Snisimura * 4795d00ea7Snisimura * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 4895d00ea7Snisimura * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 4995d00ea7Snisimura * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 5095d00ea7Snisimura * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 5195d00ea7Snisimura * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 5295d00ea7Snisimura * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 5395d00ea7Snisimura * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 5495d00ea7Snisimura * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 5595d00ea7Snisimura * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 5695d00ea7Snisimura * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 5795d00ea7Snisimura */ 5895d00ea7Snisimura 5995d00ea7Snisimura #ifndef _MACHINE_BUS_H_ 6095d00ea7Snisimura #define _MACHINE_BUS_H_ 6195d00ea7Snisimura 6295d00ea7Snisimura /* 6395d00ea7Snisimura * Value for the luna68k bus space tag, not to be used directly by MI code. 6495d00ea7Snisimura */ 6595d00ea7Snisimura #define MACHINE_BUS_SPACE_MEM 0 /* space is mem space */ 6695d00ea7Snisimura 6795d00ea7Snisimura /* 6895d00ea7Snisimura * Bus address and size types 6995d00ea7Snisimura */ 7095d00ea7Snisimura typedef u_long bus_addr_t; 7195d00ea7Snisimura typedef u_long bus_size_t; 7295d00ea7Snisimura 73bf158e33Sskrll #define PRIxBUSADDR "lx" 74bf158e33Sskrll #define PRIxBUSSIZE "lx" 75bf158e33Sskrll #define PRIuBUSSIZE "lu" 76bf158e33Sskrll 7795d00ea7Snisimura /* 7895d00ea7Snisimura * Access methods for bus resources and address space. 7995d00ea7Snisimura */ 8095d00ea7Snisimura typedef int bus_space_tag_t; 8195d00ea7Snisimura typedef u_long bus_space_handle_t; 8295d00ea7Snisimura 83bf158e33Sskrll #define PRIxBSH "lx" 84bf158e33Sskrll 8595d00ea7Snisimura /* 8602cdf4d2Sdsl * int bus_space_map(bus_space_tag_t t, bus_addr_t addr, 8702cdf4d2Sdsl * bus_size_t size, int flags, bus_space_handle_t *bshp); 8895d00ea7Snisimura * 8995d00ea7Snisimura * Map a region of bus space. 9095d00ea7Snisimura */ 9195d00ea7Snisimura 9295d00ea7Snisimura #define BUS_SPACE_MAP_CACHEABLE 0x01 9395d00ea7Snisimura #define BUS_SPACE_MAP_LINEAR 0x02 948eb798e6Sdrochner #define BUS_SPACE_MAP_PREFETCHABLE 0x04 9595d00ea7Snisimura 9602cdf4d2Sdsl int bus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, 9702cdf4d2Sdsl int, bus_space_handle_t *); 9895d00ea7Snisimura 9995d00ea7Snisimura /* 10002cdf4d2Sdsl * void bus_space_unmap(bus_space_tag_t t, 10102cdf4d2Sdsl * bus_space_handle_t bsh, bus_size_t size); 10295d00ea7Snisimura * 10395d00ea7Snisimura * Unmap a region of bus space. 10495d00ea7Snisimura */ 10595d00ea7Snisimura 10602cdf4d2Sdsl void bus_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t); 10795d00ea7Snisimura 10895d00ea7Snisimura /* 10902cdf4d2Sdsl * int bus_space_subregion(bus_space_tag_t t, 11095d00ea7Snisimura * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, 11102cdf4d2Sdsl * bus_space_handle_t *nbshp); 11295d00ea7Snisimura * 11395d00ea7Snisimura * Get a new handle for a subregion of an already-mapped area of bus space. 11495d00ea7Snisimura */ 11595d00ea7Snisimura 11602cdf4d2Sdsl int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh, 11702cdf4d2Sdsl bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp); 11895d00ea7Snisimura 11995d00ea7Snisimura /* 12002cdf4d2Sdsl * int bus_space_alloc(bus_space_tag_t t, bus_addr_t, rstart, 12195d00ea7Snisimura * bus_addr_t rend, bus_size_t size, bus_size_t align, 12295d00ea7Snisimura * bus_size_t boundary, int flags, bus_addr_t *addrp, 12302cdf4d2Sdsl * bus_space_handle_t *bshp); 12495d00ea7Snisimura * 12595d00ea7Snisimura * Allocate a region of bus space. 12695d00ea7Snisimura */ 12795d00ea7Snisimura 12802cdf4d2Sdsl int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, 12995d00ea7Snisimura bus_addr_t rend, bus_size_t size, bus_size_t align, 13095d00ea7Snisimura bus_size_t boundary, int cacheable, bus_addr_t *addrp, 13102cdf4d2Sdsl bus_space_handle_t *bshp); 13295d00ea7Snisimura 13395d00ea7Snisimura /* 13402cdf4d2Sdsl * int bus_space_free(bus_space_tag_t t, 13502cdf4d2Sdsl * bus_space_handle_t bsh, bus_size_t size); 13695d00ea7Snisimura * 13795d00ea7Snisimura * Free a region of bus space. 13895d00ea7Snisimura */ 13995d00ea7Snisimura 14002cdf4d2Sdsl void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, 14102cdf4d2Sdsl bus_size_t size); 14295d00ea7Snisimura 14395d00ea7Snisimura /* 14402cdf4d2Sdsl * u_intN_t bus_space_read_N(bus_space_tag_t tag, 14502cdf4d2Sdsl * bus_space_handle_t bsh, bus_size_t offset); 14695d00ea7Snisimura * 14795d00ea7Snisimura * Read a 1, 2, 4, or 8 byte quantity from bus space 14895d00ea7Snisimura * described by tag/handle/offset. 14995d00ea7Snisimura */ 15095d00ea7Snisimura 15195d00ea7Snisimura #define bus_space_read_1(t, h, o) \ 152bf2202e1Stsutsui ((void) t, (*(volatile u_int8_t *)((h) + (o)*4))) 15395d00ea7Snisimura 15495d00ea7Snisimura #define bus_space_read_2(t, h, o) \ 155bf2202e1Stsutsui ((void) t, (*(volatile u_int16_t *)((h) + (o)*2))) 15695d00ea7Snisimura 15795d00ea7Snisimura #define bus_space_read_4(t, h, o) \ 158bf2202e1Stsutsui ((void) t, (*(volatile u_int32_t *)((h) + (o)))) 15995d00ea7Snisimura 16095d00ea7Snisimura /* 16102cdf4d2Sdsl * void bus_space_read_multi_N(bus_space_tag_t tag, 16295d00ea7Snisimura * bus_space_handle_t bsh, bus_size_t offset, 16302cdf4d2Sdsl * u_intN_t *addr, size_t count); 16495d00ea7Snisimura * 16595d00ea7Snisimura * Read `count' 1, 2, 4, or 8 byte quantities from bus space 16695d00ea7Snisimura * described by tag/handle/offset and copy into buffer provided. 16795d00ea7Snisimura */ 16895d00ea7Snisimura 16995d00ea7Snisimura #define bus_space_read_multi_1(t, h, o, a, c) do { \ 17095d00ea7Snisimura (void) t; \ 1715f1c88d7Sperry __asm volatile (" \ 172d0e2aef0Schs movl %0,%%a0 ; \ 173d0e2aef0Schs movl %1,%%a1 ; \ 174d0e2aef0Schs movl %2,%%d0 ; \ 175d0e2aef0Schs 1: movb %%a0@,%%a1@+ ; \ 176d0e2aef0Schs subql #1,%%d0 ; \ 17795d00ea7Snisimura jne 1b" : \ 17895d00ea7Snisimura : \ 179bf2202e1Stsutsui "r" ((h) + (o)*4), "g" (a), "g" ((size_t)(c)) : \ 180*e603bf95Stsutsui "a0","a1","d0","memory"); \ 18195d00ea7Snisimura } while (0) 18295d00ea7Snisimura 18395d00ea7Snisimura #define bus_space_read_multi_2(t, h, o, a, c) do { \ 18495d00ea7Snisimura (void) t; \ 1855f1c88d7Sperry __asm volatile (" \ 186d0e2aef0Schs movl %0,%%a0 ; \ 187d0e2aef0Schs movl %1,%%a1 ; \ 188d0e2aef0Schs movl %2,%%d0 ; \ 189d0e2aef0Schs 1: movw %%a0@,%%a1@+ ; \ 190d0e2aef0Schs subql #1,%%d0 ; \ 19195d00ea7Snisimura jne 1b" : \ 19295d00ea7Snisimura : \ 193bf2202e1Stsutsui "r" ((h) + (o)*2), "g" (a), "g" ((size_t)(c)) : \ 194*e603bf95Stsutsui "a0","a1","d0","memory"); \ 19595d00ea7Snisimura } while (0) 19695d00ea7Snisimura 19795d00ea7Snisimura #define bus_space_read_multi_4(t, h, o, a, c) do { \ 19895d00ea7Snisimura (void) t; \ 1995f1c88d7Sperry __asm volatile (" \ 200d0e2aef0Schs movl %0,%%a0 ; \ 201d0e2aef0Schs movl %1,%%a1 ; \ 202d0e2aef0Schs movl %2,%%d0 ; \ 203d0e2aef0Schs 1: movl %%a0@,%%a1@+ ; \ 204d0e2aef0Schs subql #1,%%d0 ; \ 20595d00ea7Snisimura jne 1b" : \ 20695d00ea7Snisimura : \ 20795d00ea7Snisimura "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \ 208*e603bf95Stsutsui "a0","a1","d0","memory"); \ 20995d00ea7Snisimura } while (0) 21095d00ea7Snisimura 21195d00ea7Snisimura /* 21202cdf4d2Sdsl * void bus_space_read_region_N(bus_space_tag_t tag, 21395d00ea7Snisimura * bus_space_handle_t bsh, bus_size_t offset, 21402cdf4d2Sdsl * u_intN_t *addr, size_t count); 21595d00ea7Snisimura * 21695d00ea7Snisimura * Read `count' 1, 2, 4, or 8 byte quantities from bus space 21795d00ea7Snisimura * described by tag/handle and starting at `offset' and copy into 21895d00ea7Snisimura * buffer provided. 21995d00ea7Snisimura */ 22095d00ea7Snisimura 22195d00ea7Snisimura #define bus_space_read_region_1(t, h, o, a, c) do { \ 22295d00ea7Snisimura (void) t; \ 2235f1c88d7Sperry __asm volatile (" \ 224d0e2aef0Schs movl %0,%%a0 ; \ 225d0e2aef0Schs movl %1,%%a1 ; \ 226d0e2aef0Schs movl %2,%%d0 ; \ 227bf2202e1Stsutsui 1: movb %%a0@,%%a1@+ ; \ 228bf2202e1Stsutsui addql #4,%%a0 ; \ 229d0e2aef0Schs subql #1,%%d0 ; \ 23095d00ea7Snisimura jne 1b" : \ 23195d00ea7Snisimura : \ 232bf2202e1Stsutsui "r" ((h) + (o)*4), "g" (a), "g" ((size_t)(c)) : \ 233*e603bf95Stsutsui "a0","a1","d0","memory"); \ 23495d00ea7Snisimura } while (0) 23595d00ea7Snisimura 23695d00ea7Snisimura #define bus_space_read_region_2(t, h, o, a, c) do { \ 23795d00ea7Snisimura (void) t; \ 2385f1c88d7Sperry __asm volatile (" \ 239d0e2aef0Schs movl %0,%%a0 ; \ 240d0e2aef0Schs movl %1,%%a1 ; \ 241d0e2aef0Schs movl %2,%%d0 ; \ 242bf2202e1Stsutsui 1: movw %%a0@,%%a1@+ ; \ 243bf2202e1Stsutsui addql #4,%%a0 ; \ 244d0e2aef0Schs subql #1,%%d0 ; \ 24595d00ea7Snisimura jne 1b" : \ 24695d00ea7Snisimura : \ 247bf2202e1Stsutsui "r" ((h) + (o)*2), "g" (a), "g" ((size_t)(c)) : \ 248*e603bf95Stsutsui "a0","a1","d0","memory"); \ 24995d00ea7Snisimura } while (0) 25095d00ea7Snisimura 25195d00ea7Snisimura #define bus_space_read_region_4(t, h, o, a, c) do { \ 25295d00ea7Snisimura (void) t; \ 2535f1c88d7Sperry __asm volatile (" \ 254d0e2aef0Schs movl %0,%%a0 ; \ 255d0e2aef0Schs movl %1,%%a1 ; \ 256d0e2aef0Schs movl %2,%%d0 ; \ 257d0e2aef0Schs 1: movl %%a0@+,%%a1@+ ; \ 258d0e2aef0Schs subql #1,%%d0 ; \ 25995d00ea7Snisimura jne 1b" : \ 26095d00ea7Snisimura : \ 26195d00ea7Snisimura "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \ 262*e603bf95Stsutsui "a0","a1","d0","memory"); \ 26395d00ea7Snisimura } while (0) 26495d00ea7Snisimura 26595d00ea7Snisimura /* 26602cdf4d2Sdsl * void bus_space_write_N(bus_space_tag_t tag, 26795d00ea7Snisimura * bus_space_handle_t bsh, bus_size_t offset, 26802cdf4d2Sdsl * u_intN_t value); 26995d00ea7Snisimura * 27095d00ea7Snisimura * Write the 1, 2, 4, or 8 byte value `value' to bus space 27195d00ea7Snisimura * described by tag/handle/offset. 27295d00ea7Snisimura */ 27395d00ea7Snisimura 27495d00ea7Snisimura #define bus_space_write_1(t, h, o, v) \ 275bf2202e1Stsutsui ((void) t, ((void)(*(volatile u_int8_t *)((h) + (o)*4) = (v)))) 27695d00ea7Snisimura 27795d00ea7Snisimura #define bus_space_write_2(t, h, o, v) \ 278bf2202e1Stsutsui ((void) t, ((void)(*(volatile u_int16_t *)((h) + (o)*2) = (v)))) 27995d00ea7Snisimura 28095d00ea7Snisimura #define bus_space_write_4(t, h, o, v) \ 281bf2202e1Stsutsui ((void) t, ((void)(*(volatile u_int32_t *)((h) + (o)) = (v)))) 28295d00ea7Snisimura 28395d00ea7Snisimura /* 28402cdf4d2Sdsl * void bus_space_write_multi_N(bus_space_tag_t tag, 28595d00ea7Snisimura * bus_space_handle_t bsh, bus_size_t offset, 28602cdf4d2Sdsl * const u_intN_t *addr, size_t count); 28795d00ea7Snisimura * 28895d00ea7Snisimura * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 28995d00ea7Snisimura * provided to bus space described by tag/handle/offset. 29095d00ea7Snisimura */ 29195d00ea7Snisimura 29295d00ea7Snisimura #define bus_space_write_multi_1(t, h, o, a, c) do { \ 29395d00ea7Snisimura (void) t; \ 2945f1c88d7Sperry __asm volatile (" \ 295d0e2aef0Schs movl %0,%%a0 ; \ 296d0e2aef0Schs movl %1,%%a1 ; \ 297d0e2aef0Schs movl %2,%%d0 ; \ 298ae2b6b31Stsutsui 1: movb %%a1@+,%%a0@ ; \ 299d0e2aef0Schs subql #1,%%d0 ; \ 30095d00ea7Snisimura jne 1b" : \ 30195d00ea7Snisimura : \ 302bf2202e1Stsutsui "r" ((h) + (o)*4), "g" (a), "g" ((size_t)(c)) : \ 30395d00ea7Snisimura "a0","a1","d0"); \ 30495d00ea7Snisimura } while (0) 30595d00ea7Snisimura 30695d00ea7Snisimura #define bus_space_write_multi_2(t, h, o, a, c) do { \ 30795d00ea7Snisimura (void) t; \ 3085f1c88d7Sperry __asm volatile (" \ 309d0e2aef0Schs movl %0,%%a0 ; \ 310d0e2aef0Schs movl %1,%%a1 ; \ 311d0e2aef0Schs movl %2,%%d0 ; \ 312ae2b6b31Stsutsui 1: movw %%a1@+,%%a0@ ; \ 313d0e2aef0Schs subql #1,%%d0 ; \ 31495d00ea7Snisimura jne 1b" : \ 31595d00ea7Snisimura : \ 316bf2202e1Stsutsui "r" ((h) + (o)*2), "g" (a), "g" ((size_t)(c)) : \ 31795d00ea7Snisimura "a0","a1","d0"); \ 31895d00ea7Snisimura } while (0) 31995d00ea7Snisimura 32095d00ea7Snisimura #define bus_space_write_multi_4(t, h, o, a, c) do { \ 32195d00ea7Snisimura (void) t; \ 3225f1c88d7Sperry __asm volatile (" \ 323d0e2aef0Schs movl %0,%%a0 ; \ 324d0e2aef0Schs movl %1,%%a1 ; \ 325d0e2aef0Schs movl %2,%%d0 ; \ 326ae2b6b31Stsutsui 1: movl %%a1@+,%%a0@ ; \ 327d0e2aef0Schs subql #1,%%d0 ; \ 32895d00ea7Snisimura jne 1b" : \ 32995d00ea7Snisimura : \ 33095d00ea7Snisimura "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \ 33195d00ea7Snisimura "a0","a1","d0"); \ 33295d00ea7Snisimura } while (0) 33395d00ea7Snisimura 33495d00ea7Snisimura /* 33502cdf4d2Sdsl * void bus_space_write_region_N(bus_space_tag_t tag, 33695d00ea7Snisimura * bus_space_handle_t bsh, bus_size_t offset, 33702cdf4d2Sdsl * const u_intN_t *addr, size_t count); 33895d00ea7Snisimura * 33995d00ea7Snisimura * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 34095d00ea7Snisimura * to bus space described by tag/handle starting at `offset'. 34195d00ea7Snisimura */ 34295d00ea7Snisimura 34395d00ea7Snisimura #define bus_space_write_region_1(t, h, o, a, c) do { \ 34495d00ea7Snisimura (void) t; \ 3455f1c88d7Sperry __asm volatile (" \ 346d0e2aef0Schs movl %0,%%a0 ; \ 347d0e2aef0Schs movl %1,%%a1 ; \ 348d0e2aef0Schs movl %2,%%d0 ; \ 349bf2202e1Stsutsui 1: movb %%a1@+,%%a0@ ; \ 350bf2202e1Stsutsui addql #4,%%a0 ; \ 351d0e2aef0Schs subql #1,%%d0 ; \ 35295d00ea7Snisimura jne 1b" : \ 35395d00ea7Snisimura : \ 354bf2202e1Stsutsui "r" ((h) + (o)*4), "g" (a), "g" ((size_t)(c)) : \ 35595d00ea7Snisimura "a0","a1","d0"); \ 35695d00ea7Snisimura } while (0) 35795d00ea7Snisimura 35895d00ea7Snisimura #define bus_space_write_region_2(t, h, o, a, c) do { \ 35995d00ea7Snisimura (void) t; \ 3605f1c88d7Sperry __asm volatile (" \ 361d0e2aef0Schs movl %0,%%a0 ; \ 362d0e2aef0Schs movl %1,%%a1 ; \ 363d0e2aef0Schs movl %2,%%d0 ; \ 364bf2202e1Stsutsui 1: movw %%a1@+,%%a0@ ; \ 365bf2202e1Stsutsui addql #4,%%a0 ; \ 366d0e2aef0Schs subql #1,%%d0 ; \ 36795d00ea7Snisimura jne 1b" : \ 36895d00ea7Snisimura : \ 369bf2202e1Stsutsui "r" ((h) + (o)*2), "g" (a), "g" ((size_t)(c)) : \ 37095d00ea7Snisimura "a0","a1","d0"); \ 37195d00ea7Snisimura } while (0) 37295d00ea7Snisimura 37395d00ea7Snisimura #define bus_space_write_region_4(t, h, o, a, c) do { \ 37495d00ea7Snisimura (void) t; \ 3755f1c88d7Sperry __asm volatile (" \ 376d0e2aef0Schs movl %0,%%a0 ; \ 377d0e2aef0Schs movl %1,%%a1 ; \ 378d0e2aef0Schs movl %2,%%d0 ; \ 379ae2b6b31Stsutsui 1: movl %%a1@+,%%a0@+ ; \ 380d0e2aef0Schs subql #1,%%d0 ; \ 38195d00ea7Snisimura jne 1b" : \ 38295d00ea7Snisimura : \ 38395d00ea7Snisimura "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \ 38495d00ea7Snisimura "a0","a1","d0"); \ 38595d00ea7Snisimura } while (0) 38695d00ea7Snisimura 38795d00ea7Snisimura /* 38802cdf4d2Sdsl * void bus_space_set_multi_N(bus_space_tag_t tag, 38995d00ea7Snisimura * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 39002cdf4d2Sdsl * size_t count); 39195d00ea7Snisimura * 39295d00ea7Snisimura * Write the 1, 2, 4, or 8 byte value `val' to bus space described 39395d00ea7Snisimura * by tag/handle/offset `count' times. 39495d00ea7Snisimura */ 39595d00ea7Snisimura 39695d00ea7Snisimura #define bus_space_set_multi_1(t, h, o, val, c) do { \ 39795d00ea7Snisimura (void) t; \ 3985f1c88d7Sperry __asm volatile (" \ 399d0e2aef0Schs movl %0,%%a0 ; \ 400d0e2aef0Schs movl %1,%%d1 ; \ 401d0e2aef0Schs movl %2,%%d0 ; \ 402d0e2aef0Schs 1: movb %%d1,%%a0@ ; \ 403d0e2aef0Schs subql #1,%%d0 ; \ 40495d00ea7Snisimura jne 1b" : \ 40595d00ea7Snisimura : \ 406bf2202e1Stsutsui "r" ((h)+(o)*4), "g" ((u_long)val), \ 40795d00ea7Snisimura "g" ((size_t)(c)) : \ 40895d00ea7Snisimura "a0","d0","d1"); \ 40995d00ea7Snisimura } while (0) 41095d00ea7Snisimura 41195d00ea7Snisimura #define bus_space_set_multi_2(t, h, o, val, c) do { \ 41295d00ea7Snisimura (void) t; \ 4135f1c88d7Sperry __asm volatile (" \ 414d0e2aef0Schs movl %0,%%a0 ; \ 415d0e2aef0Schs movl %1,%%d1 ; \ 416d0e2aef0Schs movl %2,%%d0 ; \ 417d0e2aef0Schs 1: movw %%d1,%%a0@ ; \ 418d0e2aef0Schs subql #1,%%d0 ; \ 41995d00ea7Snisimura jne 1b" : \ 42095d00ea7Snisimura : \ 421bf2202e1Stsutsui "r" ((h)+(o)*2), "g" ((u_long)val), \ 42295d00ea7Snisimura "g" ((size_t)(c)) : \ 42395d00ea7Snisimura "a0","d0","d1"); \ 42495d00ea7Snisimura } while (0) 42595d00ea7Snisimura 42695d00ea7Snisimura #define bus_space_set_multi_4(t, h, o, val, c) do { \ 42795d00ea7Snisimura (void) t; \ 4285f1c88d7Sperry __asm volatile (" \ 429d0e2aef0Schs movl %0,%%a0 ; \ 430d0e2aef0Schs movl %1,%%d1 ; \ 431d0e2aef0Schs movl %2,%%d0 ; \ 432d0e2aef0Schs 1: movl %%d1,%%a0@ ; \ 433d0e2aef0Schs subql #1,%%d0 ; \ 43495d00ea7Snisimura jne 1b" : \ 43595d00ea7Snisimura : \ 43695d00ea7Snisimura "r" ((h)+(o)), "g" ((u_long)val), \ 43795d00ea7Snisimura "g" ((size_t)(c)) : \ 43895d00ea7Snisimura "a0","d0","d1"); \ 43995d00ea7Snisimura } while (0) 44095d00ea7Snisimura 44195d00ea7Snisimura /* 44202cdf4d2Sdsl * void bus_space_set_region_N(bus_space_tag_t tag, 44395d00ea7Snisimura * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, 44402cdf4d2Sdsl * size_t count); 44595d00ea7Snisimura * 44695d00ea7Snisimura * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 44795d00ea7Snisimura * by tag/handle starting at `offset'. 44895d00ea7Snisimura */ 44995d00ea7Snisimura 45095d00ea7Snisimura #define bus_space_set_region_1(t, h, o, val, c) do { \ 45195d00ea7Snisimura (void) t; \ 4525f1c88d7Sperry __asm volatile (" \ 453d0e2aef0Schs movl %0,%%a0 ; \ 454d0e2aef0Schs movl %1,%%d1 ; \ 455d0e2aef0Schs movl %2,%%d0 ; \ 456bf2202e1Stsutsui 1: movb %%d1,%%a0@ ; \ 457bf2202e1Stsutsui addql #4,%%a0 ; \ 458d0e2aef0Schs subql #1,%%d0 ; \ 45995d00ea7Snisimura jne 1b" : \ 46095d00ea7Snisimura : \ 461bf2202e1Stsutsui "r" ((h)+(o)*4), "g" ((u_long)val), \ 46295d00ea7Snisimura "g" ((size_t)(c)) : \ 46395d00ea7Snisimura "a0","d0","d1"); \ 46495d00ea7Snisimura } while (0) 46595d00ea7Snisimura 46695d00ea7Snisimura #define bus_space_set_region_2(t, h, o, val, c) do { \ 46795d00ea7Snisimura (void) t; \ 4685f1c88d7Sperry __asm volatile (" \ 469d0e2aef0Schs movl %0,%%a0 ; \ 470d0e2aef0Schs movl %1,%%d1 ; \ 471d0e2aef0Schs movl %2,%%d0 ; \ 472bf2202e1Stsutsui 1: movw %%d1,%%a0@ ; \ 473bf2202e1Stsutsui addql #4,%%a0 ; \ 474d0e2aef0Schs subql #1,%%d0 ; \ 47595d00ea7Snisimura jne 1b" : \ 47695d00ea7Snisimura : \ 477bf2202e1Stsutsui "r" ((h)+(o)*2), "g" ((u_long)val), \ 47895d00ea7Snisimura "g" ((size_t)(c)) : \ 47995d00ea7Snisimura "a0","d0","d1"); \ 48095d00ea7Snisimura } while (0) 48195d00ea7Snisimura 48295d00ea7Snisimura #define bus_space_set_region_4(t, h, o, val, c) do { \ 48395d00ea7Snisimura (void) t; \ 4845f1c88d7Sperry __asm volatile (" \ 485d0e2aef0Schs movl %0,%%a0 ; \ 486d0e2aef0Schs movl %1,%%d1 ; \ 487d0e2aef0Schs movl %2,%%d0 ; \ 488d0e2aef0Schs 1: movl %%d1,%%a0@+ ; \ 489d0e2aef0Schs subql #1,%%d0 ; \ 49095d00ea7Snisimura jne 1b" : \ 49195d00ea7Snisimura : \ 49295d00ea7Snisimura "r" ((h)+(o)), "g" ((u_long)val), \ 49395d00ea7Snisimura "g" ((size_t)(c)) : \ 49495d00ea7Snisimura "a0","d0","d1"); \ 49595d00ea7Snisimura } while (0) 49695d00ea7Snisimura 49795d00ea7Snisimura /* 49802cdf4d2Sdsl * void bus_space_copy_N(bus_space_tag_t tag, 49995d00ea7Snisimura * bus_space_handle_t bsh1, bus_size_t off1, 50095d00ea7Snisimura * bus_space_handle_t bsh2, bus_size_t off2, 50102cdf4d2Sdsl * size_t count); 50295d00ea7Snisimura * 50395d00ea7Snisimura * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 50495d00ea7Snisimura * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 50595d00ea7Snisimura */ 50695d00ea7Snisimura 50795d00ea7Snisimura #define __MACHINE_copy_region_N(BYTES) \ 508fbae48b9Sperry static __inline void __CONCAT(bus_space_copy_region_,BYTES) \ 50902cdf4d2Sdsl (bus_space_tag_t, \ 51095d00ea7Snisimura bus_space_handle_t bsh1, bus_size_t off1, \ 51195d00ea7Snisimura bus_space_handle_t bsh2, bus_size_t off2, \ 51202cdf4d2Sdsl bus_size_t count); \ 51395d00ea7Snisimura \ 514fbae48b9Sperry static __inline void \ 5151d7f24eaSmatt __CONCAT(bus_space_copy_region_,BYTES)( \ 5161d7f24eaSmatt bus_space_tag_t t, \ 5171d7f24eaSmatt bus_space_handle_t h1, \ 5181d7f24eaSmatt bus_size_t o1, \ 5191d7f24eaSmatt bus_space_handle_t h2, \ 5201d7f24eaSmatt bus_size_t o2, \ 5211d7f24eaSmatt bus_size_t c) \ 52295d00ea7Snisimura { \ 52395d00ea7Snisimura bus_size_t o; \ 52495d00ea7Snisimura \ 52595d00ea7Snisimura if ((h1 + o1) >= (h2 + o2)) { \ 52695d00ea7Snisimura /* src after dest: copy forward */ \ 52795d00ea7Snisimura for (o = 0; c != 0; c--, o += BYTES) \ 52895d00ea7Snisimura __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 52995d00ea7Snisimura __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 53095d00ea7Snisimura } else { \ 53195d00ea7Snisimura /* dest after src: copy backwards */ \ 53295d00ea7Snisimura for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \ 53395d00ea7Snisimura __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \ 53495d00ea7Snisimura __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \ 53595d00ea7Snisimura } \ 53695d00ea7Snisimura } 53795d00ea7Snisimura __MACHINE_copy_region_N(1) 53895d00ea7Snisimura __MACHINE_copy_region_N(2) 53995d00ea7Snisimura __MACHINE_copy_region_N(4) 54095d00ea7Snisimura 54195d00ea7Snisimura #undef __MACHINE_copy_region_N 54295d00ea7Snisimura 54395d00ea7Snisimura /* 54495d00ea7Snisimura * Bus read/write barrier methods. 54595d00ea7Snisimura * 54602cdf4d2Sdsl * void bus_space_barrier(bus_space_tag_t tag, 54795d00ea7Snisimura * bus_space_handle_t bsh, bus_size_t offset, 54802cdf4d2Sdsl * bus_size_t len, int flags); 54995d00ea7Snisimura * 55095d00ea7Snisimura * Note: the 680x0 does not currently require barriers, but we must 55195d00ea7Snisimura * provide the flags to MI code. 55295d00ea7Snisimura */ 55395d00ea7Snisimura #define bus_space_barrier(t, h, o, l, f) \ 55495d00ea7Snisimura ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) 55595d00ea7Snisimura #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 55695d00ea7Snisimura #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 55795d00ea7Snisimura 55895d00ea7Snisimura #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) 55995d00ea7Snisimura 560485e133aStsutsui /* 561485e133aStsutsui * There is no bus_dma(9)'fied bus drivers on this port. 562485e133aStsutsui */ 563485e133aStsutsui #define __HAVE_NO_BUS_DMA 564485e133aStsutsui 56595d00ea7Snisimura #endif /* _MACHINE_BUS_H_ */ 566