1 #include "u.h" 2 #include "../port/lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 #include "io.h" 7 #include "ureg.h" 8 #include "version.h" 9 10 /* where b.com or qboot leaves configuration info */ 11 #define BOOTARGS ((char*)CONFADDR) 12 #define BOOTARGSLEN 1024 13 #define MAXCONF 32 14 15 extern ulong kerndate; 16 extern int cflag; 17 int remotedebug; 18 19 extern int main_pool_pcnt; 20 extern int heap_pool_pcnt; 21 extern int image_pool_pcnt; 22 23 char bootargs[BOOTARGSLEN+1]; 24 char bootdisk[KNAMELEN]; 25 char *confname[MAXCONF]; 26 char *confval[MAXCONF]; 27 int nconf; 28 29 extern void addconf(char *, char *); 30 31 /* 32 * arguments passed to initcode and /boot 33 */ 34 char argbuf[128]; 35 36 static void 37 options(void) 38 { 39 long i, n; 40 char *cp, *line[MAXCONF], *p, *q; 41 42 /* 43 * parse configuration args from bootstrap 44 */ 45 memmove(bootargs, BOOTARGS, BOOTARGSLEN); /* where b.com leaves its config */ 46 cp = bootargs; 47 cp[BOOTARGSLEN-1] = 0; 48 49 /* 50 * Strip out '\r', change '\t' -> ' '. 51 */ 52 p = cp; 53 for(q = cp; *q; q++){ 54 if(*q == '\r') 55 continue; 56 if(*q == '\t') 57 *q = ' '; 58 *p++ = *q; 59 } 60 *p = 0; 61 62 n = getfields(cp, line, MAXCONF, 1, "\n"); 63 for(i = 0; i < n; i++){ 64 if(*line[i] == '#') 65 continue; 66 cp = strchr(line[i], '='); 67 if(cp == 0) 68 continue; 69 *cp++ = 0; 70 confname[nconf] = line[i]; 71 confval[nconf] = cp; 72 nconf++; 73 } 74 } 75 76 void 77 doc(char *m) 78 { 79 USED(m); 80 print("%s...\n", m); uartwait(); 81 } 82 83 static void 84 poolsizeinit(void) 85 { 86 ulong nb; 87 88 nb = conf.npage*BY2PG; 89 poolsize(mainmem, (nb*main_pool_pcnt)/100, 0); 90 poolsize(heapmem, (nb*heap_pool_pcnt)/100, 0); 91 poolsize(imagmem, (nb*image_pool_pcnt)/100, 1); 92 } 93 94 static void 95 serialconsole(void) 96 { 97 char *p; 98 int port, baud; 99 100 p = getconf("console"); 101 if(p == nil) 102 p = "0"; 103 if(p != nil && !remotedebug){ 104 port = strtol(p, nil, 0); 105 baud = 9600; 106 p = getconf("baud"); 107 if(p != nil){ 108 baud = strtol(p, nil, 0); 109 if(baud < 9600) 110 baud = 9600; 111 } 112 uartspecial(port, baud, &kbdq, &printq, kbdcr2nl); 113 } 114 } 115 116 void 117 main(void) 118 { 119 machinit(); 120 options(); 121 archinit(); 122 quotefmtinstall(); 123 confinit(); 124 cpminit(); 125 xinit(); 126 poolsizeinit(); 127 trapinit(); 128 mmuinit(); 129 printinit(); 130 uartinstall(); 131 serialconsole(); 132 doc("screeninit"); 133 screeninit(); 134 doc("kbdinit"); 135 kbdinit(); 136 doc("clockinit"); 137 clockinit(); 138 doc("procinit"); 139 procinit(); 140 cpuidprint(); 141 doc("links"); 142 links(); 143 doc("chandevreset"); 144 chandevreset(); 145 146 eve = strdup("inferno"); 147 148 print("\nInferno %s\n", VERSION); 149 print("Vita Nuova\n"); 150 print("conf %s (%lud) jit %d\n\n",conffile, kerndate, cflag); 151 152 doc("userinit"); 153 userinit(); 154 doc("schedinit"); 155 schedinit(); 156 } 157 158 void 159 machinit(void) 160 { 161 int n; 162 163 n = m->machno; 164 memset(m, 0, sizeof(Mach)); 165 m->machno = n; 166 m->mmask = 1<<m->machno; 167 m->iomem = KADDR(getimmr() & ~0xFFFF); 168 m->cputype = getpvr()>>16; 169 m->delayloop = 20000; /* initial estimate only; set by clockinit */ 170 m->speed = 50; /* initial estimate only; set by archinit */ 171 } 172 173 void 174 init0(void) 175 { 176 Osenv *o; 177 int i; 178 char buf[2*KNAMELEN]; 179 180 up->nerrlab = 0; 181 182 spllo(); 183 184 if(waserror()) 185 panic("init0"); 186 /* 187 * These are o.k. because rootinit is null. 188 * Then early kproc's will have a root and dot. 189 */ 190 o = up->env; 191 o->pgrp->slash = namec("#/", Atodir, 0, 0); 192 cnameclose(o->pgrp->slash->name); 193 o->pgrp->slash->name = newcname("/"); 194 o->pgrp->dot = cclone(o->pgrp->slash); 195 196 chandevinit(); 197 198 if(!waserror()){ 199 ksetenv("cputype", "power", 0); 200 snprint(buf, sizeof(buf), "power %s", conffile); 201 ksetenv("terminal", buf, 0); 202 poperror(); 203 } 204 for(i = 0; i < nconf; i++) 205 if(confname[i][0] != '*'){ 206 if(!waserror()){ 207 ksetenv(confname[i], confval[i], 0); 208 poperror(); 209 } 210 } 211 212 poperror(); 213 disinit("/osinit.dis"); 214 } 215 216 void 217 userinit(void) 218 { 219 Proc *p; 220 Osenv *o; 221 222 p = newproc(); 223 o = p->env; 224 225 o->fgrp = newfgrp(nil); 226 227 o->pgrp = newpgrp(); 228 o->egrp = newegrp(); 229 kstrdup(&o->user, eve); 230 231 strcpy(p->text, "interp"); 232 233 /* 234 * Kernel Stack 235 */ 236 p->sched.pc = (ulong)init0; 237 p->sched.sp = (ulong)p->kstack+KSTACK; 238 239 ready(p); 240 } 241 242 Conf conf; 243 244 void 245 addconf(char *name, char *val) 246 { 247 if(nconf >= MAXCONF) 248 return; 249 confname[nconf] = name; 250 confval[nconf] = val; 251 nconf++; 252 } 253 254 char* 255 getconf(char *name) 256 { 257 int i; 258 259 for(i = 0; i < nconf; i++) 260 if(cistrcmp(confname[i], name) == 0) 261 return confval[i]; 262 return 0; 263 } 264 265 void 266 confinit(void) 267 { 268 char *p; 269 int pcnt; 270 271 if(p = getconf("*kernelpercent")) 272 pcnt = 100 - strtol(p, 0, 0); 273 else 274 pcnt = 0; 275 276 conf.nscc = 4; 277 conf.smcuarts = 1<<0; /* SMC1 (usual console) */ 278 conf.sccuarts = 1<<1; /* SCC2 available by default */ 279 280 archconfinit(); 281 282 conf.npage = conf.npage0 + conf.npage1; 283 if(pcnt < 10) 284 pcnt = 70; 285 conf.ialloc = (((conf.npage*(100-pcnt))/100)/2)*BY2PG; 286 287 conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5; 288 conf.nmach = MAXMACH; 289 } 290 291 void 292 exit(int ispanic) 293 { 294 up = 0; 295 spllo(); 296 print("cpu %d exiting\n", m->machno); 297 298 /* Shutdown running devices */ 299 chandevshutdown(); 300 301 delay(1000); 302 splhi(); 303 if(ispanic) 304 for(;;); 305 archreboot(); 306 } 307 308 void 309 reboot(void) 310 { 311 exit(0); 312 } 313 314 void 315 halt(void) 316 { 317 print("cpu halted\n"); 318 microdelay(1000); 319 for(;;) 320 ; 321 } 322 323 int 324 isaconfig(char *class, int ctlrno, ISAConf *isa) 325 { 326 char cc[KNAMELEN], *p; 327 int i; 328 329 snprint(cc, sizeof cc, "%s%d", class, ctlrno); 330 p = getconf(cc); 331 if(p == nil) 332 return 0; 333 334 isa->nopt = tokenize(p, isa->opt, NISAOPT); 335 for(i = 0; i < isa->nopt; i++){ 336 p = isa->opt[i]; 337 if(cistrncmp(p, "type=", 5) == 0) 338 isa->type = p + 5; 339 else if(cistrncmp(p, "port=", 5) == 0) 340 isa->port = strtoul(p+5, &p, 0); 341 else if(cistrncmp(p, "irq=", 4) == 0) 342 isa->irq = strtoul(p+4, &p, 0); 343 else if(cistrncmp(p, "mem=", 4) == 0) 344 isa->mem = strtoul(p+4, &p, 0); 345 else if(cistrncmp(p, "size=", 5) == 0) 346 isa->size = strtoul(p+5, &p, 0); 347 else if(cistrncmp(p, "freq=", 5) == 0) 348 isa->freq = strtoul(p+5, &p, 0); 349 else if(cistrncmp(p, "dma=", 4) == 0) 350 isa->dma = strtoul(p+4, &p, 0); 351 } 352 return 1; 353 } 354 355 /* 356 * Save the mach dependent part of the process state. 357 */ 358 void 359 procsave(Proc*) 360 { 361 } 362 363 void 364 uartputs(char *s, int n) 365 { 366 // screenputs(buf, n); 367 putstrn(s, n); 368 uartwait(); 369 } 370 371 /* stubs */ 372 void 373 setfsr(ulong) 374 { 375 } 376 377 ulong 378 getfsr() 379 { 380 return 0; 381 } 382 383 void 384 setfcr(ulong) 385 { 386 } 387 388 ulong 389 getfcr() 390 { 391 return 0; 392 } 393