nonsec_virt.S 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * code for switching cores into non-secure state and into HYP mode
  3. *
  4. * Copyright (c) 2013 Andre Przywara <andre.przywara@linaro.org>
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <config.h>
  9. #include <linux/linkage.h>
  10. #include <asm/gic.h>
  11. #include <asm/armv7.h>
  12. #include <asm/proc-armv/ptrace.h>
  13. .arch_extension sec
  14. .arch_extension virt
  15. .pushsection ._secure.text, "ax"
  16. .align 5
  17. /* the vector table for secure state and HYP mode */
  18. _monitor_vectors:
  19. .word 0 /* reset */
  20. .word 0 /* undef */
  21. adr pc, _secure_monitor
  22. .word 0
  23. .word 0
  24. .word 0
  25. .word 0
  26. .word 0
  27. .macro is_cpu_virt_capable tmp
  28. mrc p15, 0, \tmp, c0, c1, 1 @ read ID_PFR1
  29. and \tmp, \tmp, #CPUID_ARM_VIRT_MASK @ mask virtualization bits
  30. cmp \tmp, #(1 << CPUID_ARM_VIRT_SHIFT)
  31. .endm
  32. /*
  33. * secure monitor handler
  34. * U-Boot calls this "software interrupt" in start.S
  35. * This is executed on a "smc" instruction, we use a "smc #0" to switch
  36. * to non-secure state.
  37. * r0, r1, r2: passed to the callee
  38. * ip: target PC
  39. */
  40. _secure_monitor:
  41. #ifdef CONFIG_ARMV7_PSCI
  42. ldr r5, =_psci_vectors @ Switch to the next monitor
  43. mcr p15, 0, r5, c12, c0, 1
  44. isb
  45. @ Obtain a secure stack, and configure the PSCI backend
  46. bl psci_arch_init
  47. #endif
  48. #ifdef CONFIG_ARM_ERRATA_773022
  49. mrc p15, 0, r5, c1, c0, 1
  50. orr r5, r5, #(1 << 1)
  51. mcr p15, 0, r5, c1, c0, 1
  52. isb
  53. #endif
  54. #ifdef CONFIG_ARM_ERRATA_774769
  55. mrc p15, 0, r5, c1, c0, 1
  56. orr r5, r5, #(1 << 25)
  57. mcr p15, 0, r5, c1, c0, 1
  58. isb
  59. #endif
  60. mrc p15, 0, r5, c1, c1, 0 @ read SCR
  61. bic r5, r5, #0x4a @ clear IRQ, EA, nET bits
  62. orr r5, r5, #0x31 @ enable NS, AW, FW bits
  63. @ FIQ preserved for secure mode
  64. mov r6, #SVC_MODE @ default mode is SVC
  65. is_cpu_virt_capable r4
  66. #ifdef CONFIG_ARMV7_VIRT
  67. orreq r5, r5, #0x100 @ allow HVC instruction
  68. moveq r6, #HYP_MODE @ Enter the kernel as HYP
  69. #endif
  70. mcr p15, 0, r5, c1, c1, 0 @ write SCR (with NS bit set)
  71. isb
  72. bne 1f
  73. @ Reset CNTVOFF to 0 before leaving monitor mode
  74. mrc p15, 0, r4, c0, c1, 1 @ read ID_PFR1
  75. ands r4, r4, #CPUID_ARM_GENTIMER_MASK @ test arch timer bits
  76. movne r4, #0
  77. mcrrne p15, 4, r4, r4, c14 @ Reset CNTVOFF to zero
  78. 1:
  79. mov lr, ip
  80. mov ip, #(F_BIT | I_BIT | A_BIT) @ Set A, I and F
  81. tst lr, #1 @ Check for Thumb PC
  82. orrne ip, ip, #T_BIT @ Set T if Thumb
  83. orr ip, ip, r6 @ Slot target mode in
  84. msr spsr_cxfs, ip @ Set full SPSR
  85. movs pc, lr @ ERET to non-secure
  86. ENTRY(_do_nonsec_entry)
  87. mov ip, r0
  88. mov r0, r1
  89. mov r1, r2
  90. mov r2, r3
  91. smc #0
  92. ENDPROC(_do_nonsec_entry)
  93. .macro get_cbar_addr addr
  94. #ifdef CONFIG_ARM_GIC_BASE_ADDRESS
  95. ldr \addr, =CONFIG_ARM_GIC_BASE_ADDRESS
  96. #else
  97. mrc p15, 4, \addr, c15, c0, 0 @ read CBAR
  98. bfc \addr, #0, #15 @ clear reserved bits
  99. #endif
  100. .endm
  101. .macro get_gicd_addr addr
  102. get_cbar_addr \addr
  103. add \addr, \addr, #GIC_DIST_OFFSET @ GIC dist i/f offset
  104. .endm
  105. .macro get_gicc_addr addr, tmp
  106. get_cbar_addr \addr
  107. is_cpu_virt_capable \tmp
  108. movne \tmp, #GIC_CPU_OFFSET_A9 @ GIC CPU offset for A9
  109. moveq \tmp, #GIC_CPU_OFFSET_A15 @ GIC CPU offset for A15/A7
  110. add \addr, \addr, \tmp
  111. .endm
  112. #ifndef CONFIG_ARMV7_PSCI
  113. /*
  114. * Secondary CPUs start here and call the code for the core specific parts
  115. * of the non-secure and HYP mode transition. The GIC distributor specific
  116. * code has already been executed by a C function before.
  117. * Then they go back to wfi and wait to be woken up by the kernel again.
  118. */
  119. ENTRY(_smp_pen)
  120. cpsid i
  121. cpsid f
  122. bl _nonsec_init
  123. adr r0, _smp_pen @ do not use this address again
  124. b smp_waitloop @ wait for IPIs, board specific
  125. ENDPROC(_smp_pen)
  126. #endif
  127. /*
  128. * Switch a core to non-secure state.
  129. *
  130. * 1. initialize the GIC per-core interface
  131. * 2. allow coprocessor access in non-secure modes
  132. *
  133. * Called from smp_pen by secondary cores and directly by the BSP.
  134. * Do not assume that the stack is available and only use registers
  135. * r0-r3 and r12.
  136. *
  137. * PERIPHBASE is used to get the GIC address. This could be 40 bits long,
  138. * though, but we check this in C before calling this function.
  139. */
  140. ENTRY(_nonsec_init)
  141. get_gicd_addr r3
  142. mvn r1, #0 @ all bits to 1
  143. str r1, [r3, #GICD_IGROUPRn] @ allow private interrupts
  144. get_gicc_addr r3, r1
  145. mov r1, #3 @ Enable both groups
  146. str r1, [r3, #GICC_CTLR] @ and clear all other bits
  147. mov r1, #0xff
  148. str r1, [r3, #GICC_PMR] @ set priority mask register
  149. mrc p15, 0, r0, c1, c1, 2
  150. movw r1, #0x3fff
  151. movt r1, #0x0004
  152. orr r0, r0, r1
  153. mcr p15, 0, r0, c1, c1, 2 @ NSACR = all copros to non-sec
  154. /* The CNTFRQ register of the generic timer needs to be
  155. * programmed in secure state. Some primary bootloaders / firmware
  156. * omit this, so if the frequency is provided in the configuration,
  157. * we do this here instead.
  158. * But first check if we have the generic timer.
  159. */
  160. #ifdef CONFIG_TIMER_CLK_FREQ
  161. mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1
  162. and r0, r0, #CPUID_ARM_GENTIMER_MASK @ mask arch timer bits
  163. cmp r0, #(1 << CPUID_ARM_GENTIMER_SHIFT)
  164. ldreq r1, =CONFIG_TIMER_CLK_FREQ
  165. mcreq p15, 0, r1, c14, c0, 0 @ write CNTFRQ
  166. #endif
  167. adr r1, _monitor_vectors
  168. mcr p15, 0, r1, c12, c0, 1 @ set MVBAR to secure vectors
  169. isb
  170. mov r0, r3 @ return GICC address
  171. bx lr
  172. ENDPROC(_nonsec_init)
  173. #ifdef CONFIG_SMP_PEN_ADDR
  174. /* void __weak smp_waitloop(unsigned previous_address); */
  175. ENTRY(smp_waitloop)
  176. wfi
  177. ldr r1, =CONFIG_SMP_PEN_ADDR @ load start address
  178. ldr r1, [r1]
  179. #ifdef CONFIG_PEN_ADDR_BIG_ENDIAN
  180. rev r1, r1
  181. #endif
  182. cmp r0, r1 @ make sure we dont execute this code
  183. beq smp_waitloop @ again (due to a spurious wakeup)
  184. mov r0, r1
  185. b _do_nonsec_entry
  186. ENDPROC(smp_waitloop)
  187. .weak smp_waitloop
  188. #endif
  189. .popsection