Home | History | Annotate | Line # | Download | only in vax
      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
     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