nonsec_virt.S 5.5 KB

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