blob: 018c61742ee8fd4a3b1e3ade9ac7cccc338a022e [file] [log] [blame]
York Suna84cd722014-06-23 15:15:54 -07001/*
2 * (C) Copyright 2014 Freescale Semiconductor
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 *
6 * Extracted from armv8/start.S
7 */
8
9#include <config.h>
10#include <linux/linkage.h>
York Sun56cc3db2014-09-08 12:20:00 -070011#include <asm/gic.h>
York Suna84cd722014-06-23 15:15:54 -070012#include <asm/macro.h>
York Sun56cc3db2014-09-08 12:20:00 -070013#include "mp.h"
York Suna84cd722014-06-23 15:15:54 -070014
15ENTRY(lowlevel_init)
16 mov x29, lr /* Save LR */
17
Scott Wooda814e662015-03-20 19:28:10 -070018 /* Add fully-coherent masters to DVM domain */
19 ldr x1, =CCI_MN_BASE
20 ldr x2, [x1, #CCI_MN_RNF_NODEID_LIST]
21 str x2, [x1, #CCI_MN_DVM_DOMAIN_CTL_SET]
221: ldr x3, [x1, #CCI_MN_DVM_DOMAIN_CTL_SET]
23 mvn x0, x3
24 tst x0, x3 /* Wait for domain addition to complete */
25 b.ne 1b
26
York Suna84cd722014-06-23 15:15:54 -070027 /* Set the SMMU page size in the sACR register */
28 ldr x1, =SMMU_BASE
29 ldr w0, [x1, #0x10]
30 orr w0, w0, #1 << 16 /* set sACR.pagesize to indicate 64K page */
31 str w0, [x1, #0x10]
32
33 /* Initialize GIC Secure Bank Status */
34#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
35 branch_if_slave x0, 1f
36 ldr x0, =GICD_BASE
37 bl gic_init_secure
381:
39#ifdef CONFIG_GICV3
40 ldr x0, =GICR_BASE
41 bl gic_init_secure_percpu
42#elif defined(CONFIG_GICV2)
43 ldr x0, =GICD_BASE
44 ldr x1, =GICC_BASE
45 bl gic_init_secure_percpu
46#endif
47#endif
48
York Sun56cc3db2014-09-08 12:20:00 -070049 branch_if_master x0, x1, 2f
York Suna84cd722014-06-23 15:15:54 -070050
York Sun56cc3db2014-09-08 12:20:00 -070051 ldr x0, =secondary_boot_func
52 blr x0
532:
Bhupesh Sharmaa0c00ff2015-01-06 13:11:21 -080054
55#ifdef CONFIG_FSL_TZPC_BP147
56 /* Set Non Secure access for all devices protected via TZPC */
57 ldr x1, =TZPCDECPROT_0_SET_BASE /* Decode Protection-0 Set Reg */
58 orr w0, w0, #1 << 3 /* DCFG_RESET is accessible from NS world */
59 str w0, [x1]
60
61 isb
62 dsb sy
63#endif
64
65#ifdef CONFIG_FSL_TZASC_400
66 /* Set TZASC so that:
67 * a. We use only Region0 whose global secure write/read is EN
68 * b. We use only Region0 whose NSAID write/read is EN
69 *
70 * NOTE: As per the CCSR map doc, TZASC 3 and TZASC 4 are just
71 * placeholders.
72 */
73 ldr x1, =TZASC_GATE_KEEPER(0)
74 ldr x0, [x1] /* Filter 0 Gate Keeper Register */
75 orr x0, x0, #1 << 0 /* Set open_request for Filter 0 */
76 str x0, [x1]
77
78 ldr x1, =TZASC_GATE_KEEPER(1)
79 ldr x0, [x1] /* Filter 0 Gate Keeper Register */
80 orr x0, x0, #1 << 0 /* Set open_request for Filter 0 */
81 str x0, [x1]
82
83 ldr x1, =TZASC_REGION_ATTRIBUTES_0(0)
84 ldr x0, [x1] /* Region-0 Attributes Register */
85 orr x0, x0, #1 << 31 /* Set Sec global write en, Bit[31] */
86 orr x0, x0, #1 << 30 /* Set Sec global read en, Bit[30] */
87 str x0, [x1]
88
89 ldr x1, =TZASC_REGION_ATTRIBUTES_0(1)
90 ldr x0, [x1] /* Region-1 Attributes Register */
91 orr x0, x0, #1 << 31 /* Set Sec global write en, Bit[31] */
92 orr x0, x0, #1 << 30 /* Set Sec global read en, Bit[30] */
93 str x0, [x1]
94
95 ldr x1, =TZASC_REGION_ID_ACCESS_0(0)
96 ldr w0, [x1] /* Region-0 Access Register */
97 mov w0, #0xFFFFFFFF /* Set nsaid_wr_en and nsaid_rd_en */
98 str w0, [x1]
99
100 ldr x1, =TZASC_REGION_ID_ACCESS_0(1)
101 ldr w0, [x1] /* Region-1 Attributes Register */
102 mov w0, #0xFFFFFFFF /* Set nsaid_wr_en and nsaid_rd_en */
103 str w0, [x1]
104
105 isb
106 dsb sy
107#endif
York Sun56cc3db2014-09-08 12:20:00 -0700108 mov lr, x29 /* Restore LR */
109 ret
110ENDPROC(lowlevel_init)
111
York Sun1ce575f2015-01-06 13:18:42 -0800112hnf_pstate_poll:
113 /* x0 has the desired status, return 0 for success, 1 for timeout
114 * clobber x1, x2, x3, x4, x6, x7
115 */
116 mov x1, x0
117 mov x7, #0 /* flag for timeout */
118 mrs x3, cntpct_el0 /* read timer */
119 add x3, x3, #1200 /* timeout after 100 microseconds */
120 mov x0, #0x18
121 movk x0, #0x420, lsl #16 /* HNF0_PSTATE_STATUS */
122 mov w6, #8 /* HN-F node count */
1231:
124 ldr x2, [x0]
125 cmp x2, x1 /* check status */
126 b.eq 2f
127 mrs x4, cntpct_el0
128 cmp x4, x3
129 b.ls 1b
130 mov x7, #1 /* timeout */
131 b 3f
1322:
133 add x0, x0, #0x10000 /* move to next node */
134 subs w6, w6, #1
135 cbnz w6, 1b
1363:
137 mov x0, x7
138 ret
139
140hnf_set_pstate:
141 /* x0 has the desired state, clobber x1, x2, x6 */
142 mov x1, x0
143 /* power state to SFONLY */
144 mov w6, #8 /* HN-F node count */
145 mov x0, #0x10
146 movk x0, #0x420, lsl #16 /* HNF0_PSTATE_REQ */
1471: /* set pstate to sfonly */
148 ldr x2, [x0]
149 and x2, x2, #0xfffffffffffffffc /* & HNFPSTAT_MASK */
150 orr x2, x2, x1
151 str x2, [x0]
152 add x0, x0, #0x10000 /* move to next node */
153 subs w6, w6, #1
154 cbnz w6, 1b
155
156 ret
157
158ENTRY(__asm_flush_l3_cache)
159 /*
160 * Return status in x0
161 * success 0
162 * tmeout 1 for setting SFONLY, 2 for FAM, 3 for both
163 */
164 mov x29, lr
165 mov x8, #0
166
167 dsb sy
168 mov x0, #0x1 /* HNFPSTAT_SFONLY */
169 bl hnf_set_pstate
170
171 mov x0, #0x4 /* SFONLY status */
172 bl hnf_pstate_poll
173 cbz x0, 1f
174 mov x8, #1 /* timeout */
1751:
176 dsb sy
177 mov x0, #0x3 /* HNFPSTAT_FAM */
178 bl hnf_set_pstate
179
180 mov x0, #0xc /* FAM status */
181 bl hnf_pstate_poll
182 cbz x0, 1f
183 add x8, x8, #0x2
1841:
185 mov x0, x8
186 mov lr, x29
187 ret
188ENDPROC(__asm_flush_l3_cache)
189
York Sun56cc3db2014-09-08 12:20:00 -0700190 /* Keep literals not used by the secondary boot code outside it */
191 .ltorg
192
193 /* Using 64 bit alignment since the spin table is accessed as data */
194 .align 4
195 .global secondary_boot_code
196 /* Secondary Boot Code starts here */
197secondary_boot_code:
198 .global __spin_table
199__spin_table:
200 .space CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE
201
202 .align 2
203ENTRY(secondary_boot_func)
York Suna84cd722014-06-23 15:15:54 -0700204 /*
York Sun56cc3db2014-09-08 12:20:00 -0700205 * MPIDR_EL1 Fields:
206 * MPIDR[1:0] = AFF0_CPUID <- Core ID (0,1)
207 * MPIDR[7:2] = AFF0_RES
208 * MPIDR[15:8] = AFF1_CLUSTERID <- Cluster ID (0,1,2,3)
209 * MPIDR[23:16] = AFF2_CLUSTERID
210 * MPIDR[24] = MT
211 * MPIDR[29:25] = RES0
212 * MPIDR[30] = U
213 * MPIDR[31] = ME
214 * MPIDR[39:32] = AFF3
215 *
216 * Linear Processor ID (LPID) calculation from MPIDR_EL1:
217 * (We only use AFF0_CPUID and AFF1_CLUSTERID for now
218 * until AFF2_CLUSTERID and AFF3 have non-zero values)
219 *
220 * LPID = MPIDR[15:8] | MPIDR[1:0]
York Suna84cd722014-06-23 15:15:54 -0700221 */
York Sun56cc3db2014-09-08 12:20:00 -0700222 mrs x0, mpidr_el1
223 ubfm x1, x0, #8, #15
224 ubfm x2, x0, #0, #1
225 orr x10, x2, x1, lsl #2 /* x10 has LPID */
226 ubfm x9, x0, #0, #15 /* x9 contains MPIDR[15:0] */
York Suna84cd722014-06-23 15:15:54 -0700227 /*
York Sun56cc3db2014-09-08 12:20:00 -0700228 * offset of the spin table element for this core from start of spin
229 * table (each elem is padded to 64 bytes)
York Suna84cd722014-06-23 15:15:54 -0700230 */
York Sun56cc3db2014-09-08 12:20:00 -0700231 lsl x1, x10, #6
232 ldr x0, =__spin_table
233 /* physical address of this cpus spin table element */
234 add x11, x1, x0
235
York Sun77a10972015-03-20 19:28:08 -0700236 ldr x0, =__real_cntfrq
237 ldr x0, [x0]
238 msr cntfrq_el0, x0 /* set with real frequency */
York Sun56cc3db2014-09-08 12:20:00 -0700239 str x9, [x11, #16] /* LPID */
240 mov x4, #1
241 str x4, [x11, #8] /* STATUS */
242 dsb sy
243#if defined(CONFIG_GICV3)
244 gic_wait_for_interrupt_m x0
245#elif defined(CONFIG_GICV2)
246 ldr x0, =GICC_BASE
247 gic_wait_for_interrupt_m x0, w1
248#endif
249
250 bl secondary_switch_to_el2
York Suna84cd722014-06-23 15:15:54 -0700251#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
York Sun56cc3db2014-09-08 12:20:00 -0700252 bl secondary_switch_to_el1
York Suna84cd722014-06-23 15:15:54 -0700253#endif
York Suna84cd722014-06-23 15:15:54 -0700254
York Sun56cc3db2014-09-08 12:20:00 -0700255slave_cpu:
256 wfe
257 ldr x0, [x11]
258 cbz x0, slave_cpu
259#ifndef CONFIG_ARMV8_SWITCH_TO_EL1
260 mrs x1, sctlr_el2
261#else
262 mrs x1, sctlr_el1
263#endif
264 tbz x1, #25, cpu_is_le
265 rev x0, x0 /* BE to LE conversion */
266cpu_is_le:
267 br x0 /* branch to the given address */
268ENDPROC(secondary_boot_func)
269
270ENTRY(secondary_switch_to_el2)
271 switch_el x0, 1f, 0f, 0f
2720: ret
2731: armv8_switch_to_el2_m x0
274ENDPROC(secondary_switch_to_el2)
275
276ENTRY(secondary_switch_to_el1)
277 switch_el x0, 0f, 1f, 0f
2780: ret
2791: armv8_switch_to_el1_m x0, x1
280ENDPROC(secondary_switch_to_el1)
281
282 /* Ensure that the literals used by the secondary boot code are
283 * assembled within it (this is required so that we can protect
284 * this area with a single memreserve region
285 */
286 .ltorg
287
288 /* 64 bit alignment for elements accessed as data */
289 .align 4
York Sun77a10972015-03-20 19:28:08 -0700290 .global __real_cntfrq
291__real_cntfrq:
292 .quad COUNTER_FREQUENCY
York Sun56cc3db2014-09-08 12:20:00 -0700293 .globl __secondary_boot_code_size
294 .type __secondary_boot_code_size, %object
295 /* Secondary Boot Code ends here */
296__secondary_boot_code_size:
297 .quad .-secondary_boot_code