cache_armv7.S 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 2013 Free Software Foundation, Inc.
  4. *
  5. * GRUB is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * GRUB is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <grub/symbol.h>
  19. .file "cache_armv7.S"
  20. .text
  21. .syntax unified
  22. #if !defined (__thumb2__)
  23. .arch armv7a
  24. .arm
  25. #else
  26. .arch armv7
  27. .thumb
  28. #endif
  29. # define DMB dmb
  30. # define DSB dsb
  31. # define ISB isb
  32. #define ARMV7 1
  33. FUNCTION(grub_arm_clean_dcache_range_poc_armv7)
  34. DSB
  35. @ Clean data cache for range to point-of-coherence
  36. 1: cmp r0, r1
  37. bge 2f
  38. mcr p15, 0, r0, c7, c14, 1 @ DCCMVAC
  39. add r0, r0, r2 @ Next line
  40. b 1b
  41. 2: DSB
  42. bx lr
  43. @ r0 - CLIDR
  44. @ r1 - LoC
  45. @ r2 - current level
  46. @ r3 - num sets
  47. @ r4 - num ways
  48. @ r5 - current set
  49. @ r6 - current way
  50. @ r7 - line size
  51. @ r8 - scratch
  52. @ r9 - scratch
  53. @ r10 - scratch
  54. @ r11 - scratch
  55. clean_invalidate_dcache:
  56. push {r4-r12, lr}
  57. mrc p15, 1, r0, c0, c0, 1 @ Read CLIDR
  58. lsr r1, r0, #24 @ Extract LoC
  59. and r1, r1, #0x7
  60. mov r2, #0 @ First level, L1
  61. 2: and r8, r0, #7 @ cache type at current level
  62. cmp r8, #2
  63. blt 5f @ instruction only, or none, skip level
  64. @ set current cache level/type (for CCSIDR read)
  65. lsl r8, r2, #1
  66. mcr p15, 2, r8, c0, c0, 0 @ Write CSSELR (level, type: data/uni)
  67. @ read current cache information
  68. mrc p15, 1, r8, c0, c0, 0 @ Read CCSIDR
  69. lsr r3, r8, #13 @ Number of sets -1
  70. @ Keep only 14 bits of r3
  71. lsl r3, r3, #18
  72. lsr r3, r3, #18
  73. lsr r4, r8, #3 @ Number of ways -1
  74. @ Keep only 9 bits of r4
  75. lsl r4, r4, #23
  76. lsr r4, r4, #23
  77. and r7, r8, #7 @ log2(line size in words) - 2
  78. add r7, r7, #2 @ adjust
  79. mov r8, #1
  80. lsl r7, r8, r7 @ -> line size in words
  81. lsl r7, r7, #2 @ -> bytes
  82. @ set loop
  83. mov r5, #0 @ current set = 0
  84. 3: lsl r8, r2, #1 @ insert level
  85. clz r9, r7 @ calculate set field offset
  86. mov r10, #31
  87. sub r9, r10, r9
  88. lsl r10, r5, r9
  89. orr r8, r8, r10 @ insert set field
  90. @ way loop
  91. @ calculate way field offset
  92. mov r6, #0 @ current way = 0
  93. add r10, r4, #1
  94. clz r9, r10 @ r9 = way field offset
  95. add r9, r9, #1
  96. 4: lsl r10, r6, r9
  97. orr r11, r8, r10 @ insert way field
  98. @ clean and invalidate line by set/way
  99. mcr p15, 0, r11, c7, c14, 2 @ DCCISW
  100. @ next way
  101. add r6, r6, #1
  102. cmp r6, r4
  103. ble 4b
  104. @ next set
  105. add r5, r5, #1
  106. cmp r5, r3
  107. ble 3b
  108. @ next level
  109. 5: lsr r0, r0, #3 @ align next level CLIDR 'type' field
  110. add r2, r2, #1 @ increment cache level counter
  111. cmp r2, r1
  112. blt 2b @ outer loop
  113. @ return
  114. 6: DSB
  115. ISB
  116. pop {r4-r12, lr}
  117. bx lr
  118. #include "cache.S"