main.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "io.h"
  7. #include "init.h"
  8. #include "pool.h"
  9. Conf conf;
  10. FPsave initfp;
  11. void
  12. main(void)
  13. {
  14. memset(edata, 0, (ulong)end-(ulong)edata);
  15. conf.nmach = 1;
  16. machinit();
  17. ioinit();
  18. i8250console();
  19. quotefmtinstall();
  20. print("\nPlan 9\n");
  21. confinit();
  22. xinit();
  23. raveninit();
  24. trapinit();
  25. printinit();
  26. cpuidprint();
  27. mmuinit();
  28. hwintrinit();
  29. clockinit();
  30. kbdinit();
  31. procinit0();
  32. initseg();
  33. timersinit();
  34. links();
  35. chandevreset();
  36. pageinit();
  37. swapinit();
  38. fpsave(&initfp);
  39. initfp.fpscr = 0;
  40. userinit();
  41. schedinit();
  42. }
  43. void
  44. machinit(void)
  45. {
  46. memset(m, 0, sizeof(Mach));
  47. m->cputype = getpvr()>>16;
  48. /*
  49. * For polled uart output at boot, need
  50. * a default delay constant. 100000 should
  51. * be enough for a while. Cpuidentify will
  52. * calculate the real value later.
  53. */
  54. m->loopconst = 100000;
  55. /* turn on caches */
  56. puthid0(gethid0() | BIT(16) | BIT(17));
  57. active.machs = 1;
  58. active.exiting = 0;
  59. }
  60. void
  61. cpuidprint(void)
  62. {
  63. char *id;
  64. id = "unknown PowerPC";
  65. switch(m->cputype) {
  66. case 9:
  67. id = "PowerPC 604e";
  68. break;
  69. }
  70. print("cpu0: %s\n", id);
  71. }
  72. static struct
  73. {
  74. char *name;
  75. char *val;
  76. }
  77. plan9ini[] =
  78. {
  79. { "console", "0" },
  80. { "ether0", "type=2114x" },
  81. };
  82. char*
  83. getconf(char *name)
  84. {
  85. int i;
  86. for(i = 0; i < nelem(plan9ini); i++)
  87. if(cistrcmp(name, plan9ini[i].name) == 0)
  88. return plan9ini[i].val;
  89. return nil;
  90. }
  91. void
  92. init0(void)
  93. {
  94. // char **p, *q, name[KNAMELEN];
  95. // int n;
  96. char buf[2*KNAMELEN];
  97. up->nerrlab = 0;
  98. spllo();
  99. /*
  100. * These are o.k. because rootinit is null.
  101. * Then early kproc's will have a root and dot.
  102. */
  103. up->slash = namec("#/", Atodir, 0, 0);
  104. pathclose(up->slash->path);
  105. up->slash->path = newpath("/");
  106. up->dot = cclone(up->slash);
  107. chandevinit();
  108. if(!waserror()){
  109. snprint(buf, sizeof(buf), "power %s mtx", conffile);
  110. ksetenv("terminal", buf, 0);
  111. ksetenv("cputype", "power", 0);
  112. if(cpuserver)
  113. ksetenv("service", "cpu", 0);
  114. else
  115. ksetenv("service", "terminal", 0);
  116. /*
  117. for(p = confenv; *p; p++) {
  118. q = strchr(p[0], '=');
  119. if(q == 0)
  120. continue;
  121. n = q-p[0];
  122. if(n >= KNAMELEN)
  123. n = KNAMELEN-1;
  124. memmove(name, p[0], n);
  125. name[n] = 0;
  126. if(name[0] != '*')
  127. ksetenv(name, q+1, 0);
  128. ksetenv(name, q+1, 1);
  129. }
  130. */
  131. poperror();
  132. }
  133. kproc("alarm", alarmkproc, 0);
  134. kproc("mmusweep", mmusweep, 0);
  135. touser((void*)(USTKTOP-8));
  136. }
  137. void
  138. userinit(void)
  139. {
  140. Proc *p;
  141. Segment *s;
  142. KMap *k;
  143. Page *pg;
  144. p = newproc();
  145. p->pgrp = newpgrp();
  146. p->egrp = smalloc(sizeof(Egrp));
  147. p->egrp->ref = 1;
  148. p->fgrp = dupfgrp(nil);
  149. p->rgrp = newrgrp();
  150. p->procmode = 0640;
  151. kstrdup(&eve, "");
  152. kstrdup(&p->text, "*init*");
  153. kstrdup(&p->user, eve);
  154. p->fpstate = FPinit;
  155. /*
  156. * Kernel Stack
  157. *
  158. * N.B. The -12 for the stack pointer is important.
  159. * 4 bytes for gotolabel's return PC
  160. */
  161. p->sched.pc = (ulong)init0;
  162. p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD);
  163. /*
  164. * User Stack
  165. */
  166. s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
  167. p->seg[SSEG] = s;
  168. pg = newpage(1, 0, USTKTOP-BY2PG);
  169. segpage(s, pg);
  170. /*
  171. * Text
  172. */
  173. s = newseg(SG_TEXT, UTZERO, 1);
  174. s->flushme++;
  175. p->seg[TSEG] = s;
  176. pg = newpage(1, 0, UTZERO);
  177. memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
  178. segpage(s, pg);
  179. k = kmap(s->map[0]->pages[0]);
  180. memmove((ulong*)VA(k), initcode, sizeof initcode);
  181. kunmap(k);
  182. ready(p);
  183. }
  184. /* still to do */
  185. void
  186. reboot(void*, void*, ulong)
  187. {
  188. exit(0);
  189. }
  190. void
  191. exit(int ispanic)
  192. {
  193. int ms, once;
  194. lock(&active);
  195. if(ispanic)
  196. active.ispanic = ispanic;
  197. else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
  198. active.ispanic = 0;
  199. once = active.machs & (1<<m->machno);
  200. active.machs &= ~(1<<m->machno);
  201. active.exiting = 1;
  202. unlock(&active);
  203. if(once)
  204. print("cpu%d: exiting\n", m->machno);
  205. spllo();
  206. for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
  207. delay(TK2MS(2));
  208. if(active.machs == 0 && consactive() == 0)
  209. break;
  210. }
  211. if(active.ispanic && m->machno == 0){
  212. if(cpuserver)
  213. delay(10000);
  214. else if(conf.monitor)
  215. for(;;);
  216. }
  217. else
  218. delay(1000);
  219. watchreset();
  220. }
  221. /*
  222. * set up floating point for a new process
  223. */
  224. void
  225. procsetup(Proc *p)
  226. {
  227. p->fpstate = FPinit;
  228. }
  229. /*
  230. * Save the mach dependent part of the process state.
  231. */
  232. void
  233. procsave(Proc *p)
  234. {
  235. if(p->fpstate == FPactive){
  236. if(p->state != Moribund)
  237. fpsave(&up->fpsave);
  238. p->fpstate = FPinactive;
  239. }
  240. }
  241. void
  242. confinit(void)
  243. {
  244. char *p;
  245. int userpcnt;
  246. ulong pa, kpages;
  247. extern ulong memsize; /* passed in from ROM monitor */
  248. if(p = getconf("*kernelpercent"))
  249. userpcnt = 100 - strtol(p, 0, 0);
  250. else
  251. userpcnt = 0;
  252. pa = PGROUND(PADDR(end));
  253. conf.mem[0].npage = memsize/BY2PG;
  254. conf.mem[0].base = pa;
  255. conf.npage = conf.mem[0].npage;
  256. conf.nmach = 1;
  257. conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
  258. if(cpuserver)
  259. conf.nproc *= 3;
  260. if(conf.nproc > 2000)
  261. conf.nproc = 2000;
  262. conf.nimage = 200;
  263. conf.nswap = conf.nproc*80;
  264. conf.nswppo = 4096;
  265. conf.copymode = 0; /* copy on write */
  266. if(cpuserver) {
  267. if(userpcnt < 10)
  268. userpcnt = 70;
  269. kpages = conf.npage - (conf.npage*userpcnt)/100;
  270. /*
  271. * Hack for the big boys. Only good while physmem < 4GB.
  272. * Give the kernel a max. of 16MB + enough to allocate the
  273. * page pool.
  274. * This is an overestimate as conf.upages < conf.npages.
  275. * The patch of nimage is a band-aid, scanning the whole
  276. * page list in imagereclaim just takes too long.
  277. */
  278. if(kpages > (16*MB + conf.npage*sizeof(Page))/BY2PG){
  279. kpages = (16*MB + conf.npage*sizeof(Page))/BY2PG;
  280. conf.nimage = 2000;
  281. kpages += (conf.nproc*KSTACK)/BY2PG;
  282. }
  283. } else {
  284. if(userpcnt < 10) {
  285. if(conf.npage*BY2PG < 16*MB)
  286. userpcnt = 40;
  287. else
  288. userpcnt = 60;
  289. }
  290. kpages = conf.npage - (conf.npage*userpcnt)/100;
  291. /*
  292. * Make sure terminals with low memory get at least
  293. * 4MB on the first Image chunk allocation.
  294. */
  295. if(conf.npage*BY2PG < 16*MB)
  296. imagmem->minarena = 4*1024*1024;
  297. }
  298. conf.upages = conf.npage - kpages;
  299. conf.ialloc = (kpages/2)*BY2PG;
  300. /*
  301. * Guess how much is taken by the large permanent
  302. * datastructures. Mntcache and Mntrpc are not accounted for
  303. * (probably ~300KB).
  304. */
  305. kpages *= BY2PG;
  306. kpages -= conf.upages*sizeof(Page)
  307. + conf.nproc*sizeof(Proc)
  308. + conf.nimage*sizeof(Image)
  309. + conf.nswap
  310. + conf.nswppo*sizeof(Page);
  311. mainmem->maxsize = kpages;
  312. if(!cpuserver){
  313. /*
  314. * give terminals lots of image memory, too; the dynamic
  315. * allocation will balance the load properly, hopefully.
  316. * be careful with 32-bit overflow.
  317. */
  318. imagmem->maxsize = kpages;
  319. }
  320. // conf.monitor = 1; /* BUG */
  321. }
  322. static int
  323. getcfields(char* lp, char** fields, int n, char* sep)
  324. {
  325. int i;
  326. for(i = 0; lp && *lp && i < n; i++){
  327. while(*lp && strchr(sep, *lp) != 0)
  328. *lp++ = 0;
  329. if(*lp == 0)
  330. break;
  331. fields[i] = lp;
  332. while(*lp && strchr(sep, *lp) == 0){
  333. if(*lp == '\\' && *(lp+1) == '\n')
  334. *lp++ = ' ';
  335. lp++;
  336. }
  337. }
  338. return i;
  339. }
  340. int
  341. isaconfig(char *class, int ctlrno, ISAConf *isa)
  342. {
  343. int i;
  344. char cc[KNAMELEN], *p;
  345. sprint(cc, "%s%d", class, ctlrno);
  346. p = getconf(cc);
  347. if(p == 0)
  348. return 0;
  349. isa->nopt = tokenize(p, isa->opt, NISAOPT);
  350. for(i = 0; i < isa->nopt; i++){
  351. p = isa->opt[i];
  352. if(cistrncmp(p, "type=", 5) == 0)
  353. isa->type = p + 5;
  354. else if(cistrncmp(p, "port=", 5) == 0)
  355. isa->port = strtoul(p+5, &p, 0);
  356. else if(cistrncmp(p, "irq=", 4) == 0)
  357. isa->irq = strtoul(p+4, &p, 0);
  358. else if(cistrncmp(p, "dma=", 4) == 0)
  359. isa->dma = strtoul(p+4, &p, 0);
  360. else if(cistrncmp(p, "mem=", 4) == 0)
  361. isa->mem = strtoul(p+4, &p, 0);
  362. else if(cistrncmp(p, "size=", 5) == 0)
  363. isa->size = strtoul(p+5, &p, 0);
  364. else if(cistrncmp(p, "freq=", 5) == 0)
  365. isa->freq = strtoul(p+5, &p, 0);
  366. }
  367. return 1;
  368. }
  369. int
  370. cistrcmp(char *a, char *b)
  371. {
  372. int ac, bc;
  373. for(;;){
  374. ac = *a++;
  375. bc = *b++;
  376. if(ac >= 'A' && ac <= 'Z')
  377. ac = 'a' + (ac - 'A');
  378. if(bc >= 'A' && bc <= 'Z')
  379. bc = 'a' + (bc - 'A');
  380. ac -= bc;
  381. if(ac)
  382. return ac;
  383. if(bc == 0)
  384. break;
  385. }
  386. return 0;
  387. }
  388. int
  389. cistrncmp(char *a, char *b, int n)
  390. {
  391. unsigned ac, bc;
  392. while(n > 0){
  393. ac = *a++;
  394. bc = *b++;
  395. n--;
  396. if(ac >= 'A' && ac <= 'Z')
  397. ac = 'a' + (ac - 'A');
  398. if(bc >= 'A' && bc <= 'Z')
  399. bc = 'a' + (bc - 'A');
  400. ac -= bc;
  401. if(ac)
  402. return ac;
  403. if(bc == 0)
  404. break;
  405. }
  406. return 0;
  407. }