xref: /optee_os/core/arch/arm/plat-stm/tz_a9init.S (revision a0fdab653c2f0ea1f1c2b2fa8765f2e8a0df0474)
1/*
2 * Copyright (c) 2014, STMicroelectronics International N.V.
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 are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28/*
29 * Entry points for the A9 inits, A9 revision specific or not.
30 * It is assume no stack is available when these routines are called.
31 * It is assume each routine is called with return address in LR
32 * and with ARM registers R0, R1, R2, R3 being scratchable.
33 */
34#include <kernel/tz_ssvce_def.h>
35#include <arm32_macros.S>
36#include <asm.S>
37
38#define CPUID_A9_R2P2_H 0x412f
39#define CPUID_A9_R2P2_L 0xc092
40
41#define CPUID_A9_R3P0_H 0x413f
42#define CPUID_A9_R3P0_L 0xc090
43
44.section .text
45.balign 4
46.code 32
47
48/*
49 * arm_secboot_identify_cpu - identify and save CPU version
50 *
51 * Use scratables registers R0-R3.
52 * No stack usage.
53 * LR store return address.
54 * Trap CPU in case of error.
55 */
56FUNC arm_secboot_identify_cpu , :
57
58	mrc  p15, 0, r0, c0, c0, 0  /* read A9 ID */
59	movw r1, #CPUID_A9_R2P2_L
60	movt r1, #CPUID_A9_R2P2_H
61	cmp  r0, r1
62	beq  _ident_a9_r2p2
63	movw r1, #CPUID_A9_R3P0_L
64	movt r1, #CPUID_A9_R3P0_H
65	cmp  r0, r1
66	beq  _ident_a9_r3p0
67	b . /* TODO: unknown id: reset? log? */
68
69_ident_a9_r2p2:
70	/* unsupported version. TODO: needs to be supported */
71	b . /* TODO: unknown id: reset? log? */
72
73_ident_a9_r3p0:
74	mov pc, lr /* back to tzinit */
75END_FUNC arm_secboot_identify_cpu
76
77/*
78 * Memory Cache Level2 Configuration Function
79 *
80 * Use scratables registers R0-R3.
81 * No stack usage.
82 * LR store return address.
83 * Trap CPU in case of error.
84 */
85FUNC arm_cl2_config , :
86
87	mrc  p15, 0, r0, c0, c0, 0  /* read A9 ID */
88	movw r1, #CPUID_A9_R3P0_L
89	movt r1, #CPUID_A9_R3P0_H
90	cmp  r0, r1
91	beq  _config_l2cc_r3p0
92	b . /* TODO: unknown id: reset? log? */
93
94_config_l2cc_r3p0:
95	/*
96	 * TAG RAM Control Register
97	 *
98	 * bit[10:8]:1 - 2 cycle of write accesses latency
99	 * bit[6:4]:1 - 2 cycle of read accesses latency
100	 * bit[2:0]:1 - 2 cycle of setup latency
101	 */
102	movw r0, #PL310_TAG_RAM_CTRL
103	movt r0, #PL310_BASE_H
104	ldr  r2, [r0]
105	movw r1, #0xf888
106	movt r1, #0xffff
107	and  r2,r2,r1
108	movw r1, #0xf999
109	movt r1, #0xffff
110	orr  r2,r2,r1
111	str  r2, [r0]
112
113	/*
114	 * DATA RAM Control Register
115	 *
116	 * bit[10:8]:2 - 3 cycle of write accesses latency
117	 * bit[6:4]:2 - 3 cycle of read accesses latency
118	 * bit[2:0]:2 - 3 cycle of setup latency
119	 */
120	movw r0, #PL310_DATA_RAM_CTRL
121	movt r0, #PL310_BASE_H
122	ldr  r2, [r0]
123	movw r1, #0xf888
124	movt r1, #0xffff
125	and  r2,r2,r1
126	movw r1, #0xfaaa
127	movt r1, #0xffff
128	orr  r2,r2,r1
129	str  r2, [r0]
130
131	/*
132	 * Auxiliary Control Register = 0x3C480800
133	 *
134	 * I/Dcache prefetch enabled (bit29:28=2b11)
135	 * NS can access interrupts (bit27=1)
136	 * NS can lockown cache lines (bit26=1)
137	 * Pseudo-random replacement policy (bit25=0)
138	 * Force write allocated (default)
139	 * Shared attribute internally ignored (bit22=1, bit13=0)
140	 * Parity disabled (bit21=0)
141	 * Event monitor disabled (bit20=0)
142	 * 128kB ways, 8-way associativity (bit19:17=3b100 bit16=0)
143	 * Store buffer device limitation enabled (bit11=1)
144	 * Cacheable accesses have high prio (bit10=0)
145	 * Full Line Zero (FLZ) disabled (bit0=0)
146	 */
147	movw r0, #PL310_AUX_CTRL
148	movt r0, #PL310_BASE_H
149	movw r1, #0x0800
150	movt r1, #0x3C48
151	str  r1, [r0]
152
153	/*
154	 * Prefetch Control Register = 0x31000007
155	 *
156	 * Double linefill disabled (bit30=0)
157	 * I/D prefetch enabled (bit29:28=2b11)
158	 * Prefetch drop enabled (bit24=1)
159	 * Incr double linefill disable (bit23=0)
160	 * Prefetch offset = 7 (bit4:0)
161	 */
162	movw r0, #PL310_PREFETCH_CTRL
163	movt r0, #PL310_BASE_H
164	movw r1, #0x0007
165	movt r1, #0x3100
166	str  r1, [r0]
167
168	/*
169	 * Power Register = 0x00000003
170	 *
171	 * Dynamic clock gating enabled
172	 * Standby mode enabled
173	 */
174	movw r0, #PL310_POWER_CTRL
175	movt r0, #PL310_BASE_H
176	movw r1, #0x0003
177	movt r1, #0x0000
178	str  r1, [r0]
179
180	/* invalidate all cache ways */
181	movw r0, #PL310_INV_BY_WAY
182	movt r0, #PL310_BASE_H
183	movw r1, #0x00FF
184	movt r1, #0x0000
185	str  r1, [r0]
186
187	mov pc, lr
188END_FUNC arm_cl2_config
189/* End of arm_cl2_config */
190
191
192/*
193 * Memory Cache Level2 Enable Function
194 *
195 * If PL310 supports FZLW, enable also FZL in A9 core
196 *
197 * Use scratables registers R0-R3.
198 * No stack usage.
199 * LR store return address.
200 * Trap CPU in case of error.
201 * TODO: to be moved to PL310 code (tz_svce_pl310.S ?)
202 */
203FUNC arm_cl2_enable , :
204
205
206	/* Enable PL310 ctrl -> only set lsb bit */
207	movw r0, #PL310_CTRL
208	movt r0, #PL310_BASE_H
209	mov  r1, #0x1
210	str  r1, [r0]
211
212	/* if L2 FLZW enable, enable in L1 */
213	movw r0, #PL310_AUX_CTRL
214	movt r0, #PL310_BASE_H
215	ldr  r1, [r0]
216	tst  r1, #(1 << 0) /* test AUX_CTRL[FLZ] */
217	mrc  p15, 0, r0, c1, c0, 1
218	orrne r0, r0, #(1 << 3) /* enable ACTLR[FLZW] */
219	mcr  p15, 0, r0, c1, c0, 1
220
221	mov pc, lr
222END_FUNC arm_cl2_enable
223
224/*
225 * Cortex A9 configuration early configuration
226 *
227 * Use scratables registers R0-R3.
228 * No stack usage.
229 * LR store return address.
230 * Trap CPU in case of error.
231 */
232FUNC plat_cpu_reset_early , :
233
234	/* only r3p0 is supported */
235	mrc  p15, 0, r0, c0, c0, 0  /* read A9 ID */
236	movw r1, #CPUID_A9_R3P0_L
237	movt r1, #CPUID_A9_R3P0_H
238	cmp  r0, r1
239	beq  _early_a9_r3p0
240	b . /* TODO: unknown id: reset? log? */
241
242_early_a9_r3p0:
243	/*
244	 * Mandated HW config loaded
245	 *
246	 * SCTLR = 0x00004000
247	 * - Round-Robin replac. for icache, btac, i/duTLB (bit14: RoundRobin)
248	 *
249	 * ACTRL = 0x00000041
250	 * - core always in full SMP (FW bit0=1, SMP bit6=1)
251	 * - L2 write full line of zero disabled (bit3=0)
252	 *   (keep WFLZ low. Will be set once outer L2 is ready)
253	 *
254	 * NSACR = 0x00020C00
255	 * - NSec cannot change ACTRL.SMP (NS_SMP bit18=0)
256	 * - Nsec can lockdown TLB (TL bit17=1)
257	 * - NSec cannot access PLE (PLE bit16=0)
258	 * - NSec can use SIMD/VFP (CP10/CP11) (bit15:14=2b00, bit11:10=2b11)
259	 *
260	 * PCR = 0x00000001
261	 * - no change latency, enable clk gating
262	 */
263	movw r0, #0x4000
264	movt r0, #0x0000
265	write_sctlr r0
266
267	movw r0, #0x0041
268	movt r0, #0x0000
269	write_actlr r0
270
271	movw r0, #0x0C00
272	movt r0, #0x0002
273	write_nsacr r0
274
275	movw r0, #0x0000
276	movt r0, #0x0001
277	write_pcr r0
278
279	/*
280	 * GIC configuration
281	 *
282	 * Register ICDISR0 = 0xFFFFFFFF
283	 * - All local interrupts are NonSecure.
284	 *
285	 * Register ICCPMR = 0xFFFFFFFF
286	 */
287
288	movw r0, #GIC_DIST_ISR0
289	movt r0, #GIC_DIST_BASE_H
290	mov  r1, #0xFFFFFFFF
291	str  r1, [r0]
292
293	movw r0, #CORE_ICC_ICCPMR
294	movt r0, #GIC_CPU_BASE_H
295	mov  r1, #0xFFFFFFFF
296	str  r1, [r0]
297
298	mov pc, lr /* back to tzinit */
299END_FUNC plat_cpu_reset_early
300
301/*
302 * arm_secboot_errata - arm errata, specific per core revision
303 *
304 * Use scratables registers R0-R3.
305 * No stack usage.
306 * LR store return address.
307 * Trap CPU in case of error.
308 */
309FUNC arm_secboot_errata , :
310
311	mrc  p15, 0, r0, c0, c0, 0  /* read A9 ID */
312	movw r1, #CPUID_A9_R2P2_L
313	movt r1, #CPUID_A9_R2P2_H
314	cmp  r0, r1
315	beq  _errata_a9_r2p2
316	movw r1, #CPUID_A9_R3P0_L
317	movt r1, #CPUID_A9_R3P0_H
318	cmp  r0, r1
319	beq  _errata_a9_r3p0
320	b . /* TODO: unknown id: reset? log? */
321
322_errata_a9_r2p2:
323	/* unsupported version. TODO: needs to be supported */
324	b . /* TODO: unknown id: reset? log? */
325
326_errata_a9_r3p0:
327	mov pc, lr
328END_FUNC arm_secboot_errata
329
330/*
331 * A9 secured config, needed only from a single core
332 *
333 * Use scratables registers R0-R3.
334 * No stack usage.
335 * LR store return address.
336 * Trap CPU in case of error.
337 *
338 * TODO: size optim in code
339 */
340FUNC plat_cpu_reset_late , :
341
342	mrc p15, 0, r0, c0, c0, 5
343	ands r0, #3
344	beq _boot_late_primary_cpu
345
346_boot_late_secondary_cpu:
347	mov pc, lr
348
349_boot_late_primary_cpu:
350	/*
351	 * Snoop Control Unit configuration
352	 *
353	 * SCU is enabled with filtering off.
354	 * Both Secure/Unsecure can access SCU and timers
355	 *
356	 * 0x00 SCUControl = 0x00000060 !!!  should be 0x5 !   A NETTOYER !!!!!!!!!!!!!!!!!!!!!!!!!
357	 * 0x04 SCUConfiguration =  ???                        A NETTOYER !!!!!!!!!!!!!!!!!!!!!!!!!
358	 * 0x0C SCUInvalidateAll (Secure cfg)
359	 * 0x40 FilteringStartAddress = 0x40000000
360	 * 0x44 FilteeringEndAddress - 0x80000000
361	 * 0x50 SCUAccessControl
362	 * 0x54 SCUSecureAccessControl
363	 */
364
365	/*
366	 * SCU Access Register : SAC = 0x00000003
367	 * - both secure CPU access SCU
368	 */
369	movw r0, #SCU_SAC /* LSB */
370	movt r0, #SCU_BASE_H /* MSB */
371	movw r1, #0x0003
372	movt r1, #0x0000
373	str  r1, [r0]
374
375	/*
376	 * SCU NonSecure Access Register : SNSAC : 0x00000333
377	 * - both nonsec cpu access SCU, private and global timer
378	 */
379	movw r0, #SCU_NSAC /* LSB */
380	movt r0, #SCU_BASE_H /* MSB */
381	movw r1, #0x0333
382	movt r1, #0x0000
383	str  r1, [r0]
384
385	/*
386	 * SCU Filtering End Address register: SFEA
387	 */
388	movw r0, #SCU_FILT_EA /* LSB */
389	movt r0, #SCU_BASE_H /* MSB */
390	movw r1, #(CPU_PORT_FILT_END & 0xFFFF)
391	movt r1, #(CPU_PORT_FILT_END >> 16)
392	str  r1, [r0]
393
394	/*
395	 * SCU Filtering Start Address register: SFSA
396	 */
397	movw r0, #SCU_FILT_SA /* LSB */
398	movt r0, #SCU_BASE_H /* MSB */
399	movw r1, #(CPU_PORT_FILT_START & 0xFFFF)
400	movt r1, #(CPU_PORT_FILT_START >> 16)
401	str  r1, [r0]
402
403	/*
404	 * SCU Control Register : CTRL = 0x00000065
405	 * - ic stanby enable=1
406	 * - scu standby enable=1
407	 * - scu enable=1
408	 */
409	movw r0, #SCU_CTRL /* LSB */
410	movt r0, #SCU_BASE_H /* MSB */
411	movw r1, #0x0065
412	movt r1, #0x0000
413	str	 r1, [r0]
414
415	/*- GIC secure configuration ---*/
416
417	/*
418	 * Register ICDISR[1-31] = 0xFFFFFFFF
419	 * - All external interrupts are NonSecure.
420	 */
421	movw r0, #GIC_DIST_ISR1
422	movt r0, #GIC_DIST_BASE_H
423	mov  r2, #0xFFFFFFFF
424	mov  r1, #31 /* Nb of loop rounds */
425loop_1:
426	str r2, [r0]
427	add r0, #4
428	sub r1, r1, #1
429	cmp r1, #0
430	bne loop_1
431
432
433	/*- PL310 Memory Controller (Note: should be done with NS=1) ---*/
434
435	/*
436	 * reg12_addr_filtering_end
437	 */
438	movw r0, #PL310_ADDR_FILT_END
439	movt r0, #PL310_BASE_H
440	movw r1, #(CPU_PORT_FILT_END & 0xFFFF)
441	movt r1, #(CPU_PORT_FILT_END >> 16)
442	str  r1, [r0]
443
444	/*
445	 * reg12_addr_filtering_start
446	 */
447	movw r0, #PL310_ADDR_FILT_START
448	movt r0, #PL310_BASE_H
449	movw r1, #((CPU_PORT_FILT_START & 0xFFFF) | 1)
450	movt r1, #(CPU_PORT_FILT_START >> 16)
451	str  r1, [r0]
452
453	/* Allow NSec to manage FIQ/Imprecise abort */
454	mrc p15, 0, r0, c1, c1, 0    /* read Secure Configuration Register */
455	orr r0, r0, #0x30            /* SCR[FW]=1, SCR[AW]=1 */
456	mcr p15, 0, r0, c1, c1, 0    /* write updated value in Secure Configuration Register */
457
458	mov pc, lr
459END_FUNC plat_cpu_reset_late
460