Zynq.Caches.Mos 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. MODULE Caches;
  2. (**
  3. AUTHOR Timothée Martiel, 12/2015
  4. PURPOSE Cache maintenance operations for Zynq 7000 SoC
  5. Cache features:
  6. o L1:
  7. - cache line = 32 bytes
  8. - 4 ways
  9. - 256 sets
  10. o L2:
  11. - cache line = 32 bytes
  12. - 8 ways
  13. *)
  14. IMPORT SYSTEM, Trace;
  15. CONST
  16. CacheLineSize * = 32;
  17. PROCEDURE EnableL1Cache *;
  18. CODE
  19. ; Enable Cache and TLB maintenance broadcast
  20. MRC P15, 0, R0, C1, C0, 1
  21. ORR R0, R0, #1H
  22. MCR P15, 0, R0, C1, C0, 1
  23. ISB
  24. ; Enable Caching in SCTLR
  25. MRC P15, 0, R0, C1, C0, 0
  26. ORR R0, R0, #4H
  27. MCR P15, 0, R0, C1, C0, 0
  28. ISB
  29. END EnableL1Cache;
  30. (** Enable L2 cache, prefetching and other speculative execution support *)
  31. PROCEDURE EnableL2Cache *;
  32. CODE
  33. LDR R0,[PC, #L2CCCrtl-$-8] ; load l2cc base address base + control register
  34. MOV R1, #0 ; force the disable bit
  35. STR R1, [R0,#0] ; disable the l2 caches
  36. LDR R0, [PC, #L2CCAuxCtrl-$-8] ; load l2cc base address base + aux control register
  37. LDR R1,[R0,#0] ; read the register
  38. LDR R2, [PC, #L2CCAuxControl-$-8] ; set the default bits
  39. ORR R1,R1,R2
  40. STR R1, [R0,#0] ; STORE THE AUX CONTROL REGISTER
  41. LDR R0,[PC, #L2CCTAGLatReg-$-8] ; load l2cc base address base + tag latency address
  42. LDR R1, [PC, #L2CCTAGLatency-$-8] ; set the latencies for the tag
  43. STR R1, [R0,#0] ; store the tag latency register register
  44. LDR R0, [PC, #L2CCDataLatReg-$-8] ; load l2cc base address base + data latency address
  45. LDR R1,[PC, #L2CCDataLatency-$-8] ; set the latencies for the data
  46. STR R1, [R0,#0] ; store the data latency register register
  47. LDR R0,[PC, #L2CCWay-$-8] ; load l2cc base address base + way register
  48. LDR R2, [PC, #H0xffff-$-8]
  49. STR R2, [R0,#0] ; force invalidate
  50. LDR R0, [PC, #L2CCSync-$-8] ; need to poll 0x730, pss_l2cc_cache_sync_offset
  51. ; Load L2CC base address base + sync register
  52. ; poll for completion
  53. Sync:
  54. LDR R1, [R0,#0]
  55. CMP R1, #0
  56. BNE Sync
  57. LDR R0,[PC, #L2CCIntRaw-$-8] ; clear pending interrupts
  58. LDR R1,[R0,#0]
  59. LDR R0,[PC, #L2CCIntClear-$-8]
  60. STR R1,[R0,#0]
  61. LDR R0,[PC,#L2CCCrtl-$-8] ; load l2cc base address base + control register
  62. LDR R1,[R0,#0] ; read the register
  63. MOV R2, #1 ; set the enable bit
  64. ORR R1,R1,R2
  65. STR R1, [R0,#0] ; enable the l2 caches
  66. MRC P15, 0, R0, C1, C0, 0 ; flow prediction enable
  67. ORR R0, R0, #800H ; #0x800
  68. MCR P15, 0, R0, C1, C0, 0
  69. ISB
  70. MRC P15, 0, R0, C1, C0, 1 ; read auxiliary control register
  71. ORR R0, R0, #4 ; enable dside prefetch
  72. ORR R0, R0, #2 ; enable L2 prefetch hint
  73. MCR P15, 0, R0, C1, C0, 1 ; write auxiliary control register
  74. ISB
  75. B exit
  76. ; Data
  77. H0xffff: d32 0FFFFH
  78. L2CCWay: d32 0F8F02000H + 077CH
  79. L2CCSync: d32 0F8F02000H + 0730H
  80. L2CCCrtl: d32 0F8F02000H + 0100H
  81. L2CCAuxCtrl: d32 0F8F02000H + 0104H
  82. L2CCTAGLatReg: d32 0F8F02000H + 0108H
  83. L2CCDataLatReg: d32 0F8F02000H + 010CH
  84. L2CCIntClear: d32 0F8F02000H + 0220H
  85. L2CCIntRaw: d32 0F8F02000H + 021CH
  86. L2CCAuxControl: d32 72360000H
  87. L2CCTAGLatency: d32 0111H
  88. L2CCDataLatency: d32 0121H
  89. exit:
  90. END EnableL2Cache;
  91. (** Clean all dirty L1 & L2 data cache entries *)
  92. PROCEDURE CleanDCache *;
  93. CONST
  94. L2CCBBase = 0F8F02000H;
  95. L2COfs = L2CCBBase + 7BCH;
  96. L2CSync = L2CCBBase + 730H;
  97. CODE
  98. ; Clean all sets of all ways of L1 cache
  99. MOV R0, #0
  100. WayLoop:
  101. CMP R0, #4
  102. BEQ EndWayLoop
  103. LSL R4, R0, #30
  104. MOV R1, #0
  105. SetLoop:
  106. CMP R1, #256
  107. BEQ EndSetLoop
  108. LSL R3, R1, #5
  109. ORR R3, R4, R3
  110. MCR P15, 0, R3, C7, C10, 2
  111. ADD R1, R1, #1
  112. B SetLoop
  113. EndSetLoop:
  114. ADD R0, R0, #1
  115. B WayLoop
  116. EndWayLoop:
  117. DSB
  118. ; Invalidate all L2 ways
  119. LDR R0, [PC, #L2COfsAdr - $ - 8] ; R0 := reg7_inv_way address
  120. MOV R1, #0FH ; R1 := 0FH => invalidate all ways
  121. STR R1, [R0, #0] ; reg7_inv_way <- R1
  122. Sync:
  123. DSB
  124. LDR R0, [PC, #L2CSyncAdr - $ - 8] ; R0 := L2 cache sync register address
  125. MOV R1, #1
  126. STR R1, [R0, #0] ; [R0] := 1
  127. SyncLoop: ; repeat
  128. LDR R1, [R0, #0] ; R1 := l2 cache syc state
  129. CMP R1, #0
  130. BEQ Exit ; until R1 = 0
  131. B SyncLoop
  132. L2COfsAdr: d32 L2COfs
  133. L2CSyncAdr: d32 L2CSync
  134. Exit:
  135. END CleanDCache;
  136. (** Clean L1 and L2 data caches for memory region [adr, adr + size). Assumes a 1:1 memory mapping for the memory region *)
  137. PROCEDURE CleanDCacheRange*(adr:ADDRESS; len: SIZE);
  138. CONST
  139. cacheline = 32;
  140. L2CCBBase = 0F8F02000H;
  141. L2CCCacheSync = L2CCBBase + 00730H;
  142. L2CCCacheInvClnPAOfs= 007F0H;
  143. L2CCOffset = L2CCBBase + L2CCCacheInvClnPAOfs;
  144. BEGIN
  145. IF len = 0 THEN RETURN END;
  146. CODE
  147. LDR R0, [FP, #adr] ; R0 := adr
  148. LDR R1, [FP, #len] ; R1 := len
  149. LDR R2, [PC, #Cacheline - 8 - $] ; R2 := cacheline
  150. SUB R3, R2, #1 ; R3 := cacheline - 1
  151. AND R3, R0, R3 ; R3 := adr MOD cacheline
  152. ADD R1, R1, R0
  153. SUB R0, R0, R3 ; R0 := adr - adr MOD cacheline
  154. ;ADD R1, R1, R3 ; R1 := len + adr MOD cacheline
  155. MOV R3, #0
  156. MCR P15, 2, R3, C0, C0, 0 ; Select cache level 1
  157. LDR R4, [PC, #L2COfs - 8 - $] ; R4 := L2 cache flush address register address
  158. Loop:
  159. CMP R0, R1 ; while R0 < R1
  160. BEQ Sync
  161. BHI Sync
  162. MCR P15, 0, R0, C7, C10, 1 ; Clean Cache Level 1 By MVA (R0)
  163. STR R0, [R4, #0] ; Clean Cache Level 2 By PA (R0)
  164. DSB
  165. ADD R0, R0, R2 ; R0 := R0 + cacheline
  166. B Loop ; end
  167. Sync:
  168. DSB
  169. LDR R0, [PC, #L2CSync - 8 - $] ; R0 := L2 cache sync register address
  170. ;MOV R1, #1
  171. ;STR R1, [R0, #0] ; [R0] := 1
  172. SyncLoop: ; repeat
  173. LDR R1, [R0, #0] ; R1 := l2 cache syc state
  174. CMP R1, #0
  175. BEQ Exit ; until R1 = 0
  176. B SyncLoop
  177. Cacheline: d32 cacheline
  178. L2COfs: d32 L2CCOffset
  179. L2CSync: d32 L2CCCacheSync
  180. Exit:
  181. END;
  182. END CleanDCacheRange;
  183. (** Invalidate all L1 & L2 data cache entries *)
  184. PROCEDURE InvalidateDCache*( dCacheBase: LONGINT );
  185. CODE
  186. LDR R1, [FP, #dCacheBase] ; R1 contains the virtual address of a region of cacheable memory
  187. LDR R1, [R1, #0]
  188. MOV R0, #1024 ; R0 is the loop count
  189. .loop1
  190. MCR p15, 0, R1, c7, c2, 5 ; allocate line in data cache
  191. ADD R1, R1, #32 ; increment the address in R1 to the next cache line
  192. SUBS R0, R0, #1
  193. BNE loop1
  194. ; clean the mini-data cache
  195. MOV R0, #64
  196. .loop2
  197. LDR R3, [R1], #32 ; load and increment to next cache line
  198. SUBS R0, R0, #1
  199. BNE loop2
  200. B invalidate
  201. DCD dCacheBase
  202. .invalidate
  203. ; invalidate data cache and mini-data cache
  204. MCR p15, 0, R0, c7, c6, 0
  205. ; cpwait
  206. MRC p15, 0, R0, c2, c0, 0
  207. MOV R0, R0
  208. SUB PC, PC, #4
  209. MOV R0, R0
  210. MOV R0, R0
  211. MOV R0, R0
  212. MOV R0, R0
  213. END InvalidateDCache;
  214. (** Invalidate L1 and L2 data caches for the memory region [adr, adr + size). Assumes a 1:1 memory mapping for the memory region *)
  215. PROCEDURE InvalidateDCacheRange*(adr: ADDRESS; len: SIZE);
  216. CONST
  217. cacheline = 32;
  218. L2CCBBase = 0F8F02000H;
  219. L2CCCacheSync = L2CCBBase + 00730H;
  220. L2CCCacheInvPAOfs = 00770H;
  221. L2CCOffset = L2CCBBase + L2CCCacheInvPAOfs;
  222. BEGIN
  223. IF len = 0 THEN RETURN END;
  224. CODE
  225. LDR R0, [FP, #adr] ; R0 := adr
  226. LDR R1, [FP, #len] ; R1 := len
  227. LDR R2, [PC, #Cacheline - 8 - $] ; R2 := cacheline
  228. SUB R3, R2, #1 ; R3 := cacheline - 1
  229. AND R3, R0, R3 ; R3 := adr MOD cacheline
  230. SUB R0, R0, R3 ; R0 := adr - adr MOD cacheline
  231. ADD R1, R1, R3 ; R1 := len + adr MOD cacheline
  232. MOV R5, #0 ; R5 := 0 (counter value)
  233. MOV R3, #0
  234. MCR P15, 2, R3, C0, C0, 0 ; Select cache level 1
  235. LDR R4, [PC, #L2COfs - 8 - $] ; R4 := L2 cache invalidate address register address
  236. Loop:
  237. CMP R5, R1 ; while R5 < R1
  238. BEQ Sync
  239. BHI Sync
  240. STR R0, [R4, #0] ; Invalidate Cache Level 2 By PA (R0)
  241. DSB
  242. MCR P15, 0, R0, C7, C6, 1 ; Invalidate Cache Level 1 By MVA (R0)
  243. ADD R0, R0, R2 ; R0 := R0 + cacheline
  244. ADD R5, R5, R2
  245. B Loop ; end
  246. Sync:
  247. DSB
  248. LDR R0, [PC, #L2CSync - 8 - $] ; R0 := L2 cache sync register address
  249. MOV R1, #1
  250. STR R1, [R0, #0] ; [R0] := 1
  251. SyncLoop: ; repeat
  252. LDR R1, [R0, #0] ; R1 := l2 cache syc state
  253. CMP R1, #0
  254. BEQ Exit ; until R1 = 0
  255. B SyncLoop
  256. Cacheline: d32 cacheline
  257. L2COfs: d32 L2CCOffset
  258. L2CSync: d32 L2CCCacheSync
  259. Exit:
  260. END;
  261. END InvalidateDCacheRange;
  262. PROCEDURE InvalidateICache *;
  263. CODE
  264. MCR P15, 0, R0, C7, C5, 0 ; invalidate ICache & BTB
  265. ; cpwait
  266. MRC P15, 0, R0, C2, C0, 0
  267. MOV R0, R0
  268. SUB PC, PC, #4
  269. MOV R0, R0
  270. MOV R0, R0
  271. MOV R0, R0
  272. MOV R0, R0
  273. END InvalidateICache;
  274. PROCEDURE InvalidateTLB *;
  275. CODE
  276. MCR P15, 0, R0, C8, C3, 0 ; invalidate I+D TLB
  277. ; cpwait
  278. MRC P15, 0, R0, C2, C0, 0
  279. MOV R0, R0
  280. SUB PC, PC, #4
  281. MOV R0, R0
  282. MOV R0, R0
  283. MOV R0, R0
  284. MOV R0, R0
  285. END InvalidateTLB;
  286. PROCEDURE InvalidateTLBEntry * (address: ADDRESS);
  287. CODE
  288. LDR R0, [FP, #address]
  289. ;ADD SP, SP, #4 ; remove parameter
  290. MCR P15, 0, R0, C8, C3, 1 ; invalidate address
  291. ; cpwait
  292. MRC P15, 0, R0, C2, C0, 0
  293. MOV R0, R0
  294. SUB PC, PC, #4
  295. MOV R0, R0
  296. MOV R0, R0
  297. MOV R0, R0
  298. MOV R0, R0
  299. END InvalidateTLBEntry;
  300. (* DrainWriteBuffer - drains the write buffer. Works only in a priviledged mode *)
  301. PROCEDURE DrainWriteBuffer*;
  302. CODE
  303. MCR p15, 0, R0, c7, c10, 4 ; drain WB
  304. ; cpwait
  305. MRC p15, 0, R0, c2, c0, 0
  306. MOV R0, R0
  307. SUB PC, PC, #4
  308. MOV R0, R0
  309. MOV R0, R0
  310. MOV R0, R0
  311. MOV R0, R0
  312. END DrainWriteBuffer;
  313. PROCEDURE Info *;
  314. VAR
  315. dword: ADDRESS;
  316. BEGIN
  317. CODE
  318. MOV R0, #0
  319. MCR P15, 2, R0, C0, C0, 0
  320. MRC P15, 1, R0, C0, C0, 0
  321. STR R0, [FP, #dword]
  322. END;
  323. Trace.String("Cache Size Reg: "); Trace.Address(dword); Trace.Ln;
  324. Trace.String(" Cache line size = "); Trace.Int(LSH(LONGINT(1), 2 + dword MOD 8) * 4, 0); Trace.Ln;
  325. Trace.String(" Associativity = "); Trace.Int(LSH(dword MOD 2000H, -3) + 1, 0); Trace.Ln;
  326. Trace.String(" Number of sets = "); Trace.Int(LSH(dword MOD 10000000H, -13) + 1, 0); Trace.Ln;
  327. END Info;
  328. END Caches.