Home | History | Annotate | Line # | Download | only in pci
pci_swiz_bus_io_chipdep.c revision 1.31
      1 /* $NetBSD: pci_swiz_bus_io_chipdep.c,v 1.31 2000/04/17 17:30:48 drochner Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 1998, 2000 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) 1995, 1996 Carnegie-Mellon University.
     42  * All rights reserved.
     43  *
     44  * Author: Chris G. Demetriou
     45  *
     46  * Permission to use, copy, modify and distribute this software and
     47  * its documentation is hereby granted, provided that both the copyright
     48  * notice and this permission notice appear in all copies of the
     49  * software, derivative works or modified versions, and any portions
     50  * thereof, and that both notices appear in supporting documentation.
     51  *
     52  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     53  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
     54  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     55  *
     56  * Carnegie Mellon requests users of this software to return to
     57  *
     58  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     59  *  School of Computer Science
     60  *  Carnegie Mellon University
     61  *  Pittsburgh PA 15213-3890
     62  *
     63  * any improvements or extensions that they make and grant Carnegie the
     64  * rights to redistribute these changes.
     65  */
     66 
     67 /*
     68  * Common PCI Chipset "bus I/O" functions, for chipsets which have to
     69  * deal with only a single PCI interface chip in a machine.
     70  *
     71  * uses:
     72  *	CHIP		name of the 'chip' it's being compiled for.
     73  *	CHIP_IO_BASE	Sparse I/O space base to use.
     74  *	CHIP_IO_EX_STORE
     75  *			If defined, device-provided static storage area
     76  *			for the I/O space extent.  If this is defined,
     77  *			CHIP_IO_EX_STORE_SIZE must also be defined.  If
     78  *			this is not defined, a static area will be
     79  *			declared.
     80  *	CHIP_IO_EX_STORE_SIZE
     81  *			Size of the device-provided static storage area
     82  *			for the I/O memory space extent.
     83  */
     84 
     85 #include <sys/extent.h>
     86 
     87 #define	__C(A,B)	__CONCAT(A,B)
     88 #define	__S(S)		__STRING(S)
     89 
     90 /* mapping/unmapping */
     91 int		__C(CHIP,_io_map) __P((void *, bus_addr_t, bus_size_t, int,
     92 		    bus_space_handle_t *, int));
     93 void		__C(CHIP,_io_unmap) __P((void *, bus_space_handle_t,
     94 		    bus_size_t, int));
     95 int		__C(CHIP,_io_subregion) __P((void *, bus_space_handle_t,
     96 		    bus_size_t, bus_size_t, bus_space_handle_t *));
     97 
     98 int		__C(CHIP,_io_translate) __P((void *, bus_addr_t, bus_size_t,
     99 		    int, struct alpha_bus_space_translation *));
    100 int		__C(CHIP,_io_get_window) __P((void *, int,
    101 		    struct alpha_bus_space_translation *));
    102 
    103 /* allocation/deallocation */
    104 int		__C(CHIP,_io_alloc) __P((void *, bus_addr_t, bus_addr_t,
    105 		    bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *,
    106                     bus_space_handle_t *));
    107 void		__C(CHIP,_io_free) __P((void *, bus_space_handle_t,
    108 		    bus_size_t));
    109 
    110 /* get kernel virtual address */
    111 void *		__C(CHIP,_io_vaddr) __P((void *, bus_space_handle_t));
    112 
    113 /* barrier */
    114 inline void	__C(CHIP,_io_barrier) __P((void *, bus_space_handle_t,
    115 		    bus_size_t, bus_size_t, int));
    116 
    117 /* read (single) */
    118 inline u_int8_t	__C(CHIP,_io_read_1) __P((void *, bus_space_handle_t,
    119 		    bus_size_t));
    120 inline u_int16_t __C(CHIP,_io_read_2) __P((void *, bus_space_handle_t,
    121 		    bus_size_t));
    122 inline u_int32_t __C(CHIP,_io_read_4) __P((void *, bus_space_handle_t,
    123 		    bus_size_t));
    124 inline u_int64_t __C(CHIP,_io_read_8) __P((void *, bus_space_handle_t,
    125 		    bus_size_t));
    126 
    127 /* read multiple */
    128 void		__C(CHIP,_io_read_multi_1) __P((void *, bus_space_handle_t,
    129 		    bus_size_t, u_int8_t *, bus_size_t));
    130 void		__C(CHIP,_io_read_multi_2) __P((void *, bus_space_handle_t,
    131 		    bus_size_t, u_int16_t *, bus_size_t));
    132 void		__C(CHIP,_io_read_multi_4) __P((void *, bus_space_handle_t,
    133 		    bus_size_t, u_int32_t *, bus_size_t));
    134 void		__C(CHIP,_io_read_multi_8) __P((void *, bus_space_handle_t,
    135 		    bus_size_t, u_int64_t *, bus_size_t));
    136 
    137 /* read region */
    138 void		__C(CHIP,_io_read_region_1) __P((void *, bus_space_handle_t,
    139 		    bus_size_t, u_int8_t *, bus_size_t));
    140 void		__C(CHIP,_io_read_region_2) __P((void *, bus_space_handle_t,
    141 		    bus_size_t, u_int16_t *, bus_size_t));
    142 void		__C(CHIP,_io_read_region_4) __P((void *, bus_space_handle_t,
    143 		    bus_size_t, u_int32_t *, bus_size_t));
    144 void		__C(CHIP,_io_read_region_8) __P((void *, bus_space_handle_t,
    145 		    bus_size_t, u_int64_t *, bus_size_t));
    146 
    147 /* write (single) */
    148 inline void	__C(CHIP,_io_write_1) __P((void *, bus_space_handle_t,
    149 		    bus_size_t, u_int8_t));
    150 inline void	__C(CHIP,_io_write_2) __P((void *, bus_space_handle_t,
    151 		    bus_size_t, u_int16_t));
    152 inline void	__C(CHIP,_io_write_4) __P((void *, bus_space_handle_t,
    153 		    bus_size_t, u_int32_t));
    154 inline void	__C(CHIP,_io_write_8) __P((void *, bus_space_handle_t,
    155 		    bus_size_t, u_int64_t));
    156 
    157 /* write multiple */
    158 void		__C(CHIP,_io_write_multi_1) __P((void *, bus_space_handle_t,
    159 		    bus_size_t, const u_int8_t *, bus_size_t));
    160 void		__C(CHIP,_io_write_multi_2) __P((void *, bus_space_handle_t,
    161 		    bus_size_t, const u_int16_t *, bus_size_t));
    162 void		__C(CHIP,_io_write_multi_4) __P((void *, bus_space_handle_t,
    163 		    bus_size_t, const u_int32_t *, bus_size_t));
    164 void		__C(CHIP,_io_write_multi_8) __P((void *, bus_space_handle_t,
    165 		    bus_size_t, const u_int64_t *, bus_size_t));
    166 
    167 /* write region */
    168 void		__C(CHIP,_io_write_region_1) __P((void *, bus_space_handle_t,
    169 		    bus_size_t, const u_int8_t *, bus_size_t));
    170 void		__C(CHIP,_io_write_region_2) __P((void *, bus_space_handle_t,
    171 		    bus_size_t, const u_int16_t *, bus_size_t));
    172 void		__C(CHIP,_io_write_region_4) __P((void *, bus_space_handle_t,
    173 		    bus_size_t, const u_int32_t *, bus_size_t));
    174 void		__C(CHIP,_io_write_region_8) __P((void *, bus_space_handle_t,
    175 		    bus_size_t, const u_int64_t *, bus_size_t));
    176 
    177 /* set multiple */
    178 void		__C(CHIP,_io_set_multi_1) __P((void *, bus_space_handle_t,
    179 		    bus_size_t, u_int8_t, bus_size_t));
    180 void		__C(CHIP,_io_set_multi_2) __P((void *, bus_space_handle_t,
    181 		    bus_size_t, u_int16_t, bus_size_t));
    182 void		__C(CHIP,_io_set_multi_4) __P((void *, bus_space_handle_t,
    183 		    bus_size_t, u_int32_t, bus_size_t));
    184 void		__C(CHIP,_io_set_multi_8) __P((void *, bus_space_handle_t,
    185 		    bus_size_t, u_int64_t, bus_size_t));
    186 
    187 /* set region */
    188 void		__C(CHIP,_io_set_region_1) __P((void *, bus_space_handle_t,
    189 		    bus_size_t, u_int8_t, bus_size_t));
    190 void		__C(CHIP,_io_set_region_2) __P((void *, bus_space_handle_t,
    191 		    bus_size_t, u_int16_t, bus_size_t));
    192 void		__C(CHIP,_io_set_region_4) __P((void *, bus_space_handle_t,
    193 		    bus_size_t, u_int32_t, bus_size_t));
    194 void		__C(CHIP,_io_set_region_8) __P((void *, bus_space_handle_t,
    195 		    bus_size_t, u_int64_t, bus_size_t));
    196 
    197 /* copy */
    198 void		__C(CHIP,_io_copy_region_1) __P((void *, bus_space_handle_t,
    199 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
    200 void		__C(CHIP,_io_copy_region_2) __P((void *, bus_space_handle_t,
    201 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
    202 void		__C(CHIP,_io_copy_region_4) __P((void *, bus_space_handle_t,
    203 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
    204 void		__C(CHIP,_io_copy_region_8) __P((void *, bus_space_handle_t,
    205 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
    206 
    207 #ifndef	CHIP_IO_EX_STORE
    208 static long
    209     __C(CHIP,_io_ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)];
    210 #define	CHIP_IO_EX_STORE(v)		(__C(CHIP, _io_ex_storage))
    211 #define	CHIP_IO_EX_STORE_SIZE(v)	(sizeof __C(CHIP, _io_ex_storage))
    212 #endif
    213 
    214 #ifndef CHIP_ADDR_SHIFT
    215 #define	CHIP_ADDR_SHIFT		5
    216 #endif
    217 
    218 #ifndef CHIP_SIZE_SHIFT
    219 #define	CHIP_SIZE_SHIFT		3
    220 #endif
    221 
    222 void
    223 __C(CHIP,_bus_io_init)(t, v)
    224 	bus_space_tag_t t;
    225 	void *v;
    226 {
    227 	struct extent *ex;
    228 
    229 	/*
    230 	 * Initialize the bus space tag.
    231 	 */
    232 
    233 	/* cookie */
    234 	t->abs_cookie =		v;
    235 
    236 	/* mapping/unmapping */
    237 	t->abs_map =		__C(CHIP,_io_map);
    238 	t->abs_unmap =		__C(CHIP,_io_unmap);
    239 	t->abs_subregion =	__C(CHIP,_io_subregion);
    240 
    241 	t->abs_translate =	__C(CHIP,_io_translate);
    242 	t->abs_get_window =	__C(CHIP,_io_get_window);
    243 
    244 	/* allocation/deallocation */
    245 	t->abs_alloc =		__C(CHIP,_io_alloc);
    246 	t->abs_free = 		__C(CHIP,_io_free);
    247 
    248 	/* get kernel virtual address */
    249 	t->abs_vaddr =		__C(CHIP,_io_vaddr);
    250 
    251 	/* barrier */
    252 	t->abs_barrier =	__C(CHIP,_io_barrier);
    253 
    254 	/* read (single) */
    255 	t->abs_r_1 =		__C(CHIP,_io_read_1);
    256 	t->abs_r_2 =		__C(CHIP,_io_read_2);
    257 	t->abs_r_4 =		__C(CHIP,_io_read_4);
    258 	t->abs_r_8 =		__C(CHIP,_io_read_8);
    259 
    260 	/* read multiple */
    261 	t->abs_rm_1 =		__C(CHIP,_io_read_multi_1);
    262 	t->abs_rm_2 =		__C(CHIP,_io_read_multi_2);
    263 	t->abs_rm_4 =		__C(CHIP,_io_read_multi_4);
    264 	t->abs_rm_8 =		__C(CHIP,_io_read_multi_8);
    265 
    266 	/* read region */
    267 	t->abs_rr_1 =		__C(CHIP,_io_read_region_1);
    268 	t->abs_rr_2 =		__C(CHIP,_io_read_region_2);
    269 	t->abs_rr_4 =		__C(CHIP,_io_read_region_4);
    270 	t->abs_rr_8 =		__C(CHIP,_io_read_region_8);
    271 
    272 	/* write (single) */
    273 	t->abs_w_1 =		__C(CHIP,_io_write_1);
    274 	t->abs_w_2 =		__C(CHIP,_io_write_2);
    275 	t->abs_w_4 =		__C(CHIP,_io_write_4);
    276 	t->abs_w_8 =		__C(CHIP,_io_write_8);
    277 
    278 	/* write multiple */
    279 	t->abs_wm_1 =		__C(CHIP,_io_write_multi_1);
    280 	t->abs_wm_2 =		__C(CHIP,_io_write_multi_2);
    281 	t->abs_wm_4 =		__C(CHIP,_io_write_multi_4);
    282 	t->abs_wm_8 =		__C(CHIP,_io_write_multi_8);
    283 
    284 	/* write region */
    285 	t->abs_wr_1 =		__C(CHIP,_io_write_region_1);
    286 	t->abs_wr_2 =		__C(CHIP,_io_write_region_2);
    287 	t->abs_wr_4 =		__C(CHIP,_io_write_region_4);
    288 	t->abs_wr_8 =		__C(CHIP,_io_write_region_8);
    289 
    290 	/* set multiple */
    291 	t->abs_sm_1 =		__C(CHIP,_io_set_multi_1);
    292 	t->abs_sm_2 =		__C(CHIP,_io_set_multi_2);
    293 	t->abs_sm_4 =		__C(CHIP,_io_set_multi_4);
    294 	t->abs_sm_8 =		__C(CHIP,_io_set_multi_8);
    295 
    296 	/* set region */
    297 	t->abs_sr_1 =		__C(CHIP,_io_set_region_1);
    298 	t->abs_sr_2 =		__C(CHIP,_io_set_region_2);
    299 	t->abs_sr_4 =		__C(CHIP,_io_set_region_4);
    300 	t->abs_sr_8 =		__C(CHIP,_io_set_region_8);
    301 
    302 	/* copy */
    303 	t->abs_c_1 =		__C(CHIP,_io_copy_region_1);
    304 	t->abs_c_2 =		__C(CHIP,_io_copy_region_2);
    305 	t->abs_c_4 =		__C(CHIP,_io_copy_region_4);
    306 	t->abs_c_8 =		__C(CHIP,_io_copy_region_8);
    307 
    308 	/* XXX WE WANT EXTENT_NOCOALESCE, BUT WE CAN'T USE IT. XXX */
    309 	ex = extent_create(__S(__C(CHIP,_bus_io)), 0x0UL, 0xffffffffUL,
    310 	    M_DEVBUF, (caddr_t)CHIP_IO_EX_STORE(v), CHIP_IO_EX_STORE_SIZE(v),
    311 	    EX_NOWAIT);
    312 	extent_alloc_region(ex, 0, 0xffffffffUL, EX_NOWAIT);
    313 
    314 #ifdef CHIP_IO_W1_BUS_START
    315 #ifdef EXTENT_DEBUG
    316 	printf("io: freeing from 0x%lx to 0x%lx\n", CHIP_IO_W1_BUS_START(v),
    317 	    CHIP_IO_W1_BUS_END(v));
    318 #endif
    319 	extent_free(ex, CHIP_IO_W1_BUS_START(v),
    320 	    CHIP_IO_W1_BUS_END(v) - CHIP_IO_W1_BUS_START(v) + 1, EX_NOWAIT);
    321 #endif
    322 #ifdef CHIP_IO_W2_BUS_START
    323 #ifdef EXTENT_DEBUG
    324 	printf("io: freeing from 0x%lx to 0x%lx\n", CHIP_IO_W2_BUS_START(v),
    325 	    CHIP_IO_W2_BUS_END(v));
    326 #endif
    327 	extent_free(ex, CHIP_IO_W2_BUS_START(v),
    328 	    CHIP_IO_W2_BUS_END(v) - CHIP_IO_W2_BUS_START(v) + 1, EX_NOWAIT);
    329 #endif
    330 
    331 #ifdef EXTENT_DEBUG
    332 	extent_print(ex);
    333 #endif
    334 	CHIP_IO_EXTENT(v) = ex;
    335 }
    336 
    337 int
    338 __C(CHIP,_io_translate)(v, ioaddr, iolen, flags, abst)
    339 	void *v;
    340 	bus_addr_t ioaddr;
    341 	bus_size_t iolen;
    342 	int flags;
    343 	struct alpha_bus_space_translation *abst;
    344 {
    345 	bus_addr_t ioend = ioaddr + (iolen - 1);
    346 	int linear = flags & BUS_SPACE_MAP_LINEAR;
    347 
    348 	/*
    349 	 * Can't map i/o space linearly.
    350 	 */
    351 	if (linear)
    352 		return (EOPNOTSUPP);
    353 
    354 #ifdef CHIP_IO_W1_BUS_START
    355 	if (ioaddr >= CHIP_IO_W1_BUS_START(v) &&
    356 	    ioend <= CHIP_IO_W1_BUS_END(v))
    357 		return (__C(CHIP,_io_get_window)(v, 0, abst));
    358 #endif
    359 
    360 #ifdef CHIP_IO_W2_BUS_START
    361 	if (ioaddr >= CHIP_IO_W2_BUS_START(v) &&
    362 	    ioend <= CHIP_IO_W2_BUS_END(v))
    363 		return (__C(CHIP,_io_get_window)(v, 1, abst));
    364 #endif
    365 
    366 #ifdef EXTENT_DEBUG
    367 	printf("\n");
    368 #ifdef CHIP_IO_W1_BUS_START
    369 	printf("%s: window[1]=0x%lx-0x%lx\n",
    370 	    __S(__C(CHIP,_io_map)), CHIP_IO_W1_BUS_START(v),
    371 	    CHIP_IO_W1_BUS_END(v));
    372 #endif
    373 #ifdef CHIP_IO_W2_BUS_START
    374 	printf("%s: window[2]=0x%lx-0x%lx\n",
    375 	    __S(__C(CHIP,_io_map)), CHIP_IO_W2_BUS_START(v),
    376 	    CHIP_IO_W2_BUS_END(v));
    377 #endif
    378 #endif /* EXTENT_DEBUG */
    379 	/* No translation. */
    380 	return (EINVAL);
    381 }
    382 
    383 int
    384 __C(CHIP,_io_get_window)(v, window, abst)
    385 	void *v;
    386 	int window;
    387 	struct alpha_bus_space_translation *abst;
    388 {
    389 
    390 	switch (window) {
    391 #ifdef CHIP_IO_W1_BUS_START
    392 	case 0:
    393 		abst->abst_bus_start = CHIP_IO_W1_BUS_START(v);
    394 		abst->abst_bus_end = CHIP_IO_W1_BUS_END(v);
    395 		abst->abst_sys_start = CHIP_IO_W1_SYS_START(v);
    396 		abst->abst_sys_end = CHIP_IO_W1_SYS_END(v);
    397 		abst->abst_addr_shift = CHIP_ADDR_SHIFT;
    398 		abst->abst_size_shift = CHIP_SIZE_SHIFT;
    399 		abst->abst_flags = 0;
    400 		break;
    401 #endif
    402 
    403 #ifdef CHIP_IO_W2_BUS_START
    404 	case 1:
    405 		abst->abst_bus_start = CHIP_IO_W2_BUS_START(v);
    406 		abst->abst_bus_end = CHIP_IO_W2_BUS_END(v);
    407 		abst->abst_sys_start = CHIP_IO_W2_SYS_START(v);
    408 		abst->abst_sys_end = CHIP_IO_W2_SYS_END(v);
    409 		abst->abst_addr_shift = CHIP_ADDR_SHIFT;
    410 		abst->abst_size_shift = CHIP_SIZE_SHIFT;
    411 		abst->abst_flags = 0;
    412 		break;
    413 #endif
    414 
    415 	default:
    416 		panic(__S(__C(CHIP,_io_get_window)) ": invalid window %d",
    417 		    window);
    418 	}
    419 
    420 	return (0);
    421 }
    422 
    423 int
    424 __C(CHIP,_io_map)(v, ioaddr, iosize, flags, iohp, acct)
    425 	void *v;
    426 	bus_addr_t ioaddr;
    427 	bus_size_t iosize;
    428 	int flags;
    429 	bus_space_handle_t *iohp;
    430 	int acct;
    431 {
    432 	struct alpha_bus_space_translation abst;
    433 	int error;
    434 
    435 	/*
    436 	 * Get the translation for this address.
    437 	 */
    438 	error = __C(CHIP,_io_translate)(v, ioaddr, iosize, flags, &abst);
    439 	if (error)
    440 		return (error);
    441 
    442 	if (acct == 0)
    443 		goto mapit;
    444 
    445 #ifdef EXTENT_DEBUG
    446 	printf("io: allocating 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
    447 #endif
    448         error = extent_alloc_region(CHIP_IO_EXTENT(v), ioaddr, iosize,
    449             EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
    450 	if (error) {
    451 #ifdef EXTENT_DEBUG
    452 		printf("io: allocation failed (%d)\n", error);
    453 		extent_print(CHIP_IO_EXTENT(v));
    454 #endif
    455 		return (error);
    456 	}
    457 
    458  mapit:
    459 	*iohp = (ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start) >>
    460 	    CHIP_ADDR_SHIFT) + (ioaddr - abst.abst_bus_start);
    461 
    462 	return (0);
    463 }
    464 
    465 void
    466 __C(CHIP,_io_unmap)(v, ioh, iosize, acct)
    467 	void *v;
    468 	bus_space_handle_t ioh;
    469 	bus_size_t iosize;
    470 	int acct;
    471 {
    472 	bus_addr_t ioaddr;
    473 	int error;
    474 
    475 	if (acct == 0)
    476 		return;
    477 
    478 #ifdef EXTENT_DEBUG
    479 	printf("io: freeing handle 0x%lx for 0x%lx\n", ioh, iosize);
    480 #endif
    481 
    482 	ioh = ALPHA_K0SEG_TO_PHYS(ioh << CHIP_ADDR_SHIFT) >> CHIP_ADDR_SHIFT;
    483 
    484 #ifdef CHIP_IO_W1_BUS_START
    485 	if ((ioh << CHIP_ADDR_SHIFT) >= CHIP_IO_W1_SYS_START(v) &&
    486 	    (ioh << CHIP_ADDR_SHIFT) <= CHIP_IO_W1_SYS_END(v)) {
    487 		ioaddr = CHIP_IO_W1_BUS_START(v) +
    488 		    (ioh - (CHIP_IO_W1_SYS_START(v) >> CHIP_ADDR_SHIFT));
    489 	} else
    490 #endif
    491 #ifdef CHIP_IO_W2_BUS_START
    492 	if ((ioh << CHIP_ADDR_SHIFT) >= CHIP_IO_W2_SYS_START(v) &&
    493 	    (ioh << CHIP_ADDR_SHIFT) <= CHIP_IO_W2_SYS_END(v)) {
    494 		ioaddr = CHIP_IO_W2_BUS_START(v) +
    495 		    (ioh - (CHIP_IO_W2_SYS_START(v) >> CHIP_ADDR_SHIFT));
    496 	} else
    497 #endif
    498 	{
    499 		printf("\n");
    500 #ifdef CHIP_IO_W1_BUS_START
    501 		printf("%s: sys window[1]=0x%lx-0x%lx\n",
    502 		    __S(__C(CHIP,_io_map)), CHIP_IO_W1_SYS_START(v),
    503 		    CHIP_IO_W1_SYS_END(v));
    504 #endif
    505 #ifdef CHIP_IO_W2_BUS_START
    506 		printf("%s: sys window[2]=0x%lx-0x%lx\n",
    507 		    __S(__C(CHIP,_io_map)), CHIP_IO_W2_SYS_START(v),
    508 		    CHIP_IO_W2_SYS_END(v));
    509 #endif
    510 		panic("%s: don't know how to unmap %lx",
    511 		    __S(__C(CHIP,_io_unmap)), (ioh << CHIP_ADDR_SHIFT));
    512 	}
    513 
    514 #ifdef EXTENT_DEBUG
    515 	printf("io: freeing 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
    516 #endif
    517         error = extent_free(CHIP_IO_EXTENT(v), ioaddr, iosize,
    518             EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
    519 	if (error) {
    520 		printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n",
    521 		   __S(__C(CHIP,_io_unmap)), ioaddr, ioaddr + iosize - 1,
    522 		   error);
    523 #ifdef EXTENT_DEBUG
    524 		extent_print(CHIP_IO_EXTENT(v));
    525 #endif
    526 	}
    527 }
    528 
    529 int
    530 __C(CHIP,_io_subregion)(v, ioh, offset, size, nioh)
    531 	void *v;
    532 	bus_space_handle_t ioh, *nioh;
    533 	bus_size_t offset, size;
    534 {
    535 
    536 	*nioh = ioh + offset;
    537 	return (0);
    538 }
    539 
    540 int
    541 __C(CHIP,_io_alloc)(v, rstart, rend, size, align, boundary, flags,
    542     addrp, bshp)
    543 	void *v;
    544 	bus_addr_t rstart, rend, *addrp;
    545 	bus_size_t size, align, boundary;
    546 	int flags;
    547 	bus_space_handle_t *bshp;
    548 {
    549 	struct alpha_bus_space_translation abst;
    550 	int linear = flags & BUS_SPACE_MAP_LINEAR;
    551 	bus_addr_t ioaddr;
    552 	int error;
    553 
    554 	/*
    555 	 * Can't map i/o space linearly.
    556 	 */
    557 	if (linear)
    558 		return (EOPNOTSUPP);
    559 
    560 	/*
    561 	 * Do the requested allocation.
    562 	 */
    563 #ifdef EXTENT_DEBUG
    564 	printf("io: allocating from 0x%lx to 0x%lx\n", rstart, rend);
    565 #endif
    566 	error = extent_alloc_subregion(CHIP_IO_EXTENT(v), rstart, rend,
    567 	    size, align, boundary,
    568 	    EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0),
    569 	    &ioaddr);
    570 	if (error) {
    571 #ifdef EXTENT_DEBUG
    572 		printf("io: allocation failed (%d)\n", error);
    573 		extent_print(CHIP_IO_EXTENT(v));
    574 #endif
    575 		return (error);
    576 	}
    577 
    578 #ifdef EXTENT_DEBUG
    579 	printf("io: allocated 0x%lx to 0x%lx\n", ioaddr, ioaddr + size - 1);
    580 #endif
    581 
    582 	error = __C(CHIP,_io_translate)(v, ioaddr, size, flags, &abst);
    583 	if (error) {
    584 		(void) extent_free(CHIP_IO_EXTENT(v), ioaddr, size,
    585 		    EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
    586 		return (error);
    587 	}
    588 
    589 	*addrp = ioaddr;
    590 	*bshp = (ALPHA_PHYS_TO_K0SEG(abst.abst_sys_start) >>
    591 	    CHIP_ADDR_SHIFT) + (ioaddr - abst.abst_bus_start);
    592 
    593 	return (0);
    594 }
    595 
    596 void
    597 __C(CHIP,_io_free)(v, bsh, size)
    598 	void *v;
    599 	bus_space_handle_t bsh;
    600 	bus_size_t size;
    601 {
    602 
    603 	/* Unmap does all we need to do. */
    604 	__C(CHIP,_io_unmap)(v, bsh, size, 1);
    605 }
    606 
    607 void *
    608 __C(CHIP,_io_vaddr)(v, bsh)
    609 	void *v;
    610 	bus_space_handle_t bsh;
    611 {
    612 	/*
    613 	 * _io_translate() catches BUS_SPACE_MAP_LINEAR,
    614 	 * so we shouldn't get here
    615 	 */
    616 	panic("_io_vaddr");
    617 }
    618 
    619 inline void
    620 __C(CHIP,_io_barrier)(v, h, o, l, f)
    621 	void *v;
    622 	bus_space_handle_t h;
    623 	bus_size_t o, l;
    624 	int f;
    625 {
    626 
    627 	if ((f & BUS_SPACE_BARRIER_READ) != 0)
    628 		alpha_mb();
    629 	else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
    630 		alpha_wmb();
    631 }
    632 
    633 inline u_int8_t
    634 __C(CHIP,_io_read_1)(v, ioh, off)
    635 	void *v;
    636 	bus_space_handle_t ioh;
    637 	bus_size_t off;
    638 {
    639 	register bus_space_handle_t tmpioh;
    640 	register u_int32_t *port, val;
    641 	register u_int8_t rval;
    642 	register int offset;
    643 
    644 	alpha_mb();
    645 
    646 	tmpioh = ioh + off;
    647 	offset = tmpioh & 3;
    648 	port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) |
    649 	    (0 << CHIP_SIZE_SHIFT));
    650 	val = *port;
    651 	rval = ((val) >> (8 * offset)) & 0xff;
    652 
    653 	return rval;
    654 }
    655 
    656 inline u_int16_t
    657 __C(CHIP,_io_read_2)(v, ioh, off)
    658 	void *v;
    659 	bus_space_handle_t ioh;
    660 	bus_size_t off;
    661 {
    662 	register bus_space_handle_t tmpioh;
    663 	register u_int32_t *port, val;
    664 	register u_int16_t rval;
    665 	register int offset;
    666 
    667 	alpha_mb();
    668 
    669 	tmpioh = ioh + off;
    670 	offset = tmpioh & 3;
    671 	port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) |
    672 	    (1 << CHIP_SIZE_SHIFT));
    673 	val = *port;
    674 	rval = ((val) >> (8 * offset)) & 0xffff;
    675 
    676 	return rval;
    677 }
    678 
    679 inline u_int32_t
    680 __C(CHIP,_io_read_4)(v, ioh, off)
    681 	void *v;
    682 	bus_space_handle_t ioh;
    683 	bus_size_t off;
    684 {
    685 	register bus_space_handle_t tmpioh;
    686 	register u_int32_t *port, val;
    687 	register u_int32_t rval;
    688 	register int offset;
    689 
    690 	alpha_mb();
    691 
    692 	tmpioh = ioh + off;
    693 	offset = tmpioh & 3;
    694 	port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) |
    695 	    (3 << CHIP_SIZE_SHIFT));
    696 	val = *port;
    697 #if 0
    698 	rval = ((val) >> (8 * offset)) & 0xffffffff;
    699 #else
    700 	rval = val;
    701 #endif
    702 
    703 	return rval;
    704 }
    705 
    706 inline u_int64_t
    707 __C(CHIP,_io_read_8)(v, ioh, off)
    708 	void *v;
    709 	bus_space_handle_t ioh;
    710 	bus_size_t off;
    711 {
    712 
    713 	/* XXX XXX XXX */
    714 	panic("%s not implemented", __S(__C(CHIP,_io_read_8)));
    715 }
    716 
    717 #define CHIP_io_read_multi_N(BYTES,TYPE)				\
    718 void									\
    719 __C(__C(CHIP,_io_read_multi_),BYTES)(v, h, o, a, c)			\
    720 	void *v;							\
    721 	bus_space_handle_t h;						\
    722 	bus_size_t o, c;						\
    723 	TYPE *a;							\
    724 {									\
    725 									\
    726 	while (c-- > 0) {						\
    727 		__C(CHIP,_io_barrier)(v, h, o, sizeof *a,		\
    728 		    BUS_SPACE_BARRIER_READ);				\
    729 		*a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
    730 	}								\
    731 }
    732 CHIP_io_read_multi_N(1,u_int8_t)
    733 CHIP_io_read_multi_N(2,u_int16_t)
    734 CHIP_io_read_multi_N(4,u_int32_t)
    735 CHIP_io_read_multi_N(8,u_int64_t)
    736 
    737 #define CHIP_io_read_region_N(BYTES,TYPE)				\
    738 void									\
    739 __C(__C(CHIP,_io_read_region_),BYTES)(v, h, o, a, c)			\
    740 	void *v;							\
    741 	bus_space_handle_t h;						\
    742 	bus_size_t o, c;						\
    743 	TYPE *a;							\
    744 {									\
    745 									\
    746 	while (c-- > 0) {						\
    747 		*a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
    748 		o += sizeof *a;						\
    749 	}								\
    750 }
    751 CHIP_io_read_region_N(1,u_int8_t)
    752 CHIP_io_read_region_N(2,u_int16_t)
    753 CHIP_io_read_region_N(4,u_int32_t)
    754 CHIP_io_read_region_N(8,u_int64_t)
    755 
    756 inline void
    757 __C(CHIP,_io_write_1)(v, ioh, off, val)
    758 	void *v;
    759 	bus_space_handle_t ioh;
    760 	bus_size_t off;
    761 	u_int8_t val;
    762 {
    763 	register bus_space_handle_t tmpioh;
    764 	register u_int32_t *port, nval;
    765 	register int offset;
    766 
    767 	tmpioh = ioh + off;
    768 	offset = tmpioh & 3;
    769         nval = val << (8 * offset);
    770         port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) |
    771             (0 << CHIP_SIZE_SHIFT));
    772         *port = nval;
    773         alpha_mb();
    774 }
    775 
    776 inline void
    777 __C(CHIP,_io_write_2)(v, ioh, off, val)
    778 	void *v;
    779 	bus_space_handle_t ioh;
    780 	bus_size_t off;
    781 	u_int16_t val;
    782 {
    783 	register bus_space_handle_t tmpioh;
    784 	register u_int32_t *port, nval;
    785 	register int offset;
    786 
    787 	tmpioh = ioh + off;
    788 	offset = tmpioh & 3;
    789         nval = val << (8 * offset);
    790         port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) |
    791             (1 << CHIP_SIZE_SHIFT));
    792         *port = nval;
    793         alpha_mb();
    794 }
    795 
    796 inline void
    797 __C(CHIP,_io_write_4)(v, ioh, off, val)
    798 	void *v;
    799 	bus_space_handle_t ioh;
    800 	bus_size_t off;
    801 	u_int32_t val;
    802 {
    803 	register bus_space_handle_t tmpioh;
    804 	register u_int32_t *port, nval;
    805 	register int offset;
    806 
    807 	tmpioh = ioh + off;
    808 	offset = tmpioh & 3;
    809         nval = val /*<< (8 * offset)*/;
    810         port = (u_int32_t *)((tmpioh << CHIP_ADDR_SHIFT) |
    811             (3 << CHIP_SIZE_SHIFT));
    812         *port = nval;
    813         alpha_mb();
    814 }
    815 
    816 inline void
    817 __C(CHIP,_io_write_8)(v, ioh, off, val)
    818 	void *v;
    819 	bus_space_handle_t ioh;
    820 	bus_size_t off;
    821 	u_int64_t val;
    822 {
    823 
    824 	/* XXX XXX XXX */
    825 	panic("%s not implemented", __S(__C(CHIP,_io_write_8)));
    826 	alpha_mb();
    827 }
    828 
    829 #define CHIP_io_write_multi_N(BYTES,TYPE)				\
    830 void									\
    831 __C(__C(CHIP,_io_write_multi_),BYTES)(v, h, o, a, c)			\
    832 	void *v;							\
    833 	bus_space_handle_t h;						\
    834 	bus_size_t o, c;						\
    835 	const TYPE *a;							\
    836 {									\
    837 									\
    838 	while (c-- > 0) {						\
    839 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);		\
    840 		__C(CHIP,_io_barrier)(v, h, o, sizeof *a,		\
    841 		    BUS_SPACE_BARRIER_WRITE);				\
    842 	}								\
    843 }
    844 CHIP_io_write_multi_N(1,u_int8_t)
    845 CHIP_io_write_multi_N(2,u_int16_t)
    846 CHIP_io_write_multi_N(4,u_int32_t)
    847 CHIP_io_write_multi_N(8,u_int64_t)
    848 
    849 #define CHIP_io_write_region_N(BYTES,TYPE)				\
    850 void									\
    851 __C(__C(CHIP,_io_write_region_),BYTES)(v, h, o, a, c)			\
    852 	void *v;							\
    853 	bus_space_handle_t h;						\
    854 	bus_size_t o, c;						\
    855 	const TYPE *a;							\
    856 {									\
    857 									\
    858 	while (c-- > 0) {						\
    859 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);		\
    860 		o += sizeof *a;						\
    861 	}								\
    862 }
    863 CHIP_io_write_region_N(1,u_int8_t)
    864 CHIP_io_write_region_N(2,u_int16_t)
    865 CHIP_io_write_region_N(4,u_int32_t)
    866 CHIP_io_write_region_N(8,u_int64_t)
    867 
    868 #define CHIP_io_set_multi_N(BYTES,TYPE)					\
    869 void									\
    870 __C(__C(CHIP,_io_set_multi_),BYTES)(v, h, o, val, c)			\
    871 	void *v;							\
    872 	bus_space_handle_t h;						\
    873 	bus_size_t o, c;						\
    874 	TYPE val;							\
    875 {									\
    876 									\
    877 	while (c-- > 0) {						\
    878 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, val);		\
    879 		__C(CHIP,_io_barrier)(v, h, o, sizeof val,		\
    880 		    BUS_SPACE_BARRIER_WRITE);				\
    881 	}								\
    882 }
    883 CHIP_io_set_multi_N(1,u_int8_t)
    884 CHIP_io_set_multi_N(2,u_int16_t)
    885 CHIP_io_set_multi_N(4,u_int32_t)
    886 CHIP_io_set_multi_N(8,u_int64_t)
    887 
    888 #define CHIP_io_set_region_N(BYTES,TYPE)				\
    889 void									\
    890 __C(__C(CHIP,_io_set_region_),BYTES)(v, h, o, val, c)			\
    891 	void *v;							\
    892 	bus_space_handle_t h;						\
    893 	bus_size_t o, c;						\
    894 	TYPE val;							\
    895 {									\
    896 									\
    897 	while (c-- > 0) {						\
    898 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, val);		\
    899 		o += sizeof val;					\
    900 	}								\
    901 }
    902 CHIP_io_set_region_N(1,u_int8_t)
    903 CHIP_io_set_region_N(2,u_int16_t)
    904 CHIP_io_set_region_N(4,u_int32_t)
    905 CHIP_io_set_region_N(8,u_int64_t)
    906 
    907 #define	CHIP_io_copy_region_N(BYTES)					\
    908 void									\
    909 __C(__C(CHIP,_io_copy_region_),BYTES)(v, h1, o1, h2, o2, c)		\
    910 	void *v;							\
    911 	bus_space_handle_t h1, h2;					\
    912 	bus_size_t o1, o2, c;						\
    913 {									\
    914 	bus_size_t o;							\
    915 									\
    916 	if ((h1 + o1) >= (h2 + o2)) {					\
    917 		/* src after dest: copy forward */			\
    918 		for (o = 0; c != 0; c--, o += BYTES)			\
    919 			__C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o,	\
    920 			    __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \
    921 	} else {							\
    922 		/* dest after src: copy backwards */			\
    923 		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES)	\
    924 			__C(__C(CHIP,_io_write_),BYTES)(v, h2, o2 + o,	\
    925 			    __C(__C(CHIP,_io_read_),BYTES)(v, h1, o1 + o)); \
    926 	}								\
    927 }
    928 CHIP_io_copy_region_N(1)
    929 CHIP_io_copy_region_N(2)
    930 CHIP_io_copy_region_N(4)
    931 CHIP_io_copy_region_N(8)
    932