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