1
2
3
4
5
6
7
8
9#include <config.h>
10#include <linux/linkage.h>
11#include <asm/gic.h>
12#include <asm/armv7.h>
13#include <asm/proc-armv/ptrace.h>
14
15.arch_extension sec
16.arch_extension virt
17
18 .pushsection ._secure.text, "ax"
19
20 .align 5
21
22_monitor_vectors:
23 .word 0
24 .word 0
25 adr pc, _secure_monitor
26 .word 0
27 .word 0
28 .word 0
29 .word 0
30 .word 0
31
32.macro is_cpu_virt_capable tmp
33 mrc p15, 0, \tmp, c0, c1, 1 @ read ID_PFR1
34 and \tmp, \tmp,
35 cmp \tmp,
36.endm
37
38
39
40
41
42
43
44
45
46_secure_monitor:
47#ifdef CONFIG_ARMV7_PSCI
48 ldr r5, =_psci_vectors @ Switch to the next monitor
49 mcr p15, 0, r5, c12, c0, 1
50 isb
51
52 @ Obtain a secure stack
53 bl psci_stack_setup
54
55 @ Configure the PSCI backend
56 push {r0, r1, r2, ip}
57 bl psci_arch_init
58 pop {r0, r1, r2, ip}
59#endif
60
61#ifdef CONFIG_ARM_ERRATA_773022
62 mrc p15, 0, r5, c1, c0, 1
63 orr r5, r5,
64 mcr p15, 0, r5, c1, c0, 1
65 isb
66#endif
67
68#ifdef CONFIG_ARM_ERRATA_774769
69 mrc p15, 0, r5, c1, c0, 1
70 orr r5, r5,
71 mcr p15, 0, r5, c1, c0, 1
72 isb
73#endif
74
75 mrc p15, 0, r5, c1, c1, 0 @ read SCR
76 bic r5, r5,
77 orr r5, r5,
78 @ FIQ preserved for secure mode
79 mov r6,
80 is_cpu_virt_capable r4
81#ifdef CONFIG_ARMV7_VIRT
82 orreq r5, r5,
83 moveq r6,
84#endif
85
86 mcr p15, 0, r5, c1, c1, 0 @ write SCR (with NS bit set)
87 isb
88
89 bne 1f
90
91 @ Reset CNTVOFF to 0 before leaving monitor mode
92 mrc p15, 0, r4, c0, c1, 1 @ read ID_PFR1
93 ands r4, r4,
94 movne r4,
95 mcrrne p15, 4, r4, r4, c14 @ Reset CNTVOFF to zero
961:
97 mov lr, ip
98 mov ip,
99 tst lr,
100 orrne ip, ip,
101 orr ip, ip, r6 @ Slot target mode in
102 msr spsr_cxfs, ip @ Set full SPSR
103 movs pc, lr @ ERET to non-secure
104
105ENTRY(_do_nonsec_entry)
106 mov ip, r0
107 mov r0, r1
108 mov r1, r2
109 mov r2, r3
110 smc
111ENDPROC(_do_nonsec_entry)
112
113.macro get_cbar_addr addr
114#ifdef CONFIG_ARM_GIC_BASE_ADDRESS
115 ldr \addr, =CONFIG_ARM_GIC_BASE_ADDRESS
116#else
117 mrc p15, 4, \addr, c15, c0, 0 @ read CBAR
118 bfc \addr,
119#endif
120.endm
121
122.macro get_gicd_addr addr
123 get_cbar_addr \addr
124 add \addr, \addr,
125.endm
126
127.macro get_gicc_addr addr, tmp
128 get_cbar_addr \addr
129 is_cpu_virt_capable \tmp
130 movne \tmp,
131 moveq \tmp,
132 add \addr, \addr, \tmp
133.endm
134
135#ifndef CONFIG_ARMV7_PSCI
136
137
138
139
140
141
142ENTRY(_smp_pen)
143 cpsid i
144 cpsid f
145
146 bl _nonsec_init
147
148 adr r0, _smp_pen @ do not use this address again
149 b smp_waitloop @ wait for IPIs, board specific
150ENDPROC(_smp_pen)
151#endif
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166ENTRY(_nonsec_init)
167 get_gicd_addr r3
168
169 mvn r1,
170 str r1, [r3,
171
172 get_gicc_addr r3, r1
173
174 mov r1,
175 str r1, [r3,
176 mov r1,
177 str r1, [r3,
178
179 mrc p15, 0, r0, c1, c1, 2
180 movw r1,
181 movt r1,
182 orr r0, r0, r1
183 mcr p15, 0, r0, c1, c1, 2 @ NSACR = all copros to non-sec
184
185
186
187
188
189
190
191#ifdef CONFIG_TIMER_CLK_FREQ
192 mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1
193 and r0, r0,
194 cmp r0,
195 ldreq r1, =CONFIG_TIMER_CLK_FREQ
196 mcreq p15, 0, r1, c14, c0, 0 @ write CNTFRQ
197#endif
198
199 adr r1, _monitor_vectors
200 mcr p15, 0, r1, c12, c0, 1 @ set MVBAR to secure vectors
201 isb
202
203 mov r0, r3 @ return GICC address
204 bx lr
205ENDPROC(_nonsec_init)
206
207#ifdef CONFIG_SMP_PEN_ADDR
208
209ENTRY(smp_waitloop)
210 wfi
211 ldr r1, =CONFIG_SMP_PEN_ADDR @ load start address
212 ldr r1, [r1]
213#ifdef CONFIG_PEN_ADDR_BIG_ENDIAN
214 rev r1, r1
215#endif
216 cmp r0, r1 @ make sure we dont execute this code
217 beq smp_waitloop @ again (due to a spurious wakeup)
218 mov r0, r1
219 b _do_nonsec_entry
220ENDPROC(smp_waitloop)
221.weak smp_waitloop
222#endif
223
224 .popsection
225