xref: /netbsd-src/sys/arch/sun3/sun3/autoconf.c (revision 76dfffe33547c37f8bdd446e3e4ab0f3c16cea4b)
1 /*	$NetBSD: autoconf.c,v 1.36 1996/10/13 03:47:45 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 1994 Gordon W. Ross
5  * Copyright (c) 1993 Adam Glass
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by Adam Glass.
19  * 4. The name of the authors may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35  * Setup the system to run on the current machine.
36  *
37  * Configure() is called at boot time.  Available
38  * devices are determined (from possibilities mentioned in ioconf.c),
39  * and the drivers are initialized.
40  */
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/device.h>
45 #include <sys/map.h>
46 #include <sys/buf.h>
47 #include <sys/dkstat.h>
48 #include <sys/conf.h>
49 #include <sys/dmap.h>
50 #include <sys/reboot.h>
51 
52 #include <vm/vm.h>
53 #include <vm/vm_kern.h>
54 #include <vm/vm_map.h>
55 
56 #include <machine/autoconf.h>
57 #include <machine/cpu.h>
58 #include <machine/isr.h>
59 #include <machine/pte.h>
60 #include <machine/pmap.h>
61 
62 extern int soft1intr();
63 
64 void swapgeneric();
65 void swapconf(), dumpconf();
66 
67 int cold;
68 
69 void configure()
70 {
71 	struct device *mainbus;
72 
73 	/* General device autoconfiguration. */
74 	mainbus = config_rootfound("mainbus", NULL);
75 	if (mainbus == NULL)
76 		panic("configure: mainbus not found");
77 
78 	/* Choose root and swap devices. */
79 	swapgeneric();
80 	swapconf();
81 	dumpconf();
82 	cold = 0;
83 }
84 
85 /*
86  * Configure swap space and related parameters.
87  */
88 void
89 swapconf()
90 {
91 	struct swdevt *swp;
92 	u_int maj;
93 	int nblks;
94 
95 	for (swp = swdevt; swp->sw_dev != NODEV; swp++) {
96 
97 		maj = major(swp->sw_dev);
98 		if (maj > nblkdev) /* paranoid? */
99 			break;
100 
101 		if (bdevsw[maj].d_psize) {
102 			nblks = (*bdevsw[maj].d_psize)(swp->sw_dev);
103 			if (nblks > 0 &&
104 				(swp->sw_nblks == 0 || swp->sw_nblks > nblks))
105 				swp->sw_nblks = nblks;
106 			swp->sw_nblks = ctod(dtoc(swp->sw_nblks));
107 		}
108 	}
109 }
110 
111 /*
112  * Generic "bus" support functions.
113  *
114  * bus_scan:
115  * This function is passed to config_search() by the attach function
116  * for each of the "bus" drivers (obctl, obio, obmem, vmes, vmel).
117  * The purpose of this function is to copy the "locators" into our
118  * confargs structure, so child drivers may use the confargs both
119  * as match parameters and as temporary storage for the defaulted
120  * locator values determined in the child_match and preserved for
121  * the child_attach function.  If the bus attach functions just
122  * used config_found, then we would not have an opportunity to
123  * setup the confargs for each child match and attach call.
124  *
125  * bus_print:
126  * Just prints out the final (non-default) locators.
127  */
128 int bus_scan(parent, child, aux)
129 	struct device *parent;
130 	void *child, *aux;
131 {
132 	struct cfdata *cf = child;
133 	struct confargs *ca = aux;
134 	cfmatch_t mf;
135 
136 #ifdef	DIAGNOSTIC
137 	if (parent->dv_cfdata->cf_driver->cd_indirect)
138 		panic("bus_scan: indirect?");
139 	if (cf->cf_fstate == FSTATE_STAR)
140 		panic("bus_scan: FSTATE_STAR");
141 #endif
142 
143 	/* ca->ca_bustype set by parent */
144 	ca->ca_paddr  = cf->cf_loc[0];
145 	ca->ca_intpri = cf->cf_loc[1];
146 	ca->ca_intvec = -1;
147 
148 	if ((ca->ca_bustype == BUS_VME16) ||
149 		(ca->ca_bustype == BUS_VME32))
150 	{
151 		ca->ca_intvec = cf->cf_loc[2];
152 	}
153 
154 	/*
155 	 * Note that this allows the match function to save
156 	 * defaulted locators in the confargs that will be
157 	 * preserved for the related attach call.
158 	 */
159 	mf = cf->cf_attach->ca_match;
160 	if ((*mf)(parent, cf, ca) > 0) {
161 		config_attach(parent, cf, ca, bus_print);
162 	}
163 	return (0);
164 }
165 
166 /*
167  * Print out the confargs.  The parent name is non-NULL
168  * when there was no match found by config_found().
169  */
170 int
171 bus_print(args, name)
172 	void *args;
173 	const char *name;
174 {
175 	struct confargs *ca = args;
176 
177 	if (name)
178 		printf("%s:", name);
179 
180 	if (ca->ca_paddr != -1)
181 		printf(" addr 0x%x", ca->ca_paddr);
182 	if (ca->ca_intpri != -1)
183 		printf(" level %d", ca->ca_intpri);
184 	if (ca->ca_intvec != -1)
185 		printf(" vector 0x%x", ca->ca_intvec);
186 
187 	return(UNCONF);
188 }
189 
190 extern vm_offset_t tmp_vpages[];
191 static const int bustype_to_ptetype[4] = {
192 	PGT_OBMEM,
193 	PGT_OBIO,
194 	PGT_VME_D16,
195 	PGT_VME_D32,
196 };
197 
198 /*
199  * Read addr with size len (1,2,4) into val.
200  * If this generates a bus error, return -1
201  *
202  *	Create a temporary mapping,
203  *	Try the access using peek_*
204  *	Clean up temp. mapping
205  */
206 int bus_peek(bustype, paddr, sz)
207 	int bustype, paddr, sz;
208 {
209 	int off, pte, rv;
210 	vm_offset_t pgva;
211 	caddr_t va;
212 
213 	if (bustype & ~3)
214 		return -1;
215 
216 	off = paddr & PGOFSET;
217 	paddr -= off;
218 	pte = PA_PGNUM(paddr);
219 	pte |= bustype_to_ptetype[bustype];
220 	pte |= (PG_VALID | PG_WRITE | PG_SYSTEM | PG_NC);
221 
222 	pgva = tmp_vpages[0];
223 	va = (caddr_t)pgva + off;
224 
225 	/* All mappings in tmp_vpages are non-cached, so no flush. */
226 	set_pte(pgva, pte);
227 
228 	/*
229 	 * OK, try the access using one of the assembly routines
230 	 * that will set pcb_onfault and catch any bus errors.
231 	 */
232 	switch (sz) {
233 	case 1:
234 		rv = peek_byte(va);
235 		break;
236 	case 2:
237 		rv = peek_word(va);
238 		break;
239 	default:
240 		printf(" bus_peek: invalid size=%d\n", sz);
241 		rv = -1;
242 	}
243 
244 	/* All mappings in tmp_vpages are non-cached, so no flush. */
245 	set_pte(pgva, PG_INVAL);
246 
247 	return rv;
248 }
249 
250 static const int bustype_to_pmaptype[4] = {
251 	0,
252 	PMAP_OBIO,
253 	PMAP_VME16,
254 	PMAP_VME32,
255 };
256 
257 char *
258 bus_mapin(bustype, paddr, sz)
259 	int bustype, paddr, sz;
260 {
261 	int off, pa, pgs, pmt;
262 	vm_offset_t va, retval;
263 
264 	if (bustype & ~3)
265 		return (NULL);
266 
267 	off = paddr & PGOFSET;
268 	pa = paddr - off;
269 	sz += off;
270 	sz = sun3_round_page(sz);
271 
272 	pmt = bustype_to_pmaptype[bustype];
273 	pmt |= PMAP_NC;	/* non-cached */
274 
275 	/* Get some kernel virtual address space. */
276 	va = kmem_alloc_wait(kernel_map, sz);
277 	if (va == 0)
278 		panic("bus_mapin");
279 	retval = va + off;
280 
281 	/* Map it to the specified bus. */
282 #if 0	/* XXX */
283 	/* This has a problem with wrap-around... */
284 	pmap_map((int)va, pa | pmt, pa + sz, VM_PROT_ALL);
285 #else
286 	do {
287 		pmap_enter(pmap_kernel(), va, pa | pmt, VM_PROT_ALL, FALSE);
288 		va += NBPG;
289 		pa += NBPG;
290 	} while ((sz -= NBPG) > 0);
291 #endif
292 
293 	return ((char*)retval);
294 }
295