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