1 /* $NetBSD: locore.c,v 1.63 2001/09/28 11:59:54 chs 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 u_int 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 ka49_calls; 78 extern struct cpu_dep ka53_calls; 79 extern struct cpu_dep ka410_calls; 80 extern struct cpu_dep ka610_calls; 81 extern struct cpu_dep ka630_calls; 82 extern struct cpu_dep ka650_calls; 83 extern struct cpu_dep ka660_calls; 84 extern struct cpu_dep ka670_calls; 85 extern struct cpu_dep ka680_calls; 86 87 /* 88 * Start is called from boot; the first routine that is called 89 * in kernel. Kernel stack is setup somewhere in a safe place; 90 * but we need to move it to a better known place. Memory 91 * management is disabled, and no interrupt system is active. 92 */ 93 void 94 _start(struct rpb *prpb) 95 { 96 extern void *scratch; 97 struct pte *pt; 98 99 mtpr(AST_NO, PR_ASTLVL); /* Turn off ASTs */ 100 101 findcpu(); /* Set up the CPU identifying variables */ 102 103 cpu_model[0] = 0; /* Be sure */ 104 if (vax_confdata & 0x80) 105 strcpy(cpu_model, "MicroVAX "); 106 else 107 strcpy(cpu_model, "VAXstation "); 108 109 switch (vax_boardtype) { 110 #if VAX780 || VAXANY 111 case VAX_BTYP_780: 112 dep_call = &ka780_calls; 113 strcpy(cpu_model,"VAX 11/780"); 114 if (vax_cpudata & 0x100) 115 cpu_model[9] = '5'; 116 break; 117 #endif 118 #if VAX750 || VAXANY 119 case VAX_BTYP_750: 120 dep_call = &ka750_calls; 121 strcpy(cpu_model, "VAX 11/750"); 122 break; 123 #endif 124 #if VAX8600 || VAXANY 125 case VAX_BTYP_790: 126 dep_call = &ka860_calls; 127 strcpy(cpu_model,"VAX 8600"); 128 if (vax_cpudata & 0x100) 129 cpu_model[6] = '5'; 130 break; 131 #endif 132 #if VAX410 || VAXANY 133 case VAX_BTYP_420: /* They are very similar */ 134 dep_call = &ka410_calls; 135 strcat(cpu_model, "3100"); 136 if (((vax_siedata >> 8) & 0xff) == 1) 137 strcat(cpu_model, "/m{38,48}"); 138 else if (((vax_siedata >> 8) & 0xff) == 0) 139 strcat(cpu_model, "/m{30,40}"); 140 break; 141 142 case VAX_BTYP_410: 143 dep_call = &ka410_calls; 144 strcat(cpu_model, "2000"); 145 break; 146 #endif 147 #if VAX43 || VAXANY 148 case VAX_BTYP_43: 149 dep_call = &ka43_calls; 150 strcat(cpu_model, "3100/m76"); 151 break; 152 #endif 153 #if VAX46 || VAXANY 154 case VAX_BTYP_46: 155 dep_call = &ka46_calls; 156 switch(vax_siedata & 0x3) { 157 case 1: strcpy(cpu_model, "MicroVAX 3100/80"); break; 158 case 2: strcpy(cpu_model, "VAXstation 4000/60"); break; 159 default: strcpy(cpu_model, "unknown"); break; 160 } 161 break; 162 #endif 163 #if VAX48 || VAXANY 164 case VAX_BTYP_48: 165 dep_call = &ka48_calls; 166 switch (vax_siedata & 3) { 167 case 1: strcpy(cpu_model, "MicroVAX 3100/m{30,40}"); break; 168 case 2: strcpy(cpu_model, "VAXstation 4000 VLC"); break; 169 default: strcpy(cpu_model, "unknown SOC"); break; 170 } 171 break; 172 #endif 173 #if VAX49 || VAXANY 174 case VAX_BTYP_49: 175 dep_call = &ka49_calls; 176 strcat(cpu_model, "4000/90"); 177 break; 178 #endif 179 #if VAX53 || VAXANY 180 case VAX_BTYP_53: 181 dep_call = &ka53_calls; 182 switch((vax_siedata & 0xff00) >> 8) { 183 case VAX_STYP_51: 184 strcpy(cpu_model, "MicroVAX 3100/m{90,95}"); break; 185 case VAX_STYP_52: 186 strcpy(cpu_model, "VAX 4000/100"); break; 187 case VAX_STYP_53: 188 strcpy(cpu_model, "VAX 4000/{105A,106A,108}"); break; 189 case VAX_STYP_55: 190 strcpy(cpu_model, "MicroVAX 3100/m85"); break; 191 default: 192 strcpy(cpu_model,"unknown 1303"); 193 } 194 break; 195 #endif 196 #if VAX610 || VAXANY 197 case VAX_BTYP_610: 198 dep_call = &ka610_calls; 199 strcpy(cpu_model,"MicroVAX I"); 200 break; 201 #endif 202 #if VAX630 || VAXANY 203 case VAX_BTYP_630: 204 dep_call = &ka630_calls; 205 strcpy(cpu_model,"MicroVAX II"); 206 break; 207 #endif 208 #if VAX650 || VAXANY 209 case VAX_BTYP_650: 210 dep_call = &ka650_calls; 211 strcpy(cpu_model,"MicroVAX "); 212 switch ((vax_siedata >> 8) & 255) { 213 case VAX_SIE_KA640: 214 strcat(cpu_model, "3300/3400"); 215 break; 216 217 case VAX_SIE_KA650: 218 strcat(cpu_model, "3500/3600"); 219 break; 220 221 case VAX_SIE_KA655: 222 strcat(cpu_model, "3800/3900"); 223 break; 224 225 default: 226 strcat(cpu_model, "III"); 227 break; 228 } 229 break; 230 #endif 231 #if VAX660 || VAXANY 232 case VAX_BTYP_660: 233 dep_call = &ka660_calls; 234 strcpy(cpu_model,"VAX 4000/200"); 235 break; 236 #endif 237 #if VAX670 || VAXANY 238 case VAX_BTYP_670: 239 dep_call = &ka670_calls; 240 strcpy(cpu_model,"VAX 4000/300"); 241 break; 242 #endif 243 #if VAX680 || VAXANY 244 case VAX_BTYP_680: 245 dep_call = &ka680_calls; 246 switch((vax_siedata & 0xff00) >> 8) { 247 case VAX_STYP_675: 248 strcpy(cpu_model,"VAX 4000/400"); break; 249 case VAX_STYP_680: 250 strcpy(cpu_model,"VAX 4000/500"); break; 251 default: 252 strcpy(cpu_model,"unknown 1301"); 253 } 254 break; 255 case VAX_BTYP_681: 256 dep_call = &ka680_calls; 257 switch((vax_siedata & 0xff00) >> 8) { 258 case VAX_STYP_681: 259 strcpy(cpu_model,"VAX 4000/500A"); break; 260 case VAX_STYP_691: 261 strcpy(cpu_model,"VAX 4000/600A"); break; 262 case VAX_STYP_694: 263 strcpy(cpu_model,"VAX 4000/705A"); break; 264 default: 265 strcpy(cpu_model,"unknown 1305"); 266 } 267 break; 268 #endif 269 #if VAX8200 || VAXANY 270 case VAX_BTYP_8000: 271 dep_call = &ka820_calls; 272 strcpy(cpu_model, "VAX 8200"); 273 break; 274 #endif 275 #if VAX8800 || VAXANY 276 case VAX_BTYP_8PS: 277 case VAX_BTYP_8800: /* Matches all other KA88-machines also */ 278 strcpy(cpu_model, "VAX 8800"); 279 dep_call = &ka88_calls; 280 break; 281 #endif 282 #if VAX6400 || VAXANY 283 case VAX_BTYP_9RR: 284 /* cpu_model set in steal_pages */ 285 dep_call = &ka6400_calls; 286 break; 287 #endif 288 default: 289 /* CPU not supported, just give up */ 290 asm("halt"); 291 } 292 293 /* 294 * Machines older than MicroVAX II have their boot blocks 295 * loaded directly or the boot program loaded from console 296 * media, so we need to figure out their memory size. 297 * This is not easily done on MicroVAXen, so we get it from 298 * VMB instead. 299 * 300 * In post-1.4 a RPB is always provided from the boot blocks. 301 */ 302 #if defined(COMPAT_14) 303 if (prpb == 0) { 304 bzero((caddr_t)proc0paddr + REDZONEADDR, sizeof(struct rpb)); 305 prpb = (struct rpb *)(proc0paddr + REDZONEADDR); 306 prpb->pfncnt = avail_end >> VAX_PGSHIFT; 307 prpb->rpb_base = (void *)-1; /* RPB is fake */ 308 } else 309 #endif 310 bcopy(prpb, (caddr_t)proc0paddr + REDZONEADDR, sizeof(struct rpb)); 311 if (prpb->pfncnt) 312 avail_end = prpb->pfncnt << VAX_PGSHIFT; 313 else 314 while (badaddr((caddr_t)avail_end, 4) == 0) 315 avail_end += VAX_NBPG * 128; 316 boothowto = prpb->rpb_bootr5; 317 318 avail_end &= ~PGOFSET; /* be sure */ 319 320 proc0.p_addr = (void *)proc0paddr; /* XXX */ 321 322 /* Clear the used parts of the uarea except for the pcb */ 323 bzero(&proc0.p_addr->u_stats, sizeof(struct user) - sizeof(struct pcb)); 324 325 pmap_bootstrap(); 326 327 /* Now running virtual. set red zone for proc0 */ 328 pt = kvtopte((u_int)proc0.p_addr + REDZONEADDR); 329 pt->pg_v = 0; 330 331 ((struct pcb *)proc0paddr)->framep = scratch; 332 333 /* 334 * Change mode down to userspace is done by faking a stack 335 * frame that is setup in cpu_set_kpc(). Not done by returning 336 * from main anymore. 337 */ 338 main(); 339 /* NOTREACHED */ 340 } 341