1 #include "u.h" 2 #include "../port/lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 7 #include "init.h" 8 #include "arm.h" 9 #include <pool.h> 10 11 #include "reboot.h" 12 13 uintptr kseg0 = KZERO; 14 Mach* machaddr[MAXMACH]; 15 16 /* 17 * Option arguments from the command line. 18 * oargv[0] is the boot file. 19 * Optionsinit() is called from multiboot() 20 * or some other machine-dependent place 21 * to set it all up. 22 */ 23 static int oargc; 24 static char* oargv[20]; 25 static char oargb[128]; 26 static int oargblen; 27 static char oenv[4096]; 28 29 static uintptr sp; /* XXX - must go - user stack of init proc */ 30 31 int vflag; 32 char debug[256]; 33 34 static void 35 optionsinit(char* s) 36 { 37 char *o; 38 #ifdef USE_FLASH 39 uintptr va; 40 char *p; 41 42 va = 0xf0000000; 43 if(mmukmap(va, PHYSFLASH, 1*MiB) != 0){ 44 o = oenv; 45 for(p = (char*)(va+256*KiB+4); *p != 0; p += strlen(p)+1) 46 o = strecpy(o, oenv+sizeof(oenv), p)+1; 47 mmukunmap(va, PHYSFLASH, 1*MiB); 48 } 49 #else 50 strcpy(oenv, "ethaddr=00:50:43:01:c4:9e"); // TODO 51 #endif 52 53 o = strecpy(oargb, oargb+sizeof(oargb), s)+1; 54 if(getenv("bootargs", o, o - oargb) != nil) 55 *(o-1) = ' '; 56 57 oargblen = strlen(oargb); 58 oargc = tokenize(oargb, oargv, nelem(oargv)-1); 59 oargv[oargc] = nil; 60 } 61 62 char* 63 getenv(char* name, char* buf, int n) 64 { 65 char *e, *p, *q; 66 67 p = oenv; 68 while(*p != 0){ 69 if((e = strchr(p, '=')) == nil) 70 break; 71 for(q = name; p < e; p++){ 72 if(*p != *q) 73 break; 74 q++; 75 } 76 if(p == e && *q == 0){ 77 strecpy(buf, buf+n, e+1); 78 return buf; 79 } 80 p += strlen(p)+1; 81 } 82 83 return nil; 84 } 85 86 #include "io.h" 87 88 typedef struct Spiregs Spiregs; 89 struct Spiregs { 90 ulong ictl; /* interface ctl */ 91 ulong icfg; /* interface config */ 92 ulong out; /* data out */ 93 ulong in; /* data in */ 94 ulong ic; /* interrupt cause */ 95 ulong im; /* interrupt mask */ 96 ulong _pad[2]; 97 ulong dwrcfg; /* direct write config */ 98 ulong dwrhdr; /* direct write header */ 99 }; 100 101 enum { 102 /* ictl bits */ 103 Csnact = 1<<0, /* serial memory activated */ 104 105 /* icfg bits */ 106 Bytelen = 1<<5, /* 2^(this_bit) bytes per transfer */ 107 Dirrdcmd= 1<<10, /* flag: fast read */ 108 }; 109 110 static void 111 dumpbytes(uchar *bp, long max) 112 { 113 iprint("%#p: ", bp); 114 for (; max > 0; max--) 115 iprint("%02.2ux ", *bp++); 116 iprint("...\n"); 117 } 118 119 vlong probeaddr(uintptr); 120 121 // linux sez environment is in nand, 128K at offset 0x40000 122 static void 123 spiprobe(void) 124 { 125 Spiregs *rp = (Spiregs *)AddrSpi; 126 127 l2cacheon(); 128 129 rp->ictl |= Csnact; 130 coherence(); 131 rp->icfg |= Dirrdcmd | 3<<8; /* fast reads, 4-byte addresses */ 132 rp->icfg &= ~Bytelen; /* one-byte reads */ 133 coherence(); 134 135 print("spi flash at %#ux: memory reads enabled\n", PHYSSPIFLASH); 136 #ifdef AMBITIOUS 137 uchar *p, *ep, *np; 138 139 p = (uchar *)PHYSSPIFLASH; 140 ep = p + FLASHSIZE - 64; 141 iprint("scan: "); 142 for (; p < ep - 1; p++) { 143 iprint("%#p of %,ld bytes...", p, ep - p); 144 np = memchr(p, 'e', ep - p); 145 if (np == nil) 146 break; 147 p = np; 148 if (*p == 'e' && memcmp(p, "ethaddr", 7) == 0) 149 break; 150 } 151 dumpbytes(p, 64); 152 #endif 153 } 154 155 void archconsole(void); 156 157 /* 158 * this low-level printing stuff is ugly, 159 * but there appears to be no other way to 160 * print until after #t is populated. 161 */ 162 163 #define wave(c) { \ 164 coherence(); \ 165 while ((*(ulong *)(PHYSCONS+4*5) & (1<<5)) == 0) /* (x->lsr&LSRthre)==0? */ \ 166 ; \ 167 *(ulong *)PHYSCONS = (c); \ 168 coherence(); \ 169 } 170 171 /* 172 * entered from l.s with mmu enabled. 173 * 174 * we may have to realign the data segment; apparently 5l -H0 -R4096 175 * does not pad the text segment. on the other hand, we may have been 176 * loaded by another kernel. 177 * 178 * be careful not to touch the data segment until we know it's aligned. 179 */ 180 void 181 main(Mach* mach) 182 { 183 extern char bdata[], edata[], end[], etext[]; 184 static ulong vfy = 0xcafebabe; 185 186 m = mach; 187 if (vfy != 0xcafebabe) 188 memmove(bdata, etext, edata - bdata); 189 if (vfy != 0xcafebabe) { 190 wave('?'); 191 panic("misaligned data segment"); 192 } 193 memset(edata, 0, end - edata); /* zero bss */ 194 vfy = 0; 195 196 wave('9'); 197 machinit(); 198 archreset(); 199 mmuinit(); 200 201 optionsinit("/boot/boot boot"); 202 quotefmtinstall(); 203 archconsole(); 204 wave('\n'); 205 206 confinit(); 207 xinit(); 208 wave('\r'); 209 210 /* 211 * Printinit will cause the first malloc call. 212 * (printinit->qopen->malloc) unless any of the 213 * above (like clockintr) do an irqenable, which 214 * will call malloc. 215 * If the system dies here it's probably due 216 * to malloc(->xalloc) not being initialised 217 * correctly, or the data segment is misaligned 218 * (it's amazing how far you can get with 219 * things like that completely broken). 220 * 221 * (Should be) boilerplate from here on. 222 */ 223 trapinit(); 224 clockinit(); 225 226 printinit(); 227 /* only now can we print */ 228 uartkirkwoodconsole(); 229 archconfinit(); 230 cpuidprint(); 231 timersinit(); 232 233 procinit0(); 234 initseg(); 235 links(); 236 chandevreset(); 237 238 spiprobe(); 239 240 pageinit(); 241 swapinit(); 242 userinit(); 243 schedinit(); 244 } 245 246 void 247 cpuidprint(void) 248 { 249 char name[64]; 250 251 cputype2name(name, sizeof name); 252 print("cpu%d: %lldMHz ARM %s\n", m->machno, m->cpuhz/1000000, name); 253 } 254 255 void 256 machinit(void) 257 { 258 memset(m, 0, sizeof(Mach)); 259 m->machno = 0; 260 machaddr[m->machno] = m; 261 262 m->ticks = 1; 263 m->perf.period = 1; 264 265 conf.nmach = 1; 266 267 active.machs = 1; 268 active.exiting = 0; 269 270 up = nil; 271 } 272 273 static void 274 shutdown(int ispanic) 275 { 276 int ms, once; 277 278 lock(&active); 279 if(ispanic) 280 active.ispanic = ispanic; 281 else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0) 282 active.ispanic = 0; 283 once = active.machs & (1<<m->machno); 284 active.machs &= ~(1<<m->machno); 285 active.exiting = 1; 286 unlock(&active); 287 288 if(once) 289 iprint("cpu%d: exiting\n", m->machno); 290 spllo(); 291 for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){ 292 delay(TK2MS(2)); 293 if(active.machs == 0 && consactive() == 0) 294 break; 295 } 296 delay(1000); 297 } 298 299 /* 300 * exit kernel either on a panic or user request 301 */ 302 void 303 exit(int code) 304 { 305 shutdown(code); 306 splhi(); 307 archreboot(); 308 } 309 310 /* 311 * the new kernel is already loaded at address `code' 312 * of size `size' and entry point `entry'. 313 */ 314 void 315 reboot(void *entry, void *code, ulong size) 316 { 317 void (*f)(ulong, ulong, ulong); 318 319 iprint("starting reboot..."); 320 // writeconf(); 321 shutdown(0); 322 323 /* 324 * should be the only processor running now 325 */ 326 327 print("shutting down...\n"); 328 delay(200); 329 330 /* turn off buffered serial console */ 331 serialoq = nil; 332 333 /* shutdown devices */ 334 devtabshutdown(); 335 336 /* call off the dog */ 337 clockshutdown(); 338 339 splhi(); 340 341 /* setup reboot trampoline function */ 342 f = (void*)REBOOTADDR; 343 memmove(f, rebootcode, sizeof(rebootcode)); 344 coherence(); 345 dcflushall(); 346 icflushall(); 347 348 print("rebooting..."); 349 iprint("entry %#lux code %#lux size %ld\n", 350 PADDR(entry), PADDR(code), size); 351 delay(100); /* wait for uart to quiesce */ 352 353 /* off we go - never to return */ 354 coherence(); 355 dcflushall(); 356 icflushall(); 357 (*f)(PADDR(entry), PADDR(code), size); 358 359 iprint("loaded kernel returned!\n"); 360 delay(1000); 361 archreboot(); 362 } 363 364 /* 365 * starting place for first process 366 */ 367 void 368 init0(void) 369 { 370 char buf[2*KNAMELEN]; 371 372 assert(up != nil); 373 up->nerrlab = 0; 374 coherence(); 375 spllo(); 376 377 /* 378 * These are o.k. because rootinit is null. 379 * Then early kproc's will have a root and dot. 380 */ 381 up->slash = namec("#/", Atodir, 0, 0); 382 pathclose(up->slash->path); 383 up->slash->path = newpath("/"); 384 up->dot = cclone(up->slash); 385 386 devtabinit(); 387 388 if(!waserror()){ 389 snprint(buf, sizeof(buf), "%s %s", "ARM", conffile); 390 ksetenv("terminal", buf, 0); 391 ksetenv("cputype", "arm", 0); 392 if(cpuserver) 393 ksetenv("service", "cpu", 0); 394 else 395 ksetenv("service", "terminal", 0); 396 397 /* sheevaplug configuration */ 398 ksetenv("nvram", "/boot/nvram", 0); 399 ksetenv("nvroff", "0", 0); 400 ksetenv("nvrlen", "512", 0); 401 ksetenv("nobootprompt", "tcp", 0); 402 403 poperror(); 404 } 405 kproc("alarm", alarmkproc, 0); 406 407 touser(sp); 408 } 409 410 static void 411 bootargs(uintptr base) 412 { 413 int i; 414 ulong ssize; 415 char **av, *p; 416 417 /* 418 * Push the boot args onto the stack. 419 * The initial value of the user stack must be such 420 * that the total used is larger than the maximum size 421 * of the argument list checked in syscall. 422 */ 423 i = oargblen+1; 424 p = UINT2PTR(STACKALIGN(base + PGSIZE - sizeof(up->s.args) - i)); 425 memmove(p, oargb, i); 426 427 /* 428 * Now push argc and the argv pointers. 429 * This isn't strictly correct as the code jumped to by 430 * touser in init9.s calls startboot (port/initcode.c) which 431 * expects arguments 432 * startboot(char *argv0, char **argv) 433 * not the usual (int argc, char* argv[]), but argv0 is 434 * unused so it doesn't matter (at the moment...). 435 */ 436 av = (char**)(p - (oargc+2)*sizeof(char*)); 437 ssize = base + PGSIZE - PTR2UINT(av); 438 *av++ = (char*)oargc; 439 for(i = 0; i < oargc; i++) 440 *av++ = (oargv[i] - oargb) + (p - base) + (USTKTOP - BY2PG); 441 *av = nil; 442 443 /* 444 * Leave space for the return PC of the 445 * caller of initcode. 446 */ 447 sp = USTKTOP - ssize - sizeof(void*); 448 } 449 450 /* 451 * create the first process 452 */ 453 void 454 userinit(void) 455 { 456 Proc *p; 457 Segment *s; 458 KMap *k; 459 Page *pg; 460 461 /* no processes yet */ 462 up = nil; 463 464 p = newproc(); 465 p->pgrp = newpgrp(); 466 p->egrp = smalloc(sizeof(Egrp)); 467 p->egrp->ref = 1; 468 p->fgrp = dupfgrp(nil); 469 p->rgrp = newrgrp(); 470 p->procmode = 0640; 471 472 kstrdup(&eve, ""); 473 kstrdup(&p->text, "*init*"); 474 kstrdup(&p->user, eve); 475 476 /* 477 * Kernel Stack 478 */ 479 p->sched.pc = PTR2UINT(init0); 480 p->sched.sp = PTR2UINT(p->kstack+KSTACK-sizeof(up->s.args)-sizeof(uintptr)); 481 p->sched.sp = STACKALIGN(p->sched.sp); 482 483 /* 484 * User Stack 485 * 486 * Technically, newpage can't be called here because it 487 * should only be called when in a user context as it may 488 * try to sleep if there are no pages available, but that 489 * shouldn't be the case here. 490 */ 491 s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG); 492 p->seg[SSEG] = s; 493 pg = newpage(1, 0, USTKTOP-BY2PG); 494 segpage(s, pg); 495 k = kmap(pg); 496 bootargs(VA(k)); 497 kunmap(k); 498 499 /* 500 * Text 501 */ 502 s = newseg(SG_TEXT, UTZERO, 1); 503 s->flushme++; 504 p->seg[TSEG] = s; 505 pg = newpage(1, 0, UTZERO); 506 memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); 507 segpage(s, pg); 508 k = kmap(s->map[0]->pages[0]); 509 memmove(UINT2PTR(VA(k)), initcode, sizeof initcode); 510 kunmap(k); 511 512 ready(p); 513 } 514 515 Conf conf; /* XXX - must go - gag */ 516 517 Confmem sheevamem[] = { 518 /* 519 * Memory available to Plan 9: 520 */ 521 { .base = 0x00000000, .limit = 512*1024*1024, }, 522 }; 523 524 void 525 confinit(void) 526 { 527 int i; 528 ulong kpages; 529 uintptr pa; 530 531 /* 532 * Copy the physical memory configuration to Conf.mem. 533 * The physical memory configuration will be used later 534 * to check against what the the Pico Array wants. 535 */ 536 if(nelem(sheevamem) > nelem(conf.mem)){ 537 iprint("memory configuration botch\n"); 538 exit(1); 539 } 540 memmove(conf.mem, sheevamem, sizeof(sheevamem)); 541 542 conf.npage = 0; 543 pa = PADDR(PGROUND(PTR2UINT(end))); 544 545 /* 546 * we assume that the kernel is at the beginning of one of the 547 * contiguous chunks of memory and fits therein. 548 */ 549 for(i=0; i<nelem(conf.mem); i++){ 550 /* take kernel out of allocatable space */ 551 if(pa > conf.mem[i].base && pa < conf.mem[i].limit) 552 conf.mem[i].base = pa; 553 554 conf.mem[i].npage = (conf.mem[i].limit - conf.mem[i].base)/BY2PG; 555 conf.npage += conf.mem[i].npage; 556 } 557 558 conf.upages = (conf.npage*90)/100; 559 conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG; 560 561 /* only one processor */ 562 conf.nmach = 1; 563 564 /* set up other configuration parameters */ 565 conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5; 566 if(cpuserver) 567 conf.nproc *= 3; 568 if(conf.nproc > 2000) 569 conf.nproc = 2000; 570 conf.nswap = conf.npage*3; 571 conf.nswppo = 4096; 572 conf.nimage = 200; 573 574 conf.copymode = 0; /* copy on write */ 575 576 /* 577 * Guess how much is taken by the large permanent 578 * datastructures. Mntcache and Mntrpc are not accounted for 579 * (probably ~300KB). 580 */ 581 kpages = conf.npage - conf.upages; 582 kpages *= BY2PG; 583 kpages -= conf.upages*sizeof(Page) 584 + conf.nproc*sizeof(Proc) 585 + conf.nimage*sizeof(Image) 586 + conf.nswap 587 + conf.nswppo*sizeof(Page); 588 mainmem->maxsize = kpages; 589 if(!cpuserver) 590 /* 591 * give terminals lots of image memory, too; the dynamic 592 * allocation will balance the load properly, hopefully. 593 * be careful with 32-bit overflow. 594 */ 595 imagmem->maxsize = kpages; 596 } 597 598 char* 599 getconf(char *) 600 { 601 return nil; 602 } 603 604 int 605 cmpswap(long *addr, long old, long new) 606 { 607 return cas32(addr, old, new); 608 } 609