ops.S 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /*
  2. * Copyright (c) 2008 Travis Geiselbrecht
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining
  5. * a copy of this software and associated documentation files
  6. * (the "Software"), to deal in the Software without restriction,
  7. * including without limitation the rights to use, copy, modify, merge,
  8. * publish, distribute, sublicense, and/or sell copies of the Software,
  9. * and to permit persons to whom the Software is furnished to do so,
  10. * subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be
  13. * included in all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  18. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  19. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  20. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  21. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. #include <asm.h>
  24. .text
  25. /* void arch_enable_ints(void); */
  26. FUNCTION(arch_enable_ints)
  27. mrs r0, cpsr
  28. bic r0, r0, #(1<<7) /* clear the I bit */
  29. msr cpsr_c, r0
  30. bx lr
  31. /* void arch_disable_ints(void); */
  32. FUNCTION(arch_disable_ints)
  33. mrs r0, cpsr
  34. orr r0, r0, #(1<<7)
  35. msr cpsr_c, r0
  36. bx lr
  37. #if 0
  38. /* int atomic_swap(int *ptr, int val);
  39. In cortex A7 does not support swp instruction,
  40. so we decide to drop this function
  41. */
  42. FUNCTION(atomic_swap)
  43. swp r0, r2, [r1]
  44. bx lr
  45. #endif
  46. /* int atomic_add(int *ptr, int val); */
  47. FUNCTION(atomic_add)
  48. #if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
  49. /* use load/store exclusive */
  50. .L_loop_add:
  51. ldrex r12, [r0]
  52. add r2, r12, r1
  53. strex r3, r2, [r0]
  54. cmp r3, #0
  55. bne .L_loop_add
  56. /* save old value */
  57. mov r0, r12
  58. bx lr
  59. #else
  60. /* disable interrupts, do the add, and reenable */
  61. mrs r2, cpsr
  62. mov r12, r2
  63. orr r2, r2, #(3<<6)
  64. msr cpsr_c, r2
  65. /* ints disabled, old cpsr state in r12 */
  66. /* do the add, leave the previous value in r0 */
  67. mov r3, r0
  68. ldr r0, [r3]
  69. add r2, r0, r1
  70. str r2, [r3]
  71. /* restore interrupts and exit */
  72. msr cpsr_c, r12
  73. bx lr
  74. #endif
  75. /* int atomic_and(int *ptr, int val); */
  76. FUNCTION(atomic_and)
  77. #if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
  78. /* use load/store exclusive */
  79. .L_loop_and:
  80. ldrex r12, [r0]
  81. and r2, r12, r1
  82. strex r3, r2, [r0]
  83. cmp r3, #0
  84. bne .L_loop_and
  85. /* save old value */
  86. mov r0, r12
  87. bx lr
  88. #else
  89. /* disable interrupts, do the and, and reenable */
  90. mrs r2, cpsr
  91. mov r12, r2
  92. orr r2, r2, #(3<<6)
  93. msr cpsr_c, r2
  94. /* ints disabled, old cpsr state in r12 */
  95. /* do the and, leave the previous value in r0 */
  96. mov r3, r0
  97. ldr r0, [r3]
  98. and r2, r0, r1
  99. str r2, [r3]
  100. /* restore interrupts and exit */
  101. msr cpsr_c, r12
  102. bx lr
  103. #endif
  104. /* int atomic_or(int *ptr, int val); */
  105. FUNCTION(atomic_or)
  106. #if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
  107. /* use load/store exclusive */
  108. .L_loop_or:
  109. ldrex r12, [r0]
  110. orr r2, r12, r1
  111. strex r3, r2, [r0]
  112. cmp r3, #0
  113. bne .L_loop_or
  114. /* save old value */
  115. mov r0, r12
  116. bx lr
  117. #else
  118. /* disable interrupts, do the or, and reenable */
  119. mrs r2, cpsr
  120. mov r12, r2
  121. orr r2, r2, #(3<<6)
  122. msr cpsr_c, r2
  123. /* ints disabled, old cpsr state in r12 */
  124. /* do the or, leave the previous value in r0 */
  125. mov r3, r0
  126. ldr r0, [r3]
  127. orr r2, r0, r1
  128. str r2, [r3]
  129. /* restore interrupts and exit */
  130. msr cpsr_c, r12
  131. bx lr
  132. #endif
  133. /* void arch_idle(); */
  134. FUNCTION(arch_idle)
  135. #if ARM_ISA_ARMV7
  136. wfi /* .word 0xe320f003 wfi */
  137. #elif PLATFORM_MSM7K
  138. /* TODO: safely handle wfi */
  139. #elif ARM_CPU_ARM1136 || ARM_CPU_ARM926
  140. mov r0, #0
  141. mcr p15, 0, r0, c7, c0, #4
  142. #elif ARM_CPU_ARM7
  143. /* nothing to do here */
  144. #else
  145. #error unknown cpu
  146. #endif
  147. bx lr
  148. /* uint32_t arm_read_cr1(void) */
  149. FUNCTION(arm_read_cr1)
  150. mrc p15, 0, r0, c1, c0, 0
  151. bx lr
  152. /* void arm_write_cr1(uint32_t val) */
  153. FUNCTION(arm_write_cr1)
  154. mcr p15, 0, r0, c1, c0, 0
  155. bx lr
  156. /* uint32_t arm_read_cr1_aux(void) */
  157. FUNCTION(arm_read_cr1_aux)
  158. mrc p15, 0, r0, c1, c0, 1
  159. bx lr
  160. /* void arm_write_cr1_aux(uint32_t val) */
  161. FUNCTION(arm_write_cr1_aux)
  162. mcr p15, 0, r0, c1, c0, 1
  163. bx lr
  164. /* void arm_write_ttbr(uint32_t val) */
  165. FUNCTION(arm_write_ttbr)
  166. #ifndef MTK_LM_MODE
  167. mcr p15, 0, r0, c2, c0, 0
  168. #else
  169. /*high part(r1) is fixed at 0x0000_0000*/
  170. /*low part(r0) is the input value*/
  171. mov r1, #0
  172. mcrr p15, 0, r0, r1, c2
  173. #endif
  174. bx lr
  175. /* void arm_write_dacr(uint32_t val) */
  176. FUNCTION(arm_write_dacr)
  177. mcr p15, 0, r0, c3, c0, 0
  178. bx lr
  179. /* void arm_invalidate_tlb(void) */
  180. FUNCTION(arm_invalidate_tlb)
  181. mov r0, #0
  182. mcr p15, 0, r0, c8, c7, 0
  183. bx lr
  184. /* void arch_switch_stacks_and_call(addr_t call, addr_t stack) */
  185. FUNCTION(arch_switch_stacks_and_call)
  186. mov sp, r1
  187. bx r0
  188. /*void dmb(void) */
  189. FUNCTION(dmb)
  190. #if ARM_CPU_CORTEX_A8
  191. dmb sy
  192. #elif ARM_CPU_ARM1136
  193. mov r0, #0
  194. mcr p15, 0, r0, c7, c10, 5
  195. #endif
  196. bx lr
  197. /*void isb(void) */
  198. FUNCTION(isb)
  199. #if ARM_CPU_CORTEX_A8
  200. isb sy
  201. #elif ARM_CPU_ARM1136
  202. mov r0, #0
  203. mcr p15, 0, r0, c7, c5, 4
  204. #endif
  205. bx lr
  206. /*void dsb(void) */
  207. FUNCTION(dsb)
  208. #if ARM_CPU_CORTEX_A8
  209. dsb sy
  210. #elif ARM_CPU_ARM1136
  211. mov r0, #0
  212. mcr p15, 0, r0, c7, c10, 4
  213. #endif
  214. bx lr
  215. /* uint32_t arm_read_cycle_count(void); */
  216. FUNCTION(arm_read_cycle_count)
  217. /* uint32_t arch_cycle_count(void); */
  218. FUNCTION(arch_cycle_count)
  219. #if ARM_CPU_CORTEX_A8
  220. mrc p15, 0, r0, c9, c13, 0
  221. #else
  222. mov r0, #0
  223. #endif
  224. bx lr
  225. /* Jump to MTK Download Agent */
  226. FUNCTION(jump_da)
  227. mov r4,r1
  228. mov r5,r2
  229. mov pc,r0