1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (C) 2017 Timesys Corporation.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <arm32.h>
30 #include <console.h>
31 #include <drivers/atmel_saic.h>
32 #include <drivers/atmel_uart.h>
33 #include <io.h>
34 #include <kernel/boot.h>
35 #include <kernel/interrupt.h>
36 #include <kernel/misc.h>
37 #include <kernel/panic.h>
38 #include <kernel/tz_ssvce_def.h>
39 #include <matrix.h>
40 #include <mm/core_mmu.h>
41 #include <mm/core_memprot.h>
42 #include <platform_config.h>
43 #include <sama5d2.h>
44 #include <stdint.h>
45 #include <sm/optee_smc.h>
46 #include <tz_matrix.h>
47
48 static struct atmel_uart_data console_data;
49 register_phys_mem_pgdir(MEM_AREA_IO_SEC, CONSOLE_UART_BASE,
50 CORE_MMU_PGDIR_SIZE);
51
console_init(void)52 void console_init(void)
53 {
54 atmel_uart_init(&console_data, CONSOLE_UART_BASE);
55 register_serial_console(&console_data.chip);
56 }
57
58 register_phys_mem_pgdir(MEM_AREA_IO_SEC, AT91C_BASE_MATRIX32,
59 CORE_MMU_PGDIR_SIZE);
60 register_phys_mem_pgdir(MEM_AREA_IO_SEC, AT91C_BASE_MATRIX64,
61 CORE_MMU_PGDIR_SIZE);
62
matrix32_base(void)63 vaddr_t matrix32_base(void)
64 {
65 static void *va;
66
67 if (cpu_mmu_enabled()) {
68 if (!va)
69 va = phys_to_virt(AT91C_BASE_MATRIX32, MEM_AREA_IO_SEC,
70 1);
71 return (vaddr_t)va;
72 }
73 return AT91C_BASE_MATRIX32;
74 }
75
matrix64_base(void)76 vaddr_t matrix64_base(void)
77 {
78 static void *va;
79
80 if (cpu_mmu_enabled()) {
81 if (!va)
82 va = phys_to_virt(AT91C_BASE_MATRIX64, MEM_AREA_IO_SEC,
83 1);
84 return (vaddr_t)va;
85 }
86 return AT91C_BASE_MATRIX64;
87 }
88
matrix_configure_slave_h64mx(void)89 static void matrix_configure_slave_h64mx(void)
90 {
91 unsigned int ddr_port;
92 unsigned int ssr_setting;
93 unsigned int sasplit_setting;
94 unsigned int srtop_setting;
95
96 /*
97 * 0: Bridge from H64MX to AXIMX
98 * (Internal ROM, Crypto Library, PKCC RAM): Always Secured
99 */
100
101 /* 1: H64MX Peripheral Bridge: SDMMC0, SDMMC1 Non-Secure */
102 srtop_setting = MATRIX_SRTOP(1, MATRIX_SRTOP_VALUE_128M)
103 | MATRIX_SRTOP(2, MATRIX_SRTOP_VALUE_128M);
104 sasplit_setting = MATRIX_SASPLIT(1, MATRIX_SASPLIT_VALUE_128M)
105 | MATRIX_SASPLIT(2, MATRIX_SASPLIT_VALUE_128M);
106 ssr_setting = (MATRIX_LANSECH_NS(1)
107 | MATRIX_LANSECH_NS(2)
108 | MATRIX_RDNSECH_NS(1)
109 | MATRIX_RDNSECH_NS(2)
110 | MATRIX_WRNSECH_NS(1)
111 | MATRIX_WRNSECH_NS(2));
112 matrix_configure_slave_security(matrix64_base(),
113 H64MX_SLAVE_PERI_BRIDGE,
114 srtop_setting,
115 sasplit_setting,
116 ssr_setting);
117
118 /*
119 * Matrix DDR configuration is hardcoded here and is difficult to
120 * generate at runtime. Since this configuration expect the secure
121 * DRAM to be at start of RAM and 8M of size, enforce it here.
122 */
123 COMPILE_TIME_ASSERT(CFG_TZDRAM_START == AT91C_BASE_DDRCS);
124 COMPILE_TIME_ASSERT(CFG_TZDRAM_SIZE == 0x800000);
125
126 /* 2 ~ 9 DDR2 Port1 ~ 7: Non-Secure, except op-tee tee/ta memory */
127 srtop_setting = MATRIX_SRTOP(0, MATRIX_SRTOP_VALUE_128M);
128 sasplit_setting = (MATRIX_SASPLIT(0, MATRIX_SASPLIT_VALUE_8M)
129 | MATRIX_SASPLIT(1, MATRIX_SASPLIT_VALUE_128M)
130 | MATRIX_SASPLIT(2, MATRIX_SASPLIT_VALUE_128M)
131 | MATRIX_SASPLIT(3, MATRIX_SASPLIT_VALUE_128M));
132 ssr_setting = (MATRIX_LANSECH_S(0)
133 | MATRIX_LANSECH_NS(1)
134 | MATRIX_LANSECH_NS(2)
135 | MATRIX_LANSECH_NS(3)
136 | MATRIX_RDNSECH_S(0)
137 | MATRIX_RDNSECH_NS(1)
138 | MATRIX_RDNSECH_NS(2)
139 | MATRIX_RDNSECH_NS(3)
140 | MATRIX_WRNSECH_S(0)
141 | MATRIX_WRNSECH_NS(1)
142 | MATRIX_WRNSECH_NS(2)
143 | MATRIX_WRNSECH_NS(3));
144 /* DDR port 0 not used from NWd */
145 for (ddr_port = 1; ddr_port < 8; ddr_port++) {
146 matrix_configure_slave_security(matrix64_base(),
147 (H64MX_SLAVE_DDR2_PORT_0 + ddr_port),
148 srtop_setting,
149 sasplit_setting,
150 ssr_setting);
151 }
152
153 /*
154 * 10: Internal SRAM 128K:
155 * - First 64K are reserved for suspend code in Secure World
156 * - Last 64K are for Non-Secure world (used by CAN)
157 */
158 srtop_setting = MATRIX_SRTOP(0, MATRIX_SRTOP_VALUE_128K);
159 sasplit_setting = MATRIX_SASPLIT(0, MATRIX_SRTOP_VALUE_64K);
160 ssr_setting = (MATRIX_LANSECH_S(0) | MATRIX_RDNSECH_S(0) |
161 MATRIX_WRNSECH_S(0));
162 matrix_configure_slave_security(matrix64_base(),
163 H64MX_SLAVE_INTERNAL_SRAM,
164 srtop_setting, sasplit_setting,
165 ssr_setting);
166
167 /* 11: Internal SRAM 128K (Cache L2): Default */
168
169 /* 12: QSPI0: Normal world */
170 /* 13: QSPI1: Normal world */
171 srtop_setting = MATRIX_SRTOP(0, MATRIX_SRTOP_VALUE_128M);
172 sasplit_setting = MATRIX_SASPLIT(0, MATRIX_SASPLIT_VALUE_128M);
173 ssr_setting = MATRIX_LANSECH_NS(0) | MATRIX_RDNSECH_NS(0) |
174 MATRIX_WRNSECH_NS(0);
175
176 matrix_configure_slave_security(matrix64_base(), H64MX_SLAVE_QSPI0,
177 srtop_setting, sasplit_setting,
178 ssr_setting);
179 matrix_configure_slave_security(matrix64_base(), H64MX_SLAVE_QSPI1,
180 srtop_setting, sasplit_setting,
181 ssr_setting);
182 /* 14: AESB: Default */
183 }
184
matrix_configure_slave_h32mx(void)185 static void matrix_configure_slave_h32mx(void)
186 {
187 unsigned int ssr_setting;
188 unsigned int sasplit_setting;
189 unsigned int srtop_setting;
190
191 /* 0: Bridge from H32MX to H64MX: Not Secured */
192 /* 1: H32MX Peripheral Bridge 0: Not Secured */
193 /* 2: H32MX Peripheral Bridge 1: Not Secured */
194
195 /*
196 * 3: External Bus Interface
197 * EBI CS0 Memory(256M) ----> Slave Region 0, 1
198 * EBI CS1 Memory(256M) ----> Slave Region 2, 3
199 * EBI CS2 Memory(256M) ----> Slave Region 4, 5
200 * EBI CS3 Memory(128M) ----> Slave Region 6
201 * NFC Command Registers(128M) -->Slave Region 7
202 * NANDFlash(EBI CS3) --> Slave Region 6: Non-Secure
203 */
204 srtop_setting = MATRIX_SRTOP(6, MATRIX_SRTOP_VALUE_128M);
205 srtop_setting |= MATRIX_SRTOP(7, MATRIX_SRTOP_VALUE_128M);
206 sasplit_setting = MATRIX_SASPLIT(6, MATRIX_SASPLIT_VALUE_128M);
207 sasplit_setting |= MATRIX_SASPLIT(7, MATRIX_SASPLIT_VALUE_128M);
208 ssr_setting = (MATRIX_LANSECH_NS(6)
209 | MATRIX_RDNSECH_NS(6)
210 | MATRIX_WRNSECH_NS(6));
211 ssr_setting |= (MATRIX_LANSECH_NS(7)
212 | MATRIX_RDNSECH_NS(7)
213 | MATRIX_WRNSECH_NS(7));
214 matrix_configure_slave_security(matrix32_base(),
215 H32MX_EXTERNAL_EBI,
216 srtop_setting,
217 sasplit_setting,
218 ssr_setting);
219
220 /* 4: NFC SRAM (4K): Non-Secure */
221 srtop_setting = MATRIX_SRTOP(0, MATRIX_SRTOP_VALUE_8K);
222 sasplit_setting = MATRIX_SASPLIT(0, MATRIX_SASPLIT_VALUE_8K);
223 ssr_setting = (MATRIX_LANSECH_NS(0)
224 | MATRIX_RDNSECH_NS(0)
225 | MATRIX_WRNSECH_NS(0));
226 matrix_configure_slave_security(matrix32_base(),
227 H32MX_NFC_SRAM,
228 srtop_setting,
229 sasplit_setting,
230 ssr_setting);
231
232 /* 5:
233 * USB Device High Speed Dual Port RAM (DPR): 1M
234 * USB Host OHCI registers: 1M
235 * USB Host EHCI registers: 1M
236 */
237 srtop_setting = (MATRIX_SRTOP(0, MATRIX_SRTOP_VALUE_1M)
238 | MATRIX_SRTOP(1, MATRIX_SRTOP_VALUE_1M)
239 | MATRIX_SRTOP(2, MATRIX_SRTOP_VALUE_1M));
240 sasplit_setting = (MATRIX_SASPLIT(0, MATRIX_SASPLIT_VALUE_1M)
241 | MATRIX_SASPLIT(1, MATRIX_SASPLIT_VALUE_1M)
242 | MATRIX_SASPLIT(2, MATRIX_SASPLIT_VALUE_1M));
243 ssr_setting = (MATRIX_LANSECH_NS(0)
244 | MATRIX_LANSECH_NS(1)
245 | MATRIX_LANSECH_NS(2)
246 | MATRIX_RDNSECH_NS(0)
247 | MATRIX_RDNSECH_NS(1)
248 | MATRIX_RDNSECH_NS(2)
249 | MATRIX_WRNSECH_NS(0)
250 | MATRIX_WRNSECH_NS(1)
251 | MATRIX_WRNSECH_NS(2));
252 matrix_configure_slave_security(matrix32_base(),
253 H32MX_USB,
254 srtop_setting,
255 sasplit_setting,
256 ssr_setting);
257 }
258
259 static unsigned int security_ps_peri_id[] = {
260 AT91C_ID_PMC,
261 AT91C_ID_ARM,
262 AT91C_ID_PIT,
263 AT91C_ID_WDT,
264 AT91C_ID_GMAC,
265 AT91C_ID_XDMAC0,
266 AT91C_ID_XDMAC1,
267 AT91C_ID_ICM,
268 AT91C_ID_AES,
269 AT91C_ID_AESB,
270 AT91C_ID_TDES,
271 AT91C_ID_SHA,
272 AT91C_ID_MPDDRC,
273 AT91C_ID_HSMC,
274 AT91C_ID_FLEXCOM0,
275 AT91C_ID_FLEXCOM1,
276 AT91C_ID_FLEXCOM2,
277 AT91C_ID_FLEXCOM3,
278 AT91C_ID_FLEXCOM4,
279 AT91C_ID_UART0,
280 AT91C_ID_UART1,
281 AT91C_ID_UART2,
282 AT91C_ID_UART3,
283 AT91C_ID_UART4,
284 AT91C_ID_TWI0,
285 AT91C_ID_TWI1,
286 AT91C_ID_SDMMC0,
287 AT91C_ID_SDMMC1,
288 AT91C_ID_SPI0,
289 AT91C_ID_SPI1,
290 AT91C_ID_TC0,
291 AT91C_ID_TC1,
292 AT91C_ID_PWM,
293 AT91C_ID_ADC,
294 AT91C_ID_UHPHS,
295 AT91C_ID_UDPHS,
296 AT91C_ID_SSC0,
297 AT91C_ID_SSC1,
298 AT91C_ID_LCDC,
299 AT91C_ID_ISI,
300 AT91C_ID_TRNG,
301 AT91C_ID_PDMIC,
302 AT91C_ID_SFC,
303 AT91C_ID_QSPI0,
304 AT91C_ID_QSPI1,
305 AT91C_ID_I2SC0,
306 AT91C_ID_I2SC1,
307 AT91C_ID_CAN0_INT0,
308 AT91C_ID_CAN1_INT0,
309 AT91C_ID_CLASSD,
310 AT91C_ID_SFR,
311 AT91C_ID_L2CC,
312 AT91C_ID_CAN0_INT1,
313 AT91C_ID_CAN1_INT1,
314 AT91C_ID_GMAC_Q1,
315 AT91C_ID_GMAC_Q2,
316 AT91C_ID_SDMMC0_TIMER,
317 AT91C_ID_SDMMC1_TIMER,
318 AT91C_ID_SYS,
319 AT91C_ID_ACC,
320 AT91C_ID_RXLP,
321 AT91C_ID_SFRBU,
322 AT91C_ID_CHIPID,
323 };
324
matrix_init(void)325 static int matrix_init(void)
326 {
327 matrix_write_protect_disable(matrix64_base());
328 matrix_write_protect_disable(matrix32_base());
329
330 matrix_configure_slave_h64mx();
331 matrix_configure_slave_h32mx();
332
333 return matrix_configure_periph_non_secure(security_ps_peri_id,
334 ARRAY_SIZE(security_ps_peri_id));
335 }
336
plat_primary_init_early(void)337 void plat_primary_init_early(void)
338 {
339 matrix_init();
340 }
341
itr_core_handler(void)342 void itr_core_handler(void)
343 {
344 atmel_saic_it_handle();
345 }
346
main_init_gic(void)347 void main_init_gic(void)
348 {
349 if (atmel_saic_setup())
350 panic("Failed to init interrupts\n");
351 }
352