main.c 18 KB

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