xref: /netbsd-src/sys/arch/sun3/sun3x/bus_subr.c (revision 3e6e9bd41e7ba487295ddb9874fe08472742ab1c)
1 /*	$NetBSD: bus_subr.c,v 1.33 2013/09/06 17:43:19 tsutsui Exp $	*/
2 
3 /*-
4  * Copyright (c) 1996 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Adam Glass and Gordon W. Ross.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * bus_xxx support functions, Sun3X-specific part.
34  * The common stuff is in autoconf.c
35  */
36 
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: bus_subr.c,v 1.33 2013/09/06 17:43:19 tsutsui Exp $");
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/device.h>
43 
44 #include <uvm/uvm_extern.h>
45 
46 #include <machine/autoconf.h>
47 #include <machine/cpu.h>
48 #include <machine/mon.h>
49 #include <machine/pmap.h>
50 #include <machine/pte.h>
51 
52 #include <sun3/sun3/machdep.h>
53 #include <sun3/sun3x/vme.h>
54 
55 label_t *nofault;
56 
57 /* These are defined in pmap.c */
58 extern vaddr_t tmp_vpages[];
59 extern int tmp_vpages_inuse;
60 
61 static const struct {
62 	long base;
63 	long mask;
64 } bus_info[BUS__NTYPES] = {
65 	{ /* OBIO  */ 0, ~0 },
66 	{ /* OBMEM */ 0, ~0 },
67 	/* VME A16 */
68 	{ VME16D16_BASE, VME16_MASK },
69 	{ VME16D32_BASE, VME16_MASK },
70 	/* VME A24 */
71 	{ VME24D16_BASE, VME24_MASK },
72 	{ VME24D32_BASE, VME24_MASK },
73 	/* VME A32 */
74 	{ VME32D16_BASE, VME32_MASK },
75 	{ VME32D32_BASE, VME32_MASK },
76 };
77 
78 /*
79  * Create a temporary, one-page mapping for a device.
80  * This is used by some device probe routines that
81  * need to do peek/write/read tricks.
82  */
83 void *
bus_tmapin(int bustype,int pa)84 bus_tmapin(int bustype, int pa)
85 {
86 	vaddr_t pgva;
87 	int off, s;
88 
89 	if ((bustype < 0) || (bustype >= BUS__NTYPES))
90 		panic("bus_tmapin: bustype");
91 
92 	off = pa & PGOFSET;
93 	pa -= off;
94 
95 	pa &= bus_info[bustype].mask;
96 	pa |= bus_info[bustype].base;
97 	pa |= PMAP_NC;
98 
99 	s = splvm();
100 	if (tmp_vpages_inuse)
101 		panic("bus_tmapin: tmp_vpages_inuse");
102 	tmp_vpages_inuse++;
103 
104 	pgva = tmp_vpages[1];
105 	pmap_kenter_pa(pgva, pa, VM_PROT_READ | VM_PROT_WRITE, 0);
106 	pmap_update(pmap_kernel());
107 	splx(s);
108 
109 	return ((void *)(pgva + off));
110 }
111 
112 void
bus_tmapout(void * vp)113 bus_tmapout(void *vp)
114 {
115 	vaddr_t pgva;
116 	int s;
117 
118 	pgva = m68k_trunc_page(vp);
119 	if (pgva != tmp_vpages[1])
120 		return;
121 
122 	s = splvm();
123 	pmap_kremove(pgva, PAGE_SIZE);
124 	pmap_update(pmap_kernel());
125 	--tmp_vpages_inuse;
126 	splx(s);
127 }
128 
129 /*
130  * Make a permanent mapping for a device.
131  */
132 void *
bus_mapin(int bustype,int pa,int sz)133 bus_mapin(int bustype, int pa, int sz)
134 {
135 	vaddr_t va;
136 	int off;
137 
138 	if ((bustype < 0) || (bustype >= BUS__NTYPES))
139 		panic("bus_mapin: bustype");
140 
141 	off = pa & PGOFSET;
142 	pa -= off;
143 	sz += off;
144 	sz = m68k_round_page(sz);
145 
146 	/* Borrow PROM mappings if we can. */
147 	if (bustype == BUS_OBIO) {
148 		if (find_prom_map(pa, PMAP_OBIO, sz, &va) == 0)
149 			goto done;
150 	}
151 
152 	pa &= bus_info[bustype].mask;
153 	pa |= bus_info[bustype].base;
154 	pa |= PMAP_NC;	/* non-cached */
155 
156 	/* Get some kernel virtual address space. */
157 	va = uvm_km_alloc(kernel_map, sz, 0, UVM_KMF_VAONLY | UVM_KMF_WAITVA);
158 	if (va == 0)
159 		panic("bus_mapin");
160 
161 	/* Map it to the specified bus. */
162 	pmap_map(va, pa, pa + sz, VM_PROT_ALL);
163 
164 done:
165 	return ((void*)(va + off));
166 }
167 
168 void
bus_mapout(void * ptr,int sz)169 bus_mapout(void *ptr, int sz)
170 {
171 	vaddr_t va;
172 	int off;
173 
174 	va = (vaddr_t)ptr;
175 
176 	/* If it was a PROM mapping, do NOT free it! */
177 	if ((va >= SUN3X_MONSTART) && (va < SUN3X_MONEND))
178 		return;
179 
180 	off = va & PGOFSET;
181 	va -= off;
182 	sz += off;
183 	sz = m68k_round_page(sz);
184 
185 	pmap_remove(pmap_kernel(), va, va + sz);
186 	pmap_update(pmap_kernel());
187 	uvm_km_free(kernel_map, va, sz, UVM_KMF_VAONLY);
188 }
189