1 /*
2 * Copyright (c) 2017-2018, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 #include <ti/csl/arch/a53/src/startup/aarch64/boot_defs.h>
34 //************************** Global symbols ************************************
35 .global Entry
36 .global _stack
37 .global _bss_start
38 .global _bss_end
39 .global start_boot
40 .global ti_csl_arm_gicv3_vectors
42 .macro GICD_WRITE_LOOP x, y, offset
43 str w1, [x0, #\offset]
44 .if \y-\x
45 GICD_WRITE_LOOP "(\x+1)", \y, "(\offset+4)"
46 .endif
47 .endm
49 .macro INIT_GICD_IGROUPR
50 ldr x0, =CSL_GIC_BASE_ADDR
51 mvn w1, wzr
52 GICD_WRITE_LOOP 0, 31, 0x0080
53 .endm
55 .macro INIT_GICD_IGRPMODR
56 ldr x0, =CSL_GIC_BASE_ADDR
57 mov w1, wzr
58 GICD_WRITE_LOOP 0, 31, 0x0D00
59 .endm
62 .section .text.csl_a53_startup, "ax"
63 .func Entry
64 Entry:
65 mov x21, sp /* Store the SP in x21 */
66 mov x22, x30 /* Store the LR in x22 */
67 mrs x0, currentel
68 cmp x0, #0xC
69 bne 2f
70 ldr x0, =ti_csl_arm_v8a_Core_disableCaches
71 blr x0
73 /*
74 * ----------------------
75 * Switch from EL3 to EL2
76 * ----------------------
77 */
78 mov x0, #0x0531
79 msr scr_el3, x0
80 msr cptr_el3, xzr /* Disable all trap bits */
81 mov x0, #0x33ff
82 msr cptr_el2, x0 /* Disable all trap bits */
83 ldr x0, =CSL_GIC_BASE_ADDR
84 mov w1, #0x37
85 str w1, [x0] /* Enable GIC */
86 mov x0, #0xf
87 msr s3_6_c12_c12_5, x0 /* Enable GIC system register interface
88 and disable IRQ/FIQ bypass */
89 isb
90 mov x0, #0x1
91 msr s3_6_c12_c12_7, x0 /* Enable Non-secure group 1 interrupts */
92 isb
93 INIT_GICD_IGROUPR
94 INIT_GICD_IGRPMODR
95 ldr x0, =CSL_GICR_BASE_ADDR
96 ldr x1, =ti_csl_arm_v8a_Core_getGicxAddr
97 blr x1
98 ldr w1, [x0, #0x14]
99 mov w2, #0x2
100 bic w1, w1, w2
101 str w1, [x0, #0x14] /* wakeup GICR */
102 1: ldr w1, [x0, #0x14]
103 and w1, w1, #0x4
104 cbnz w1, 1b
105 ldr x0, =CSL_GICS_BASE_ADDR
106 ldr x1, =ti_csl_arm_v8a_Core_getGicxAddr
107 blr x1
108 mvn x1, xzr
109 str w1, [x0, #0x80] /* Configure all SGIs & PPIs as Group 1 ints */
110 str wzr, [x0, #0xD00] /* Clear GICR_IGRPMODR0 */
111 mov x0, #0xff
112 msr icc_pmr_el1, x0 /* Set priority mask */
113 mov x0, #0x0830
114 movk x0, #0x30c5, lsl #16
115 msr sctlr_el2, x0 /* Initialize sctlr_el2 to reset values */
116 mrs x0, actlr_el3
117 orr x0, x0, #0x2
118 msr actlr_el3, x0 /* Enable CPUECTLR_EL1 access from EL2 */
119 /* TODO setup vbar */
120 ldr x0, =CSL_GTC_CNTCR_ADDR
121 ldr w1, [x0]
122 orr w1, w1, #0x1
123 str w1, [x0] /* Enable system counter */
124 isb
125 bl switch_to_el2
127 2:
128 mrs x0, currentel /* Read again as currentEL may have changed */
129 cmp x0, #0x8
130 bne 3f
132 /*
133 * ----------------------
134 * Switch from EL2 to EL1
135 * ----------------------
136 */
137 mrs x0, cnthctl_el2
138 orr x0, x0, #0x3 /* Enable EL1/EL0 access to timers */
139 msr cnthctl_el2, x0
140 msr cntvoff_el2, xzr
141 mov x0, #0x33ff
142 msr cptr_el2, x0 /* Disable all trap bits */
143 msr hstr_el2, xzr /* Disable all coprocessor trap bits */
144 mov x0, #0x0002 /* 64bit EL1, Disable hypervisor call (HVC)
145 instruction, Set/Way Invalidation Override */
146 movk x0, #0xA000, lsl #16
147 msr hcr_el2, x0
148 mov x0, #0x0838
149 movk x0, #0x30d0, lsl #16
150 msr sctlr_el1, x0
151 mrs x0, actlr_el2
152 orr x0, x0, #2
153 msr actlr_el2, x0
154 isb
155 mov x0, #0xF
156 msr icc_sre_el2, x0 /* Enable GIC system register interface
157 and disable IRQ/FIQ bypass */
158 bl switch_to_el1
159 3:
160 ldr x0, =gnu_targets_arm_rtsv8A_startupAsm
161 br x0
163 switch_to_el1:
164 mov x0, #0x3c5
165 msr spsr_el2, x0
166 msr elr_el2, x30
167 eret
169 switch_to_el2:
170 mov x0, #0x3c9
171 msr spsr_el3, x0
172 msr elr_el3, x30
173 eret
175 .endfunc
177 /*
178 * ======== Core_getGicxBaseAddr ========
179 *
180 * Ptr Core_getGicxAddr(Ptr gicxBaseAddr)
181 */
182 .section .text.csl_startup, "ax"
183 .func ti_csl_arm_v8a_Core_getGicxAddr
185 ti_csl_arm_v8a_Core_getGicxAddr:
186 ldr x1, =CSL_GICX_OFFSET
187 mrs x2, mpidr_el1
188 ubfx x3, x2, #8, #8 /* x3 = Cluster Id */
189 and x2, x2, #0xFF /* x2 = Core Id */
190 sub x3, x3, #0
191 mrs x4, s3_1_c11_c0_2 /* Read L2CTLR_EL1 */
192 ubfx x4, x4, #24, #2 /* x4 = Number of cores per cluster */
193 lsl x3, x3, x4 /* x3 = clusterIdx * numCoresPerCluster */
194 add x2, x2, x3
195 madd x0, x1, x2, x0
196 ret
197 .endfunc
200 .section .text.csl_a53_startup, "ax"
201 .func gnu_targets_arm_rtsv8A_startupAsm
202 gnu_targets_arm_rtsv8A_startupAsm:
203 /*
204 * ---------------------
205 * Boot code starts here
206 * ---------------------
207 */
209 mov x0, #0x3C0
210 msr daif, x0 /* Mask all interrupts */
212 #if defined(__ARM_FP)
213 mov x0, #(3 << 20)
214 msr cpacr_el1, x0 /* Enable FP/SIMD at EL1 */
215 #endif
217 isb /* Synchronize processor context */
219 /*
220 * ------------------------
221 * Initialize stack pointer
222 * ------------------------
223 */
224 msr spsel, #1 /* Use SP_ELx for ELx */
225 ldr x0, =__TI_STACK_BASE
226 ldr x1, =__TI_STACK_SIZE
227 add x0, x0, x1
228 and x0, x0, #(~0xf) /* 16-byte align SP */
229 mov sp, x0 /* Initialize SP */
231 /* Setup the vector table for all levels */
232 ldr x0, =ti_csl_arm_gicv3_vectors
233 msr vbar_el1, x0 /* Set vector table base address */
235 stp x21, x22, [sp, #-16]! /* save SP and LR to stack */
237 /* do more initialization in C, go to main() */
238 bl start_boot_diag
239 mov x20, x0
240 ldp x0, x1, [sp], #16 /* Load SP and LR to stack */
241 mov sp, x0
242 mov x30, x1
243 ret
244 .endfunc
246 /*
247 * ======== Core_disableCaches ========
248 */
249 .section .text.ti_csl_arm_v8a_Core_disableCaches
250 .func ti_csl_arm_v8a_Core_disableCaches
252 ti_csl_arm_v8a_Core_disableCaches:
253 mrs x0, clidr_el1
254 and w3, w0, #0x07000000 /* Get 2 x Level of Coherence */
255 lsr w3, w3, #23
256 cbz w3, 5f
257 mov w10, #0 /* w10 = 2 x cache level */
258 mov w8, #1 /* w8 = Constant 0b1 */
259 1:
260 add w2, w10, w10, lsr #1 /* Caclulate 3x cache level */
261 lsr w1, w0, w2 /* Extract cache type for this level */
262 and w1, w1, #0x7
263 cmp w1, #2
264 blt 4f /* No data or unified cache */
265 msr csselr_el1, x10 /* Select this cache level */
266 isb /* Synchronize change of csselr */
267 mrs x1, ccsidr_el1 /* Read ccsidr */
268 and w2, w1, #7 /* w2 = log2(linelen)-4 */
269 add w2, w2, #4 /* w2 = log2(linelen) */
270 ubfx w4, w1, #3, #10 /* w4 = max way number, right aligned */
271 clz w5, w4 /* w5 = 32-log2(ways), bit position of
272 way in dc operand */
273 lsl w9, w4, w5 /* w9 = max way number, aligned to
274 position in DC operand */
275 lsl w16, w8, w5 /* w16 = amount to decrement way number
276 per iteration */
277 2:
278 ubfx w7, w1, #13, #15 /* w7 = max set number, right aligned */
279 lsl w7, w7, w2 /* w7 = max set number, aligned to
280 position in DC operand */
281 lsl w17, w8, w2 /* w17 = amount to decrement set number
282 per iteration */
283 3:
284 orr w11, w10, w9 /* w11 = combine way num & cache ...*/
285 orr w11, w11, w7 /* ... num and set num for DC operand */
286 dc cisw, x11 /* Do data cache clean and invalidate
287 by set and way */
288 subs w7, w7, w17 /* Decrement set number */
289 bge 3b
290 subs x9, x9, x16 /* Decrement way number */
291 bge 2b
292 4:
293 add w10, w10, #2 /* Increment 2 x cache level */
294 cmp w3, w10
295 dsb sy /* Ensure completion of previous cache
296 maintenance operation */
297 bgt 1b
298 5:
299 mrs x0, sctlr_el3 /* read SCTLR_EL3 */
300 bic x0, x0, #0x0004 /* clear C bit */
301 msr sctlr_el3, x0 /* DCache disabled */
303 mrs x0, sctlr_el3 /* read SCTLR_EL3 */
304 bic x0, x0, #0x1000 /* clear I bit */
305 msr sctlr_el3, x0 /* ICache disabled */
306 ic iallu /* invalidate all ICache */
307 dsb sy
308 isb
310 ret
311 .endfunc
313 .end