main.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884
  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. // The kernel has a limited area identity mapped for it. If when loaded
  433. // it goes beyond that area, we'll have problems. If the identity
  434. // mapping changes, change this assert.
  435. assert(((uintptr_t)end - KZERO) < 16*MiB);
  436. /*
  437. * Check that our data is on the right boundaries.
  438. * This works because the immediate value is in code.
  439. */
  440. //cgaprint(800, "hello harvey\n");
  441. //for(;;);
  442. if (x != 0x123456)
  443. panic("Data is not set up correctly\n");
  444. // Clear BSS
  445. memset(edata, 0, end - edata);
  446. // TODO(aki): figure this out.
  447. mach = (void *) (KZERO + 1048576 + 11*4096);
  448. if(mach != machp()){ cgapost(0x01);for(;;); }
  449. sys = (void *) (KZERO + 1048576);
  450. /*
  451. * ilock via i8250enable via i8250console
  452. * needs machp()->machno, sys->machptr[] set, and
  453. * also 'up' set to nil.
  454. */
  455. cgapost(sizeof(uintptr_t)*8);
  456. memset(mach, 0, sizeof(Mach));
  457. mach->self = (uintptr_t)mach;
  458. mach->machno = 0;
  459. mach->online = 1;
  460. mach->NIX.nixtype = NIXTC;
  461. mach->stack = PTR2UINT(sys->machstk);
  462. *(uintptr_t*)mach->stack = STACKGUARD;
  463. mach->vsvm = sys->vsvmpage;
  464. mach->externup = nil;
  465. active.nonline = 1;
  466. active.exiting = 0;
  467. active.nbooting = 0;
  468. asminit();
  469. multiboot(mbmagic, mbaddress, 0);
  470. options(oargc, oargv);
  471. /*
  472. * Need something for initial delays
  473. * until a timebase is worked out.
  474. */
  475. mach->cpuhz = 2000000000ll;
  476. mach->cpumhz = 2000;
  477. sys->cyclefreq = mach->cpuhz;
  478. cgainit();
  479. i8250console("0");
  480. consputs = cgaconsputs;
  481. /* It all ends here. */
  482. vsvminit(MACHSTKSZ, NIXTC, mach);
  483. if (machp() != mach)
  484. panic("After vsvminit, m and machp() are different");
  485. sys->nmach = 1;
  486. fmtinit();
  487. print("\nHarvey\n");
  488. if(vflag){
  489. multiboot(mbmagic, mbaddress, vflag);
  490. }
  491. mach->perf.period = 1;
  492. if((hz = archhz()) != 0ll){
  493. mach->cpuhz = hz;
  494. mach->cyclefreq = hz;
  495. sys->cyclefreq = hz;
  496. mach->cpumhz = hz/1000000ll;
  497. }
  498. //iprint("archhz returns 0x%lld\n", hz);
  499. //iprint("NOTE: if cpuidhz runs too fast, we get die early with a NULL pointer\n");
  500. //iprint("So, until that's fixed, we bring up AP cores slowly. Sorry!\n");
  501. /*
  502. * Mmuinit before meminit because it
  503. * flushes the TLB via machp()->pml4->pa.
  504. */
  505. mmuinit();
  506. ioinit();
  507. keybinit();
  508. meminit();
  509. confinit();
  510. archinit();
  511. mallocinit();
  512. /* test malloc. It's easier to find out it's broken here,
  513. * not deep in some call chain.
  514. * See next note.
  515. *
  516. */
  517. if (1) {
  518. void *v = malloc(1234);
  519. hi("allocated\n ");
  520. free(v);
  521. hi("free ok\n");
  522. }
  523. /*
  524. * Acpiinit will cause the first malloc
  525. * call to happen.
  526. * If the system dies here it's probably due
  527. * to malloc not being initialised
  528. * correctly, or the data segment is misaligned
  529. * (it's amazing how far you can get with
  530. * things like that completely broken).
  531. */
  532. if (1){ acpiinit(); hi(" acpiinit();\n");}
  533. umeminit();
  534. /*
  535. * This is necessary with GRUB and QEMU.
  536. * Without it an interrupt can occur at a weird vector,
  537. * because the vector base is likely different, causing
  538. * havoc. Do it before any APIC initialisation.
  539. */
  540. i8259init(32);
  541. procinit0();
  542. print("before mpacpi, maxcores %d\n", maxcores);
  543. mpacpi(maxcores);
  544. trapinit();
  545. printinit();
  546. apiconline();
  547. ioapiconline();
  548. /* Forcing to single core if desired */
  549. if(!nosmp) {
  550. sipi();
  551. }
  552. //working.
  553. teardownidmap(mach);
  554. timersinit();
  555. fpuinit();
  556. psinit(conf.nproc);
  557. initimage();
  558. links();
  559. keybenable();
  560. mouseenable();
  561. devtabreset();
  562. pageinit();
  563. swapinit();
  564. userinit();
  565. /* Forcing to single core if desired */
  566. if(!nosmp) {
  567. nixsquids();
  568. testiccs();
  569. }
  570. alloc_cpu_buffers();
  571. acpistart();
  572. print("CPU Freq. %dMHz\n", mach->cpumhz);
  573. print("schedinit...\n");
  574. schedinit();
  575. }
  576. void
  577. init0(void)
  578. {
  579. Proc *up = externup();
  580. char buf[2*KNAMELEN];
  581. up->nerrlab = 0;
  582. /*
  583. * if(consuart == nil)
  584. * i8250console("0");
  585. */
  586. spllo();
  587. /*
  588. * These are o.k. because rootinit is null.
  589. * Then early kproc's will have a root and dot.
  590. */
  591. up->slash = namec("#/", Atodir, 0, 0);
  592. pathclose(up->slash->path);
  593. up->slash->path = newpath("/");
  594. up->dot = cclone(up->slash);
  595. devtabinit();
  596. if(!waserror()){
  597. snprint(buf, sizeof(buf), "%s", "AMD64");
  598. loadenv(oargc, oargv);
  599. ksetenv("terminal", buf, 0);
  600. ksetenv("cputype", cputype, 0);
  601. ksetenv("pgsz", "2097152", 0);
  602. // no longer. confsetenv();
  603. poperror();
  604. }
  605. kproc("alarm", alarmkproc, 0);
  606. //debugtouser((void *)UTZERO);
  607. touser(sp);
  608. }
  609. void
  610. bootargs(uintptr_t base)
  611. {
  612. int i;
  613. uint32_t ssize;
  614. char **av, *p;
  615. /*
  616. * Push the boot args onto the stack.
  617. * Make sure the validaddr check in syscall won't fail
  618. * because there are fewer than the maximum number of
  619. * args by subtracting sizeof(up->arg).
  620. */
  621. i = oargblen+1;
  622. p = UINT2PTR(STACKALIGN(base + BIGPGSZ - sizeof(((Proc*)0)->arg) - i));
  623. memmove(p, oargb, i);
  624. /*
  625. * Now push argc and the argv pointers.
  626. * This isn't strictly correct as the code jumped to by
  627. * touser in init9.[cs] calls startboot (port/initcode.c) which
  628. * expects arguments
  629. * startboot(char* argv0, char* argv[])
  630. * not the usual (int argc, char* argv[]), but argv0 is
  631. * unused so it doesn't matter (at the moment...).
  632. */
  633. av = (char**)(p - (oargc+2)*sizeof(char*));
  634. ssize = base + BIGPGSZ - PTR2UINT(av);
  635. *av++ = (char*)oargc;
  636. for(i = 0; i < oargc; i++)
  637. *av++ = (oargv[i] - oargb) + (p - base) + (USTKTOP - BIGPGSZ);
  638. *av = nil;
  639. sp = USTKTOP - ssize;
  640. }
  641. void
  642. userinit(void)
  643. {
  644. Proc *up = externup();
  645. Proc *p;
  646. Segment *s;
  647. KMap *k;
  648. Page *pg;
  649. int sno;
  650. p = newproc();
  651. p->pgrp = newpgrp();
  652. p->egrp = smalloc(sizeof(Egrp));
  653. p->egrp->r.ref = 1;
  654. p->fgrp = dupfgrp(nil);
  655. p->rgrp = newrgrp();
  656. p->procmode = 0640;
  657. kstrdup(&eve, "");
  658. kstrdup(&p->text, "*init*");
  659. kstrdup(&p->user, eve);
  660. /*
  661. * Kernel Stack
  662. *
  663. * N.B. make sure there's enough space for syscall to check
  664. * for valid args and
  665. * space for gotolabel's return PC
  666. * AMD64 stack must be quad-aligned.
  667. */
  668. p->sched.pc = PTR2UINT(init0);
  669. p->sched.sp = PTR2UINT(p->kstack+KSTACK-sizeof(up->arg)-sizeof(uintptr_t));
  670. p->sched.sp = STACKALIGN(p->sched.sp);
  671. /*
  672. * User Stack
  673. *
  674. * Technically, newpage can't be called here because it
  675. * should only be called when in a user context as it may
  676. * try to sleep if there are no pages available, but that
  677. * shouldn't be the case here.
  678. */
  679. sno = 0;
  680. s = newseg(SG_STACK|SG_READ|SG_WRITE, USTKTOP-USTKSIZE, USTKSIZE/ BIGPGSZ);
  681. p->seg[sno++] = s;
  682. pg = newpage(1, 0, USTKTOP-BIGPGSZ, BIGPGSZ, -1);
  683. segpage(s, pg);
  684. k = kmap(pg);
  685. bootargs(VA(k));
  686. kunmap(k);
  687. /*
  688. * Text
  689. */
  690. s = newseg(SG_TEXT|SG_READ|SG_EXEC, UTZERO, 1);
  691. s->flushme++;
  692. p->seg[sno++] = s;
  693. pg = newpage(1, 0, UTZERO, BIGPGSZ, -1);
  694. memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
  695. segpage(s, pg);
  696. k = kmap(s->map[0]->pages[0]);
  697. /* UTZERO is only needed until we make init not have 2M block of zeros at the front. */
  698. memmove(UINT2PTR(VA(k) + init_code_start - UTZERO), init_code_out, sizeof(init_code_out));
  699. kunmap(k);
  700. /*
  701. * Data
  702. */
  703. s = newseg(SG_DATA|SG_READ|SG_WRITE, UTZERO + BIGPGSZ, 1);
  704. s->flushme++;
  705. p->seg[sno++] = s;
  706. pg = newpage(1, 0, UTZERO + BIGPGSZ, BIGPGSZ, -1);
  707. memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
  708. segpage(s, pg);
  709. k = kmap(s->map[0]->pages[0]);
  710. /* This depends on init having a text segment < 2M. */
  711. memmove(UINT2PTR(VA(k) + init_data_start - (UTZERO + BIGPGSZ)), init_data_out, sizeof(init_data_out));
  712. kunmap(k);
  713. ready(p);
  714. }
  715. void
  716. confinit(void)
  717. {
  718. int i;
  719. conf.npage = 0;
  720. for(i=0; i<nelem(conf.mem); i++)
  721. conf.npage += conf.mem[i].npage;
  722. conf.nproc = 1000;
  723. conf.nimage = 200;
  724. }
  725. static void
  726. shutdown(int ispanic)
  727. {
  728. int ms, once;
  729. lock(&active.l);
  730. if(ispanic)
  731. active.ispanic = ispanic;
  732. else if(machp()->machno == 0 && machp()->online == 0)
  733. active.ispanic = 0;
  734. once = machp()->online;
  735. machp()->online = 0;
  736. adec(&active.nonline);
  737. active.exiting = 1;
  738. unlock(&active.l);
  739. if(once)
  740. iprint("cpu%d: exiting\n", machp()->machno);
  741. spllo();
  742. for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
  743. delay(TK2MS(2));
  744. if(active.nonline == 0 && consactive() == 0)
  745. break;
  746. }
  747. if(active.ispanic && machp()->machno == 0){
  748. if(cpuserver)
  749. delay(30000);
  750. else
  751. for(;;)
  752. halt();
  753. }
  754. else
  755. delay(1000);
  756. }
  757. void
  758. reboot(void* v, void* w, int32_t i)
  759. {
  760. panic("reboot\n");
  761. }
  762. void
  763. exit(int ispanic)
  764. {
  765. shutdown(ispanic);
  766. archreset();
  767. }