xref: /netbsd-src/sys/arch/sun3/sun3x/bus_subr.c (revision 3e6e9bd41e7ba487295ddb9874fe08472742ab1c)
1*3e6e9bd4Stsutsui /*	$NetBSD: bus_subr.c,v 1.33 2013/09/06 17:43:19 tsutsui Exp $	*/
2201c1f17Sgwr 
3201c1f17Sgwr /*-
4201c1f17Sgwr  * Copyright (c) 1996 The NetBSD Foundation, Inc.
5201c1f17Sgwr  * All rights reserved.
6201c1f17Sgwr  *
7201c1f17Sgwr  * This code is derived from software contributed to The NetBSD Foundation
8201c1f17Sgwr  * by Adam Glass and Gordon W. Ross.
9201c1f17Sgwr  *
10201c1f17Sgwr  * Redistribution and use in source and binary forms, with or without
11201c1f17Sgwr  * modification, are permitted provided that the following conditions
12201c1f17Sgwr  * are met:
13201c1f17Sgwr  * 1. Redistributions of source code must retain the above copyright
14201c1f17Sgwr  *    notice, this list of conditions and the following disclaimer.
15201c1f17Sgwr  * 2. Redistributions in binary form must reproduce the above copyright
16201c1f17Sgwr  *    notice, this list of conditions and the following disclaimer in the
17201c1f17Sgwr  *    documentation and/or other materials provided with the distribution.
18201c1f17Sgwr  *
19201c1f17Sgwr  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20201c1f17Sgwr  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21201c1f17Sgwr  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22201c1f17Sgwr  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23201c1f17Sgwr  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24201c1f17Sgwr  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25201c1f17Sgwr  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26201c1f17Sgwr  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27201c1f17Sgwr  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28201c1f17Sgwr  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29201c1f17Sgwr  * POSSIBILITY OF SUCH DAMAGE.
30201c1f17Sgwr  */
31201c1f17Sgwr 
32201c1f17Sgwr /*
335193e1e3Sgwr  * bus_xxx support functions, Sun3X-specific part.
345193e1e3Sgwr  * The common stuff is in autoconf.c
35201c1f17Sgwr  */
36201c1f17Sgwr 
37ed517291Slukem #include <sys/cdefs.h>
38*3e6e9bd4Stsutsui __KERNEL_RCSID(0, "$NetBSD: bus_subr.c,v 1.33 2013/09/06 17:43:19 tsutsui Exp $");
39ed517291Slukem 
40201c1f17Sgwr #include <sys/param.h>
41201c1f17Sgwr #include <sys/systm.h>
42201c1f17Sgwr #include <sys/device.h>
43201c1f17Sgwr 
441b01ec09Sgwr #include <uvm/uvm_extern.h>
451b01ec09Sgwr 
46201c1f17Sgwr #include <machine/autoconf.h>
47201c1f17Sgwr #include <machine/cpu.h>
48201c1f17Sgwr #include <machine/mon.h>
49eff2e270Sgwr #include <machine/pmap.h>
50eff2e270Sgwr #include <machine/pte.h>
51eff2e270Sgwr 
52eff2e270Sgwr #include <sun3/sun3/machdep.h>
53eff2e270Sgwr #include <sun3/sun3x/vme.h>
54201c1f17Sgwr 
55201c1f17Sgwr label_t *nofault;
56201c1f17Sgwr 
573f6f86d8Sjeremy /* These are defined in pmap.c */
58573961b5Stsutsui extern vaddr_t tmp_vpages[];
593f6f86d8Sjeremy extern int tmp_vpages_inuse;
60201c1f17Sgwr 
61eff2e270Sgwr static const struct {
62eff2e270Sgwr 	long base;
63eff2e270Sgwr 	long mask;
64eff2e270Sgwr } bus_info[BUS__NTYPES] = {
65eff2e270Sgwr 	{ /* OBIO  */ 0, ~0 },
66eff2e270Sgwr 	{ /* OBMEM */ 0, ~0 },
67eff2e270Sgwr 	/* VME A16 */
68eff2e270Sgwr 	{ VME16D16_BASE, VME16_MASK },
69eff2e270Sgwr 	{ VME16D32_BASE, VME16_MASK },
70eff2e270Sgwr 	/* VME A24 */
71eff2e270Sgwr 	{ VME24D16_BASE, VME24_MASK },
72eff2e270Sgwr 	{ VME24D32_BASE, VME24_MASK },
73eff2e270Sgwr 	/* VME A32 */
74eff2e270Sgwr 	{ VME32D16_BASE, VME32_MASK },
75eff2e270Sgwr 	{ VME32D32_BASE, VME32_MASK },
76eff2e270Sgwr };
77201c1f17Sgwr 
78201c1f17Sgwr /*
795193e1e3Sgwr  * Create a temporary, one-page mapping for a device.
805193e1e3Sgwr  * This is used by some device probe routines that
815193e1e3Sgwr  * need to do peek/write/read tricks.
82201c1f17Sgwr  */
835193e1e3Sgwr void *
bus_tmapin(int bustype,int pa)8410b1a7beSchs bus_tmapin(int bustype, int pa)
85201c1f17Sgwr {
86573961b5Stsutsui 	vaddr_t pgva;
87d74e1744Sgwr 	int off, s;
88201c1f17Sgwr 
89eff2e270Sgwr 	if ((bustype < 0) || (bustype >= BUS__NTYPES))
905193e1e3Sgwr 		panic("bus_tmapin: bustype");
91eff2e270Sgwr 
92a5b83941Sgwr 	off = pa & PGOFSET;
93a5b83941Sgwr 	pa -= off;
945193e1e3Sgwr 
955193e1e3Sgwr 	pa &= bus_info[bustype].mask;
965193e1e3Sgwr 	pa |= bus_info[bustype].base;
97a5b83941Sgwr 	pa |= PMAP_NC;
98201c1f17Sgwr 
99a3ec356dSthorpej 	s = splvm();
1003f6f86d8Sjeremy 	if (tmp_vpages_inuse)
1015193e1e3Sgwr 		panic("bus_tmapin: tmp_vpages_inuse");
1023f6f86d8Sjeremy 	tmp_vpages_inuse++;
103b53e0d4fSjeremy 
104a5b83941Sgwr 	pgva = tmp_vpages[1];
1059480c51bScegger 	pmap_kenter_pa(pgva, pa, VM_PROT_READ | VM_PROT_WRITE, 0);
1060e7661f0Schris 	pmap_update(pmap_kernel());
1075193e1e3Sgwr 	splx(s);
108201c1f17Sgwr 
1095193e1e3Sgwr 	return ((void *)(pgva + off));
110201c1f17Sgwr }
111201c1f17Sgwr 
11210b1a7beSchs void
bus_tmapout(void * vp)11310b1a7beSchs bus_tmapout(void *vp)
1145193e1e3Sgwr {
115573961b5Stsutsui 	vaddr_t pgva;
1165193e1e3Sgwr 	int s;
1175193e1e3Sgwr 
1185193e1e3Sgwr 	pgva = m68k_trunc_page(vp);
1195193e1e3Sgwr 	if (pgva != tmp_vpages[1])
1205193e1e3Sgwr 		return;
1215193e1e3Sgwr 
122a3ec356dSthorpej 	s = splvm();
1233b9d5835Sthorpej 	pmap_kremove(pgva, PAGE_SIZE);
1240e7661f0Schris 	pmap_update(pmap_kernel());
1253f6f86d8Sjeremy 	--tmp_vpages_inuse;
126b53e0d4fSjeremy 	splx(s);
127201c1f17Sgwr }
128201c1f17Sgwr 
1295193e1e3Sgwr /*
1305193e1e3Sgwr  * Make a permanent mapping for a device.
1315193e1e3Sgwr  */
132201c1f17Sgwr void *
bus_mapin(int bustype,int pa,int sz)13310b1a7beSchs bus_mapin(int bustype, int pa, int sz)
134201c1f17Sgwr {
135573961b5Stsutsui 	vaddr_t va;
136a5b83941Sgwr 	int off;
137201c1f17Sgwr 
138eff2e270Sgwr 	if ((bustype < 0) || (bustype >= BUS__NTYPES))
139a5b83941Sgwr 		panic("bus_mapin: bustype");
140201c1f17Sgwr 
141a5b83941Sgwr 	off = pa & PGOFSET;
142a5b83941Sgwr 	pa -= off;
143201c1f17Sgwr 	sz += off;
144a5b83941Sgwr 	sz = m68k_round_page(sz);
145201c1f17Sgwr 
1465193e1e3Sgwr 	/* Borrow PROM mappings if we can. */
1475193e1e3Sgwr 	if (bustype == BUS_OBIO) {
148c207dcd8Stsutsui 		if (find_prom_map(pa, PMAP_OBIO, sz, &va) == 0)
1495193e1e3Sgwr 			goto done;
1505193e1e3Sgwr 	}
1515193e1e3Sgwr 
1525193e1e3Sgwr 	pa &= bus_info[bustype].mask;
1535193e1e3Sgwr 	pa |= bus_info[bustype].base;
154a5b83941Sgwr 	pa |= PMAP_NC;	/* non-cached */
155201c1f17Sgwr 
156201c1f17Sgwr 	/* Get some kernel virtual address space. */
1576b2d8b66Syamt 	va = uvm_km_alloc(kernel_map, sz, 0, UVM_KMF_VAONLY | UVM_KMF_WAITVA);
158201c1f17Sgwr 	if (va == 0)
159201c1f17Sgwr 		panic("bus_mapin");
160201c1f17Sgwr 
161201c1f17Sgwr 	/* Map it to the specified bus. */
1625193e1e3Sgwr 	pmap_map(va, pa, pa + sz, VM_PROT_ALL);
163201c1f17Sgwr 
1645193e1e3Sgwr done:
1655193e1e3Sgwr 	return ((void*)(va + off));
166201c1f17Sgwr }
167201c1f17Sgwr 
1685193e1e3Sgwr void
bus_mapout(void * ptr,int sz)16910b1a7beSchs bus_mapout(void *ptr, int sz)
170eb841680Sgwr {
171573961b5Stsutsui 	vaddr_t va;
1725193e1e3Sgwr 	int off;
173eb841680Sgwr 
174573961b5Stsutsui 	va = (vaddr_t)ptr;
175eff2e270Sgwr 
1765193e1e3Sgwr 	/* If it was a PROM mapping, do NOT free it! */
1775193e1e3Sgwr 	if ((va >= SUN3X_MONSTART) && (va < SUN3X_MONEND))
1785193e1e3Sgwr 		return;
179eb841680Sgwr 
1805193e1e3Sgwr 	off = va & PGOFSET;
1815193e1e3Sgwr 	va -= off;
1825193e1e3Sgwr 	sz += off;
1835193e1e3Sgwr 	sz = m68k_round_page(sz);
184201c1f17Sgwr 
1858e1de5f3Stsutsui 	pmap_remove(pmap_kernel(), va, va + sz);
1868e1de5f3Stsutsui 	pmap_update(pmap_kernel());
1876b2d8b66Syamt 	uvm_km_free(kernel_map, va, sz, UVM_KMF_VAONLY);
188201c1f17Sgwr }
189