xref: /netbsd-src/sys/arch/sun3/sun3/autoconf.c (revision ce0bb6e8d2e560ecacbe865a848624f94498063b)
1 /*	$NetBSD: autoconf.c,v 1.24 1995/04/10 05:44:08 mycroft 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 mainbusattach __P((struct device *, struct device *, void *));
65 void swapgeneric();
66 void swapconf(), dumpconf();
67 
68 
69 struct mainbus_softc {
70 	struct device mainbus_dev;
71 };
72 
73 struct cfdriver mainbuscd =
74 { NULL, "mainbus", always_match, mainbusattach, DV_DULL,
75 	sizeof(struct mainbus_softc), 0};
76 
77 void mainbusattach(parent, self, args)
78 	struct device *parent;
79 	struct device *self;
80 	void *args;
81 {
82 	struct cfdata *new_match;
83 
84 	printf("\n");
85 	while (1) {
86 		new_match = config_search(NULL, self, NULL);
87 		if (!new_match) break;
88 		config_attach(self, new_match, NULL, NULL);
89 	}
90 }
91 
92 int nmi_intr(arg)
93 	int arg;
94 {
95 	printf("nmi interrupt received\n");
96 	return 1;
97 }
98 
99 void configure()
100 {
101 	int root_found;
102 
103 	/* General device autoconfiguration. */
104 	root_found = config_rootfound("mainbus", NULL);
105 	if (!root_found)
106 		panic("configure: mainbus not found");
107 
108 	/* Install non-device interrupt handlers. */
109 	isr_add_autovect(nmi_intr, 0, 7);
110 	isr_add_autovect(soft1intr, 0, 1);
111 
112 #ifdef	GENERIC
113 	/* Choose root and swap devices. */
114 	swapgeneric();
115 #endif
116 	swapconf();
117 	dumpconf();
118 }
119 
120 /*
121  * Configure swap space and related parameters.
122  */
123 void
124 swapconf()
125 {
126 	struct swdevt *swp;
127 	u_int maj;
128 	int nblks;
129 
130 	for (swp = swdevt; swp->sw_dev != NODEV; swp++) {
131 		maj = major(swp->sw_dev);
132 
133 		if (maj > nblkdev) /* paranoid? */
134 			break;
135 
136 		if (bdevsw[maj].d_psize) {
137 			nblks = (*bdevsw[maj].d_psize)(swp->sw_dev);
138 			if (nblks > 0 &&
139 				(swp->sw_nblks == 0 || swp->sw_nblks > nblks))
140 				swp->sw_nblks = nblks;
141 			swp->sw_nblks = ctod(dtoc(swp->sw_nblks));
142 		}
143 	}
144 }
145 
146 int always_match(parent, cf, args)
147 	struct device *parent;
148 	void *cf;
149 	void *args;
150 {
151 	return 1;
152 }
153 
154 /*
155  * Generic "bus" support functions.
156  */
157 void bus_scan(parent, child, bustype)
158 	struct device *parent;
159 	void *child;
160 	int bustype;
161 {
162 	struct cfdata *cf = child;
163 	struct confargs ca;
164 	cfmatch_t match;
165 
166 #ifdef	DIAGNOSTIC
167 	if (parent->dv_cfdata->cf_driver->cd_indirect)
168 		panic("bus_scan: indirect?");
169 	if (cf->cf_fstate == FSTATE_STAR)
170 		panic("bus_scan: FSTATE_STAR");
171 #endif
172 
173 	ca.ca_bustype = bustype;
174 	ca.ca_paddr  = cf->cf_loc[0];
175 	ca.ca_intpri = cf->cf_loc[1];
176 
177 	if ((bustype == BUS_VME16) || (bustype == BUS_VME32)) {
178 		ca.ca_intvec = cf->cf_loc[2];
179 	} else {
180 		ca.ca_intvec = -1;
181 	}
182 
183 	match = cf->cf_driver->cd_match;
184 	if ((*match)(parent, cf, &ca) > 0) {
185 		config_attach(parent, cf, &ca, bus_print);
186 	}
187 }
188 
189 int
190 bus_print(args, name)
191 	void *args;
192 	char *name;
193 {
194 	struct confargs *ca = args;
195 
196 	if (ca->ca_paddr != -1)
197 		printf(" addr 0x%x", ca->ca_paddr);
198 	if (ca->ca_intpri != -1)
199 		printf(" level %d", ca->ca_intpri);
200 	if (ca->ca_intvec != -1)
201 		printf(" vector 0x%x", ca->ca_intvec);
202 	/* XXXX print flags? */
203 	return(QUIET);
204 }
205 
206 extern vm_offset_t tmp_vpages[];
207 static const int bustype_to_ptetype[4] = {
208 	PGT_OBMEM,
209 	PGT_OBIO,
210 	PGT_VME_D16,
211 	PGT_VME_D32,
212 };
213 
214 /*
215  * Read addr with size len (1,2,4) into val.
216  * If this generates a bus error, return -1
217  *
218  *	Create a temporary mapping,
219  *	Try the access using peek_*
220  *	Clean up temp. mapping
221  */
222 int bus_peek(bustype, paddr, sz)
223 	int bustype, paddr, sz;
224 {
225 	int off, pte, rv;
226 	vm_offset_t pgva;
227 	caddr_t va;
228 
229 	if (bustype & ~3)
230 		return -1;
231 
232 	off = paddr & PGOFSET;
233 	paddr -= off;
234 	pte = PA_PGNUM(paddr);
235 	pte |= bustype_to_ptetype[bustype];
236 	pte |= (PG_VALID | PG_WRITE | PG_SYSTEM | PG_NC);
237 
238 	pgva = tmp_vpages[0];
239 	va = (caddr_t)pgva + off;
240 
241 	set_pte(pgva, pte);
242 
243 	/*
244 	 * OK, try the access using one of the assembly routines
245 	 * that will set pcb_onfault and catch any bus errors.
246 	 */
247 	switch (sz) {
248 	case 1:
249 		rv = peek_byte(va);
250 		break;
251 	case 2:
252 		rv = peek_word(va);
253 		break;
254 	default:
255 		printf(" bus_peek: invalid size=%d\n", sz);
256 		rv = -1;
257 	}
258 
259 	set_pte(pgva, PG_INVAL);
260 
261 	return rv;
262 }
263 
264 static const int bustype_to_pmaptype[4] = {
265 	0,
266 	PMAP_OBIO,
267 	PMAP_VME16,
268 	PMAP_VME32,
269 };
270 
271 extern caddr_t dvma_vm_alloc();
272 
273 char *
274 bus_mapin(bustype, paddr, sz)
275 	int bustype, paddr, sz;
276 {
277 	int off, pa, pgs, pmt;
278 	caddr_t va;
279 
280 	if (bustype & ~3)
281 		return (NULL);
282 
283 	off = paddr & PGOFSET;
284 	pa = paddr - off;
285 	sz += off;
286 	sz = sun3_round_page(sz);
287 
288 	pmt = bustype_to_pmaptype[bustype];
289 	pmt |= PMAP_NC;	/* non-cached */
290 
291 	/* Get some DVMA space. */
292 	va = dvma_vm_alloc(sz);
293 	if (va == NULL)
294 		panic("bus_mapin");
295 
296 	/* Map it to the specified bus. */
297 	pmap_map((int)va, pa | pmt, pa + sz, VM_PROT_ALL);
298 
299 	return (va + off);
300 }
301