cache_4xx.S 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. /*
  2. * (C) Copyright 2007
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * Author: Igor Lisitsin <igor@emcraft.com>
  6. *
  7. * SPDX-License-Identifier: GPL-2.0+
  8. */
  9. #include <config.h>
  10. #include <post.h>
  11. #include <ppc_asm.tmpl>
  12. #include <ppc_defs.h>
  13. #include <asm/cache.h>
  14. #include <asm/mmu.h>
  15. #if CONFIG_POST & CONFIG_SYS_POST_CACHE
  16. .text
  17. /*
  18. * All 44x variants deal with cache management differently
  19. * because they have the address translation always enabled.
  20. * The 40x ppc's don't use address translation in U-Boot at all,
  21. * so we have to distinguish here between 40x and 44x.
  22. */
  23. #ifdef CONFIG_440
  24. /* void cache_post_disable (int tlb)
  25. */
  26. cache_post_disable:
  27. tlbre r0, r3, 0x0002
  28. ori r0, r0, TLB_WORD2_I_ENABLE@l
  29. tlbwe r0, r3, 0x0002
  30. sync
  31. isync
  32. blr
  33. /* void cache_post_wt (int tlb)
  34. */
  35. cache_post_wt:
  36. tlbre r0, r3, 0x0002
  37. ori r0, r0, TLB_WORD2_W_ENABLE@l
  38. andi. r0, r0, ~TLB_WORD2_I_ENABLE@l
  39. tlbwe r0, r3, 0x0002
  40. sync
  41. isync
  42. blr
  43. /* void cache_post_wb (int tlb)
  44. */
  45. cache_post_wb:
  46. tlbre r0, r3, 0x0002
  47. andi. r0, r0, ~TLB_WORD2_W_ENABLE@l
  48. andi. r0, r0, ~TLB_WORD2_I_ENABLE@l
  49. tlbwe r0, r3, 0x0002
  50. sync
  51. isync
  52. blr
  53. #else
  54. /* void cache_post_disable (int tlb)
  55. */
  56. cache_post_disable:
  57. lis r0, 0x0000
  58. ori r0, r0, 0x0000
  59. mtdccr r0
  60. sync
  61. isync
  62. blr
  63. /* void cache_post_wt (int tlb)
  64. */
  65. cache_post_wt:
  66. lis r0, 0x8000
  67. ori r0, r0, 0x0000
  68. mtdccr r0
  69. lis r0, 0x8000
  70. ori r0, r0, 0x0000
  71. mtdcwr r0
  72. sync
  73. isync
  74. blr
  75. /* void cache_post_wb (int tlb)
  76. */
  77. cache_post_wb:
  78. lis r0, 0x8000
  79. ori r0, r0, 0x0000
  80. mtdccr r0
  81. lis r0, 0x0000
  82. ori r0, r0, 0x0000
  83. mtdcwr r0
  84. sync
  85. isync
  86. blr
  87. #endif
  88. /* void cache_post_dinvalidate (void *p, int size)
  89. */
  90. cache_post_dinvalidate:
  91. dcbi r0, r3
  92. addi r3, r3, CONFIG_SYS_CACHELINE_SIZE
  93. subic. r4, r4, CONFIG_SYS_CACHELINE_SIZE
  94. bgt cache_post_dinvalidate
  95. sync
  96. blr
  97. /* void cache_post_dstore (void *p, int size)
  98. */
  99. cache_post_dstore:
  100. dcbst r0, r3
  101. addi r3, r3, CONFIG_SYS_CACHELINE_SIZE
  102. subic. r4, r4, CONFIG_SYS_CACHELINE_SIZE
  103. bgt cache_post_dstore
  104. sync
  105. blr
  106. /* void cache_post_dtouch (void *p, int size)
  107. */
  108. cache_post_dtouch:
  109. dcbt r0, r3
  110. addi r3, r3, CONFIG_SYS_CACHELINE_SIZE
  111. subic. r4, r4, CONFIG_SYS_CACHELINE_SIZE
  112. bgt cache_post_dtouch
  113. sync
  114. blr
  115. /* void cache_post_iinvalidate (void)
  116. */
  117. cache_post_iinvalidate:
  118. iccci r0, r0
  119. sync
  120. blr
  121. /* void cache_post_memset (void *p, int val, int size)
  122. */
  123. cache_post_memset:
  124. mtctr r5
  125. 1:
  126. stb r4, 0(r3)
  127. addi r3, r3, 1
  128. bdnz 1b
  129. blr
  130. /* int cache_post_check (void *p, int size)
  131. */
  132. cache_post_check:
  133. mtctr r4
  134. 1:
  135. lbz r0, 0(r3)
  136. addi r3, r3, 1
  137. cmpwi r0, 0xff
  138. bne 2f
  139. bdnz 1b
  140. li r3, 0
  141. blr
  142. 2:
  143. li r3, -1
  144. blr
  145. #define CACHE_POST_DISABLE() \
  146. mr r3, r10; \
  147. bl cache_post_disable
  148. #define CACHE_POST_WT() \
  149. mr r3, r10; \
  150. bl cache_post_wt
  151. #define CACHE_POST_WB() \
  152. mr r3, r10; \
  153. bl cache_post_wb
  154. #define CACHE_POST_DINVALIDATE() \
  155. mr r3, r11; \
  156. mr r4, r12; \
  157. bl cache_post_dinvalidate
  158. #define CACHE_POST_DFLUSH() \
  159. mr r3, r11; \
  160. mr r4, r12; \
  161. bl cache_post_dflush
  162. #define CACHE_POST_DSTORE() \
  163. mr r3, r11; \
  164. mr r4, r12; \
  165. bl cache_post_dstore
  166. #define CACHE_POST_DTOUCH() \
  167. mr r3, r11; \
  168. mr r4, r12; \
  169. bl cache_post_dtouch
  170. #define CACHE_POST_IINVALIDATE() \
  171. bl cache_post_iinvalidate
  172. #define CACHE_POST_MEMSET(val) \
  173. mr r3, r11; \
  174. li r4, val; \
  175. mr r5, r12; \
  176. bl cache_post_memset
  177. #define CACHE_POST_CHECK() \
  178. mr r3, r11; \
  179. mr r4, r12; \
  180. bl cache_post_check; \
  181. mr r13, r3
  182. /*
  183. * Write and read 0xff pattern with caching enabled.
  184. */
  185. .global cache_post_test1
  186. cache_post_test1:
  187. mflr r9
  188. mr r10, r3 /* tlb */
  189. mr r11, r4 /* p */
  190. mr r12, r5 /* size */
  191. CACHE_POST_WB()
  192. CACHE_POST_DINVALIDATE()
  193. /* Write the negative pattern to the test area */
  194. CACHE_POST_MEMSET(0xff)
  195. /* Read the test area */
  196. CACHE_POST_CHECK()
  197. CACHE_POST_DINVALIDATE()
  198. CACHE_POST_DISABLE()
  199. mr r3, r13
  200. mtlr r9
  201. blr
  202. /*
  203. * Write zeroes with caching enabled.
  204. * Write 0xff pattern with caching disabled.
  205. * Read 0xff pattern with caching enabled.
  206. */
  207. .global cache_post_test2
  208. cache_post_test2:
  209. mflr r9
  210. mr r10, r3 /* tlb */
  211. mr r11, r4 /* p */
  212. mr r12, r5 /* size */
  213. CACHE_POST_WB()
  214. CACHE_POST_DINVALIDATE()
  215. /* Write the zero pattern to the test area */
  216. CACHE_POST_MEMSET(0)
  217. CACHE_POST_DINVALIDATE()
  218. CACHE_POST_DISABLE()
  219. /* Write the negative pattern to the test area */
  220. CACHE_POST_MEMSET(0xff)
  221. CACHE_POST_WB()
  222. /* Read the test area */
  223. CACHE_POST_CHECK()
  224. CACHE_POST_DINVALIDATE()
  225. CACHE_POST_DISABLE()
  226. mr r3, r13
  227. mtlr r9
  228. blr
  229. /*
  230. * Write-through mode test.
  231. * Write zeroes, store the cache, write 0xff pattern.
  232. * Invalidate the cache.
  233. * Check that 0xff pattern is read.
  234. */
  235. .global cache_post_test3
  236. cache_post_test3:
  237. mflr r9
  238. mr r10, r3 /* tlb */
  239. mr r11, r4 /* p */
  240. mr r12, r5 /* size */
  241. CACHE_POST_WT()
  242. CACHE_POST_DINVALIDATE()
  243. /* Cache the test area */
  244. CACHE_POST_DTOUCH()
  245. /* Write the zero pattern to the test area */
  246. CACHE_POST_MEMSET(0)
  247. CACHE_POST_DSTORE()
  248. /* Write the negative pattern to the test area */
  249. CACHE_POST_MEMSET(0xff)
  250. CACHE_POST_DINVALIDATE()
  251. CACHE_POST_DISABLE()
  252. /* Read the test area */
  253. CACHE_POST_CHECK()
  254. mr r3, r13
  255. mtlr r9
  256. blr
  257. /*
  258. * Write-back mode test.
  259. * Write 0xff pattern, store the cache, write zeroes.
  260. * Invalidate the cache.
  261. * Check that 0xff pattern is read.
  262. */
  263. .global cache_post_test4
  264. cache_post_test4:
  265. mflr r9
  266. mr r10, r3 /* tlb */
  267. mr r11, r4 /* p */
  268. mr r12, r5 /* size */
  269. CACHE_POST_WB()
  270. CACHE_POST_DINVALIDATE()
  271. /* Cache the test area */
  272. CACHE_POST_DTOUCH()
  273. /* Write the negative pattern to the test area */
  274. CACHE_POST_MEMSET(0xff)
  275. CACHE_POST_DSTORE()
  276. /* Write the zero pattern to the test area */
  277. CACHE_POST_MEMSET(0)
  278. CACHE_POST_DINVALIDATE()
  279. CACHE_POST_DISABLE()
  280. /* Read the test area */
  281. CACHE_POST_CHECK()
  282. mr r3, r13
  283. mtlr r9
  284. blr
  285. /*
  286. * Load the test instructions into the instruction cache.
  287. * Replace the test instructions.
  288. * Check that the original instructions are executed.
  289. */
  290. .global cache_post_test5
  291. cache_post_test5:
  292. mflr r9
  293. mr r10, r3 /* tlb */
  294. mr r11, r4 /* p */
  295. mr r12, r5 /* size */
  296. CACHE_POST_WT()
  297. CACHE_POST_IINVALIDATE()
  298. /* Compute r13 = cache_post_test_inst */
  299. bl cache_post_test5_reloc
  300. cache_post_test5_reloc:
  301. mflr r13
  302. lis r0, (cache_post_test_inst - cache_post_test5_reloc)@h
  303. ori r0, r0, (cache_post_test_inst - cache_post_test5_reloc)@l
  304. add r13, r13, r0
  305. /* Copy the test instructions to the test area */
  306. lwz r0, 0(r13)
  307. stw r0, 0(r11)
  308. lwz r0, 8(r13)
  309. stw r0, 4(r11)
  310. sync
  311. /* Invalidate the cache line */
  312. icbi r0, r11
  313. sync
  314. isync
  315. /* Execute the test instructions */
  316. mtlr r11
  317. blrl
  318. /* Replace the test instruction */
  319. lwz r0, 4(r13)
  320. stw r0, 0(r11)
  321. sync
  322. /* Do not invalidate the cache line */
  323. isync
  324. /* Execute the test instructions */
  325. mtlr r11
  326. blrl
  327. mr r13, r3
  328. CACHE_POST_IINVALIDATE()
  329. CACHE_POST_DINVALIDATE()
  330. CACHE_POST_DISABLE()
  331. mr r3, r13
  332. mtlr r9
  333. blr
  334. /*
  335. * Load the test instructions into the instruction cache.
  336. * Replace the test instructions and invalidate the cache.
  337. * Check that the replaced instructions are executed.
  338. */
  339. .global cache_post_test6
  340. cache_post_test6:
  341. mflr r9
  342. mr r10, r3 /* tlb */
  343. mr r11, r4 /* p */
  344. mr r12, r5 /* size */
  345. CACHE_POST_WT()
  346. CACHE_POST_IINVALIDATE()
  347. /* Compute r13 = cache_post_test_inst */
  348. bl cache_post_test6_reloc
  349. cache_post_test6_reloc:
  350. mflr r13
  351. lis r0, (cache_post_test_inst - cache_post_test6_reloc)@h
  352. ori r0, r0, (cache_post_test_inst - cache_post_test6_reloc)@l
  353. add r13, r13, r0
  354. /* Copy the test instructions to the test area */
  355. lwz r0, 4(r13)
  356. stw r0, 0(r11)
  357. lwz r0, 8(r13)
  358. stw r0, 4(r11)
  359. sync
  360. /* Invalidate the cache line */
  361. icbi r0, r11
  362. sync
  363. isync
  364. /* Execute the test instructions */
  365. mtlr r11
  366. blrl
  367. /* Replace the test instruction */
  368. lwz r0, 0(r13)
  369. stw r0, 0(r11)
  370. sync
  371. /* Invalidate the cache line */
  372. icbi r0, r11
  373. sync
  374. isync
  375. /* Execute the test instructions */
  376. mtlr r11
  377. blrl
  378. mr r13, r3
  379. CACHE_POST_IINVALIDATE()
  380. CACHE_POST_DINVALIDATE()
  381. CACHE_POST_DISABLE()
  382. mr r3, r13
  383. mtlr r9
  384. blr
  385. /* Test instructions.
  386. */
  387. cache_post_test_inst:
  388. li r3, 0
  389. li r3, -1
  390. blr
  391. #endif /* CONFIG_POST & CONFIG_SYS_POST_CACHE */