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