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