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_at386.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: releng/5.3/sys/i386/include/bus_at386.h 126891 2004-03-12 21:45:33Z trhodes $ */
   71 
   72 #ifndef _I386_BUS_AT386_H_
   73 #define _I386_BUS_AT386_H_
   74 
   75 #include <machine/cpufunc.h>
   76 
   77 /*
   78  * To remain compatible with NetBSD's interface, default to both memio and
   79  * pio when neither of them is defined.
   80  */ 
   81 #if !defined(_I386_BUS_PIO_H_) && !defined(_I386_BUS_MEMIO_H_)
   82 #define _I386_BUS_PIO_H_
   83 #define _I386_BUS_MEMIO_H_
   84 #endif
   85 
   86 /*
   87  * Values for the i386 bus space tag, not to be used directly by MI code.
   88  */
   89 #define I386_BUS_SPACE_IO       0       /* space is i/o space */
   90 #define I386_BUS_SPACE_MEM      1       /* space is mem space */
   91 
   92 /*
   93  * Bus address and size types
   94  */
   95 #ifdef PAE
   96 typedef uint64_t bus_addr_t;
   97 #else
   98 typedef uint32_t bus_addr_t;
   99 #endif
  100 typedef uint32_t bus_size_t;
  101 
  102 #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
  103 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
  104 #define BUS_SPACE_MAXSIZE       0xFFFFFFFF
  105 #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
  106 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
  107 #ifdef PAE
  108 #define BUS_SPACE_MAXADDR       0xFFFFFFFFFFFFFFFFULL
  109 #else
  110 #define BUS_SPACE_MAXADDR       0xFFFFFFFF
  111 #endif
  112 
  113 #define BUS_SPACE_UNRESTRICTED  (~0)
  114 
  115 /*
  116  * Access methods for bus resources and address space.
  117  */
  118 typedef int bus_space_tag_t;
  119 typedef u_int bus_space_handle_t;
  120 
  121 /*
  122  * Map a region of device bus space into CPU virtual address space.
  123  */
  124 
  125 static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
  126                                   bus_size_t size, int flags,
  127                                   bus_space_handle_t *bshp);
  128 
  129 static __inline int
  130 bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
  131               bus_size_t size __unused, int flags __unused,
  132               bus_space_handle_t *bshp)
  133 {
  134 
  135         *bshp = addr;
  136         return (0);
  137 }
  138 
  139 /*
  140  * Unmap a region of device bus space.
  141  */
  142 
  143 static __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
  144                                      bus_size_t size);
  145 
  146 static __inline void
  147 bus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
  148                 bus_size_t size __unused)
  149 {
  150 }
  151 
  152 /*
  153  * Get a new handle for a subregion of an already-mapped area of bus space.
  154  */
  155 
  156 static __inline int bus_space_subregion(bus_space_tag_t t,
  157                                         bus_space_handle_t bsh,
  158                                         bus_size_t offset, bus_size_t size,
  159                                         bus_space_handle_t *nbshp);
  160 
  161 static __inline int
  162 bus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t bsh,
  163                     bus_size_t offset, bus_size_t size __unused,
  164                     bus_space_handle_t *nbshp)
  165 {
  166 
  167         *nbshp = bsh + offset;
  168         return (0);
  169 }
  170 
  171 /*
  172  * Allocate a region of memory that is accessible to devices in bus space.
  173  */
  174 
  175 int     bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
  176                         bus_addr_t rend, bus_size_t size, bus_size_t align,
  177                         bus_size_t boundary, int flags, bus_addr_t *addrp,
  178                         bus_space_handle_t *bshp);
  179 
  180 /*
  181  * Free a region of bus space accessible memory.
  182  */
  183 
  184 static __inline void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
  185                                     bus_size_t size);
  186 
  187 static __inline void
  188 bus_space_free(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
  189                bus_size_t size __unused)
  190 {
  191 }
  192 
  193 
  194 #if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_)
  195 
  196 /*
  197  * Read a 1, 2, 4, or 8 byte quantity from bus space
  198  * described by tag/handle/offset.
  199  */
  200 static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
  201                                           bus_space_handle_t handle,
  202                                           bus_size_t offset);
  203 
  204 static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
  205                                            bus_space_handle_t handle,
  206                                            bus_size_t offset);
  207 
  208 static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
  209                                            bus_space_handle_t handle,
  210                                            bus_size_t offset);
  211 
  212 static __inline u_int8_t
  213 bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
  214                  bus_size_t offset)
  215 {
  216 #if defined (_I386_BUS_PIO_H_)
  217 #if defined (_I386_BUS_MEMIO_H_)
  218         if (tag == I386_BUS_SPACE_IO)
  219 #endif
  220                 return (inb(handle + offset));
  221 #endif
  222 #if defined (_I386_BUS_MEMIO_H_)
  223         return (*(volatile u_int8_t *)(handle + offset));
  224 #endif
  225 }
  226 
  227 static __inline u_int16_t
  228 bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
  229                  bus_size_t offset)
  230 {
  231 #if defined(_I386_BUS_PIO_H_)
  232 #if defined(_I386_BUS_MEMIO_H_)
  233         if (tag == I386_BUS_SPACE_IO)
  234 #endif
  235                 return (inw(handle + offset));
  236 #endif
  237 #if defined(_I386_BUS_MEMIO_H_)
  238         return (*(volatile u_int16_t *)(handle + offset));
  239 #endif
  240 }
  241 
  242 static __inline u_int32_t
  243 bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
  244                  bus_size_t offset)
  245 {
  246 #if defined(_I386_BUS_PIO_H_)
  247 #if defined(_I386_BUS_MEMIO_H_)
  248         if (tag == I386_BUS_SPACE_IO)
  249 #endif
  250                 return (inl(handle + offset));
  251 #endif
  252 #if defined(_I386_BUS_MEMIO_H_)
  253         return (*(volatile u_int32_t *)(handle + offset));
  254 #endif
  255 }
  256 
  257 #if 0   /* Cause a link error for bus_space_read_8 */
  258 #define bus_space_read_8(t, h, o)       !!! bus_space_read_8 unimplemented !!!
  259 #endif
  260 
  261 /*
  262  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
  263  * described by tag/handle/offset and copy into buffer provided.
  264  */
  265 static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
  266                                             bus_space_handle_t bsh,
  267                                             bus_size_t offset, u_int8_t *addr,
  268                                             size_t count);
  269 
  270 static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
  271                                             bus_space_handle_t bsh,
  272                                             bus_size_t offset, u_int16_t *addr,
  273                                             size_t count);
  274 
  275 static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
  276                                             bus_space_handle_t bsh,
  277                                             bus_size_t offset, u_int32_t *addr,
  278                                             size_t count);
  279 
  280 static __inline void
  281 bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
  282                        bus_size_t offset, u_int8_t *addr, size_t count)
  283 {
  284 #if defined(_I386_BUS_PIO_H_)
  285 #if defined(_I386_BUS_MEMIO_H_)
  286         if (tag == I386_BUS_SPACE_IO)
  287 #endif
  288                 insb(bsh + offset, addr, count);
  289 #endif
  290 #if defined(_I386_BUS_MEMIO_H_)
  291 #if defined(_I386_BUS_PIO_H_)
  292         else
  293 #endif
  294         {
  295 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  296                 __asm __volatile("                              \n\
  297                         cld                                     \n\
  298                 1:      movb (%2),%%al                          \n\
  299                         stosb                                   \n\
  300                         loop 1b"                                :
  301                     "=D" (addr), "=c" (count)                   :
  302                     "r" (bsh + offset), "" (addr), "1" (count) :
  303                     "%eax", "memory");
  304 #else
  305 # ifndef lint
  306 #  error "no assembler code for your compiler"
  307 # endif
  308 #endif
  309         }
  310 #endif
  311 }
  312 
  313 static __inline void
  314 bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
  315                        bus_size_t offset, u_int16_t *addr, size_t count)
  316 {
  317 #if defined(_I386_BUS_PIO_H_)
  318 #if defined(_I386_BUS_MEMIO_H_)
  319         if (tag == I386_BUS_SPACE_IO)
  320 #endif
  321                 insw(bsh + offset, addr, count);
  322 #endif
  323 #if defined(_I386_BUS_MEMIO_H_)
  324 #if defined(_I386_BUS_PIO_H_)
  325         else
  326 #endif
  327         {
  328 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  329                 __asm __volatile("                              \n\
  330                         cld                                     \n\
  331                 1:      movw (%2),%%ax                          \n\
  332                         stosw                                   \n\
  333                         loop 1b"                                :
  334                     "=D" (addr), "=c" (count)                   :
  335                     "r" (bsh + offset), "" (addr), "1" (count) :
  336                     "%eax", "memory");
  337 #else
  338 # ifndef lint
  339 #  error "no assembler code for your compiler"
  340 # endif
  341 #endif
  342         }
  343 #endif
  344 }
  345 
  346 static __inline void
  347 bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
  348                        bus_size_t offset, u_int32_t *addr, size_t count)
  349 {
  350 #if defined(_I386_BUS_PIO_H_)
  351 #if defined(_I386_BUS_MEMIO_H_)
  352         if (tag == I386_BUS_SPACE_IO)
  353 #endif
  354                 insl(bsh + offset, addr, count);
  355 #endif
  356 #if defined(_I386_BUS_MEMIO_H_)
  357 #if defined(_I386_BUS_PIO_H_)
  358         else
  359 #endif
  360         {
  361 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  362                 __asm __volatile("                              \n\
  363                         cld                                     \n\
  364                 1:      movl (%2),%%eax                         \n\
  365                         stosl                                   \n\
  366                         loop 1b"                                :
  367                     "=D" (addr), "=c" (count)                   :
  368                     "r" (bsh + offset), "" (addr), "1" (count) :
  369                     "%eax", "memory");
  370 #else
  371 # ifndef lint
  372 #  error "no assembler code for your compiler"
  373 # endif
  374 #endif
  375         }
  376 #endif
  377 }
  378 
  379 #if 0   /* Cause a link error for bus_space_read_multi_8 */
  380 #define bus_space_read_multi_8  !!! bus_space_read_multi_8 unimplemented !!!
  381 #endif
  382 
  383 /*
  384  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
  385  * described by tag/handle and starting at `offset' and copy into
  386  * buffer provided.
  387  */
  388 static __inline void bus_space_read_region_1(bus_space_tag_t tag,
  389                                              bus_space_handle_t bsh,
  390                                              bus_size_t offset, u_int8_t *addr,
  391                                              size_t count);
  392 
  393 static __inline void bus_space_read_region_2(bus_space_tag_t tag,
  394                                              bus_space_handle_t bsh,
  395                                              bus_size_t offset, u_int16_t *addr,
  396                                              size_t count);
  397 
  398 static __inline void bus_space_read_region_4(bus_space_tag_t tag,
  399                                              bus_space_handle_t bsh,
  400                                              bus_size_t offset, u_int32_t *addr,
  401                                              size_t count);
  402 
  403 
  404 static __inline void
  405 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
  406                         bus_size_t offset, u_int8_t *addr, size_t count)
  407 {
  408 #if defined(_I386_BUS_PIO_H_)
  409 #if defined(_I386_BUS_MEMIO_H_)
  410         if (tag == I386_BUS_SPACE_IO)
  411 #endif
  412         {
  413                 int _port_ = bsh + offset;
  414 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  415                 __asm __volatile("                              \n\
  416                         cld                                     \n\
  417                 1:      inb %w2,%%al                            \n\
  418                         stosb                                   \n\
  419                         incl %2                                 \n\
  420                         loop 1b"                                :
  421                     "=D" (addr), "=c" (count), "=d" (_port_)    :
  422                     "" (addr), "1" (count), "2" (_port_)       :
  423                     "%eax", "memory", "cc");
  424 #else
  425 # ifndef lint
  426 #  error "no assembler code for your compiler"
  427 # endif
  428 #endif
  429         }
  430 #endif
  431 #if defined(_I386_BUS_MEMIO_H_)
  432 #if defined(_I386_BUS_PIO_H_)
  433         else
  434 #endif
  435         {
  436                 int _port_ = bsh + offset;
  437 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  438                 __asm __volatile("                              \n\
  439                         cld                                     \n\
  440                         repne                                   \n\
  441                         movsb"                                  :
  442                     "=D" (addr), "=c" (count), "=S" (_port_)    :
  443                     "" (addr), "1" (count), "2" (_port_)       :
  444                     "memory", "cc");
  445 #else
  446 # ifndef lint
  447 #  error "no assembler code for your compiler"
  448 # endif
  449 #endif
  450         }
  451 #endif
  452 }
  453 
  454 static __inline void
  455 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
  456                         bus_size_t offset, u_int16_t *addr, size_t count)
  457 {
  458 #if defined(_I386_BUS_PIO_H_)
  459 #if defined(_I386_BUS_MEMIO_H_)
  460         if (tag == I386_BUS_SPACE_IO)
  461 #endif
  462         {
  463                 int _port_ = bsh + offset;
  464 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  465                 __asm __volatile("                              \n\
  466                         cld                                     \n\
  467                 1:      inw %w2,%%ax                            \n\
  468                         stosw                                   \n\
  469                         addl $2,%2                              \n\
  470                         loop 1b"                                :
  471                     "=D" (addr), "=c" (count), "=d" (_port_)    :
  472                     "" (addr), "1" (count), "2" (_port_)       :
  473                     "%eax", "memory", "cc");
  474 #else
  475 # ifndef lint
  476 #  error "no assembler code for your compiler"
  477 # endif
  478 #endif
  479         }
  480 #endif
  481 #if defined(_I386_BUS_MEMIO_H_)
  482 #if defined(_I386_BUS_PIO_H_)
  483         else
  484 #endif
  485         {
  486                 int _port_ = bsh + offset;
  487 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  488                 __asm __volatile("                              \n\
  489                         cld                                     \n\
  490                         repne                                   \n\
  491                         movsw"                                  :
  492                     "=D" (addr), "=c" (count), "=S" (_port_)    :
  493                     "" (addr), "1" (count), "2" (_port_)       :
  494                     "memory", "cc");
  495 #else
  496 # ifndef lint
  497 #  error "no assembler code for your compiler"
  498 # endif
  499 #endif
  500         }
  501 #endif
  502 }
  503 
  504 static __inline void
  505 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
  506                         bus_size_t offset, u_int32_t *addr, size_t count)
  507 {
  508 #if defined(_I386_BUS_PIO_H_)
  509 #if defined(_I386_BUS_MEMIO_H_)
  510         if (tag == I386_BUS_SPACE_IO)
  511 #endif
  512         {
  513                 int _port_ = bsh + offset;
  514 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  515                 __asm __volatile("                              \n\
  516                         cld                                     \n\
  517                 1:      inl %w2,%%eax                           \n\
  518                         stosl                                   \n\
  519                         addl $4,%2                              \n\
  520                         loop 1b"                                :
  521                     "=D" (addr), "=c" (count), "=d" (_port_)    :
  522                     "" (addr), "1" (count), "2" (_port_)       :
  523                     "%eax", "memory", "cc");
  524 #else
  525 # ifndef lint
  526 #  error "no assembler code for your compiler"
  527 # endif
  528 #endif
  529         }
  530 #endif
  531 #if defined(_I386_BUS_MEMIO_H_)
  532 #if defined(_I386_BUS_PIO_H_)
  533         else
  534 #endif
  535         {
  536                 int _port_ = bsh + offset;
  537 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  538                 __asm __volatile("                              \n\
  539                         cld                                     \n\
  540                         repne                                   \n\
  541                         movsl"                                  :
  542                     "=D" (addr), "=c" (count), "=S" (_port_)    :
  543                     "" (addr), "1" (count), "2" (_port_)       :
  544                     "memory", "cc");
  545 #else
  546 # ifndef lint
  547 #  error "no assembler code for your compiler"
  548 # endif
  549 #endif
  550         }
  551 #endif
  552 }
  553 
  554 #if 0   /* Cause a link error for bus_space_read_region_8 */
  555 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
  556 #endif
  557 
  558 /*
  559  * Write the 1, 2, 4, or 8 byte value `value' to bus space
  560  * described by tag/handle/offset.
  561  */
  562 
  563 static __inline void bus_space_write_1(bus_space_tag_t tag,
  564                                        bus_space_handle_t bsh,
  565                                        bus_size_t offset, u_int8_t value);
  566 
  567 static __inline void bus_space_write_2(bus_space_tag_t tag,
  568                                        bus_space_handle_t bsh,
  569                                        bus_size_t offset, u_int16_t value);
  570 
  571 static __inline void bus_space_write_4(bus_space_tag_t tag,
  572                                        bus_space_handle_t bsh,
  573                                        bus_size_t offset, u_int32_t value);
  574 
  575 static __inline void
  576 bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
  577                        bus_size_t offset, u_int8_t value)
  578 {
  579 #if defined(_I386_BUS_PIO_H_)
  580 #if defined(_I386_BUS_MEMIO_H_)
  581         if (tag == I386_BUS_SPACE_IO)
  582 #endif
  583                 outb(bsh + offset, value);
  584 #endif
  585 #if defined(_I386_BUS_MEMIO_H_)
  586 #if defined(_I386_BUS_PIO_H_)
  587         else
  588 #endif
  589                 *(volatile u_int8_t *)(bsh + offset) = value;
  590 #endif
  591 }
  592 
  593 static __inline void
  594 bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
  595                        bus_size_t offset, u_int16_t value)
  596 {
  597 #if defined(_I386_BUS_PIO_H_)
  598 #if defined(_I386_BUS_MEMIO_H_)
  599         if (tag == I386_BUS_SPACE_IO)
  600 #endif
  601                 outw(bsh + offset, value);
  602 #endif
  603 #if defined(_I386_BUS_MEMIO_H_)
  604 #if defined(_I386_BUS_PIO_H_)
  605         else
  606 #endif
  607                 *(volatile u_int16_t *)(bsh + offset) = value;
  608 #endif
  609 }
  610 
  611 static __inline void
  612 bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
  613                        bus_size_t offset, u_int32_t value)
  614 {
  615 #if defined(_I386_BUS_PIO_H_)
  616 #if defined(_I386_BUS_MEMIO_H_)
  617         if (tag == I386_BUS_SPACE_IO)
  618 #endif
  619                 outl(bsh + offset, value);
  620 #endif
  621 #if defined(_I386_BUS_MEMIO_H_)
  622 #if defined(_I386_BUS_PIO_H_)
  623         else
  624 #endif
  625                 *(volatile u_int32_t *)(bsh + offset) = value;
  626 #endif
  627 }
  628 
  629 #if 0   /* Cause a link error for bus_space_write_8 */
  630 #define bus_space_write_8       !!! bus_space_write_8 not implemented !!!
  631 #endif
  632 
  633 /*
  634  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
  635  * provided to bus space described by tag/handle/offset.
  636  */
  637 
  638 static __inline void bus_space_write_multi_1(bus_space_tag_t tag,
  639                                              bus_space_handle_t bsh,
  640                                              bus_size_t offset,
  641                                              const u_int8_t *addr,
  642                                              size_t count);
  643 static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
  644                                              bus_space_handle_t bsh,
  645                                              bus_size_t offset,
  646                                              const u_int16_t *addr,
  647                                              size_t count);
  648 
  649 static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
  650                                              bus_space_handle_t bsh,
  651                                              bus_size_t offset,
  652                                              const u_int32_t *addr,
  653                                              size_t count);
  654 
  655 static __inline void
  656 bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
  657                         bus_size_t offset, const u_int8_t *addr, size_t count)
  658 {
  659 #if defined(_I386_BUS_PIO_H_)
  660 #if defined(_I386_BUS_MEMIO_H_)
  661         if (tag == I386_BUS_SPACE_IO)
  662 #endif
  663                 outsb(bsh + offset, addr, count);
  664 #endif
  665 #if defined(_I386_BUS_MEMIO_H_)
  666 #if defined(_I386_BUS_PIO_H_)
  667         else
  668 #endif
  669         {
  670 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  671                 __asm __volatile("                              \n\
  672                         cld                                     \n\
  673                 1:      lodsb                                   \n\
  674                         movb %%al,(%2)                          \n\
  675                         loop 1b"                                :
  676                     "=S" (addr), "=c" (count)                   :
  677                     "r" (bsh + offset), "" (addr), "1" (count) :
  678                     "%eax", "memory", "cc");
  679 #else
  680 # ifndef lint
  681 #  error "no assembler code for your compiler"
  682 # endif
  683 #endif
  684         }
  685 #endif
  686 }
  687 
  688 static __inline void
  689 bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
  690                         bus_size_t offset, const u_int16_t *addr, size_t count)
  691 {
  692 #if defined(_I386_BUS_PIO_H_)
  693 #if defined(_I386_BUS_MEMIO_H_)
  694         if (tag == I386_BUS_SPACE_IO)
  695 #endif
  696                 outsw(bsh + offset, addr, count);
  697 #endif
  698 #if defined(_I386_BUS_MEMIO_H_)
  699 #if defined(_I386_BUS_PIO_H_)
  700         else
  701 #endif
  702         {
  703 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  704                 __asm __volatile("                              \n\
  705                         cld                                     \n\
  706                 1:      lodsw                                   \n\
  707                         movw %%ax,(%2)                          \n\
  708                         loop 1b"                                :
  709                     "=S" (addr), "=c" (count)                   :
  710                     "r" (bsh + offset), "" (addr), "1" (count) :
  711                     "%eax", "memory", "cc");
  712 #else
  713 # ifndef lint
  714 #  error "no assembler code for your compiler"
  715 # endif
  716 #endif
  717         }
  718 #endif
  719 }
  720 
  721 static __inline void
  722 bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
  723                         bus_size_t offset, const u_int32_t *addr, size_t count)
  724 {
  725 #if defined(_I386_BUS_PIO_H_)
  726 #if defined(_I386_BUS_MEMIO_H_)
  727         if (tag == I386_BUS_SPACE_IO)
  728 #endif
  729                 outsl(bsh + offset, addr, count);
  730 #endif
  731 #if defined(_I386_BUS_MEMIO_H_)
  732 #if defined(_I386_BUS_PIO_H_)
  733         else
  734 #endif
  735         {
  736 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  737                 __asm __volatile("                              \n\
  738                         cld                                     \n\
  739                 1:      lodsl                                   \n\
  740                         movl %%eax,(%2)                         \n\
  741                         loop 1b"                                :
  742                     "=S" (addr), "=c" (count)                   :
  743                     "r" (bsh + offset), "" (addr), "1" (count) :
  744                     "%eax", "memory", "cc");
  745 #else
  746 # ifndef lint
  747 #  error "no assembler code for your compiler"
  748 # endif
  749 #endif
  750         }
  751 #endif
  752 }
  753 
  754 #if 0   /* Cause a link error for bus_space_write_multi_8 */
  755 #define bus_space_write_multi_8(t, h, o, a, c)                          \
  756                         !!! bus_space_write_multi_8 unimplemented !!!
  757 #endif
  758 
  759 /*
  760  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
  761  * to bus space described by tag/handle starting at `offset'.
  762  */
  763 
  764 static __inline void bus_space_write_region_1(bus_space_tag_t tag,
  765                                               bus_space_handle_t bsh,
  766                                               bus_size_t offset,
  767                                               const u_int8_t *addr,
  768                                               size_t count);
  769 static __inline void bus_space_write_region_2(bus_space_tag_t tag,
  770                                               bus_space_handle_t bsh,
  771                                               bus_size_t offset,
  772                                               const u_int16_t *addr,
  773                                               size_t count);
  774 static __inline void bus_space_write_region_4(bus_space_tag_t tag,
  775                                               bus_space_handle_t bsh,
  776                                               bus_size_t offset,
  777                                               const u_int32_t *addr,
  778                                               size_t count);
  779 
  780 static __inline void
  781 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
  782                          bus_size_t offset, const u_int8_t *addr, size_t count)
  783 {
  784 #if defined(_I386_BUS_PIO_H_)
  785 #if defined(_I386_BUS_MEMIO_H_)
  786         if (tag == I386_BUS_SPACE_IO)
  787 #endif
  788         {
  789                 int _port_ = bsh + offset;
  790 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  791                 __asm __volatile("                              \n\
  792                         cld                                     \n\
  793                 1:      lodsb                                   \n\
  794                         outb %%al,%w0                           \n\
  795                         incl %0                                 \n\
  796                         loop 1b"                                :
  797                     "=d" (_port_), "=S" (addr), "=c" (count)    :
  798                     "" (_port_), "1" (addr), "2" (count)       :
  799                     "%eax", "memory", "cc");
  800 #else
  801 # ifndef lint
  802 #  error "no assembler code for your compiler"
  803 # endif
  804 #endif
  805         }
  806 #endif
  807 #if defined(_I386_BUS_MEMIO_H_)
  808 #if defined(_I386_BUS_PIO_H_)
  809         else
  810 #endif
  811         {
  812                 int _port_ = bsh + offset;
  813 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  814                 __asm __volatile("                              \n\
  815                         cld                                     \n\
  816                         repne                                   \n\
  817                         movsb"                                  :
  818                     "=D" (_port_), "=S" (addr), "=c" (count)    :
  819                     "" (_port_), "1" (addr), "2" (count)       :
  820                     "memory", "cc");
  821 #else
  822 # ifndef lint
  823 #  error "no assembler code for your compiler"
  824 # endif
  825 #endif
  826         }
  827 #endif
  828 }
  829 
  830 static __inline void
  831 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
  832                          bus_size_t offset, const u_int16_t *addr, size_t count)
  833 {
  834 #if defined(_I386_BUS_PIO_H_)
  835 #if defined(_I386_BUS_MEMIO_H_)
  836         if (tag == I386_BUS_SPACE_IO)
  837 #endif
  838         {
  839                 int _port_ = bsh + offset;
  840 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  841                 __asm __volatile("                              \n\
  842                         cld                                     \n\
  843                 1:      lodsw                                   \n\
  844                         outw %%ax,%w0                           \n\
  845                         addl $2,%0                              \n\
  846                         loop 1b"                                :
  847                     "=d" (_port_), "=S" (addr), "=c" (count)    :
  848                     "" (_port_), "1" (addr), "2" (count)       :
  849                     "%eax", "memory", "cc");
  850 #else
  851 # ifndef lint
  852 #  error "no assembler code for your compiler"
  853 # endif
  854 #endif
  855         }
  856 #endif
  857 #if defined(_I386_BUS_MEMIO_H_)
  858 #if defined(_I386_BUS_PIO_H_)
  859         else
  860 #endif
  861         {
  862                 int _port_ = bsh + offset;
  863 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  864                 __asm __volatile("                              \n\
  865                         cld                                     \n\
  866                         repne                                   \n\
  867                         movsw"                                  :
  868                     "=D" (_port_), "=S" (addr), "=c" (count)    :
  869                     "" (_port_), "1" (addr), "2" (count)       :
  870                     "memory", "cc");
  871 #else
  872 # ifndef lint
  873 #  error "no assembler code for your compiler"
  874 # endif
  875 #endif
  876         }
  877 #endif
  878 }
  879 
  880 static __inline void
  881 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
  882                          bus_size_t offset, const u_int32_t *addr, size_t count)
  883 {
  884 #if defined(_I386_BUS_PIO_H_)
  885 #if defined(_I386_BUS_MEMIO_H_)
  886         if (tag == I386_BUS_SPACE_IO)
  887 #endif
  888         {
  889                 int _port_ = bsh + offset;
  890 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  891                 __asm __volatile("                              \n\
  892                         cld                                     \n\
  893                 1:      lodsl                                   \n\
  894                         outl %%eax,%w0                          \n\
  895                         addl $4,%0                              \n\
  896                         loop 1b"                                :
  897                     "=d" (_port_), "=S" (addr), "=c" (count)    :
  898                     "" (_port_), "1" (addr), "2" (count)       :
  899                     "%eax", "memory", "cc");
  900 #else
  901 # ifndef lint
  902 #  error "no assembler code for your compiler"
  903 # endif
  904 #endif
  905         }
  906 #endif
  907 #if defined(_I386_BUS_MEMIO_H_)
  908 #if defined(_I386_BUS_PIO_H_)
  909         else
  910 #endif
  911         {
  912                 int _port_ = bsh + offset;
  913 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
  914                 __asm __volatile("                              \n\
  915                         cld                                     \n\
  916                         repne                                   \n\
  917                         movsl"                                  :
  918                     "=D" (_port_), "=S" (addr), "=c" (count)    :
  919                     "" (_port_), "1" (addr), "2" (count)       :
  920                     "memory", "cc");
  921 #else
  922 # ifndef lint
  923 #  error "no assembler code for your compiler"
  924 # endif
  925 #endif
  926         }
  927 #endif
  928 }
  929 
  930 #if 0   /* Cause a link error for bus_space_write_region_8 */
  931 #define bus_space_write_region_8                                        \
  932                         !!! bus_space_write_region_8 unimplemented !!!
  933 #endif
  934 
  935 /*
  936  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
  937  * by tag/handle/offset `count' times.
  938  */
  939 
  940 static __inline void bus_space_set_multi_1(bus_space_tag_t tag,
  941                                            bus_space_handle_t bsh,
  942                                            bus_size_t offset,
  943                                            u_int8_t value, size_t count);
  944 static __inline void bus_space_set_multi_2(bus_space_tag_t tag,
  945                                            bus_space_handle_t bsh,
  946                                            bus_size_t offset,
  947                                            u_int16_t value, size_t count);
  948 static __inline void bus_space_set_multi_4(bus_space_tag_t tag,
  949                                            bus_space_handle_t bsh,
  950                                            bus_size_t offset,
  951                                            u_int32_t value, size_t count);
  952 
  953 static __inline void
  954 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
  955                       bus_size_t offset, u_int8_t value, size_t count)
  956 {
  957         bus_space_handle_t addr = bsh + offset;
  958 
  959 #if defined(_I386_BUS_PIO_H_)
  960 #if defined(_I386_BUS_MEMIO_H_)
  961         if (tag == I386_BUS_SPACE_IO)
  962 #endif
  963                 while (count--)
  964                         outb(addr, value);
  965 #endif
  966 #if defined(_I386_BUS_MEMIO_H_)
  967 #if defined(_I386_BUS_PIO_H_)
  968         else
  969 #endif
  970                 while (count--)
  971                         *(volatile u_int8_t *)(addr) = value;
  972 #endif
  973 }
  974 
  975 static __inline void
  976 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
  977                      bus_size_t offset, u_int16_t value, size_t count)
  978 {
  979         bus_space_handle_t addr = bsh + offset;
  980 
  981 #if defined(_I386_BUS_PIO_H_)
  982 #if defined(_I386_BUS_MEMIO_H_)
  983         if (tag == I386_BUS_SPACE_IO)
  984 #endif
  985                 while (count--)
  986                         outw(addr, value);
  987 #endif
  988 #if defined(_I386_BUS_MEMIO_H_)
  989 #if defined(_I386_BUS_PIO_H_)
  990         else
  991 #endif
  992                 while (count--)
  993                         *(volatile u_int16_t *)(addr) = value;
  994 #endif
  995 }
  996 
  997 static __inline void
  998 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
  999                       bus_size_t offset, u_int32_t value, size_t count)
 1000 {
 1001         bus_space_handle_t addr = bsh + offset;
 1002 
 1003 #if defined(_I386_BUS_PIO_H_)
 1004 #if defined(_I386_BUS_MEMIO_H_)
 1005         if (tag == I386_BUS_SPACE_IO)
 1006 #endif
 1007                 while (count--)
 1008                         outl(addr, value);
 1009 #endif
 1010 #if defined(_I386_BUS_MEMIO_H_)
 1011 #if defined(_I386_BUS_PIO_H_)
 1012         else
 1013 #endif
 1014                 while (count--)
 1015                         *(volatile u_int32_t *)(addr) = value;
 1016 #endif
 1017 }
 1018 
 1019 #if 0   /* Cause a link error for bus_space_set_multi_8 */
 1020 #define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
 1021 #endif
 1022 
 1023 /*
 1024  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
 1025  * by tag/handle starting at `offset'.
 1026  */
 1027 
 1028 static __inline void bus_space_set_region_1(bus_space_tag_t tag,
 1029                                             bus_space_handle_t bsh,
 1030                                             bus_size_t offset, u_int8_t value,
 1031                                             size_t count);
 1032 static __inline void bus_space_set_region_2(bus_space_tag_t tag,
 1033                                             bus_space_handle_t bsh,
 1034                                             bus_size_t offset, u_int16_t value,
 1035                                             size_t count);
 1036 static __inline void bus_space_set_region_4(bus_space_tag_t tag,
 1037                                             bus_space_handle_t bsh,
 1038                                             bus_size_t offset, u_int32_t value,
 1039                                             size_t count);
 1040 
 1041 static __inline void
 1042 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
 1043                        bus_size_t offset, u_int8_t value, size_t count)
 1044 {
 1045         bus_space_handle_t addr = bsh + offset;
 1046 
 1047 #if defined(_I386_BUS_PIO_H_)
 1048 #if defined(_I386_BUS_MEMIO_H_)
 1049         if (tag == I386_BUS_SPACE_IO)
 1050 #endif
 1051                 for (; count != 0; count--, addr++)
 1052                         outb(addr, value);
 1053 #endif
 1054 #if defined(_I386_BUS_MEMIO_H_)
 1055 #if defined(_I386_BUS_PIO_H_)
 1056         else
 1057 #endif
 1058                 for (; count != 0; count--, addr++)
 1059                         *(volatile u_int8_t *)(addr) = value;
 1060 #endif
 1061 }
 1062 
 1063 static __inline void
 1064 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
 1065                        bus_size_t offset, u_int16_t value, size_t count)
 1066 {
 1067         bus_space_handle_t addr = bsh + offset;
 1068 
 1069 #if defined(_I386_BUS_PIO_H_)
 1070 #if defined(_I386_BUS_MEMIO_H_)
 1071         if (tag == I386_BUS_SPACE_IO)
 1072 #endif
 1073                 for (; count != 0; count--, addr += 2)
 1074                         outw(addr, value);
 1075 #endif
 1076 #if defined(_I386_BUS_MEMIO_H_)
 1077 #if defined(_I386_BUS_PIO_H_)
 1078         else
 1079 #endif
 1080                 for (; count != 0; count--, addr += 2)
 1081                         *(volatile u_int16_t *)(addr) = value;
 1082 #endif
 1083 }
 1084 
 1085 static __inline void
 1086 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
 1087                        bus_size_t offset, u_int32_t value, size_t count)
 1088 {
 1089         bus_space_handle_t addr = bsh + offset;
 1090 
 1091 #if defined(_I386_BUS_PIO_H_)
 1092 #if defined(_I386_BUS_MEMIO_H_)
 1093         if (tag == I386_BUS_SPACE_IO)
 1094 #endif
 1095                 for (; count != 0; count--, addr += 4)
 1096                         outl(addr, value);
 1097 #endif
 1098 #if defined(_I386_BUS_MEMIO_H_)
 1099 #if defined(_I386_BUS_PIO_H_)
 1100         else
 1101 #endif
 1102                 for (; count != 0; count--, addr += 4)
 1103                         *(volatile u_int32_t *)(addr) = value;
 1104 #endif
 1105 }
 1106 
 1107 #if 0   /* Cause a link error for bus_space_set_region_8 */
 1108 #define bus_space_set_region_8  !!! bus_space_set_region_8 unimplemented !!!
 1109 #endif
 1110 
 1111 /*
 1112  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
 1113  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
 1114  */
 1115 
 1116 static __inline void bus_space_copy_region_1(bus_space_tag_t tag,
 1117                                              bus_space_handle_t bsh1,
 1118                                              bus_size_t off1,
 1119                                              bus_space_handle_t bsh2,
 1120                                              bus_size_t off2, size_t count);
 1121 
 1122 static __inline void bus_space_copy_region_2(bus_space_tag_t tag,
 1123                                              bus_space_handle_t bsh1,
 1124                                              bus_size_t off1,
 1125                                              bus_space_handle_t bsh2,
 1126                                              bus_size_t off2, size_t count);
 1127 
 1128 static __inline void bus_space_copy_region_4(bus_space_tag_t tag,
 1129                                              bus_space_handle_t bsh1,
 1130                                              bus_size_t off1,
 1131                                              bus_space_handle_t bsh2,
 1132                                              bus_size_t off2, size_t count);
 1133 
 1134 static __inline void
 1135 bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
 1136                         bus_size_t off1, bus_space_handle_t bsh2,
 1137                         bus_size_t off2, size_t count)
 1138 {
 1139         bus_space_handle_t addr1 = bsh1 + off1;
 1140         bus_space_handle_t addr2 = bsh2 + off2;
 1141 
 1142 #if defined(_I386_BUS_PIO_H_)
 1143 #if defined(_I386_BUS_MEMIO_H_)
 1144         if (tag == I386_BUS_SPACE_IO)
 1145 #endif
 1146         {
 1147                 if (addr1 >= addr2) {
 1148                         /* src after dest: copy forward */
 1149                         for (; count != 0; count--, addr1++, addr2++)
 1150                                 outb(addr2, inb(addr1));
 1151                 } else {
 1152                         /* dest after src: copy backwards */
 1153                         for (addr1 += (count - 1), addr2 += (count - 1);
 1154                             count != 0; count--, addr1--, addr2--)
 1155                                 outb(addr2, inb(addr1));
 1156                 }
 1157         }
 1158 #endif
 1159 #if defined(_I386_BUS_MEMIO_H_)
 1160 #if defined(_I386_BUS_PIO_H_)
 1161         else
 1162 #endif
 1163         {
 1164                 if (addr1 >= addr2) {
 1165                         /* src after dest: copy forward */
 1166                         for (; count != 0; count--, addr1++, addr2++)
 1167                                 *(volatile u_int8_t *)(addr2) =
 1168                                     *(volatile u_int8_t *)(addr1);
 1169                 } else {
 1170                         /* dest after src: copy backwards */
 1171                         for (addr1 += (count - 1), addr2 += (count - 1);
 1172                             count != 0; count--, addr1--, addr2--)
 1173                                 *(volatile u_int8_t *)(addr2) =
 1174                                     *(volatile u_int8_t *)(addr1);
 1175                 }
 1176         }
 1177 #endif
 1178 }
 1179 
 1180 static __inline void
 1181 bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
 1182                         bus_size_t off1, bus_space_handle_t bsh2,
 1183                         bus_size_t off2, size_t count)
 1184 {
 1185         bus_space_handle_t addr1 = bsh1 + off1;
 1186         bus_space_handle_t addr2 = bsh2 + off2;
 1187 
 1188 #if defined(_I386_BUS_PIO_H_)
 1189 #if defined(_I386_BUS_MEMIO_H_)
 1190         if (tag == I386_BUS_SPACE_IO)
 1191 #endif
 1192         {
 1193                 if (addr1 >= addr2) {
 1194                         /* src after dest: copy forward */
 1195                         for (; count != 0; count--, addr1 += 2, addr2 += 2)
 1196                                 outw(addr2, inw(addr1));
 1197                 } else {
 1198                         /* dest after src: copy backwards */
 1199                         for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
 1200                             count != 0; count--, addr1 -= 2, addr2 -= 2)
 1201                                 outw(addr2, inw(addr1));
 1202                 }
 1203         }
 1204 #endif
 1205 #if defined(_I386_BUS_MEMIO_H_)
 1206 #if defined(_I386_BUS_PIO_H_)
 1207         else
 1208 #endif
 1209         {
 1210                 if (addr1 >= addr2) {
 1211                         /* src after dest: copy forward */
 1212                         for (; count != 0; count--, addr1 += 2, addr2 += 2)
 1213                                 *(volatile u_int16_t *)(addr2) =
 1214                                     *(volatile u_int16_t *)(addr1);
 1215                 } else {
 1216                         /* dest after src: copy backwards */
 1217                         for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
 1218                             count != 0; count--, addr1 -= 2, addr2 -= 2)
 1219                                 *(volatile u_int16_t *)(addr2) =
 1220                                     *(volatile u_int16_t *)(addr1);
 1221                 }
 1222         }
 1223 #endif
 1224 }
 1225 
 1226 static __inline void
 1227 bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
 1228                         bus_size_t off1, bus_space_handle_t bsh2,
 1229                         bus_size_t off2, size_t count)
 1230 {
 1231         bus_space_handle_t addr1 = bsh1 + off1;
 1232         bus_space_handle_t addr2 = bsh2 + off2;
 1233 
 1234 #if defined(_I386_BUS_PIO_H_)
 1235 #if defined(_I386_BUS_MEMIO_H_)
 1236         if (tag == I386_BUS_SPACE_IO)
 1237 #endif
 1238         {
 1239                 if (addr1 >= addr2) {
 1240                         /* src after dest: copy forward */
 1241                         for (; count != 0; count--, addr1 += 4, addr2 += 4)
 1242                                 outl(addr2, inl(addr1));
 1243                 } else {
 1244                         /* dest after src: copy backwards */
 1245                         for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
 1246                             count != 0; count--, addr1 -= 4, addr2 -= 4)
 1247                                 outl(addr2, inl(addr1));
 1248                 }
 1249         }
 1250 #endif
 1251 #if defined(_I386_BUS_MEMIO_H_)
 1252 #if defined(_I386_BUS_PIO_H_)
 1253         else
 1254 #endif
 1255         {
 1256                 if (addr1 >= addr2) {
 1257                         /* src after dest: copy forward */
 1258                         for (; count != 0; count--, addr1 += 4, addr2 += 4)
 1259                                 *(volatile u_int32_t *)(addr2) =
 1260                                     *(volatile u_int32_t *)(addr1);
 1261                 } else {
 1262                         /* dest after src: copy backwards */
 1263                         for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
 1264                             count != 0; count--, addr1 -= 4, addr2 -= 4)
 1265                                 *(volatile u_int32_t *)(addr2) =
 1266                                     *(volatile u_int32_t *)(addr1);
 1267                 }
 1268         }
 1269 #endif
 1270 }
 1271 
 1272 #endif /* defined(_I386_BUS_PIO_H_) || defined(_I386_MEM_IO_H_) */
 1273 
 1274 #if 0   /* Cause a link error for bus_space_copy_8 */
 1275 #define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!!
 1276 #endif
 1277 
 1278 /*
 1279  * Bus read/write barrier methods.
 1280  *
 1281  *      void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
 1282  *                             bus_size_t offset, bus_size_t len, int flags);
 1283  *
 1284  *
 1285  * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
 1286  * prevent reordering by the compiler; all Intel x86 processors currently
 1287  * retire operations outside the CPU in program order.
 1288  */
 1289 #define BUS_SPACE_BARRIER_READ  0x01            /* force read barrier */
 1290 #define BUS_SPACE_BARRIER_WRITE 0x02            /* force write barrier */
 1291 
 1292 static __inline void
 1293 bus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
 1294                   bus_size_t offset __unused, bus_size_t len __unused, int flags)
 1295 {
 1296 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
 1297         if (flags & BUS_SPACE_BARRIER_READ)
 1298                 __asm __volatile("lock; addl $0,0(%%esp)" : : : "memory");
 1299         else
 1300                 __asm __volatile("" : : : "memory");
 1301 #else
 1302 # ifndef lint
 1303 #  error "no assembler code for your compiler"
 1304 # endif
 1305 #endif
 1306 }
 1307 
 1308 #endif /* _I386_BUS_AT386_H_ */

Cache object: f5ada1c6b6469528e73330f42d74a46e


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