main.c 18 KB

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