xref: /optee_os/core/arch/arm/plat-stm/tz_a9init.S (revision a31f13fbe554136fa2314c7daf1af9d8b0b0ad8d)
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#include <kernel/unwind.h>
38
39#define CPUID_A9_R3P0_H 0x413f
40#define CPUID_A9_R3P0_L 0xc090
41
42.section .text
43.balign 4
44.code 32
45
46/*
47 * Memory Cache Level2 Configuration Function
48 *
49 * Use scratables registers R0-R3.
50 * No stack usage.
51 * LR store return address.
52 * Trap CPU in case of error.
53 */
54FUNC arm_cl2_config , :
55UNWIND(	.fnstart)
56
57	mrc  p15, 0, r0, c0, c0, 0  /* read A9 ID */
58	movw r1, #CPUID_A9_R3P0_L
59	movt r1, #CPUID_A9_R3P0_H
60	cmp  r0, r1
61	beq  _config_l2cc_r3p0
62	b . /* TODO: unknown id: reset? log? */
63
64_config_l2cc_r3p0:
65	/*
66	 * TAG RAM Control Register
67	 *
68	 * bit[10:8]:1 - 2 cycle of write accesses latency
69	 * bit[6:4]:1 - 2 cycle of read accesses latency
70	 * bit[2:0]:1 - 2 cycle of setup latency
71	 */
72	movw r0, #PL310_TAG_RAM_CTRL
73	movt r0, #PL310_BASE_H
74	ldr  r2, [r0]
75	movw r1, #0xf888
76	movt r1, #0xffff
77	and  r2,r2,r1
78	movw r1, #0xf999
79	movt r1, #0xffff
80	orr  r2,r2,r1
81	str  r2, [r0]
82
83	/*
84	 * DATA RAM Control Register
85	 *
86	 * bit[10:8]:2 - 3 cycle of write accesses latency
87	 * bit[6:4]:2 - 3 cycle of read accesses latency
88	 * bit[2:0]:2 - 3 cycle of setup latency
89	 */
90	movw r0, #PL310_DATA_RAM_CTRL
91	movt r0, #PL310_BASE_H
92	ldr  r2, [r0]
93	movw r1, #0xf888
94	movt r1, #0xffff
95	and  r2,r2,r1
96	movw r1, #0xfaaa
97	movt r1, #0xffff
98	orr  r2,r2,r1
99	str  r2, [r0]
100
101	/*
102	 * Auxiliary Control Register = 0x3C480800
103	 *
104	 * I/Dcache prefetch enabled (bit29:28=2b11)
105	 * NS can access interrupts (bit27=1)
106	 * NS can lockown cache lines (bit26=1)
107	 * Pseudo-random replacement policy (bit25=0)
108	 * Force write allocated (default)
109	 * Shared attribute internally ignored (bit22=1, bit13=0)
110	 * Parity disabled (bit21=0)
111	 * Event monitor disabled (bit20=0)
112	 * 128kB ways, 8-way associativity (bit19:17=3b100 bit16=0)
113	 * Store buffer device limitation enabled (bit11=1)
114	 * Cacheable accesses have high prio (bit10=0)
115	 * Full Line Zero (FLZ) disabled (bit0=0)
116	 */
117	movw r0, #PL310_AUX_CTRL
118	movt r0, #PL310_BASE_H
119	movw r1, #0x0800
120	movt r1, #0x3C48
121	str  r1, [r0]
122
123	/*
124	 * Prefetch Control Register = 0x31000007
125	 *
126	 * Double linefill disabled (bit30=0)
127	 * I/D prefetch enabled (bit29:28=2b11)
128	 * Prefetch drop enabled (bit24=1)
129	 * Incr double linefill disable (bit23=0)
130	 * Prefetch offset = 7 (bit4:0)
131	 */
132	movw r0, #PL310_PREFETCH_CTRL
133	movt r0, #PL310_BASE_H
134	movw r1, #0x0007
135	movt r1, #0x3100
136	str  r1, [r0]
137
138	/*
139	 * Power Register = 0x00000003
140	 *
141	 * Dynamic clock gating enabled
142	 * Standby mode enabled
143	 */
144	movw r0, #PL310_POWER_CTRL
145	movt r0, #PL310_BASE_H
146	movw r1, #0x0003
147	movt r1, #0x0000
148	str  r1, [r0]
149
150	/* invalidate all cache ways */
151	movw r0, #PL310_INV_BY_WAY
152	movt r0, #PL310_BASE_H
153	movw r1, #0x00FF
154	movt r1, #0x0000
155	str  r1, [r0]
156
157	mov pc, lr
158UNWIND(	.fnend)
159END_FUNC arm_cl2_config
160/* End of arm_cl2_config */
161
162
163/*
164 * Memory Cache Level2 Enable Function
165 *
166 * If PL310 supports FZLW, enable also FZL in A9 core
167 *
168 * Use scratables registers R0-R3.
169 * No stack usage.
170 * LR store return address.
171 * Trap CPU in case of error.
172 * TODO: to be moved to PL310 code (tz_svce_pl310.S ?)
173 */
174FUNC arm_cl2_enable , :
175UNWIND(	.fnstart)
176
177
178	/* Enable PL310 ctrl -> only set lsb bit */
179	movw r0, #PL310_CTRL
180	movt r0, #PL310_BASE_H
181	mov  r1, #0x1
182	str  r1, [r0]
183
184	/* if L2 FLZW enable, enable in L1 */
185	movw r0, #PL310_AUX_CTRL
186	movt r0, #PL310_BASE_H
187	ldr  r1, [r0]
188	tst  r1, #(1 << 0) /* test AUX_CTRL[FLZ] */
189	mrc  p15, 0, r0, c1, c0, 1
190	orrne r0, r0, #(1 << 3) /* enable ACTLR[FLZW] */
191	mcr  p15, 0, r0, c1, c0, 1
192
193	mov pc, lr
194UNWIND(	.fnend)
195END_FUNC arm_cl2_enable
196
197/*
198 * Cortex A9 configuration early configuration
199 *
200 * Use scratables registers R0-R3.
201 * No stack usage.
202 * LR store return address.
203 * Trap CPU in case of error.
204 */
205FUNC plat_cpu_reset_early , :
206UNWIND(	.fnstart)
207
208	/* only r3p0 is supported */
209	mrc  p15, 0, r0, c0, c0, 0  /* read A9 ID */
210	movw r1, #CPUID_A9_R3P0_L
211	movt r1, #CPUID_A9_R3P0_H
212	cmp  r0, r1
213	beq  _early_a9_r3p0
214	b . /* TODO: unknown id: reset? log? */
215
216_early_a9_r3p0:
217	/*
218	 * Mandated HW config loaded
219	 *
220	 * SCTLR = 0x00004000
221	 * - Round-Robin replac. for icache, btac, i/duTLB (bit14: RoundRobin)
222	 *
223	 * ACTRL = 0x00000041
224	 * - core always in full SMP (FW bit0=1, SMP bit6=1)
225	 * - L2 write full line of zero disabled (bit3=0)
226	 *   (keep WFLZ low. Will be set once outer L2 is ready)
227	 *
228	 * NSACR = 0x00020C00
229	 * - NSec cannot change ACTRL.SMP (NS_SMP bit18=0)
230	 * - Nsec can lockdown TLB (TL bit17=1)
231	 * - NSec cannot access PLE (PLE bit16=0)
232	 * - NSec can use SIMD/VFP (CP10/CP11) (bit15:14=2b00, bit11:10=2b11)
233	 *
234	 * PCR = 0x00000001
235	 * - no change latency, enable clk gating
236	 */
237	movw r0, #0x4000
238	movt r0, #0x0000
239	write_sctlr r0
240
241	movw r0, #0x0041
242	movt r0, #0x0000
243	write_actlr r0
244
245	movw r0, #0x0C00
246	movt r0, #0x0002
247	write_nsacr r0
248
249	movw r0, #0x0000
250	movt r0, #0x0001
251	write_pcr r0
252
253	/*
254	 * GIC configuration
255	 *
256	 * Register ICDISR0 = 0xFFFFFFFF
257	 * - All local interrupts are NonSecure.
258	 *
259	 * Register ICCPMR = 0xFFFFFFFF
260	 */
261
262	movw r0, #GIC_DIST_ISR0
263	movt r0, #GIC_DIST_BASE_H
264	mov  r1, #0xFFFFFFFF
265	str  r1, [r0]
266
267	movw r0, #CORE_ICC_ICCPMR
268	movt r0, #GIC_CPU_BASE_H
269	mov  r1, #0xFFFFFFFF
270	str  r1, [r0]
271
272	mov pc, lr /* back to tzinit */
273UNWIND(	.fnend)
274END_FUNC plat_cpu_reset_early
275
276/*
277 * A9 secured config, needed only from a single core
278 *
279 * Use scratables registers R0-R3.
280 * No stack usage.
281 * LR store return address.
282 * Trap CPU in case of error.
283 *
284 * TODO: size optim in code
285 */
286FUNC plat_cpu_reset_late , :
287UNWIND(	.fnstart)
288
289	mrc p15, 0, r0, c0, c0, 5
290	ands r0, #3
291	beq _boot_late_primary_cpu
292
293_boot_late_secondary_cpu:
294	mov pc, lr
295
296_boot_late_primary_cpu:
297	/*
298	 * Snoop Control Unit configuration
299	 *
300	 * SCU is enabled with filtering off.
301	 * Both Secure/Unsecure can access SCU and timers
302	 *
303	 * 0x00 SCUControl = 0x00000060 !!!  should be 0x5 !   A NETTOYER !!!!!!!!!!!!!!!!!!!!!!!!!
304	 * 0x04 SCUConfiguration =  ???                        A NETTOYER !!!!!!!!!!!!!!!!!!!!!!!!!
305	 * 0x0C SCUInvalidateAll (Secure cfg)
306	 * 0x40 FilteringStartAddress = 0x40000000
307	 * 0x44 FilteeringEndAddress - 0x80000000
308	 * 0x50 SCUAccessControl
309	 * 0x54 SCUSecureAccessControl
310	 */
311
312	/*
313	 * SCU Access Register : SAC = 0x00000003
314	 * - both secure CPU access SCU
315	 */
316	movw r0, #SCU_SAC /* LSB */
317	movt r0, #SCU_BASE_H /* MSB */
318	movw r1, #0x0003
319	movt r1, #0x0000
320	str  r1, [r0]
321
322	/*
323	 * SCU NonSecure Access Register : SNSAC : 0x00000333
324	 * - both nonsec cpu access SCU, private and global timer
325	 */
326	movw r0, #SCU_NSAC /* LSB */
327	movt r0, #SCU_BASE_H /* MSB */
328	movw r1, #0x0333
329	movt r1, #0x0000
330	str  r1, [r0]
331
332	/*
333	 * SCU Filtering End Address register: SFEA
334	 */
335	movw r0, #SCU_FILT_EA /* LSB */
336	movt r0, #SCU_BASE_H /* MSB */
337	movw r1, #(CPU_PORT_FILT_END & 0xFFFF)
338	movt r1, #(CPU_PORT_FILT_END >> 16)
339	str  r1, [r0]
340
341	/*
342	 * SCU Filtering Start Address register: SFSA
343	 */
344	movw r0, #SCU_FILT_SA /* LSB */
345	movt r0, #SCU_BASE_H /* MSB */
346	movw r1, #(CPU_PORT_FILT_START & 0xFFFF)
347	movt r1, #(CPU_PORT_FILT_START >> 16)
348	str  r1, [r0]
349
350	/*
351	 * SCU Control Register : CTRL = 0x00000065
352	 * - ic stanby enable=1
353	 * - scu standby enable=1
354	 * - scu enable=1
355	 */
356	movw r0, #SCU_CTRL /* LSB */
357	movt r0, #SCU_BASE_H /* MSB */
358	movw r1, #0x0065
359	movt r1, #0x0000
360	str	 r1, [r0]
361
362	/*- GIC secure configuration ---*/
363
364	/*
365	 * Register ICDISR[1-31] = 0xFFFFFFFF
366	 * - All external interrupts are NonSecure.
367	 */
368	movw r0, #GIC_DIST_ISR1
369	movt r0, #GIC_DIST_BASE_H
370	mov  r2, #0xFFFFFFFF
371	mov  r1, #31 /* Nb of loop rounds */
372loop_1:
373	str r2, [r0]
374	add r0, #4
375	sub r1, r1, #1
376	cmp r1, #0
377	bne loop_1
378
379
380	/*- PL310 Memory Controller (Note: should be done with NS=1) ---*/
381
382	/*
383	 * reg12_addr_filtering_end
384	 */
385	movw r0, #PL310_ADDR_FILT_END
386	movt r0, #PL310_BASE_H
387	movw r1, #(CPU_PORT_FILT_END & 0xFFFF)
388	movt r1, #(CPU_PORT_FILT_END >> 16)
389	str  r1, [r0]
390
391	/*
392	 * reg12_addr_filtering_start
393	 */
394	movw r0, #PL310_ADDR_FILT_START
395	movt r0, #PL310_BASE_H
396	movw r1, #((CPU_PORT_FILT_START & 0xFFFF) | 1)
397	movt r1, #(CPU_PORT_FILT_START >> 16)
398	str  r1, [r0]
399
400	/* Allow NSec to manage FIQ/Imprecise abort */
401	mrc p15, 0, r0, c1, c1, 0    /* read Secure Configuration Register */
402	orr r0, r0, #0x30            /* SCR[FW]=1, SCR[AW]=1 */
403	mcr p15, 0, r0, c1, c1, 0    /* write updated value in Secure Configuration Register */
404
405	mov pc, lr
406UNWIND(	.fnend)
407END_FUNC plat_cpu_reset_late
408