The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/include/bus.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $    */
    2 
    3 /*-
    4  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
    9  * NASA Ames Research Center.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *      This product includes software developed by the NetBSD
   22  *      Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 /*
   41  * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
   42  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
   43  *
   44  * Redistribution and use in source and binary forms, with or without
   45  * modification, are permitted provided that the following conditions
   46  * are met:
   47  * 1. Redistributions of source code must retain the above copyright
   48  *    notice, this list of conditions and the following disclaimer.
   49  * 2. Redistributions in binary form must reproduce the above copyright
   50  *    notice, this list of conditions and the following disclaimer in the
   51  *    documentation and/or other materials provided with the distribution.
   52  * 3. All advertising materials mentioning features or use of this software
   53  *    must display the following acknowledgement:
   54  *      This product includes software developed by Christopher G. Demetriou
   55  *      for the NetBSD Project.
   56  * 4. The name of the author may not be used to endorse or promote products
   57  *    derived from this software without specific prior written permission
   58  *
   59  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   60  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   61  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   62  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   63  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   64  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   65  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   66  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   67  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   68  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   69  */
   70 /* $FreeBSD$ */
   71 
   72 #ifndef _I386_BUS_H_
   73 #define _I386_BUS_H_
   74 
   75 #include <machine/cpufunc.h>
   76 
   77 /*
   78  * Values for the i386 bus space tag, not to be used directly by MI code.
   79  */
   80 #define I386_BUS_SPACE_IO       0       /* space is i/o space */
   81 #define I386_BUS_SPACE_MEM      1       /* space is mem space */
   82 
   83 /*
   84  * Bus address and size types
   85  */
   86 typedef u_int bus_addr_t;
   87 typedef u_int bus_size_t;
   88 
   89 #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
   90 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
   91 #define BUS_SPACE_MAXSIZE       (64 * 1024) /* Maximum supported size */
   92 #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
   93 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
   94 #define BUS_SPACE_MAXADDR       0xFFFFFFFF
   95 
   96 #define BUS_SPACE_UNRESTRICTED  (~0)
   97 
   98 /*
   99  * Access methods for bus resources and address space.
  100  */
  101 typedef int bus_space_tag_t;
  102 typedef u_int bus_space_handle_t;
  103 
  104 /*
  105  * Map a region of device bus space into CPU virtual address space.
  106  */
  107 
  108 #define BUS_SPACE_MAP_CACHEABLE         0x01
  109 #define BUS_SPACE_MAP_LINEAR            0x02
  110 
  111 int     bus_space_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
  112                       int flags, bus_space_handle_t *bshp);
  113 
  114 /*
  115  * Unmap a region of device bus space.
  116  */
  117 
  118 void    bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
  119                         bus_size_t size);
  120 
  121 /*
  122  * Get a new handle for a subregion of an already-mapped area of bus space.
  123  */
  124 
  125 int     bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
  126                             bus_size_t offset, bus_size_t size,
  127                             bus_space_handle_t *nbshp);
  128 
  129 /*
  130  * Allocate a region of memory that is accessible to devices in bus space.
  131  */
  132 
  133 int     bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
  134                         bus_addr_t rend, bus_size_t size, bus_size_t align,
  135                         bus_size_t boundary, int flags, bus_addr_t *addrp,
  136                         bus_space_handle_t *bshp);
  137 
  138 /*
  139  * Free a region of bus space accessible memory.
  140  */
  141 
  142 void    bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
  143                        bus_size_t size);
  144 
  145 #if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_)
  146 
  147 /*
  148  * Read a 1, 2, 4, or 8 byte quantity from bus space
  149  * described by tag/handle/offset.
  150  */
  151 static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
  152                                           bus_space_handle_t handle,
  153                                           bus_size_t offset);
  154 
  155 static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
  156                                            bus_space_handle_t handle,
  157                                            bus_size_t offset);
  158 
  159 static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
  160                                            bus_space_handle_t handle,
  161                                            bus_size_t offset);
  162 
  163 static __inline u_int8_t
  164 bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
  165                  bus_size_t offset)
  166 {
  167 #if defined (_I386_BUS_PIO_H_)
  168 #if defined (_I386_BUS_MEMIO_H_)
  169         if (tag == I386_BUS_SPACE_IO)
  170 #endif
  171                 return (inb(handle + offset));
  172 #endif
  173 #if defined (_I386_BUS_MEMIO_H_)
  174         return (*(volatile u_int8_t *)(handle + offset));
  175 #endif
  176 }
  177 
  178 static __inline u_int16_t
  179 bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
  180                  bus_size_t offset)
  181 {
  182 #if defined(_I386_BUS_PIO_H_)
  183 #if defined(_I386_BUS_MEMIO_H_)
  184         if (tag == I386_BUS_SPACE_IO)
  185 #endif
  186                 return (inw(handle + offset));
  187 #endif
  188 #if defined(_I386_BUS_MEMIO_H_)
  189         return (*(volatile u_int16_t *)(handle + offset));
  190 #endif
  191 }
  192 
  193 static __inline u_int32_t
  194 bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
  195                  bus_size_t offset)
  196 {
  197 #if defined(_I386_BUS_PIO_H_)
  198 #if defined(_I386_BUS_MEMIO_H_)
  199         if (tag == I386_BUS_SPACE_IO)
  200 #endif
  201                 return (inl(handle + offset));
  202 #endif
  203 #if defined(_I386_BUS_MEMIO_H_)
  204         return (*(volatile u_int32_t *)(handle + offset));
  205 #endif
  206 }
  207 
  208 #if 0   /* Cause a link error for bus_space_read_8 */
  209 #define bus_space_read_8(t, h, o)       !!! bus_space_read_8 unimplemented !!!
  210 #endif
  211 
  212 /*
  213  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
  214  * described by tag/handle/offset and copy into buffer provided.
  215  */
  216 static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
  217                                             bus_space_handle_t bsh,
  218                                             bus_size_t offset, u_int8_t *addr,
  219                                             size_t count);
  220 
  221 static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
  222                                             bus_space_handle_t bsh,
  223                                             bus_size_t offset, u_int16_t *addr,
  224                                             size_t count);
  225 
  226 static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
  227                                             bus_space_handle_t bsh,
  228                                             bus_size_t offset, u_int32_t *addr,
  229                                             size_t count);
  230 
  231 static __inline void
  232 bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
  233                        bus_size_t offset, u_int8_t *addr, size_t count)
  234 {
  235 #if defined(_I386_BUS_PIO_H_)
  236 #if defined(_I386_BUS_MEMIO_H_)
  237         if (tag == I386_BUS_SPACE_IO)
  238 #endif
  239                 insb(bsh + offset, addr, count);
  240 #endif
  241 #if defined(_I386_BUS_MEMIO_H_)
  242 #if defined(_I386_BUS_PIO_H_)
  243         else
  244 #endif
  245         {
  246                 int __x __asm__("%eax");
  247                 __asm __volatile("                              \n\
  248                         cld                                     \n\
  249                 1:      movb (%1),%%al                          \n\
  250                         stosb                                   \n\
  251                         loop 1b"                                :
  252                     "=&a" (__x)                                 :
  253                     "r" (bsh + offset), "D" (addr), "c" (count) :
  254                     "%edi", "%ecx", "memory");
  255         }
  256 #endif
  257 }
  258 
  259 static __inline void
  260 bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
  261                        bus_size_t offset, u_int16_t *addr, size_t count)
  262 {
  263 #if defined(_I386_BUS_PIO_H_)
  264 #if defined(_I386_BUS_MEMIO_H_)
  265         if (tag == I386_BUS_SPACE_IO)
  266 #endif
  267                 insw(bsh + offset, addr, count);
  268 #endif
  269 #if defined(_I386_BUS_MEMIO_H_)
  270 #if defined(_I386_BUS_PIO_H_)
  271         else
  272 #endif
  273         {
  274                 int __x __asm__("%eax");
  275                 __asm __volatile("                              \n\
  276                         cld                                     \n\
  277                 1:      movw (%1),%%ax                          \n\
  278                         stosw                                   \n\
  279                         loop 1b"                                :
  280                     "=&a" (__x)                                 :
  281                     "r" (bsh + offset), "D" (addr), "c" (count) :
  282                     "%edi", "%ecx", "memory");
  283         }
  284 #endif
  285 }
  286 
  287 static __inline void
  288 bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
  289                        bus_size_t offset, u_int32_t *addr, size_t count)
  290 {
  291 #if defined(_I386_BUS_PIO_H_)
  292 #if defined(_I386_BUS_MEMIO_H_)
  293         if (tag == I386_BUS_SPACE_IO)
  294 #endif
  295                 insl(bsh + offset, addr, count);
  296 #endif
  297 #if defined(_I386_BUS_MEMIO_H_)
  298 #if defined(_I386_BUS_PIO_H_)
  299         else
  300 #endif
  301         {
  302                 int __x __asm__("%eax");
  303                 __asm __volatile("                              \n\
  304                         cld                                     \n\
  305                 1:      movl (%1),%%eax                         \n\
  306                         stosl                                   \n\
  307                         loop 1b"                                :
  308                     "=&a" (__x)                                 :
  309                     "r" (bsh + offset), "D" (addr), "c" (count) :
  310                     "%edi", "%ecx", "memory");
  311         }
  312 #endif
  313 }
  314 
  315 #if 0   /* Cause a link error for bus_space_read_multi_8 */
  316 #define bus_space_read_multi_8  !!! bus_space_read_multi_8 unimplemented !!!
  317 #endif
  318 
  319 /*
  320  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
  321  * described by tag/handle and starting at `offset' and copy into
  322  * buffer provided.
  323  */
  324 static __inline void bus_space_read_region_1(bus_space_tag_t tag,
  325                                              bus_space_handle_t bsh,
  326                                              bus_size_t offset, u_int8_t *addr,
  327                                              size_t count);
  328 
  329 static __inline void bus_space_read_region_2(bus_space_tag_t tag,
  330                                              bus_space_handle_t bsh,
  331                                              bus_size_t offset, u_int16_t *addr,
  332                                              size_t count);
  333 
  334 static __inline void bus_space_read_region_4(bus_space_tag_t tag,
  335                                              bus_space_handle_t bsh,
  336                                              bus_size_t offset, u_int32_t *addr,
  337                                              size_t count);
  338 
  339 
  340 static __inline void
  341 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
  342                         bus_size_t offset, u_int8_t *addr, size_t count)
  343 {
  344 #if defined(_I386_BUS_PIO_H_)
  345 #if defined(_I386_BUS_MEMIO_H_)
  346         if (tag == I386_BUS_SPACE_IO)
  347 #endif
  348         {
  349                 int __x __asm__("%eax");
  350                 __asm __volatile("                              \n\
  351                         cld                                     \n\
  352                 1:      inb %w1,%%al                            \n\
  353                         stosb                                   \n\
  354                         incl %1                                 \n\
  355                         loop 1b"                                :
  356                     "=&a" (__x)                                 :
  357                     "d" (bsh + offset), "D" (addr), "c" (count) :
  358                     "%edx", "%edi", "%ecx", "memory");
  359         }
  360 #endif
  361 #if defined(_I386_BUS_MEMIO_H_)
  362 #if defined(_I386_BUS_PIO_H_)
  363         else
  364 #endif
  365         {
  366                 __asm __volatile("                              \n\
  367                         cld                                     \n\
  368                         repne                                   \n\
  369                         movsb"                                  :
  370                                                                 :
  371                     "S" (bsh + offset), "D" (addr), "c" (count) :
  372                     "%esi", "%edi", "%ecx", "memory");
  373         }
  374 #endif
  375 }
  376 
  377 static __inline void
  378 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
  379                         bus_size_t offset, u_int16_t *addr, size_t count)
  380 {
  381 #if defined(_I386_BUS_PIO_H_)
  382 #if defined(_I386_BUS_MEMIO_H_)
  383         if (tag == I386_BUS_SPACE_IO)
  384 #endif
  385         {
  386                 int __x __asm__("%eax");
  387                 __asm __volatile("                              \n\
  388                         cld                                     \n\
  389                 1:      inw %w1,%%ax                            \n\
  390                         stosw                                   \n\
  391                         addl $2,%1                              \n\
  392                         loop 1b"                                :
  393                     "=&a" (__x)                                 :
  394                     "d" (bsh + offset), "D" (addr), "c" (count) :
  395                     "%edx", "%edi", "%ecx", "memory");
  396         }
  397 #endif
  398 #if defined(_I386_BUS_MEMIO_H_)
  399 #if defined(_I386_BUS_PIO_H_)
  400         else
  401 #endif
  402         {
  403                 __asm __volatile("                              \n\
  404                         cld                                     \n\
  405                         repne                                   \n\
  406                         movsw"                                  :
  407                                                                 :
  408                     "S" (bsh + offset), "D" (addr), "c" (count) :
  409                     "%esi", "%edi", "%ecx", "memory");
  410         }
  411 #endif
  412 }
  413 
  414 static __inline void
  415 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
  416                         bus_size_t offset, u_int32_t *addr, size_t count)
  417 {
  418 #if defined(_I386_BUS_PIO_H_)
  419 #if defined(_I386_BUS_MEMIO_H_)
  420         if (tag == I386_BUS_SPACE_IO)
  421 #endif
  422         {
  423                 int __x __asm__("%eax");
  424                 __asm __volatile("                              \n\
  425                         cld                                     \n\
  426                 1:      inl %w1,%%eax                           \n\
  427                         stosl                                   \n\
  428                         addl $4,%1                              \n\
  429                         loop 1b"                                :
  430                     "=&a" (__x)                                 :
  431                     "d" (bsh + offset), "D" (addr), "c" (count) :
  432                     "%edx", "%edi", "%ecx", "memory");
  433         }
  434 #endif
  435 #if defined(_I386_BUS_MEMIO_H_)
  436 #if defined(_I386_BUS_PIO_H_)
  437         else
  438 #endif
  439         {
  440                 __asm __volatile("                              \n\
  441                         cld                                     \n\
  442                         repne                                   \n\
  443                         movsl"                                  :
  444                                                                 :
  445                     "S" (bsh + offset), "D" (addr), "c" (count) :
  446                     "%esi", "%edi", "%ecx", "memory");
  447         }
  448 #endif
  449 }
  450 
  451 #if 0   /* Cause a link error for bus_space_read_region_8 */
  452 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
  453 #endif
  454 
  455 /*
  456  * Write the 1, 2, 4, or 8 byte value `value' to bus space
  457  * described by tag/handle/offset.
  458  */
  459 
  460 static __inline void bus_space_write_1(bus_space_tag_t tag,
  461                                        bus_space_handle_t bsh,
  462                                        bus_size_t offset, u_int8_t value);
  463 
  464 static __inline void bus_space_write_2(bus_space_tag_t tag,
  465                                        bus_space_handle_t bsh,
  466                                        bus_size_t offset, u_int16_t value);
  467 
  468 static __inline void bus_space_write_4(bus_space_tag_t tag,
  469                                        bus_space_handle_t bsh,
  470                                        bus_size_t offset, u_int32_t value);
  471 
  472 static __inline void
  473 bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
  474                        bus_size_t offset, u_int8_t value)
  475 {
  476 #if defined(_I386_BUS_PIO_H_)
  477 #if defined(_I386_BUS_MEMIO_H_)
  478         if (tag == I386_BUS_SPACE_IO)
  479 #endif
  480                 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 
  490 static __inline void
  491 bus_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 
  508 static __inline void
  509 bus_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 
  535 static __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);
  540 static __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 
  546 static __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 
  552 static __inline void
  553 bus_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 
  580 static __inline void
  581 bus_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 
  608 static __inline void
  609 bus_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 
  646 static __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);
  651 static __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);
  656 static __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 
  662 static __inline void
  663 bus_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 
  699 static __inline void
  700 bus_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 
  736 static __inline void
  737 bus_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 
  783 static __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);
  787 static __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);
  791 static __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 
  796 static __inline void
  797 bus_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 
  818 static __inline void
  819 bus_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 
  840 static __inline void
  841 bus_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 
  871 static __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);
  875 static __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);
  879 static __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 
  884 static __inline void
  885 bus_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 
  906 static __inline void
  907 bus_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 
  928 static __inline void
  929 bus_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 
  959 static __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 
  965 static __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 
  971 static __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 
  977 static __inline void
  978 bus_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 
 1023 static __inline void
 1024 bus_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 
 1069 static __inline void
 1070 bus_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. */
 1148 struct mbuf;
 1149 struct uio;
 1150 
 1151 /*
 1152  *      bus_dmasync_op_t
 1153  *
 1154  *      Operations performed by bus_dmamap_sync().
 1155  */
 1156 typedef 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  */
 1171 typedef struct bus_dma_tag      *bus_dma_tag_t;
 1172 
 1173 /*
 1174  *      bus_dmamap_t
 1175  *
 1176  *      DMA mapping instance information.
 1177  */
 1178 typedef 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  */
 1186 typedef 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  */
 1195 typedef 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 */
 1218 int 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 
 1224 int 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  */
 1230 int 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  */
 1236 int 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  */
 1243 int 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  */
 1250 void 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  */
 1256 typedef 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  */
 1261 int 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  */
 1268 void _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  */
 1276 void _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_ */

Cache object: 6519422e8b241b1329a66520ca074d66


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.