Home | History | Annotate | Line # | Download | only in pci
pci_swiz_bus_io_chipdep.c revision 1.9
      1 /*	$NetBSD: pci_swiz_bus_io_chipdep.c,v 1.9 1996/10/23 04:12:31 cgd Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
      5  * All rights reserved.
      6  *
      7  * Author: Chris G. Demetriou
      8  *
      9  * Permission to use, copy, modify and distribute this software and
     10  * its documentation is hereby granted, provided that both the copyright
     11  * notice and this permission notice appear in all copies of the
     12  * software, derivative works or modified versions, and any portions
     13  * thereof, and that both notices appear in supporting documentation.
     14  *
     15  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     16  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
     17  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     18  *
     19  * Carnegie Mellon requests users of this software to return to
     20  *
     21  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     22  *  School of Computer Science
     23  *  Carnegie Mellon University
     24  *  Pittsburgh PA 15213-3890
     25  *
     26  * any improvements or extensions that they make and grant Carnegie the
     27  * rights to redistribute these changes.
     28  */
     29 
     30 /*
     31  * Common PCI Chipset "bus I/O" functions, for chipsets which have to
     32  * deal with only a single PCI interface chip in a machine.
     33  *
     34  * uses:
     35  *	CHIP		name of the 'chip' it's being compiled for.
     36  *	CHIP_IO_BASE	Sparse I/O space base to use.
     37  */
     38 
     39 #define	__C(A,B)	__CONCAT(A,B)
     40 #define	__S(S)		__STRING(S)
     41 
     42 /* mapping/unmapping */
     43 int		__C(CHIP,_io_map) __P((void *, bus_addr_t, bus_size_t, int,
     44 		    bus_space_handle_t *));
     45 void		__C(CHIP,_io_unmap) __P((void *, bus_space_handle_t,
     46 		    bus_size_t));
     47 int		__C(CHIP,_io_subregion) __P((void *, bus_space_handle_t,
     48 		    bus_size_t, bus_size_t, bus_space_handle_t *));
     49 
     50 /* allocation/deallocation */
     51 int		__C(CHIP,_io_alloc) __P((void *, bus_addr_t, bus_addr_t,
     52 		    bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *,
     53                     bus_space_handle_t *));
     54 void		__C(CHIP,_io_free) __P((void *, bus_space_handle_t,
     55 		    bus_size_t));
     56 
     57 /* read (single) */
     58 u_int8_t	__C(CHIP,_io_read_1) __P((void *, bus_space_handle_t,
     59 		    bus_size_t));
     60 u_int16_t	__C(CHIP,_io_read_2) __P((void *, bus_space_handle_t,
     61 		    bus_size_t));
     62 u_int32_t	__C(CHIP,_io_read_4) __P((void *, bus_space_handle_t,
     63 		    bus_size_t));
     64 u_int64_t	__C(CHIP,_io_read_8) __P((void *, bus_space_handle_t,
     65 		    bus_size_t));
     66 
     67 /* read multiple */
     68 void		__C(CHIP,_io_read_multi_1) __P((void *, bus_space_handle_t,
     69 		    bus_size_t, u_int8_t *, bus_size_t));
     70 void		__C(CHIP,_io_read_multi_2) __P((void *, bus_space_handle_t,
     71 		    bus_size_t, u_int16_t *, bus_size_t));
     72 void		__C(CHIP,_io_read_multi_4) __P((void *, bus_space_handle_t,
     73 		    bus_size_t, u_int32_t *, bus_size_t));
     74 void		__C(CHIP,_io_read_multi_8) __P((void *, bus_space_handle_t,
     75 		    bus_size_t, u_int64_t *, bus_size_t));
     76 
     77 /* read region */
     78 void		__C(CHIP,_io_read_region_1) __P((void *, bus_space_handle_t,
     79 		    bus_size_t, u_int8_t *, bus_size_t));
     80 void		__C(CHIP,_io_read_region_2) __P((void *, bus_space_handle_t,
     81 		    bus_size_t, u_int16_t *, bus_size_t));
     82 void		__C(CHIP,_io_read_region_4) __P((void *, bus_space_handle_t,
     83 		    bus_size_t, u_int32_t *, bus_size_t));
     84 void		__C(CHIP,_io_read_region_8) __P((void *, bus_space_handle_t,
     85 		    bus_size_t, u_int64_t *, bus_size_t));
     86 
     87 /* write (single) */
     88 void		__C(CHIP,_io_write_1) __P((void *, bus_space_handle_t,
     89 		    bus_size_t, u_int8_t));
     90 void		__C(CHIP,_io_write_2) __P((void *, bus_space_handle_t,
     91 		    bus_size_t, u_int16_t));
     92 void		__C(CHIP,_io_write_4) __P((void *, bus_space_handle_t,
     93 		    bus_size_t, u_int32_t));
     94 void		__C(CHIP,_io_write_8) __P((void *, bus_space_handle_t,
     95 		    bus_size_t, u_int64_t));
     96 
     97 /* write multiple */
     98 void		__C(CHIP,_io_write_multi_1) __P((void *, bus_space_handle_t,
     99 		    bus_size_t, const u_int8_t *, bus_size_t));
    100 void		__C(CHIP,_io_write_multi_2) __P((void *, bus_space_handle_t,
    101 		    bus_size_t, const u_int16_t *, bus_size_t));
    102 void		__C(CHIP,_io_write_multi_4) __P((void *, bus_space_handle_t,
    103 		    bus_size_t, const u_int32_t *, bus_size_t));
    104 void		__C(CHIP,_io_write_multi_8) __P((void *, bus_space_handle_t,
    105 		    bus_size_t, const u_int64_t *, bus_size_t));
    106 
    107 /* write region */
    108 void		__C(CHIP,_io_write_region_1) __P((void *, bus_space_handle_t,
    109 		    bus_size_t, const u_int8_t *, bus_size_t));
    110 void		__C(CHIP,_io_write_region_2) __P((void *, bus_space_handle_t,
    111 		    bus_size_t, const u_int16_t *, bus_size_t));
    112 void		__C(CHIP,_io_write_region_4) __P((void *, bus_space_handle_t,
    113 		    bus_size_t, const u_int32_t *, bus_size_t));
    114 void		__C(CHIP,_io_write_region_8) __P((void *, bus_space_handle_t,
    115 		    bus_size_t, const u_int64_t *, bus_size_t));
    116 
    117 /* barrier */
    118 void		__C(CHIP,_io_barrier) __P((void *, bus_space_handle_t,
    119 		    bus_size_t, bus_size_t, int));
    120 
    121 static struct alpha_bus_space __C(CHIP,_io_space) = {
    122 	/* cookie */
    123 	NULL,
    124 
    125 	/* mapping/unmapping */
    126 	__C(CHIP,_io_map),
    127 	__C(CHIP,_io_unmap),
    128 	__C(CHIP,_io_subregion),
    129 
    130 	/* allocation/deallocation */
    131 	__C(CHIP,_io_alloc),
    132 	__C(CHIP,_io_free),
    133 
    134 	/* read (single) */
    135 	__C(CHIP,_io_read_1),
    136 	__C(CHIP,_io_read_2),
    137 	__C(CHIP,_io_read_4),
    138 	__C(CHIP,_io_read_8),
    139 
    140 	/* read multi */
    141 	__C(CHIP,_io_read_multi_1),
    142 	__C(CHIP,_io_read_multi_2),
    143 	__C(CHIP,_io_read_multi_4),
    144 	__C(CHIP,_io_read_multi_8),
    145 
    146 	/* read region */
    147 	__C(CHIP,_io_read_region_1),
    148 	__C(CHIP,_io_read_region_2),
    149 	__C(CHIP,_io_read_region_4),
    150 	__C(CHIP,_io_read_region_8),
    151 
    152 	/* write (single) */
    153 	__C(CHIP,_io_write_1),
    154 	__C(CHIP,_io_write_2),
    155 	__C(CHIP,_io_write_4),
    156 	__C(CHIP,_io_write_8),
    157 
    158 	/* write multi */
    159 	__C(CHIP,_io_write_multi_1),
    160 	__C(CHIP,_io_write_multi_2),
    161 	__C(CHIP,_io_write_multi_4),
    162 	__C(CHIP,_io_write_multi_8),
    163 
    164 	/* write region */
    165 	__C(CHIP,_io_write_region_1),
    166 	__C(CHIP,_io_write_region_2),
    167 	__C(CHIP,_io_write_region_4),
    168 	__C(CHIP,_io_write_region_8),
    169 
    170 	/* set multi */
    171 	/* XXX IMPLEMENT */
    172 
    173 	/* set region */
    174 	/* XXX IMPLEMENT */
    175 
    176 	/* copy */
    177 	/* XXX IMPLEMENT */
    178 
    179 	/* barrier */
    180 	__C(CHIP,_io_barrier),
    181 };
    182 
    183 bus_space_tag_t
    184 __C(CHIP,_bus_io_init)(iov)
    185 	void *iov;
    186 {
    187         bus_space_tag_t h = &__C(CHIP,_io_space);;
    188 
    189 	h->abs_cookie = iov;
    190 	return (h);
    191 }
    192 
    193 int
    194 __C(CHIP,_io_map)(v, ioaddr, iosize, cacheable, iohp)
    195 	void *v;
    196 	bus_addr_t ioaddr;
    197 	bus_size_t iosize;
    198 	int cacheable;
    199 	bus_space_handle_t *iohp;
    200 {
    201 
    202 #ifdef CHIP_IO_W1_START
    203 	if (ioaddr >= CHIP_IO_W1_START(v) &&
    204 	    ioaddr <= CHIP_IO_W1_END(v)) {
    205 		*iohp = (ALPHA_PHYS_TO_K0SEG(CHIP_IO_W1_BASE(v)) >> 5) +
    206 		    (ioaddr & CHIP_IO_W1_MASK(v));
    207 	} else
    208 #endif
    209 #ifdef CHIP_IO_W2_START
    210 	if (ioaddr >= CHIP_IO_W2_START(v) &&
    211 	    ioaddr <= CHIP_IO_W2_END(v)) {
    212 		*iohp = (ALPHA_PHYS_TO_K0SEG(CHIP_IO_W2_BASE(v)) >> 5) +
    213 		    (ioaddr & CHIP_IO_W2_MASK(v));
    214 	} else
    215 #endif
    216 	{
    217 		printf("\n");
    218 #ifdef CHIP_IO_W1_START
    219 		printf("%s: window[1]=0x%lx-0x%lx\n",
    220 		    __S(__C(CHIP,_io_map)), CHIP_IO_W1_START(v),
    221 		    CHIP_IO_W1_END(v)-1);
    222 #endif
    223 #ifdef CHIP_IO_W2_START
    224 		printf("%s: window[2]=0x%lx-0x%lx\n",
    225 		    __S(__C(CHIP,_io_map)), CHIP_IO_W2_START(v),
    226 		    CHIP_IO_W2_END(v)-1);
    227 #endif
    228 		panic("%s: don't know how to map %lx non-cacheable",
    229 		    __S(__C(CHIP,_io_map)), ioaddr);
    230 	}
    231 
    232 	/* XXX XXX XXX XXX XXX XXX */
    233 	return (0);
    234 }
    235 
    236 void
    237 __C(CHIP,_io_unmap)(v, ioh, iosize)
    238 	void *v;
    239 	bus_space_handle_t ioh;
    240 	bus_size_t iosize;
    241 {
    242 
    243 	/* XXX nothing to do. */
    244 	/* XXX XXX XXX XXX XXX XXX */
    245 }
    246 
    247 int
    248 __C(CHIP,_io_subregion)(v, ioh, offset, size, nioh)
    249 	void *v;
    250 	bus_space_handle_t ioh, *nioh;
    251 	bus_size_t offset, size;
    252 {
    253 
    254 	*nioh = ioh + offset;
    255 	return (0);
    256 }
    257 
    258 int
    259 __C(CHIP,_io_alloc)(v, rstart, rend, size, align, boundary, cacheable,
    260     addrp, bshp)
    261 	void *v;
    262 	bus_addr_t rstart, rend, *addrp;
    263 	bus_size_t size, align, boundary;
    264 	int cacheable;
    265 	bus_space_handle_t *bshp;
    266 {
    267 
    268 	/* XXX XXX XXX XXX XXX XXX */
    269 	panic("%s not implemented", __S(__C(CHIP,_io_alloc)));
    270 }
    271 
    272 void
    273 __C(CHIP,_io_free)(v, bsh, size)
    274 	void *v;
    275 	bus_space_handle_t bsh;
    276 	bus_size_t size;
    277 {
    278 
    279 	/* XXX XXX XXX XXX XXX XXX */
    280 	panic("%s not implemented", __S(__C(CHIP,_io_free)));
    281 }
    282 
    283 u_int8_t
    284 __C(CHIP,_io_read_1)(v, ioh, off)
    285 	void *v;
    286 	bus_space_handle_t ioh;
    287 	bus_size_t off;
    288 {
    289 	register bus_space_handle_t tmpioh;
    290 	register u_int32_t *port, val;
    291 	register u_int8_t rval;
    292 	register int offset;
    293 
    294 	alpha_mb();
    295 
    296 	tmpioh = ioh + off;
    297 	offset = tmpioh & 3;
    298 	port = (u_int32_t *)((tmpioh << 5) | (0 << 3));
    299 	val = *port;
    300 	rval = ((val) >> (8 * offset)) & 0xff;
    301 
    302 	return rval;
    303 }
    304 
    305 u_int16_t
    306 __C(CHIP,_io_read_2)(v, ioh, off)
    307 	void *v;
    308 	bus_space_handle_t ioh;
    309 	bus_size_t off;
    310 {
    311 	register bus_space_handle_t tmpioh;
    312 	register u_int32_t *port, val;
    313 	register u_int16_t rval;
    314 	register int offset;
    315 
    316 	alpha_mb();
    317 
    318 	tmpioh = ioh + off;
    319 	offset = tmpioh & 3;
    320 	port = (u_int32_t *)((tmpioh << 5) | (1 << 3));
    321 	val = *port;
    322 	rval = ((val) >> (8 * offset)) & 0xffff;
    323 
    324 	return rval;
    325 }
    326 
    327 u_int32_t
    328 __C(CHIP,_io_read_4)(v, ioh, off)
    329 	void *v;
    330 	bus_space_handle_t ioh;
    331 	bus_size_t off;
    332 {
    333 	register bus_space_handle_t tmpioh;
    334 	register u_int32_t *port, val;
    335 	register u_int32_t rval;
    336 	register int offset;
    337 
    338 	alpha_mb();
    339 
    340 	tmpioh = ioh + off;
    341 	offset = tmpioh & 3;
    342 	port = (u_int32_t *)((tmpioh << 5) | (3 << 3));
    343 	val = *port;
    344 #if 0
    345 	rval = ((val) >> (8 * offset)) & 0xffffffff;
    346 #else
    347 	rval = val;
    348 #endif
    349 
    350 	return rval;
    351 }
    352 
    353 u_int64_t
    354 __C(CHIP,_io_read_8)(v, ioh, off)
    355 	void *v;
    356 	bus_space_handle_t ioh;
    357 	bus_size_t off;
    358 {
    359 
    360 	/* XXX XXX XXX */
    361 	panic("%s not implemented", __S(__C(CHIP,_io_read_8)));
    362 }
    363 
    364 #define CHIP_io_read_multi_N(BYTES,TYPE)				\
    365 void									\
    366 __C(__C(CHIP,_io_read_multi_),BYTES)(v, h, o, a, c)			\
    367 	void *v;							\
    368 	bus_space_handle_t h;						\
    369 	bus_size_t o, c;						\
    370 	TYPE *a;							\
    371 {									\
    372 									\
    373 	while (c-- > 0) {						\
    374 		__C(CHIP,_io_barrier)(v, h, o, sizeof *a,		\
    375 		    BUS_BARRIER_READ);					\
    376 		*a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
    377 	}								\
    378 }
    379 CHIP_io_read_multi_N(1,u_int8_t)
    380 CHIP_io_read_multi_N(2,u_int16_t)
    381 CHIP_io_read_multi_N(4,u_int32_t)
    382 CHIP_io_read_multi_N(8,u_int64_t)
    383 
    384 #define CHIP_io_read_region_N(BYTES,TYPE)				\
    385 void									\
    386 __C(__C(CHIP,_io_read_region_),BYTES)(v, h, o, a, c)			\
    387 	void *v;							\
    388 	bus_space_handle_t h;						\
    389 	bus_size_t o, c;						\
    390 	TYPE *a;							\
    391 {									\
    392 									\
    393 	while (c-- > 0) {						\
    394 		*a++ = __C(__C(CHIP,_io_read_),BYTES)(v, h, o);		\
    395 		o += sizeof *a;						\
    396 	}								\
    397 }
    398 CHIP_io_read_region_N(1,u_int8_t)
    399 CHIP_io_read_region_N(2,u_int16_t)
    400 CHIP_io_read_region_N(4,u_int32_t)
    401 CHIP_io_read_region_N(8,u_int64_t)
    402 
    403 void
    404 __C(CHIP,_io_write_1)(v, ioh, off, val)
    405 	void *v;
    406 	bus_space_handle_t ioh;
    407 	bus_size_t off;
    408 	u_int8_t val;
    409 {
    410 	register bus_space_handle_t tmpioh;
    411 	register u_int32_t *port, nval;
    412 	register int offset;
    413 
    414 	tmpioh = ioh + off;
    415 	offset = tmpioh & 3;
    416         nval = val << (8 * offset);
    417         port = (u_int32_t *)((tmpioh << 5) | (0 << 3));
    418         *port = nval;
    419         alpha_mb();
    420 }
    421 
    422 void
    423 __C(CHIP,_io_write_2)(v, ioh, off, val)
    424 	void *v;
    425 	bus_space_handle_t ioh;
    426 	bus_size_t off;
    427 	u_int16_t val;
    428 {
    429 	register bus_space_handle_t tmpioh;
    430 	register u_int32_t *port, nval;
    431 	register int offset;
    432 
    433 	tmpioh = ioh + off;
    434 	offset = tmpioh & 3;
    435         nval = val << (8 * offset);
    436         port = (u_int32_t *)((tmpioh << 5) | (1 << 3));
    437         *port = nval;
    438         alpha_mb();
    439 }
    440 
    441 void
    442 __C(CHIP,_io_write_4)(v, ioh, off, val)
    443 	void *v;
    444 	bus_space_handle_t ioh;
    445 	bus_size_t off;
    446 	u_int32_t val;
    447 {
    448 	register bus_space_handle_t tmpioh;
    449 	register u_int32_t *port, nval;
    450 	register int offset;
    451 
    452 	tmpioh = ioh + off;
    453 	offset = tmpioh & 3;
    454         nval = val /*<< (8 * offset)*/;
    455         port = (u_int32_t *)((tmpioh << 5) | (3 << 3));
    456         *port = nval;
    457         alpha_mb();
    458 }
    459 
    460 void
    461 __C(CHIP,_io_write_8)(v, ioh, off, val)
    462 	void *v;
    463 	bus_space_handle_t ioh;
    464 	bus_size_t off;
    465 	u_int64_t val;
    466 {
    467 
    468 	/* XXX XXX XXX */
    469 	panic("%s not implemented", __S(__C(CHIP,_io_write_8)));
    470 	alpha_mb();
    471 }
    472 
    473 #define CHIP_io_write_multi_N(BYTES,TYPE)				\
    474 void									\
    475 __C(__C(CHIP,_io_write_multi_),BYTES)(v, h, o, a, c)			\
    476 	void *v;							\
    477 	bus_space_handle_t h;						\
    478 	bus_size_t o, c;						\
    479 	const TYPE *a;							\
    480 {									\
    481 									\
    482 	while (c-- > 0) {						\
    483 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);		\
    484 		__C(CHIP,_io_barrier)(v, h, o, sizeof *a,		\
    485 		    BUS_BARRIER_WRITE);					\
    486 	}								\
    487 }
    488 CHIP_io_write_multi_N(1,u_int8_t)
    489 CHIP_io_write_multi_N(2,u_int16_t)
    490 CHIP_io_write_multi_N(4,u_int32_t)
    491 CHIP_io_write_multi_N(8,u_int64_t)
    492 
    493 #define CHIP_io_write_region_N(BYTES,TYPE)				\
    494 void									\
    495 __C(__C(CHIP,_io_write_region_),BYTES)(v, h, o, a, c)			\
    496 	void *v;							\
    497 	bus_space_handle_t h;						\
    498 	bus_size_t o, c;						\
    499 	const TYPE *a;							\
    500 {									\
    501 									\
    502 	while (c-- > 0) {						\
    503 		__C(__C(CHIP,_io_write_),BYTES)(v, h, o, *a++);		\
    504 		o += sizeof *a;						\
    505 	}								\
    506 }
    507 CHIP_io_write_region_N(1,u_int8_t)
    508 CHIP_io_write_region_N(2,u_int16_t)
    509 CHIP_io_write_region_N(4,u_int32_t)
    510 CHIP_io_write_region_N(8,u_int64_t)
    511 
    512 void
    513 __C(CHIP,_io_barrier)(v, h, o, l, f)
    514 	void *v;
    515 	bus_space_handle_t h;
    516 	bus_size_t o, l;
    517 	int f;
    518 {
    519 
    520 	if ((f & BUS_BARRIER_READ) != 0)
    521 		alpha_mb();
    522 	else if ((f & BUS_BARRIER_WRITE) != 0)
    523 		alpha_wmb();
    524 }
    525