l.s 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. /*
  2. * ti omap3530 SoC machine assist
  3. * arm cortex-a8 processor
  4. *
  5. * loader uses R11 as scratch.
  6. * R9 and R10 are used for `extern register' variables.
  7. *
  8. * ARM v7 arch. ref. man. §B1.3.3 that we don't need barriers
  9. * around moves to CPSR.
  10. */
  11. #include "arm.s"
  12. /*
  13. * MCR and MRC are counter-intuitively named.
  14. * MCR coproc, opcode1, Rd, CRn, CRm[, opcode2] # arm -> coproc
  15. * MRC coproc, opcode1, Rd, CRn, CRm[, opcode2] # coproc -> arm
  16. */
  17. /*
  18. * Entered here from Das U-Boot or another Plan 9 kernel with MMU disabled.
  19. * Until the MMU is enabled it is OK to call functions provided
  20. * they are within ±32MiB relative and do not require any
  21. * local variables or more than one argument (i.e. there is
  22. * no stack).
  23. */
  24. TEXT _start(SB), 1, $-4
  25. MOVW $setR12(SB), R12 /* load the SB */
  26. SUB $KZERO, R12
  27. ADD $PHYSDRAM, R12
  28. /* SVC mode, interrupts disabled */
  29. MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1
  30. MOVW R1, CPSR
  31. BARRIERS
  32. DELAY(printloopret, 1)
  33. PUTC('\r')
  34. DELAY(printloopnl, 1)
  35. PUTC('\n')
  36. /*
  37. * work around errata
  38. */
  39. MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
  40. ORR $(CpACissue1|CpACldstissue1), R1 /* fight omap35x errata 3.1.1.9 */
  41. ORR $CpACibe, R1 /* enable cp15 invalidate */
  42. ORR $CpACl1pe, R1 /* enable l1 parity checking */
  43. ORR $CpCalign, R1 /* catch alignment errors */
  44. BIC $CpACasa, R1 /* no speculative accesses */
  45. /* go faster with fewer restrictions */
  46. BIC $(CpACcachenopipe|CpACcp15serial|CpACcp15waitidle|CpACcp15pipeflush), R1
  47. MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
  48. ISB
  49. MRC CpSC, 1, R1, C(CpCLD), C(CpCLDl2), CpCLDl2aux
  50. ORR $CpCl2nowralloc, R1 /* fight cortex errata 460075 */
  51. ORR $(CpCl2ecc|CpCl2eccparity), R1
  52. #ifdef TEDIUM
  53. /*
  54. * I don't know why this clobbers the system, but I'm tired
  55. * of arguing with this fussy processor. To hell with it.
  56. */
  57. MCR CpSC, 1, R1, C(CpCLD), C(CpCLDl2), CpCLDl2aux
  58. ISB
  59. #endif
  60. DELAY(printloops, 1)
  61. PUTC('P')
  62. /*
  63. * disable the MMU & caches
  64. */
  65. MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
  66. BIC $(CpCdcache|CpCicache|CpCmmu), R1
  67. ORR $CpCsbo, R1
  68. BIC $CpCsbz, R1
  69. MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
  70. ISB
  71. MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
  72. BIC $CpACl2en, R1 /* turn l2 cache off */
  73. MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
  74. ISB
  75. PUTC('l')
  76. DELAY(printloop3, 1)
  77. PUTC('a')
  78. /* clear Mach */
  79. MOVW $PADDR(MACHADDR), R4 /* address of Mach */
  80. MOVW $0, R0
  81. _machZ:
  82. MOVW R0, (R4)
  83. ADD $4, R4
  84. CMP.S $PADDR(L1+L1X(0)), R4 /* end at top-level page table */
  85. BNE _machZ
  86. /*
  87. * set up the MMU page table
  88. */
  89. PUTC('n')
  90. /* clear all PTEs first, to provide a default */
  91. // MOVW $PADDR(L1+L1X(0)), R4 /* address of PTE for 0 */
  92. _ptenv0:
  93. ZEROPTE()
  94. CMP.S $PADDR(L1+16*KiB), R4
  95. BNE _ptenv0
  96. DELAY(printloop4, 2)
  97. PUTC(' ')
  98. /*
  99. * set up double map of PHYSDRAM, KZERO to PHYSDRAM for first few MBs,
  100. * but only if KZERO and PHYSDRAM differ.
  101. */
  102. MOVW $PTEDRAM, R2 /* PTE bits */
  103. MOVW $PHYSDRAM, R3 /* pa */
  104. CMP $KZERO, R3
  105. BEQ no2map
  106. MOVW $PADDR(L1+L1X(PHYSDRAM)), R4 /* address of PTE for PHYSDRAM */
  107. MOVW $DOUBLEMAPMBS, R5
  108. _ptdbl:
  109. FILLPTE()
  110. SUB.S $1, R5
  111. BNE _ptdbl
  112. no2map:
  113. /*
  114. * back up and fill in PTEs for memory at KZERO.
  115. * beagle has 1 bank of 256MB of SDRAM at PHYSDRAM;
  116. * igepv2 has 1 bank of 512MB at PHYSDRAM.
  117. * Map the maximum (512MB).
  118. */
  119. PUTC('9')
  120. MOVW $PTEDRAM, R2 /* PTE bits */
  121. MOVW $PHYSDRAM, R3
  122. MOVW $PADDR(L1+L1X(KZERO)), R4 /* start with PTE for KZERO */
  123. MOVW $512, R5 /* inner loop count (MBs) */
  124. _ptekrw: /* set PTEs */
  125. FILLPTE()
  126. SUB.S $1, R5 /* decrement inner loop count */
  127. BNE _ptekrw
  128. /*
  129. * back up and fill in PTEs for MMIO
  130. * stop somewhere after uarts
  131. */
  132. PUTC(' ')
  133. MOVW $PTEIO, R2 /* PTE bits */
  134. MOVW $PHYSIO, R3
  135. MOVW $PADDR(L1+L1X(VIRTIO)), R4 /* start with PTE for VIRTIO */
  136. _ptenv2:
  137. FILLPTE()
  138. CMP.S $PADDR(L1+L1X(PHYSIOEND)), R4
  139. BNE _ptenv2
  140. /* mmu.c sets up the trap vectors later */
  141. /*
  142. * set up a temporary stack; avoid data & bss segments
  143. */
  144. MOVW $(PHYSDRAM | (128*1024*1024)), R13
  145. /* invalidate caches */
  146. BL cachedinv(SB)
  147. MOVW $KZERO, R0
  148. MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
  149. ISB
  150. MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEwait
  151. BARRIERS
  152. PUTC('f')
  153. /*
  154. * turn caches on
  155. */
  156. MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
  157. ORR $CpACl2en, R1 /* turn l2 cache on */
  158. MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
  159. BARRIERS
  160. MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
  161. ORR $(CpCdcache|CpCicache), R1
  162. MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
  163. BARRIERS
  164. PUTC('r')
  165. /* set the domain access control */
  166. MOVW $Client, R0
  167. BL dacput(SB)
  168. DELAY(printloop5, 2)
  169. PUTC('o')
  170. /* set the translation table base */
  171. MOVW $PADDR(L1), R0
  172. BL ttbput(SB)
  173. MOVW $0, R0
  174. BL pidput(SB) /* paranoia */
  175. PUTC('m')
  176. /*
  177. * the little dance to turn the MMU on
  178. */
  179. BL cacheuwbinv(SB)
  180. BL mmuinvalidate(SB)
  181. BL mmuenable(SB)
  182. PUTC(' ')
  183. /* warp the PC into the virtual map */
  184. MOVW $KZERO, R0
  185. BL _r15warp(SB)
  186. /*
  187. * now running at KZERO+something!
  188. */
  189. MOVW $setR12(SB), R12 /* reload the SB */
  190. /*
  191. * set up temporary stack again, in case we've just switched
  192. * to a new register set.
  193. */
  194. MOVW $(KZERO|(128*1024*1024)), R13
  195. /* can now execute arbitrary C code */
  196. BL cacheuwbinv(SB)
  197. PUTC('B')
  198. MOVW $PHYSDRAM, R3 /* pa */
  199. CMP $KZERO, R3
  200. BEQ no2unmap
  201. /* undo double map of PHYSDRAM, KZERO & first few MBs */
  202. MOVW $(L1+L1X(PHYSDRAM)), R4 /* addr. of PTE for PHYSDRAM */
  203. MOVW $0, R0
  204. MOVW $DOUBLEMAPMBS, R5
  205. _ptudbl:
  206. ZEROPTE()
  207. SUB.S $1, R5
  208. BNE _ptudbl
  209. no2unmap:
  210. BARRIERS
  211. MOVW $KZERO, R0
  212. MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
  213. BARRIERS
  214. #ifdef HIGH_SECURITY /* i.e., not GP omap */
  215. /* hack: set `secure monitor' vector base addr for cortex */
  216. // MOVW $HVECTORS, R0
  217. MOVW $PADDR(L1), R0
  218. SUB $(MACHSIZE+(2*1024)), R0
  219. MCR CpSC, 0, R0, C(CpVECS), C(CpVECSbase), CpVECSmon
  220. ISB
  221. #endif
  222. /*
  223. * call main in C
  224. * pass Mach to main and set up the stack in it
  225. */
  226. MOVW $(MACHADDR), R0 /* Mach */
  227. MOVW R0, R13
  228. ADD $(MACHSIZE), R13 /* stack pointer */
  229. SUB $4, R13 /* space for link register */
  230. MOVW R0, R10 /* m = MACHADDR */
  231. PUTC('e')
  232. BL main(SB) /* void main(Mach*) */
  233. /*FALLTHROUGH*/
  234. /*
  235. * reset the system
  236. */
  237. TEXT _reset(SB), 1, $-4
  238. MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R0
  239. MOVW R0, CPSR
  240. BARRIERS
  241. DELAY(printloopr, 2)
  242. PUTC('!')
  243. PUTC('r')
  244. PUTC('e')
  245. PUTC('s')
  246. PUTC('e')
  247. PUTC('t')
  248. PUTC('!')
  249. PUTC('\r')
  250. PUTC('\n')
  251. /* turn the caches off */
  252. BL cacheuwbinv(SB)
  253. MRC CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
  254. BIC $(CpCicache|CpCdcache|CpCalign), R0
  255. ORR $CpCsw, R0 /* enable SWP */
  256. MCR CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
  257. BARRIERS
  258. /* redo double map of PHYSDRAM, KZERO & first few MBs */
  259. MOVW $PTEDRAM, R2 /* PTE bits */
  260. MOVW $PHYSDRAM, R3 /* pa */
  261. MOVW $(L1+L1X(PHYSDRAM)), R4 /* address of PHYSDRAM's PTE */
  262. MOVW $DOUBLEMAPMBS, R5
  263. _ptrdbl:
  264. FILLPTE()
  265. SUB.S $1, R5
  266. BNE _ptrdbl
  267. MOVW $PHYSDRAM, R0
  268. MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
  269. BARRIERS
  270. /* turn the MMU off */
  271. MOVW $PHYSDRAM, R0
  272. BL _r15warp(SB)
  273. BL mmuinvalidate(SB)
  274. BL mmudisable(SB)
  275. /* set new reset vector */
  276. MOVW $HVECTORS, R2
  277. MOVW $0xe59ff018, R3 /* MOVW 0x18(R15), R15 */
  278. MOVW R3, (R2)
  279. BARRIERS
  280. // MOVW $PHYSFLASH, R3 /* TODO */
  281. // MOVW R3, 0x20(R2) /* where $0xe59ff018 jumps to */
  282. /* ...and jump to it */
  283. // MOVW R2, R15 /* software reboot */
  284. _limbo: /* should not get here... */
  285. BL idlehands(SB)
  286. B _limbo /* ... and can't get out */
  287. BL _div(SB) /* hack to load _div, etc. */
  288. TEXT _r15warp(SB), 1, $-4
  289. BIC $KSEGM, R14 /* link reg, will become PC */
  290. ORR R0, R14
  291. BIC $KSEGM, R13 /* SP too */
  292. ORR R0, R13
  293. RET
  294. /*
  295. * `single-element' cache operations.
  296. * in arm arch v7, they operate on all cache levels, so separate
  297. * l2 functions are unnecessary.
  298. */
  299. TEXT cachedwbse(SB), $-4 /* D writeback SE */
  300. MOVW R0, R2
  301. MOVW CPSR, R3
  302. CPSID /* splhi */
  303. BARRIERS /* force outstanding stores to cache */
  304. MOVW R2, R0
  305. MOVW 4(FP), R1
  306. ADD R0, R1 /* R1 is end address */
  307. BIC $(CACHELINESZ-1), R0 /* cache line start */
  308. _dwbse:
  309. MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEse
  310. /* can't have a BARRIER here since it zeroes R0 */
  311. ADD $CACHELINESZ, R0
  312. CMP.S R0, R1
  313. BGT _dwbse
  314. B _wait
  315. TEXT cachedwbinvse(SB), $-4 /* D writeback+invalidate SE */
  316. MOVW R0, R2
  317. MOVW CPSR, R3
  318. CPSID /* splhi */
  319. BARRIERS /* force outstanding stores to cache */
  320. MOVW R2, R0
  321. MOVW 4(FP), R1
  322. ADD R0, R1 /* R1 is end address */
  323. BIC $(CACHELINESZ-1), R0 /* cache line start */
  324. _dwbinvse:
  325. MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEwbi), CpCACHEse
  326. /* can't have a BARRIER here since it zeroes R0 */
  327. ADD $CACHELINESZ, R0
  328. CMP.S R0, R1
  329. BGT _dwbinvse
  330. _wait: /* drain write buffer */
  331. BARRIERS
  332. /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
  333. MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEwait
  334. ISB
  335. MOVW R3, CPSR /* splx */
  336. RET
  337. TEXT cachedinvse(SB), $-4 /* D invalidate SE */
  338. MOVW R0, R2
  339. MOVW CPSR, R3
  340. CPSID /* splhi */
  341. BARRIERS /* force outstanding stores to cache */
  342. MOVW R2, R0
  343. MOVW 4(FP), R1
  344. ADD R0, R1 /* R1 is end address */
  345. BIC $(CACHELINESZ-1), R0 /* cache line start */
  346. _dinvse:
  347. MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvd), CpCACHEse
  348. /* can't have a BARRIER here since it zeroes R0 */
  349. ADD $CACHELINESZ, R0
  350. CMP.S R0, R1
  351. BGT _dinvse
  352. B _wait
  353. /*
  354. * enable mmu and high vectors
  355. */
  356. TEXT mmuenable(SB), 1, $-4
  357. MRC CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
  358. ORR $(CpChv|CpCmmu), R0
  359. MCR CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
  360. BARRIERS
  361. RET
  362. TEXT mmudisable(SB), 1, $-4
  363. MRC CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
  364. BIC $(CpChv|CpCmmu), R0
  365. MCR CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
  366. BARRIERS
  367. RET
  368. /*
  369. * If one of these MCR instructions crashes or hangs the machine,
  370. * check your Level 1 page table (at TTB) closely.
  371. */
  372. TEXT mmuinvalidate(SB), $-4 /* invalidate all */
  373. MOVW CPSR, R2
  374. CPSID /* interrupts off */
  375. BARRIERS
  376. MOVW PC, R0 /* some valid virtual address */
  377. MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
  378. BARRIERS
  379. MOVW R2, CPSR /* interrupts restored */
  380. RET
  381. TEXT mmuinvalidateaddr(SB), $-4 /* invalidate single entry */
  382. MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinvse
  383. BARRIERS
  384. RET
  385. TEXT cpidget(SB), 1, $-4 /* main ID */
  386. MRC CpSC, 0, R0, C(CpID), C(0), CpIDid
  387. RET
  388. TEXT cpctget(SB), 1, $-4 /* cache type */
  389. MRC CpSC, 0, R0, C(CpID), C(0), CpIDct
  390. RET
  391. TEXT controlget(SB), 1, $-4 /* control */
  392. MRC CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
  393. RET
  394. TEXT ttbget(SB), 1, $-4 /* translation table base */
  395. MRC CpSC, 0, R0, C(CpTTB), C(0), CpTTB0
  396. RET
  397. TEXT ttbput(SB), 1, $-4 /* translation table base */
  398. MCR CpSC, 0, R0, C(CpTTB), C(0), CpTTB0
  399. MCR CpSC, 0, R0, C(CpTTB), C(0), CpTTB1 /* cortex has two */
  400. ISB
  401. RET
  402. TEXT dacget(SB), 1, $-4 /* domain access control */
  403. MRC CpSC, 0, R0, C(CpDAC), C(0)
  404. RET
  405. TEXT dacput(SB), 1, $-4 /* domain access control */
  406. MCR CpSC, 0, R0, C(CpDAC), C(0)
  407. ISB
  408. RET
  409. TEXT fsrget(SB), 1, $-4 /* data fault status */
  410. MRC CpSC, 0, R0, C(CpFSR), C(0), CpDFSR
  411. RET
  412. TEXT ifsrget(SB), 1, $-4 /* instruction fault status */
  413. MRC CpSC, 0, R0, C(CpFSR), C(0), CpIFSR
  414. RET
  415. TEXT farget(SB), 1, $-4 /* fault address */
  416. MRC CpSC, 0, R0, C(CpFAR), C(0x0)
  417. RET
  418. TEXT getpsr(SB), 1, $-4
  419. MOVW CPSR, R0
  420. RET
  421. TEXT getscr(SB), 1, $-4
  422. MRC CpSC, 0, R0, C(CpCONTROL), C(CpCONTROLscr), CpSCRscr
  423. RET
  424. TEXT pidget(SB), 1, $-4 /* address translation pid */
  425. MRC CpSC, 0, R0, C(CpPID), C(0x0)
  426. RET
  427. TEXT pidput(SB), 1, $-4 /* address translation pid */
  428. MCR CpSC, 0, R0, C(CpPID), C(0x0)
  429. ISB
  430. RET
  431. TEXT splhi(SB), 1, $-4
  432. MOVW CPSR, R0
  433. CPSID /* turn off interrupts */
  434. MOVW $(MACHADDR+4), R2 /* save caller pc in Mach */
  435. MOVW R14, 0(R2)
  436. RET
  437. TEXT spllo(SB), 1, $-4 /* start marker for devkprof.c */
  438. MOVW CPSR, R0
  439. CPSIE
  440. RET
  441. TEXT splx(SB), 1, $-4
  442. MOVW $(MACHADDR+0x04), R2 /* save caller pc in Mach */
  443. MOVW R14, 0(R2)
  444. MOVW CPSR, R3
  445. MOVW R0, CPSR /* reset interrupt level */
  446. MOVW R3, R0 /* must return old CPSR */
  447. RET
  448. TEXT spldone(SB), 1, $0 /* end marker for devkprof.c */
  449. RET
  450. TEXT islo(SB), 1, $-4
  451. MOVW CPSR, R0
  452. AND $(PsrDirq), R0
  453. EOR $(PsrDirq), R0
  454. RET
  455. TEXT tas(SB), $-4
  456. TEXT _tas(SB), $-4
  457. MOVW R0,R1
  458. MOVW $1,R0
  459. SWPW R0,(R1) /* fix: deprecated in armv7 */
  460. RET
  461. TEXT clz(SB), $-4
  462. CLZ(0, 0) /* 0 is R0 */
  463. RET
  464. TEXT setlabel(SB), 1, $-4
  465. MOVW R13, 0(R0) /* sp */
  466. MOVW R14, 4(R0) /* pc */
  467. MOVW $0, R0
  468. RET
  469. TEXT gotolabel(SB), 1, $-4
  470. MOVW 0(R0), R13 /* sp */
  471. MOVW 4(R0), R14 /* pc */
  472. MOVW $1, R0
  473. RET
  474. TEXT getcallerpc(SB), 1, $-4
  475. MOVW 0(R13), R0
  476. RET
  477. TEXT idlehands(SB), $-4
  478. BARRIERS
  479. WFI
  480. RET
  481. TEXT coherence(SB), $-4
  482. BARRIERS
  483. RET
  484. #include "cache.v7.s"