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