1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2019-2020, STMicroelectronics
4 */
5
6 #include <assert.h>
7 #include <config.h>
8 #include <drivers/clk.h>
9 #include <drivers/clk_dt.h>
10 #include <drivers/stm32mp_dt_bindings.h>
11 #include <drivers/tzc400.h>
12 #include <initcall.h>
13 #include <io.h>
14 #include <keep.h>
15 #include <kernel/dt.h>
16 #include <kernel/interrupt.h>
17 #include <kernel/panic.h>
18 #include <kernel/pm.h>
19 #include <kernel/tee_misc.h>
20 #include <libfdt.h>
21 #include <mm/core_memprot.h>
22 #include <platform_config.h>
23 #include <stm32_util.h>
24 #include <trace.h>
25 #include <util.h>
26
27 #define IS_PAGE_ALIGNED(addr) (((addr) & SMALL_PAGE_MASK) == 0)
28 #define FILTER_MASK(_width) GENMASK_32(((_width) - U(1)), U(0))
29
30 /*
31 * struct stm32mp_tzc_region - Define a TZC400 region configuration
32 * @cfg: Region configuration bit mask
33 * @addr: Region physical base address
34 * @len: Region byte size
35 */
36 struct stm32mp_tzc_region {
37 uint32_t cfg;
38 uint32_t addr;
39 uint32_t len;
40 };
41
42 /*
43 * struct stm32mp_tzc_platdata - Device platform data
44 * @name: Device name for debug purpose
45 * @base: TZC400 IOMEM base address
46 * @clk: TZC400 bus clocks (1 or 2 clocks, depending on the platform)
47 * @mem_base: Physical base address of the memory covered by the device
48 * @mem_size: Byte size of the physical memory covered by the device
49 * @itr_chip: Interrupt controller handle
50 * @itr_num: TZC400 interrupt number handled by @itr_chip
51 */
52 struct stm32mp_tzc_platdata {
53 const char *name;
54 vaddr_t base;
55 struct clk *clk[2];
56 uint32_t mem_base;
57 uint32_t mem_size;
58 struct itr_chip *itr_chip;
59 size_t itr_num;
60 };
61
62 /*
63 * struct stm32mp_tzc_driver_data - Device configuration read from the hardware
64 * @nb_filters: Number of TZC400 filter cells
65 * @nb_regions: Number of regions supported by the TZC400
66 */
67 struct stm32mp_tzc_driver_data {
68 uint32_t nb_filters;
69 uint32_t nb_regions;
70 };
71
72 /*
73 * struct tzc_device - Device data
74 * @pdata: Device configuration read from the platform DT
75 * @ddata: Device configuration data read from the hardware
76 * @reg: Array of regions configured in the controller
77 * @nb_reg_used: Number of cells in @reg
78 */
79 struct tzc_device {
80 struct stm32mp_tzc_platdata pdata;
81 struct stm32mp_tzc_driver_data ddata;
82 struct tzc_region_config *reg;
83 uint32_t nb_reg_used;
84 };
85
86 /*
87 * struct tzc_region_non_sec - Registered non-secure memory region
88 * @region: Memory region description
89 * @link: Link in non-secure memory list
90 *
91 * At TZC driver initialization, there are memory regions defined in the DT
92 * with TZC configuration information. TZC is first configured for each of
93 * these regions and each is carved out from the overall memory address range
94 * controlled by TZC. This results in a series a memory regions that, by
95 * construction, are assigned to non-secure world.
96 */
97 struct tzc_region_non_sec {
98 struct tzc_region_config region;
99 SLIST_ENTRY(tzc_region_non_sec) link;
100 };
101
102 static SLIST_HEAD(nsec_list_head, tzc_region_non_sec) nsec_region_list =
103 SLIST_HEAD_INITIALIZER(nsec_list_head);
104
tzc_it_handler(struct itr_handler * handler __unused)105 static enum itr_return tzc_it_handler(struct itr_handler *handler __unused)
106 {
107 EMSG("TZC permission failure");
108 tzc_fail_dump();
109
110 if (IS_ENABLED(CFG_STM32MP_PANIC_ON_TZC_PERM_VIOLATION))
111 panic();
112 else
113 tzc_int_clear();
114
115 return ITRR_HANDLED;
116 }
117 DECLARE_KEEP_PAGER(tzc_it_handler);
118
tzc_region_check_overlap(struct tzc_device * tzc_dev,const struct tzc_region_config * reg)119 static TEE_Result tzc_region_check_overlap(struct tzc_device *tzc_dev,
120 const struct tzc_region_config *reg)
121 {
122 unsigned int i = 0;
123
124 /* Check if base address already defined in another region */
125 for (i = 0; i < tzc_dev->nb_reg_used; i++)
126 if (reg->base <= tzc_dev->reg[i].top &&
127 reg->top >= tzc_dev->reg[i].base)
128 return TEE_ERROR_ACCESS_CONFLICT;
129
130 return TEE_SUCCESS;
131 }
132
tzc_set_driverdata(struct tzc_device * tzc_dev)133 static void tzc_set_driverdata(struct tzc_device *tzc_dev)
134 {
135 uintptr_t base = tzc_dev->pdata.base;
136 uint32_t regval = 0;
137
138 regval = io_read32(base + BUILD_CONFIG_OFF);
139 tzc_dev->ddata.nb_filters = ((regval >> BUILD_CONFIG_NF_SHIFT) &
140 BUILD_CONFIG_NF_MASK) + 1;
141 tzc_dev->ddata.nb_regions = ((regval >> BUILD_CONFIG_NR_SHIFT) &
142 BUILD_CONFIG_NR_MASK);
143
144 DMSG("TZC400 Filters %"PRIu32" Regions %"PRIu32,
145 tzc_dev->ddata.nb_filters, tzc_dev->ddata.nb_regions);
146 }
147
stm32mp_tzc_region0(bool enable)148 static void stm32mp_tzc_region0(bool enable)
149 {
150 struct tzc_region_config region_cfg_0 = {
151 .base = 0,
152 .top = UINT_MAX,
153 .sec_attr = TZC_REGION_S_NONE,
154 .ns_device_access = 0,
155 };
156
157 if (enable)
158 region_cfg_0.sec_attr = TZC_REGION_S_RDWR;
159
160 tzc_configure_region(0, ®ion_cfg_0);
161 }
162
stm32mp_tzc_reset_region(struct tzc_device * tzc_dev)163 static void stm32mp_tzc_reset_region(struct tzc_device *tzc_dev)
164 {
165 unsigned int i = 0;
166 const struct tzc_region_config cfg = { .top = 0x00000FFF };
167
168 /* Clean old configuration */
169 for (i = 0; i < tzc_dev->ddata.nb_regions; i++)
170 tzc_configure_region(i + 1, &cfg);
171 }
172
append_region(struct tzc_device * tzc_dev,const struct tzc_region_config * region_cfg)173 static TEE_Result append_region(struct tzc_device *tzc_dev,
174 const struct tzc_region_config *region_cfg)
175 {
176 TEE_Result res = TEE_SUCCESS;
177 unsigned int index = tzc_dev->nb_reg_used;
178
179 if (index >= tzc_dev->ddata.nb_regions ||
180 !core_is_buffer_inside(region_cfg->base,
181 region_cfg->top + 1 - region_cfg->base,
182 tzc_dev->pdata.mem_base,
183 tzc_dev->pdata.mem_size))
184 return TEE_ERROR_BAD_PARAMETERS;
185
186 res = tzc_region_check_overlap(tzc_dev, region_cfg);
187 if (res)
188 return res;
189
190 tzc_dev->reg[tzc_dev->nb_reg_used] = *region_cfg;
191 tzc_dev->nb_reg_used++;
192
193 tzc_configure_region(tzc_dev->nb_reg_used, region_cfg);
194
195 return TEE_SUCCESS;
196 }
197
198 static TEE_Result
exclude_region_from_nsec(const struct tzc_region_config * reg_exclude)199 exclude_region_from_nsec(const struct tzc_region_config *reg_exclude)
200 {
201 struct tzc_region_non_sec *reg = NULL;
202
203 SLIST_FOREACH(reg, &nsec_region_list, link) {
204 if (core_is_buffer_inside(reg_exclude->base,
205 reg_exclude->top + 1 -
206 reg_exclude->base,
207 reg->region.base,
208 reg->region.top + 1 -
209 reg->region.base))
210 break;
211 }
212
213 if (!reg)
214 return TEE_ERROR_ITEM_NOT_FOUND;
215
216 if (reg_exclude->base == reg->region.base &&
217 reg_exclude->top == reg->region.top) {
218 /* Remove this entry */
219 SLIST_REMOVE(&nsec_region_list, reg, tzc_region_non_sec, link);
220 free(reg);
221 } else if (reg_exclude->base == reg->region.base) {
222 reg->region.base = reg_exclude->top + 1;
223 } else if (reg_exclude->top == reg->region.top) {
224 reg->region.top = reg_exclude->base - 1;
225 } else {
226 struct tzc_region_non_sec *new_nsec =
227 calloc(1, sizeof(*new_nsec));
228
229 if (!new_nsec)
230 return TEE_ERROR_OUT_OF_MEMORY;
231
232 new_nsec->region = reg->region;
233 reg->region.top = reg_exclude->base - 1;
234 new_nsec->region.base = reg_exclude->top + 1;
235 SLIST_INSERT_AFTER(reg, new_nsec, link);
236 }
237
238 return TEE_SUCCESS;
239 }
240
stm32mp_tzc_cfg_boot_region(struct tzc_device * tzc_dev)241 static void stm32mp_tzc_cfg_boot_region(struct tzc_device *tzc_dev)
242 {
243 unsigned int idx = 0;
244 static struct tzc_region_config boot_region[] = {
245 {
246 .base = CFG_TZDRAM_START,
247 .top = CFG_TZDRAM_START + CFG_TZDRAM_SIZE - 1,
248 .sec_attr = TZC_REGION_S_RDWR,
249 .ns_device_access = 0,
250 },
251 #ifdef CFG_CORE_RESERVED_SHM
252 {
253 .base = CFG_SHMEM_START,
254 .top = CFG_SHMEM_START + CFG_SHMEM_SIZE - 1,
255 .sec_attr = TZC_REGION_S_NONE,
256 .ns_device_access =
257 TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID),
258 }
259 #endif
260 };
261
262 static_assert(IS_PAGE_ALIGNED(CFG_TZDRAM_START));
263 static_assert(IS_PAGE_ALIGNED(CFG_TZDRAM_SIZE));
264 #ifdef CFG_CORE_RESERVED_SHM
265 static_assert(IS_PAGE_ALIGNED(CFG_SHMEM_START));
266 static_assert(IS_PAGE_ALIGNED(CFG_SHMEM_SIZE));
267 #endif
268
269 stm32mp_tzc_region0(true);
270
271 stm32mp_tzc_reset_region(tzc_dev);
272
273 for (idx = 0; idx < ARRAY_SIZE(boot_region); idx++) {
274 TEE_Result res = TEE_ERROR_GENERIC;
275
276 boot_region[idx].filters =
277 FILTER_MASK(tzc_dev->ddata.nb_filters);
278
279 res = append_region(tzc_dev, &boot_region[idx]);
280 if (res) {
281 EMSG("Failed to add region %u", idx);
282 panic();
283 }
284
285 res = exclude_region_from_nsec(&boot_region[idx]);
286 if (res) {
287 EMSG("Failed to configure region %u", idx);
288 panic();
289 }
290 }
291
292 /* Remove region0 access */
293 stm32mp_tzc_region0(false);
294 }
295
add_node_memory_regions(struct tzc_device * tzc_dev,const void * fdt,int node)296 static TEE_Result add_node_memory_regions(struct tzc_device *tzc_dev,
297 const void *fdt, int node)
298 {
299 const fdt32_t *conf_list = NULL;
300 unsigned int nregions = 0;
301 unsigned int i = 0;
302 int len = 0;
303
304 conf_list = fdt_getprop(fdt, node, "memory-region", &len);
305 if (!conf_list)
306 return TEE_SUCCESS;
307
308 nregions = len / sizeof(uint32_t);
309 if (nregions > tzc_dev->ddata.nb_regions) {
310 EMSG("Too many regions defined in %s",
311 fdt_get_name(fdt, node, NULL));
312 return TEE_ERROR_BAD_PARAMETERS;
313 }
314
315 for (i = 0; i < nregions; i++) {
316 uint32_t phandle = fdt32_to_cpu(*(conf_list + i));
317 struct tzc_region_config region_cfg = { };
318 const fdt32_t *prop = NULL;
319 paddr_t region_base = 0;
320 size_t region_size = 0;
321 int pnode = 0;
322
323 pnode = fdt_node_offset_by_phandle(fdt, phandle);
324 if (pnode < 0)
325 return TEE_ERROR_BAD_PARAMETERS;
326
327 region_base = fdt_reg_base_address(fdt, pnode);
328 region_size = fdt_reg_size(fdt, pnode);
329 assert(region_base != (paddr_t)-1 && region_size != (size_t)-1);
330
331 if (!IS_PAGE_ALIGNED(region_base) ||
332 !IS_PAGE_ALIGNED(region_size))
333 return TEE_ERROR_BAD_PARAMETERS;
334
335 region_cfg.base = region_base;
336 region_cfg.top = region_base + region_size - 1;
337 region_cfg.filters = FILTER_MASK(tzc_dev->ddata.nb_filters);
338
339 prop = fdt_getprop(fdt, pnode, "st,protreg", &len);
340 if (!prop || (unsigned int)len != (2 * sizeof(uint32_t)))
341 return TEE_ERROR_BAD_PARAMETERS;
342
343 switch (fdt32_to_cpu(prop[0])) {
344 case DT_TZC_REGION_S_NONE:
345 region_cfg.sec_attr = TZC_REGION_S_NONE;
346 break;
347 case DT_TZC_REGION_S_RD:
348 region_cfg.sec_attr = TZC_REGION_S_RD;
349 break;
350 case DT_TZC_REGION_S_WR:
351 region_cfg.sec_attr = TZC_REGION_S_WR;
352 break;
353 case DT_TZC_REGION_S_RDWR:
354 region_cfg.sec_attr = TZC_REGION_S_RDWR;
355 break;
356 default:
357 return TEE_ERROR_BAD_PARAMETERS;
358 }
359 region_cfg.ns_device_access = fdt32_to_cpu(prop[1]);
360
361 DMSG("%#08"PRIxVA" - %#08"PRIxVA" : Sec access %i NS access %#"PRIx32,
362 region_cfg.base, region_cfg.top, region_cfg.sec_attr,
363 region_cfg.ns_device_access);
364
365 if (append_region(tzc_dev, ®ion_cfg))
366 panic("Error adding region");
367
368 if (exclude_region_from_nsec(®ion_cfg))
369 panic("Not able to exclude region");
370 }
371
372 return TEE_SUCCESS;
373 }
374
375 /*
376 * Adds a TZC region entry for each non-secure memory area defined by
377 * nsec_region_list. The function releases resources used to build this
378 * non-secure region list.
379 */
add_carved_out_nsec(struct tzc_device * tzc_dev)380 static void add_carved_out_nsec(struct tzc_device *tzc_dev)
381 {
382 struct tzc_region_non_sec *region = NULL;
383 struct tzc_region_non_sec *region_safe = NULL;
384
385 SLIST_FOREACH_SAFE(region, &nsec_region_list, link, region_safe) {
386 DMSG("%#08"PRIxVA" - %#08"PRIxVA" : Sec access %i NS access %#"PRIx32,
387 region->region.base, region->region.top,
388 region->region.sec_attr,
389 region->region.ns_device_access);
390
391 if (append_region(tzc_dev, ®ion->region))
392 panic("Error adding region");
393
394 SLIST_REMOVE(&nsec_region_list, region,
395 tzc_region_non_sec, link);
396 free(region);
397 };
398 }
399
stm32mp_tzc_parse_fdt(struct tzc_device * tzc_dev,const void * fdt,int node)400 static TEE_Result stm32mp_tzc_parse_fdt(struct tzc_device *tzc_dev,
401 const void *fdt, int node)
402 {
403 TEE_Result res = TEE_ERROR_GENERIC;
404 struct io_pa_va base = { };
405 size_t reg_size = 0;
406 int offs = 0;
407
408 res = interrupt_dt_get(fdt, node, &tzc_dev->pdata.itr_chip,
409 &tzc_dev->pdata.itr_num);
410 if (res)
411 return res;
412
413 res = clk_dt_get_by_index(fdt, node, 0, tzc_dev->pdata.clk);
414 if (res)
415 return res;
416
417 res = clk_dt_get_by_index(fdt, node, 1, tzc_dev->pdata.clk + 1);
418 if (res == TEE_ERROR_ITEM_NOT_FOUND)
419 DMSG("No secondary clock for %s",
420 fdt_get_name(fdt, node, NULL));
421 else if (res)
422 return res;
423
424 base.pa = fdt_reg_base_address(fdt, node);
425 if (base.pa == DT_INFO_INVALID_REG)
426 return TEE_ERROR_BAD_PARAMETERS;
427
428 reg_size = fdt_reg_size(fdt, node);
429 if (reg_size == DT_INFO_INVALID_REG_SIZE)
430 return TEE_ERROR_BAD_PARAMETERS;
431
432 tzc_dev->pdata.name = strdup(fdt_get_name(fdt, node, NULL));
433 tzc_dev->pdata.base = io_pa_or_va_secure(&base, reg_size);
434
435 offs = fdt_node_offset_by_prop_value(fdt, offs, "device_type",
436 "memory", sizeof("memory"));
437 if (offs < 0)
438 panic("No memory reference for TZC DT node");
439
440 tzc_dev->pdata.mem_base = fdt_reg_base_address(fdt, offs);
441 tzc_dev->pdata.mem_size = fdt_reg_size(fdt, offs);
442
443 assert(tzc_dev->pdata.mem_base != DT_INFO_INVALID_REG &&
444 tzc_dev->pdata.mem_size != DT_INFO_INVALID_REG_SIZE);
445
446 return TEE_SUCCESS;
447 }
448
stm32mp1_tzc_pm(enum pm_op op,unsigned int pm_hint __unused,const struct pm_callback_handle * hdl)449 static TEE_Result stm32mp1_tzc_pm(enum pm_op op,
450 unsigned int pm_hint __unused,
451 const struct pm_callback_handle *hdl)
452 {
453 unsigned int i = 0;
454 struct tzc_device *tzc_dev =
455 (struct tzc_device *)PM_CALLBACK_GET_HANDLE(hdl);
456
457 if (op == PM_OP_RESUME) {
458 stm32mp_tzc_region0(true);
459
460 stm32mp_tzc_reset_region(tzc_dev);
461
462 for (i = 0; i < tzc_dev->nb_reg_used; i++)
463 tzc_configure_region(i + 1, &tzc_dev->reg[i]);
464
465 stm32mp_tzc_region0(false);
466 }
467
468 return TEE_SUCCESS;
469 }
470 DECLARE_KEEP_PAGER(stm32mp1_tzc_pm);
471
stm32mp1_tzc_probe(const void * fdt,int node,const void * compt_data __unused)472 static TEE_Result stm32mp1_tzc_probe(const void *fdt, int node,
473 const void *compt_data __unused)
474 {
475 TEE_Result res = TEE_ERROR_GENERIC;
476 struct tzc_device *tzc_dev = NULL;
477 struct tzc_region_non_sec *nsec_region = NULL;
478
479 tzc_dev = calloc(1, sizeof(*tzc_dev));
480 if (!tzc_dev)
481 panic();
482
483 res = stm32mp_tzc_parse_fdt(tzc_dev, fdt, node);
484 if (res) {
485 free(tzc_dev);
486 return res;
487 }
488
489 tzc_set_driverdata(tzc_dev);
490 tzc_dev->reg = calloc(tzc_dev->ddata.nb_regions,
491 sizeof(*tzc_dev->reg));
492 if (!tzc_dev->reg)
493 panic();
494
495 if (clk_enable(tzc_dev->pdata.clk[0]))
496 panic();
497 if (tzc_dev->pdata.clk[1] && clk_enable(tzc_dev->pdata.clk[1]))
498 panic();
499
500 tzc_init(tzc_dev->pdata.base);
501
502 nsec_region = calloc(1, sizeof(*nsec_region));
503 if (!nsec_region)
504 panic();
505
506 nsec_region->region.base = tzc_dev->pdata.mem_base;
507 nsec_region->region.top = tzc_dev->pdata.mem_base +
508 tzc_dev->pdata.mem_size - 1;
509 nsec_region->region.sec_attr = TZC_REGION_S_NONE;
510 nsec_region->region.ns_device_access = TZC_REGION_NSEC_ALL_ACCESS_RDWR;
511 nsec_region->region.filters = FILTER_MASK(tzc_dev->ddata.nb_filters);
512
513 SLIST_INSERT_HEAD(&nsec_region_list, nsec_region, link);
514
515 stm32mp_tzc_cfg_boot_region(tzc_dev);
516
517 res = add_node_memory_regions(tzc_dev, fdt, node);
518 if (res) {
519 EMSG("Can't add memory regions: %"PRIx32, res);
520 panic();
521 }
522
523 add_carved_out_nsec(tzc_dev);
524
525 tzc_dump_state();
526
527 res = interrupt_create_handler(tzc_dev->pdata.itr_chip,
528 tzc_dev->pdata.itr_num, tzc_it_handler,
529 NULL, 0, NULL);
530 if (res)
531 panic();
532
533 interrupt_enable(tzc_dev->pdata.itr_chip, tzc_dev->pdata.itr_num);
534 tzc_set_action(TZC_ACTION_INT);
535
536 register_pm_core_service_cb(stm32mp1_tzc_pm, tzc_dev,
537 "stm32mp1-tzc400");
538
539 return TEE_SUCCESS;
540 }
541
542 static const struct dt_device_match tzc_secu_match_table[] = {
543 { .compatible = "st,stm32mp1-tzc" },
544 { }
545 };
546
547 DEFINE_DT_DRIVER(tzc_stm32mp1_dt_driver) = {
548 .name = "stm32mp1-tzc400",
549 .type = DT_DRIVER_NOTYPE,
550 .match_table = tzc_secu_match_table,
551 .probe = stm32mp1_tzc_probe,
552 };
553