1*0fc03ff9Sjsg /* $OpenBSD: bus.h,v 1.38 2024/10/22 22:01:58 jsg Exp $ */ 25fdbebc0Sjason /* $NetBSD: bus.h,v 1.31 2001/09/21 15:30:41 wiz Exp $ */ 3bd12f793Sart 4bd12f793Sart /*- 5bd12f793Sart * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc. 6bd12f793Sart * All rights reserved. 7bd12f793Sart * 8bd12f793Sart * This code is derived from software contributed to The NetBSD Foundation 9bd12f793Sart * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 10bd12f793Sart * NASA Ames Research Center. 11bd12f793Sart * 12bd12f793Sart * Redistribution and use in source and binary forms, with or without 13bd12f793Sart * modification, are permitted provided that the following conditions 14bd12f793Sart * are met: 15bd12f793Sart * 1. Redistributions of source code must retain the above copyright 16bd12f793Sart * notice, this list of conditions and the following disclaimer. 17bd12f793Sart * 2. Redistributions in binary form must reproduce the above copyright 18bd12f793Sart * notice, this list of conditions and the following disclaimer in the 19bd12f793Sart * documentation and/or other materials provided with the distribution. 20bd12f793Sart * 21bd12f793Sart * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22bd12f793Sart * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23bd12f793Sart * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24bd12f793Sart * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25bd12f793Sart * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26bd12f793Sart * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27bd12f793Sart * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28bd12f793Sart * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29bd12f793Sart * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30bd12f793Sart * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31bd12f793Sart * POSSIBILITY OF SUCH DAMAGE. 32bd12f793Sart */ 33bd12f793Sart 34bd12f793Sart /* 355cdd493aSjason * Copyright (c) 1997-1999, 2001 Eduardo E. Horvath. All rights reserved. 36bd12f793Sart * Copyright (c) 1996 Charles M. Hannum. All rights reserved. 37bd12f793Sart * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. 38bd12f793Sart * 39bd12f793Sart * Redistribution and use in source and binary forms, with or without 40bd12f793Sart * modification, are permitted provided that the following conditions 41bd12f793Sart * are met: 42bd12f793Sart * 1. Redistributions of source code must retain the above copyright 43bd12f793Sart * notice, this list of conditions and the following disclaimer. 44bd12f793Sart * 2. Redistributions in binary form must reproduce the above copyright 45bd12f793Sart * notice, this list of conditions and the following disclaimer in the 46bd12f793Sart * documentation and/or other materials provided with the distribution. 47bd12f793Sart * 3. All advertising materials mentioning features or use of this software 48bd12f793Sart * must display the following acknowledgement: 49bd12f793Sart * This product includes software developed by Christopher G. Demetriou 50bd12f793Sart * for the NetBSD Project. 51bd12f793Sart * 4. The name of the author may not be used to endorse or promote products 52bd12f793Sart * derived from this software without specific prior written permission 53bd12f793Sart * 54bd12f793Sart * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 55bd12f793Sart * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 56bd12f793Sart * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 57bd12f793Sart * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 58bd12f793Sart * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 59bd12f793Sart * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 60bd12f793Sart * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 61bd12f793Sart * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 62bd12f793Sart * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 63bd12f793Sart * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 64bd12f793Sart */ 65bd12f793Sart 662fa72412Spirofti #ifndef _MACHINE_BUS_H_ 672fa72412Spirofti #define _MACHINE_BUS_H_ 68bd12f793Sart 6927d3e2e5Sdlg #include <sys/atomic.h> 70bd12f793Sart 71f56b290dSderaadt #ifdef _KERNEL 72f56b290dSderaadt 73bd12f793Sart /* 74bd12f793Sart * Debug hooks 75bd12f793Sart */ 76bd12f793Sart 77bd12f793Sart #define BSDB_ACCESS 0x01 78bd12f793Sart #define BSDB_MAP 0x02 79eb79e960Shenric #define BSDB_ASSERT 0x04 80eb79e960Shenric #define BSDB_MAPDETAIL 0x08 81eb79e960Shenric #define BSDB_ALL_ACCESS 0x10 82bd12f793Sart extern int bus_space_debug; 83bd12f793Sart 84eb79e960Shenric #define BSHDB_ACCESS 0x01 85eb79e960Shenric #define BSHDB_NO_ACCESS 0x02 86eb79e960Shenric 87eb79e960Shenric #if defined(BUS_SPACE_DEBUG) 88eb79e960Shenric #include <sys/systm.h> 89745b6152Shenric #define BUS_SPACE_PRINTF(l, s) do { \ 90745b6152Shenric if(bus_space_debug & (l)) printf s; \ 91745b6152Shenric } while(0) 92eb79e960Shenric #define BUS_SPACE_TRACE(t, h, s) do { \ 93eb79e960Shenric if ( (((bus_space_debug & BSDB_ALL_ACCESS) != 0) && \ 94eb79e960Shenric (((h).bh_flags & BSHDB_NO_ACCESS) == 0)) || \ 95eb79e960Shenric (((bus_space_debug & BSDB_ACCESS) != 0) && \ 96eb79e960Shenric (((h).bh_flags & BSHDB_ACCESS) != 0))) \ 97eb79e960Shenric printf s; \ 98eb79e960Shenric } while(0) 99eb79e960Shenric #define BUS_SPACE_SET_FLAGS(t, h, f) ((h).bh_flags |= (f)) 100eb79e960Shenric #define BUS_SPACE_CLEAR_FLAGS(t, h, f) ((h).bh_flags &= ~(f)) 101eb79e960Shenric #define BUS_SPACE_FLAG_DECL(s) int s 102eb79e960Shenric #define BUS_SPACE_SAVE_FLAGS(t, h, s) (s = (h).bh_flags) 103eb79e960Shenric #define BUS_SPACE_RESTORE_FLAGS(t, h, s) (s = (h).bh_flags) 104eb79e960Shenric #define BUS_SPACE_ASSERT(t, h, o, n) do { \ 105eb79e960Shenric if (bus_space_debug & BSDB_ASSERT) \ 106eb79e960Shenric bus_space_assert(t, &(h), o, n); \ 107eb79e960Shenric } while(0) 108745b6152Shenric #else /* BUS_SPACE_DEBUG */ 109eb79e960Shenric #define BUS_SPACE_PRINTF(l, s) 110eb79e960Shenric #define BUS_SPACE_TRACE(t, h, s) 111eb79e960Shenric #define BUS_SPACE_SET_FLAGS(t, h, f) 112eb79e960Shenric #define BUS_SPACE_CLEAR_FLAGS(t, h, f) 113eb79e960Shenric #define BUS_SPACE_FLAG_DECL(s) 114eb79e960Shenric #define BUS_SPACE_SAVE_FLAGS(t, h, s) 115eb79e960Shenric #define BUS_SPACE_RESTORE_FLAGS(t, h, s) 116eb79e960Shenric #define BUS_SPACE_ASSERT(t, h, o, n) 117745b6152Shenric #endif /* BUS_SPACE_DEBUG */ 118eb79e960Shenric 119eb79e960Shenric 120bd12f793Sart /* 121d277156aSsobrado * UPA and SBus spaces are non-cached and big endian 122bd12f793Sart * (except for RAM and PROM) 123bd12f793Sart * 124bd12f793Sart * PCI spaces are non-cached and little endian 125bd12f793Sart */ 126bd12f793Sart 1270793d0d1Sjsg enum sparc_bus_type { 128bd12f793Sart UPA_BUS_SPACE, 129bd12f793Sart SBUS_BUS_SPACE, 130bd12f793Sart PCI_CONFIG_BUS_SPACE, 131bd12f793Sart PCI_IO_BUS_SPACE, 132bd12f793Sart PCI_MEMORY_BUS_SPACE, 133bd12f793Sart LAST_BUS_SPACE 134bd12f793Sart }; 135bd12f793Sart /* For backwards compatibility */ 136bd12f793Sart #define SPARC_BUS_SPACE UPA_BUS_SPACE 137bd12f793Sart 138bd12f793Sart /* 139bd12f793Sart * Bus address and size types 140bd12f793Sart */ 141eb79e960Shenric typedef const struct sparc_bus_space_tag *bus_space_tag_t; 1427142cce9Smiod typedef u_long bus_addr_t; 1437142cce9Smiod typedef u_long bus_size_t; 144bd12f793Sart 145eb79e960Shenric 146eb79e960Shenric typedef struct _bus_space_handle { 147eb79e960Shenric paddr_t bh_ptr; 148eb79e960Shenric #ifdef BUS_SPACE_DEBUG 149eb79e960Shenric bus_space_tag_t bh_tag; 150eb79e960Shenric bus_size_t bh_size; 151eb79e960Shenric int bh_flags; 152eb79e960Shenric #endif 153eb79e960Shenric } bus_space_handle_t; 154eb79e960Shenric 1555fdbebc0Sjason /* For buses which have an iospace. */ 1565fdbebc0Sjason #define BUS_ADDR_IOSPACE(x) ((x)>>32) 1575fdbebc0Sjason #define BUS_ADDR_PADDR(x) ((x)&0xffffffff) 158eb79e960Shenric #define BUS_ADDR(io, pa) ((((bus_addr_t)io)<<32)|(pa)) 1595fdbebc0Sjason 160bd12f793Sart /* 161bd12f793Sart * Access methods for bus resources and address space. 162bd12f793Sart */ 163bd12f793Sart 164bd12f793Sart struct sparc_bus_space_tag { 165bd12f793Sart void *cookie; 166bd12f793Sart bus_space_tag_t parent; 1670793d0d1Sjsg enum sparc_bus_type default_type; 168eb79e960Shenric u_int8_t asi; 169eb79e960Shenric u_int8_t sasi; 170eb79e960Shenric char name[32]; 171bd12f793Sart 172c4071fd1Smillert int (*sparc_bus_alloc)(bus_space_tag_t, 173eb79e960Shenric bus_space_tag_t, 1745fdbebc0Sjason bus_addr_t, bus_addr_t, 1755fdbebc0Sjason bus_size_t, bus_size_t, bus_size_t, 176c4071fd1Smillert int, bus_addr_t *, bus_space_handle_t *); 177bd12f793Sart 178c4071fd1Smillert void (*sparc_bus_free)(bus_space_tag_t, 179eb79e960Shenric bus_space_tag_t, 180c4071fd1Smillert bus_space_handle_t, bus_size_t); 181bd12f793Sart 182c4071fd1Smillert int (*sparc_bus_map)(bus_space_tag_t, 183eb79e960Shenric bus_space_tag_t, 184eb79e960Shenric bus_addr_t, bus_size_t, 185eb79e960Shenric int, bus_space_handle_t *); 186eb79e960Shenric 187eb79e960Shenric int (*sparc_bus_protect)(bus_space_tag_t, 188eb79e960Shenric bus_space_tag_t, 189eb79e960Shenric bus_space_handle_t, bus_size_t, int); 190bd12f793Sart 191c4071fd1Smillert int (*sparc_bus_unmap)(bus_space_tag_t, 192eb79e960Shenric bus_space_tag_t, 193c4071fd1Smillert bus_space_handle_t, bus_size_t); 1945fdbebc0Sjason 195c4071fd1Smillert int (*sparc_bus_subregion)(bus_space_tag_t, 196eb79e960Shenric bus_space_tag_t, 1975fdbebc0Sjason bus_space_handle_t, bus_size_t, 198c4071fd1Smillert bus_size_t, bus_space_handle_t *); 1995fdbebc0Sjason 200c4071fd1Smillert paddr_t (*sparc_bus_mmap)(bus_space_tag_t, 201eb79e960Shenric bus_space_tag_t, 202c4071fd1Smillert bus_addr_t, off_t, int, int); 2035fdbebc0Sjason 2044f9e30d0Smillert void *(*sparc_intr_establish)(bus_space_tag_t, 205eb79e960Shenric bus_space_tag_t, 2065fdbebc0Sjason int, int, int, 20785729938Shenric int (*)(void *), void *, 20885729938Shenric const char *); 2091d9e937eSjmatthew void *(*sparc_intr_establish_cpu)(bus_space_tag_t, 2101d9e937eSjmatthew bus_space_tag_t, 2111d9e937eSjmatthew int, int, int, 2121d9e937eSjmatthew struct cpu_info *, 2131d9e937eSjmatthew int (*)(void *), void *, 2141d9e937eSjmatthew const char *); 215bd12f793Sart 21659c45879Skettenis bus_addr_t (*sparc_bus_addr)(bus_space_tag_t, 21759c45879Skettenis bus_space_tag_t, bus_space_handle_t); 218bd12f793Sart }; 219bd12f793Sart 220bd12f793Sart /* 221bd12f793Sart * Bus space function prototypes. 222bd12f793Sart */ 223eb79e960Shenric int bus_space_alloc( 2245fdbebc0Sjason bus_space_tag_t, 2255fdbebc0Sjason bus_addr_t, /* reg start */ 2265fdbebc0Sjason bus_addr_t, /* reg end */ 2275fdbebc0Sjason bus_size_t, /* size */ 2285fdbebc0Sjason bus_size_t, /* alignment */ 2295fdbebc0Sjason bus_size_t, /* boundary */ 2305fdbebc0Sjason int, /* flags */ 2315fdbebc0Sjason bus_addr_t *, 232c4071fd1Smillert bus_space_handle_t *); 233eb79e960Shenric void bus_space_free( 2345fdbebc0Sjason bus_space_tag_t, 2355fdbebc0Sjason bus_space_handle_t, 236c4071fd1Smillert bus_size_t); 237eb79e960Shenric int bus_space_map( 238bd12f793Sart bus_space_tag_t, 239bd12f793Sart bus_addr_t, 240bd12f793Sart bus_size_t, 241bd12f793Sart int, /*flags*/ 242c4071fd1Smillert bus_space_handle_t *); 243eb79e960Shenric int bus_space_protect( 244bd12f793Sart bus_space_tag_t, 245eb79e960Shenric bus_space_handle_t, 246bd12f793Sart bus_size_t, 247eb79e960Shenric int); /*flags*/ 248eb79e960Shenric int bus_space_unmap( 249bd12f793Sart bus_space_tag_t, 250bd12f793Sart bus_space_handle_t, 251c4071fd1Smillert bus_size_t); 252eb79e960Shenric int bus_space_subregion( 253bd12f793Sart bus_space_tag_t, 254bd12f793Sart bus_space_handle_t, 255bd12f793Sart bus_size_t, 256bd12f793Sart bus_size_t, 257c4071fd1Smillert bus_space_handle_t *); 258c4071fd1Smillert static void bus_space_barrier( 259bd12f793Sart bus_space_tag_t, 260bd12f793Sart bus_space_handle_t, 261bd12f793Sart bus_size_t, 262bd12f793Sart bus_size_t, 263c4071fd1Smillert int); 264eb79e960Shenric paddr_t bus_space_mmap( 265bd12f793Sart bus_space_tag_t, 2665fdbebc0Sjason bus_addr_t, /*addr*/ 2675fdbebc0Sjason off_t, /*offset*/ 2685fdbebc0Sjason int, /*prot*/ 269c4071fd1Smillert int); /*flags*/ 270eb79e960Shenric void *bus_intr_establish( 271bd12f793Sart bus_space_tag_t, 272bd12f793Sart int, /*bus-specific intr*/ 273bd12f793Sart int, /*device class level, 274bd12f793Sart see machine/intr.h*/ 275bd12f793Sart int, /*flags*/ 276c4071fd1Smillert int (*)(void *), /*handler*/ 27785729938Shenric void *, /*handler arg*/ 27885729938Shenric const char *); /*what*/ 2791d9e937eSjmatthew void *bus_intr_establish_cpu( 2801d9e937eSjmatthew bus_space_tag_t, 2811d9e937eSjmatthew int, /*bus-specific intr*/ 2821d9e937eSjmatthew int, /*device class level, 2831d9e937eSjmatthew see machine/intr.h*/ 2841d9e937eSjmatthew int, /*flags*/ 2851d9e937eSjmatthew struct cpu_info *, /*cpu*/ 2861d9e937eSjmatthew int (*)(void *), /*handler*/ 2871d9e937eSjmatthew void *, /*handler arg*/ 2881d9e937eSjmatthew const char *); /*what*/ 28985729938Shenric void *bus_intr_allocate( 29085729938Shenric bus_space_tag_t, 29185729938Shenric int (*)(void *), /*handler*/ 29285729938Shenric void *, /*handler arg*/ 29385729938Shenric int, /*number*/ 29485729938Shenric int, /*pil*/ 29585729938Shenric volatile u_int64_t *, /*map*/ 29685729938Shenric volatile u_int64_t *, /*clr*/ 29785729938Shenric const char *); /*what*/ 29885729938Shenric void bus_intr_free(void *); 299eb79e960Shenric void bus_space_render_tag( 300eb79e960Shenric bus_space_tag_t, 301eb79e960Shenric char *, 302eb79e960Shenric size_t); 303eb79e960Shenric void *bus_space_vaddr( 304eb79e960Shenric bus_space_tag_t, 305eb79e960Shenric bus_space_handle_t); 306bd12f793Sart 307745b6152Shenric #ifdef BUS_SPACE_DEBUG 308745b6152Shenric void bus_space_assert(bus_space_tag_t, 309745b6152Shenric const bus_space_handle_t *, 310745b6152Shenric bus_size_t, int); 311745b6152Shenric void bus_space_render_tag(bus_space_tag_t, char*, size_t); 312745b6152Shenric #endif /* BUS_SPACE_DEBUG */ 313745b6152Shenric 314745b6152Shenric 315eb79e960Shenric #define _BS_PRECALL(t,f) \ 316bd12f793Sart while (t->f == NULL) \ 317eb79e960Shenric t = t->parent; 318eb79e960Shenric #define _BS_POSTCALL 319bd12f793Sart 320eb79e960Shenric #define _BS_CALL(t,f) \ 321eb79e960Shenric (*(t)->f) 3225fdbebc0Sjason 32387881ff4Sdlg /* flags for bus_space_barrier() */ 32487881ff4Sdlg #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 32587881ff4Sdlg #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 32687881ff4Sdlg 327eb79e960Shenric static inline void 32847c47feaSjsg bus_space_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 32947c47feaSjsg bus_size_t s, int f) 330bd12f793Sart { 33187881ff4Sdlg #ifdef notyet 33287881ff4Sdlg switch (f) { 33387881ff4Sdlg case (BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE): 33427d3e2e5Sdlg __membar("#LoadLoad|#StoreStore"); 33587881ff4Sdlg break; 33687881ff4Sdlg case BUS_SPACE_BARRIER_READ: 33727d3e2e5Sdlg membar("#LoadLoad"); 33887881ff4Sdlg break; 33987881ff4Sdlg case BUS_SPACE_BARRIER_WRITE: 34027d3e2e5Sdlg membar("#StoreStore"); 34187881ff4Sdlg break; 34287881ff4Sdlg default: 34387881ff4Sdlg break; 34487881ff4Sdlg } 34587881ff4Sdlg #else 34627d3e2e5Sdlg __membar("#Sync"); 34787881ff4Sdlg #endif 348bd12f793Sart } 349bd12f793Sart 350eb79e960Shenric #include <sparc64/sparc64/busop.h> 351bd12f793Sart 352bd12f793Sart /* flags for bus space map functions */ 353bd12f793Sart #define BUS_SPACE_MAP_CACHEABLE 0x0001 354bd12f793Sart #define BUS_SPACE_MAP_LINEAR 0x0002 355bd12f793Sart #define BUS_SPACE_MAP_READONLY 0x0004 356bd12f793Sart #define BUS_SPACE_MAP_PREFETCHABLE 0x0008 357eb79e960Shenric #define BUS_SPACE_MAP_PROMADDRESS 0x0010 358bd12f793Sart #define BUS_SPACE_MAP_BUS1 0x0100 /* placeholders for bus functions... */ 359bd12f793Sart #define BUS_SPACE_MAP_BUS2 0x0200 360bd12f793Sart #define BUS_SPACE_MAP_BUS3 0x0400 361bd12f793Sart #define BUS_SPACE_MAP_BUS4 0x0800 362bd12f793Sart 363bd12f793Sart 364f8e9be80Skettenis /* flags for bus_intr_establish() */ 365f8e9be80Skettenis #define BUS_INTR_ESTABLISH_MPSAFE 0x0001 366f8e9be80Skettenis #define BUS_INTR_ESTABLISH_SOFTINTR 0x0002 367bd12f793Sart 368bd12f793Sart /* 369bd12f793Sart * Flags used in various bus DMA methods. 370bd12f793Sart */ 371bdd819b7Skettenis #define BUS_DMA_WAITOK 0x0000 /* safe to sleep (pseudo-flag) */ 372bdd819b7Skettenis #define BUS_DMA_NOWAIT 0x0001 /* not safe to sleep */ 373bdd819b7Skettenis #define BUS_DMA_ALLOCNOW 0x0002 /* perform resource allocation now */ 374bdd819b7Skettenis #define BUS_DMA_COHERENT 0x0004 /* hint: map memory DMA coherent */ 375bdd819b7Skettenis #define BUS_DMA_NOWRITE 0x0008 /* I suppose the following two should default on */ 376bdd819b7Skettenis #define BUS_DMA_BUS1 0x0010 /* placeholders for bus functions... */ 377bdd819b7Skettenis #define BUS_DMA_BUS2 0x0020 378bdd819b7Skettenis #define BUS_DMA_BUS3 0x0040 379bdd819b7Skettenis #define BUS_DMA_BUS4 0x0080 380bdd819b7Skettenis #define BUS_DMA_STREAMING 0x0100 /* hint: sequential, unidirectional */ 381bdd819b7Skettenis #define BUS_DMA_READ 0x0200 /* mapping is device -> memory only */ 382bdd819b7Skettenis #define BUS_DMA_WRITE 0x0400 /* mapping is memory -> device only */ 383bdd819b7Skettenis #define BUS_DMA_ZERO 0x0800 /* zero memory in dmamem_alloc */ 384bdd819b7Skettenis #define BUS_DMA_OVERRUN 0x1000 /* tolerate DMA overruns */ 385b0002153Sdlg #define BUS_DMA_64BIT 0x2000 /* device handles 64bit dva */ 386bd12f793Sart 387bd12f793Sart #define BUS_DMA_NOCACHE BUS_DMA_BUS1 388bd12f793Sart #define BUS_DMA_DVMA BUS_DMA_BUS2 /* Don't bother with alignment */ 389f40adf33Sjason #define BUS_DMA_24BIT BUS_DMA_BUS3 /* 24bit device */ 390bd12f793Sart 391eb79e960Shenric #define BUS_DMA_RAW BUS_DMA_STREAMING 392eb79e960Shenric 393bd12f793Sart /* Forwards needed by prototypes below. */ 394bd12f793Sart struct mbuf; 395bd12f793Sart struct uio; 396bd12f793Sart 397bd12f793Sart /* 398bd12f793Sart * Operations performed by bus_dmamap_sync(). 399bd12f793Sart */ 400bd12f793Sart #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */ 401bd12f793Sart #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */ 402bd12f793Sart #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */ 403bd12f793Sart #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */ 404bd12f793Sart 405bd12f793Sart typedef struct sparc_bus_dma_tag *bus_dma_tag_t; 406bd12f793Sart typedef struct sparc_bus_dmamap *bus_dmamap_t; 407bd12f793Sart 408bd12f793Sart /* 409bd12f793Sart * bus_dma_segment_t 410bd12f793Sart * 411bd12f793Sart * Describes a single contiguous DMA transaction. Values 412bd12f793Sart * are suitable for programming into DMA registers. 413bd12f793Sart */ 414bd12f793Sart struct sparc_bus_dma_segment { 415bd12f793Sart bus_addr_t ds_addr; /* DVMA address */ 416bd12f793Sart bus_size_t ds_len; /* length of transfer */ 417745b6152Shenric /* 418745b6152Shenric * The following is to support bus_dmamem_alloc()'s 419745b6152Shenric * odd interface. Only the values in the first 420745b6152Shenric * segment are used. This means that 3/5ths of 421745b6152Shenric * most segments are useless space (and mbufs use 1024 422745b6152Shenric * segments). 423745b6152Shenric */ 424bd12f793Sart bus_size_t _ds_boundary; /* don't cross this */ 425bd12f793Sart bus_size_t _ds_align; /* align to this */ 426bd12f793Sart void *_ds_mlist; /* XXX - dmamap_alloc'ed pages */ 427bd12f793Sart }; 428bd12f793Sart typedef struct sparc_bus_dma_segment bus_dma_segment_t; 429bd12f793Sart 430bd12f793Sart 431bd12f793Sart /* 432bd12f793Sart * bus_dma_tag_t 433bd12f793Sart * 434bd12f793Sart * A machine-dependent opaque type describing the implementation of 435bd12f793Sart * DMA for a given bus. 436bd12f793Sart */ 437bd12f793Sart struct sparc_bus_dma_tag { 438bd12f793Sart void *_cookie; /* cookie used in the guts */ 439bd12f793Sart struct sparc_bus_dma_tag* _parent; 440bd12f793Sart 441bd12f793Sart /* 442bd12f793Sart * DMA mapping methods. 443bd12f793Sart */ 444745b6152Shenric int (*_dmamap_create)(bus_dma_tag_t, bus_dma_tag_t, bus_size_t, 445745b6152Shenric int, bus_size_t, bus_size_t, int, bus_dmamap_t *); 446745b6152Shenric void (*_dmamap_destroy)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t); 447745b6152Shenric int (*_dmamap_load)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, 448745b6152Shenric void *, bus_size_t, struct proc *, int); 449745b6152Shenric int (*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dma_tag_t, 450745b6152Shenric bus_dmamap_t, struct mbuf *, int); 451745b6152Shenric int (*_dmamap_load_uio)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, 452c4071fd1Smillert struct uio *, int); 453745b6152Shenric int (*_dmamap_load_raw)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, 454c4071fd1Smillert bus_dma_segment_t *, int, bus_size_t, int); 455745b6152Shenric void (*_dmamap_unload)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t); 456745b6152Shenric void (*_dmamap_sync)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, 457c4071fd1Smillert bus_addr_t, bus_size_t, int); 458bd12f793Sart 459bd12f793Sart /* 460bd12f793Sart * DMA memory utility functions. 461bd12f793Sart */ 462745b6152Shenric int (*_dmamem_alloc)(bus_dma_tag_t, bus_dma_tag_t, bus_size_t, 463745b6152Shenric bus_size_t, bus_size_t, bus_dma_segment_t *, int, int *, 464745b6152Shenric int); 465745b6152Shenric void (*_dmamem_free)(bus_dma_tag_t, bus_dma_tag_t, 466c4071fd1Smillert bus_dma_segment_t *, int); 467745b6152Shenric int (*_dmamem_map)(bus_dma_tag_t, bus_dma_tag_t, 468745b6152Shenric bus_dma_segment_t *, int, size_t, caddr_t *, int); 469745b6152Shenric void (*_dmamem_unmap)(bus_dma_tag_t, bus_dma_tag_t, caddr_t, 470745b6152Shenric size_t); 471745b6152Shenric paddr_t (*_dmamem_mmap)(bus_dma_tag_t, bus_dma_tag_t, 472745b6152Shenric bus_dma_segment_t *, int, off_t, int, int); 473bd12f793Sart }; 474bd12f793Sart 475745b6152Shenric #define _BD_PRECALL(t,f) \ 476745b6152Shenric while (t->f == NULL) { \ 477745b6152Shenric t = t->_parent; \ 478745b6152Shenric } 479745b6152Shenric #define _BD_CALL(t,f) \ 480745b6152Shenric (*(t)->f) 481745b6152Shenric #define _BD_POSTCALL 482bd12f793Sart 483745b6152Shenric static inline int 484745b6152Shenric bus_dmamap_create(bus_dma_tag_t t, bus_size_t s, int n, bus_size_t m, 485745b6152Shenric bus_size_t b, int f, bus_dmamap_t *p) 486745b6152Shenric { 487745b6152Shenric int r; 488745b6152Shenric const bus_dma_tag_t t0 = t; 489745b6152Shenric _BD_PRECALL(t, _dmamap_create); 490745b6152Shenric r = _BD_CALL(t, _dmamap_create)(t, t0, s, n, m, b, f, p); 491745b6152Shenric _BD_POSTCALL; 492745b6152Shenric return (r); 493745b6152Shenric } 494745b6152Shenric static inline void 495745b6152Shenric bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t p) 496745b6152Shenric { 497745b6152Shenric const bus_dma_tag_t t0 = t; 498745b6152Shenric _BD_PRECALL(t, _dmamap_destroy); 499745b6152Shenric _BD_CALL(t, _dmamap_destroy)(t, t0, p); 500745b6152Shenric _BD_POSTCALL; 501745b6152Shenric } 502745b6152Shenric static inline int 503745b6152Shenric bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t m, void *b, bus_size_t s, 504745b6152Shenric struct proc *p, int f) 505745b6152Shenric { 506745b6152Shenric const bus_dma_tag_t t0 = t; 507745b6152Shenric int r; 508745b6152Shenric _BD_PRECALL(t, _dmamap_load); 509745b6152Shenric r = _BD_CALL(t, _dmamap_load)(t, t0, m, b, s, p, f); 510745b6152Shenric _BD_POSTCALL; 511745b6152Shenric return (r); 512745b6152Shenric } 513745b6152Shenric static inline int 514745b6152Shenric bus_dmamap_load_mbuf(bus_dma_tag_t t, bus_dmamap_t m, struct mbuf *b, 515745b6152Shenric int f) 516745b6152Shenric { 517745b6152Shenric const bus_dma_tag_t t0 = t; 518745b6152Shenric int r; 519745b6152Shenric _BD_PRECALL(t, _dmamap_load_mbuf); 520745b6152Shenric r = _BD_CALL(t, _dmamap_load_mbuf)(t, t0, m, b, f); 521745b6152Shenric _BD_POSTCALL; 522745b6152Shenric return (r); 523745b6152Shenric } 524745b6152Shenric static inline int 525745b6152Shenric bus_dmamap_load_uio(bus_dma_tag_t t, bus_dmamap_t m, struct uio * u, int f) 526745b6152Shenric { 527745b6152Shenric const bus_dma_tag_t t0 = t; 528745b6152Shenric int r; 529745b6152Shenric _BD_PRECALL(t, _dmamap_load_uio); 530745b6152Shenric r = _BD_CALL(t, _dmamap_load_uio)(t, t0, m, u, f); 531745b6152Shenric _BD_POSTCALL; 532745b6152Shenric return (r); 533745b6152Shenric } 534745b6152Shenric static inline int 535745b6152Shenric bus_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t m, bus_dma_segment_t *sg, 536745b6152Shenric int n, bus_size_t s, int f) 537745b6152Shenric { 538745b6152Shenric const bus_dma_tag_t t0 = t; 539745b6152Shenric int r; 540745b6152Shenric _BD_PRECALL(t, _dmamap_load_raw); 541745b6152Shenric r = _BD_CALL(t, _dmamap_load_raw)(t, t0, m, sg, n, s, f); 542745b6152Shenric _BD_POSTCALL; 543745b6152Shenric return (r); 544745b6152Shenric } 545745b6152Shenric static inline void 546745b6152Shenric bus_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t p) 547745b6152Shenric { 548745b6152Shenric const bus_dma_tag_t t0 = t; 549745b6152Shenric _BD_PRECALL(t, _dmamap_unload); 550745b6152Shenric _BD_CALL(t, _dmamap_unload)(t, t0, p); 551745b6152Shenric _BD_POSTCALL; 552745b6152Shenric } 553745b6152Shenric static inline void 554745b6152Shenric bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t p, bus_addr_t o, bus_size_t l, 555745b6152Shenric int ops) 556745b6152Shenric { 557745b6152Shenric const bus_dma_tag_t t0 = t; 558745b6152Shenric _BD_PRECALL(t, _dmamap_sync); 559745b6152Shenric _BD_CALL(t, _dmamap_sync)(t, t0, p, o, l, ops); 560745b6152Shenric _BD_POSTCALL; 561745b6152Shenric } 562745b6152Shenric static inline int 563745b6152Shenric bus_dmamem_alloc(bus_dma_tag_t t, bus_size_t s, bus_size_t a, bus_size_t b, 564745b6152Shenric bus_dma_segment_t *sg, int n, int *r, int f) 565745b6152Shenric { 566745b6152Shenric const bus_dma_tag_t t0 = t; 567745b6152Shenric int ret; 568745b6152Shenric _BD_PRECALL(t, _dmamem_alloc); 569745b6152Shenric ret = _BD_CALL(t, _dmamem_alloc)(t, t0, s, a, b, sg, n, r, f); 570745b6152Shenric _BD_POSTCALL; 571745b6152Shenric return (ret); 572745b6152Shenric } 573745b6152Shenric static inline void 574745b6152Shenric bus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *sg, int n) 575745b6152Shenric { 576745b6152Shenric const bus_dma_tag_t t0 = t; 577745b6152Shenric _BD_PRECALL(t, _dmamem_free); 578745b6152Shenric _BD_CALL(t, _dmamem_free)(t, t0, sg, n); 579745b6152Shenric _BD_POSTCALL; 580745b6152Shenric } 581745b6152Shenric static inline int 582745b6152Shenric bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *sg, int n, size_t s, 583745b6152Shenric caddr_t *k, int f) 584745b6152Shenric { 585745b6152Shenric const bus_dma_tag_t t0 = t; 586745b6152Shenric int r; 587745b6152Shenric _BD_PRECALL(t, _dmamem_map); 588745b6152Shenric r = _BD_CALL(t, _dmamem_map)(t, t0, sg, n, s, k, f); 589745b6152Shenric _BD_POSTCALL; 590745b6152Shenric return (r); 591745b6152Shenric } 592745b6152Shenric static inline void 593745b6152Shenric bus_dmamem_unmap(bus_dma_tag_t t, caddr_t k, size_t s) 594745b6152Shenric { 595745b6152Shenric const bus_dma_tag_t t0 = t; 596745b6152Shenric _BD_PRECALL(t, _dmamem_unmap); 597745b6152Shenric _BD_CALL(t, _dmamem_unmap)(t, t0, k, s); 598745b6152Shenric _BD_POSTCALL; 599745b6152Shenric } 600745b6152Shenric static inline paddr_t 601745b6152Shenric bus_dmamem_mmap(bus_dma_tag_t t, bus_dma_segment_t *sg, int n, off_t o, int p, 602745b6152Shenric int f) 603745b6152Shenric { 604745b6152Shenric const bus_dma_tag_t t0 = t; 605745b6152Shenric int r; 606745b6152Shenric _BD_PRECALL(t, _dmamem_mmap); 607745b6152Shenric r = _BD_CALL(t, _dmamem_mmap)(t, t0, sg, n, o, p, f); 608745b6152Shenric _BD_POSTCALL; 609745b6152Shenric return (r); 610745b6152Shenric } 611bd12f793Sart 612bd12f793Sart /* 613bd12f793Sart * bus_dmamap_t 614bd12f793Sart * 615bd12f793Sart * Describes a DMA mapping. 616bd12f793Sart */ 617bd12f793Sart struct sparc_bus_dmamap { 618bd12f793Sart /* 6195cdd493aSjason * PRIVATE MEMBERS: not for use by machine-independent code. 620bd12f793Sart */ 6215cdd493aSjason bus_addr_t _dm_dvmastart; /* start and size of allocated */ 6225cdd493aSjason bus_size_t _dm_dvmasize; /* DVMA segment for this map */ 6235cdd493aSjason 624bd12f793Sart bus_size_t _dm_size; /* largest DMA transfer mappable */ 625bd12f793Sart bus_size_t _dm_maxsegsz; /* largest possible segment */ 626bd12f793Sart bus_size_t _dm_boundary; /* don't cross this */ 627bd12f793Sart int _dm_segcnt; /* number of segs this map can map */ 628bd12f793Sart int _dm_flags; /* misc. flags */ 629bd12f793Sart #define _DM_TYPE_LOAD 0 630bd12f793Sart #define _DM_TYPE_SEGS 1 631bd12f793Sart #define _DM_TYPE_UIO 2 632bd12f793Sart #define _DM_TYPE_MBUF 3 633745b6152Shenric int _dm_type; /* mapping type: raw, uio, mbuf, etc */ 634745b6152Shenric void *_dm_source; /* source mbuf/uio/etc. for unload */ 635bd12f793Sart 636bd12f793Sart void *_dm_cookie; /* cookie for bus-specific functions */ 637bd12f793Sart 638bd12f793Sart /* 639bd12f793Sart * PUBLIC MEMBERS: these are used by machine-independent code. 640bd12f793Sart */ 641bd12f793Sart bus_size_t dm_mapsize; /* size of the mapping */ 642bd12f793Sart int dm_nsegs; /* # valid segments in mapping */ 643745b6152Shenric 644bd12f793Sart bus_dma_segment_t dm_segs[1]; /* segments; variable length */ 645bd12f793Sart }; 646bd12f793Sart 647f56b290dSderaadt #endif /* _KERNEL */ 648f56b290dSderaadt 6492fa72412Spirofti #endif /* _MACHINE_BUS_H_ */ 650eb79e960Shenric 651