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 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 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 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 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 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 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 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 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 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 */ 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 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 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 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