1/* $NetBSD: bus_space_alignstride_chipdep.c,v 1.18 2011/09/23 12:42:15 macallan Exp $ */
2
3/*-
4 * Copyright (c) 1998, 2000, 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/*
34 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
35 * All rights reserved.
36 *
37 * Author: Chris G. Demetriou
38 *
39 * Permission to use, copy, modify and distribute this software and
40 * its documentation is hereby granted, provided that both the copyright
41 * notice and this permission notice appear in all copies of the
42 * software, derivative works or modified versions, and any portions
43 * thereof, and that both notices appear in supporting documentation.
44 *
45 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
46 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
47 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
48 *
49 * Carnegie Mellon requests users of this software to return to
50 *
51 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
52 *  School of Computer Science
53 *  Carnegie Mellon University
54 *  Pittsburgh PA 15213-3890
55 *
56 * any improvements or extensions that they make and grant Carnegie the
57 * rights to redistribute these changes.
58 */
59
60/*
61 * Common Chipset "bus I/O" functions.
62 *
63 * uses:
64 *	CHIP		name of the 'chip' it's being compiled for.
65 *	CHIP_BASE	memory or I/O space base to use.
66 *	CHIP_EX_STORE
67 *			If defined, device-provided static storage area
68 *			for the memory or I/O space extent.  If this is
69 *			defined, CHIP_EX_STORE_SIZE must also be defined.
70 *			If this is not defined, a static area will be
71 *			declared.
72 *	CHIP_EX_STORE_SIZE
73 *			Size of the device-provided static storage area
74 *			for the memory or I/O memory space extent.
75 *	CHIP_LITTLE_ENDIAN | CHIP_BIG_ENDIAN
76 *			For endian-specific busses, like PCI (little).
77 *	CHIP_ACCESS_SIZE
78 *			Size (in bytes) of minimum bus access, e.g. 4
79 *			to indicate all bus cycles are 32-bits.  Defaults
80 *			to 1, indicating any access size is valid.
81 */
82
83#include <sys/cdefs.h>
84__KERNEL_RCSID(0, "$NetBSD: bus_space_alignstride_chipdep.c,v 1.18 2011/09/23 12:42:15 macallan Exp $");
85
86#ifdef CHIP_EXTENT
87#include <sys/extent.h>
88#endif
89#include <sys/malloc.h>
90
91#include <mips/locore.h>
92
93#include <uvm/uvm_extern.h>
94
95#define	__C(A,B)	__CONCAT(A,B)
96#define	__S(S)		__STRING(S)
97
98#ifdef CHIP_IO
99#define	__BS(A)		__C(__C(CHIP,_bus_io_),A)
100#endif
101#ifdef CHIP_MEM
102#define	__BS(A)		__C(__C(CHIP,_bus_mem_),A)
103#endif
104
105#if defined(CHIP_LITTLE_ENDIAN)
106#define	CHIP_SWAP16(x)	le16toh(x)
107#define	CHIP_SWAP32(x)	le32toh(x)
108#define	CHIP_SWAP64(x)	le64toh(x)
109#define	CHIP_NEED_STREAM	1
110#elif defined(CHIP_BIG_ENDIAN)
111#define	CHIP_SWAP16(x)	be16toh(x)
112#define	CHIP_SWAP32(x)	be32toh(x)
113#define	CHIP_SWAP64(x)	be64toh(x)
114#define	CHIP_NEED_STREAM	1
115#else
116#define	CHIP_SWAP16(x)	(x)
117#define	CHIP_SWAP32(x)	(x)
118#define	CHIP_SWAP64(x)	(x)
119#endif
120
121#ifndef	CHIP_ACCESS_SIZE
122#define	CHIP_ACCESS_SIZE	1
123#endif
124
125#if CHIP_ACCESS_SIZE==1
126# define CHIP_SWAP_ACCESS(x)	(x)
127#elif CHIP_ACCESS_SIZE==2
128# define CHIP_SWAP_ACCESS(x)	CHIP_SWAP16(x)
129#elif CHIP_ACCESS_SIZE==4
130# define CHIP_SWAP_ACCESS(x)	CHIP_SWAP32(x)
131#elif CHIP_ACCESS_SIZE==8
132# define CHIP_SWAP_ACCESS(x)	CHIP_SWAP64(x)
133#else
134# error your access size not implemented
135#endif
136
137/*
138 * The logic here determines a few macros to support requirements for
139 * whole-word accesses:
140 *
141 * CHIP_TYPE is a uintXX_t that represents the native access type for the bus.
142 *
143 * CHIP_SHIFTXX is the number of bits to shift a big-endian value to convert
144 * convert between the CHIP_TYPE and uintXX_t.
145 *
146 * The idea is that if we want to do a 16bit load from a bus that only
147 * supports 32-bit accesses, we will access the first 16 bits of the
148 * addressed 32-bit word.
149 *
150 * Obviously (hopefully) this method is inadequate to support addressing the
151 * second half of a 16-bit word, or the upper 3/4 of a 32-bit value, etc.
152 * In other words, the drivers should probably not be relying on this!
153 *
154 * We should probably come back in here some day and handle offsets properly.
155 * to do that, we need to mask off the low order bits of the address, and
156 * then figure out which bits they correspond to.
157 *
158 * If we have fixed access size limitations, we need to make sure that
159 * handle shifting required for big-endian storage.  The reality is
160 * that if the bus only supports size "n", then drivers should
161 * probably only access it using "n" sized (or bigger) accesses.
162 */
163
164#if	CHIP_ACCESS_SIZE == 1
165#define	CHIP_TYPE	uint8_t
166#endif
167
168#if	CHIP_ACCESS_SIZE == 2
169#define	CHIP_TYPE	uint16_t
170#endif
171
172#if	CHIP_ACCESS_SIZE == 4
173#define	CHIP_TYPE	uint32_t
174#endif
175
176#if	CHIP_ACCESS_SIZE == 8
177#define	CHIP_TYPE	uint64_t
178#endif
179
180#ifndef CHIP_TYPE
181#error	"Invalid chip access size!"
182#endif
183
184#ifdef CHIP_EXTENT
185#ifndef	CHIP_EX_STORE
186static long
187    __BS(ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)];
188#define	CHIP_EX_STORE(v)	(__BS(ex_storage))
189#define	CHIP_EX_STORE_SIZE(v)	(sizeof __BS(ex_storage))
190#endif
191#endif /* CHIP_EXTENT */
192
193#ifndef CHIP_ALIGN_STRIDE
194#define	CHIP_ALIGN_STRIDE	0
195#endif
196
197#if CHIP_ALIGN_STRIDE > 0
198#define	CHIP_OFF8(o)	((o) << (CHIP_ALIGN_STRIDE))
199#else
200#define	CHIP_OFF8(o)	(o)
201#endif
202
203#if CHIP_ALIGN_STRIDE > 1
204#define	CHIP_OFF16(o)	((o) << (CHIP_ALIGN_STRIDE - 1))
205#else
206#define	CHIP_OFF16(o)	(o)
207#endif
208
209#if CHIP_ALIGN_STRIDE > 2
210#define	CHIP_OFF32(o)	((o) << (CHIP_ALIGN_STRIDE - 2))
211#else
212#define	CHIP_OFF32(o)	(o)
213#endif
214
215#if CHIP_ALIGN_STRIDE > 3
216#define	CHIP_OFF64(o)	((o) << (CHIP_ALIGN_STRIDE - 3))
217#else
218#define	CHIP_OFF64(o)	(o)
219#endif
220
221
222static int
223__BS(get_window)(void *v, int window, struct mips_bus_space_translation *mbst)
224{
225
226	switch (window) {
227#ifdef CHIP_W1_BUS_START
228	case 0:
229		mbst->mbst_bus_start = CHIP_W1_BUS_START(v);
230		mbst->mbst_bus_end = CHIP_W1_BUS_END(v);
231		mbst->mbst_sys_start = CHIP_W1_SYS_START(v);
232		mbst->mbst_sys_end = CHIP_W1_SYS_END(v);
233		mbst->mbst_align_stride = CHIP_ALIGN_STRIDE;
234		mbst->mbst_flags = 0;
235		break;
236#endif
237
238#ifdef CHIP_W2_BUS_START
239	case 1:
240		mbst->mbst_bus_start = CHIP_W2_BUS_START(v);
241		mbst->mbst_bus_end = CHIP_W2_BUS_END(v);
242		mbst->mbst_sys_start = CHIP_W2_SYS_START(v);
243		mbst->mbst_sys_end = CHIP_W2_SYS_END(v);
244		mbst->mbst_align_stride = CHIP_ALIGN_STRIDE;
245		mbst->mbst_flags = 0;
246		break;
247#endif
248
249#ifdef CHIP_W3_BUS_START
250	case 2:
251		mbst->mbst_bus_start = CHIP_W3_BUS_START(v);
252		mbst->mbst_bus_end = CHIP_W3_BUS_END(v);
253		mbst->mbst_sys_start = CHIP_W3_SYS_START(v);
254		mbst->mbst_sys_end = CHIP_W3_SYS_END(v);
255		mbst->mbst_align_stride = CHIP_ALIGN_STRIDE;
256		mbst->mbst_flags = 0;
257		break;
258#endif
259
260	default:
261		panic(__S(__BS(get_window)) ": invalid window %d",
262		    window);
263	}
264
265	return (0);
266}
267
268static int
269__BS(translate)(void *v, bus_addr_t addr, bus_size_t len, int flags,
270    struct mips_bus_space_translation *mbst)
271{
272	bus_addr_t end = addr + (len - 1);
273#if CHIP_ALIGN_STRIDE != 0
274	int linear = flags & BUS_SPACE_MAP_LINEAR;
275
276	/*
277	 * Can't map xxx space linearly.
278	 */
279	if (linear)
280		return (EOPNOTSUPP);
281#endif
282
283#ifdef CHIP_W1_BUS_START
284	if (addr >= CHIP_W1_BUS_START(v) && end <= CHIP_W1_BUS_END(v))
285		return (__BS(get_window)(v, 0, mbst));
286#endif
287
288#ifdef CHIP_W2_BUS_START
289	if (addr >= CHIP_W2_BUS_START(v) && end <= CHIP_W2_BUS_END(v))
290		return (__BS(get_window)(v, 1, mbst));
291#endif
292
293#ifdef CHIP_W3_BUS_START
294	if (addr >= CHIP_W3_BUS_START(v) && end <= CHIP_W3_BUS_END(v))
295		return (__BS(get_window)(v, 2, mbst));
296#endif
297
298#ifdef EXTENT_DEBUG
299	printf("\n");
300#ifdef CHIP_W1_BUS_START
301	printf("%s: window[1]=0x%lx-0x%lx\n", __S(__BS(map)),
302	    (u_long)CHIP_W1_BUS_START(v), (u_long)CHIP_W1_BUS_END(v));
303#endif
304#ifdef CHIP_W2_BUS_START
305	printf("%s: window[2]=0x%lx-0x%lx\n", __S(__BS(map)),
306	    (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v));
307#endif
308#ifdef CHIP_W3_BUS_START
309	printf("%s: window[3]=0x%lx-0x%lx\n", __S(__BS(map)),
310	    (u_long)CHIP_W3_BUS_START(v), (u_long)CHIP_W3_BUS_END(v));
311#endif
312#endif /* EXTENT_DEBUG */
313	/* No translation. */
314	return (EINVAL);
315}
316
317static int
318__BS(map)(void *v, bus_addr_t addr, bus_size_t size, int flags,
319    bus_space_handle_t *hp, int acct)
320{
321	struct mips_bus_space_translation mbst;
322	int error;
323
324	/*
325	 * Get the translation for this address.
326	 */
327	error = __BS(translate)(v, addr, size, flags, &mbst);
328	if (error)
329		return (error);
330
331#ifdef CHIP_EXTENT
332	if (acct == 0)
333		goto mapit;
334
335#ifdef EXTENT_DEBUG
336	printf("%s: allocating %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n",
337		__S(__BS(map)), addr, addr + size - 1);
338#endif
339        error = extent_alloc_region(CHIP_EXTENT(v), addr, size,
340            EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
341	if (error) {
342#ifdef EXTENT_DEBUG
343		printf("%s: allocation failed (%d)\n", __S(__BS(map)), error);
344		extent_print(CHIP_EXTENT(v));
345#endif
346		return (error);
347	}
348
349 mapit:
350#endif /* CHIP_EXTENT */
351
352	addr = mbst.mbst_sys_start + (addr - mbst.mbst_bus_start);
353
354#ifdef _LP64
355	if (flags & BUS_SPACE_MAP_CACHEABLE)
356		*hp = MIPS_PHYS_TO_XKPHYS_CACHED(addr);
357	else if (flags & BUS_SPACE_MAP_PREFETCHABLE)
358		*hp = MIPS_PHYS_TO_XKPHYS_ACC(addr);
359	else
360		*hp = MIPS_PHYS_TO_XKPHYS_UNCACHED(addr);
361#else
362	if (((addr + size) & ~MIPS_PHYS_MASK) != 0) {
363		vaddr_t va;
364		paddr_t pa;
365		int s;
366
367		size = round_page((addr % PAGE_SIZE) + size);
368		va = uvm_km_alloc(kernel_map, size, PAGE_SIZE,
369			UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
370		if (va == 0)
371			return ENOMEM;
372
373		/* check use of handle_is_km in BS(unmap) */
374		KASSERT(!(MIPS_KSEG0_P(va) || MIPS_KSEG1_P(va)));
375
376		*hp = va + (addr & PAGE_MASK);
377		pa = trunc_page(addr);
378
379		s = splhigh();
380		while (size != 0) {
381			pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, 0);
382			pa += PAGE_SIZE;
383			va += PAGE_SIZE;
384			size -= PAGE_SIZE;
385		}
386		pmap_update(pmap_kernel());
387		splx(s);
388	} else {
389		if (flags & BUS_SPACE_MAP_CACHEABLE)
390			*hp = MIPS_PHYS_TO_KSEG0(addr);
391		else
392			*hp = MIPS_PHYS_TO_KSEG1(addr);
393	}
394#endif
395
396	return (0);
397}
398
399static void
400__BS(unmap)(void *v, bus_space_handle_t h, bus_size_t size, int acct)
401{
402#if !defined(_LP64) || defined(CHIP_EXTENT)
403	bus_addr_t addr = 0;	/* initialize to appease gcc */
404#endif
405#ifndef _LP64
406	bool handle_is_km;
407
408	/* determine if h is addr obtained from uvm_km_alloc */
409	handle_is_km = !(MIPS_KSEG0_P(h) || MIPS_KSEG1_P(h));
410	if (handle_is_km == true) {
411		paddr_t pa;
412		vaddr_t va = (vaddr_t)trunc_page(h);
413		vsize_t sz = (vsize_t)round_page((h % PAGE_SIZE) + size);
414		int s;
415
416		s = splhigh();
417
418		if (pmap_extract(pmap_kernel(), (vaddr_t)h, &pa) == false)
419			panic("%s: pmap_extract failed", __func__);
420		addr = (bus_addr_t)pa;
421#if 0
422		printf("%s:%d: addr %#"PRIxBUSADDR", sz %#"PRIxVSIZE"\n",
423			__func__, __LINE__, addr, sz);
424#endif
425		/* sanity check: this is why we couldn't map w/ kseg[0,1] */
426		KASSERT (((addr + sz) & ~MIPS_PHYS_MASK) != 0);
427
428		pmap_kremove(va, sz);
429		pmap_update(pmap_kernel());
430		uvm_km_free(kernel_map, va, sz, UVM_KMF_VAONLY);
431
432		splx(s);
433	}
434#endif	/* _LP64 */
435
436#ifdef CHIP_EXTENT
437
438	if (acct == 0)
439		return;
440
441#ifdef EXTENT_DEBUG
442	printf("%s: freeing handle %#"PRIxBSH" for %#"PRIxBUSSIZE"\n",
443		__S(__BS(unmap)), h, size);
444#endif
445
446#ifdef _LP64
447	KASSERT(MIPS_XKPHYS_P(h));
448	addr = MIPS_XKPHYS_TO_PHYS(h);
449#else
450	if (handle_is_km == false) {
451		if (MIPS_KSEG0_P(h))
452			addr = MIPS_KSEG0_TO_PHYS(h);
453		else
454			addr = MIPS_KSEG1_TO_PHYS(h);
455	}
456#endif
457
458#ifdef CHIP_W1_BUS_START
459	if (addr >= CHIP_W1_SYS_START(v) && addr <= CHIP_W1_SYS_END(v)) {
460		addr = CHIP_W1_BUS_START(v) + (addr - CHIP_W1_SYS_START(v));
461	} else
462#endif
463#ifdef CHIP_W2_BUS_START
464	if (addr >= CHIP_W2_SYS_START(v) && addr <= CHIP_W2_SYS_END(v)) {
465		addr = CHIP_W2_BUS_START(v) + (addr - CHIP_W2_SYS_START(v));
466	} else
467#endif
468#ifdef CHIP_W3_BUS_START
469	if (addr >= CHIP_W3_SYS_START(v) && addr <= CHIP_W3_SYS_END(v)) {
470		addr = CHIP_W3_BUS_START(v) + (addr - CHIP_W3_SYS_START(v));
471	} else
472#endif
473	{
474		printf("\n");
475#ifdef CHIP_W1_BUS_START
476		printf("%s: sys window[1]=0x%lx-0x%lx\n",
477		    __S(__BS(map)), (u_long)CHIP_W1_SYS_START(v),
478		    (u_long)CHIP_W1_SYS_END(v));
479#endif
480#ifdef CHIP_W2_BUS_START
481		printf("%s: sys window[2]=0x%lx-0x%lx\n",
482		    __S(__BS(map)), (u_long)CHIP_W2_SYS_START(v),
483		    (u_long)CHIP_W2_SYS_END(v));
484#endif
485#ifdef CHIP_W3_BUS_START
486		printf("%s: sys window[3]=0x%lx-0x%lx\n",
487		    __S(__BS(unmap)), (u_long)CHIP_W3_SYS_START(v),
488		    (u_long)CHIP_W3_SYS_END(v));
489#endif
490		panic("%s: don't know how to unmap %#"PRIxBSH, __S(__BS(unmap)), h);
491	}
492
493#ifdef EXTENT_DEBUG
494	printf("%s: freeing %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n",
495	    __S(__BS(unmap)), addr, addr + size - 1);
496#endif
497        int error = extent_free(CHIP_EXTENT(v), addr, size,
498            EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
499	if (error) {
500		printf("%s: WARNING: could not unmap"
501		    " %#"PRIxBUSADDR"-%#"PRIxBUSADDR" (error %d)\n",
502		    __S(__BS(unmap)), addr, addr + size - 1, error);
503#ifdef EXTENT_DEBUG
504		extent_print(CHIP_EXTENT(v));
505#endif
506	}
507#endif /* CHIP_EXTENT */
508}
509
510static int
511__BS(subregion)(void *v, bus_space_handle_t h, bus_size_t offset,
512    bus_size_t size, bus_space_handle_t *nh)
513{
514
515	*nh = h + (offset << CHIP_ALIGN_STRIDE);
516	return (0);
517}
518
519static int
520__BS(alloc)(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
521    bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
522    bus_space_handle_t *bshp)
523{
524#ifdef CHIP_EXTENT
525	struct mips_bus_space_translation mbst;
526	u_long addr;	/* bogus but makes extent happy */
527	int error;
528#if CHIP_ALIGN_STRIDE != 0
529	int linear = flags & BUS_SPACE_MAP_LINEAR;
530
531	/*
532	 * Can't map xxx space linearly.
533	 */
534	if (linear)
535		return (EOPNOTSUPP);
536#endif
537
538	/*
539	 * Do the requested allocation.
540	 */
541#ifdef EXTENT_DEBUG
542	printf("%s: allocating from %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n",
543		__S(__BS(alloc)), rstart, rend);
544#endif
545	error = extent_alloc_subregion(CHIP_EXTENT(v), rstart, rend, size,
546	    align, boundary,
547	    EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0),
548	    &addr);
549	if (error) {
550#ifdef EXTENT_DEBUG
551		printf("%s: allocation failed (%d)\n", __S(__BS(alloc)), error);
552		extent_print(CHIP_EXTENT(v));
553#endif
554		return (error);
555	}
556
557#ifdef EXTENT_DEBUG
558	printf("%s: allocated 0x%lx to %#"PRIxBUSSIZE"\n",
559		__S(__BS(alloc)), addr, addr + size - 1);
560#endif
561
562	error = __BS(translate)(v, addr, size, flags, &mbst);
563	if (error) {
564		(void) extent_free(CHIP_EXTENT(v), addr, size,
565		    EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
566		return (error);
567	}
568
569	*addrp = addr;
570#ifdef _LP64
571	if (flags & BUS_SPACE_MAP_CACHEABLE)
572		*bshp = MIPS_PHYS_TO_XKPHYS_CACHED(mbst.mbst_sys_start +
573		    (addr - mbst.mbst_bus_start));
574	else
575		*bshp = MIPS_PHYS_TO_XKPHYS_UNCACHED(mbst.mbst_sys_start +
576		    (addr - mbst.mbst_bus_start));
577#else
578	if (flags & BUS_SPACE_MAP_CACHEABLE)
579		*bshp = MIPS_PHYS_TO_KSEG0(mbst.mbst_sys_start +
580		    (addr - mbst.mbst_bus_start));
581	else
582		*bshp = MIPS_PHYS_TO_KSEG1(mbst.mbst_sys_start +
583		    (addr - mbst.mbst_bus_start));
584#endif
585
586	return (0);
587#else /* ! CHIP_EXTENT */
588	return (EOPNOTSUPP);
589#endif /* CHIP_EXTENT */
590}
591
592static void
593__BS(free)(void *v, bus_space_handle_t bsh, bus_size_t size)
594{
595
596	/* Unmap does all we need to do. */
597	__BS(unmap)(v, bsh, size, 1);
598}
599
600static void *
601__BS(vaddr)(void *v, bus_space_handle_t bsh)
602{
603
604#if CHIP_ALIGN_STRIDE != 0
605	/* Linear mappings not possible. */
606	return (NULL);
607#else
608	return ((void *)bsh);
609#endif
610}
611
612static paddr_t
613__BS(mmap)(void *v, bus_addr_t addr, off_t off, int prot, int flags)
614{
615#ifdef CHIP_IO
616
617	/* Not supported for I/O space. */
618	return (-1);
619#elif defined(CHIP_MEM)
620	paddr_t ret;
621	struct mips_bus_space_translation mbst;
622	int error;
623
624	/*
625	 * Get the translation for this address.
626	 */
627	error = __BS(translate)(v, addr, off + PAGE_SIZE, flags,
628	    &mbst);
629	if (error)
630		return (-1);
631	ret = mbst.mbst_sys_start + (addr - mbst.mbst_bus_start) + off;
632#if defined(_MIPS_PADDR_T_64BIT) || defined(_LP64)
633	if (flags & BUS_SPACE_MAP_PREFETCHABLE) {
634		ret |= PGC_PREFETCH;
635	}
636#endif
637
638	return (mips_btop(ret));
639#else
640# error must define one of CHIP_IO or CHIP_MEM
641#endif
642}
643
644static void
645__BS(barrier)(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int f)
646{
647
648	/* XXX XXX XXX */
649	if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
650		wbflush();
651}
652
653static uint8_t
654__BS(read_1)(void *v, bus_space_handle_t h, bus_size_t off)
655{
656#if CHIP_ACCESS_SIZE > 1
657	volatile CHIP_TYPE *ptr;
658#else	/* CHIP_ACCESS_SIZE > 1 */
659	volatile uint8_t *ptr;
660#endif	/* CHIP_ACCESS_SIZE > 1 */
661	uint8_t r;
662        int shift;
663
664        h += CHIP_OFF8(off);
665        shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
666        ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
667        r = (uint8_t)(CHIP_SWAP_ACCESS(*ptr) >> shift);
668
669        return r;
670}
671
672static uint16_t
673__BS(read_2)(void *v, bus_space_handle_t h, bus_size_t off)
674{
675#if CHIP_ACCESS_SIZE > 2
676	volatile CHIP_TYPE *ptr;
677#else	/* CHIP_ACCESS_SIZE > 2 */
678	volatile uint16_t *ptr;
679#endif	/* CHIP_ACCESS_SIZE > 2 */
680	uint16_t r;
681        int shift;
682
683	KASSERT((off & 1) == 0);
684        h += CHIP_OFF16(off);
685        shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
686        ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
687	r = (uint16_t)CHIP_SWAP16(*ptr >> shift);
688
689	return r;
690}
691
692static uint32_t
693__BS(read_4)(void *v, bus_space_handle_t h, bus_size_t off)
694{
695#if CHIP_ACCESS_SIZE > 4
696	volatile CHIP_TYPE *ptr;
697#else	/* CHIP_ACCESS_SIZE > 4 */
698	volatile uint32_t *ptr;
699#endif
700	uint32_t r;
701        int shift;
702
703	KASSERT((off & 3) == 0);
704        h += CHIP_OFF32(off);
705        shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
706        ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
707	r = (uint32_t)CHIP_SWAP32(*ptr >> shift);
708
709	return r;
710}
711
712static uint64_t
713__BS(read_8)(void *v, bus_space_handle_t h, bus_size_t off)
714{
715	volatile uint64_t *ptr;
716	volatile uint64_t r;
717        int shift;
718
719	KASSERT((off & 7) == 0);
720        h += CHIP_OFF64(off);
721        shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
722        ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
723	r =  CHIP_SWAP64(*ptr >> shift);
724
725	return r;
726}
727
728
729#define CHIP_read_multi_N(BYTES,TYPE)					\
730static void									\
731__C(__BS(read_multi_),BYTES)(void *v, bus_space_handle_t h,		\
732    bus_size_t o, TYPE *a, bus_size_t c)				\
733{									\
734									\
735	while (c-- > 0) {						\
736		__BS(barrier)(v, h, o, sizeof *a,			\
737		    BUS_SPACE_BARRIER_READ);				\
738		*a++ = __C(__BS(read_),BYTES)(v, h, o);			\
739	}								\
740}
741CHIP_read_multi_N(1,uint8_t)
742CHIP_read_multi_N(2,uint16_t)
743CHIP_read_multi_N(4,uint32_t)
744CHIP_read_multi_N(8,uint64_t)
745
746#define CHIP_read_region_N(BYTES,TYPE)					\
747static void									\
748__C(__BS(read_region_),BYTES)(void *v, bus_space_handle_t h,		\
749    bus_size_t o, TYPE *a, bus_size_t c)				\
750{									\
751									\
752	while (c-- > 0) {						\
753		*a++ = __C(__BS(read_),BYTES)(v, h, o);			\
754		o += sizeof *a;						\
755	}								\
756}
757CHIP_read_region_N(1,uint8_t)
758CHIP_read_region_N(2,uint16_t)
759CHIP_read_region_N(4,uint32_t)
760CHIP_read_region_N(8,uint64_t)
761
762
763static void
764__BS(write_1)(void *v, bus_space_handle_t h, bus_size_t off, uint8_t val)
765{
766#if CHIP_ACCESS_SIZE > 1
767	volatile CHIP_TYPE *ptr;
768#else	/* CHIP_ACCESS_SIZE > 1 */
769	volatile uint8_t *ptr;
770#endif	/* CHIP_ACCESS_SIZE > 1 */
771	int shift;
772
773	h += CHIP_OFF8(off);
774	shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
775	ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
776	*ptr = CHIP_SWAP_ACCESS(((CHIP_TYPE)val) << shift);
777}
778
779static void
780__BS(write_2)(void *v, bus_space_handle_t h, bus_size_t off, uint16_t val)
781{
782#if CHIP_ACCESS_SIZE > 2
783	volatile CHIP_TYPE *ptr;
784#else	/* CHIP_ACCESS_SIZE > 2 */
785	volatile uint16_t *ptr;
786#endif	/* CHIP_ACCESS_SIZE > 2 */
787	int shift;
788
789	KASSERT((off & 1) == 0);
790	h += CHIP_OFF16(off);
791	shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
792	ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
793	if (CHIP_ACCESS_SIZE > 2)
794		*ptr = (CHIP_TYPE)(CHIP_SWAP16(val)) << shift;
795	else
796		*ptr = CHIP_SWAP16(val);
797}
798
799static void
800__BS(write_4)(void *v, bus_space_handle_t h, bus_size_t off, uint32_t val)
801{
802#if CHIP_ACCESS_SIZE > 4
803	volatile CHIP_TYPE *ptr;
804#else	/* CHIP_ACCESS_SIZE > 4 */
805	volatile uint32_t *ptr;
806#endif	/* CHIP_ACCESS_SIZE > 4 */
807        int shift;
808
809	KASSERT((off & 3) == 0);
810        h += CHIP_OFF32(off);
811        shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
812        ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
813        if (CHIP_ACCESS_SIZE > 4)
814		*ptr = (CHIP_TYPE)(CHIP_SWAP32(val)) << shift;
815        else
816                *ptr = CHIP_SWAP32(val);
817}
818
819static void
820__BS(write_8)(void *v, bus_space_handle_t h, bus_size_t off, uint64_t val)
821{
822	volatile uint64_t *ptr;
823        int shift;
824
825	KASSERT((off & 7) == 0);
826        h += CHIP_OFF64(off);
827        shift = (off & (CHIP_ACCESS_SIZE - 1)) * 8;
828        ptr = (void *)(h & ~((bus_space_handle_t)(CHIP_ACCESS_SIZE - 1)));
829	*ptr = CHIP_SWAP64(val) << shift;
830}
831
832#define CHIP_write_multi_N(BYTES,TYPE)					\
833static void									\
834__C(__BS(write_multi_),BYTES)(void *v, bus_space_handle_t h,		\
835    bus_size_t o, const TYPE *a, bus_size_t c)				\
836{									\
837									\
838	while (c-- > 0) {						\
839		__C(__BS(write_),BYTES)(v, h, o, *a++);			\
840		__BS(barrier)(v, h, o, sizeof *a,			\
841		    BUS_SPACE_BARRIER_WRITE);				\
842	}								\
843}
844CHIP_write_multi_N(1,uint8_t)
845CHIP_write_multi_N(2,uint16_t)
846CHIP_write_multi_N(4,uint32_t)
847CHIP_write_multi_N(8,uint64_t)
848
849#define CHIP_write_region_N(BYTES,TYPE)					\
850static void									\
851__C(__BS(write_region_),BYTES)(void *v, bus_space_handle_t h,		\
852    bus_size_t o, const TYPE *a, bus_size_t c)				\
853{									\
854									\
855	while (c-- > 0) {						\
856		__C(__BS(write_),BYTES)(v, h, o, *a++);			\
857		o += sizeof *a;						\
858	}								\
859}
860CHIP_write_region_N(1,uint8_t)
861CHIP_write_region_N(2,uint16_t)
862CHIP_write_region_N(4,uint32_t)
863CHIP_write_region_N(8,uint64_t)
864
865#define CHIP_set_multi_N(BYTES,TYPE)					\
866static void									\
867__C(__BS(set_multi_),BYTES)(void *v, bus_space_handle_t h,		\
868    bus_size_t o, TYPE val, bus_size_t c)				\
869{									\
870									\
871	while (c-- > 0) {						\
872		__C(__BS(write_),BYTES)(v, h, o, val);			\
873		__BS(barrier)(v, h, o, sizeof val,			\
874		    BUS_SPACE_BARRIER_WRITE);				\
875	}								\
876}
877CHIP_set_multi_N(1,uint8_t)
878CHIP_set_multi_N(2,uint16_t)
879CHIP_set_multi_N(4,uint32_t)
880CHIP_set_multi_N(8,uint64_t)
881
882#define CHIP_set_region_N(BYTES,TYPE)					\
883static void									\
884__C(__BS(set_region_),BYTES)(void *v, bus_space_handle_t h,		\
885    bus_size_t o, TYPE val, bus_size_t c)				\
886{									\
887									\
888	while (c-- > 0) {						\
889		__C(__BS(write_),BYTES)(v, h, o, val);			\
890		o += sizeof val;					\
891	}								\
892}
893CHIP_set_region_N(1,uint8_t)
894CHIP_set_region_N(2,uint16_t)
895CHIP_set_region_N(4,uint32_t)
896CHIP_set_region_N(8,uint64_t)
897
898#define	CHIP_copy_region_N(BYTES)					\
899static void									\
900__C(__BS(copy_region_),BYTES)(void *v, bus_space_handle_t h1,		\
901    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)	\
902{									\
903	bus_size_t o;							\
904									\
905	if ((h1 + o1) >= (h2 + o2)) {					\
906		/* src after dest: copy forward */			\
907		for (o = 0; c != 0; c--, o += BYTES)			\
908			__C(__BS(write_),BYTES)(v, h2, o2 + o,		\
909			    __C(__BS(read_),BYTES)(v, h1, o1 + o));	\
910	} else {							\
911		/* dest after src: copy backwards */			\
912		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES)	\
913			__C(__BS(write_),BYTES)(v, h2, o2 + o,		\
914			    __C(__BS(read_),BYTES)(v, h1, o1 + o));	\
915	}								\
916}
917CHIP_copy_region_N(1)
918CHIP_copy_region_N(2)
919CHIP_copy_region_N(4)
920CHIP_copy_region_N(8)
921
922#ifdef	CHIP_NEED_STREAM
923
924static uint8_t
925__BS(read_stream_1)(void *v, bus_space_handle_t h, bus_size_t off)
926{
927#if CHIP_ACCESS_SIZE > 1
928	volatile CHIP_TYPE *ptr;
929#else	/* CHIP_ACCESS_SIZE > 1 */
930	volatile uint8_t *ptr;
931#endif	/* CHIP_ACCESS_SIZE > 1 */
932
933	ptr = (void *)(intptr_t)(h + CHIP_OFF8(off));
934	return *ptr & 0xff;
935}
936
937static uint16_t
938__BS(read_stream_2)(void *v, bus_space_handle_t h, bus_size_t off)
939{
940#if CHIP_ACCESS_SIZE > 2
941	volatile CHIP_TYPE *ptr;
942#else	/* CHIP_ACCESS_SIZE > 2 */
943	volatile uint16_t *ptr;
944#endif	/* CHIP_ACCESS_SIZE > 2 */
945
946	ptr = (void *)(intptr_t)(h + CHIP_OFF16(off));
947	return *ptr & 0xffff;
948}
949
950static uint32_t
951__BS(read_stream_4)(void *v, bus_space_handle_t h, bus_size_t off)
952{
953#if CHIP_ACCESS_SIZE > 4
954	volatile CHIP_TYPE *ptr;
955#else	/* CHIP_ACCESS_SIZE > 4 */
956	volatile uint32_t *ptr;
957#endif
958
959	ptr = (void *)(intptr_t)(h + CHIP_OFF32(off));
960	return *ptr & 0xffffffff;
961}
962
963static uint64_t
964__BS(read_stream_8)(void *v, bus_space_handle_t h, bus_size_t off)
965{
966	volatile uint64_t *ptr;
967
968	ptr = (void *)(intptr_t)(h + CHIP_OFF64(off));
969	return *ptr;
970}
971
972#define CHIP_read_multi_stream_N(BYTES,TYPE)				\
973static void									\
974__C(__BS(read_multi_stream_),BYTES)(void *v, bus_space_handle_t h,	\
975    bus_size_t o, TYPE *a, bus_size_t c)				\
976{									\
977									\
978	while (c-- > 0) {						\
979		__BS(barrier)(v, h, o, sizeof *a,			\
980		    BUS_SPACE_BARRIER_READ);				\
981		*a++ = __C(__BS(read_stream_),BYTES)(v, h, o);		\
982	}								\
983}
984CHIP_read_multi_stream_N(1,uint8_t)
985CHIP_read_multi_stream_N(2,uint16_t)
986CHIP_read_multi_stream_N(4,uint32_t)
987CHIP_read_multi_stream_N(8,uint64_t)
988
989#define CHIP_read_region_stream_N(BYTES,TYPE)				\
990static void									\
991__C(__BS(read_region_stream_),BYTES)(void *v, bus_space_handle_t h,	\
992    bus_size_t o, TYPE *a, bus_size_t c)				\
993{									\
994									\
995	while (c-- > 0) {						\
996		*a++ = __C(__BS(read_stream_),BYTES)(v, h, o);		\
997		o += sizeof *a;						\
998	}								\
999}
1000CHIP_read_region_stream_N(1,uint8_t)
1001CHIP_read_region_stream_N(2,uint16_t)
1002CHIP_read_region_stream_N(4,uint32_t)
1003CHIP_read_region_stream_N(8,uint64_t)
1004
1005static void
1006__BS(write_stream_1)(void *v, bus_space_handle_t h, bus_size_t off,
1007		     uint8_t val)
1008{
1009#if CHIP_ACCESS_SIZE > 1
1010	volatile CHIP_TYPE *ptr;
1011#else	/* CHIP_ACCESS_SIZE > 1 */
1012	volatile uint8_t *ptr;
1013#endif	/* CHIP_ACCESS_SIZE > 1 */
1014
1015	ptr = (void *)(intptr_t)(h + CHIP_OFF8(off));
1016	*ptr = val;
1017}
1018
1019static void
1020__BS(write_stream_2)(void *v, bus_space_handle_t h, bus_size_t off,
1021	      uint16_t val)
1022{
1023#if CHIP_ACCESS_SIZE > 2
1024	volatile CHIP_TYPE *ptr;
1025#else	/* CHIP_ACCESS_SIZE > 2 */
1026	volatile uint16_t *ptr;
1027#endif	/* CHIP_ACCESS_SIZE > 2 */
1028
1029	ptr = (void *)(intptr_t)(h + CHIP_OFF16(off));
1030	*ptr = val;
1031}
1032
1033static void
1034__BS(write_stream_4)(void *v, bus_space_handle_t h, bus_size_t off,
1035		     uint32_t val)
1036{
1037#if CHIP_ACCESS_SIZE > 4
1038	volatile CHIP_TYPE *ptr;
1039#else	/* CHIP_ACCESS_SIZE > 4 */
1040	volatile uint32_t *ptr;
1041#endif	/* CHIP_ACCESS_SIZE > 4 */
1042
1043	ptr = (void *)(intptr_t)(h + CHIP_OFF32(off));
1044	*ptr = val;
1045}
1046
1047static void
1048__BS(write_stream_8)(void *v, bus_space_handle_t h, bus_size_t off,
1049		     uint64_t val)
1050{
1051	volatile uint64_t *ptr;
1052
1053	ptr = (void *)(intptr_t)(h + CHIP_OFF64(off));
1054	*ptr = val;
1055}
1056
1057#define CHIP_write_multi_stream_N(BYTES,TYPE)				\
1058static void									\
1059__C(__BS(write_multi_stream_),BYTES)(void *v, bus_space_handle_t h,	\
1060    bus_size_t o, const TYPE *a, bus_size_t c)				\
1061{									\
1062									\
1063	while (c-- > 0) {						\
1064		__C(__BS(write_stream_),BYTES)(v, h, o, *a++);		\
1065		__BS(barrier)(v, h, o, sizeof *a,			\
1066		    BUS_SPACE_BARRIER_WRITE);				\
1067	}								\
1068}
1069CHIP_write_multi_stream_N(1,uint8_t)
1070CHIP_write_multi_stream_N(2,uint16_t)
1071CHIP_write_multi_stream_N(4,uint32_t)
1072CHIP_write_multi_stream_N(8,uint64_t)
1073
1074#define CHIP_write_region_stream_N(BYTES,TYPE)				\
1075static void									\
1076__C(__BS(write_region_stream_),BYTES)(void *v, bus_space_handle_t h,	\
1077    bus_size_t o, const TYPE *a, bus_size_t c)				\
1078{									\
1079									\
1080	while (c-- > 0) {						\
1081		__C(__BS(write_stream_),BYTES)(v, h, o, *a++);		\
1082		o += sizeof *a;						\
1083	}								\
1084}
1085CHIP_write_region_stream_N(1,uint8_t)
1086CHIP_write_region_stream_N(2,uint16_t)
1087CHIP_write_region_stream_N(4,uint32_t)
1088CHIP_write_region_stream_N(8,uint64_t)
1089
1090#endif	/* CHIP_NEED_STREAM */
1091
1092void
1093__BS(init)(bus_space_tag_t t, void *v)
1094{
1095#ifdef CHIP_EXTENT
1096	struct extent *ex;
1097#endif
1098
1099	/*
1100	 * Initialize the bus space tag.
1101	 */
1102
1103	/* cookie */
1104	t->bs_cookie =		v;
1105
1106	/* mapping/unmapping */
1107	t->bs_map =		__BS(map);
1108	t->bs_unmap =		__BS(unmap);
1109	t->bs_subregion =	__BS(subregion);
1110
1111	t->bs_translate =	__BS(translate);
1112	t->bs_get_window =	__BS(get_window);
1113
1114	/* allocation/deallocation */
1115	t->bs_alloc =		__BS(alloc);
1116	t->bs_free =		__BS(free);
1117
1118	/* get kernel virtual address */
1119	t->bs_vaddr =		__BS(vaddr);
1120
1121	/* mmap for user */
1122	t->bs_mmap =		__BS(mmap);
1123
1124	/* barrier */
1125	t->bs_barrier =		__BS(barrier);
1126
1127	/* read (single) */
1128	t->bs_r_1 =		__BS(read_1);
1129	t->bs_r_2 =		__BS(read_2);
1130	t->bs_r_4 =		__BS(read_4);
1131	t->bs_r_8 =		__BS(read_8);
1132
1133	/* read multiple */
1134	t->bs_rm_1 =		__BS(read_multi_1);
1135	t->bs_rm_2 =		__BS(read_multi_2);
1136	t->bs_rm_4 =		__BS(read_multi_4);
1137	t->bs_rm_8 =		__BS(read_multi_8);
1138
1139	/* read region */
1140	t->bs_rr_1 =		__BS(read_region_1);
1141	t->bs_rr_2 =		__BS(read_region_2);
1142	t->bs_rr_4 =		__BS(read_region_4);
1143	t->bs_rr_8 =		__BS(read_region_8);
1144
1145	/* write (single) */
1146	t->bs_w_1 =		__BS(write_1);
1147	t->bs_w_2 =		__BS(write_2);
1148	t->bs_w_4 =		__BS(write_4);
1149	t->bs_w_8 =		__BS(write_8);
1150
1151	/* write multiple */
1152	t->bs_wm_1 =		__BS(write_multi_1);
1153	t->bs_wm_2 =		__BS(write_multi_2);
1154	t->bs_wm_4 =		__BS(write_multi_4);
1155	t->bs_wm_8 =		__BS(write_multi_8);
1156
1157	/* write region */
1158	t->bs_wr_1 =		__BS(write_region_1);
1159	t->bs_wr_2 =		__BS(write_region_2);
1160	t->bs_wr_4 =		__BS(write_region_4);
1161	t->bs_wr_8 =		__BS(write_region_8);
1162
1163	/* set multiple */
1164	t->bs_sm_1 =		__BS(set_multi_1);
1165	t->bs_sm_2 =		__BS(set_multi_2);
1166	t->bs_sm_4 =		__BS(set_multi_4);
1167	t->bs_sm_8 =		__BS(set_multi_8);
1168
1169	/* set region */
1170	t->bs_sr_1 =		__BS(set_region_1);
1171	t->bs_sr_2 =		__BS(set_region_2);
1172	t->bs_sr_4 =		__BS(set_region_4);
1173	t->bs_sr_8 =		__BS(set_region_8);
1174
1175	/* copy */
1176	t->bs_c_1 =		__BS(copy_region_1);
1177	t->bs_c_2 =		__BS(copy_region_2);
1178	t->bs_c_4 =		__BS(copy_region_4);
1179	t->bs_c_8 =		__BS(copy_region_8);
1180
1181#ifdef CHIP_NEED_STREAM
1182	/* read (single), stream */
1183	t->bs_rs_1 =		__BS(read_stream_1);
1184	t->bs_rs_2 =		__BS(read_stream_2);
1185	t->bs_rs_4 =		__BS(read_stream_4);
1186	t->bs_rs_8 =		__BS(read_stream_8);
1187
1188	/* read multiple, stream */
1189	t->bs_rms_1 =		__BS(read_multi_stream_1);
1190	t->bs_rms_2 =		__BS(read_multi_stream_2);
1191	t->bs_rms_4 =		__BS(read_multi_stream_4);
1192	t->bs_rms_8 =		__BS(read_multi_stream_8);
1193
1194	/* read region, stream */
1195	t->bs_rrs_1 =		__BS(read_region_stream_1);
1196	t->bs_rrs_2 =		__BS(read_region_stream_2);
1197	t->bs_rrs_4 =		__BS(read_region_stream_4);
1198	t->bs_rrs_8 =		__BS(read_region_stream_8);
1199
1200	/* write (single), stream */
1201	t->bs_ws_1 =		__BS(write_stream_1);
1202	t->bs_ws_2 =		__BS(write_stream_2);
1203	t->bs_ws_4 =		__BS(write_stream_4);
1204	t->bs_ws_8 =		__BS(write_stream_8);
1205
1206	/* write multiple, stream */
1207	t->bs_wms_1 =		__BS(write_multi_stream_1);
1208	t->bs_wms_2 =		__BS(write_multi_stream_2);
1209	t->bs_wms_4 =		__BS(write_multi_stream_4);
1210	t->bs_wms_8 =		__BS(write_multi_stream_8);
1211
1212	/* write region, stream */
1213	t->bs_wrs_1 =		__BS(write_region_stream_1);
1214	t->bs_wrs_2 =		__BS(write_region_stream_2);
1215	t->bs_wrs_4 =		__BS(write_region_stream_4);
1216	t->bs_wrs_8 =		__BS(write_region_stream_8);
1217
1218#else	/* CHIP_NEED_STREAM */
1219
1220	/* read (single), stream */
1221	t->bs_rs_1 =		__BS(read_1);
1222	t->bs_rs_2 =		__BS(read_2);
1223	t->bs_rs_4 =		__BS(read_4);
1224	t->bs_rs_8 =		__BS(read_8);
1225
1226	/* read multiple, stream */
1227	t->bs_rms_1 =		__BS(read_multi_1);
1228	t->bs_rms_2 =		__BS(read_multi_2);
1229	t->bs_rms_4 =		__BS(read_multi_4);
1230	t->bs_rms_8 =		__BS(read_multi_8);
1231
1232	/* read region, stream */
1233	t->bs_rrs_1 =		__BS(read_region_1);
1234	t->bs_rrs_2 =		__BS(read_region_2);
1235	t->bs_rrs_4 =		__BS(read_region_4);
1236	t->bs_rrs_8 =		__BS(read_region_8);
1237
1238	/* write (single), stream */
1239	t->bs_ws_1 =		__BS(write_1);
1240	t->bs_ws_2 =		__BS(write_2);
1241	t->bs_ws_4 =		__BS(write_4);
1242	t->bs_ws_8 =		__BS(write_8);
1243
1244	/* write multiple, stream */
1245	t->bs_wms_1 =		__BS(write_multi_1);
1246	t->bs_wms_2 =		__BS(write_multi_2);
1247	t->bs_wms_4 =		__BS(write_multi_4);
1248	t->bs_wms_8 =		__BS(write_multi_8);
1249
1250	/* write region, stream */
1251	t->bs_wrs_1 =		__BS(write_region_1);
1252	t->bs_wrs_2 =		__BS(write_region_2);
1253	t->bs_wrs_4 =		__BS(write_region_4);
1254	t->bs_wrs_8 =		__BS(write_region_8);
1255#endif	/* CHIP_NEED_STREAM */
1256
1257#ifdef CHIP_EXTENT
1258	/* XXX WE WANT EXTENT_NOCOALESCE, BUT WE CAN'T USE IT. XXX */
1259	ex = extent_create(__S(__BS(bus)), 0x0UL, ~0UL,
1260	    (void *)CHIP_EX_STORE(v), CHIP_EX_STORE_SIZE(v), EX_NOWAIT);
1261	extent_alloc_region(ex, 0, ~0UL, EX_NOWAIT);
1262
1263#ifdef CHIP_W1_BUS_START
1264	/*
1265	 * The window may be disabled.  We notice this by seeing
1266	 * -1 as the bus base address.
1267	 */
1268	if (CHIP_W1_BUS_START(v) == (bus_addr_t) -1) {
1269#ifdef EXTENT_DEBUG
1270		printf("%s: this space is disabled\n", __S(__BS(init)));
1271#endif
1272		return;
1273	}
1274
1275#ifdef EXTENT_DEBUG
1276	printf("%s: freeing from %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n",
1277	    __S(__BS(init)), (bus_addr_t)CHIP_W1_BUS_START(v),
1278	    (bus_addr_t)CHIP_W1_BUS_END(v));
1279#endif
1280	extent_free(ex, CHIP_W1_BUS_START(v),
1281	    CHIP_W1_BUS_END(v) - CHIP_W1_BUS_START(v) + 1, EX_NOWAIT);
1282#endif
1283#ifdef CHIP_W2_BUS_START
1284	if (CHIP_W2_BUS_START(v) != CHIP_W1_BUS_START(v)) {
1285#ifdef EXTENT_DEBUG
1286		printf("xxx: freeing from 0x%lx to 0x%lx\n",
1287		    (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v));
1288#endif
1289		extent_free(ex, CHIP_W2_BUS_START(v),
1290		    CHIP_W2_BUS_END(v) - CHIP_W2_BUS_START(v) + 1, EX_NOWAIT);
1291	} else {
1292#ifdef EXTENT_DEBUG
1293		printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n",
1294		    (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v));
1295#endif
1296	}
1297#endif
1298#ifdef CHIP_W3_BUS_START
1299	if (CHIP_W3_BUS_START(v) != CHIP_W1_BUS_START(v) &&
1300	    CHIP_W3_BUS_START(v) != CHIP_W2_BUS_START(v)) {
1301#ifdef EXTENT_DEBUG
1302		printf("xxx: freeing from 0x%lx to 0x%lx\n",
1303		    (u_long)CHIP_W3_BUS_START(v), (u_long)CHIP_W3_BUS_END(v));
1304#endif
1305		extent_free(ex, CHIP_W3_BUS_START(v),
1306		    CHIP_W3_BUS_END(v) - CHIP_W3_BUS_START(v) + 1, EX_NOWAIT);
1307	} else {
1308#ifdef EXTENT_DEBUG
1309		printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n",
1310		    (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v));
1311#endif
1312	}
1313#endif
1314
1315#ifdef EXTENT_DEBUG
1316	extent_print(ex);
1317#endif
1318	CHIP_EXTENT(v) = ex;
1319#endif /* CHIP_EXTENT */
1320}
1321
1322