main.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  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. int i;
  232. ulong *p;
  233. ulong a;
  234. addr += OneMeg - sizeof(ulong);
  235. p = (ulong*)addr;
  236. *p = addr;
  237. for(i=0; i<nelem(conf.mem); i++){
  238. for(a = conf.mem[i].base+OneMeg-sizeof(ulong); a < conf.mem[i].limit; a += OneMeg){
  239. p = (ulong*)a;
  240. *p = 0;
  241. }
  242. }
  243. p = (ulong*)addr;
  244. if(*p != addr)
  245. return -1;
  246. return 0;
  247. }
  248. /*
  249. * we assume that the kernel is at the beginning of one of the
  250. * contiguous chunks of memory.
  251. */
  252. void
  253. confinit(void)
  254. {
  255. int i, j;
  256. ulong addr;
  257. ulong ktop;
  258. /* find first two contiguous sections of available memory */
  259. addr = PHYSDRAM0;
  260. for(i=0; i<nelem(conf.mem); i++){
  261. conf.mem[i].base = addr;
  262. conf.mem[i].limit = addr;
  263. }
  264. for(j=0; j<nelem(conf.mem); j++){
  265. conf.mem[j].base = addr;
  266. conf.mem[j].limit = addr;
  267. for(i = 0; i < 512; i++){
  268. if(probemem(addr) == 0)
  269. break;
  270. addr += OneMeg;
  271. }
  272. for(; i < 512; i++){
  273. if(probemem(addr) < 0)
  274. break;
  275. addr += OneMeg;
  276. conf.mem[j].limit = addr;
  277. }
  278. }
  279. conf.npage = 0;
  280. for(i=0; i<nelem(conf.mem); i++){
  281. /* take kernel out of allocatable space */
  282. ktop = PGROUND((ulong)end);
  283. if(ktop >= conf.mem[i].base && ktop <= conf.mem[i].limit)
  284. conf.mem[i].base = ktop;
  285. /* zero memory */
  286. memset((void*)conf.mem[i].base, 0, conf.mem[i].limit - conf.mem[i].base);
  287. conf.mem[i].npage = (conf.mem[i].limit - conf.mem[i].base)/BY2PG;
  288. conf.npage += conf.mem[i].npage;
  289. }
  290. if(conf.npage > 16*MB/BY2PG){
  291. conf.upages = (conf.npage*60)/100;
  292. imagmem->minarena = 4*1024*1024;
  293. }else
  294. conf.upages = (conf.npage*40)/100;
  295. conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG;
  296. /* only one processor */
  297. conf.nmach = 1;
  298. /* set up other configuration parameters */
  299. conf.nproc = 100;
  300. conf.nswap = conf.npage*3;
  301. conf.nswppo = 4096;
  302. conf.nimage = 200;
  303. conf.monitor = 1;
  304. conf.copymode = 0; /* copy on write */
  305. }
  306. GPIOregs *gpioregs;
  307. ulong *egpioreg = (ulong*)EGPIOREGS;
  308. PPCregs *ppcregs;
  309. MemConfRegs *memconfregs;
  310. PowerRegs *powerregs;
  311. ResetRegs *resetregs;
  312. /*
  313. * configure the machine
  314. */
  315. void
  316. machinit(void)
  317. {
  318. /* set direction of SA1110 io pins and select alternate functions for some */
  319. gpioregs = mapspecial(GPIOREGS, sizeof(GPIOregs));
  320. gpioregs->direction =
  321. GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o
  322. |GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o
  323. |GPIO_CLK_SET0_o|GPIO_CLK_SET1_o
  324. |GPIO_L3_SDA_io|GPIO_L3_MODE_o|GPIO_L3_SCLK_o
  325. |GPIO_COM_RTS_o;
  326. gpioregs->rising = 0;
  327. gpioregs->falling = 0;
  328. gpioregs->altfunc |=
  329. GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o
  330. |GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o
  331. |GPIO_SSP_CLK_i;
  332. /* map in special H3650 io pins */
  333. egpioreg = mapspecial(EGPIOREGS, sizeof(ulong));
  334. /* map in peripheral pin controller (ssp will need it) */
  335. ppcregs = mapspecial(PPCREGS, sizeof(PPCregs));
  336. /* SA1110 power management */
  337. powerregs = mapspecial(POWERREGS, sizeof(PowerRegs));
  338. /* memory configuraton */
  339. memconfregs = mapspecial(MEMCONFREGS, sizeof(MemConfRegs));
  340. /* reset controller */
  341. resetregs = mapspecial(RESETREGS, sizeof(ResetRegs));
  342. }
  343. /*
  344. * manage egpio bits
  345. */
  346. static ulong egpiosticky;
  347. void
  348. egpiobits(ulong bits, int on)
  349. {
  350. if(on)
  351. egpiosticky |= bits;
  352. else
  353. egpiosticky &= ~bits;
  354. *egpioreg = egpiosticky;
  355. }
  356. void
  357. rs232power(int on)
  358. {
  359. egpiobits(EGPIO_rs232_power, on);
  360. delay(50);
  361. }
  362. void
  363. audioamppower(int on)
  364. {
  365. egpiobits(EGPIO_audio_power, on);
  366. delay(50);
  367. }
  368. void
  369. audioicpower(int on)
  370. {
  371. egpiobits(EGPIO_audio_ic_power, on);
  372. delay(50);
  373. }
  374. void
  375. irpower(int on)
  376. {
  377. egpiobits(EGPIO_ir_power, on);
  378. delay(50);
  379. }
  380. void
  381. lcdpower(int on)
  382. {
  383. egpiobits(EGPIO_lcd_3v|EGPIO_lcd_ic_power|EGPIO_lcd_5v|EGPIO_lcd_9v, on);
  384. delay(50);
  385. }
  386. void
  387. flashprogpower(int on)
  388. {
  389. egpiobits(EGPIO_prog_flash, on);
  390. }
  391. /* here on hardware reset */
  392. void
  393. resettrap(void)
  394. {
  395. }
  396. /*
  397. * for drivers that used to run on x86's
  398. */
  399. void
  400. outb(ulong a, uchar v)
  401. {
  402. *(uchar*)a = v;
  403. }
  404. void
  405. outs(ulong a, ushort v)
  406. {
  407. *(ushort*)a = v;
  408. }
  409. void
  410. outss(ulong a, void *p, int n)
  411. {
  412. ushort *sp = p;
  413. while(n-- > 0)
  414. *(ushort*)a = *sp++;
  415. }
  416. void
  417. outl(ulong a, ulong v)
  418. {
  419. *(ulong*)a = v;
  420. }
  421. uchar
  422. inb(ulong a)
  423. {
  424. return *(uchar*)a;
  425. }
  426. ushort
  427. ins(ulong a)
  428. {
  429. return *(ushort*)a;
  430. }
  431. void
  432. inss(ulong a, void *p, int n)
  433. {
  434. ushort *sp = p;
  435. while(n-- > 0)
  436. *sp++ = *(ushort*)a;
  437. }
  438. ulong
  439. inl(ulong a)
  440. {
  441. return *(ulong*)a;
  442. }
  443. char*
  444. getconf(char*)
  445. {
  446. return nil;
  447. }
  448. long
  449. _xdec(long *p)
  450. {
  451. int s;
  452. long v;
  453. s = splhi();
  454. v = --*p;
  455. splx(s);
  456. return v;
  457. }
  458. void
  459. _xinc(long *p)
  460. {
  461. int s;
  462. s = splhi();
  463. ++*p;
  464. splx(s);
  465. }
  466. int
  467. cmpswap(long *addr, long old, long new)
  468. {
  469. int r, s;
  470. s = splhi();
  471. if(r = (*addr==old))
  472. *addr = new;
  473. splx(s);
  474. return r;
  475. }