xref: /netbsd-src/sys/arch/vax/vax/locore.c (revision 6a6027692662ba623e7bf5274322989a7b5d1440)
1 /*	$NetBSD: locore.c,v 1.84 2017/05/22 16:53:05 ragge Exp $	*/
2 /*
3  * Copyright (c) 1994, 1998 Ludd, University of Lule}, Sweden.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27  /* All bugs are subject to removal without further notice */
28 
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: locore.c,v 1.84 2017/05/22 16:53:05 ragge Exp $");
31 
32 #include "opt_compat_netbsd.h"
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/cpu.h>
37 #include <sys/device.h>
38 #include <sys/proc.h>
39 #include <sys/reboot.h>
40 
41 #include <uvm/uvm_extern.h>
42 
43 #include <machine/sid.h>
44 #include <machine/nexus.h>
45 #include <machine/rpb.h>
46 
47 #include "opt_cputype.h"
48 
49 void	_start(struct rpb *);
50 void	main(void);
51 
52 extern	paddr_t avail_end;
53 paddr_t esym;
54 
55 /*
56  * The strict CPU-dependent information is set up here, in
57  * form of a pointer to a struct that is specific for each CPU.
58  */
59 extern const struct cpu_dep ka780_calls;
60 extern const struct cpu_dep ka750_calls;
61 extern const struct cpu_dep ka730_calls;
62 extern const struct cpu_dep ka860_calls;
63 extern const struct cpu_dep ka820_calls;
64 extern const struct cpu_dep ka6400_calls;
65 extern const struct cpu_dep ka88_calls;
66 extern const struct cpu_dep ka43_calls;
67 extern const struct cpu_dep ka46_calls;
68 extern const struct cpu_dep ka48_calls;
69 extern const struct cpu_dep vxt_calls;
70 extern const struct cpu_dep ka49_calls;
71 extern const struct cpu_dep ka53_calls;
72 extern const struct cpu_dep ka410_calls;
73 extern const struct cpu_dep ka610_calls;
74 extern const struct cpu_dep ka630_calls;
75 extern const struct cpu_dep ka650_calls;
76 extern const struct cpu_dep ka660_calls;
77 extern const struct cpu_dep ka670_calls;
78 extern const struct cpu_dep ka680_calls;
79 
80 /*
81  * Start is called from boot; the first routine that is called
82  * in kernel. Kernel stack is setup somewhere in a safe place;
83  * but we need to move it to a better known place. Memory
84  * management is disabled, and no interrupt system is active.
85  */
86 void
_start(struct rpb * prpb)87 _start(struct rpb *prpb)
88 {
89 	extern uintptr_t scratch;
90 	struct pte *pt;
91 	vaddr_t uv;
92 	const char *mv;
93 #if VAX410 || VAXANY
94 	const char *md;
95 #endif
96 
97 	mtpr(AST_NO, PR_ASTLVL); /* Turn off ASTs */
98 
99 	findcpu(); /* Set up the CPU identifying variables */
100 
101 	if (vax_confdata & 0x80)
102 		mv = "MicroVAX";
103 	else
104 		mv = "VAXstation";
105 
106 	switch (vax_boardtype) {
107 #if VAX780 || VAXANY
108 	case VAX_BTYP_780:
109 		dep_call = &ka780_calls;
110 		cpu_setmodel("VAX 11/78%c", vax_cpudata & 0x100 ? '5' : '0');
111 		mv = NULL;
112 		break;
113 #endif
114 #if VAX750 || VAXANY
115 	case VAX_BTYP_750:
116 		dep_call = &ka750_calls;
117 		mv = "VAX 11/750";
118 		break;
119 #endif
120 #if VAX730 || VAXANY
121 	case VAX_BTYP_730:
122 		dep_call = &ka730_calls;
123 		mv = "VAX 11/730";
124 		break;
125 #endif
126 #if VAX8600 || VAXANY
127 	case VAX_BTYP_790:
128 		dep_call = &ka860_calls;
129 		cpu_setmodel("VAX 86%c0", vax_cpudata & 0x800000 ? '5' : '0');
130 		mv = NULL;
131 		break;
132 #endif
133 #if VAX410 || VAXANY
134 	case VAX_BTYP_420: /* They are very similar */
135 		dep_call = &ka410_calls;
136 		if (((vax_siedata >> 8) & 0xff) == 1)
137 			md = "/m{38,48}";
138 		else if (((vax_siedata >> 8) & 0xff) == 0)
139 			md = "/m{30,40}";
140 		else
141 			md = "";
142 		cpu_setmodel("%s 3100%s", mv, md);
143 		mv = NULL;
144 		break;
145 
146 	case VAX_BTYP_410:
147 		dep_call = &ka410_calls;
148 		cpu_setmodel("%s 2000", mv);
149 		mv = NULL;
150 		break;
151 #endif
152 #if VAX43 || VAXANY
153 	case VAX_BTYP_43:
154 		dep_call = &ka43_calls;
155 		cpu_setmodel("%s 3100/m76", mv);
156 		mv = NULL;
157 		break;
158 #endif
159 #if VAX46 || VAXANY
160 	case VAX_BTYP_46:
161 		dep_call = &ka46_calls;
162 		switch(vax_siedata & 0x3) {
163 		case 1: mv = "MicroVAX 3100/80"; break;
164 		case 2: mv = "VAXstation 4000/60"; break;
165 		default: mv = "unknown"; break;
166 		}
167 		break;
168 #endif
169 #if VAX48 || VAXANY
170 	case VAX_BTYP_48:
171 		dep_call = &ka48_calls;
172 		switch (vax_siedata & 3) {
173 		case 1: mv = "MicroVAX 3100/m{30,40}"; break;
174 		case 2: mv = "VAXstation 4000 VLC"; break;
175 		default: mv = "unknown SOC"; break;
176 		}
177 		break;
178 #endif
179 #if 0 && (VXT2000 || VAXANY)
180 	case VAX_BTYP_VXT:
181 		dep_call = &vxt_calls;
182 		mv = "VXT 2000 X terminal";
183 		break;
184 #endif
185 #if VAX49 || VAXANY
186 	case VAX_BTYP_49:
187 		dep_call = &ka49_calls;
188 		cpu_setmodel("%s 4000/{90,90A,96}", mv);
189 		mv = NULL;
190 		break;
191 #endif
192 #if VAX53 || VAXANY
193 	case VAX_BTYP_53:
194 		dep_call = &ka53_calls;
195 		switch((vax_siedata & 0xff00) >> 8) {
196 		case VAX_STYP_51:
197 			mv = "MicroVAX 3100/m{90,95}"; break;
198 		case VAX_STYP_52:
199 			mv = "VAX 4000/100"; break;
200 		case VAX_STYP_53:
201 			mv = "VAX 4000/{105A,106A,108}"; break;
202 		case VAX_STYP_55:
203 			mv = "MicroVAX 3100/m85"; break;
204 		default:
205 			mv = "unknown 1303"; break;
206 		}
207 		break;
208 #endif
209 #if VAX610 || VAXANY
210 	case VAX_BTYP_610:
211 		dep_call = &ka610_calls;
212 		mv = "MicroVAX I";
213 		break;
214 #endif
215 #if VAX630 || VAXANY
216 	case VAX_BTYP_630:
217 		dep_call = &ka630_calls;
218 		mv = "MicroVAX II";
219 		break;
220 #endif
221 #if VAX650 || VAXANY
222 	case VAX_BTYP_650:
223 		dep_call = &ka650_calls;
224 		switch ((vax_siedata >> 8) & 255) {
225 		case VAX_SIE_KA640:
226 			mv = "3300/3400";
227 			break;
228 
229 		case VAX_SIE_KA650:
230 			mv = "3500/3600";
231 			break;
232 
233 		case VAX_SIE_KA655:
234 			mv = "3800/3900";
235 			break;
236 
237 		default:
238 			mv = "III";
239 			break;
240 		}
241 		cpu_setmodel("MicroVAX %s", mv);
242 		mv = NULL;
243 		break;
244 #endif
245 #if VAX660 || VAXANY
246 	case VAX_BTYP_660:
247 		dep_call = &ka660_calls;
248 		mv = "VAX 4000/200";
249 		break;
250 #endif
251 #if VAX670 || VAXANY
252 	case VAX_BTYP_670:
253 		dep_call = &ka670_calls;
254 		mv = "VAX 4000/300";
255 		break;
256 #endif
257 #if VAX680 || VAXANY
258 	case VAX_BTYP_680:
259 		dep_call = &ka680_calls;
260 		switch((vax_siedata & 0xff00) >> 8) {
261 		case VAX_STYP_675:
262 			mv = "VAX 4000/400"; break;
263 		case VAX_STYP_680:
264 			mv = "VAX 4000/500"; break;
265 		default:
266 			mv = "unknown 1301";
267 		}
268 		break;
269 	case VAX_BTYP_681:
270 		dep_call = &ka680_calls;
271 		switch((vax_siedata & 0xff00) >> 8) {
272 		case VAX_STYP_681:
273 			mv = "VAX 4000/500A"; break;
274 		case VAX_STYP_691:
275 			mv = "VAX 4000/600A"; break;
276 		case VAX_STYP_694:
277 			cpu_setmodel("VAX 4000/70%cA",
278 			    vax_cpudata & 0x1000 ? '5' : '0');
279 			mv = NULL;
280 			break;
281 		default:
282 			mv = "unknown 1305";
283 		}
284 		break;
285 #endif
286 #if VAX8200 || VAXANY
287 	case VAX_BTYP_8000:
288 		dep_call = &ka820_calls;
289 		mv = "VAX 8200";
290 		break;
291 #endif
292 #if VAX8800 || VAXANY
293 	case VAX_BTYP_8PS:
294 	case VAX_BTYP_8800: /* Matches all other KA88-machines also */
295 		mv = "VAX 8800";
296 		dep_call = &ka88_calls;
297 		break;
298 #endif
299 #if VAX6400 || VAXANY
300 	case VAX_BTYP_9RR:
301 		/* XXX (a lie): cpu model is not set in steal_pages */
302 		dep_call = &ka6400_calls;
303 		break;
304 #endif
305 	default:
306 		/* CPU not supported, just give up */
307 		__asm("halt");
308 	}
309 
310 	if (mv != NULL)
311 		cpu_setmodel("%s", mv);
312 
313 	/*
314 	 * Machines older than MicroVAX II have their boot blocks
315 	 * loaded directly or the boot program loaded from console
316 	 * media, so we need to figure out their memory size.
317 	 * This is not easily done on MicroVAXen, so we get it from
318 	 * VMB instead.
319 	 *
320 	 * In post-1.4 a RPB is always provided from the boot blocks.
321 	 */
322 	uv = uvm_lwp_getuarea(&lwp0);
323 	uv += REDZONEADDR;
324 #if defined(COMPAT_14)
325 	if (prpb == 0) {
326 		memset((void *)uv, 0, sizeof(struct rpb));
327 		prpb = (struct rpb *)uv;
328 		prpb->pfncnt = avail_end >> VAX_PGSHIFT;
329 		prpb->rpb_base = (void *)-1;	/* RPB is fake */
330 	} else
331 #endif
332 	memcpy((void *)uv, prpb, sizeof(struct rpb));
333 	if (prpb->pfncnt)
334 		avail_end = prpb->pfncnt << VAX_PGSHIFT;
335 	else
336 		while (badaddr((void *)avail_end, 4) == 0)
337 			avail_end += VAX_NBPG * 128;
338 	boothowto = prpb->rpb_bootr5;
339 
340 	avail_end &= ~PGOFSET; /* be sure */
341 
342 	pmap_bootstrap();
343 
344 	/* Now running virtual. set red zone for proc0 */
345 	pt = kvtopte(uv);
346 	pt->pg_v = 0;
347 
348 	lwp0.l_md.md_utf = (void *)scratch;
349 
350 	/*
351 	 * Change mode down to userspace is done by faking a stack
352 	 * frame that is setup in cpu_set_kpc(). Not done by returning
353 	 * from main anymore.
354 	 */
355 	main();
356 	/* NOTREACHED */
357 }
358