archtegra.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. /*
  2. * nvidia tegra 2 architecture-specific stuff
  3. */
  4. #include "u.h"
  5. #include "../port/lib.h"
  6. #include "mem.h"
  7. #include "dat.h"
  8. #include "fns.h"
  9. #include "../port/error.h"
  10. #include "io.h"
  11. #include "arm.h"
  12. #include "../port/netif.h"
  13. #include "etherif.h"
  14. #include "../port/flashif.h"
  15. #include "../port/usb.h"
  16. #include "../port/portusbehci.h"
  17. #include "usbehci.h"
  18. enum {
  19. /* hardware limits imposed by register contents or layouts */
  20. Maxcpus = 4,
  21. Maxflowcpus = 2,
  22. Debug = 0,
  23. };
  24. typedef struct Clkrst Clkrst;
  25. typedef struct Diag Diag;
  26. typedef struct Flow Flow;
  27. typedef struct Scu Scu;
  28. typedef struct Power Power;
  29. struct Clkrst {
  30. ulong rstsrc;
  31. ulong rstdevl;
  32. ulong rstdevh;
  33. ulong rstdevu;
  34. ulong clkoutl;
  35. ulong clkouth;
  36. ulong clkoutu;
  37. uchar _pad0[0x24-0x1c];
  38. ulong supcclkdiv; /* super cclk divider */
  39. ulong _pad1;
  40. ulong supsclkdiv; /* super sclk divider */
  41. uchar _pad4[0x4c-0x30];
  42. ulong clkcpu;
  43. uchar _pad1[0xe0-0x50];
  44. ulong pllxbase; /* pllx controls CPU clock speed */
  45. ulong pllxmisc;
  46. ulong pllebase; /* plle is dedicated to pcie */
  47. ulong pllemisc;
  48. uchar _pad2[0x340-0xf0];
  49. ulong cpuset;
  50. ulong cpuclr;
  51. };
  52. enum {
  53. /* rstsrc bits */
  54. Wdcpurst = 1<<0,
  55. Wdcoprst = 1<<1,
  56. Wdsysrst = 1<<2,
  57. Wdsel = 1<<4, /* tmr1 or tmr2? */
  58. Wdena = 1<<5,
  59. /* devl bits */
  60. Sysreset = 1<<2,
  61. /* clkcpu bits */
  62. Cpu1stop = 1<<9,
  63. Cpu0stop = 1<<8,
  64. /* cpu* bits */
  65. Cpu1dbgreset = 1<<13,
  66. Cpu0dbgreset = 1<<12,
  67. Cpu1wdreset = 1<<9,
  68. Cpu0wdreset = 1<<8,
  69. Cpu1dereset = 1<<5,
  70. Cpu0dereset = 1<<4,
  71. Cpu1reset = 1<<1,
  72. Cpu0reset = 1<<0,
  73. };
  74. struct Power {
  75. ulong ctl; /* mainly for rtc clock signals */
  76. ulong secregdis;
  77. ulong swrst;
  78. ulong wakevmask;
  79. ulong waklvl;
  80. ulong waksts;
  81. ulong swwaksts;
  82. ulong dpdpadsovr; /* deep power down pads override */
  83. ulong dpdsample;
  84. ulong dpden;
  85. ulong gatetimroff;
  86. ulong gatetimron;
  87. ulong toggle;
  88. ulong unclamp;
  89. ulong gatests; /* ro */
  90. ulong goodtmr;
  91. ulong blinktmr;
  92. ulong noiopwr;
  93. ulong detect;
  94. ulong detlatch;
  95. ulong scratch[24];
  96. ulong secscratch[6];
  97. ulong cpupwrgoodtmr;
  98. ulong cpupwrofftmr;
  99. ulong pgmask[2];
  100. ulong autowaklvl;
  101. ulong autowaklvlmask;
  102. ulong wakdelay;
  103. ulong detval;
  104. ulong ddr;
  105. ulong usbdebdel; /* usb de-bounce delay */
  106. ulong usbao;
  107. ulong cryptoop;
  108. ulong pllpwb0ovr;
  109. ulong scratch24[42-24+1];
  110. ulong boundoutmirr[3];
  111. ulong sys33ven;
  112. ulong boundoutmirracc;
  113. ulong gate;
  114. };
  115. enum {
  116. /* toggle bits */
  117. Start = 1<<8,
  118. /* partition ids */
  119. Partpcie= 3,
  120. Partl2 = 4,
  121. };
  122. struct Scu {
  123. ulong ctl;
  124. ulong cfg; /* ro */
  125. ulong cpupwrsts;
  126. ulong inval;
  127. uchar _pad0[0x40-0x10];
  128. ulong filtstart;
  129. ulong filtend;
  130. uchar _pad1[0x50-0x48];
  131. ulong accctl; /* initially 0 */
  132. ulong nsaccctl;
  133. };
  134. enum {
  135. /* ctl bits */
  136. Scuenable = 1<<0,
  137. Filter = 1<<1,
  138. Scuparity = 1<<2,
  139. Specfill = 1<<3, /* only for PL310 */
  140. Allport0 = 1<<4,
  141. Standby = 1<<5,
  142. Icstandby = 1<<6,
  143. };
  144. struct Flow {
  145. ulong haltcpu0;
  146. ulong haltcop;
  147. ulong cpu0;
  148. ulong cop;
  149. ulong xrq;
  150. ulong haltcpu1;
  151. ulong cpu1;
  152. };
  153. enum {
  154. /* haltcpu* bits */
  155. Stop = 2<<29,
  156. /* cpu* bits */
  157. Event = 1<<14, /* w1c */
  158. Waitwfebitsshift = 4,
  159. Waitwfebitsmask = MASK(2),
  160. Eventenable = 1<<1,
  161. Cpuenable = 1<<0,
  162. };
  163. struct Diag {
  164. Cacheline c0;
  165. Lock;
  166. long cnt;
  167. long sync;
  168. Cacheline c1;
  169. };
  170. extern ulong testmem;
  171. /*
  172. * number of cpus available. contrast with conf.nmach, which is number
  173. * of running cpus.
  174. */
  175. int navailcpus;
  176. Isolated l1ptstable;
  177. Soc soc = {
  178. .clkrst = 0x60006000, /* clock & reset signals */
  179. .power = 0x7000e400,
  180. .exceptvec = PHYSEVP, /* undocumented magic */
  181. .sema = 0x60001000,
  182. .l2cache= PHYSL2BAG, /* pl310 bag on the side */
  183. .flow = 0x60007000,
  184. /* 4 non-gic controllers */
  185. // .intr = { 0x60004000, 0x60004100, 0x60004200, 0x60004300, },
  186. /* private memory region */
  187. .scu = 0x50040000,
  188. /* we got this address from the `cortex-a series programmer's guide'. */
  189. .intr = 0x50040100, /* per-cpu interface */
  190. .glbtmr = 0x50040200,
  191. .loctmr = 0x50040600,
  192. .intrdist=0x50041000,
  193. .uart = { 0x70006000, 0x70006040,
  194. 0x70006200, 0x70006300, 0x70006400, },
  195. .rtc = 0x7000e000,
  196. .tmr = { 0x60005000, 0x60005008, 0x60005050, 0x60005058, },
  197. .µs = 0x60005010,
  198. .pci = 0x80000000,
  199. .ether = 0xa0024000,
  200. .nand = 0x70008000,
  201. .nor = 0x70009000, /* also VIRTNOR */
  202. .ehci = P2VAHB(0xc5000000), /* 1st of 3 */
  203. .ide = P2VAHB(0xc3000000),
  204. .gpio = { 0x6000d000, 0x6000d080, 0x6000d100, 0x6000d180,
  205. 0x6000d200, 0x6000d280, 0x6000d300, },
  206. .spi = { 0x7000d400, 0x7000d600, 0x7000d800, 0x7000da00, },
  207. .twsi = 0x7000c000,
  208. .mmc = { P2VAHB(0xc8000000), P2VAHB(0xc8000200),
  209. P2VAHB(0xc8000400), P2VAHB(0xc8000600), },
  210. };
  211. static volatile Diag diag;
  212. static int missed;
  213. void
  214. dumpcpuclks(void) /* run CPU at full speed */
  215. {
  216. Clkrst *clk = (Clkrst *)soc.clkrst;
  217. iprint("pllx base %#lux misc %#lux\n", clk->pllxbase, clk->pllxmisc);
  218. iprint("plle base %#lux misc %#lux\n", clk->pllebase, clk->pllemisc);
  219. iprint("super cclk divider %#lux\n", clk->supcclkdiv);
  220. iprint("super sclk divider %#lux\n", clk->supsclkdiv);
  221. }
  222. static char *
  223. devidstr(ulong)
  224. {
  225. return "ARM Cortex-A9";
  226. }
  227. void
  228. archtegralink(void)
  229. {
  230. }
  231. /* convert AddrDevid register to a string in buf and return buf */
  232. char *
  233. cputype2name(char *buf, int size)
  234. {
  235. ulong r;
  236. r = cpidget(); /* main id register */
  237. assert((r >> 24) == 'A');
  238. seprint(buf, buf + size, "Cortex-A9 r%ldp%ld",
  239. (r >> 20) & MASK(4), r & MASK(4));
  240. return buf;
  241. }
  242. static void
  243. errata(void)
  244. {
  245. ulong reg, r, p;
  246. /* apply cortex-a9 errata workarounds */
  247. r = cpidget(); /* main id register */
  248. assert((r >> 24) == 'A');
  249. p = r & MASK(4); /* minor revision */
  250. r >>= 20;
  251. r &= MASK(4); /* major revision */
  252. /* this is an undocumented `diagnostic register' that linux knows */
  253. reg = cprdsc(0, CpDTLB, 0, 1);
  254. if (r < 2 || r == 2 && p <= 2)
  255. reg |= 1<<4; /* 742230 */
  256. if (r == 2 && p <= 2)
  257. reg |= 1<<6 | 1<<12 | 1<<22; /* 743622, 2×742231 */
  258. if (r < 3)
  259. reg |= 1<<11; /* 751472 */
  260. cpwrsc(0, CpDTLB, 0, 1, reg);
  261. }
  262. void
  263. archconfinit(void)
  264. {
  265. char *p;
  266. ulong hz;
  267. assert(m != nil);
  268. m->cpuhz = 1000 * Mhz; /* trimslice speed */
  269. p = getconf("*cpumhz");
  270. if (p) {
  271. hz = atoi(p) * Mhz;
  272. if (hz >= 100*Mhz && hz <= 3600UL*Mhz)
  273. m->cpuhz = hz;
  274. }
  275. m->delayloop = m->cpuhz/2000; /* initial estimate */
  276. errata();
  277. }
  278. int
  279. archether(unsigned ctlrno, Ether *ether)
  280. {
  281. switch(ctlrno) {
  282. case 0:
  283. ether->type = "rtl8169"; /* pci-e ether */
  284. ether->ctlrno = ctlrno;
  285. ether->irq = Pcieirq; /* non-msi pci-e intr */
  286. ether->nopt = 0;
  287. ether->mbps = 1000;
  288. return 1;
  289. }
  290. return -1;
  291. }
  292. void
  293. dumpscustate(void)
  294. {
  295. Scu *scu = (Scu *)soc.scu;
  296. print("cpu%d scu: accctl %#lux\n", m->machno, scu->accctl);
  297. print("cpu%d scu: smp cpu bit map %#lo for %ld cpus; ", m->machno,
  298. (scu->cfg >> 4) & MASK(4), (scu->cfg & MASK(2)) + 1);
  299. print("cpus' power %#lux\n", scu->cpupwrsts);
  300. }
  301. void
  302. scuon(void)
  303. {
  304. Scu *scu = (Scu *)soc.scu;
  305. if (scu->ctl & Scuenable)
  306. return;
  307. scu->inval = MASK(16);
  308. coherence();
  309. scu->ctl = Scuparity | Scuenable | Specfill;
  310. coherence();
  311. }
  312. int
  313. getncpus(void)
  314. {
  315. int n;
  316. char *p;
  317. Scu *scu;
  318. if (navailcpus == 0) {
  319. scu = (Scu *)soc.scu;
  320. navailcpus = (scu->cfg & MASK(2)) + 1;
  321. if (navailcpus > MAXMACH)
  322. navailcpus = MAXMACH;
  323. p = getconf("*ncpu");
  324. if (p && *p) {
  325. n = atoi(p);
  326. if (n > 0 && n < navailcpus)
  327. navailcpus = n;
  328. }
  329. }
  330. return navailcpus;
  331. }
  332. void
  333. cpuidprint(void)
  334. {
  335. char name[64];
  336. cputype2name(name, sizeof name);
  337. delay(50); /* let uart catch up */
  338. iprint("cpu%d: %lldMHz ARM %s %s-endian\n",
  339. m->machno, m->cpuhz / Mhz, name,
  340. getpsr() & PsrBigend? "big": "little");
  341. }
  342. static void
  343. clockson(void)
  344. {
  345. Clkrst *clk = (Clkrst *)soc.clkrst;
  346. /* enable all by clearing resets */
  347. clk->rstdevl = clk->rstdevh = clk->rstdevu = 0;
  348. coherence();
  349. clk->clkoutl = clk->clkouth = clk->clkoutu = ~0; /* enable all clocks */
  350. coherence();
  351. clk->rstsrc = Wdcpurst | Wdcoprst | Wdsysrst | Wdena;
  352. coherence();
  353. }
  354. /* we could be shutting down ourself (if cpu == m->machno), so take care. */
  355. void
  356. stopcpu(uint cpu)
  357. {
  358. Flow *flow = (Flow *)soc.flow;
  359. Clkrst *clk = (Clkrst *)soc.clkrst;
  360. if (cpu == 0) {
  361. iprint("stopcpu: may not stop cpu0\n");
  362. return;
  363. }
  364. machoff(cpu);
  365. lock(&active);
  366. active.stopped |= 1 << cpu;
  367. unlock(&active);
  368. l1cache->wb();
  369. /* shut down arm7 avp coproc so it can't cause mischief. */
  370. /* could try watchdog without stopping avp. */
  371. flow->haltcop = Stop;
  372. coherence();
  373. flow->cop = 0; /* no Cpuenable */
  374. coherence();
  375. delay(10);
  376. assert(cpu < Maxflowcpus);
  377. *(cpu == 0? &flow->haltcpu0: &flow->haltcpu1) = Stop;
  378. coherence();
  379. *(cpu == 0? &flow->cpu0: &flow->cpu1) = 0; /* no Cpuenable */
  380. coherence();
  381. delay(10);
  382. /* cold reset */
  383. assert(cpu < Maxcpus);
  384. clk->cpuset = (Cpu0reset | Cpu0dbgreset | Cpu0dereset) << cpu;
  385. coherence();
  386. delay(1);
  387. l1cache->wb();
  388. }
  389. static void
  390. synccpus(volatile long *cntp, int n)
  391. {
  392. ainc(cntp);
  393. while (*cntp < n)
  394. ;
  395. /* all cpus should now be here */
  396. }
  397. static void
  398. pass1(int pass, volatile Diag *dp)
  399. {
  400. int i;
  401. if(m->machno == 0)
  402. iprint(" %d", pass);
  403. for (i = 1000*1000; --i > 0; ) {
  404. ainc(&dp->cnt);
  405. adec(&dp->cnt);
  406. }
  407. synccpus(&dp->sync, navailcpus);
  408. /* all cpus are now here */
  409. ilock(dp);
  410. if(dp->cnt != 0)
  411. panic("cpu%d: diag: failed w count %ld", m->machno, dp->cnt);
  412. iunlock(dp);
  413. synccpus(&dp->sync, 2 * navailcpus);
  414. /* all cpus are now here */
  415. adec(&dp->sync);
  416. adec(&dp->sync);
  417. }
  418. /*
  419. * try to confirm coherence of l1 caches.
  420. * assume that all available cpus will be started.
  421. */
  422. void
  423. l1diag(void)
  424. {
  425. int pass;
  426. volatile Diag *dp;
  427. if (!Debug)
  428. return;
  429. l1cache->wb();
  430. /*
  431. * synchronise and print
  432. */
  433. dp = &diag;
  434. ilock(dp);
  435. if (m->machno == 0)
  436. iprint("l1: waiting for %d cpus... ", navailcpus);
  437. iunlock(dp);
  438. synccpus(&dp->sync, navailcpus);
  439. ilock(dp);
  440. if (m->machno == 0)
  441. iprint("cache coherency pass");
  442. iunlock(dp);
  443. synccpus(&dp->sync, 2 * navailcpus);
  444. adec(&dp->sync);
  445. adec(&dp->sync);
  446. /*
  447. * cpus contend
  448. */
  449. for (pass = 0; pass < 3; pass++)
  450. pass1(pass, dp);
  451. /*
  452. * synchronise and check sanity
  453. */
  454. synccpus(&dp->sync, navailcpus);
  455. if(dp->sync < navailcpus || dp->sync >= 2 * navailcpus)
  456. panic("cpu%d: diag: failed w dp->sync %ld", m->machno,
  457. dp->sync);
  458. if(dp->cnt != 0)
  459. panic("cpu%d: diag: failed w dp->cnt %ld", m->machno,
  460. dp->cnt);
  461. ilock(dp);
  462. iprint(" cpu%d ok", m->machno);
  463. iunlock(dp);
  464. synccpus(&dp->sync, 2 * navailcpus);
  465. adec(&dp->sync);
  466. adec(&dp->sync);
  467. l1cache->wb();
  468. /*
  469. * all done, print
  470. */
  471. ilock(dp);
  472. if (m->machno == 0)
  473. iprint("\n");
  474. iunlock(dp);
  475. }
  476. static void
  477. unfreeze(uint cpu)
  478. {
  479. Clkrst *clk = (Clkrst *)soc.clkrst;
  480. Flow *flow = (Flow *)soc.flow;
  481. assert(cpu < Maxcpus);
  482. clk->clkcpu &= ~(Cpu0stop << cpu);
  483. coherence();
  484. /* out of reset */
  485. clk->cpuclr = (Cpu0reset | Cpu0wdreset | Cpu0dbgreset | Cpu0dereset) <<
  486. cpu;
  487. coherence();
  488. assert(cpu < Maxflowcpus);
  489. *(cpu == 0? &flow->cpu0: &flow->cpu1) = 0;
  490. coherence();
  491. *(cpu == 0? &flow->haltcpu0: &flow->haltcpu1) = 0; /* normal operat'n */
  492. coherence();
  493. }
  494. /*
  495. * this is all a bit magic. the soc.exceptvec register is effectively
  496. * undocumented. we had to look at linux and experiment, alas. this is the
  497. * sort of thing that should be standardised as part of the cortex mpcore spec.
  498. * even intel document their equivalent procedure.
  499. */
  500. int
  501. startcpu(uint cpu)
  502. {
  503. int i, r;
  504. ulong oldvec, rstaddr;
  505. ulong *evp = (ulong *)soc.exceptvec; /* magic */
  506. r = 0;
  507. if (getncpus() < 2 || cpu == m->machno ||
  508. cpu >= MAXMACH || cpu >= navailcpus)
  509. return -1;
  510. oldvec = *evp;
  511. l1cache->wb(); /* start next cpu w same view of ram */
  512. *evp = rstaddr = PADDR(_vrst); /* will start cpu executing at _vrst */
  513. coherence();
  514. l1cache->wb();
  515. unfreeze(cpu);
  516. for (i = 2000; i > 0 && *evp == rstaddr; i--)
  517. delay(1);
  518. if (i <= 0 || *evp != cpu) {
  519. iprint("cpu%d: didn't start!\n", cpu);
  520. stopcpu(cpu); /* make sure it's stopped */
  521. r = -1;
  522. }
  523. *evp = oldvec;
  524. return r;
  525. }
  526. static void
  527. cksecure(void)
  528. {
  529. ulong db;
  530. extern ulong getdebug(void);
  531. if (getscr() & 1)
  532. panic("cpu%d: running non-secure", m->machno);
  533. db = getdebug();
  534. if (db)
  535. iprint("cpu%d: debug enable reg %#lux\n", m->machno, db);
  536. }
  537. ulong
  538. smpon(void)
  539. {
  540. ulong aux;
  541. /* cortex-a9 model-specific configuration */
  542. aux = getauxctl();
  543. putauxctl(aux | CpACsmp | CpACmaintbcast);
  544. return aux;
  545. }
  546. void
  547. cortexa9cachecfg(void)
  548. {
  549. /* cortex-a9 model-specific configuration */
  550. putauxctl(getauxctl() | CpACparity | CpAClwr0line | CpACl2pref);
  551. }
  552. /*
  553. * called on a cpu other than 0 from cpureset in l.s,
  554. * from _vrst in lexception.s.
  555. * mmu and l1 (and system-wide l2) caches and coherency (smpon) are on,
  556. * but interrupts are disabled.
  557. * our mmu is using an exact copy of cpu0's l1 page table
  558. * as it was after userinit ran.
  559. */
  560. void
  561. cpustart(void)
  562. {
  563. int ms;
  564. ulong *evp;
  565. Power *pwr;
  566. up = nil;
  567. if (active.machs & (1<<m->machno)) {
  568. serialputc('?');
  569. serialputc('r');
  570. panic("cpu%d: resetting after start", m->machno);
  571. }
  572. assert(m->machno != 0);
  573. errata();
  574. cortexa9cachecfg();
  575. memdiag(&testmem);
  576. machinit(); /* bumps nmach, adds bit to machs */
  577. machoff(m->machno); /* not ready to go yet */
  578. /* clock signals and scu are system-wide and already on */
  579. clockshutdown(); /* kill any watch-dog timer */
  580. trapinit();
  581. clockinit(); /* sets loop delay */
  582. timersinit();
  583. cpuidprint();
  584. /*
  585. * notify cpu0 that we're up so it can proceed to l1diag.
  586. */
  587. evp = (ulong *)soc.exceptvec; /* magic */
  588. *evp = m->machno;
  589. coherence();
  590. l1diag(); /* contend with other cpus to verify sanity */
  591. /*
  592. * pwr->noiopwr == 0
  593. * pwr->detect == 0x1ff (default, all disabled)
  594. */
  595. pwr = (Power *)soc.power;
  596. assert(pwr->gatests == MASK(7)); /* everything has power */
  597. /*
  598. * 8169 has to initialise before we get past this, thus cpu0
  599. * has to schedule processes first.
  600. */
  601. if (Debug)
  602. iprint("cpu%d: waiting for 8169\n", m->machno);
  603. for (ms = 0; !l1ptstable.word && ms < 5000; ms += 10) {
  604. delay(10);
  605. cachedinvse(&l1ptstable.word, sizeof l1ptstable.word);
  606. }
  607. if (!l1ptstable.word)
  608. iprint("cpu%d: 8169 unreasonably slow; proceeding\n", m->machno);
  609. /* now safe to copy cpu0's l1 pt in mmuinit */
  610. mmuinit(); /* update our l1 pt from cpu0's */
  611. fpon();
  612. machon(m->machno); /* now ready to go and be scheduled */
  613. if (Debug)
  614. iprint("cpu%d: scheding\n", m->machno);
  615. schedinit();
  616. panic("cpu%d: schedinit returned", m->machno);
  617. }
  618. /* mainly used to break out of wfi */
  619. void
  620. sgintr(Ureg *ureg, void *)
  621. {
  622. iprint("cpu%d: got sgi\n", m->machno);
  623. /* try to prod cpu1 into life when it gets stuck */
  624. if (m->machno != 0)
  625. clockprod(ureg);
  626. }
  627. void
  628. archreset(void)
  629. {
  630. static int beenhere;
  631. if (beenhere)
  632. return;
  633. beenhere = 1;
  634. /* conservative temporary values until archconfinit runs */
  635. m->cpuhz = 1000 * Mhz; /* trimslice speed */
  636. m->delayloop = m->cpuhz/2000; /* initial estimate */
  637. prcachecfg();
  638. clockson();
  639. /* all partitions were powered up by u-boot, so needn't do anything */
  640. archconfinit();
  641. // resetusb();
  642. fpon();
  643. if (irqtooearly)
  644. panic("archreset: too early for irqenable");
  645. irqenable(Cpu0irq, sgintr, nil, "cpu0");
  646. irqenable(Cpu1irq, sgintr, nil, "cpu1");
  647. /* ... */
  648. }
  649. void
  650. archreboot(void)
  651. {
  652. Clkrst *clk = (Clkrst *)soc.clkrst;
  653. assert(m->machno == 0);
  654. iprint("archreboot: reset!\n");
  655. delay(20);
  656. clk->rstdevl |= Sysreset;
  657. coherence();
  658. delay(500);
  659. /* shouldn't get here */
  660. splhi();
  661. iprint("awaiting reset");
  662. for(;;) {
  663. delay(1000);
  664. print(".");
  665. }
  666. }
  667. void
  668. kbdinit(void)
  669. {
  670. }
  671. static void
  672. missing(ulong addr, char *name)
  673. {
  674. static int firstmiss = 1;
  675. if (addr == 0) {
  676. iprint("address zero for %s\n", name);
  677. return;
  678. }
  679. if (probeaddr(addr) >= 0)
  680. return;
  681. missed++;
  682. if (firstmiss) {
  683. iprint("missing:");
  684. firstmiss = 0;
  685. } else
  686. iprint(",\n\t");
  687. iprint(" %s at %#lux", name, addr);
  688. }
  689. /* verify that all the necessary device registers are accessible */
  690. void
  691. chkmissing(void)
  692. {
  693. delay(10);
  694. missing(KZERO, "dram");
  695. missing(soc.intr, "intr ctlr");
  696. missing(soc.intrdist, "intr distrib");
  697. missing(soc.tmr[0], "tegra timer1");
  698. missing(soc.uart[0], "console uart");
  699. missing(soc.pci, "pcie");
  700. missing(soc.ether, "ether8169");
  701. missing(soc.µs, "µs counter");
  702. if (missed)
  703. iprint("\n");
  704. delay(10);
  705. }
  706. void
  707. archflashwp(Flash*, int)
  708. {
  709. }
  710. /*
  711. * for ../port/devflash.c:/^flashreset
  712. * retrieve flash type, virtual base and length and return 0;
  713. * return -1 on error (no flash)
  714. */
  715. int
  716. archflashreset(int bank, Flash *f)
  717. {
  718. if(bank != 0)
  719. return -1;
  720. panic("archflashreset: rewrite for nor & nand flash on ts");
  721. /*
  722. * this is set up for the igepv2 board.
  723. */
  724. f->type = "onenand";
  725. f->addr = (void*)VIRTNOR; /* mapped here by archreset */
  726. f->size = 0; /* done by probe */
  727. f->width = 1;
  728. f->interleave = 0;
  729. return 0;
  730. }