archsup.S 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. /*++
  2. Copyright (c) 2012 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. archsup.S
  5. Abstract:
  6. This module implements ARMv7 processor architecture features not
  7. implementable in C.
  8. Author:
  9. Evan Green 11-Aug-2012
  10. Environment:
  11. Kernel mode
  12. --*/
  13. ##
  14. ## ------------------------------------------------------------------ Includes
  15. ##
  16. #include <minoca/kernel/arm.inc>
  17. ##
  18. ## --------------------------------------------------------------- Definitions
  19. ##
  20. ##
  21. ## ---------------------------------------------------------------------- Code
  22. ##
  23. ASSEMBLY_FILE_HEADER
  24. ##
  25. ## VOID
  26. ## ArCleanEntireCache (
  27. ## VOID
  28. ## )
  29. ##
  30. /*++
  31. Routine Description:
  32. This routine cleans the entire data cache.
  33. Arguments:
  34. None.
  35. Return Value:
  36. None.
  37. --*/
  38. FUNCTION ArCleanEntireCache
  39. stmdb %sp!, {%r4-%r11} @ Save non-volatile registers.
  40. mrc p15, 1, %r0, c0, c0, 1 @ Read CLIDR into R0.
  41. ands %r3, %r0, #0x7000000 @
  42. mov %r3, %r3, LSR #23 @ Cache level value (naturally aligned).
  43. beq ArCleanEntireCacheEnd @
  44. mov %r10, #0 @
  45. ArCleanEntireCacheLoop1:
  46. add %r2, %r10, %r10, LSR #1 @ Work out 3 x cache level.
  47. mov %r1, %r0, LSR %r2 @ Bottom 3 bits are the Cache Type for
  48. and %r1, %r1, #7 @ this level. Get those 3 bits.
  49. cmp %r1, #2 @ Check to see if there's no cache or
  50. blt ArCleanEntireCacheSkip @ only instruction cache at this level.
  51. mcr p15, 2, %r10, c0, c0, 0 @ Write CSSELR from R10.
  52. ISB @ ISB to sync the change to CCSIDR.
  53. mrc p15, 1, %r1, c0, c0, 0 @ Read current CCSIDR
  54. and %r2, %r1, #7 @ Extract the line length field.
  55. add %r2, %r2, #4 @ Add 4 for the line length offset
  56. ldr %r4, =0x3FF @ (log2 16 bytes).
  57. ands %r4, %r4, %r1, LSR #3 @ R4 is the max number on the way size
  58. @ (right aligned).
  59. clz %r5, %r4 @ R5 is the bit position of way size
  60. @ increment.
  61. mov %r9, %r4 @ R9 is the working copy of the max way
  62. @ size (right aligned).
  63. ArCleanEntireCacheLoop2:
  64. ldr %r7, =0x00007FFF @
  65. ands %r7, %r7, %r1, LSR #13 @ R7 is the max number of the index size
  66. @ (right aligned).
  67. ArCleanEntireCacheLoop3:
  68. lsl %r11, %r9, %r5 @ Factor in the way number and cache
  69. orr %r11, %r10, %r11 @ number into R11.
  70. lsl %r4, %r7, %r2 @ Factor in the
  71. orr %r11, %r11, %r4 @ index number.
  72. mcr p15, 0, %r11, c7, c10, 2 @ DCCSW, clean by set/way.
  73. subs %r7, %r7, #1 @ Decrement the index.
  74. bge ArCleanEntireCacheLoop3 @
  75. subs %r9, %r9, #1 @ Decrement the way number.
  76. bge ArCleanEntireCacheLoop2 @
  77. ArCleanEntireCacheSkip:
  78. add %r10, %r10, #2 @ Increment the cache number.
  79. cmp %r3, %r10
  80. bgt ArCleanEntireCacheLoop1
  81. ArCleanEntireCacheEnd:
  82. mcr p15, 0, %r0, c7, c5, 0 @ Write to ICIALLU
  83. ldmia %sp!, {%r4-%r11} @ Restore non-volatile registers.
  84. DSB @ Data Synchronization barrier.
  85. bx %lr
  86. END_FUNCTION ArCleanEntireCache
  87. ##
  88. ## VOID
  89. ## ArCleanInvalidateEntireCache (
  90. ## VOID
  91. ## )
  92. ##
  93. /*++
  94. Routine Description:
  95. This routine cleans and invalidates the entire data cache.
  96. Arguments:
  97. None.
  98. Return Value:
  99. None.
  100. --*/
  101. FUNCTION ArCleanInvalidateEntireCache
  102. stmdb %sp!, {%r4-%r11} @ Save non-volatile registers.
  103. mrc p15, 1, %r0, c0, c0, 1 @ Read CLIDR into R0.
  104. ands %r3, %r0, #0x7000000 @
  105. mov %r3, %r3, LSR #23 @ Cache level value (naturally aligned).
  106. beq ArCleanInvalidateEntireCacheEnd @
  107. mov %r10, #0 @
  108. ArCleanInvalidateEntireCacheLoop1:
  109. add %r2, %r10, %r10, LSR #1 @ Work out 3 x cache level.
  110. mov %r1, %r0, LSR %r2 @ Bottom 3 bits are the Cache Type for
  111. and %r1, %r1, #7 @ this level. Get those 3 bits.
  112. cmp %r1, #2 @ Check to see if there's no cache at
  113. blt ArCleanInvalidateEntireCacheSkip @ this level.
  114. mcr p15, 2, %r10, c0, c0, 0 @ Write CSSELR from R10.
  115. ISB @ ISB to sync the change to CCSIDR.
  116. mrc p15, 1, %r1, c0, c0, 0 @ Read current CCSIDR
  117. and %r2, %r1, #7 @ Extract the line length field.
  118. add %r2, %r2, #4 @ Add 4 for the line length offset
  119. ldr %r4, =0x3FF @ (log2 16 bytes).
  120. ands %r4, %r4, %r1, LSR #3 @ R4 is the max number on the way size
  121. @ (right aligned).
  122. clz %r5, %r4 @ R5 is the bit position of way size
  123. @ increment.
  124. mov %r9, %r4 @ R9 is the working copy of the max way
  125. @ size (right aligned).
  126. ArCleanInvalidateEntireCacheLoop2:
  127. ldr %r7, =0x00007FFF @
  128. ands %r7, %r7, %r1, LSR #13 @ R7 is the max number of the index size
  129. @ (right aligned).
  130. ArCleanInvalidateEntireCacheLoop3:
  131. lsl %r11, %r9, %r5 @ Factor in the way number and cache
  132. orr %r11, %r10, %r11 @ number into R11.
  133. lsl %r4, %r7, %r2 @ Factor in the
  134. orr %r11, %r11, %r4 @ index number.
  135. mcr p15, 0, %r11, c7, c14, 2 @ DCCISW, clean and invalidate set/way.
  136. subs %r7, %r7, #1 @ Decrement the index.
  137. bge ArCleanInvalidateEntireCacheLoop3
  138. subs %r9, %r9, #1 @ Decrement the way number.
  139. bge ArCleanInvalidateEntireCacheLoop2
  140. ArCleanInvalidateEntireCacheSkip:
  141. add %r10, %r10, #2 @ Increment the cache number.
  142. cmp %r3, %r10
  143. bgt ArCleanInvalidateEntireCacheLoop1
  144. ArCleanInvalidateEntireCacheEnd:
  145. mcr p15, 0, %r0, c7, c5, 0 @ Write to ICIALLU
  146. DSB
  147. ldmia %sp!, {%r4-%r11} @ Restore non-volatile registers.
  148. bx %lr
  149. END_FUNCTION ArCleanInvalidateEntireCache
  150. ##
  151. ## ULONG
  152. ## ArGetMultiprocessorIdRegister (
  153. ## VOID
  154. ## )
  155. ##
  156. /*++
  157. Routine Description:
  158. This routine gets the Multiprocessor ID register (MPIDR).
  159. Arguments:
  160. None.
  161. Return Value:
  162. Returns the value of the MPIDR.
  163. --*/
  164. FUNCTION ArGetMultiprocessorIdRegister
  165. mrc p15, 0, %r0, %c0, %c0, 5 @ Get the MPIDR
  166. bx %lr @
  167. END_FUNCTION ArGetMultiprocessorIdRegister
  168. ##
  169. ## ULONG
  170. ## ArGetPerformanceControlRegister (
  171. ## VOID
  172. ## )
  173. ##
  174. /*++
  175. Routine Description:
  176. This routine retrieves the PMCR (Performance Monitor Control Register).
  177. Arguments:
  178. None.
  179. Return Value:
  180. Returns the value of the PMCR.
  181. --*/
  182. FUNCTION ArGetPerformanceControlRegister
  183. mrc p15, 0, %r0, %c9, %c12, 0 @ Get the PMCR.
  184. bx %lr @
  185. END_FUNCTION ArGetPerformanceControlRegister
  186. ##
  187. ## VOID
  188. ## ArSetPerformanceControlRegister (
  189. ## ULONG Value
  190. ## )
  191. ##
  192. /*++
  193. Routine Description:
  194. This routine sets the PMCR (Performance Monitor Control Register).
  195. Arguments:
  196. Value - Supplies the value to set in the PMCR.
  197. Return Value:
  198. None.
  199. --*/
  200. FUNCTION ArSetPerformanceControlRegister
  201. mcr p15, 0, %r0, %c9, %c12, 0 @ Set the PMCR.
  202. bx %lr @
  203. END_FUNCTION ArSetPerformanceControlRegister
  204. ##
  205. ## VOID
  206. ## ArClearPerformanceInterruptRegister (
  207. ## ULONG Value
  208. ## )
  209. ##
  210. /*++
  211. Routine Description:
  212. This routine sets the PMINTENCLR (Performance Monitor Interrupt Clear)
  213. register.
  214. Arguments:
  215. Value - Supplies the value to set in the PMINTENCLR.
  216. Return Value:
  217. None.
  218. --*/
  219. FUNCTION ArClearPerformanceInterruptRegister
  220. mcr p15, 0, %r0, %c9, %c14, 2 @ Set the PMINTENCLR.
  221. bx %lr @
  222. END_FUNCTION ArClearPerformanceInterruptRegister
  223. ##
  224. ## VOID
  225. ## ArSetPerformanceUserEnableRegister (
  226. ## ULONG Value
  227. ## )
  228. ##
  229. /*++
  230. Routine Description:
  231. This routine sets the PMUSERENR (Performance Monitor User Enable Register).
  232. Arguments:
  233. Value - Supplies the value to set in the PMUSERENR.
  234. Return Value:
  235. None.
  236. --*/
  237. FUNCTION ArSetPerformanceUserEnableRegister
  238. mcr p15, 0, %r0, %c9, %c14, 0 @ Set the PMUSERENR.
  239. bx %lr @
  240. END_FUNCTION ArSetPerformanceUserEnableRegister
  241. ##
  242. ## ULONG
  243. ## ArGetPerformanceCounterEnableRegister (
  244. ## VOID
  245. ## )
  246. ##
  247. /*++
  248. Routine Description:
  249. This routine retrieves the PMCNTENSET (Performance Monitor Counter Enable
  250. Set) register.
  251. Arguments:
  252. None.
  253. Return Value:
  254. Returns the value of the PMCNTENSET.
  255. --*/
  256. FUNCTION ArGetPerformanceCounterEnableRegister
  257. mrc p15, 0, %r0, %c9, %c12, 1 @ Get the PMCNTENSET register.
  258. bx %lr @
  259. END_FUNCTION ArGetPerformanceCounterEnableRegister
  260. ##
  261. ## VOID
  262. ## ArSetCycleCountEnableRegister (
  263. ## ULONG Value
  264. ## )
  265. ##
  266. /*++
  267. Routine Description:
  268. This routine sets the PMCNTENSET (Performance Monitor Counter Enable
  269. Set) register.
  270. Arguments:
  271. Value - Supplies the value to set in the PMCNTENSET register.
  272. Return Value:
  273. None.
  274. --*/
  275. FUNCTION ArSetPerformanceCounterEnableRegister
  276. mcr p15, 0, %r0, %c9, %c12, 1 @ Set the PMCNTENSET register.
  277. bx %lr @
  278. END_FUNCTION ArSetPerformanceCounterEnableRegister
  279. ##
  280. ## ULONG
  281. ## ArGetCycleCountRegister (
  282. ## VOID
  283. ## )
  284. ##
  285. /*++
  286. Routine Description:
  287. This routine retrieves the PMCCNTR (Performance Monitor Cycle Counter)
  288. register.
  289. Arguments:
  290. None.
  291. Return Value:
  292. Returns the value of the PMCCNTR.
  293. --*/
  294. FUNCTION ArGetCycleCountRegister
  295. mrc p15, 0, %r0, %c9, %c13, 0 @ Get the PMCCNTR register.
  296. bx %lr @
  297. END_FUNCTION ArGetCycleCountRegister
  298. ##
  299. ## VOID
  300. ## ArSetCycleCountRegister (
  301. ## ULONG Value
  302. ## )
  303. ##
  304. /*++
  305. Routine Description:
  306. This routine sets the PMCCNTR (Performance Monitor Cycle Counter) register.
  307. Arguments:
  308. Value - Supplies the value to set in the PMCCNTR register.
  309. Return Value:
  310. None.
  311. --*/
  312. FUNCTION ArSetCycleCountRegister
  313. mcr p15, 0, %r0, %c9, %c13, 0 @ Set the PMCCNTR register.
  314. bx %lr @
  315. END_FUNCTION ArSetCycleCountRegister
  316. ##
  317. ## --------------------------------------------------------- Internal Functions
  318. ##