Home | History | Annotate | Line # | Download | only in pci
      1  1.24   thorpej /* $NetBSD: pci_bwx_bus_io_chipdep.c,v 1.24 2023/12/06 01:46:34 thorpej Exp $ */
      2   1.1   thorpej 
      3   1.1   thorpej /*-
      4   1.7   thorpej  * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
      5   1.1   thorpej  * All rights reserved.
      6   1.1   thorpej  *
      7   1.1   thorpej  * This code is derived from software contributed to The NetBSD Foundation
      8   1.1   thorpej  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
      9   1.1   thorpej  * NASA Ames Research Center.
     10   1.1   thorpej  *
     11   1.1   thorpej  * Redistribution and use in source and binary forms, with or without
     12   1.1   thorpej  * modification, are permitted provided that the following conditions
     13   1.1   thorpej  * are met:
     14   1.1   thorpej  * 1. Redistributions of source code must retain the above copyright
     15   1.1   thorpej  *    notice, this list of conditions and the following disclaimer.
     16   1.1   thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     17   1.1   thorpej  *    notice, this list of conditions and the following disclaimer in the
     18   1.1   thorpej  *    documentation and/or other materials provided with the distribution.
     19   1.1   thorpej  *
     20   1.1   thorpej  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21   1.1   thorpej  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22   1.1   thorpej  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23   1.1   thorpej  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24   1.1   thorpej  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25   1.1   thorpej  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26   1.1   thorpej  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27   1.1   thorpej  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28   1.1   thorpej  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29   1.1   thorpej  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30   1.1   thorpej  * POSSIBILITY OF SUCH DAMAGE.
     31   1.1   thorpej  */
     32   1.1   thorpej 
     33   1.1   thorpej /*
     34   1.1   thorpej  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
     35   1.1   thorpej  * All rights reserved.
     36   1.1   thorpej  *
     37   1.1   thorpej  * Author: Chris G. Demetriou
     38  1.21      matt  *
     39   1.1   thorpej  * Permission to use, copy, modify and distribute this software and
     40   1.1   thorpej  * its documentation is hereby granted, provided that both the copyright
     41   1.1   thorpej  * notice and this permission notice appear in all copies of the
     42   1.1   thorpej  * software, derivative works or modified versions, and any portions
     43   1.1   thorpej  * thereof, and that both notices appear in supporting documentation.
     44  1.21      matt  *
     45  1.21      matt  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     46  1.21      matt  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
     47   1.1   thorpej  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     48  1.21      matt  *
     49   1.1   thorpej  * Carnegie Mellon requests users of this software to return to
     50   1.1   thorpej  *
     51   1.1   thorpej  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     52   1.1   thorpej  *  School of Computer Science
     53   1.1   thorpej  *  Carnegie Mellon University
     54   1.1   thorpej  *  Pittsburgh PA 15213-3890
     55   1.1   thorpej  *
     56   1.1   thorpej  * any improvements or extensions that they make and grant Carnegie the
     57   1.1   thorpej  * rights to redistribute these changes.
     58   1.1   thorpej  */
     59   1.1   thorpej 
     60   1.1   thorpej /*
     61   1.1   thorpej  * Common PCI Chipset "bus I/O" functions, for chipsets which have to
     62   1.1   thorpej  * deal with only a single PCI interface chip in a machine.
     63   1.1   thorpej  *
     64   1.1   thorpej  * uses:
     65   1.1   thorpej  *	CHIP		name of the 'chip' it's being compiled for.
     66   1.1   thorpej  *	CHIP_IO_BASE	I/O space base to use.
     67  1.23   thorpej  *	CHIP_IO_ARENA_STORE
     68   1.1   thorpej  *			If defined, device-provided static storage area
     69  1.23   thorpej  *			for the I/O space arena.  If this is defined,
     70  1.23   thorpej  *			CHIP_IO_BTAG_STORE and CHIP_IO_BTAG_COUNT must
     71  1.23   thorpej  *			also be defined.  If this is not defined, a
     72  1.23   thorpej  *			static area will be declared.
     73  1.23   thorpej  *	CHIP_IO_BTAG_STORE
     74  1.23   thorpej  *			Device-provided static storage area for the
     75  1.23   thorpej  *			I/O space arena's boundary tags.  Ignored
     76  1.23   thorpej  *			unless CHIP_IO_ARENA_STORE is defined.
     77  1.23   thorpej  *	CHIP_IO_BTAG_COUNT
     78  1.23   thorpej  *			The number of device-provided static I/O
     79  1.23   thorpej  *			space boundary tags.  Ignored unless
     80  1.23   thorpej  *			CHIP_IO_ARENA_STORE is defined.
     81   1.1   thorpej  */
     82  1.14     lukem 
     83  1.14     lukem #include <sys/cdefs.h>
     84  1.24   thorpej __KERNEL_RCSID(1, "$NetBSD: pci_bwx_bus_io_chipdep.c,v 1.24 2023/12/06 01:46:34 thorpej Exp $");
     85   1.1   thorpej 
     86  1.23   thorpej #include <sys/vmem_impl.h>
     87   1.6   thorpej 
     88   1.6   thorpej #include <machine/bwx.h>
     89   1.1   thorpej 
     90   1.1   thorpej #define	__C(A,B)	__CONCAT(A,B)
     91   1.1   thorpej #define	__S(S)		__STRING(S)
     92   1.1   thorpej 
     93   1.1   thorpej /* mapping/unmapping */
     94  1.22   thorpej static int	__C(CHIP,_io_map)(void *, bus_addr_t, bus_size_t, int,
     95  1.18       dsl 		    bus_space_handle_t *, int);
     96  1.22   thorpej static void	__C(CHIP,_io_unmap)(void *, bus_space_handle_t,
     97  1.18       dsl 		    bus_size_t, int);
     98  1.22   thorpej static int	__C(CHIP,_io_subregion)(void *, bus_space_handle_t,
     99  1.18       dsl 		    bus_size_t, bus_size_t, bus_space_handle_t *);
    100  1.18       dsl 
    101  1.22   thorpej static int	__C(CHIP,_io_translate)(void *, bus_addr_t, bus_size_t,
    102  1.18       dsl 		    int, struct alpha_bus_space_translation *);
    103  1.22   thorpej static int	__C(CHIP,_io_get_window)(void *, int,
    104  1.18       dsl 		    struct alpha_bus_space_translation *);
    105   1.7   thorpej 
    106   1.1   thorpej /* allocation/deallocation */
    107  1.22   thorpej static int	__C(CHIP,_io_alloc)(void *, bus_addr_t, bus_addr_t,
    108   1.1   thorpej 		    bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *,
    109  1.21      matt 	            bus_space_handle_t *);
    110  1.22   thorpej static void	__C(CHIP,_io_free)(void *, bus_space_handle_t,
    111  1.18       dsl 		    bus_size_t);
    112   1.1   thorpej 
    113   1.9  drochner /* get kernel virtual address */
    114  1.22   thorpej static void *	__C(CHIP,_io_vaddr)(void *, bus_space_handle_t);
    115   1.9  drochner 
    116  1.12   thorpej /* mmap for user */
    117  1.22   thorpej static paddr_t	__C(CHIP,_io_mmap)(void *, bus_addr_t, off_t, int, int);
    118  1.12   thorpej 
    119   1.1   thorpej /* barrier */
    120  1.22   thorpej static inline void __C(CHIP,_io_barrier)(void *, bus_space_handle_t,
    121  1.18       dsl 		    bus_size_t, bus_size_t, int);
    122   1.1   thorpej 
    123   1.1   thorpej /* read (single) */
    124  1.22   thorpej static inline uint8_t __C(CHIP,_io_read_1)(void *, bus_space_handle_t,
    125  1.18       dsl 		    bus_size_t);
    126  1.21      matt static inline uint16_t __C(CHIP,_io_read_2)(void *, bus_space_handle_t,
    127  1.18       dsl 		    bus_size_t);
    128  1.21      matt static inline uint32_t __C(CHIP,_io_read_4)(void *, bus_space_handle_t,
    129  1.18       dsl 		    bus_size_t);
    130  1.21      matt static inline uint64_t __C(CHIP,_io_read_8)(void *, bus_space_handle_t,
    131  1.18       dsl 		    bus_size_t);
    132   1.1   thorpej 
    133   1.1   thorpej /* read multiple */
    134  1.22   thorpej static void	__C(CHIP,_io_read_multi_1)(void *, bus_space_handle_t,
    135  1.21      matt 		    bus_size_t, uint8_t *, bus_size_t);
    136  1.22   thorpej static void	__C(CHIP,_io_read_multi_2)(void *, bus_space_handle_t,
    137  1.21      matt 		    bus_size_t, uint16_t *, bus_size_t);
    138  1.22   thorpej static void	__C(CHIP,_io_read_multi_4)(void *, bus_space_handle_t,
    139  1.21      matt 		    bus_size_t, uint32_t *, bus_size_t);
    140  1.22   thorpej static void	__C(CHIP,_io_read_multi_8)(void *, bus_space_handle_t,
    141  1.21      matt 		    bus_size_t, uint64_t *, bus_size_t);
    142   1.1   thorpej 
    143   1.1   thorpej /* read region */
    144  1.22   thorpej static void	__C(CHIP,_io_read_region_1)(void *, bus_space_handle_t,
    145  1.21      matt 		    bus_size_t, uint8_t *, bus_size_t);
    146  1.22   thorpej static void	__C(CHIP,_io_read_region_2)(void *, bus_space_handle_t,
    147  1.21      matt 		    bus_size_t, uint16_t *, bus_size_t);
    148  1.22   thorpej static void	__C(CHIP,_io_read_region_4)(void *, bus_space_handle_t,
    149  1.21      matt 		    bus_size_t, uint32_t *, bus_size_t);
    150  1.22   thorpej static void	__C(CHIP,_io_read_region_8)(void *, bus_space_handle_t,
    151  1.21      matt 		    bus_size_t, uint64_t *, bus_size_t);
    152   1.1   thorpej 
    153   1.1   thorpej /* write (single) */
    154  1.22   thorpej static inline void __C(CHIP,_io_write_1)(void *, bus_space_handle_t,
    155  1.21      matt 		    bus_size_t, uint8_t);
    156  1.22   thorpej static inline void __C(CHIP,_io_write_2)(void *, bus_space_handle_t,
    157  1.21      matt 		    bus_size_t, uint16_t);
    158  1.22   thorpej static inline void __C(CHIP,_io_write_4)(void *, bus_space_handle_t,
    159  1.21      matt 		    bus_size_t, uint32_t);
    160  1.22   thorpej static inline void __C(CHIP,_io_write_8)(void *, bus_space_handle_t,
    161  1.21      matt 		    bus_size_t, uint64_t);
    162   1.1   thorpej 
    163   1.1   thorpej /* write multiple */
    164  1.22   thorpej static void	__C(CHIP,_io_write_multi_1)(void *, bus_space_handle_t,
    165  1.21      matt 		    bus_size_t, const uint8_t *, bus_size_t);
    166  1.22   thorpej static void	__C(CHIP,_io_write_multi_2)(void *, bus_space_handle_t,
    167  1.21      matt 		    bus_size_t, const uint16_t *, bus_size_t);
    168  1.22   thorpej static void	__C(CHIP,_io_write_multi_4)(void *, bus_space_handle_t,
    169  1.21      matt 		    bus_size_t, const uint32_t *, bus_size_t);
    170  1.22   thorpej static void	__C(CHIP,_io_write_multi_8)(void *, bus_space_handle_t,
    171  1.21      matt 		    bus_size_t, const uint64_t *, bus_size_t);
    172   1.1   thorpej 
    173   1.1   thorpej /* write region */
    174  1.22   thorpej static void	__C(CHIP,_io_write_region_1)(void *, bus_space_handle_t,
    175  1.21      matt 		    bus_size_t, const uint8_t *, bus_size_t);
    176  1.22   thorpej static void	__C(CHIP,_io_write_region_2)(void *, bus_space_handle_t,
    177  1.21      matt 		    bus_size_t, const uint16_t *, bus_size_t);
    178  1.22   thorpej static void	__C(CHIP,_io_write_region_4)(void *, bus_space_handle_t,
    179  1.21      matt 		    bus_size_t, const uint32_t *, bus_size_t);
    180  1.22   thorpej static void	__C(CHIP,_io_write_region_8)(void *, bus_space_handle_t,
    181  1.21      matt 		    bus_size_t, const uint64_t *, bus_size_t);
    182   1.1   thorpej 
    183   1.1   thorpej /* set multiple */
    184  1.22   thorpej static void	__C(CHIP,_io_set_multi_1)(void *, bus_space_handle_t,
    185  1.21      matt 		    bus_size_t, uint8_t, bus_size_t);
    186  1.22   thorpej static void	__C(CHIP,_io_set_multi_2)(void *, bus_space_handle_t,
    187  1.21      matt 		    bus_size_t, uint16_t, bus_size_t);
    188  1.22   thorpej static void	__C(CHIP,_io_set_multi_4)(void *, bus_space_handle_t,
    189  1.21      matt 		    bus_size_t, uint32_t, bus_size_t);
    190  1.22   thorpej static void	__C(CHIP,_io_set_multi_8)(void *, bus_space_handle_t,
    191  1.21      matt 		    bus_size_t, uint64_t, bus_size_t);
    192   1.1   thorpej 
    193   1.1   thorpej /* set region */
    194  1.22   thorpej static void	__C(CHIP,_io_set_region_1)(void *, bus_space_handle_t,
    195  1.21      matt 		    bus_size_t, uint8_t, bus_size_t);
    196  1.22   thorpej static void	__C(CHIP,_io_set_region_2)(void *, bus_space_handle_t,
    197  1.21      matt 		    bus_size_t, uint16_t, bus_size_t);
    198  1.22   thorpej static void	__C(CHIP,_io_set_region_4)(void *, bus_space_handle_t,
    199  1.21      matt 		    bus_size_t, uint32_t, bus_size_t);
    200  1.22   thorpej static void	__C(CHIP,_io_set_region_8)(void *, bus_space_handle_t,
    201  1.21      matt 		    bus_size_t, uint64_t, bus_size_t);
    202   1.1   thorpej 
    203   1.1   thorpej /* copy */
    204  1.22   thorpej static void	__C(CHIP,_io_copy_region_1)(void *, bus_space_handle_t,
    205  1.18       dsl 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
    206  1.22   thorpej static void	__C(CHIP,_io_copy_region_2)(void *, bus_space_handle_t,
    207  1.18       dsl 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
    208  1.22   thorpej static void	__C(CHIP,_io_copy_region_4)(void *, bus_space_handle_t,
    209  1.18       dsl 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
    210  1.22   thorpej static void	__C(CHIP,_io_copy_region_8)(void *, bus_space_handle_t,
    211  1.18       dsl 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
    212   1.1   thorpej 
    213  1.23   thorpej #ifndef CHIP_IO_ARENA_STORE
    214  1.23   thorpej #define	CHIP_IO_BTAG_COUNT(v)	VMEM_EST_BTCOUNT(1, 8)
    215  1.23   thorpej #define	CHIP_IO_BTAG_STORE(v)	__C(CHIP,_io_btag_store)
    216  1.23   thorpej #define	CHIP_IO_ARENA_STORE(v)	(&(__C(CHIP,_io_arena_store)))
    217  1.23   thorpej 
    218  1.23   thorpej static struct vmem __C(CHIP,_io_arena_store);
    219  1.23   thorpej static struct vmem_btag __C(CHIP,_io_btag_store)[CHIP_IO_BTAG_COUNT(xxx)];
    220  1.23   thorpej #endif /* CHIP_IO_ARENA_STORE */
    221   1.1   thorpej 
    222   1.1   thorpej void
    223  1.21      matt __C(CHIP,_bus_io_init)(
    224  1.21      matt 	bus_space_tag_t t,
    225  1.21      matt 	void *v)
    226   1.1   thorpej {
    227  1.23   thorpej 	vmem_t *vm;
    228  1.23   thorpej 	int error __diagused;
    229   1.1   thorpej 
    230   1.1   thorpej 	/*
    231   1.1   thorpej 	 * Initialize the bus space tag.
    232   1.1   thorpej 	 */
    233   1.1   thorpej 
    234   1.1   thorpej 	/* cookie */
    235   1.1   thorpej 	t->abs_cookie =		v;
    236   1.1   thorpej 
    237   1.1   thorpej 	/* mapping/unmapping */
    238   1.1   thorpej 	t->abs_map =		__C(CHIP,_io_map);
    239   1.1   thorpej 	t->abs_unmap =		__C(CHIP,_io_unmap);
    240   1.1   thorpej 	t->abs_subregion =	__C(CHIP,_io_subregion);
    241   1.1   thorpej 
    242   1.7   thorpej 	t->abs_translate =	__C(CHIP,_io_translate);
    243   1.8   thorpej 	t->abs_get_window =	__C(CHIP,_io_get_window);
    244   1.7   thorpej 
    245   1.1   thorpej 	/* allocation/deallocation */
    246   1.1   thorpej 	t->abs_alloc =		__C(CHIP,_io_alloc);
    247   1.1   thorpej 	t->abs_free = 		__C(CHIP,_io_free);
    248   1.1   thorpej 
    249   1.9  drochner 	/* get kernel virtual address */
    250   1.9  drochner 	t->abs_vaddr =		__C(CHIP,_io_vaddr);
    251   1.9  drochner 
    252  1.12   thorpej 	/* mmap for user */
    253  1.12   thorpej 	t->abs_mmap =		__C(CHIP,_io_mmap);
    254  1.12   thorpej 
    255   1.1   thorpej 	/* barrier */
    256   1.1   thorpej 	t->abs_barrier =	__C(CHIP,_io_barrier);
    257   1.1   thorpej 
    258   1.1   thorpej 	/* read (single) */
    259   1.1   thorpej 	t->abs_r_1 =		__C(CHIP,_io_read_1);
    260   1.1   thorpej 	t->abs_r_2 =		__C(CHIP,_io_read_2);
    261   1.1   thorpej 	t->abs_r_4 =		__C(CHIP,_io_read_4);
    262   1.1   thorpej 	t->abs_r_8 =		__C(CHIP,_io_read_8);
    263   1.1   thorpej 
    264   1.1   thorpej 	/* read multiple */
    265   1.1   thorpej 	t->abs_rm_1 =		__C(CHIP,_io_read_multi_1);
    266   1.1   thorpej 	t->abs_rm_2 =		__C(CHIP,_io_read_multi_2);
    267   1.1   thorpej 	t->abs_rm_4 =		__C(CHIP,_io_read_multi_4);
    268   1.1   thorpej 	t->abs_rm_8 =		__C(CHIP,_io_read_multi_8);
    269   1.1   thorpej 
    270   1.1   thorpej 	/* read region */
    271   1.1   thorpej 	t->abs_rr_1 =		__C(CHIP,_io_read_region_1);
    272   1.1   thorpej 	t->abs_rr_2 =		__C(CHIP,_io_read_region_2);
    273   1.1   thorpej 	t->abs_rr_4 =		__C(CHIP,_io_read_region_4);
    274   1.1   thorpej 	t->abs_rr_8 =		__C(CHIP,_io_read_region_8);
    275   1.1   thorpej 
    276   1.1   thorpej 	/* write (single) */
    277   1.1   thorpej 	t->abs_w_1 =		__C(CHIP,_io_write_1);
    278   1.1   thorpej 	t->abs_w_2 =		__C(CHIP,_io_write_2);
    279   1.1   thorpej 	t->abs_w_4 =		__C(CHIP,_io_write_4);
    280   1.1   thorpej 	t->abs_w_8 =		__C(CHIP,_io_write_8);
    281   1.1   thorpej 
    282   1.1   thorpej 	/* write multiple */
    283   1.1   thorpej 	t->abs_wm_1 =		__C(CHIP,_io_write_multi_1);
    284   1.1   thorpej 	t->abs_wm_2 =		__C(CHIP,_io_write_multi_2);
    285   1.1   thorpej 	t->abs_wm_4 =		__C(CHIP,_io_write_multi_4);
    286   1.1   thorpej 	t->abs_wm_8 =		__C(CHIP,_io_write_multi_8);
    287   1.1   thorpej 
    288   1.1   thorpej 	/* write region */
    289   1.1   thorpej 	t->abs_wr_1 =		__C(CHIP,_io_write_region_1);
    290   1.1   thorpej 	t->abs_wr_2 =		__C(CHIP,_io_write_region_2);
    291   1.1   thorpej 	t->abs_wr_4 =		__C(CHIP,_io_write_region_4);
    292   1.1   thorpej 	t->abs_wr_8 =		__C(CHIP,_io_write_region_8);
    293   1.1   thorpej 
    294   1.1   thorpej 	/* set multiple */
    295   1.1   thorpej 	t->abs_sm_1 =		__C(CHIP,_io_set_multi_1);
    296   1.1   thorpej 	t->abs_sm_2 =		__C(CHIP,_io_set_multi_2);
    297   1.1   thorpej 	t->abs_sm_4 =		__C(CHIP,_io_set_multi_4);
    298   1.1   thorpej 	t->abs_sm_8 =		__C(CHIP,_io_set_multi_8);
    299   1.1   thorpej 
    300   1.1   thorpej 	/* set region */
    301   1.1   thorpej 	t->abs_sr_1 =		__C(CHIP,_io_set_region_1);
    302   1.1   thorpej 	t->abs_sr_2 =		__C(CHIP,_io_set_region_2);
    303   1.1   thorpej 	t->abs_sr_4 =		__C(CHIP,_io_set_region_4);
    304   1.1   thorpej 	t->abs_sr_8 =		__C(CHIP,_io_set_region_8);
    305   1.1   thorpej 
    306   1.1   thorpej 	/* copy */
    307   1.1   thorpej 	t->abs_c_1 =		__C(CHIP,_io_copy_region_1);
    308   1.1   thorpej 	t->abs_c_2 =		__C(CHIP,_io_copy_region_2);
    309   1.1   thorpej 	t->abs_c_4 =		__C(CHIP,_io_copy_region_4);
    310   1.1   thorpej 	t->abs_c_8 =		__C(CHIP,_io_copy_region_8);
    311   1.1   thorpej 
    312  1.23   thorpej 	vm = vmem_init(CHIP_IO_ARENA_STORE(v),
    313  1.23   thorpej 		       __S(__C(CHIP,_bus_io)),		/* name */
    314  1.23   thorpej 		       0,				/* addr */
    315  1.23   thorpej 		       0,				/* size */
    316  1.23   thorpej 		       1,				/* quantum */
    317  1.23   thorpej 		       NULL,				/* importfn */
    318  1.23   thorpej 		       NULL,				/* releasefn */
    319  1.23   thorpej 		       NULL,				/* source */
    320  1.23   thorpej 		       0,				/* qcache_max */
    321  1.23   thorpej 		       VM_NOSLEEP | VM_PRIVTAGS,
    322  1.23   thorpej 		       IPL_NONE);
    323  1.23   thorpej 	KASSERT(vm != NULL);
    324  1.23   thorpej 
    325  1.23   thorpej 	vmem_add_bts(vm, CHIP_IO_BTAG_STORE(v), CHIP_IO_BTAG_COUNT(v));
    326  1.23   thorpej 	error = vmem_add(vm, 0, 0x100000000UL, VM_NOSLEEP);
    327  1.23   thorpej 	KASSERT(error == 0);
    328   1.1   thorpej 
    329  1.23   thorpej 	CHIP_IO_ARENA(v) = vm;
    330   1.1   thorpej }
    331   1.1   thorpej 
    332  1.22   thorpej static int
    333  1.21      matt __C(CHIP,_io_translate)(
    334  1.21      matt 	void *v,
    335  1.21      matt 	bus_addr_t ioaddr,
    336  1.21      matt 	bus_size_t iolen,
    337  1.21      matt 	int flags,
    338  1.21      matt 	struct alpha_bus_space_translation *abst)
    339   1.7   thorpej {
    340   1.7   thorpej 	int linear = flags & BUS_SPACE_MAP_LINEAR;
    341   1.7   thorpej 
    342   1.7   thorpej 	/*
    343   1.7   thorpej 	 * Can't map i/o space linearly.
    344   1.7   thorpej 	 */
    345   1.7   thorpej 	if (linear)
    346   1.7   thorpej 		return (EOPNOTSUPP);
    347   1.7   thorpej 
    348   1.8   thorpej 	return (__C(CHIP,_io_get_window)(v, 0, abst));
    349   1.8   thorpej }
    350   1.8   thorpej 
    351  1.22   thorpej static int
    352  1.21      matt __C(CHIP,_io_get_window)(
    353  1.21      matt 	void *v,
    354  1.21      matt 	int window,
    355  1.21      matt 	struct alpha_bus_space_translation *abst)
    356   1.8   thorpej {
    357   1.8   thorpej 
    358   1.8   thorpej 	switch (window) {
    359   1.8   thorpej 	case 0:
    360   1.8   thorpej 		abst->abst_bus_start = 0;
    361   1.8   thorpej 		abst->abst_bus_end = 0xffffffffUL;
    362  1.11   thorpej 		abst->abst_sys_start = CHIP_IO_SYS_START(v);
    363  1.11   thorpej 		abst->abst_sys_end = CHIP_IO_SYS_START(v) + abst->abst_bus_end;
    364   1.8   thorpej 		abst->abst_addr_shift = 0;
    365   1.8   thorpej 		abst->abst_size_shift = 0;
    366   1.8   thorpej 		abst->abst_flags = ABST_DENSE|ABST_BWX;
    367   1.8   thorpej 		break;
    368   1.8   thorpej 
    369   1.8   thorpej 	default:
    370   1.8   thorpej 		panic(__S(__C(CHIP,_io_get_window)) ": invalid window %d",
    371   1.8   thorpej 		    window);
    372   1.8   thorpej 	}
    373   1.8   thorpej 
    374   1.7   thorpej 	return (0);
    375   1.7   thorpej }
    376   1.7   thorpej 
    377  1.22   thorpej static int
    378  1.21      matt __C(CHIP,_io_map)(
    379  1.21      matt 	void *v,
    380  1.21      matt 	bus_addr_t ioaddr,
    381  1.21      matt 	bus_size_t iosize,
    382  1.21      matt 	int flags,
    383  1.21      matt 	bus_space_handle_t *iohp,
    384  1.21      matt 	int acct)
    385   1.1   thorpej {
    386   1.7   thorpej 	struct alpha_bus_space_translation abst;
    387   1.1   thorpej 	int error;
    388   1.1   thorpej 
    389   1.1   thorpej 	/*
    390   1.7   thorpej 	 * Get the translation for this address.
    391   1.1   thorpej 	 */
    392   1.7   thorpej 	error = __C(CHIP,_io_translate)(v, ioaddr, iosize, flags, &abst);
    393   1.7   thorpej 	if (error)
    394   1.7   thorpej 		return (error);
    395   1.1   thorpej 
    396   1.4   thorpej 	if (acct == 0)
    397   1.4   thorpej 		goto mapit;
    398   1.4   thorpej 
    399   1.1   thorpej #ifdef EXTENT_DEBUG
    400   1.1   thorpej 	printf("io: allocating 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
    401   1.1   thorpej #endif
    402  1.23   thorpej 	error = vmem_xalloc_addr(CHIP_IO_ARENA(v), ioaddr, iosize, VM_NOSLEEP);
    403   1.1   thorpej 	if (error) {
    404   1.1   thorpej #ifdef EXTENT_DEBUG
    405   1.1   thorpej 		printf("io: allocation failed (%d)\n", error);
    406  1.23   thorpej 		/* vmem_print(CHIP_IO_ARENA(v));	XXX */
    407   1.1   thorpej #endif
    408   1.1   thorpej 		return (error);
    409   1.1   thorpej 	}
    410   1.1   thorpej 
    411   1.4   thorpej  mapit:
    412   1.7   thorpej 	*iohp = ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start + ioaddr);
    413   1.1   thorpej 
    414   1.1   thorpej 	return (0);
    415   1.1   thorpej }
    416   1.1   thorpej 
    417  1.22   thorpej static void
    418  1.21      matt __C(CHIP,_io_unmap)(
    419  1.21      matt 	void *v,
    420  1.21      matt 	bus_space_handle_t ioh,
    421  1.21      matt 	bus_size_t iosize,
    422  1.21      matt 	int acct)
    423   1.1   thorpej {
    424   1.1   thorpej 	bus_addr_t ioaddr;
    425   1.1   thorpej 
    426   1.4   thorpej 	if (acct == 0)
    427   1.4   thorpej 		return;
    428   1.4   thorpej 
    429   1.1   thorpej #ifdef EXTENT_DEBUG
    430   1.1   thorpej 	printf("io: freeing handle 0x%lx for 0x%lx\n", ioh, iosize);
    431   1.1   thorpej #endif
    432   1.1   thorpej 
    433   1.1   thorpej 	ioaddr = ioh - ALPHA_PHYS_TO_K0SEG(CHIP_IO_SYS_START(v));
    434   1.1   thorpej 
    435   1.1   thorpej #ifdef EXTENT_DEBUG
    436   1.1   thorpej 	printf("io: freeing 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
    437   1.1   thorpej #endif
    438  1.23   thorpej 	vmem_xfree(CHIP_IO_ARENA(v), ioaddr, iosize);
    439   1.1   thorpej }
    440   1.1   thorpej 
    441  1.22   thorpej static int
    442  1.21      matt __C(CHIP,_io_subregion)(
    443  1.21      matt 	void *v,
    444  1.21      matt 	bus_space_handle_t ioh,
    445  1.21      matt 	bus_size_t offset,
    446  1.21      matt 	bus_size_t size,
    447  1.21      matt 	bus_space_handle_t *nioh)
    448   1.1   thorpej {
    449   1.1   thorpej 
    450   1.1   thorpej 	*nioh = ioh + offset;
    451   1.1   thorpej 	return (0);
    452   1.1   thorpej }
    453   1.1   thorpej 
    454  1.22   thorpej static int
    455  1.21      matt __C(CHIP,_io_alloc)(
    456  1.21      matt 	void *v,
    457  1.21      matt 	bus_addr_t rstart,
    458  1.21      matt 	bus_addr_t rend,
    459  1.21      matt 	bus_size_t size,
    460  1.21      matt 	bus_size_t align,
    461  1.21      matt 	bus_size_t boundary,
    462  1.21      matt 	int flags,
    463  1.21      matt 	bus_addr_t *addrp,
    464  1.21      matt 	bus_space_handle_t *bshp)
    465   1.1   thorpej {
    466   1.7   thorpej 	struct alpha_bus_space_translation abst;
    467   1.2   thorpej 	int linear = flags & BUS_SPACE_MAP_LINEAR;
    468  1.23   thorpej 	vmem_addr_t ioaddr;
    469  1.21      matt 	int error;
    470   1.1   thorpej 
    471   1.2   thorpej 	/*
    472   1.2   thorpej 	 * Can't map i/o space linearly.
    473   1.2   thorpej 	 */
    474   1.2   thorpej 	if (linear)
    475   1.2   thorpej 		return (EOPNOTSUPP);
    476   1.2   thorpej 
    477   1.2   thorpej 	/*
    478   1.2   thorpej 	 * Do the requested allocation.
    479   1.2   thorpej 	 */
    480   1.2   thorpej #ifdef EXTENT_DEBUG
    481   1.2   thorpej 	printf("io: allocating from 0x%lx to 0x%lx\n", rstart, rend);
    482   1.2   thorpej #endif
    483  1.23   thorpej 	error = vmem_xalloc(CHIP_IO_ARENA(v), size,
    484  1.23   thorpej 			    align,		/* align */
    485  1.23   thorpej 			    0,			/* phase */
    486  1.23   thorpej 			    boundary,		/* nocross */
    487  1.23   thorpej 			    rstart,		/* minaddr */
    488  1.23   thorpej 			    rend,		/* maxaddr */
    489  1.24   thorpej 			    VM_BESTFIT | VM_NOSLEEP,
    490  1.23   thorpej 			    &ioaddr);
    491   1.2   thorpej 	if (error) {
    492   1.2   thorpej #ifdef EXTENT_DEBUG
    493   1.2   thorpej 		printf("io: allocation failed (%d)\n", error);
    494  1.23   thorpej 		/* vmem_print(CHIP_IO_ARENA(v));	XXX */
    495   1.2   thorpej #endif
    496   1.2   thorpej 		return (error);
    497   1.2   thorpej 	}
    498   1.2   thorpej 
    499   1.2   thorpej #ifdef EXTENT_DEBUG
    500   1.2   thorpej 	printf("io: allocated 0x%lx to 0x%lx\n", ioaddr, ioaddr + size - 1);
    501   1.2   thorpej #endif
    502   1.2   thorpej 
    503   1.7   thorpej 	error = __C(CHIP,_io_translate)(v, ioaddr, size, flags, &abst);
    504   1.7   thorpej 	if (error) {
    505  1.23   thorpej 		vmem_xfree(CHIP_IO_ARENA(v), ioaddr, size);
    506   1.7   thorpej 		return (error);
    507   1.7   thorpej 	}
    508   1.7   thorpej 
    509   1.3   thorpej 	*addrp = ioaddr;
    510   1.7   thorpej 	*bshp = ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start + ioaddr);
    511   1.2   thorpej 
    512   1.2   thorpej 	return (0);
    513   1.1   thorpej }
    514   1.1   thorpej 
    515  1.22   thorpej static void
    516  1.21      matt __C(CHIP,_io_free)(
    517  1.21      matt 	void *v,
    518  1.21      matt 	bus_space_handle_t bsh,
    519  1.21      matt 	bus_size_t size)
    520   1.1   thorpej {
    521   1.1   thorpej 
    522   1.2   thorpej 	/* Unmap does all we need to do. */
    523   1.4   thorpej 	__C(CHIP,_io_unmap)(v, bsh, size, 1);
    524   1.9  drochner }
    525   1.9  drochner 
    526  1.22   thorpej static void *
    527  1.21      matt __C(CHIP,_io_vaddr)(
    528  1.21      matt 	void *v,
    529  1.21      matt 	bus_space_handle_t bsh)
    530   1.9  drochner {
    531   1.9  drochner 	/*
    532   1.9  drochner 	 * _io_translate() catches BUS_SPACE_MAP_LINEAR,
    533   1.9  drochner 	 * so we shouldn't get here
    534   1.9  drochner 	 */
    535   1.9  drochner 	panic("_io_vaddr");
    536  1.12   thorpej }
    537  1.12   thorpej 
    538  1.22   thorpej static paddr_t
    539  1.21      matt __C(CHIP,_io_mmap)(
    540  1.21      matt 	void *v,
    541  1.21      matt 	bus_addr_t addr,
    542  1.21      matt 	off_t off,
    543  1.21      matt 	int prot,
    544  1.21      matt 	int flags)
    545  1.12   thorpej {
    546  1.12   thorpej 
    547  1.12   thorpej 	/* Not supported for I/O space. */
    548  1.12   thorpej 	return (-1);
    549   1.1   thorpej }
    550   1.1   thorpej 
    551  1.19       chs static inline void
    552  1.21      matt __C(CHIP,_io_barrier)(
    553  1.21      matt 	void *v,
    554  1.21      matt 	bus_space_handle_t h,
    555  1.21      matt 	bus_size_t o,
    556  1.21      matt 	bus_size_t l,
    557  1.21      matt 	int f)
    558   1.1   thorpej {
    559   1.1   thorpej 
    560   1.1   thorpej 	if ((f & BUS_SPACE_BARRIER_READ) != 0)
    561   1.1   thorpej 		alpha_mb();
    562   1.1   thorpej 	else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
    563   1.1   thorpej 		alpha_wmb();
    564   1.1   thorpej }
    565   1.1   thorpej 
    566  1.21      matt static inline uint8_t
    567  1.21      matt __C(CHIP,_io_read_1)(
    568  1.21      matt 	void *v,
    569  1.21      matt 	bus_space_handle_t ioh,
    570  1.21      matt 	bus_size_t off)
    571   1.1   thorpej {
    572   1.1   thorpej 	bus_addr_t addr;
    573   1.1   thorpej 
    574   1.1   thorpej 	addr = ioh + off;
    575   1.1   thorpej 	alpha_mb();
    576  1.21      matt 	return (alpha_ldbu((uint8_t *)addr));
    577   1.1   thorpej }
    578   1.1   thorpej 
    579  1.21      matt static inline uint16_t
    580  1.21      matt __C(CHIP,_io_read_2)(
    581  1.21      matt 	void *v,
    582  1.21      matt 	bus_space_handle_t ioh,
    583  1.21      matt 	bus_size_t off)
    584   1.1   thorpej {
    585   1.1   thorpej 	bus_addr_t addr;
    586   1.1   thorpej 
    587   1.1   thorpej 	addr = ioh + off;
    588   1.1   thorpej #ifdef DIAGNOSTIC
    589   1.1   thorpej 	if (addr & 1)
    590   1.1   thorpej 		panic(__S(__C(CHIP,_io_read_2)) ": addr 0x%lx not aligned",
    591   1.1   thorpej 		    addr);
    592   1.1   thorpej #endif
    593   1.1   thorpej 	alpha_mb();
    594  1.21      matt 	return (alpha_ldwu((uint16_t *)addr));
    595   1.1   thorpej }
    596   1.1   thorpej 
    597  1.21      matt static inline uint32_t
    598  1.21      matt __C(CHIP,_io_read_4)(
    599  1.21      matt 	void *v,
    600  1.21      matt 	bus_space_handle_t ioh,
    601  1.21      matt 	bus_size_t off)
    602   1.1   thorpej {
    603   1.1   thorpej 	bus_addr_t addr;
    604   1.1   thorpej 
    605   1.1   thorpej 	addr = ioh + off;
    606   1.1   thorpej #ifdef DIAGNOSTIC
    607   1.1   thorpej 	if (addr & 3)
    608   1.1   thorpej 		panic(__S(__C(CHIP,_io_read_4)) ": addr 0x%lx not aligned",
    609   1.1   thorpej 		    addr);
    610   1.1   thorpej #endif
    611   1.1   thorpej 	alpha_mb();
    612  1.21      matt 	return (*(uint32_t *)addr);
    613   1.1   thorpej }
    614   1.1   thorpej 
    615  1.21      matt static inline uint64_t
    616  1.21      matt __C(CHIP,_io_read_8)(
    617  1.21      matt 	void *v,
    618  1.21      matt 	bus_space_handle_t ioh,
    619  1.21      matt 	bus_size_t off)
    620   1.1   thorpej {
    621   1.1   thorpej 
    622   1.1   thorpej 	/* XXX XXX XXX */
    623   1.1   thorpej 	panic("%s not implemented", __S(__C(CHIP,_io_read_8)));
    624   1.1   thorpej }
    625   1.1   thorpej 
    626   1.1   thorpej #define CHIP_io_read_multi_N(BYTES,TYPE)				\
    627  1.22   thorpej static void								\
    628  1.21      matt __C(__C(CHIP,_io_read_multi_),BYTES)(					\
    629  1.21      matt 	void *v,							\
    630  1.21      matt 	bus_space_handle_t h,						\
    631  1.21      matt 	bus_size_t o,							\
    632  1.21      matt 	TYPE *a,							\
    633  1.21      matt 	bus_size_t c)							\
    634   1.1   thorpej {									\
    635   1.1   thorpej 									\
    636   1.1   thorpej 	while (c-- > 0) {						\
    637   1.1   thorpej 		__C(CHIP,_io_barrier)(v, h, o, sizeof *a,		\
    638   1.5       cgd 		    BUS_SPACE_BARRIER_READ);				\
    639   1.1   thorpej 		*a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
    640   1.1   thorpej 	}								\
    641   1.1   thorpej }
    642  1.21      matt CHIP_io_read_multi_N(1,uint8_t)
    643  1.21      matt CHIP_io_read_multi_N(2,uint16_t)
    644  1.21      matt CHIP_io_read_multi_N(4,uint32_t)
    645  1.21      matt CHIP_io_read_multi_N(8,uint64_t)
    646   1.1   thorpej 
    647   1.1   thorpej #define CHIP_io_read_region_N(BYTES,TYPE)				\
    648  1.22   thorpej static void								\
    649  1.21      matt __C(__C(CHIP,_io_read_region_),BYTES)(					\
    650  1.21      matt 	void *v,							\
    651  1.21      matt 	bus_space_handle_t h,						\
    652  1.21      matt 	bus_size_t o,							\
    653  1.21      matt 	TYPE *a,							\
    654  1.21      matt 	bus_size_t c)							\
    655   1.1   thorpej {									\
    656   1.1   thorpej 									\
    657   1.1   thorpej 	while (c-- > 0) {						\
    658   1.1   thorpej 		*a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
    659   1.1   thorpej 		o += sizeof *a;						\
    660   1.1   thorpej 	}								\
    661   1.1   thorpej }
    662  1.21      matt CHIP_io_read_region_N(1,uint8_t)
    663  1.21      matt CHIP_io_read_region_N(2,uint16_t)
    664  1.21      matt CHIP_io_read_region_N(4,uint32_t)
    665  1.21      matt CHIP_io_read_region_N(8,uint64_t)
    666   1.1   thorpej 
    667  1.19       chs static inline void
    668  1.21      matt __C(CHIP,_io_write_1)(
    669  1.21      matt 	void *v,
    670  1.21      matt 	bus_space_handle_t ioh,
    671  1.21      matt 	bus_size_t off,
    672  1.21      matt 	uint8_t val)
    673   1.1   thorpej {
    674   1.1   thorpej 	bus_addr_t addr;
    675   1.1   thorpej 
    676   1.1   thorpej 	addr = ioh + off;
    677  1.21      matt 	alpha_stb((uint8_t *)addr, val);
    678   1.1   thorpej 	alpha_mb();
    679   1.1   thorpej }
    680   1.1   thorpej 
    681  1.19       chs static inline void
    682  1.21      matt __C(CHIP,_io_write_2)(
    683  1.21      matt 	void *v,
    684  1.21      matt 	bus_space_handle_t ioh,
    685  1.21      matt 	bus_size_t off,
    686  1.21      matt 	uint16_t val)
    687   1.1   thorpej {
    688   1.1   thorpej 	bus_addr_t addr;
    689   1.1   thorpej 
    690   1.1   thorpej 	addr = ioh + off;
    691   1.1   thorpej #ifdef DIAGNOSTIC
    692   1.1   thorpej 	if (addr & 1)
    693   1.1   thorpej 		panic(__S(__C(CHIP,_io_write_2)) ": addr 0x%lx not aligned",
    694   1.1   thorpej 		    addr);
    695   1.1   thorpej #endif
    696  1.21      matt 	alpha_stw((uint16_t *)addr, val);
    697   1.1   thorpej 	alpha_mb();
    698   1.1   thorpej }
    699   1.1   thorpej 
    700  1.19       chs static inline void
    701  1.21      matt __C(CHIP,_io_write_4)(
    702  1.21      matt 	void *v,
    703  1.21      matt 	bus_space_handle_t ioh,
    704  1.21      matt 	bus_size_t off,
    705  1.21      matt 	uint32_t val)
    706   1.1   thorpej {
    707   1.1   thorpej 	bus_addr_t addr;
    708   1.1   thorpej 
    709   1.1   thorpej 	addr = ioh + off;
    710   1.1   thorpej #ifdef DIAGNOSTIC
    711   1.1   thorpej 	if (addr & 3)
    712   1.1   thorpej 		panic(__S(__C(CHIP,_io_write_4)) ": addr 0x%lx not aligned",
    713   1.1   thorpej 		    addr);
    714   1.1   thorpej #endif
    715  1.21      matt 	*(uint32_t *)addr = val;
    716   1.1   thorpej 	alpha_mb();
    717   1.1   thorpej }
    718   1.1   thorpej 
    719  1.19       chs static inline void
    720  1.21      matt __C(CHIP,_io_write_8)(
    721  1.21      matt 	void *v,
    722  1.21      matt 	bus_space_handle_t ioh,
    723  1.21      matt 	bus_size_t off,
    724  1.21      matt 	uint64_t val)
    725   1.1   thorpej {
    726   1.1   thorpej 
    727   1.1   thorpej 	/* XXX XXX XXX */
    728   1.1   thorpej 	panic("%s not implemented", __S(__C(CHIP,_io_write_8)));
    729   1.1   thorpej 	alpha_mb();
    730   1.1   thorpej }
    731   1.1   thorpej 
    732   1.1   thorpej #define CHIP_io_write_multi_N(BYTES,TYPE)				\
    733  1.22   thorpej static void								\
    734  1.21      matt __C(__C(CHIP,_io_write_multi_),BYTES)(					\
    735  1.21      matt 	void *v,							\
    736  1.21      matt 	bus_space_handle_t h,						\
    737  1.21      matt 	bus_size_t o,							\
    738  1.21      matt 	const TYPE *a,							\
    739  1.21      matt 	bus_size_t c)							\
    740   1.1   thorpej {									\
    741   1.1   thorpej 									\
    742   1.1   thorpej 	while (c-- > 0) {						\
    743   1.1   thorpej 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);		\
    744   1.1   thorpej 		__C(CHIP,_io_barrier)(v, h, o, sizeof *a,		\
    745   1.5       cgd 		    BUS_SPACE_BARRIER_WRITE);				\
    746   1.1   thorpej 	}								\
    747   1.1   thorpej }
    748  1.21      matt CHIP_io_write_multi_N(1,uint8_t)
    749  1.21      matt CHIP_io_write_multi_N(2,uint16_t)
    750  1.21      matt CHIP_io_write_multi_N(4,uint32_t)
    751  1.21      matt CHIP_io_write_multi_N(8,uint64_t)
    752   1.1   thorpej 
    753   1.1   thorpej #define CHIP_io_write_region_N(BYTES,TYPE)				\
    754  1.22   thorpej static void								\
    755  1.21      matt __C(__C(CHIP,_io_write_region_),BYTES)(					\
    756  1.21      matt 	void *v,							\
    757  1.21      matt 	bus_space_handle_t h,						\
    758  1.21      matt 	bus_size_t o,							\
    759  1.21      matt 	const TYPE *a,							\
    760  1.21      matt 	bus_size_t c)							\
    761   1.1   thorpej {									\
    762   1.1   thorpej 									\
    763   1.1   thorpej 	while (c-- > 0) {						\
    764   1.1   thorpej 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);		\
    765   1.1   thorpej 		o += sizeof *a;						\
    766   1.1   thorpej 	}								\
    767   1.1   thorpej }
    768  1.21      matt CHIP_io_write_region_N(1,uint8_t)
    769  1.21      matt CHIP_io_write_region_N(2,uint16_t)
    770  1.21      matt CHIP_io_write_region_N(4,uint32_t)
    771  1.21      matt CHIP_io_write_region_N(8,uint64_t)
    772   1.1   thorpej 
    773   1.1   thorpej #define CHIP_io_set_multi_N(BYTES,TYPE)					\
    774  1.22   thorpej static void								\
    775  1.21      matt __C(__C(CHIP,_io_set_multi_),BYTES)(					\
    776  1.21      matt 	void *v,							\
    777  1.21      matt 	bus_space_handle_t h,						\
    778  1.21      matt 	bus_size_t o,							\
    779  1.21      matt 	TYPE val,							\
    780  1.21      matt 	bus_size_t c)							\
    781   1.1   thorpej {									\
    782   1.1   thorpej 									\
    783   1.1   thorpej 	while (c-- > 0) {						\
    784   1.1   thorpej 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, val);		\
    785   1.1   thorpej 		__C(CHIP,_io_barrier)(v, h, o, sizeof val,		\
    786   1.5       cgd 		    BUS_SPACE_BARRIER_WRITE);				\
    787   1.1   thorpej 	}								\
    788   1.1   thorpej }
    789  1.21      matt CHIP_io_set_multi_N(1,uint8_t)
    790  1.21      matt CHIP_io_set_multi_N(2,uint16_t)
    791  1.21      matt CHIP_io_set_multi_N(4,uint32_t)
    792  1.21      matt CHIP_io_set_multi_N(8,uint64_t)
    793   1.1   thorpej 
    794   1.1   thorpej #define CHIP_io_set_region_N(BYTES,TYPE)				\
    795  1.22   thorpej static void								\
    796  1.21      matt __C(__C(CHIP,_io_set_region_),BYTES)(					\
    797  1.21      matt 	void *v,							\
    798  1.21      matt 	bus_space_handle_t h,						\
    799  1.21      matt 	bus_size_t o,							\
    800  1.21      matt 	TYPE val,							\
    801  1.21      matt 	bus_size_t c)							\
    802   1.1   thorpej {									\
    803   1.1   thorpej 									\
    804   1.1   thorpej 	while (c-- > 0) {						\
    805   1.1   thorpej 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, val);		\
    806   1.1   thorpej 		o += sizeof val;					\
    807   1.1   thorpej 	}								\
    808   1.1   thorpej }
    809  1.21      matt CHIP_io_set_region_N(1,uint8_t)
    810  1.21      matt CHIP_io_set_region_N(2,uint16_t)
    811  1.21      matt CHIP_io_set_region_N(4,uint32_t)
    812  1.21      matt CHIP_io_set_region_N(8,uint64_t)
    813   1.1   thorpej 
    814   1.1   thorpej #define	CHIP_io_copy_region_N(BYTES)					\
    815  1.22   thorpej static void								\
    816  1.21      matt __C(__C(CHIP,_io_copy_region_),BYTES)(					\
    817  1.21      matt 	void *v,							\
    818  1.21      matt 	bus_space_handle_t h1,						\
    819  1.21      matt 	bus_size_t o1,							\
    820  1.21      matt 	bus_space_handle_t h2,						\
    821  1.21      matt 	bus_size_t o2,							\
    822  1.21      matt 	bus_size_t c)							\
    823   1.1   thorpej {									\
    824   1.1   thorpej 	bus_size_t o;							\
    825   1.1   thorpej 									\
    826   1.1   thorpej 	if ((h1 + o1) >= (h2 + o2)) {					\
    827   1.1   thorpej 		/* src after dest: copy forward */			\
    828   1.1   thorpej 		for (o = 0; c != 0; c--, o += BYTES) {			\
    829   1.1   thorpej 			__C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o,	\
    830   1.1   thorpej 			    __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \
    831   1.1   thorpej 		}							\
    832   1.1   thorpej 	} else {							\
    833   1.1   thorpej 		/* dest after src: copy backwards */			\
    834   1.1   thorpej 		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) {	\
    835   1.1   thorpej 			__C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o,	\
    836   1.1   thorpej 			    __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \
    837   1.1   thorpej 		}							\
    838   1.1   thorpej 	}								\
    839   1.1   thorpej }
    840   1.1   thorpej CHIP_io_copy_region_N(1)
    841   1.1   thorpej CHIP_io_copy_region_N(2)
    842   1.1   thorpej CHIP_io_copy_region_N(4)
    843   1.1   thorpej CHIP_io_copy_region_N(8)
    844