main.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  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 "ureg.h"
  8. #include "init.h"
  9. #include "pool.h"
  10. Mach *m;
  11. Proc *up;
  12. Conf conf;
  13. int noprint;
  14. void
  15. main(void)
  16. {
  17. mmuinvalidate();
  18. /* zero out bss */
  19. memset(edata, 0, end-edata);
  20. /* point to Mach structure */
  21. m = (Mach*)MACHADDR;
  22. memset(m, 0, sizeof(Mach));
  23. m->ticks = 1;
  24. active.machs = 1;
  25. rs232power(1);
  26. quotefmtinstall();
  27. iprint("\nPlan 9 bitsy kernel\n");
  28. confinit();
  29. xinit();
  30. mmuinit();
  31. machinit();
  32. trapinit();
  33. sa1110_uartsetup(1);
  34. dmainit();
  35. screeninit();
  36. printinit(); /* from here on, print works, before this we need iprint */
  37. clockinit();
  38. procinit0();
  39. initseg();
  40. links();
  41. chandevreset();
  42. pageinit();
  43. swapinit();
  44. userinit();
  45. powerinit();
  46. schedinit();
  47. }
  48. /* need to do better */
  49. void
  50. reboot(void*, void*, ulong)
  51. {
  52. exit(0);
  53. }
  54. /*
  55. * exit kernel either on a panic or user request
  56. */
  57. void
  58. exit(int ispanic)
  59. {
  60. void (*f)(void);
  61. USED(ispanic);
  62. delay(1000);
  63. iprint("it's a wonderful day to die\n");
  64. cacheflush();
  65. mmuinvalidate();
  66. mmudisable();
  67. f = nil;
  68. (*f)();
  69. }
  70. static uchar *sp;
  71. /*
  72. * starting place for first process
  73. */
  74. void
  75. init0(void)
  76. {
  77. up->nerrlab = 0;
  78. spllo();
  79. /*
  80. * These are o.k. because rootinit is null.
  81. * Then early kproc's will have a root and dot.
  82. */
  83. up->slash = namec("#/", Atodir, 0, 0);
  84. pathclose(up->slash->path);
  85. up->slash->path = newpath("/");
  86. up->dot = cclone(up->slash);
  87. chandevinit();
  88. if(!waserror()){
  89. ksetenv("terminal", "bitsy", 0);
  90. ksetenv("cputype", "arm", 0);
  91. if(cpuserver)
  92. ksetenv("service", "cpu", 0);
  93. else
  94. ksetenv("service", "terminal", 0);
  95. poperror();
  96. }
  97. kproc("alarm", alarmkproc, 0);
  98. kproc("power", powerkproc, 0);
  99. touser(sp);
  100. }
  101. /*
  102. * pass boot arguments to /boot
  103. */
  104. static uchar *
  105. pusharg(char *p)
  106. {
  107. int n;
  108. n = strlen(p)+1;
  109. sp -= n;
  110. memmove(sp, p, n);
  111. return sp;
  112. }
  113. static void
  114. bootargs(ulong base)
  115. {
  116. int i, ac;
  117. uchar *av[32];
  118. uchar *bootpath;
  119. uchar **lsp;
  120. /*
  121. * the sizeof(Sargs) is to make the validaddr check in
  122. * trap.c's syscall() work even when we have less than the
  123. * max number of args.
  124. */
  125. sp = (uchar*)base + BY2PG - sizeof(Sargs);
  126. bootpath = pusharg("/boot/boot");
  127. ac = 0;
  128. av[ac++] = pusharg("boot");
  129. /* 4 byte word align stack */
  130. sp = (uchar*)((ulong)sp & ~3);
  131. /* build argc, argv on stack */
  132. sp -= (ac+1)*sizeof(sp);
  133. lsp = (uchar**)sp;
  134. for(i = 0; i < ac; i++)
  135. *lsp++ = av[i] + ((USTKTOP - BY2PG) - base);
  136. *lsp = 0;
  137. /* push argv onto stack */
  138. sp -= BY2WD;
  139. lsp = (uchar**)sp;
  140. *lsp = sp + BY2WD + ((USTKTOP - BY2PG) - base);
  141. /* push pointer to "/boot" */
  142. sp -= BY2WD;
  143. lsp = (uchar**)sp;
  144. *lsp = bootpath + ((USTKTOP - BY2PG) - base);
  145. /* leave space for where the initcode's caller's return PC would normally reside */
  146. sp -= BY2WD;
  147. /* relocate stack to user's virtual addresses */
  148. sp += (USTKTOP - BY2PG) - base;
  149. }
  150. /*
  151. * create the first process
  152. */
  153. void
  154. userinit(void)
  155. {
  156. Proc *p;
  157. Segment *s;
  158. KMap *k;
  159. Page *pg;
  160. /* no processes yet */
  161. up = nil;
  162. p = newproc();
  163. p->pgrp = newpgrp();
  164. p->egrp = smalloc(sizeof(Egrp));
  165. p->egrp->ref = 1;
  166. p->fgrp = dupfgrp(nil);
  167. p->rgrp = newrgrp();
  168. p->procmode = 0640;
  169. kstrdup(&eve, "");
  170. kstrdup(&p->text, "*init*");
  171. kstrdup(&p->user, eve);
  172. /*
  173. * Kernel Stack
  174. */
  175. p->sched.pc = (ulong)init0;
  176. p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD);
  177. /*
  178. * User Stack
  179. */
  180. s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
  181. p->seg[SSEG] = s;
  182. pg = newpage(1, 0, USTKTOP-BY2PG);
  183. segpage(s, pg);
  184. k = kmap(pg);
  185. bootargs(VA(k));
  186. kunmap(k);
  187. /*
  188. * Text
  189. */
  190. s = newseg(SG_TEXT, UTZERO, 1);
  191. p->seg[TSEG] = s;
  192. pg = newpage(1, 0, UTZERO);
  193. memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
  194. segpage(s, pg);
  195. k = kmap(s->map[0]->pages[0]);
  196. memmove((ulong*)VA(k), initcode, sizeof initcode);
  197. kunmap(k);
  198. ready(p);
  199. }
  200. /*
  201. * set mach dependent process state for a new process
  202. */
  203. void
  204. procsetup(Proc *p)
  205. {
  206. p->fpstate = FPinit;
  207. }
  208. /*
  209. * Save the mach dependent part of the process state.
  210. */
  211. void
  212. procsave(Proc *p)
  213. {
  214. USED(p);
  215. }
  216. /* place holder */
  217. /*
  218. * dummy since rdb is not included
  219. */
  220. void
  221. rdb(void)
  222. {
  223. }
  224. /*
  225. * probe the last location in a meg of memory, make sure it's not
  226. * reflected into something else we've already found.
  227. */
  228. int
  229. probemem(ulong addr)
  230. {
  231. ulong *p;
  232. ulong a;
  233. addr += OneMeg - sizeof(ulong);
  234. p = (ulong*)addr;
  235. *p = addr;
  236. for(a = conf.base0+OneMeg-sizeof(ulong); a < conf.npage0; a += OneMeg){
  237. p = (ulong*)a;
  238. *p = 0;
  239. }
  240. for(a = conf.base1+OneMeg-sizeof(ulong); a < conf.npage1; a += OneMeg){
  241. p = (ulong*)a;
  242. *p = 0;
  243. }
  244. p = (ulong*)addr;
  245. if(*p != addr)
  246. return -1;
  247. return 0;
  248. }
  249. /*
  250. * we assume that the kernel is at the beginning of one of the
  251. * contiguous chunks of memory.
  252. */
  253. void
  254. confinit(void)
  255. {
  256. int i;
  257. ulong addr;
  258. ulong ktop;
  259. /* find first two contiguous sections of available memory */
  260. addr = PHYSDRAM0;
  261. conf.base0 = conf.npage0 = addr;
  262. conf.base1 = conf.npage1 = addr;
  263. for(i = 0; i < 512; i++){
  264. if(probemem(addr) == 0)
  265. break;
  266. addr += OneMeg;
  267. }
  268. for(; i < 512; i++){
  269. if(probemem(addr) < 0)
  270. break;
  271. addr += OneMeg;
  272. conf.npage0 = addr;
  273. }
  274. conf.base1 = conf.npage1 = addr;
  275. for(; i < 512; i++){
  276. if(probemem(addr) == 0)
  277. break;
  278. addr += OneMeg;
  279. }
  280. for(; i < 512; i++){
  281. if(probemem(addr) < 0)
  282. break;
  283. addr += OneMeg;
  284. conf.npage1 = addr;
  285. }
  286. /* take kernel out of allocatable space */
  287. ktop = PGROUND((ulong)end);
  288. if(ktop >= conf.base0 && ktop <= conf.npage0)
  289. conf.base0 = ktop;
  290. else if(ktop >= conf.base1 && ktop <= conf.npage1)
  291. conf.base1 = ktop;
  292. else
  293. iprint("kernel not in allocatable space\n");
  294. /* zero memory */
  295. memset((void*)conf.base0, 0, conf.npage0 - conf.base0);
  296. memset((void*)conf.base1, 0, conf.npage1 - conf.base1);
  297. /* make npage the right thing */
  298. conf.npage0 = (conf.npage0 - conf.base0)/BY2PG;
  299. conf.npage1 = (conf.npage1 - conf.base1)/BY2PG;
  300. conf.npage = conf.npage0+conf.npage1;
  301. if(conf.npage > 16*MB/BY2PG){
  302. conf.upages = (conf.npage*60)/100;
  303. imagmem->minarena = 4*1024*1024;
  304. }else
  305. conf.upages = (conf.npage*40)/100;
  306. conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG;
  307. /* only one processor */
  308. conf.nmach = 1;
  309. /* set up other configuration parameters */
  310. conf.nproc = 100;
  311. conf.nswap = conf.npage*3;
  312. conf.nswppo = 4096;
  313. conf.nimage = 200;
  314. conf.monitor = 1;
  315. conf.copymode = 0; /* copy on write */
  316. }
  317. GPIOregs *gpioregs;
  318. ulong *egpioreg = (ulong*)EGPIOREGS;
  319. PPCregs *ppcregs;
  320. MemConfRegs *memconfregs;
  321. PowerRegs *powerregs;
  322. ResetRegs *resetregs;
  323. /*
  324. * configure the machine
  325. */
  326. void
  327. machinit(void)
  328. {
  329. /* set direction of SA1110 io pins and select alternate functions for some */
  330. gpioregs = mapspecial(GPIOREGS, sizeof(GPIOregs));
  331. gpioregs->direction =
  332. GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o
  333. |GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o
  334. |GPIO_CLK_SET0_o|GPIO_CLK_SET1_o
  335. |GPIO_L3_SDA_io|GPIO_L3_MODE_o|GPIO_L3_SCLK_o
  336. |GPIO_COM_RTS_o;
  337. gpioregs->rising = 0;
  338. gpioregs->falling = 0;
  339. gpioregs->altfunc |=
  340. GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o
  341. |GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o
  342. |GPIO_SSP_CLK_i;
  343. /* map in special H3650 io pins */
  344. egpioreg = mapspecial(EGPIOREGS, sizeof(ulong));
  345. /* map in peripheral pin controller (ssp will need it) */
  346. ppcregs = mapspecial(PPCREGS, sizeof(PPCregs));
  347. /* SA1110 power management */
  348. powerregs = mapspecial(POWERREGS, sizeof(PowerRegs));
  349. /* memory configuraton */
  350. memconfregs = mapspecial(MEMCONFREGS, sizeof(MemConfRegs));
  351. /* reset controller */
  352. resetregs = mapspecial(RESETREGS, sizeof(ResetRegs));
  353. }
  354. /*
  355. * manage egpio bits
  356. */
  357. static ulong egpiosticky;
  358. void
  359. egpiobits(ulong bits, int on)
  360. {
  361. if(on)
  362. egpiosticky |= bits;
  363. else
  364. egpiosticky &= ~bits;
  365. *egpioreg = egpiosticky;
  366. }
  367. void
  368. rs232power(int on)
  369. {
  370. egpiobits(EGPIO_rs232_power, on);
  371. delay(50);
  372. }
  373. void
  374. audioamppower(int on)
  375. {
  376. egpiobits(EGPIO_audio_power, on);
  377. delay(50);
  378. }
  379. void
  380. audioicpower(int on)
  381. {
  382. egpiobits(EGPIO_audio_ic_power, on);
  383. delay(50);
  384. }
  385. void
  386. irpower(int on)
  387. {
  388. egpiobits(EGPIO_ir_power, on);
  389. delay(50);
  390. }
  391. void
  392. lcdpower(int on)
  393. {
  394. egpiobits(EGPIO_lcd_3v|EGPIO_lcd_ic_power|EGPIO_lcd_5v|EGPIO_lcd_9v, on);
  395. delay(50);
  396. }
  397. void
  398. flashprogpower(int on)
  399. {
  400. egpiobits(EGPIO_prog_flash, on);
  401. }
  402. /* here on hardware reset */
  403. void
  404. resettrap(void)
  405. {
  406. }
  407. /*
  408. * for drivers that used to run on x86's
  409. */
  410. void
  411. outb(ulong a, uchar v)
  412. {
  413. *(uchar*)a = v;
  414. }
  415. void
  416. outs(ulong a, ushort v)
  417. {
  418. *(ushort*)a = v;
  419. }
  420. void
  421. outss(ulong a, void *p, int n)
  422. {
  423. ushort *sp = p;
  424. while(n-- > 0)
  425. *(ushort*)a = *sp++;
  426. }
  427. void
  428. outl(ulong a, ulong v)
  429. {
  430. *(ulong*)a = v;
  431. }
  432. uchar
  433. inb(ulong a)
  434. {
  435. return *(uchar*)a;
  436. }
  437. ushort
  438. ins(ulong a)
  439. {
  440. return *(ushort*)a;
  441. }
  442. void
  443. inss(ulong a, void *p, int n)
  444. {
  445. ushort *sp = p;
  446. while(n-- > 0)
  447. *sp++ = *(ushort*)a;
  448. }
  449. ulong
  450. inl(ulong a)
  451. {
  452. return *(ulong*)a;
  453. }
  454. char*
  455. getconf(char*)
  456. {
  457. return nil;
  458. }
  459. long
  460. _xdec(long *p)
  461. {
  462. int x;
  463. long v;
  464. x = splhi();
  465. v = --*p;
  466. splx(x);
  467. return v;
  468. }
  469. void
  470. _xinc(long *p)
  471. {
  472. int x;
  473. x = splhi();
  474. ++*p;
  475. splx(x);
  476. }