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/arch/x86/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.11 2006/02/16 20:17:15 perry Exp $   */
    2 
    3 /*-
    4  * Copyright (c) 1996, 1997, 1998, 2001 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 
   71 #ifndef _X86_BUS_H_
   72 #define _X86_BUS_H_
   73 
   74 #include <machine/pio.h>
   75 #include <machine/cpufunc.h>    /* for x86_lfence */
   76 
   77 #ifdef BUS_SPACE_DEBUG
   78 #include <sys/systm.h> /* for printf() prototype */
   79 /*
   80  * Macros for sanity-checking the aligned-ness of pointers passed to
   81  * bus space ops.  These are not strictly necessary on the x86, but
   82  * could lead to performance improvements, and help catch problems
   83  * with drivers that would creep up on other architectures.
   84  */
   85 #define __BUS_SPACE_ALIGNED_ADDRESS(p, t)                               \
   86         ((((u_long)(p)) & (sizeof(t)-1)) == 0)
   87 
   88 #define __BUS_SPACE_ADDRESS_SANITY(p, t, d)                             \
   89 ({                                                                      \
   90         if (__BUS_SPACE_ALIGNED_ADDRESS((p), t) == 0) {                 \
   91                 printf("%s 0x%lx not aligned to %d bytes %s:%d\n",      \
   92                     d, (u_long)(p), sizeof(t), __FILE__, __LINE__);     \
   93         }                                                               \
   94         (void) 0;                                                       \
   95 })
   96 
   97 #define BUS_SPACE_ALIGNED_POINTER(p, t) __BUS_SPACE_ALIGNED_ADDRESS(p, t)
   98 #else
   99 #define __BUS_SPACE_ADDRESS_SANITY(p,t,d)       (void) 0
  100 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
  101 #endif /* BUS_SPACE_DEBUG */
  102 
  103 /*
  104  * Values for the x86 bus space tag, not to be used directly by MI code.
  105  */
  106 #define X86_BUS_SPACE_IO        0       /* space is i/o space */
  107 #define X86_BUS_SPACE_MEM       1       /* space is mem space */
  108 
  109 #define __BUS_SPACE_HAS_STREAM_METHODS 1
  110 
  111 /*
  112  * Bus address and size types
  113  */
  114 typedef u_long bus_addr_t;
  115 typedef u_long bus_size_t;
  116 
  117 /*
  118  * Access methods for bus resources and address space.
  119  */
  120 typedef int bus_space_tag_t;
  121 typedef u_long bus_space_handle_t;
  122 
  123 /*
  124  *      int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
  125  *          bus_size_t size, int flags, bus_space_handle_t *bshp);
  126  *
  127  * Map a region of bus space.
  128  */
  129 
  130 #define BUS_SPACE_MAP_CACHEABLE         0x01
  131 #define BUS_SPACE_MAP_LINEAR            0x02
  132 #define BUS_SPACE_MAP_PREFETCHABLE      0x04
  133 
  134 int     x86_memio_map(bus_space_tag_t t, bus_addr_t addr,
  135             bus_size_t size, int flags, bus_space_handle_t *bshp);
  136 /* like map, but without extent map checking/allocation */
  137 int     _x86_memio_map(bus_space_tag_t t, bus_addr_t addr,
  138             bus_size_t size, int flags, bus_space_handle_t *bshp);
  139 
  140 #define bus_space_map(t, a, s, f, hp)                                   \
  141         x86_memio_map((t), (a), (s), (f), (hp))
  142 
  143 /*
  144  *      int bus_space_unmap(bus_space_tag_t t,
  145  *          bus_space_handle_t bsh, bus_size_t size);
  146  *
  147  * Unmap a region of bus space.
  148  */
  149 
  150 void    x86_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
  151             bus_size_t size);
  152 void    _x86_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
  153             bus_size_t size, bus_addr_t *);
  154 
  155 #define bus_space_unmap(t, h, s)                                        \
  156         x86_memio_unmap((t), (h), (s))
  157 
  158 /*
  159  *      int bus_space_subregion(bus_space_tag_t t,
  160  *          bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
  161  *          bus_space_handle_t *nbshp);
  162  *
  163  * Get a new handle for a subregion of an already-mapped area of bus space.
  164  */
  165 
  166 int     x86_memio_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
  167             bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp);
  168 
  169 #define bus_space_subregion(t, h, o, s, nhp)                            \
  170         x86_memio_subregion((t), (h), (o), (s), (nhp))
  171 
  172 /*
  173  *      int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
  174  *          bus_addr_t rend, bus_size_t size, bus_size_t align,
  175  *          bus_size_t boundary, int flags, bus_addr_t *addrp,
  176  *          bus_space_handle_t *bshp);
  177  *
  178  * Allocate a region of bus space.
  179  */
  180 
  181 int     x86_memio_alloc(bus_space_tag_t t, bus_addr_t rstart,
  182             bus_addr_t rend, bus_size_t size, bus_size_t align,
  183             bus_size_t boundary, int flags, bus_addr_t *addrp,
  184             bus_space_handle_t *bshp);
  185 
  186 #define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)                  \
  187         x86_memio_alloc((t), (rs), (re), (s), (a), (b), (f), (ap), (hp))
  188 
  189 /*
  190  *      int bus_space_free(bus_space_tag_t t,
  191  *          bus_space_handle_t bsh, bus_size_t size);
  192  *
  193  * Free a region of bus space.
  194  */
  195 
  196 void    x86_memio_free(bus_space_tag_t t, bus_space_handle_t bsh,
  197             bus_size_t size);
  198 
  199 #define bus_space_free(t, h, s)                                         \
  200         x86_memio_free((t), (h), (s))
  201 
  202 /*
  203  *      void *bus_space_vaddr(bus_space_tag_t, bus_space_handle_t);
  204  *
  205  * Get the kernel virtual address for the mapped bus space.
  206  * Only allowed for regions mapped with BUS_SPACE_MAP_LINEAR.
  207  *  (XXX not enforced)
  208  */
  209 #define bus_space_vaddr(t, h) \
  210         ((t) == X86_BUS_SPACE_MEM ? (void *)(h) : (void *)0)
  211 
  212 /*
  213  *      paddr_t bus_space_mmap(bus_space_tag_t t, bus_addr_t base,
  214  *          off_t offset, int prot, int flags);
  215  *
  216  * Mmap an area of bus space.
  217  */
  218 
  219 paddr_t x86_memio_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int);
  220 
  221 #define bus_space_mmap(t, b, o, p, f)                                   \
  222         x86_memio_mmap((t), (b), (o), (p), (f))
  223 
  224 /*
  225  *      u_intN_t bus_space_read_N(bus_space_tag_t tag,
  226  *          bus_space_handle_t bsh, bus_size_t offset);
  227  *
  228  * Read a 1, 2, 4, or 8 byte quantity from bus space
  229  * described by tag/handle/offset.
  230  */
  231 
  232 #define bus_space_read_1(t, h, o)                                       \
  233         ((t) == X86_BUS_SPACE_IO ? (inb((h) + (o))) :\
  234             (*(volatile u_int8_t *)((h) + (o))))
  235 
  236 #define bus_space_read_2(t, h, o)                                       \
  237          (__BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int16_t, "bus addr"), \
  238           ((t) == X86_BUS_SPACE_IO ? (inw((h) + (o))) :         \
  239             (*(volatile u_int16_t *)((h) + (o)))))
  240 
  241 #define bus_space_read_4(t, h, o)                                       \
  242          (__BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int32_t, "bus addr"), \
  243           ((t) == X86_BUS_SPACE_IO ? (inl((h) + (o))) :         \
  244             (*(volatile u_int32_t *)((h) + (o)))))
  245 
  246 #define bus_space_read_stream_1 bus_space_read_1
  247 #define bus_space_read_stream_2 bus_space_read_2
  248 #define bus_space_read_stream_4 bus_space_read_4
  249 
  250 #if 0   /* Cause a link error for bus_space_read_8 */
  251 #define bus_space_read_8(t, h, o)       !!! bus_space_read_8 unimplemented !!!
  252 #define bus_space_read_stream_8(t, h, o)        \
  253                 !!! bus_space_read_stream_8 unimplemented !!!
  254 #endif
  255 
  256 /*
  257  *      void bus_space_read_multi_N(bus_space_tag_t tag,
  258  *          bus_space_handle_t bsh, bus_size_t offset,
  259  *          u_intN_t *addr, size_t count);
  260  *
  261  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
  262  * described by tag/handle/offset and copy into buffer provided.
  263  */
  264 
  265 #define bus_space_read_multi_1(t, h, o, ptr, cnt)                       \
  266 do {                                                                    \
  267         if ((t) == X86_BUS_SPACE_IO) {                                  \
  268                 insb((h) + (o), (ptr), (cnt));                          \
  269         } else {                                                        \
  270                 void *dummy1;                                           \
  271                 int dummy2;                                             \
  272                 void *dummy3;                                           \
  273                 int __x;                                                \
  274                 __asm volatile("                                        \
  275                         cld                                     ;       \
  276                 1:      movb (%2),%%al                          ;       \
  277                         stosb                                   ;       \
  278                         loop 1b"                                :       \
  279                     "=D" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : \
  280                     "" ((ptr)), "1" ((cnt)), "2" ((h) + (o))       :   \
  281                     "memory");                                          \
  282         }                                                               \
  283 } while (/* CONSTCOND */ 0)
  284 
  285 #define bus_space_read_multi_2(t, h, o, ptr, cnt)                       \
  286 do {                                                                    \
  287         __BUS_SPACE_ADDRESS_SANITY((ptr), u_int16_t, "buffer");         \
  288         __BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int16_t, "bus addr");   \
  289         if ((t) == X86_BUS_SPACE_IO) {                                  \
  290                 insw((h) + (o), (ptr), (cnt));                          \
  291         } else {                                                        \
  292                 void *dummy1;                                           \
  293                 int dummy2;                                             \
  294                 void *dummy3;                                           \
  295                 int __x;                                                \
  296                 __asm volatile("                                        \
  297                         cld                                     ;       \
  298                 1:      movw (%2),%%ax                          ;       \
  299                         stosw                                   ;       \
  300                         loop 1b"                                :       \
  301                     "=D" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : \
  302                     "" ((ptr)), "1" ((cnt)), "2" ((h) + (o))       :   \
  303                     "memory");                                          \
  304         }                                                               \
  305 } while (/* CONSTCOND */ 0)
  306 
  307 #define bus_space_read_multi_4(t, h, o, ptr, cnt)                       \
  308 do {                                                                    \
  309         __BUS_SPACE_ADDRESS_SANITY((ptr), u_int32_t, "buffer");         \
  310         __BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int32_t, "bus addr");   \
  311         if ((t) == X86_BUS_SPACE_IO) {                                  \
  312                 insl((h) + (o), (ptr), (cnt));                          \
  313         } else {                                                        \
  314                 void *dummy1;                                           \
  315                 int dummy2;                                             \
  316                 void *dummy3;                                           \
  317                 int __x;                                                \
  318                 __asm volatile("                                        \
  319                         cld                                     ;       \
  320                 1:      movl (%2),%%eax                         ;       \
  321                         stosl                                   ;       \
  322                         loop 1b"                                :       \
  323                     "=D" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : \
  324                     "" ((ptr)), "1" ((cnt)), "2" ((h) + (o))       :       \
  325                     "memory");                                          \
  326         }                                                               \
  327 } while (/* CONSTCOND */ 0)
  328 
  329 #define bus_space_read_multi_stream_1 bus_space_read_multi_1
  330 #define bus_space_read_multi_stream_2 bus_space_read_multi_2
  331 #define bus_space_read_multi_stream_4 bus_space_read_multi_4
  332 
  333 #if 0   /* Cause a link error for bus_space_read_multi_8 */
  334 #define bus_space_read_multi_8  !!! bus_space_read_multi_8 unimplemented !!!
  335 #define bus_space_read_multi_stream_8   \
  336                 !!! bus_space_read_multi_stream_8 unimplemented !!!
  337 #endif
  338 
  339 /*
  340  *      void bus_space_read_region_N(bus_space_tag_t tag,
  341  *          bus_space_handle_t bsh, bus_size_t offset,
  342  *          u_intN_t *addr, size_t count);
  343  *
  344  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
  345  * described by tag/handle and starting at `offset' and copy into
  346  * buffer provided.
  347  */
  348 
  349 #define bus_space_read_region_1(t, h, o, ptr, cnt)                      \
  350 do {                                                                    \
  351         if ((t) == X86_BUS_SPACE_IO) {                                  \
  352                 int dummy1;                                             \
  353                 void *dummy2;                                           \
  354                 int dummy3;                                             \
  355                 int __x;                                                \
  356                 __asm volatile("                                        \
  357                         cld                                     ;       \
  358                 1:      inb %w1,%%al                            ;       \
  359                         stosb                                   ;       \
  360                         incl %1                                 ;       \
  361                         loop 1b"                                :       \
  362                     "=&a" (__x), "=d" (dummy1), "=D" (dummy2),          \
  363                     "=c" (dummy3)                               :       \
  364                     "1" ((h) + (o)), "2" ((ptr)), "3" ((cnt))   :       \
  365                     "memory");                                          \
  366         } else {                                                        \
  367                 int dummy1;                                             \
  368                 void *dummy2;                                           \
  369                 int dummy3;                                             \
  370                 __asm volatile("                                        \
  371                         cld                                     ;       \
  372                         repne                                   ;       \
  373                         movsb"                                  :       \
  374                     "=S" (dummy1), "=D" (dummy2), "=c" (dummy3) :       \
  375                     "" ((h) + (o)), "1" ((ptr)), "2" ((cnt))   :       \
  376                     "memory");                                          \
  377         }                                                               \
  378 } while (/* CONSTCOND */ 0)
  379 
  380 #define bus_space_read_region_2(t, h, o, ptr, cnt)                      \
  381 do {                                                                    \
  382         __BUS_SPACE_ADDRESS_SANITY((ptr), u_int16_t, "buffer");         \
  383         __BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int16_t, "bus addr");   \
  384         if ((t) == X86_BUS_SPACE_IO) {                                  \
  385                 int dummy1;                                             \
  386                 void *dummy2;                                           \
  387                 int dummy3;                                             \
  388                 int __x;                                                \
  389                 __asm volatile("                                        \
  390                         cld                                     ;       \
  391                 1:      inw %w1,%%ax                            ;       \
  392                         stosw                                   ;       \
  393                         addl $2,%1                              ;       \
  394                         loop 1b"                                :       \
  395                     "=&a" (__x), "=d" (dummy1), "=D" (dummy2),          \
  396                     "=c" (dummy3)                               :       \
  397                     "1" ((h) + (o)), "2" ((ptr)), "3" ((cnt))   :       \
  398                     "memory");                                          \
  399         } else {                                                        \
  400                 int dummy1;                                             \
  401                 void *dummy2;                                           \
  402                 int dummy3;                                             \
  403                 __asm volatile("                                        \
  404                         cld                                     ;       \
  405                         repne                                   ;       \
  406                         movsw"                                  :       \
  407                     "=S" (dummy1), "=D" (dummy2), "=c" (dummy3) :       \
  408                     "" ((h) + (o)), "1" ((ptr)), "2" ((cnt))   :       \
  409                     "memory");                                          \
  410         }                                                               \
  411 } while (/* CONSTCOND */ 0)
  412 
  413 #define bus_space_read_region_4(t, h, o, ptr, cnt)                      \
  414 do {                                                                    \
  415         __BUS_SPACE_ADDRESS_SANITY((ptr), u_int32_t, "buffer");         \
  416         __BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int32_t, "bus addr");   \
  417         if ((t) == X86_BUS_SPACE_IO) {                                  \
  418                 int dummy1;                                             \
  419                 void *dummy2;                                           \
  420                 int dummy3;                                             \
  421                 int __x;                                                \
  422                 __asm volatile("                                        \
  423                         cld                                     ;       \
  424                 1:      inl %w1,%%eax                           ;       \
  425                         stosl                                   ;       \
  426                         addl $4,%1                              ;       \
  427                         loop 1b"                                :       \
  428                     "=&a" (__x), "=d" (dummy1), "=D" (dummy2),          \
  429                     "=c" (dummy3)                               :       \
  430                     "1" ((h) + (o)), "2" ((ptr)), "3" ((cnt))   :       \
  431                     "memory");                                          \
  432         } else {                                                        \
  433                 int dummy1;                                             \
  434                 void *dummy2;                                           \
  435                 int dummy3;                                             \
  436                 __asm volatile("                                        \
  437                         cld                                     ;       \
  438                         repne                                   ;       \
  439                         movsl"                                  :       \
  440                     "=S" (dummy1), "=D" (dummy2), "=c" (dummy3) :       \
  441                     "" ((h) + (o)), "1" ((ptr)), "2" ((cnt))   :       \
  442                     "memory");                                          \
  443         }                                                               \
  444 } while (/* CONSTCOND */ 0)
  445 
  446 #define bus_space_read_region_stream_1 bus_space_read_region_1
  447 #define bus_space_read_region_stream_2 bus_space_read_region_2
  448 #define bus_space_read_region_stream_4 bus_space_read_region_4
  449 
  450 #if 0   /* Cause a link error for bus_space_read_region_8 */
  451 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
  452 #define bus_space_read_region_stream_8  \
  453                 !!! bus_space_read_region_stream_8 unimplemented !!!
  454 #endif
  455 
  456 /*
  457  *      void bus_space_write_N(bus_space_tag_t tag,
  458  *          bus_space_handle_t bsh, bus_size_t offset,
  459  *          u_intN_t value);
  460  *
  461  * Write the 1, 2, 4, or 8 byte value `value' to bus space
  462  * described by tag/handle/offset.
  463  */
  464 
  465 #define bus_space_write_1(t, h, o, v)                                   \
  466 do {                                                                    \
  467         if ((t) == X86_BUS_SPACE_IO)                                    \
  468                 outb((h) + (o), (v));                                   \
  469         else                                                            \
  470                 ((void)(*(volatile u_int8_t *)((h) + (o)) = (v)));      \
  471 } while (/* CONSTCOND */ 0)
  472 
  473 #define bus_space_write_2(t, h, o, v)                                   \
  474 do {                                                                    \
  475         __BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int16_t, "bus addr");   \
  476         if ((t) == X86_BUS_SPACE_IO)                                    \
  477                 outw((h) + (o), (v));                                   \
  478         else                                                            \
  479                 ((void)(*(volatile u_int16_t *)((h) + (o)) = (v)));     \
  480 } while (/* CONSTCOND */ 0)
  481 
  482 #define bus_space_write_4(t, h, o, v)                                   \
  483 do {                                                                    \
  484         __BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int32_t, "bus addr");   \
  485         if ((t) == X86_BUS_SPACE_IO)                                    \
  486                 outl((h) + (o), (v));                                   \
  487         else                                                            \
  488                 ((void)(*(volatile u_int32_t *)((h) + (o)) = (v)));     \
  489 } while (/* CONSTCOND */ 0)
  490 
  491 #define bus_space_write_stream_1 bus_space_write_1
  492 #define bus_space_write_stream_2 bus_space_write_2
  493 #define bus_space_write_stream_4 bus_space_write_4
  494 
  495 #if 0   /* Cause a link error for bus_space_write_8 */
  496 #define bus_space_write_8       !!! bus_space_write_8 not implemented !!!
  497 #define bus_space_write_stream_8        \
  498                 !!! bus_space_write_stream_8 not implemented !!!
  499 #endif
  500 
  501 /*
  502  *      void bus_space_write_multi_N(bus_space_tag_t tag,
  503  *          bus_space_handle_t bsh, bus_size_t offset,
  504  *          const u_intN_t *addr, size_t count);
  505  *
  506  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
  507  * provided to bus space described by tag/handle/offset.
  508  */
  509 
  510 #define bus_space_write_multi_1(t, h, o, ptr, cnt)                      \
  511 do {                                                                    \
  512         if ((t) == X86_BUS_SPACE_IO) {                                  \
  513                 outsb((h) + (o), (ptr), (cnt));                         \
  514         } else {                                                        \
  515                 void *dummy1;                                           \
  516                 int dummy2;                                             \
  517                 void *dummy3;                                           \
  518                 int __x;                                                \
  519                 __asm volatile("                                        \
  520                         cld                                     ;       \
  521                 1:      lodsb                                   ;       \
  522                         movb %%al,(%2)                          ;       \
  523                         loop 1b"                                :       \
  524                     "=S" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : \
  525                     "" ((ptr)), "1" ((cnt)), "2" ((h) + (o)));         \
  526         }                                                               \
  527 } while (/* CONSTCOND */ 0)
  528 
  529 #define bus_space_write_multi_2(t, h, o, ptr, cnt)                      \
  530 do {                                                                    \
  531         __BUS_SPACE_ADDRESS_SANITY((ptr), u_int16_t, "buffer");         \
  532         __BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int16_t, "bus addr");   \
  533         if ((t) == X86_BUS_SPACE_IO) {                                  \
  534                 outsw((h) + (o), (ptr), (cnt));                         \
  535         } else {                                                        \
  536                 void *dummy1;                                           \
  537                 int dummy2;                                             \
  538                 void *dummy3;                                           \
  539                 int __x;                                                \
  540                 __asm volatile("                                        \
  541                         cld                                     ;       \
  542                 1:      lodsw                                   ;       \
  543                         movw %%ax,(%2)                          ;       \
  544                         loop 1b"                                :       \
  545                     "=S" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : \
  546                     "" ((ptr)), "1" ((cnt)), "2" ((h) + (o)));         \
  547         }                                                               \
  548 } while (/* CONSTCOND */ 0)
  549 
  550 #define bus_space_write_multi_4(t, h, o, ptr, cnt)                      \
  551 do {                                                                    \
  552         __BUS_SPACE_ADDRESS_SANITY((ptr), u_int32_t, "buffer");         \
  553         __BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int32_t, "bus addr");   \
  554         if ((t) == X86_BUS_SPACE_IO) {                                  \
  555                 outsl((h) + (o), (ptr), (cnt));                         \
  556         } else {                                                        \
  557                 void *dummy1;                                           \
  558                 int dummy2;                                             \
  559                 void *dummy3;                                           \
  560                 int __x;                                                \
  561                 __asm volatile("                                        \
  562                         cld                                     ;       \
  563                 1:      lodsl                                   ;       \
  564                         movl %%eax,(%2)                         ;       \
  565                         loop 1b"                                :       \
  566                     "=S" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : \
  567                     "" ((ptr)), "1" ((cnt)), "2" ((h) + (o)));         \
  568         }                                                               \
  569 } while (/* CONSTCOND */ 0)
  570 
  571 #define bus_space_write_multi_stream_1 bus_space_write_multi_1
  572 #define bus_space_write_multi_stream_2 bus_space_write_multi_2
  573 #define bus_space_write_multi_stream_4 bus_space_write_multi_4
  574 
  575 #if 0   /* Cause a link error for bus_space_write_multi_8 */
  576 #define bus_space_write_multi_8(t, h, o, ptr, cnt)                      \
  577                         !!! bus_space_write_multi_8 unimplemented !!!
  578 #define bus_space_write_multi_stream_8(t, h, o, ptr, cnt)               \
  579                         !!! bus_space_write_multi_stream_8 unimplemented !!!
  580 #endif
  581 
  582 /*
  583  *      void bus_space_write_region_N(bus_space_tag_t tag,
  584  *          bus_space_handle_t bsh, bus_size_t offset,
  585  *          const u_intN_t *addr, size_t count);
  586  *
  587  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
  588  * to bus space described by tag/handle starting at `offset'.
  589  */
  590 
  591 #define bus_space_write_region_1(t, h, o, ptr, cnt)                     \
  592 do {                                                                    \
  593         if ((t) == X86_BUS_SPACE_IO) {                                  \
  594                 int dummy1;                                             \
  595                 void *dummy2;                                           \
  596                 int dummy3;                                             \
  597                 int __x;                                                \
  598                 __asm volatile("                                        \
  599                         cld                                     ;       \
  600                 1:      lodsb                                   ;       \
  601                         outb %%al,%w1                           ;       \
  602                         incl %1                                 ;       \
  603                         loop 1b"                                :       \
  604                     "=&a" (__x), "=d" (dummy1), "=S" (dummy2),          \
  605                     "=c" (dummy3)                               :       \
  606                     "1" ((h) + (o)), "2" ((ptr)), "3" ((cnt))   :       \
  607                     "memory");                                          \
  608         } else {                                                        \
  609                 int dummy1;                                             \
  610                 void *dummy2;                                           \
  611                 int dummy3;                                             \
  612                 __asm volatile("                                        \
  613                         cld                                     ;       \
  614                         repne                                   ;       \
  615                         movsb"                                  :       \
  616                     "=D" (dummy1), "=S" (dummy2), "=c" (dummy3) :       \
  617                     "" ((h) + (o)), "1" ((ptr)), "2" ((cnt))   :       \
  618                     "memory");                                          \
  619         }                                                               \
  620 } while (/* CONSTCOND */ 0)
  621 
  622 #define bus_space_write_region_2(t, h, o, ptr, cnt)                     \
  623 do {                                                                    \
  624         __BUS_SPACE_ADDRESS_SANITY((ptr), u_int16_t, "buffer");         \
  625         __BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int16_t, "bus addr");   \
  626         if ((t) == X86_BUS_SPACE_IO) {                                  \
  627                 int dummy1;                                             \
  628                 void *dummy2;                                           \
  629                 int dummy3;                                             \
  630                 int __x;                                                \
  631                 __asm volatile("                                        \
  632                         cld                                     ;       \
  633                 1:      lodsw                                   ;       \
  634                         outw %%ax,%w1                           ;       \
  635                         addl $2,%1                              ;       \
  636                         loop 1b"                                :       \
  637                     "=&a" (__x), "=d" (dummy1), "=S" (dummy2),          \
  638                     "=c" (dummy3)                               :       \
  639                     "1" ((h) + (o)), "2" ((ptr)), "3" ((cnt))   :       \
  640                     "memory");                                          \
  641         } else {                                                        \
  642                 int dummy1;                                             \
  643                 void *dummy2;                                           \
  644                 int dummy3;                                             \
  645                 __asm volatile("                                        \
  646                         cld                                     ;       \
  647                         repne                                   ;       \
  648                         movsw"                                  :       \
  649                     "=D" (dummy1), "=S" (dummy2), "=c" (dummy3) :       \
  650                     "" ((h) + (o)), "1" ((ptr)), "2" ((cnt))   :       \
  651                     "memory");                                          \
  652         }                                                               \
  653 } while (/* CONSTCOND */ 0)
  654 
  655 #define bus_space_write_region_4(t, h, o, ptr, cnt)                     \
  656 do {                                                                    \
  657         __BUS_SPACE_ADDRESS_SANITY((ptr), u_int32_t, "buffer");         \
  658         __BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int32_t, "bus addr");   \
  659         if ((t) == X86_BUS_SPACE_IO) {                                  \
  660                 int dummy1;                                             \
  661                 void *dummy2;                                           \
  662                 int dummy3;                                             \
  663                 int __x;                                                \
  664                 __asm volatile("                                        \
  665                         cld                                     ;       \
  666                 1:      lodsl                                   ;       \
  667                         outl %%eax,%w1                          ;       \
  668                         addl $4,%1                              ;       \
  669                         loop 1b"                                :       \
  670                     "=&a" (__x), "=d" (dummy1), "=S" (dummy2),          \
  671                     "=c" (dummy3)                               :       \
  672                     "1" ((h) + (o)), "2" ((ptr)), "3" ((cnt))   :       \
  673                     "memory");                                          \
  674         } else {                                                        \
  675                 int dummy1;                                             \
  676                 void *dummy2;                                           \
  677                 int dummy3;                                             \
  678                 __asm volatile("                                        \
  679                         cld                                     ;       \
  680                         repne                                   ;       \
  681                         movsl"                                  :       \
  682                     "=D" (dummy1), "=S" (dummy2), "=c" (dummy3) :       \
  683                     "" ((h) + (o)), "1" ((ptr)), "2" ((cnt))   :       \
  684                     "memory");                                          \
  685         }                                                               \
  686 } while (/* CONSTCOND */ 0)
  687 
  688 #define bus_space_write_region_stream_1 bus_space_write_region_1
  689 #define bus_space_write_region_stream_2 bus_space_write_region_2
  690 #define bus_space_write_region_stream_4 bus_space_write_region_4
  691 
  692 #if 0   /* Cause a link error for bus_space_write_region_8 */
  693 #define bus_space_write_region_8                                        \
  694                         !!! bus_space_write_region_8 unimplemented !!!
  695 #define bus_space_write_region_stream_8                         \
  696                         !!! bus_space_write_region_stream_8 unimplemented !!!
  697 #endif
  698 
  699 /*
  700  *      void bus_space_set_multi_N(bus_space_tag_t tag,
  701  *          bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
  702  *          size_t count);
  703  *
  704  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
  705  * by tag/handle/offset `count' times.
  706  */
  707 
  708 static __inline void x86_memio_set_multi_1(bus_space_tag_t,
  709         bus_space_handle_t, bus_size_t, u_int8_t, size_t);
  710 static __inline void x86_memio_set_multi_2(bus_space_tag_t,
  711         bus_space_handle_t, bus_size_t, u_int16_t, size_t);
  712 static __inline void x86_memio_set_multi_4(bus_space_tag_t,
  713         bus_space_handle_t, bus_size_t, u_int32_t, size_t);
  714 
  715 #define bus_space_set_multi_1(t, h, o, v, c)                            \
  716         x86_memio_set_multi_1((t), (h), (o), (v), (c))
  717 
  718 #define bus_space_set_multi_2(t, h, o, v, c)                            \
  719 do {                                                                    \
  720         __BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int16_t, "bus addr");   \
  721         x86_memio_set_multi_2((t), (h), (o), (v), (c));         \
  722 } while (/* CONSTCOND */ 0)
  723 
  724 #define bus_space_set_multi_4(t, h, o, v, c)                            \
  725 do {                                                                    \
  726         __BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int32_t, "bus addr");   \
  727         x86_memio_set_multi_4((t), (h), (o), (v), (c));         \
  728 } while (/* CONSTCOND */ 0)
  729 
  730 static __inline void
  731 x86_memio_set_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
  732     u_int8_t v, size_t c)
  733 {
  734         bus_addr_t addr = h + o;
  735 
  736         if (t == X86_BUS_SPACE_IO)
  737                 while (c--)
  738                         outb(addr, v);
  739         else
  740                 while (c--)
  741                         *(volatile u_int8_t *)(addr) = v;
  742 }
  743 
  744 static __inline void
  745 x86_memio_set_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
  746     u_int16_t v, size_t c)
  747 {
  748         bus_addr_t addr = h + o;
  749 
  750         if (t == X86_BUS_SPACE_IO)
  751                 while (c--)
  752                         outw(addr, v);
  753         else
  754                 while (c--)
  755                         *(volatile u_int16_t *)(addr) = v;
  756 }
  757 
  758 static __inline void
  759 x86_memio_set_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
  760     u_int32_t v, size_t c)
  761 {
  762         bus_addr_t addr = h + o;
  763 
  764         if (t == X86_BUS_SPACE_IO)
  765                 while (c--)
  766                         outl(addr, v);
  767         else
  768                 while (c--)
  769                         *(volatile u_int32_t *)(addr) = v;
  770 }
  771 
  772 #if 0   /* Cause a link error for bus_space_set_multi_8 */
  773 #define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
  774 #endif
  775 
  776 /*
  777  *      void bus_space_set_region_N(bus_space_tag_t tag,
  778  *          bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
  779  *          size_t count);
  780  *
  781  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
  782  * by tag/handle starting at `offset'.
  783  */
  784 
  785 static __inline void x86_memio_set_region_1(bus_space_tag_t,
  786         bus_space_handle_t, bus_size_t, u_int8_t, size_t);
  787 static __inline void x86_memio_set_region_2(bus_space_tag_t,
  788         bus_space_handle_t, bus_size_t, u_int16_t, size_t);
  789 static __inline void x86_memio_set_region_4(bus_space_tag_t,
  790         bus_space_handle_t, bus_size_t, u_int32_t, size_t);
  791 
  792 #define bus_space_set_region_1(t, h, o, v, c)                           \
  793         x86_memio_set_region_1((t), (h), (o), (v), (c))
  794 
  795 #define bus_space_set_region_2(t, h, o, v, c)                           \
  796 do {                                                                    \
  797         __BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int16_t, "bus addr");   \
  798         x86_memio_set_region_2((t), (h), (o), (v), (c));                \
  799 } while (/* CONSTCOND */ 0)
  800 
  801 #define bus_space_set_region_4(t, h, o, v, c)                           \
  802 do {                                                                    \
  803         __BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int32_t, "bus addr");   \
  804         x86_memio_set_region_4((t), (h), (o), (v), (c));                \
  805 } while (/* CONSTCOND */ 0)
  806 
  807 static __inline void
  808 x86_memio_set_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
  809     u_int8_t v, size_t c)
  810 {
  811         bus_addr_t addr = h + o;
  812 
  813         if (t == X86_BUS_SPACE_IO)
  814                 for (; c != 0; c--, addr++)
  815                         outb(addr, v);
  816         else
  817                 for (; c != 0; c--, addr++)
  818                         *(volatile u_int8_t *)(addr) = v;
  819 }
  820 
  821 static __inline void
  822 x86_memio_set_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
  823     u_int16_t v, size_t c)
  824 {
  825         bus_addr_t addr = h + o;
  826 
  827         if (t == X86_BUS_SPACE_IO)
  828                 for (; c != 0; c--, addr += 2)
  829                         outw(addr, v);
  830         else
  831                 for (; c != 0; c--, addr += 2)
  832                         *(volatile u_int16_t *)(addr) = v;
  833 }
  834 
  835 static __inline void
  836 x86_memio_set_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
  837     u_int32_t v, size_t c)
  838 {
  839         bus_addr_t addr = h + o;
  840 
  841         if (t == X86_BUS_SPACE_IO)
  842                 for (; c != 0; c--, addr += 4)
  843                         outl(addr, v);
  844         else
  845                 for (; c != 0; c--, addr += 4)
  846                         *(volatile u_int32_t *)(addr) = v;
  847 }
  848 
  849 #if 0   /* Cause a link error for bus_space_set_region_8 */
  850 #define bus_space_set_region_8  !!! bus_space_set_region_8 unimplemented !!!
  851 #endif
  852 
  853 /*
  854  *      void bus_space_copy_region_N(bus_space_tag_t tag,
  855  *          bus_space_handle_t bsh1, bus_size_t off1,
  856  *          bus_space_handle_t bsh2, bus_size_t off2,
  857  *          size_t count);
  858  *
  859  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
  860  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
  861  */
  862 
  863 static __inline void x86_memio_copy_region_1(bus_space_tag_t,
  864         bus_space_handle_t, bus_size_t, bus_space_handle_t,
  865         bus_size_t, size_t);
  866 static __inline void x86_memio_copy_region_2(bus_space_tag_t,
  867         bus_space_handle_t, bus_size_t, bus_space_handle_t,
  868         bus_size_t, size_t);
  869 static __inline void x86_memio_copy_region_4(bus_space_tag_t,
  870         bus_space_handle_t, bus_size_t, bus_space_handle_t,
  871         bus_size_t, size_t);
  872 
  873 #define bus_space_copy_region_1(t, h1, o1, h2, o2, c)                   \
  874         x86_memio_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
  875 
  876 #define bus_space_copy_region_2(t, h1, o1, h2, o2, c)                   \
  877 do {                                                                    \
  878         __BUS_SPACE_ADDRESS_SANITY((h1) + (o1), u_int16_t, "bus addr 1"); \
  879         __BUS_SPACE_ADDRESS_SANITY((h2) + (o2), u_int16_t, "bus addr 2"); \
  880         x86_memio_copy_region_2((t), (h1), (o1), (h2), (o2), (c));      \
  881 } while (/* CONSTCOND */ 0)
  882 
  883 #define bus_space_copy_region_4(t, h1, o1, h2, o2, c)                   \
  884 do {                                                                    \
  885         __BUS_SPACE_ADDRESS_SANITY((h1) + (o1), u_int32_t, "bus addr 1"); \
  886         __BUS_SPACE_ADDRESS_SANITY((h2) + (o2), u_int32_t, "bus addr 2"); \
  887         x86_memio_copy_region_4((t), (h1), (o1), (h2), (o2), (c));      \
  888 } while (/* CONSTCOND */ 0)
  889 
  890 static __inline void
  891 x86_memio_copy_region_1(bus_space_tag_t t,
  892     bus_space_handle_t h1, bus_size_t o1,
  893     bus_space_handle_t h2, bus_size_t o2, size_t c)
  894 {
  895         bus_addr_t addr1 = h1 + o1;
  896         bus_addr_t addr2 = h2 + o2;
  897 
  898         if (t == X86_BUS_SPACE_IO) {
  899                 if (addr1 >= addr2) {
  900                         /* src after dest: copy forward */
  901                         for (; c != 0; c--, addr1++, addr2++)
  902                                 outb(addr2, inb(addr1));
  903                 } else {
  904                         /* dest after src: copy backwards */
  905                         for (addr1 += (c - 1), addr2 += (c - 1);
  906                             c != 0; c--, addr1--, addr2--)
  907                                 outb(addr2, inb(addr1));
  908                 }
  909         } else {
  910                 if (addr1 >= addr2) {
  911                         /* src after dest: copy forward */
  912                         for (; c != 0; c--, addr1++, addr2++)
  913                                 *(volatile u_int8_t *)(addr2) =
  914                                     *(volatile u_int8_t *)(addr1);
  915                 } else {
  916                         /* dest after src: copy backwards */
  917                         for (addr1 += (c - 1), addr2 += (c - 1);
  918                             c != 0; c--, addr1--, addr2--)
  919                                 *(volatile u_int8_t *)(addr2) =
  920                                     *(volatile u_int8_t *)(addr1);
  921                 }
  922         }
  923 }
  924 
  925 static __inline void
  926 x86_memio_copy_region_2(bus_space_tag_t t,
  927     bus_space_handle_t h1, bus_size_t o1,
  928     bus_space_handle_t h2, bus_size_t o2, size_t c)
  929 {
  930         bus_addr_t addr1 = h1 + o1;
  931         bus_addr_t addr2 = h2 + o2;
  932 
  933         if (t == X86_BUS_SPACE_IO) {
  934                 if (addr1 >= addr2) {
  935                         /* src after dest: copy forward */
  936                         for (; c != 0; c--, addr1 += 2, addr2 += 2)
  937                                 outw(addr2, inw(addr1));
  938                 } else {
  939                         /* dest after src: copy backwards */
  940                         for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1);
  941                             c != 0; c--, addr1 -= 2, addr2 -= 2)
  942                                 outw(addr2, inw(addr1));
  943                 }
  944         } else {
  945                 if (addr1 >= addr2) {
  946                         /* src after dest: copy forward */
  947                         for (; c != 0; c--, addr1 += 2, addr2 += 2)
  948                                 *(volatile u_int16_t *)(addr2) =
  949                                     *(volatile u_int16_t *)(addr1);
  950                 } else {
  951                         /* dest after src: copy backwards */
  952                         for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1);
  953                             c != 0; c--, addr1 -= 2, addr2 -= 2)
  954                                 *(volatile u_int16_t *)(addr2) =
  955                                     *(volatile u_int16_t *)(addr1);
  956                 }
  957         }
  958 }
  959 
  960 static __inline void
  961 x86_memio_copy_region_4(bus_space_tag_t t,
  962     bus_space_handle_t h1, bus_size_t o1,
  963     bus_space_handle_t h2, bus_size_t o2, size_t c)
  964 {
  965         bus_addr_t addr1 = h1 + o1;
  966         bus_addr_t addr2 = h2 + o2;
  967 
  968         if (t == X86_BUS_SPACE_IO) {
  969                 if (addr1 >= addr2) {
  970                         /* src after dest: copy forward */
  971                         for (; c != 0; c--, addr1 += 4, addr2 += 4)
  972                                 outl(addr2, inl(addr1));
  973                 } else {
  974                         /* dest after src: copy backwards */
  975                         for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1);
  976                             c != 0; c--, addr1 -= 4, addr2 -= 4)
  977                                 outl(addr2, inl(addr1));
  978                 }
  979         } else {
  980                 if (addr1 >= addr2) {
  981                         /* src after dest: copy forward */
  982                         for (; c != 0; c--, addr1 += 4, addr2 += 4)
  983                                 *(volatile u_int32_t *)(addr2) =
  984                                     *(volatile u_int32_t *)(addr1);
  985                 } else {
  986                         /* dest after src: copy backwards */
  987                         for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1);
  988                             c != 0; c--, addr1 -= 4, addr2 -= 4)
  989                                 *(volatile u_int32_t *)(addr2) =
  990                                     *(volatile u_int32_t *)(addr1);
  991                 }
  992         }
  993 }
  994 
  995 #if 0   /* Cause a link error for bus_space_copy_8 */
  996 #define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!!
  997 #endif
  998 
  999 
 1000 /*
 1001  * Bus read/write barrier methods.
 1002  *
 1003  *      void bus_space_barrier(bus_space_tag_t tag,
 1004  *          bus_space_handle_t bsh, bus_size_t offset,
 1005  *          bus_size_t len, int flags);
 1006  *
 1007  * Note: the x86 does not currently require barriers, but we must
 1008  * provide the flags to MI code.
 1009  */
 1010 #define bus_space_barrier(t, h, o, l, f)        \
 1011         ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
 1012 #define BUS_SPACE_BARRIER_READ  0x01            /* force read barrier */
 1013 #define BUS_SPACE_BARRIER_WRITE 0x02            /* force write barrier */
 1014 
 1015 
 1016 /*
 1017  * Flags used in various bus DMA methods.
 1018  */
 1019 #define BUS_DMA_WAITOK          0x000   /* safe to sleep (pseudo-flag) */
 1020 #define BUS_DMA_NOWAIT          0x001   /* not safe to sleep */
 1021 #define BUS_DMA_ALLOCNOW        0x002   /* perform resource allocation now */
 1022 #define BUS_DMA_COHERENT        0x004   /* hint: map memory DMA coherent */
 1023 #define BUS_DMA_STREAMING       0x008   /* hint: sequential, unidirectional */
 1024 #define BUS_DMA_BUS1            0x010   /* placeholders for bus functions... */
 1025 #define BUS_DMA_BUS2            0x020
 1026 #define BUS_DMA_BUS3            0x040
 1027 #define BUS_DMA_BUS4            0x080
 1028 #define BUS_DMA_READ            0x100   /* mapping is device -> memory only */
 1029 #define BUS_DMA_WRITE           0x200   /* mapping is memory -> device only */
 1030 #define BUS_DMA_NOCACHE         0x400   /* hint: map non-cached memory */
 1031 
 1032 /* Forwards needed by prototypes below. */
 1033 struct mbuf;
 1034 struct uio;
 1035 
 1036 /*
 1037  * Operations performed by bus_dmamap_sync().
 1038  */
 1039 #define BUS_DMASYNC_PREREAD     0x01    /* pre-read synchronization */
 1040 #define BUS_DMASYNC_POSTREAD    0x02    /* post-read synchronization */
 1041 #define BUS_DMASYNC_PREWRITE    0x04    /* pre-write synchronization */
 1042 #define BUS_DMASYNC_POSTWRITE   0x08    /* post-write synchronization */
 1043 
 1044 typedef struct x86_bus_dma_tag          *bus_dma_tag_t;
 1045 typedef struct x86_bus_dmamap           *bus_dmamap_t;
 1046 
 1047 #define BUS_DMA_TAG_VALID(t)    ((t) != (bus_dma_tag_t)0)
 1048 
 1049 /*
 1050  *      bus_dma_segment_t
 1051  *
 1052  *      Describes a single contiguous DMA transaction.  Values
 1053  *      are suitable for programming into DMA registers.
 1054  */
 1055 struct x86_bus_dma_segment {
 1056         bus_addr_t      ds_addr;        /* DMA address */
 1057         bus_size_t      ds_len;         /* length of transfer */
 1058 };
 1059 typedef struct x86_bus_dma_segment      bus_dma_segment_t;
 1060 
 1061 /*
 1062  *      bus_dma_tag_t
 1063  *
 1064  *      A machine-dependent opaque type describing the implementation of
 1065  *      DMA for a given bus.
 1066  */
 1067 
 1068 struct x86_bus_dma_tag {
 1069         /*
 1070          * The `bounce threshold' is checked while we are loading
 1071          * the DMA map.  If the physical address of the segment
 1072          * exceeds the threshold, an error will be returned.  The
 1073          * caller can then take whatever action is necessary to
 1074          * bounce the transfer.  If this value is 0, it will be
 1075          * ignored.
 1076          */
 1077         bus_addr_t _bounce_thresh;
 1078         bus_addr_t _bounce_alloc_lo;
 1079         bus_addr_t _bounce_alloc_hi;
 1080         int     (*_may_bounce)(bus_dma_tag_t, bus_dmamap_t, int, int *);
 1081 
 1082         /*
 1083          * DMA mapping methods.
 1084          */
 1085         int     (*_dmamap_create)(bus_dma_tag_t, bus_size_t, int,
 1086                     bus_size_t, bus_size_t, int, bus_dmamap_t *);
 1087         void    (*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
 1088         int     (*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
 1089                     bus_size_t, struct proc *, int);
 1090         int     (*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
 1091                     struct mbuf *, int);
 1092         int     (*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t,
 1093                     struct uio *, int);
 1094         int     (*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t,
 1095                     bus_dma_segment_t *, int, bus_size_t, int);
 1096         void    (*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
 1097         void    (*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
 1098                     bus_addr_t, bus_size_t, int);
 1099 
 1100         /*
 1101          * DMA memory utility functions.
 1102          */
 1103         int     (*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
 1104                     bus_size_t, bus_dma_segment_t *, int, int *, int);
 1105         void    (*_dmamem_free)(bus_dma_tag_t, bus_dma_segment_t *, int);
 1106         int     (*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
 1107                     int, size_t, caddr_t *, int);
 1108         void    (*_dmamem_unmap)(bus_dma_tag_t, caddr_t, size_t);
 1109         paddr_t (*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
 1110                     int, off_t, int, int);
 1111 };
 1112 
 1113 static __inline void bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t,
 1114     bus_addr_t, bus_size_t, int) __attribute__((__unused__));
 1115 
 1116 #define bus_dmamap_create(t, s, n, m, b, f, p)                  \
 1117         (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
 1118 #define bus_dmamap_destroy(t, p)                                \
 1119         (*(t)->_dmamap_destroy)((t), (p))
 1120 #define bus_dmamap_load(t, m, b, s, p, f)                       \
 1121         (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
 1122 #define bus_dmamap_load_mbuf(t, m, b, f)                        \
 1123         (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
 1124 #define bus_dmamap_load_uio(t, m, u, f)                         \
 1125         (*(t)->_dmamap_load_uio)((t), (m), (u), (f))
 1126 #define bus_dmamap_load_raw(t, m, sg, n, s, f)                  \
 1127         (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
 1128 #define bus_dmamap_unload(t, p)                                 \
 1129         (*(t)->_dmamap_unload)((t), (p))
 1130 static __inline void
 1131 bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t p, bus_addr_t o, bus_size_t l,
 1132     int ops)
 1133 {
 1134         if (ops & BUS_DMASYNC_POSTREAD)
 1135                 x86_lfence();
 1136         if (t->_dmamap_sync)
 1137                 (*t->_dmamap_sync)(t, p, o, l, ops);
 1138 }
 1139 
 1140 #define bus_dmamem_alloc(t, s, a, b, sg, n, r, f)               \
 1141         (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
 1142 #define bus_dmamem_free(t, sg, n)                               \
 1143         (*(t)->_dmamem_free)((t), (sg), (n))
 1144 #define bus_dmamem_map(t, sg, n, s, k, f)                       \
 1145         (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
 1146 #define bus_dmamem_unmap(t, k, s)                               \
 1147         (*(t)->_dmamem_unmap)((t), (k), (s))
 1148 #define bus_dmamem_mmap(t, sg, n, o, p, f)                      \
 1149         (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 1150 
 1151 /*
 1152  *      bus_dmamap_t
 1153  *
 1154  *      Describes a DMA mapping.
 1155  */
 1156 struct x86_bus_dmamap {
 1157         /*
 1158          * PRIVATE MEMBERS: not for use by machine-independent code.
 1159          */
 1160         bus_size_t      _dm_size;       /* largest DMA transfer mappable */
 1161         int             _dm_segcnt;     /* number of segs this map can map */
 1162         bus_size_t      _dm_maxmaxsegsz; /* fixed largest possible segment */
 1163         bus_size_t      _dm_boundary;   /* don't cross this */
 1164         bus_addr_t      _dm_bounce_thresh; /* bounce threshold; see tag */
 1165         int             _dm_flags;      /* misc. flags */
 1166 
 1167         void            *_dm_cookie;    /* cookie for bus-specific functions */
 1168 
 1169         /*
 1170          * PUBLIC MEMBERS: these are used by machine-independent code.
 1171          */
 1172         bus_size_t      dm_maxsegsz;    /* largest possible segment */
 1173         bus_size_t      dm_mapsize;     /* size of the mapping */
 1174         int             dm_nsegs;       /* # valid segments in mapping */
 1175         bus_dma_segment_t dm_segs[1];   /* segments; variable length */
 1176 };
 1177 
 1178 #endif /* _X86_BUS_H_ */

Cache object: 36623594d6e5035ff8de764812727539


[ 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.