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