main.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "u.h"
  10. #include "../port/lib.h"
  11. #include "mem.h"
  12. #include "dat.h"
  13. #include "fns.h"
  14. #include "init.h"
  15. #include "apic.h"
  16. #include "io.h"
  17. #include "amd64.h"
  18. #undef DBG
  19. #define DBG iprint
  20. Conf conf; /* XXX - must go - gag */
  21. static uintptr_t sp; /* XXX - must go - user stack of init proc */
  22. /* Next time you see a system with cores/sockets running at different clock rates, on x86,
  23. * let me know. AFAIK, it no longer happens. So the BSP hz is good for the AP hz.
  24. */
  25. int64_t hz;
  26. uintptr_t kseg0 = KZERO;
  27. Sys* sys = nil;
  28. usize sizeofSys = sizeof(Sys);
  29. Mach *entrym;
  30. /*
  31. * Option arguments from the command line.
  32. * oargv[0] is the boot file.
  33. * Optionsinit() is called from multiboot() to
  34. * set it all up.
  35. */
  36. char *cputype = "amd64";
  37. static int64_t oargc;
  38. static char* oargv[20];
  39. static char oargb[128];
  40. static int oargblen;
  41. static int maxcores = 1024; /* max # of cores given as an argument */
  42. static int numtcs = 32; /* initial # of TCs */
  43. char dbgflg[256];
  44. static int vflag = 1;
  45. int nosmp = 1;
  46. void
  47. optionsinit(char* s)
  48. {
  49. oargblen = strecpy(oargb, oargb+sizeof(oargb), s) - oargb;
  50. oargc = tokenize(oargb, oargv, nelem(oargv)-1);
  51. oargv[oargc] = nil;
  52. }
  53. static void
  54. options(int argc, char* argv[])
  55. {
  56. char *p;
  57. int n, o;
  58. /*
  59. * Process flags.
  60. * Flags [A-Za-z] may be optionally followed by
  61. * an integer level between 1 and 127 inclusive
  62. * (no space between flag and level).
  63. * '--' ends flag processing.
  64. */
  65. while(--argc > 0 && (*++argv)[0] == '-' && (*argv)[1] != '-'){
  66. while(o = *++argv[0]){
  67. if(!(o >= 'A' && o <= 'Z') && !(o >= 'a' && o <= 'z'))
  68. continue;
  69. n = strtol(argv[0]+1, &p, 0);
  70. if(p == argv[0]+1 || n < 1 || n > 127)
  71. n = 1;
  72. argv[0] = p-1;
  73. dbgflg[o] = n;
  74. }
  75. }
  76. vflag = dbgflg['v'];
  77. if(argc > 0){
  78. maxcores = strtol(argv[0], 0, 0);
  79. argc--;
  80. argv++;
  81. }
  82. if(argc > 0){
  83. numtcs = strtol(argv[0], 0, 0);
  84. //argc--;
  85. //argv++;
  86. }
  87. // hack.
  88. nosmp = dbgflg['n'];
  89. }
  90. void
  91. squidboy(int apicno, Mach *mach)
  92. {
  93. // FIX QEMU. extern int64_t hz;
  94. int64_t hz;
  95. mach->self = (uintptr_t)mach;
  96. sys->machptr[mach->machno] = mach;
  97. /*
  98. * Need something for initial delays
  99. * until a timebase is worked out.
  100. */
  101. mach->cpuhz = 2000000000ll;
  102. mach->cpumhz = 2000;
  103. mach->perf.period = 1;
  104. mach->nixtype = NIXAC;
  105. // no NIXAC for now.
  106. mach->nixtype = NIXTC;
  107. // NOTE: you can't do ANYTHING here before vsvminit.
  108. // PRINT WILL PANIC. So wait.
  109. vsvminit(MACHSTKSZ, mach->nixtype, mach);
  110. //DBG("Hello squidboy %d %d\n", apicno, machp()->machno);
  111. /*
  112. * Beware the Curse of The Non-Interruptable Were-Temporary.
  113. */
  114. hz = archhz();
  115. /* Intel cpu's in archk10 must be reviewed */
  116. if(hz == 0)
  117. hz = 2000000000ll;
  118. mach->cpuhz = hz;
  119. mach->cyclefreq = hz;
  120. mach->cpumhz = hz/1000000ll;
  121. mmuinit();
  122. if(!apiconline())
  123. ndnr();
  124. fpuinit();
  125. acmodeset(mach->nixtype);
  126. mach->splpc = 0;
  127. mach->online = 1;
  128. /*
  129. * CAUTION: no time sync done, etc.
  130. * Stupid print to avoid up = nil or
  131. * last cpu couldn't start in nixquids.
  132. */
  133. DBG("Wait for the thunderbirds!\n");
  134. while(!active.thunderbirdsarego)
  135. ;
  136. wrmsr(0x10, sys->epoch);
  137. mach->rdtsc = rdtsc();
  138. print("cpu%d color %d role %s tsc %lld\n",
  139. mach->machno, corecolor(mach->machno), rolename[mach->nixtype], mach->rdtsc);
  140. switch(mach->nixtype){
  141. case NIXAC:
  142. acmmuswitch();
  143. acinit();
  144. adec(&active.nbooting);
  145. ainc(&active.nonline); /* this was commented out */
  146. acsched();
  147. panic("squidboy");
  148. break;
  149. case NIXTC:
  150. /*
  151. * We only need the idt and syscall entry point actually.
  152. * At boot time the boot processor might set our role after
  153. * we have decided to become an AC.
  154. */
  155. vsvminit(MACHSTKSZ, NIXTC, mach);
  156. /*
  157. * Enable the timer interrupt.
  158. */
  159. apictimerenab();
  160. apicpri(0);
  161. timersinit();
  162. adec(&active.nbooting);
  163. ainc(&active.nonline);
  164. /* Ready? steady? going to timer */
  165. //ndnr();
  166. schedinit();
  167. break;
  168. }
  169. panic("squidboy returns (type %d)", mach->nixtype);
  170. }
  171. static void
  172. testiccs(void)
  173. {
  174. int i;
  175. Mach *mach;
  176. extern void testicc(int);
  177. /* setup arguments for all */
  178. for(i = 0; i < MACHMAX; i++)
  179. if((mach = sys->machptr[i]) != nil && mach->online && mach->nixtype == NIXAC)
  180. testicc(i);
  181. print("bootcore: all cores done\n");
  182. }
  183. /*
  184. * Rendezvous with other cores. Set roles for those that came
  185. * up online, and wait until they are initialized.
  186. * Sync TSC with them.
  187. * We assume other processors that could boot had time to
  188. * set online to 1 by now.
  189. */
  190. static void
  191. nixsquids(void)
  192. {
  193. Mach *mach;
  194. int i;
  195. uint64_t now, start;
  196. /* Not AC for now :-) */
  197. for(i = 1; i <= MACHMAX; i++)
  198. //for(i = 1; i < MACHMAX; i++)
  199. if((mach = sys->machptr[i]) != nil && mach->online){
  200. /*
  201. * Inter-core calls. A ensure *mp->iccall and mp->icargs
  202. * go into different cache lines.
  203. */
  204. mach->icc = mallocalign(sizeof *machp()->icc, ICCLNSZ, 0, 0);
  205. mach->icc->fn = nil;
  206. if(i < numtcs){
  207. sys->nmach++;
  208. mach->nixtype = NIXTC;
  209. sys->nc[NIXTC]++;
  210. }//else
  211. //sys->nc[NIXAC]++;
  212. ainc(&active.nbooting);
  213. }
  214. sys->epoch = rdtsc();
  215. mfence();
  216. wrmsr(0x10, sys->epoch);
  217. machp()->rdtsc = rdtsc();
  218. active.thunderbirdsarego = 1;
  219. start = fastticks2us(fastticks(nil));
  220. do{
  221. now = fastticks2us(fastticks(nil));
  222. }while(active.nbooting > 0 && now - start < 1000000)
  223. ;
  224. if(active.nbooting > 0)
  225. print("cpu0: %d cores couldn't start\n", active.nbooting);
  226. active.nbooting = 0;
  227. }
  228. void
  229. DONE(void)
  230. {
  231. print("DONE\n");
  232. //prflush();
  233. delay(10000);
  234. ndnr();
  235. }
  236. void
  237. HERE(void)
  238. {
  239. print("here\n");
  240. //prflush();
  241. delay(5000);
  242. }
  243. /* The old plan 9 standby ... wave ... */
  244. /* Keep to debug trap.c */
  245. void wave(int c)
  246. {
  247. outb(0x3f8, c);
  248. }
  249. void hi(char *s)
  250. {
  251. if (! s)
  252. s = "<NULL>";
  253. while (*s)
  254. wave(*s++);
  255. }
  256. /*
  257. * for gdb:
  258. * call this anywhere in your code.
  259. * die("yourturn with gdb\n");
  260. * gdb 9k
  261. * target remote localhost:1234
  262. * display/i $pc
  263. * set staydead = 0
  264. * stepi, and debug.
  265. * note, you can always resume after a die. Just set staydead = 0
  266. */
  267. int staydead = 1;
  268. void die(char *s)
  269. {
  270. wave('d');
  271. wave('i');
  272. wave('e');
  273. wave(':');
  274. hi(s);
  275. while(staydead);
  276. staydead = 1;
  277. }
  278. /*
  279. void bmemset(void *p)
  280. {
  281. __asm__ __volatile__("1: jmp 1b");
  282. }
  283. void put8(uint8_t c)
  284. {
  285. char x[] = "0123456789abcdef";
  286. wave(x[c>>4]);
  287. wave(x[c&0xf]);
  288. }
  289. void put16(uint16_t s)
  290. {
  291. put8(s>>8);
  292. put8(s);
  293. }
  294. void put32(uint32_t u)
  295. {
  296. put16(u>>16);
  297. put16(u);
  298. }
  299. void put64(uint64_t v)
  300. {
  301. put32(v>>32);
  302. put32(v);
  303. }
  304. */
  305. void debugtouser(void *va)
  306. {
  307. uintptr_t uva = (uintptr_t) va;
  308. PTE *pte, *pml4;
  309. pml4 = UINT2PTR(machp()->pml4->va);
  310. mmuwalk(pml4, uva, 0, &pte, nil);
  311. iprint("va %p m %p m>pml4 %p machp()->pml4->va %p pml4 %p PTE 0x%lx\n", va,
  312. machp(), machp()->pml4, machp()->pml4->va, (void *)pml4, *pte);
  313. }
  314. /*
  315. void badcall(uint64_t where, uint64_t what)
  316. {
  317. hi("Bad call from function "); put64(where); hi(" to "); put64(what); hi("\n");
  318. while (1)
  319. ;
  320. }
  321. */
  322. void errstr(char *s, int i) {
  323. panic("errstr");
  324. }
  325. static int x = 0x123456;
  326. /* tear down the identity map we created in assembly. ONLY do this after all the
  327. * APs have started up (and you know they've done so. But you must do it BEFORE
  328. * you create address spaces for procs, i.e. userinit()
  329. */
  330. static void
  331. teardownidmap(Mach *mach)
  332. {
  333. int i;
  334. uintptr_t va = 0;
  335. PTE *p;
  336. /* loop on the level 2 because we should not assume we know
  337. * how many there are But stop after 1G no matter what, and
  338. * report if there were that many, as that is odd.
  339. */
  340. for(i = 0; i < 512; i++, va += BIGPGSZ) {
  341. if (mmuwalk(UINT2PTR(mach->pml4->va), va, 1, &p, nil) != 1)
  342. break;
  343. if (! *p)
  344. break;
  345. iprint("teardown: va %p, pte %p\n", (void *)va, p);
  346. *p = 0;
  347. }
  348. iprint("Teardown: zapped %d PML1 entries\n", i);
  349. for(i = 2; i < 4; i++) {
  350. if (mmuwalk(UINT2PTR(mach->pml4->va), 0, i, &p, nil) != i) {
  351. iprint("weird; 0 not mapped at %d\n", i);
  352. continue;
  353. }
  354. iprint("teardown: zap %p at level %d\n", p, i);
  355. if (p)
  356. *p = 0;
  357. }
  358. }
  359. void
  360. main(uint32_t mbmagic, uint32_t mbaddress)
  361. {
  362. Mach *mach = entrym;
  363. /* when we get here, entrym is set to core0 mach. */
  364. sys->machptr[mach->machno] = entrym;
  365. // Very special case for BSP only. Too many things
  366. // assume this is set.
  367. wrmsr(GSbase, PTR2UINT(&sys->machptr[mach->machno]));
  368. if (machp() != mach)
  369. panic("mach and machp() are different!!\n");
  370. assert(sizeof(Mach) <= PGSZ);
  371. /*
  372. * Check that our data is on the right boundaries.
  373. * This works because the immediate value is in code.
  374. */
  375. //cgaprint(800, "hello harvey\n");
  376. //for(;;);
  377. if (x != 0x123456)
  378. panic("Data is not set up correctly\n");
  379. memset(edata, 0, end - edata);
  380. // TODO(aki): figure this out.
  381. mach = (void *) (KZERO + 1048576 + 11*4096);
  382. if(mach != machp()){ cgapost(0x01);for(;;); }
  383. sys = (void *) (KZERO + 1048576);
  384. /*
  385. * ilock via i8250enable via i8250console
  386. * needs machp()->machno, sys->machptr[] set, and
  387. * also 'up' set to nil.
  388. */
  389. cgapost(sizeof(uintptr_t)*8);
  390. memset(mach, 0, sizeof(Mach));
  391. mach->self = (uintptr_t)mach;
  392. mach->machno = 0;
  393. mach->online = 1;
  394. mach->nixtype = NIXTC;
  395. mach->stack = PTR2UINT(sys->machstk);
  396. *(uintptr_t*)mach->stack = STACKGUARD;
  397. mach->vsvm = sys->vsvmpage;
  398. mach->externup = nil;
  399. active.nonline = 1;
  400. active.exiting = 0;
  401. active.nbooting = 0;
  402. asminit();
  403. multiboot(mbmagic, mbaddress, 0);
  404. options(oargc, oargv);
  405. /*
  406. * Need something for initial delays
  407. * until a timebase is worked out.
  408. */
  409. mach->cpuhz = 2000000000ll;
  410. mach->cpumhz = 2000;
  411. cgainit();
  412. i8250console("0");
  413. consputs = cgaconsputs;
  414. /* It all ends here. */
  415. vsvminit(MACHSTKSZ, NIXTC, mach);
  416. if (machp() != mach)
  417. panic("After vsvminit, m and machp() are different");
  418. sys->nmach = 1;
  419. fmtinit();
  420. print("\nHarvey\n");
  421. if(vflag){
  422. multiboot(mbmagic, mbaddress, vflag);
  423. }
  424. mach->perf.period = 1;
  425. if((hz = archhz()) != 0ll){
  426. mach->cpuhz = hz;
  427. mach->cyclefreq = hz;
  428. mach->cpumhz = hz/1000000ll;
  429. }
  430. //iprint("archhz returns 0x%lld\n", hz);
  431. //iprint("NOTE: if cpuidhz runs too fast, we get die early with a NULL pointer\n");
  432. //iprint("So, until that's fixed, we bring up AP cores slowly. Sorry!\n");
  433. /*
  434. * Mmuinit before meminit because it
  435. * flushes the TLB via machp()->pml4->pa.
  436. */
  437. mmuinit();
  438. ioinit();
  439. meminit();
  440. confinit();
  441. archinit();
  442. mallocinit();
  443. /* test malloc. It's easier to find out it's broken here,
  444. * not deep in some call chain.
  445. * See next note.
  446. *
  447. void *v = malloc(1234);
  448. hi("v "); put64((uint64_t)v); hi("\n");
  449. free(v);
  450. hi("free ok\n");
  451. */
  452. /*
  453. * Acpiinit will cause the first malloc
  454. * call to happen.
  455. * If the system dies here it's probably due
  456. * to malloc not being initialised
  457. * correctly, or the data segment is misaligned
  458. * (it's amazing how far you can get with
  459. * things like that completely broken).
  460. */
  461. if (0){ acpiinit(); hi(" acpiinit();\n");}
  462. umeminit();
  463. trapinit();
  464. /*
  465. * This is necessary with GRUB and QEMU.
  466. * Without it an interrupt can occur at a weird vector,
  467. * because the vector base is likely different, causing
  468. * havoc. Do it before any APIC initialisation.
  469. */
  470. i8259init(32);
  471. procinit0();
  472. mpsinit(maxcores);
  473. apiconline();
  474. /* Forcing to single core if desired */
  475. if(!nosmp) {
  476. sipi();
  477. }
  478. //working.
  479. teardownidmap(mach);
  480. timersinit();
  481. fpuinit();
  482. psinit(conf.nproc);
  483. initimage();
  484. links();
  485. keybinit();
  486. keybenable();
  487. mouseenable();
  488. devtabreset();
  489. pageinit();
  490. swapinit();
  491. userinit();
  492. /* Forcing to single core if desired */
  493. if(!nosmp) {
  494. nixsquids();
  495. testiccs();
  496. }
  497. print("CPU Freq. %dMHz\n", mach->cpumhz);
  498. print("schedinit...\n");
  499. schedinit();
  500. }
  501. void
  502. init0(void)
  503. {
  504. Proc *up = externup();
  505. char buf[2*KNAMELEN];
  506. up->nerrlab = 0;
  507. /*
  508. * if(consuart == nil)
  509. * i8250console("0");
  510. */
  511. spllo();
  512. /*
  513. * These are o.k. because rootinit is null.
  514. * Then early kproc's will have a root and dot.
  515. */
  516. up->slash = namec("#/", Atodir, 0, 0);
  517. pathclose(up->slash->path);
  518. up->slash->path = newpath("/");
  519. up->dot = cclone(up->slash);
  520. devtabinit();
  521. if(!waserror()){
  522. snprint(buf, sizeof(buf), "%s %s", "AMD64", conffile);
  523. ksetenv("terminal", buf, 0);
  524. ksetenv("cputype", cputype, 0);
  525. if(cpuserver)
  526. ksetenv("service", "cpu", 0);
  527. else
  528. ksetenv("service", "terminal", 0);
  529. ksetenv("pgsz", "2097152", 0);
  530. // no longer. confsetenv();
  531. poperror();
  532. }
  533. kproc("alarm", alarmkproc, 0);
  534. //debugtouser((void *)UTZERO);
  535. touser(sp);
  536. }
  537. void
  538. bootargs(uintptr_t base)
  539. {
  540. int i;
  541. uint32_t ssize;
  542. char **av, *p;
  543. /*
  544. * Push the boot args onto the stack.
  545. * Make sure the validaddr check in syscall won't fail
  546. * because there are fewer than the maximum number of
  547. * args by subtracting sizeof(up->arg).
  548. */
  549. i = oargblen+1;
  550. p = UINT2PTR(STACKALIGN(base + BIGPGSZ - sizeof(((Proc*)0)->arg) - i));
  551. memmove(p, oargb, i);
  552. /*
  553. * Now push argc and the argv pointers.
  554. * This isn't strictly correct as the code jumped to by
  555. * touser in init9.[cs] calls startboot (port/initcode.c) which
  556. * expects arguments
  557. * startboot(char* argv0, char* argv[])
  558. * not the usual (int argc, char* argv[]), but argv0 is
  559. * unused so it doesn't matter (at the moment...).
  560. */
  561. av = (char**)(p - (oargc+2)*sizeof(char*));
  562. ssize = base + BIGPGSZ - PTR2UINT(av);
  563. *av++ = (char*)oargc;
  564. for(i = 0; i < oargc; i++)
  565. *av++ = (oargv[i] - oargb) + (p - base) + (USTKTOP - BIGPGSZ);
  566. *av = nil;
  567. sp = USTKTOP - ssize;
  568. }
  569. void
  570. userinit(void)
  571. {
  572. Proc *up = externup();
  573. Proc *p;
  574. Segment *s;
  575. KMap *k;
  576. Page *pg;
  577. int sno;
  578. p = newproc();
  579. p->pgrp = newpgrp();
  580. p->egrp = smalloc(sizeof(Egrp));
  581. p->egrp->ref = 1;
  582. p->fgrp = dupfgrp(nil);
  583. p->rgrp = newrgrp();
  584. p->procmode = 0640;
  585. kstrdup(&eve, "");
  586. kstrdup(&p->text, "*init*");
  587. kstrdup(&p->user, eve);
  588. /*
  589. * Kernel Stack
  590. *
  591. * N.B. make sure there's enough space for syscall to check
  592. * for valid args and
  593. * space for gotolabel's return PC
  594. * AMD64 stack must be quad-aligned.
  595. */
  596. p->sched.pc = PTR2UINT(init0);
  597. p->sched.sp = PTR2UINT(p->kstack+KSTACK-sizeof(up->arg)-sizeof(uintptr_t));
  598. p->sched.sp = STACKALIGN(p->sched.sp);
  599. /*
  600. * User Stack
  601. *
  602. * Technically, newpage can't be called here because it
  603. * should only be called when in a user context as it may
  604. * try to sleep if there are no pages available, but that
  605. * shouldn't be the case here.
  606. */
  607. sno = 0;
  608. s = newseg(SG_STACK|SG_READ|SG_WRITE, USTKTOP-USTKSIZE, USTKSIZE/ BIGPGSZ);
  609. p->seg[sno++] = s;
  610. pg = newpage(1, 0, USTKTOP-BIGPGSZ, BIGPGSZ, -1);
  611. segpage(s, pg);
  612. k = kmap(pg);
  613. bootargs(VA(k));
  614. kunmap(k);
  615. /*
  616. * Text
  617. */
  618. s = newseg(SG_TEXT|SG_READ|SG_EXEC, UTZERO, 1);
  619. s->flushme++;
  620. p->seg[sno++] = s;
  621. pg = newpage(1, 0, UTZERO, BIGPGSZ, -1);
  622. memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
  623. segpage(s, pg);
  624. k = kmap(s->map[0]->pages[0]);
  625. /* UTZERO is only needed until we make init not have 2M block of zeros at the front. */
  626. memmove(UINT2PTR(VA(k) + init_code_start - UTZERO), init_code_out, sizeof(init_code_out));
  627. kunmap(k);
  628. /*
  629. * Data
  630. */
  631. s = newseg(SG_DATA|SG_READ|SG_WRITE, UTZERO + BIGPGSZ, 1);
  632. s->flushme++;
  633. p->seg[sno++] = s;
  634. pg = newpage(1, 0, UTZERO + BIGPGSZ, BIGPGSZ, -1);
  635. memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
  636. segpage(s, pg);
  637. k = kmap(s->map[0]->pages[0]);
  638. /* This depends on init having a text segment < 2M. */
  639. memmove(UINT2PTR(VA(k) + init_data_start - (UTZERO + BIGPGSZ)), init_data_out, sizeof(init_data_out));
  640. kunmap(k);
  641. ready(p);
  642. }
  643. void
  644. confinit(void)
  645. {
  646. int i;
  647. conf.npage = 0;
  648. for(i=0; i<nelem(conf.mem); i++)
  649. conf.npage += conf.mem[i].npage;
  650. conf.nproc = 1000;
  651. conf.nimage = 200;
  652. }
  653. static void
  654. shutdown(int ispanic)
  655. {
  656. int ms, once;
  657. lock(&active);
  658. if(ispanic)
  659. active.ispanic = ispanic;
  660. else if(machp()->machno == 0 && machp()->online == 0)
  661. active.ispanic = 0;
  662. once = machp()->online;
  663. machp()->online = 0;
  664. adec(&active.nonline);
  665. active.exiting = 1;
  666. unlock(&active);
  667. if(once)
  668. iprint("cpu%d: exiting\n", machp()->machno);
  669. spllo();
  670. for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
  671. delay(TK2MS(2));
  672. if(active.nonline == 0)
  673. break;
  674. }
  675. if(active.ispanic && machp()->machno == 0){
  676. if(cpuserver)
  677. delay(30000);
  678. else
  679. for(;;)
  680. halt();
  681. }
  682. else
  683. delay(1000);
  684. }
  685. void
  686. reboot(void* v, void* w, int32_t i)
  687. {
  688. panic("reboot\n");
  689. }
  690. void
  691. exit(int ispanic)
  692. {
  693. shutdown(ispanic);
  694. archreset();
  695. }