bus.h revision 39755
1279377Simp/* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */ 2279377Simp 3279377Simp/*- 4279377Simp * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. 5279377Simp * All rights reserved. 6279377Simp * 7279377Simp * This code is derived from software contributed to The NetBSD Foundation 8279377Simp * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9279377Simp * NASA Ames Research Center. 10279377Simp * 11279377Simp * Redistribution and use in source and binary forms, with or without 12279377Simp * modification, are permitted provided that the following conditions 13279377Simp * are met: 14279377Simp * 1. Redistributions of source code must retain the above copyright 15279377Simp * notice, this list of conditions and the following disclaimer. 16279377Simp * 2. Redistributions in binary form must reproduce the above copyright 17279377Simp * notice, this list of conditions and the following disclaimer in the 18279377Simp * documentation and/or other materials provided with the distribution. 19279377Simp * 3. All advertising materials mentioning features or use of this software 20279377Simp * must display the following acknowledgement: 21279377Simp * This product includes software developed by the NetBSD 22279377Simp * Foundation, Inc. and its contributors. 23279377Simp * 4. Neither the name of The NetBSD Foundation nor the names of its 24279377Simp * contributors may be used to endorse or promote products derived 25279377Simp * from this software without specific prior written permission. 26279377Simp * 27279377Simp * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28279377Simp * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29279377Simp * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30279377Simp * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31279377Simp * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32279377Simp * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33279377Simp * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34279377Simp * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35279377Simp * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36279377Simp * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37279377Simp * POSSIBILITY OF SUCH DAMAGE. 38279377Simp */ 39279377Simp 40279377Simp/* 41279377Simp * Copyright (c) 1996 Charles M. Hannum. All rights reserved. 42279377Simp * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. 43279377Simp * 44279377Simp * Redistribution and use in source and binary forms, with or without 45279377Simp * modification, are permitted provided that the following conditions 46279377Simp * are met: 47279377Simp * 1. Redistributions of source code must retain the above copyright 48279377Simp * notice, this list of conditions and the following disclaimer. 49279377Simp * 2. Redistributions in binary form must reproduce the above copyright 50279377Simp * notice, this list of conditions and the following disclaimer in the 51279377Simp * documentation and/or other materials provided with the distribution. 52279377Simp * 3. All advertising materials mentioning features or use of this software 53279377Simp * must display the following acknowledgement: 54279377Simp * This product includes software developed by Christopher G. Demetriou 55279377Simp * for the NetBSD Project. 56279377Simp * 4. The name of the author may not be used to endorse or promote products 57279377Simp * derived from this software without specific prior written permission 58279377Simp * 59279377Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 60279377Simp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 61279377Simp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 62279377Simp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 63279377Simp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 64279377Simp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 65279377Simp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 66279377Simp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 67279377Simp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 68279377Simp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 69279377Simp */ 70279377Simp/* $Id: bus.h,v 1.3 1998/05/06 01:45:47 gibbs Exp $ */ 71279377Simp 72279377Simp#ifndef _I386_BUS_H_ 73279377Simp#define _I386_BUS_H_ 74279377Simp 75279377Simp#include <machine/cpufunc.h> 76279377Simp 77279377Simp/* 78279377Simp * Values for the i386 bus space tag, not to be used directly by MI code. 79279377Simp */ 80279377Simp#define I386_BUS_SPACE_IO 0 /* space is i/o space */ 81279377Simp#define I386_BUS_SPACE_MEM 1 /* space is mem space */ 82279377Simp 83279377Simp/* 84279377Simp * Bus address and size types 85279377Simp */ 86279377Simptypedef u_int bus_addr_t; 87279377Simptypedef u_int bus_size_t; 88279377Simp 89279377Simp#define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF 90279377Simp#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF 91279377Simp#define BUS_SPACE_MAXSIZE (64 * 1024) /* Maximum supported size */ 92279377Simp#define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF 93279377Simp#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF 94279377Simp#define BUS_SPACE_MAXADDR 0xFFFFFFFF 95279377Simp 96279377Simp#define BUS_SPACE_UNRESTRICTED (~0) 97279377Simp 98279377Simp/* 99279377Simp * Access methods for bus resources and address space. 100279377Simp */ 101279377Simptypedef int bus_space_tag_t; 102279377Simptypedef u_int bus_space_handle_t; 103279377Simp 104279377Simp/* 105279377Simp * Map a region of device bus space into CPU virtual address space. 106279377Simp */ 107279377Simp 108279377Simp#define BUS_SPACE_MAP_CACHEABLE 0x01 109279377Simp#define BUS_SPACE_MAP_LINEAR 0x02 110279377Simp 111279377Simpint bus_space_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, 112279377Simp int flags, bus_space_handle_t *bshp); 113279377Simp 114279377Simp/* 115279377Simp * Unmap a region of device bus space. 116279377Simp */ 117279377Simp 118279377Simpvoid bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, 119279377Simp bus_size_t size); 120279377Simp 121279377Simp/* 122279377Simp * Get a new handle for a subregion of an already-mapped area of bus space. 123279377Simp */ 124279377Simp 125279377Simpint bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh, 126279377Simp bus_size_t offset, bus_size_t size, 127279377Simp bus_space_handle_t *nbshp); 128279377Simp 129279377Simp/* 130279377Simp * Allocate a region of memory that is accessible to devices in bus space. 131279377Simp */ 132279377Simp 133279377Simpint bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, 134279377Simp bus_addr_t rend, bus_size_t size, bus_size_t align, 135279377Simp bus_size_t boundary, int flags, bus_addr_t *addrp, 136279377Simp bus_space_handle_t *bshp); 137279377Simp 138279377Simp/* 139279377Simp * Free a region of bus space accessible memory. 140279377Simp */ 141279377Simp 142279377Simpvoid bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, 143279377Simp bus_size_t size); 144279377Simp 145279377Simp#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) 146279377Simp 147279377Simp/* 148279377Simp * Read a 1, 2, 4, or 8 byte quantity from bus space 149279377Simp * described by tag/handle/offset. 150279377Simp */ 151279377Simpstatic __inline u_int8_t bus_space_read_1(bus_space_tag_t tag, 152279377Simp bus_space_handle_t handle, 153279377Simp bus_size_t offset); 154279377Simp 155279377Simpstatic __inline u_int16_t bus_space_read_2(bus_space_tag_t tag, 156279377Simp bus_space_handle_t handle, 157279377Simp bus_size_t offset); 158279377Simp 159279377Simpstatic __inline u_int32_t bus_space_read_4(bus_space_tag_t tag, 160279377Simp bus_space_handle_t handle, 161279377Simp bus_size_t offset); 162279377Simp 163279377Simpstatic __inline u_int8_t 164279377Simpbus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle, 165279377Simp bus_size_t offset) 166279377Simp{ 167279377Simp#if defined (_I386_BUS_PIO_H_) 168279377Simp#if defined (_I386_BUS_MEMIO_H_) 169279377Simp if (tag == I386_BUS_SPACE_IO) 170279377Simp#endif 171279377Simp return (inb(handle + offset)); 172279377Simp#endif 173279377Simp#if defined (_I386_BUS_MEMIO_H_) 174279377Simp return (*(volatile u_int8_t *)(handle + offset)); 175279377Simp#endif 176279377Simp} 177279377Simp 178279377Simpstatic __inline u_int16_t 179279377Simpbus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle, 180279377Simp bus_size_t offset) 181279377Simp{ 182279377Simp#if defined(_I386_BUS_PIO_H_) 183279377Simp#if defined(_I386_BUS_MEMIO_H_) 184279377Simp if (tag == I386_BUS_SPACE_IO) 185279377Simp#endif 186279377Simp return (inw(handle + offset)); 187279377Simp#endif 188279377Simp#if defined(_I386_BUS_MEMIO_H_) 189279377Simp return (*(volatile u_int16_t *)(handle + offset)); 190279377Simp#endif 191279377Simp} 192279377Simp 193279377Simpstatic __inline u_int32_t 194279377Simpbus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle, 195279377Simp bus_size_t offset) 196279377Simp{ 197279377Simp#if defined(_I386_BUS_PIO_H_) 198279377Simp#if defined(_I386_BUS_MEMIO_H_) 199279377Simp if (tag == I386_BUS_SPACE_IO) 200279377Simp#endif 201279377Simp return (inl(handle + offset)); 202279377Simp#endif 203279377Simp#if defined(_I386_BUS_MEMIO_H_) 204279377Simp return (*(volatile u_int32_t *)(handle + offset)); 205279377Simp#endif 206279377Simp} 207279377Simp 208279377Simp#if 0 /* Cause a link error for bus_space_read_8 */ 209279377Simp#define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!! 210279377Simp#endif 211279377Simp 212279377Simp/* 213279377Simp * Read `count' 1, 2, 4, or 8 byte quantities from bus space 214279377Simp * described by tag/handle/offset and copy into buffer provided. 215279377Simp */ 216279377Simpstatic __inline void bus_space_read_multi_1(bus_space_tag_t tag, 217279377Simp bus_space_handle_t bsh, 218279377Simp bus_size_t offset, u_int8_t *addr, 219279377Simp size_t count); 220279377Simp 221279377Simpstatic __inline void bus_space_read_multi_2(bus_space_tag_t tag, 222279377Simp bus_space_handle_t bsh, 223279377Simp bus_size_t offset, u_int16_t *addr, 224279377Simp size_t count); 225279377Simp 226279377Simpstatic __inline void bus_space_read_multi_4(bus_space_tag_t tag, 227279377Simp bus_space_handle_t bsh, 228279377Simp bus_size_t offset, u_int32_t *addr, 229279377Simp size_t count); 230279377Simp 231279377Simpstatic __inline void 232279377Simpbus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 233279377Simp bus_size_t offset, u_int8_t *addr, size_t count) 234279377Simp{ 235279377Simp#if defined(_I386_BUS_PIO_H_) 236279377Simp#if defined(_I386_BUS_MEMIO_H_) 237279377Simp if (tag == I386_BUS_SPACE_IO) 238279377Simp#endif 239279377Simp insb(bsh + offset, addr, count); 240279377Simp#endif 241279377Simp#if defined(_I386_BUS_MEMIO_H_) 242279377Simp#if defined(_I386_BUS_PIO_H_) 243279377Simp else 244279377Simp#endif 245279377Simp { 246279377Simp int __x __asm__("%eax"); 247279377Simp __asm __volatile(" \n\ 248279377Simp cld \n\ 249279377Simp 1: movb (%1),%%al \n\ 250279377Simp stosb \n\ 251279377Simp loop 1b" : 252279377Simp "=&a" (__x) : 253279377Simp "r" (bsh + offset), "D" (addr), "c" (count) : 254279377Simp "%edi", "%ecx", "memory"); 255279377Simp } 256279377Simp#endif 257279377Simp} 258279377Simp 259279377Simpstatic __inline void 260279377Simpbus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 261279377Simp bus_size_t offset, u_int16_t *addr, size_t count) 262279377Simp{ 263279377Simp#if defined(_I386_BUS_PIO_H_) 264279377Simp#if defined(_I386_BUS_MEMIO_H_) 265279377Simp if (tag == I386_BUS_SPACE_IO) 266279377Simp#endif 267279377Simp insw(bsh + offset, addr, count); 268279377Simp#endif 269279377Simp#if defined(_I386_BUS_MEMIO_H_) 270279377Simp#if defined(_I386_BUS_PIO_H_) 271279377Simp else 272279377Simp#endif 273279377Simp { 274279377Simp int __x __asm__("%eax"); 275279377Simp __asm __volatile(" \n\ 276279377Simp cld \n\ 277279377Simp 1: movw (%1),%%ax \n\ 278279377Simp stosw \n\ 279279377Simp loop 1b" : 280279377Simp "=&a" (__x) : 281279377Simp "r" (bsh + offset), "D" (addr), "c" (count) : 282279377Simp "%edi", "%ecx", "memory"); 283279377Simp } 284279377Simp#endif 285279377Simp} 286279377Simp 287279377Simpstatic __inline void 288279377Simpbus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 289279377Simp bus_size_t offset, u_int32_t *addr, size_t count) 290279377Simp{ 291279377Simp#if defined(_I386_BUS_PIO_H_) 292279377Simp#if defined(_I386_BUS_MEMIO_H_) 293279377Simp if (tag == I386_BUS_SPACE_IO) 294279377Simp#endif 295279377Simp insl(bsh + offset, addr, count); 296279377Simp#endif 297279377Simp#if defined(_I386_BUS_MEMIO_H_) 298279377Simp#if defined(_I386_BUS_PIO_H_) 299279377Simp else 300279377Simp#endif 301279377Simp { 302279377Simp int __x __asm__("%eax"); 303279377Simp __asm __volatile(" \n\ 304279377Simp cld \n\ 305279377Simp 1: movl (%1),%%eax \n\ 306279377Simp stosl \n\ 307279377Simp loop 1b" : 308279377Simp "=&a" (__x) : 309279377Simp "r" (bsh + offset), "D" (addr), "c" (count) : 310279377Simp "%edi", "%ecx", "memory"); 311279377Simp } 312279377Simp#endif 313279377Simp} 314279377Simp 315279377Simp#if 0 /* Cause a link error for bus_space_read_multi_8 */ 316279377Simp#define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!! 317279377Simp#endif 318279377Simp 319279377Simp/* 320279377Simp * Read `count' 1, 2, 4, or 8 byte quantities from bus space 321279377Simp * described by tag/handle and starting at `offset' and copy into 322279377Simp * buffer provided. 323279377Simp */ 324279377Simpstatic __inline void bus_space_read_region_1(bus_space_tag_t tag, 325279377Simp bus_space_handle_t bsh, 326279377Simp bus_size_t offset, u_int8_t *addr, 327279377Simp size_t count); 328279377Simp 329279377Simpstatic __inline void bus_space_read_region_2(bus_space_tag_t tag, 330279377Simp bus_space_handle_t bsh, 331279377Simp bus_size_t offset, u_int16_t *addr, 332279377Simp size_t count); 333279377Simp 334279377Simpstatic __inline void bus_space_read_region_4(bus_space_tag_t tag, 335279377Simp bus_space_handle_t bsh, 336279377Simp bus_size_t offset, u_int32_t *addr, 337279377Simp size_t count); 338279377Simp 339279377Simp 340279377Simpstatic __inline void 341279377Simpbus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 342279377Simp bus_size_t offset, u_int8_t *addr, size_t count) 343279377Simp{ 344279377Simp#if defined(_I386_BUS_PIO_H_) 345279377Simp#if defined(_I386_BUS_MEMIO_H_) 346279377Simp if (tag == I386_BUS_SPACE_IO) 347279377Simp#endif 348279377Simp { 349279377Simp int __x __asm__("%eax"); 350279377Simp __asm __volatile(" \n\ 351279377Simp cld \n\ 352279377Simp 1: inb %w1,%%al \n\ 353279377Simp stosb \n\ 354279377Simp incl %1 \n\ 355279377Simp loop 1b" : 356279377Simp "=&a" (__x) : 357279377Simp "d" (bsh + offset), "D" (addr), "c" (count) : 358279377Simp "%edx", "%edi", "%ecx", "memory"); 359279377Simp } 360279377Simp#endif 361279377Simp#if defined(_I386_BUS_MEMIO_H_) 362279377Simp#if defined(_I386_BUS_PIO_H_) 363279377Simp else 364279377Simp#endif 365279377Simp { 366279377Simp __asm __volatile(" \n\ 367279377Simp cld \n\ 368279377Simp repne \n\ 369279377Simp movsb" : 370279377Simp : 371279377Simp "S" (bsh + offset), "D" (addr), "c" (count) : 372279377Simp "%esi", "%edi", "%ecx", "memory"); 373279377Simp } 374279377Simp#endif 375279377Simp} 376279377Simp 377279377Simpstatic __inline void 378279377Simpbus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 379279377Simp bus_size_t offset, u_int16_t *addr, size_t count) 380279377Simp{ 381279377Simp#if defined(_I386_BUS_PIO_H_) 382279377Simp#if defined(_I386_BUS_MEMIO_H_) 383279377Simp if (tag == I386_BUS_SPACE_IO) 384279377Simp#endif 385279377Simp { 386279377Simp int __x __asm__("%eax"); 387279377Simp __asm __volatile(" \n\ 388279377Simp cld \n\ 389279377Simp 1: inw %w1,%%ax \n\ 390279377Simp stosw \n\ 391279377Simp addl $2,%1 \n\ 392279377Simp loop 1b" : 393279377Simp "=&a" (__x) : 394279377Simp "d" (bsh + offset), "D" (addr), "c" (count) : 395279377Simp "%edx", "%edi", "%ecx", "memory"); 396279377Simp } 397279377Simp#endif 398279377Simp#if defined(_I386_BUS_MEMIO_H_) 399279377Simp#if defined(_I386_BUS_PIO_H_) 400279377Simp else 401279377Simp#endif 402279377Simp { 403279377Simp __asm __volatile(" \n\ 404279377Simp cld \n\ 405279377Simp repne \n\ 406279377Simp movsw" : 407279377Simp : 408279377Simp "S" (bsh + offset), "D" (addr), "c" (count) : 409279377Simp "%esi", "%edi", "%ecx", "memory"); 410279377Simp } 411279377Simp#endif 412279377Simp} 413279377Simp 414279377Simpstatic __inline void 415279377Simpbus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 416279377Simp bus_size_t offset, u_int32_t *addr, size_t count) 417279377Simp{ 418279377Simp#if defined(_I386_BUS_PIO_H_) 419279377Simp#if defined(_I386_BUS_MEMIO_H_) 420279377Simp if (tag == I386_BUS_SPACE_IO) 421279377Simp#endif 422279377Simp { 423279377Simp int __x __asm__("%eax"); 424279377Simp __asm __volatile(" \n\ 425279377Simp cld \n\ 426279377Simp 1: inl %w1,%%eax \n\ 427279377Simp stosl \n\ 428279377Simp addl $4,%1 \n\ 429279377Simp loop 1b" : 430279377Simp "=&a" (__x) : 431279377Simp "d" (bsh + offset), "D" (addr), "c" (count) : 432279377Simp "%edx", "%edi", "%ecx", "memory"); 433279377Simp } 434279377Simp#endif 435279377Simp#if defined(_I386_BUS_MEMIO_H_) 436279377Simp#if defined(_I386_BUS_PIO_H_) 437279377Simp else 438279377Simp#endif 439279377Simp { 440279377Simp __asm __volatile(" \n\ 441279377Simp cld \n\ 442279377Simp repne \n\ 443279377Simp movsl" : 444279377Simp : 445279377Simp "S" (bsh + offset), "D" (addr), "c" (count) : 446279377Simp "%esi", "%edi", "%ecx", "memory"); 447279377Simp } 448279377Simp#endif 449279377Simp} 450279377Simp 451279377Simp#if 0 /* Cause a link error for bus_space_read_region_8 */ 452279377Simp#define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!! 453279377Simp#endif 454279377Simp 455279377Simp/* 456279377Simp * Write the 1, 2, 4, or 8 byte value `value' to bus space 457279377Simp * described by tag/handle/offset. 458279377Simp */ 459279377Simp 460279377Simpstatic __inline void bus_space_write_1(bus_space_tag_t tag, 461279377Simp bus_space_handle_t bsh, 462279377Simp bus_size_t offset, u_int8_t value); 463279377Simp 464279377Simpstatic __inline void bus_space_write_2(bus_space_tag_t tag, 465279377Simp bus_space_handle_t bsh, 466279377Simp bus_size_t offset, u_int16_t value); 467279377Simp 468279377Simpstatic __inline void bus_space_write_4(bus_space_tag_t tag, 469279377Simp bus_space_handle_t bsh, 470279377Simp bus_size_t offset, u_int32_t value); 471279377Simp 472279377Simpstatic __inline void 473279377Simpbus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh, 474279377Simp bus_size_t offset, u_int8_t value) 475279377Simp{ 476279377Simp#if defined(_I386_BUS_PIO_H_) 477279377Simp#if defined(_I386_BUS_MEMIO_H_) 478279377Simp if (tag == I386_BUS_SPACE_IO) 479279377Simp#endif 480279377Simp outb(bsh + offset, value); 481#endif 482#if defined(_I386_BUS_MEMIO_H_) 483#if defined(_I386_BUS_PIO_H_) 484 else 485#endif 486 *(volatile u_int8_t *)(bsh + offset) = value; 487#endif 488} 489 490static __inline void 491bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh, 492 bus_size_t offset, u_int16_t value) 493{ 494#if defined(_I386_BUS_PIO_H_) 495#if defined(_I386_BUS_MEMIO_H_) 496 if (tag == I386_BUS_SPACE_IO) 497#endif 498 outw(bsh + offset, value); 499#endif 500#if defined(_I386_BUS_MEMIO_H_) 501#if defined(_I386_BUS_PIO_H_) 502 else 503#endif 504 *(volatile u_int16_t *)(bsh + offset) = value; 505#endif 506} 507 508static __inline void 509bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh, 510 bus_size_t offset, u_int32_t value) 511{ 512#if defined(_I386_BUS_PIO_H_) 513#if defined(_I386_BUS_MEMIO_H_) 514 if (tag == I386_BUS_SPACE_IO) 515#endif 516 outl(bsh + offset, value); 517#endif 518#if defined(_I386_BUS_MEMIO_H_) 519#if defined(_I386_BUS_PIO_H_) 520 else 521#endif 522 *(volatile u_int32_t *)(bsh + offset) = value; 523#endif 524} 525 526#if 0 /* Cause a link error for bus_space_write_8 */ 527#define bus_space_write_8 !!! bus_space_write_8 not implemented !!! 528#endif 529 530/* 531 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 532 * provided to bus space described by tag/handle/offset. 533 */ 534 535static __inline void bus_space_write_multi_1(bus_space_tag_t tag, 536 bus_space_handle_t bsh, 537 bus_size_t offset, 538 const u_int8_t *addr, 539 size_t count); 540static __inline void bus_space_write_multi_2(bus_space_tag_t tag, 541 bus_space_handle_t bsh, 542 bus_size_t offset, 543 const u_int16_t *addr, 544 size_t count); 545 546static __inline void bus_space_write_multi_4(bus_space_tag_t tag, 547 bus_space_handle_t bsh, 548 bus_size_t offset, 549 const u_int32_t *addr, 550 size_t count); 551 552static __inline void 553bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 554 bus_size_t offset, const u_int8_t *addr, size_t count) 555{ 556#if defined(_I386_BUS_PIO_H_) 557#if defined(_I386_BUS_MEMIO_H_) 558 if (tag == I386_BUS_SPACE_IO) 559#endif 560 outsb(bsh + offset, addr, count); 561#endif 562#if defined(_I386_BUS_MEMIO_H_) 563#if defined(_I386_BUS_PIO_H_) 564 else 565#endif 566 { 567 int __x __asm__("%eax"); 568 __asm __volatile(" \n\ 569 cld \n\ 570 1: lodsb \n\ 571 movb %%al,(%1) \n\ 572 loop 1b" : 573 "=&a" (__x) : 574 "r" (bsh + offset), "S" (addr), "c" (count) : 575 "%esi", "%ecx"); 576 } 577#endif 578} 579 580static __inline void 581bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 582 bus_size_t offset, const u_int16_t *addr, size_t count) 583{ 584#if defined(_I386_BUS_PIO_H_) 585#if defined(_I386_BUS_MEMIO_H_) 586 if (tag == I386_BUS_SPACE_IO) 587#endif 588 outsw(bsh + offset, addr, count); 589#endif 590#if defined(_I386_BUS_MEMIO_H_) 591#if defined(_I386_BUS_PIO_H_) 592 else 593#endif 594 { 595 int __x __asm__("%eax"); 596 __asm __volatile(" \n\ 597 cld \n\ 598 1: lodsw \n\ 599 movw %%ax,(%1) \n\ 600 loop 1b" : 601 "=&a" (__x) : 602 "r" (bsh + offset), "S" (addr), "c" (count) : 603 "%esi", "%ecx"); 604 } 605#endif 606} 607 608static __inline void 609bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 610 bus_size_t offset, const u_int32_t *addr, size_t count) 611{ 612#if defined(_I386_BUS_PIO_H_) 613#if defined(_I386_BUS_MEMIO_H_) 614 if (tag == I386_BUS_SPACE_IO) 615#endif 616 outsl(bsh + offset, addr, count); 617#endif 618#if defined(_I386_BUS_MEMIO_H_) 619#if defined(_I386_BUS_PIO_H_) 620 else 621#endif 622 { 623 int __x __asm__("%eax"); 624 __asm __volatile(" \n\ 625 cld \n\ 626 1: lodsl \n\ 627 movl %%eax,(%1) \n\ 628 loop 1b" : 629 "=&a" (__x) : 630 "r" (bsh + offset), "S" (addr), "c" (count) : 631 "%esi", "%ecx"); 632 } 633#endif 634} 635 636#if 0 /* Cause a link error for bus_space_write_multi_8 */ 637#define bus_space_write_multi_8(t, h, o, a, c) \ 638 !!! bus_space_write_multi_8 unimplemented !!! 639#endif 640 641/* 642 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 643 * to bus space described by tag/handle starting at `offset'. 644 */ 645 646static __inline void bus_space_write_region_1(bus_space_tag_t tag, 647 bus_space_handle_t bsh, 648 bus_size_t offset, 649 const u_int8_t *addr, 650 size_t count); 651static __inline void bus_space_write_region_2(bus_space_tag_t tag, 652 bus_space_handle_t bsh, 653 bus_size_t offset, 654 const u_int16_t *addr, 655 size_t count); 656static __inline void bus_space_write_region_4(bus_space_tag_t tag, 657 bus_space_handle_t bsh, 658 bus_size_t offset, 659 const u_int32_t *addr, 660 size_t count); 661 662static __inline void 663bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 664 bus_size_t offset, const u_int8_t *addr, size_t count) 665{ 666#if defined(_I386_BUS_PIO_H_) 667#if defined(_I386_BUS_MEMIO_H_) 668 if (tag == I386_BUS_SPACE_IO) 669#endif 670 { 671 int __x __asm__("%eax"); 672 __asm __volatile(" \n\ 673 cld \n\ 674 1: lodsb \n\ 675 outb %%al,%w1 \n\ 676 incl %1 \n\ 677 loop 1b" : 678 "=&a" (__x) : 679 "d" (bsh + offset), "S" (addr), "c" (count) : 680 "%edx", "%esi", "%ecx", "memory"); 681 } 682#endif 683#if defined(_I386_BUS_MEMIO_H_) 684#if defined(_I386_BUS_PIO_H_) 685 else 686#endif 687 { 688 __asm __volatile(" \n\ 689 cld \n\ 690 repne \n\ 691 movsb" : 692 : 693 "D" (bsh + offset), "S" (addr), "c" (count) : 694 "%edi", "%esi", "%ecx", "memory"); 695 } 696#endif 697} 698 699static __inline void 700bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 701 bus_size_t offset, const u_int16_t *addr, size_t count) 702{ 703#if defined(_I386_BUS_PIO_H_) 704#if defined(_I386_BUS_MEMIO_H_) 705 if (tag == I386_BUS_SPACE_IO) 706#endif 707 { 708 int __x __asm__("%eax"); 709 __asm __volatile(" \n\ 710 cld \n\ 711 1: lodsw \n\ 712 outw %%ax,%w1 \n\ 713 addl $2,%1 \n\ 714 loop 1b" : 715 "=&a" (__x) : 716 "d" (bsh + offset), "S" (addr), "c" (count) : 717 "%edx", "%esi", "%ecx", "memory"); 718 } 719#endif 720#if defined(_I386_BUS_MEMIO_H_) 721#if defined(_I386_BUS_PIO_H_) 722 else 723#endif 724 { 725 __asm __volatile(" \n\ 726 cld \n\ 727 repne \n\ 728 movsw" : 729 : 730 "D" (bsh + offset), "S" (addr), "c" (count) : 731 "%edi", "%esi", "%ecx", "memory"); 732 } 733#endif 734} 735 736static __inline void 737bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 738 bus_size_t offset, const u_int32_t *addr, size_t count) 739{ 740#if defined(_I386_BUS_PIO_H_) 741#if defined(_I386_BUS_MEMIO_H_) 742 if (tag == I386_BUS_SPACE_IO) 743#endif 744 { 745 int __x __asm__("%eax"); 746 __asm __volatile(" \n\ 747 cld \n\ 748 1: lodsl \n\ 749 outl %%eax,%w1 \n\ 750 addl $4,%1 \n\ 751 loop 1b" : 752 "=&a" (__x) : 753 "d" (bsh + offset), "S" (addr), "c" (count) : 754 "%edx", "%esi", "%ecx", "memory"); 755 } 756#endif 757#if defined(_I386_BUS_MEMIO_H_) 758#if defined(_I386_BUS_PIO_H_) 759 else 760#endif 761 { 762 __asm __volatile(" \n\ 763 cld \n\ 764 repne \n\ 765 movsl" : 766 : 767 "D" (bsh + offset), "S" (addr), "c" (count) : 768 "%edi", "%esi", "%ecx", "memory"); 769 } 770#endif 771} 772 773#if 0 /* Cause a link error for bus_space_write_region_8 */ 774#define bus_space_write_region_8 \ 775 !!! bus_space_write_region_8 unimplemented !!! 776#endif 777 778/* 779 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 780 * by tag/handle/offset `count' times. 781 */ 782 783static __inline void bus_space_set_multi_1(bus_space_tag_t tag, 784 bus_space_handle_t bsh, 785 bus_size_t offset, 786 u_int8_t value, size_t count); 787static __inline void bus_space_set_multi_2(bus_space_tag_t tag, 788 bus_space_handle_t bsh, 789 bus_size_t offset, 790 u_int16_t value, size_t count); 791static __inline void bus_space_set_multi_4(bus_space_tag_t tag, 792 bus_space_handle_t bsh, 793 bus_size_t offset, 794 u_int32_t value, size_t count); 795 796static __inline void 797bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 798 bus_size_t offset, u_int8_t value, size_t count) 799{ 800 bus_addr_t addr = bsh + offset; 801 802#if defined(_I386_BUS_PIO_H_) 803#if defined(_I386_BUS_MEMIO_H_) 804 if (tag == I386_BUS_SPACE_IO) 805#endif 806 while (count--) 807 outb(addr, value); 808#endif 809#if defined(_I386_BUS_MEMIO_H_) 810#if defined(_I386_BUS_PIO_H_) 811 else 812#endif 813 while (count--) 814 *(volatile u_int8_t *)(addr) = value; 815#endif 816} 817 818static __inline void 819bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 820 bus_size_t offset, u_int16_t value, size_t count) 821{ 822 bus_addr_t addr = bsh + offset; 823 824#if defined(_I386_BUS_PIO_H_) 825#if defined(_I386_BUS_MEMIO_H_) 826 if (tag == I386_BUS_SPACE_IO) 827#endif 828 while (count--) 829 outw(addr, value); 830#endif 831#if defined(_I386_BUS_MEMIO_H_) 832#if defined(_I386_BUS_PIO_H_) 833 else 834#endif 835 while (count--) 836 *(volatile u_int16_t *)(addr) = value; 837#endif 838} 839 840static __inline void 841bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 842 bus_size_t offset, u_int32_t value, size_t count) 843{ 844 bus_addr_t addr = bsh + offset; 845 846#if defined(_I386_BUS_PIO_H_) 847#if defined(_I386_BUS_MEMIO_H_) 848 if (tag == I386_BUS_SPACE_IO) 849#endif 850 while (count--) 851 outl(addr, value); 852#endif 853#if defined(_I386_BUS_MEMIO_H_) 854#if defined(_I386_BUS_PIO_H_) 855 else 856#endif 857 while (count--) 858 *(volatile u_int32_t *)(addr) = value; 859#endif 860} 861 862#if 0 /* Cause a link error for bus_space_set_multi_8 */ 863#define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!! 864#endif 865 866/* 867 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 868 * by tag/handle starting at `offset'. 869 */ 870 871static __inline void bus_space_set_region_1(bus_space_tag_t tag, 872 bus_space_handle_t bsh, 873 bus_size_t offset, u_int8_t value, 874 size_t count); 875static __inline void bus_space_set_region_2(bus_space_tag_t tag, 876 bus_space_handle_t bsh, 877 bus_size_t offset, u_int16_t value, 878 size_t count); 879static __inline void bus_space_set_region_4(bus_space_tag_t tag, 880 bus_space_handle_t bsh, 881 bus_size_t offset, u_int32_t value, 882 size_t count); 883 884static __inline void 885bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 886 bus_size_t offset, u_int8_t value, size_t count) 887{ 888 bus_addr_t addr = bsh + offset; 889 890#if defined(_I386_BUS_PIO_H_) 891#if defined(_I386_BUS_MEMIO_H_) 892 if (tag == I386_BUS_SPACE_IO) 893#endif 894 for (; count != 0; count--, addr++) 895 outb(addr, value); 896#endif 897#if defined(_I386_BUS_MEMIO_H_) 898#if defined(_I386_BUS_PIO_H_) 899 else 900#endif 901 for (; count != 0; count--, addr++) 902 *(volatile u_int8_t *)(addr) = value; 903#endif 904} 905 906static __inline void 907bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 908 bus_size_t offset, u_int16_t value, size_t count) 909{ 910 bus_addr_t addr = bsh + offset; 911 912#if defined(_I386_BUS_PIO_H_) 913#if defined(_I386_BUS_MEMIO_H_) 914 if (tag == I386_BUS_SPACE_IO) 915#endif 916 for (; count != 0; count--, addr += 2) 917 outw(addr, value); 918#endif 919#if defined(_I386_BUS_MEMIO_H_) 920#if defined(_I386_BUS_PIO_H_) 921 else 922#endif 923 for (; count != 0; count--, addr += 2) 924 *(volatile u_int16_t *)(addr) = value; 925#endif 926} 927 928static __inline void 929bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 930 bus_size_t offset, u_int32_t value, size_t count) 931{ 932 bus_addr_t addr = bsh + offset; 933 934#if defined(_I386_BUS_PIO_H_) 935#if defined(_I386_BUS_MEMIO_H_) 936 if (tag == I386_BUS_SPACE_IO) 937#endif 938 for (; count != 0; count--, addr += 4) 939 outl(addr, value); 940#endif 941#if defined(_I386_BUS_MEMIO_H_) 942#if defined(_I386_BUS_PIO_H_) 943 else 944#endif 945 for (; count != 0; count--, addr += 4) 946 *(volatile u_int32_t *)(addr) = value; 947#endif 948} 949 950#if 0 /* Cause a link error for bus_space_set_region_8 */ 951#define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!! 952#endif 953 954/* 955 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 956 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 957 */ 958 959static __inline void bus_space_copy_region_1(bus_space_tag_t tag, 960 bus_space_handle_t bsh1, 961 bus_size_t off1, 962 bus_space_handle_t bsh2, 963 bus_size_t off2, size_t count); 964 965static __inline void bus_space_copy_region_2(bus_space_tag_t tag, 966 bus_space_handle_t bsh1, 967 bus_size_t off1, 968 bus_space_handle_t bsh2, 969 bus_size_t off2, size_t count); 970 971static __inline void bus_space_copy_region_4(bus_space_tag_t tag, 972 bus_space_handle_t bsh1, 973 bus_size_t off1, 974 bus_space_handle_t bsh2, 975 bus_size_t off2, size_t count); 976 977static __inline void 978bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1, 979 bus_size_t off1, bus_space_handle_t bsh2, 980 bus_size_t off2, size_t count) 981{ 982 bus_addr_t addr1 = bsh1 + off1; 983 bus_addr_t addr2 = bsh2 + off2; 984 985#if defined(_I386_BUS_PIO_H_) 986#if defined(_I386_BUS_MEMIO_H_) 987 if (tag == I386_BUS_SPACE_IO) 988#endif 989 { 990 if (addr1 >= addr2) { 991 /* src after dest: copy forward */ 992 for (; count != 0; count--, addr1++, addr2++) 993 outb(addr2, inb(addr1)); 994 } else { 995 /* dest after src: copy backwards */ 996 for (addr1 += (count - 1), addr2 += (count - 1); 997 count != 0; count--, addr1--, addr2--) 998 outb(addr2, inb(addr1)); 999 } 1000 } 1001#endif 1002#if defined(_I386_BUS_MEMIO_H_) 1003#if defined(_I386_BUS_PIO_H_) 1004 else 1005#endif 1006 { 1007 if (addr1 >= addr2) { 1008 /* src after dest: copy forward */ 1009 for (; count != 0; count--, addr1++, addr2++) 1010 *(volatile u_int8_t *)(addr2) = 1011 *(volatile u_int8_t *)(addr1); 1012 } else { 1013 /* dest after src: copy backwards */ 1014 for (addr1 += (count - 1), addr2 += (count - 1); 1015 count != 0; count--, addr1--, addr2--) 1016 *(volatile u_int8_t *)(addr2) = 1017 *(volatile u_int8_t *)(addr1); 1018 } 1019 } 1020#endif 1021} 1022 1023static __inline void 1024bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1, 1025 bus_size_t off1, bus_space_handle_t bsh2, 1026 bus_size_t off2, size_t count) 1027{ 1028 bus_addr_t addr1 = bsh1 + off1; 1029 bus_addr_t addr2 = bsh2 + off2; 1030 1031#if defined(_I386_BUS_PIO_H_) 1032#if defined(_I386_BUS_MEMIO_H_) 1033 if (tag == I386_BUS_SPACE_IO) 1034#endif 1035 { 1036 if (addr1 >= addr2) { 1037 /* src after dest: copy forward */ 1038 for (; count != 0; count--, addr1 += 2, addr2 += 2) 1039 outw(addr2, inw(addr1)); 1040 } else { 1041 /* dest after src: copy backwards */ 1042 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); 1043 count != 0; count--, addr1 -= 2, addr2 -= 2) 1044 outw(addr2, inw(addr1)); 1045 } 1046 } 1047#endif 1048#if defined(_I386_BUS_MEMIO_H_) 1049#if defined(_I386_BUS_PIO_H_) 1050 else 1051#endif 1052 { 1053 if (addr1 >= addr2) { 1054 /* src after dest: copy forward */ 1055 for (; count != 0; count--, addr1 += 2, addr2 += 2) 1056 *(volatile u_int16_t *)(addr2) = 1057 *(volatile u_int16_t *)(addr1); 1058 } else { 1059 /* dest after src: copy backwards */ 1060 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); 1061 count != 0; count--, addr1 -= 2, addr2 -= 2) 1062 *(volatile u_int16_t *)(addr2) = 1063 *(volatile u_int16_t *)(addr1); 1064 } 1065 } 1066#endif 1067} 1068 1069static __inline void 1070bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1, 1071 bus_size_t off1, bus_space_handle_t bsh2, 1072 bus_size_t off2, size_t count) 1073{ 1074 bus_addr_t addr1 = bsh1 + off1; 1075 bus_addr_t addr2 = bsh2 + off2; 1076 1077#if defined(_I386_BUS_PIO_H_) 1078#if defined(_I386_BUS_MEMIO_H_) 1079 if (tag == I386_BUS_SPACE_IO) 1080#endif 1081 { 1082 if (addr1 >= addr2) { 1083 /* src after dest: copy forward */ 1084 for (; count != 0; count--, addr1 += 4, addr2 += 4) 1085 outl(addr2, inl(addr1)); 1086 } else { 1087 /* dest after src: copy backwards */ 1088 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); 1089 count != 0; count--, addr1 -= 4, addr2 -= 4) 1090 outl(addr2, inl(addr1)); 1091 } 1092 } 1093#endif 1094#if defined(_I386_BUS_MEMIO_H_) 1095#if defined(_I386_BUS_PIO_H_) 1096 else 1097#endif 1098 { 1099 if (addr1 >= addr2) { 1100 /* src after dest: copy forward */ 1101 for (; count != 0; count--, addr1 += 4, addr2 += 4) 1102 *(volatile u_int32_t *)(addr2) = 1103 *(volatile u_int32_t *)(addr1); 1104 } else { 1105 /* dest after src: copy backwards */ 1106 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); 1107 count != 0; count--, addr1 -= 4, addr2 -= 4) 1108 *(volatile u_int32_t *)(addr2) = 1109 *(volatile u_int32_t *)(addr1); 1110 } 1111 } 1112#endif 1113} 1114 1115#endif /* defined(_I386_BUS_PIO_H_) || defined(_I386_MEM_IO_H_) */ 1116 1117#if 0 /* Cause a link error for bus_space_copy_8 */ 1118#define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!! 1119#endif 1120 1121/* 1122 * Bus read/write barrier methods. 1123 * 1124 * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, 1125 * bus_size_t offset, bus_size_t len, int flags); 1126 * 1127 * Note: the i386 does not currently require barriers, but we must 1128 * provide the flags to MI code. 1129 */ 1130#define bus_space_barrier(t, h, o, l, f) \ 1131 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) 1132#define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 1133#define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 1134 1135/* 1136 * Flags used in various bus DMA methods. 1137 */ 1138#define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */ 1139#define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */ 1140#define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */ 1141#define BUS_DMAMEM_NOSYNC 0x04 /* map memory to not require sync */ 1142#define BUS_DMA_BUS1 0x10 /* placeholders for bus functions... */ 1143#define BUS_DMA_BUS2 0x20 1144#define BUS_DMA_BUS3 0x40 1145#define BUS_DMA_BUS4 0x80 1146 1147/* Forwards needed by prototypes below. */ 1148struct mbuf; 1149struct uio; 1150 1151/* 1152 * bus_dmasync_op_t 1153 * 1154 * Operations performed by bus_dmamap_sync(). 1155 */ 1156typedef enum { 1157 BUS_DMASYNC_PREREAD, 1158 BUS_DMASYNC_POSTREAD, 1159 BUS_DMASYNC_PREWRITE, 1160 BUS_DMASYNC_POSTWRITE 1161} bus_dmasync_op_t; 1162 1163/* 1164 * bus_dma_tag_t 1165 * 1166 * A machine-dependent opaque type describing the characteristics 1167 * of how to perform DMA mappings. This structure encapsultes 1168 * information concerning address and alignment restrictions, number 1169 * of S/G segments, amount of data per S/G segment, etc. 1170 */ 1171typedef struct bus_dma_tag *bus_dma_tag_t; 1172 1173/* 1174 * bus_dmamap_t 1175 * 1176 * DMA mapping instance information. 1177 */ 1178typedef struct bus_dmamap *bus_dmamap_t; 1179 1180/* 1181 * bus_dma_segment_t 1182 * 1183 * Describes a single contiguous DMA transaction. Values 1184 * are suitable for programming into DMA registers. 1185 */ 1186typedef struct bus_dma_segment { 1187 bus_addr_t ds_addr; /* DMA address */ 1188 bus_size_t ds_len; /* length of transfer */ 1189} bus_dma_segment_t; 1190 1191/* 1192 * A function that returns 1 if the address cannot be accessed by 1193 * a device and 0 if it can be. 1194 */ 1195typedef int bus_dma_filter_t(void *, bus_addr_t); 1196 1197/* 1198 * Allocate a device specific dma_tag encapsulating the constraints of 1199 * the parent tag in addition to other restrictions specified: 1200 * 1201 * alignment: alignment for segments. 1202 * boundary: Boundary that segments cannot cross. 1203 * lowaddr: Low restricted address that cannot appear in a mapping. 1204 * highaddr: High restricted address that cannot appear in a mapping. 1205 * filtfunc: An optional function to further test if an address 1206 * within the range of lowaddr and highaddr cannot appear 1207 * in a mapping. 1208 * filtfuncarg: An argument that will be passed to filtfunc in addition 1209 * to the address to test. 1210 * maxsize: Maximum mapping size supported by this tag. 1211 * nsegments: Number of discontinuities allowed in maps. 1212 * maxsegsz: Maximum size of a segment in the map. 1213 * flags: Bus DMA flags. 1214 * dmat: A pointer to set to a valid dma tag should the return 1215 * value of this function indicate success. 1216 */ 1217/* XXX Should probably allow specification of alignment */ 1218int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignemnt, 1219 bus_size_t boundary, bus_addr_t lowaddr, 1220 bus_addr_t highaddr, bus_dma_filter_t *filtfunc, 1221 void *filtfuncarg, bus_size_t maxsize, int nsegments, 1222 bus_size_t maxsegsz, int flags, bus_dma_tag_t *dmat); 1223 1224int bus_dma_tag_destroy(bus_dma_tag_t dmat); 1225 1226/* 1227 * Allocate a handle for mapping from kva/uva/physical 1228 * address space into bus device space. 1229 */ 1230int bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp); 1231 1232/* 1233 * Destroy a handle for mapping from kva/uva/physical 1234 * address space into bus device space. 1235 */ 1236int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map); 1237 1238/* 1239 * Allocate a piece of memory that can be efficiently mapped into 1240 * bus device space based on the constraints lited in the dma tag. 1241 * A dmamap to for use with dmamap_load is also allocated. 1242 */ 1243int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, 1244 bus_dmamap_t *mapp); 1245 1246/* 1247 * Free a piece of memory and it's allociated dmamap, that was allocated 1248 * via bus_dmamem_alloc. 1249 */ 1250void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map); 1251 1252/* 1253 * A function that processes a successfully loaded dma map or an error 1254 * from a delayed load map. 1255 */ 1256typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); 1257 1258/* 1259 * Map the buffer buf into bus space using the dmamap map. 1260 */ 1261int bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, 1262 bus_size_t buflen, bus_dmamap_callback_t *callback, 1263 void *callback_arg, int flags); 1264 1265/* 1266 * Perform a syncronization operation on the given map. 1267 */ 1268void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t); 1269#define bus_dmamap_sync(dmat, dmamap, op) \ 1270 if ((dmamap) != NULL) \ 1271 _bus_dmamap_sync(dmat, dmamap, op) 1272 1273/* 1274 * Release the mapping held by map. 1275 */ 1276void _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map); 1277#define bus_dmamap_unload(dmat, dmamap) \ 1278 if ((dmamap) != NULL) \ 1279 _bus_dmamap_unload(dmat, dmamap) 1280 1281#endif /* _I386_BUS_H_ */ 1282