main.c 18 KB

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