proc-v7-2level.S 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. /*
  2. * arch/arm/mm/proc-v7-2level.S
  3. *
  4. * Copyright (C) 2001 Deep Blue Solutions Ltd.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #define TTB_S (1 << 1)
  11. #define TTB_RGN_NC (0 << 3)
  12. #define TTB_RGN_OC_WBWA (1 << 3)
  13. #define TTB_RGN_OC_WT (2 << 3)
  14. #define TTB_RGN_OC_WB (3 << 3)
  15. #define TTB_NOS (1 << 5)
  16. #define TTB_IRGN_NC ((0 << 0) | (0 << 6))
  17. #define TTB_IRGN_WBWA ((0 << 0) | (1 << 6))
  18. #define TTB_IRGN_WT ((1 << 0) | (0 << 6))
  19. #define TTB_IRGN_WB ((1 << 0) | (1 << 6))
  20. /* PTWs cacheable, inner WB not shareable, outer WB not shareable */
  21. #define TTB_FLAGS_UP TTB_IRGN_WB|TTB_RGN_OC_WB
  22. #define PMD_FLAGS_UP PMD_SECT_WB
  23. /* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
  24. #define TTB_FLAGS_SMP TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
  25. #define PMD_FLAGS_SMP PMD_SECT_WBWA|PMD_SECT_S
  26. #ifdef CONFIG_TIMA_RKP
  27. #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 6
  28. .arch_extension sec
  29. #endif
  30. #endif
  31. /*
  32. * cpu_v7_switch_mm(pgd_phys, tsk)
  33. *
  34. * Set the translation table base pointer to be pgd_phys
  35. *
  36. * - pgd_phys - physical address of new TTB
  37. *
  38. * It is assumed that:
  39. * - we are not using split page tables
  40. */
  41. ENTRY(cpu_v7_switch_mm)
  42. #ifdef CONFIG_MMU
  43. mov r2, #0
  44. ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id
  45. ALT_SMP(orr r0, r0, #TTB_FLAGS_SMP)
  46. ALT_UP(orr r0, r0, #TTB_FLAGS_UP)
  47. #ifdef CONFIG_ARM_ERRATA_430973
  48. mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
  49. #endif
  50. #ifdef CONFIG_PID_IN_CONTEXTIDR
  51. mrc p15, 0, r2, c13, c0, 1 @ read current context ID
  52. bic r2, r2, #0xff @ extract the PID
  53. and r1, r1, #0xff
  54. orr r1, r1, r2 @ insert the PID into r1
  55. #endif
  56. #ifdef CONFIG_TIMA_RKP
  57. stmfd sp!, {r2, r11}
  58. /* TZ side expects r0 to be in r11 */
  59. mov r11, r0
  60. /* r2 : mcr_val */
  61. mov r2, r0
  62. /* r0: command */
  63. ldr r0, =0x3f803221
  64. smc #1
  65. /* Restore r0 and r2 */
  66. ldmfd sp!, {r2, r11}
  67. #ifdef CONFIG_TIMA_RKP_30
  68. /* Flush TLB */
  69. mcr p15, 0, r0, c8, c3, 0
  70. dsb
  71. #endif
  72. #endif
  73. isb
  74. #ifdef CONFIG_ARM_ERRATA_754322
  75. dsb
  76. #endif
  77. mcr p15, 0, r1, c13, c0, 1 @ set context ID
  78. isb
  79. mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
  80. isb
  81. #endif
  82. mov pc, lr
  83. ENDPROC(cpu_v7_switch_mm)
  84. #ifdef CONFIG_TIMA_RKP_L2_GROUP
  85. /*
  86. * Pass the pointer to the group buffer and its length to TZ side.
  87. * cpu_v7_timal2group_set_pte_commit(tima_l2group_entry_ptr,
  88. * tima_l2group_entries_count)
  89. */
  90. ENTRY(cpu_v7_timal2group_set_pte_commit)
  91. /* Second parameter is the length, move it to r2 */
  92. mov r2, r1
  93. /* First parameter is the address, move it to r1 */
  94. mov r1, r0
  95. stmfd sp!,{r0-r3, r11}
  96. stmfd sp!,{r0}
  97. mov r11, r3
  98. ldr r0, =0x3f811221 @cmd_id=0x11
  99. smc #1
  100. pop {r0}
  101. pop {r0-r3, r11}
  102. mov pc, lr
  103. ENDPROC(cpu_v7_timal2group_set_pte_commit)
  104. /*
  105. * Function writes the pte addr, arm pte value and linux
  106. * pte value at the address pointed to by the L2 group
  107. * pointer.
  108. * cpu_v7_timal2group_set_pte_ext(pte_t *ptep, pte_t pte,
  109. * unsigned int ext, unsigned long tima_l2group_entry_ptr);
  110. */
  111. ENTRY(cpu_v7_timal2group_set_pte_ext)
  112. #ifdef CONFIG_MMU
  113. /* r3 has the pointer to the new entry */
  114. stmfd sp!,{r4}
  115. stmfd sp!,{r5}
  116. stmfd sp!,{r1}
  117. stmfd sp!,{r3}
  118. bic r3, r1, #0x000003f0
  119. bic r3, r3, #PTE_TYPE_MASK
  120. orr r3, r3, r2
  121. orr r3, r3, #PTE_EXT_AP0 | 2
  122. tst r1, #1 << 4
  123. orrne r3, r3, #PTE_EXT_TEX(1)
  124. eor r1, r1, #L_PTE_DIRTY
  125. tst r1, #L_PTE_RDONLY | L_PTE_DIRTY
  126. orrne r3, r3, #PTE_EXT_APX
  127. tst r1, #L_PTE_USER
  128. orrne r3, r3, #PTE_EXT_AP1
  129. #ifdef CONFIG_CPU_USE_DOMAINS
  130. @ allow kernel read/write access to read-only user pages
  131. tstne r3, #PTE_EXT_APX
  132. bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
  133. #endif
  134. tst r1, #L_PTE_XN
  135. orrne r3, r3, #PTE_EXT_XN
  136. tst r1, #L_PTE_YOUNG
  137. tstne r1, #L_PTE_PRESENT
  138. moveq r3, #0
  139. /* grouped operations*/
  140. /*pop back the buffer pointer to r2*/
  141. pop {r2}
  142. pop {r1}
  143. mov r5, #0
  144. ldr r4, [r0]
  145. cmp r1, r4 /* r1 has linux pte value */
  146. bne 1f
  147. ldr r4, [r0, #2048]
  148. cmp r3, r4 /* r3 has arm pte value */
  149. bne 1f
  150. mov r5, #5
  151. b 2f
  152. 1:
  153. //ldr r0, =0xdeadbee1
  154. /* r0 has the pointer to the pte */
  155. str r0, [r2]
  156. /* flush cache after the str */
  157. mcr p15, 0, r2, c7, c14, 1
  158. //ldr r1, =0xdeadbee2
  159. add r2, r2, #4
  160. /* r1 has the linux pte value */
  161. str r1, [r2]
  162. /* flush cache after the str */
  163. mcr p15, 0, r2, c7, c14, 1
  164. //ldr r3, =0xdeadbee3
  165. add r2, r2, #4
  166. /* r3 has the arm pte value */
  167. str r3, [r2]
  168. /* flush cache after the str */
  169. mcr p15, 0, r2, c7, c14, 1
  170. dsb
  171. isb
  172. #endif
  173. 2:
  174. mov r0, r5
  175. pop {r5}
  176. pop {r4}
  177. mov pc, lr
  178. ENDPROC(cpu_v7_timal2group_set_pte_ext)
  179. #endif /* CONFIG_TIMA_RKP_L2_GROUP */
  180. #ifdef CONFIG_TIMA_RKP
  181. ENTRY(cpu_v7_tima_iommu_opt)
  182. stmfd sp!,{r0-r3, r11}
  183. mov r3, r2
  184. /* Second parameter is the end addr, move it to r2 */
  185. mov r2, r1
  186. /* First parameter is the start addr, move it to r1 */
  187. mov r1, r0
  188. stmfd sp!,{r0}
  189. mov r11, r3
  190. ldr r0, =0x3f820221 @cmd_id=0x20
  191. smc #1
  192. pop {r0}
  193. pop {r0-r3, r11}
  194. mov pc, lr
  195. ENDPROC(cpu_v7_tima_iommu_opt)
  196. #endif
  197. /*
  198. * cpu_v7_set_pte_ext(ptep, pte)
  199. *
  200. * Set a level 2 translation table entry.
  201. *
  202. * - ptep - pointer to level 2 translation table entry
  203. * (hardware version is stored at +2048 bytes)
  204. * - pte - PTE value to store
  205. * - ext - value for extended PTE bits
  206. */
  207. #ifdef CONFIG_TIMA_RKP_L2_TABLES
  208. ENTRY(cpu_v7_tima_set_pte_ext)
  209. # ifdef CONFIG_MMU
  210. stmfd sp!, {r1} //added for tima
  211. bic r3, r1, #0x000003f0
  212. bic r3, r3, #PTE_TYPE_MASK
  213. orr r3, r3, r2
  214. orr r3, r3, #PTE_EXT_AP0 | 2
  215. tst r1, #1 << 4
  216. orrne r3, r3, #PTE_EXT_TEX(1)
  217. eor r1, r1, #L_PTE_DIRTY
  218. tst r1, #L_PTE_RDONLY | L_PTE_DIRTY
  219. orrne r3, r3, #PTE_EXT_APX
  220. tst r1, #L_PTE_USER
  221. orrne r3, r3, #PTE_EXT_AP1
  222. #ifdef CONFIG_CPU_USE_DOMAINS
  223. @ allow kernel read/write access to read-only user pages
  224. tstne r3, #PTE_EXT_APX
  225. bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
  226. #endif
  227. tst r1, #L_PTE_XN
  228. orrne r3, r3, #PTE_EXT_XN
  229. tst r1, #L_PTE_YOUNG
  230. tstne r1, #L_PTE_PRESENT
  231. moveq r3, #0
  232. /*next part is added for tima*/
  233. /** Check if the kernel is re-writing the same value!
  234. * In case of tima, such rewrites are unnecessary and expensive.
  235. */
  236. ldr r2, [r0]
  237. cmp r1, r2
  238. bne 1f
  239. ldr r2, [r0, #2048]
  240. cmp r3, r2
  241. beq 4f
  242. 1:
  243. /** Prepare the stack for L2 write emulation!
  244. */
  245. pop {r1}
  246. stmfd sp!,{r0-r3, r11}
  247. stmfd sp!,{r0}
  248. mov r11, r0
  249. /** Cache invalidate the values to be written
  250. */
  251. #ifndef CONFIG_TIMA_RKP_COHERENT_TT
  252. mcr p15, 0, r0, c7, c14, 1 @ flush_linux_pte
  253. #endif
  254. add r0, r0, #2048
  255. #ifndef CONFIG_TIMA_RKP_COHERENT_TT
  256. mcr p15, 0, r0, c7, c14, 1 @ flush_arm_pte
  257. dsb
  258. isb
  259. #endif
  260. ldr r0, =0x3f807221
  261. smc #1
  262. pop {r0}
  263. /** Cache invalidate again to ensure no
  264. * values re-cached by speculative fetching
  265. */
  266. #ifndef CONFIG_TIMA_RKP_COHERENT_TT
  267. mcr p15, 0, r0, c7, c6, 1
  268. dsb
  269. isb
  270. #endif
  271. #ifdef CONFIG_TIMA_RKP_DEBUG
  272. ldr r2, [r0]
  273. cmp r1, r2
  274. beq 2f
  275. stmfd sp!, {r0}
  276. ldr r0, =0x3f80f221 @cmd_id=0x0f
  277. smc #1
  278. pop {r0}
  279. 2:
  280. #endif
  281. add r0, r0, #2048
  282. #ifndef CONFIG_TIMA_RKP_COHERENT_TT
  283. mcr p15, 0, r0, c7, c6, 1
  284. dsb
  285. isb
  286. #else
  287. mcr p15, 0, r0, c7, c10, 1 @ flush_pte
  288. dsb
  289. isb
  290. #endif
  291. #ifdef CONFIG_TIMA_RKP_DEBUG
  292. ldr r2, [r0]
  293. cmp r3, r2
  294. beq 3f
  295. stmfd sp!, {r0}
  296. ldr r0, =0x3f80f221 @cmd_id=0x0f
  297. smc #1
  298. pop {r0}
  299. 3:
  300. #endif
  301. pop {r0-r3, r11}
  302. 4:
  303. #endif
  304. mov pc, lr
  305. ENDPROC(cpu_v7_tima_set_pte_ext)
  306. #endif
  307. #ifdef CONFIG_TIMA_RKP
  308. .global cpu_v7_set_pte_ext_proc_end
  309. #endif
  310. ENTRY(cpu_v7_set_pte_ext)
  311. #ifdef CONFIG_MMU
  312. str r1, [r0] @ linux version
  313. bic r3, r1, #0x000003f0
  314. bic r3, r3, #PTE_TYPE_MASK
  315. orr r3, r3, r2
  316. orr r3, r3, #PTE_EXT_AP0 | 2
  317. tst r1, #1 << 4
  318. orrne r3, r3, #PTE_EXT_TEX(1)
  319. eor r1, r1, #L_PTE_DIRTY
  320. tst r1, #L_PTE_RDONLY | L_PTE_DIRTY
  321. orrne r3, r3, #PTE_EXT_APX
  322. tst r1, #L_PTE_USER
  323. orrne r3, r3, #PTE_EXT_AP1
  324. #ifdef CONFIG_CPU_USE_DOMAINS
  325. @ allow kernel read/write access to read-only user pages
  326. tstne r3, #PTE_EXT_APX
  327. bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
  328. #endif
  329. tst r1, #L_PTE_XN
  330. orrne r3, r3, #PTE_EXT_XN
  331. tst r1, #L_PTE_YOUNG
  332. tstne r1, #L_PTE_PRESENT
  333. moveq r3, #0
  334. ARM( str r3, [r0, #2048]! )
  335. THUMB( add r0, r0, #2048 )
  336. THUMB( str r3, [r0] )
  337. ALT_SMP(W(nop))
  338. ALT_UP (mcr p15, 0, r0, c7, c10, 1) @ flush_pte
  339. #endif
  340. mov pc, lr
  341. #ifdef CONFIG_TIMA_RKP
  342. cpu_v7_set_pte_ext_proc_end:
  343. #endif
  344. ENDPROC(cpu_v7_set_pte_ext)
  345. /*
  346. * Memory region attributes with SCTLR.TRE=1
  347. *
  348. * n = TEX[0],C,B
  349. * TR = PRRR[2n+1:2n] - memory type
  350. * IR = NMRR[2n+1:2n] - inner cacheable property
  351. * OR = NMRR[2n+17:2n+16] - outer cacheable property
  352. *
  353. * n TR IR OR
  354. * UNCACHED 000 00
  355. * BUFFERABLE 001 10 00 00
  356. * WRITETHROUGH 010 10 10 10
  357. * WRITEBACK 011 10 11 11
  358. * reserved 110
  359. * WRITEALLOC 111 10 01 01
  360. * DEV_SHARED 100 01
  361. * DEV_NONSHARED 100 01
  362. * DEV_WC 001 10
  363. * DEV_CACHED 011 10
  364. *
  365. * Other attributes:
  366. *
  367. * DS0 = PRRR[16] = 0 - device shareable property
  368. * DS1 = PRRR[17] = 1 - device shareable property
  369. * NS0 = PRRR[18] = 0 - normal shareable property
  370. * NS1 = PRRR[19] = 1 - normal shareable property
  371. * NOS = PRRR[24+n] = 1 - not outer shareable
  372. */
  373. .equ PRRR, 0xff0a81a8
  374. #ifdef CONFIG_ARCH_MSM_SCORPIONMP
  375. .equ NMRR, 0x40e080e0
  376. #else
  377. .equ NMRR, 0x40e040e0
  378. #endif
  379. /*
  380. * Macro for setting up the TTBRx and TTBCR registers.
  381. * - \ttb0 and \ttb1 updated with the corresponding flags.
  382. */
  383. .macro v7_ttb_setup, zero, ttbr0, ttbr1, tmp
  384. #ifdef CONFIG_TIMA_RKP_EMUL_CP15_INSTR
  385. ldr r0, =0x3f805221
  386. smc #1
  387. #else
  388. mcr p15, 0, \zero, c2, c0, 2 @ TTB control register
  389. #endif
  390. ALT_SMP(orr \ttbr0, \ttbr0, #TTB_FLAGS_SMP)
  391. ALT_UP(orr \ttbr0, \ttbr0, #TTB_FLAGS_UP)
  392. ALT_SMP(orr \ttbr1, \ttbr1, #TTB_FLAGS_SMP)
  393. ALT_UP(orr \ttbr1, \ttbr1, #TTB_FLAGS_UP)
  394. mcr p15, 0, \ttbr1, c2, c0, 1 @ load TTB1
  395. .endm
  396. __CPUINIT
  397. /* AT
  398. * TFR EV X F I D LR S
  399. * .EEE ..EE PUI. .T.T 4RVI ZWRS BLDP WCAM
  400. * rxxx rrxx xxx0 0101 xxxx xxxx x111 xxxx < forced
  401. * 1 0 110 0011 1100 .111 1101 < we want
  402. */
  403. .align 2
  404. .type v7_crval, #object
  405. v7_crval:
  406. crval clear=0x0120c302, mmuset=0x10c03c7d, ucset=0x00c01c7c
  407. .previous