1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2021, Linaro Limited 4 * Copyright (c) 2021, Bootlin 5 * Copyright (c) 2021, Linaro Limited 6 * Copyright (c) 2021, STMicroelectronics 7 */ 8 9 #include <assert.h> 10 #include <config.h> 11 #include <initcall.h> 12 #include <kernel/boot.h> 13 #include <kernel/dt.h> 14 #include <kernel/dt_driver.h> 15 #include <libfdt.h> 16 #include <malloc.h> 17 #include <sys/queue.h> 18 #include <tee_api_defines_extensions.h> 19 #include <tee_api_types.h> 20 21 /* 22 * struct dt_driver_probe - Node instance in secure FDT to probe a driver for 23 * 24 * @link: List hook 25 * @nodeoffset: Node offset of device referenced in the FDT 26 * @type: One of DT_DRIVER_* or DT_DRIVER_NOTYPE. 27 * @deferrals: Driver probe deferrals count 28 * @dt_drv: Matching driver to probe if found or NULL 29 * @dm: Matching reference if applicable or NULL 30 */ 31 struct dt_driver_probe { 32 int nodeoffset; 33 enum dt_driver_type type; 34 unsigned int deferrals; 35 const struct dt_driver *dt_drv; 36 const struct dt_device_match *dm; 37 TAILQ_ENTRY(dt_driver_probe) link; 38 }; 39 40 /* 41 * struct dt_driver_provider - DT related info on probed device 42 * 43 * Saves information on the probed device so that device 44 * drivers can get resources from DT phandle and related arguments. 45 * 46 * @nodeoffset: Node offset of device referenced in the FDT 47 * @type: One of DT_DRIVER_* or DT_DRIVER_NOTYPE. 48 * @provider_cells: Cells count in the FDT used by the driver's references 49 * @get_of_device: Function to get driver's device ref from phandle data 50 * @priv_data: Driver private data passed as @get_of_device argument 51 * @link: Reference in DT driver providers list 52 */ 53 struct dt_driver_provider { 54 int nodeoffset; 55 enum dt_driver_type type; 56 unsigned int provider_cells; 57 uint32_t phandle; 58 get_of_device_func get_of_device; 59 void *priv_data; 60 SLIST_ENTRY(dt_driver_provider) link; 61 }; 62 63 /* 64 * Device driver providers are able to provide a driver specific instance 65 * related to device phandle arguments found in the secure embedded FDT. 66 */ 67 static SLIST_HEAD(, dt_driver_provider) dt_driver_provider_list = 68 SLIST_HEAD_INITIALIZER(dt_driver_provider_list); 69 70 /* FDT nodes for which a matching driver is to be probed */ 71 static TAILQ_HEAD(dt_driver_probe_head, dt_driver_probe) dt_driver_probe_list = 72 TAILQ_HEAD_INITIALIZER(dt_driver_probe_list); 73 74 /* FDT nodes for which a matching driver has been successfully probed */ 75 static TAILQ_HEAD(, dt_driver_probe) dt_driver_ready_list = 76 TAILQ_HEAD_INITIALIZER(dt_driver_ready_list); 77 78 /* Flag enabled when a new node (possibly typed) is added in the probe list */ 79 static bool added_node; 80 81 static void assert_type_is_valid(enum dt_driver_type type) 82 { 83 switch (type) { 84 case DT_DRIVER_NOTYPE: 85 case DT_DRIVER_UART: 86 case DT_DRIVER_CLK: 87 return; 88 default: 89 assert(0); 90 } 91 } 92 93 /* 94 * Driver provider registering API functions 95 */ 96 97 TEE_Result dt_driver_register_provider(const void *fdt, int nodeoffset, 98 get_of_device_func get_of_device, 99 void *priv, enum dt_driver_type type) 100 { 101 struct dt_driver_provider *prv = NULL; 102 int provider_cells = 0; 103 uint32_t phandle = 0; 104 105 assert_type_is_valid(type); 106 107 provider_cells = fdt_get_dt_driver_cells(fdt, nodeoffset, type); 108 if (provider_cells < 0) { 109 DMSG("Failed to find provider cells: %d", provider_cells); 110 return TEE_ERROR_GENERIC; 111 } 112 113 phandle = fdt_get_phandle(fdt, nodeoffset); 114 if (!phandle || phandle == (uint32_t)-1) { 115 DMSG("Failed to find provide phandle"); 116 return TEE_ERROR_GENERIC; 117 } 118 119 prv = calloc(1, sizeof(*prv)); 120 if (!prv) 121 return TEE_ERROR_OUT_OF_MEMORY; 122 123 prv->nodeoffset = nodeoffset; 124 prv->type = type; 125 prv->provider_cells = provider_cells; 126 prv->phandle = phandle; 127 prv->get_of_device = get_of_device; 128 prv->priv_data = priv; 129 130 SLIST_INSERT_HEAD(&dt_driver_provider_list, prv, link); 131 132 return TEE_SUCCESS; 133 } 134 135 /* Release driver provider references once all dt_drivers are initialized */ 136 static TEE_Result dt_driver_release_provider(void) 137 { 138 struct dt_driver_provider *prv = NULL; 139 140 while (!SLIST_EMPTY(&dt_driver_provider_list)) { 141 prv = SLIST_FIRST(&dt_driver_provider_list); 142 SLIST_REMOVE_HEAD(&dt_driver_provider_list, link); 143 free(prv); 144 } 145 146 return TEE_SUCCESS; 147 } 148 149 release_init_resource(dt_driver_release_provider); 150 151 /* 152 * Helper functions for dt_drivers querying driver provider information 153 */ 154 155 int fdt_get_dt_driver_cells(const void *fdt, int nodeoffset, 156 enum dt_driver_type type) 157 { 158 const char *cells_name = NULL; 159 const fdt32_t *c = NULL; 160 int len = 0; 161 162 switch (type) { 163 case DT_DRIVER_CLK: 164 cells_name = "#clock-cells"; 165 break; 166 default: 167 panic(); 168 } 169 170 c = fdt_getprop(fdt, nodeoffset, cells_name, &len); 171 if (!c) 172 return len; 173 174 if (len != sizeof(*c)) 175 return -FDT_ERR_BADNCELLS; 176 177 return fdt32_to_cpu(*c); 178 } 179 180 unsigned int dt_driver_provider_cells(struct dt_driver_provider *prv) 181 { 182 return prv->provider_cells; 183 } 184 185 struct dt_driver_provider * 186 dt_driver_get_provider_by_node(int nodeoffset, enum dt_driver_type type) 187 { 188 struct dt_driver_provider *prv = NULL; 189 190 SLIST_FOREACH(prv, &dt_driver_provider_list, link) 191 if (prv->nodeoffset == nodeoffset && prv->type == type) 192 return prv; 193 194 return NULL; 195 } 196 197 struct dt_driver_provider * 198 dt_driver_get_provider_by_phandle(uint32_t phandle, enum dt_driver_type type) 199 { 200 struct dt_driver_provider *prv = NULL; 201 202 SLIST_FOREACH(prv, &dt_driver_provider_list, link) 203 if (prv->phandle == phandle && prv->type == type) 204 return prv; 205 206 return NULL; 207 } 208 209 static void *device_from_provider_prop(struct dt_driver_provider *prv, 210 const uint32_t *prop, 211 TEE_Result *res) 212 { 213 struct dt_driver_phandle_args *pargs = NULL; 214 unsigned int n = 0; 215 void *device = NULL; 216 217 pargs = calloc(1, prv->provider_cells * sizeof(uint32_t *) + 218 sizeof(*pargs)); 219 if (!pargs) { 220 *res = TEE_ERROR_OUT_OF_MEMORY; 221 return NULL; 222 } 223 224 pargs->args_count = prv->provider_cells; 225 for (n = 0; n < prv->provider_cells; n++) 226 pargs->args[n] = fdt32_to_cpu(prop[n + 1]); 227 228 device = prv->get_of_device(pargs, prv->priv_data, res); 229 230 free(pargs); 231 232 return device; 233 } 234 235 void *dt_driver_device_from_node_idx_prop(const char *prop_name, 236 const void *fdt, int nodeoffset, 237 unsigned int prop_idx, 238 enum dt_driver_type type, 239 TEE_Result *res) 240 { 241 int len = 0; 242 int idx = 0; 243 int idx32 = 0; 244 int prv_cells = 0; 245 uint32_t phandle = 0; 246 const uint32_t *prop = NULL; 247 struct dt_driver_provider *prv = NULL; 248 249 prop = fdt_getprop(fdt, nodeoffset, prop_name, &len); 250 if (!prop) { 251 DMSG("Property %s missing in node %s", prop_name, 252 fdt_get_name(fdt, nodeoffset, NULL)); 253 *res = TEE_ERROR_GENERIC; 254 return NULL; 255 } 256 257 while (idx < len) { 258 idx32 = idx / sizeof(uint32_t); 259 phandle = fdt32_to_cpu(prop[idx32]); 260 261 prv = dt_driver_get_provider_by_phandle(phandle, type); 262 if (!prv) { 263 /* No provider registered yet */ 264 *res = TEE_ERROR_DEFER_DRIVER_INIT; 265 return NULL; 266 } 267 268 prv_cells = dt_driver_provider_cells(prv); 269 if (prop_idx) { 270 prop_idx--; 271 idx += sizeof(phandle) + prv_cells * sizeof(uint32_t); 272 continue; 273 } 274 275 return device_from_provider_prop(prv, prop + idx32, res); 276 } 277 278 *res = TEE_ERROR_GENERIC; 279 return NULL; 280 } 281 282 static unsigned int __maybe_unused probe_list_count(void) 283 { 284 struct dt_driver_probe *elt = NULL; 285 unsigned int count = 0; 286 287 TAILQ_FOREACH(elt, &dt_driver_probe_list, link) 288 count++; 289 290 return count; 291 } 292 293 static void __maybe_unused print_probe_list(const void *fdt __maybe_unused) 294 { 295 struct dt_driver_probe *elt = NULL; 296 297 DMSG("Probe list: %u elements", probe_list_count()); 298 299 TAILQ_FOREACH(elt, &dt_driver_probe_list, link) 300 DMSG("- Driver %s probes on node %s", 301 elt->dt_drv->name, 302 fdt_get_name(fdt, elt->nodeoffset, NULL)); 303 304 DMSG("Probe list end"); 305 } 306 307 /* 308 * Probe element: push to ready list if succeeds, push to probe list if probe 309 * if deferred, panic with an error trace otherwise. 310 */ 311 static TEE_Result probe_driver_node(const void *fdt, 312 struct dt_driver_probe *elt) 313 { 314 TEE_Result res = TEE_ERROR_GENERIC; 315 const char __maybe_unused *drv_name = NULL; 316 const char __maybe_unused *node_name = NULL; 317 318 node_name = fdt_get_name(fdt, elt->nodeoffset, NULL); 319 drv_name = elt->dt_drv->name; 320 FMSG("Probing %s on node %s", drv_name, node_name); 321 322 res = elt->dt_drv->probe(fdt, elt->nodeoffset, elt->dm->compat_data); 323 switch (res) { 324 case TEE_SUCCESS: 325 TAILQ_INSERT_HEAD(&dt_driver_ready_list, elt, link); 326 327 DMSG("element: %s on node %s initialized", drv_name, node_name); 328 break; 329 case TEE_ERROR_DEFER_DRIVER_INIT: 330 elt->deferrals++; 331 TAILQ_INSERT_TAIL(&dt_driver_probe_list, elt, link); 332 333 DMSG("element: %s on node %s deferred %u time(s)", drv_name, 334 node_name, elt->deferrals); 335 break; 336 default: 337 EMSG("Fail to probe %s on node %s: %#"PRIx32, 338 drv_name, node_name, res); 339 panic(); 340 } 341 342 return res; 343 } 344 345 static TEE_Result alloc_elt_and_probe(const void *fdt, int node, 346 const struct dt_driver *dt_drv, 347 const struct dt_device_match *dm) 348 { 349 struct dt_driver_probe *elt = NULL; 350 351 /* Will be freed when lists are released */ 352 elt = calloc(1, sizeof(*elt)); 353 if (!elt) 354 return TEE_ERROR_OUT_OF_MEMORY; 355 356 elt->nodeoffset = node; 357 elt->dt_drv = dt_drv; 358 elt->dm = dm; 359 elt->type = dt_drv->type; 360 361 return probe_driver_node(fdt, elt); 362 } 363 364 /* Lookup a compatible driver, possibly of a specific @type, for the FDT node */ 365 static TEE_Result probe_device_by_compat(const void *fdt, int node, 366 const char *compat, 367 enum dt_driver_type type) 368 { 369 const struct dt_driver *drv = NULL; 370 const struct dt_device_match *dm = NULL; 371 372 for_each_dt_driver(drv) { 373 if (drv->type != type) 374 continue; 375 376 for (dm = drv->match_table; dm && dm->compatible; dm++) 377 if (strcmp(dm->compatible, compat) == 0) 378 return alloc_elt_and_probe(fdt, node, drv, dm); 379 } 380 381 return TEE_ERROR_ITEM_NOT_FOUND; 382 } 383 384 /* 385 * Lookup the best matching compatible driver, possibly of a specific @type, 386 * for the FDT node. 387 */ 388 TEE_Result dt_driver_probe_device_by_node(const void *fdt, int nodeoffset, 389 enum dt_driver_type type) 390 { 391 int idx = 0; 392 int len = 0; 393 int count = 0; 394 const char *compat = NULL; 395 TEE_Result res = TEE_ERROR_GENERIC; 396 397 assert_type_is_valid(type); 398 399 count = fdt_stringlist_count(fdt, nodeoffset, "compatible"); 400 if (count < 0) 401 return TEE_ERROR_ITEM_NOT_FOUND; 402 403 for (idx = 0; idx < count; idx++) { 404 compat = fdt_stringlist_get(fdt, nodeoffset, "compatible", 405 idx, &len); 406 if (!compat) 407 return TEE_ERROR_GENERIC; 408 409 res = probe_device_by_compat(fdt, nodeoffset, compat, type); 410 411 if (res != TEE_ERROR_ITEM_NOT_FOUND) 412 return res; 413 } 414 415 return TEE_ERROR_ITEM_NOT_FOUND; 416 } 417 418 static TEE_Result process_probe_list(const void *fdt) 419 { 420 struct dt_driver_probe *elt = NULL; 421 struct dt_driver_probe *prev = NULL; 422 unsigned int __maybe_unused loop_count = 0; 423 unsigned int __maybe_unused deferral_loop_count = 0; 424 bool __maybe_unused one_deferred = false; 425 bool one_probed_ok = false; 426 427 do { 428 loop_count++; 429 FMSG("Probe loop %u after %u for deferral(s)", loop_count, 430 deferral_loop_count); 431 432 /* Hack here for TRACE_DEBUG messages on probe list elements */ 433 if (TRACE_LEVEL >= TRACE_FLOW) 434 print_probe_list(fdt); 435 436 if (TAILQ_EMPTY(&dt_driver_probe_list)) 437 return TEE_SUCCESS; 438 439 /* 440 * Probe from current end to top. Deferred probed node are 441 * pushed back after current tail for the next probe round. 442 * Reset probe result flags and see status after probe round. 443 */ 444 one_deferred = false; 445 one_probed_ok = false; 446 added_node = false; 447 448 TAILQ_FOREACH_REVERSE_SAFE(elt, &dt_driver_probe_list, 449 dt_driver_probe_head, link, prev) { 450 TAILQ_REMOVE(&dt_driver_probe_list, elt, link); 451 452 switch (probe_driver_node(fdt, elt)) { 453 case TEE_SUCCESS: 454 one_probed_ok = true; 455 break; 456 case TEE_ERROR_DEFER_DRIVER_INIT: 457 one_deferred = true; 458 break; 459 default: 460 /* We don't expect error return codes */ 461 assert(0); 462 } 463 } 464 465 if (one_deferred) 466 deferral_loop_count++; 467 468 } while (added_node || one_probed_ok); 469 470 EMSG("Panic on unresolved dependencies after %u rounds, %u deferred:", 471 loop_count, deferral_loop_count); 472 473 TAILQ_FOREACH(elt, &dt_driver_probe_list, link) 474 EMSG("- %s on node %s", elt->dt_drv->name, 475 fdt_get_name(fdt, elt->nodeoffset, NULL)); 476 477 panic(); 478 } 479 480 static int driver_probe_compare(struct dt_driver_probe *candidate, 481 struct dt_driver_probe *elt) 482 { 483 if (candidate->nodeoffset != elt->nodeoffset || 484 candidate->type != elt->type) 485 return 1; 486 487 assert(elt->dt_drv == candidate->dt_drv); 488 return 0; 489 } 490 491 /* 492 * Return TEE_SUCCESS if compatible found 493 * TEE_ERROR_OUT_OF_MEMORY if heap is exhausted 494 */ 495 static TEE_Result add_node_to_probe(const void *fdt, int node, 496 const struct dt_driver *dt_drv, 497 const struct dt_device_match *dm) 498 { 499 const char __maybe_unused *node_name = fdt_get_name(fdt, node, NULL); 500 const char __maybe_unused *drv_name = dt_drv->name; 501 struct dt_driver_probe *elt = NULL; 502 struct dt_driver_probe elt_new = { 503 .dm = dm, 504 .dt_drv = dt_drv, 505 .nodeoffset = node, 506 .type = dt_drv->type, 507 }; 508 509 /* If node/type found in probe list or ready list, nothing to do */ 510 TAILQ_FOREACH(elt, &dt_driver_probe_list, link) 511 if (!driver_probe_compare(&elt_new, elt)) 512 return TEE_SUCCESS; 513 514 TAILQ_FOREACH(elt, &dt_driver_ready_list, link) 515 if (!driver_probe_compare(&elt_new, elt)) 516 return TEE_SUCCESS; 517 518 elt = malloc(sizeof(*elt)); 519 if (!elt) 520 return TEE_ERROR_OUT_OF_MEMORY; 521 522 DMSG("element: %s on node %s", node_name, drv_name); 523 524 memcpy(elt, &elt_new, sizeof(*elt)); 525 526 added_node = true; 527 528 TAILQ_INSERT_TAIL(&dt_driver_probe_list, elt, link); 529 530 /* Hack here for TRACE_DEBUG messages on current probe list elements */ 531 if (TRACE_LEVEL >= TRACE_FLOW) 532 print_probe_list(fdt); 533 534 return TEE_SUCCESS; 535 } 536 537 /* 538 * Add a node to the probe list if a dt_driver matches target compatible. 539 * 540 * If @type is DT_DRIVER_ANY, probe list can hold only 1 driver to probe for 541 * the node. A node may probe several drivers if have a unique driver type. 542 * 543 * Return TEE_SUCCESS if compatible found 544 * TEE_ERROR_ITEM_NOT_FOUND if no matching driver 545 * TEE_ERROR_OUT_OF_MEMORY if heap is exhausted 546 */ 547 static TEE_Result add_probe_node_by_compat(const void *fdt, int node, 548 const char *compat) 549 { 550 TEE_Result res = TEE_ERROR_ITEM_NOT_FOUND; 551 const struct dt_driver *dt_drv = NULL; 552 const struct dt_device_match *dm = NULL; 553 uint32_t found_types = 0; 554 555 for_each_dt_driver(dt_drv) { 556 for (dm = dt_drv->match_table; dm && dm->compatible; dm++) { 557 if (strcmp(dm->compatible, compat) == 0) { 558 assert(dt_drv->type < 32); 559 560 res = add_node_to_probe(fdt, node, dt_drv, dm); 561 if (res) 562 return res; 563 564 if (found_types & BIT(dt_drv->type)) { 565 EMSG("Driver %s multi hit on type %u", 566 dt_drv->name, dt_drv->type); 567 panic(); 568 } 569 found_types |= BIT(dt_drv->type); 570 571 /* Matching found for this driver, try next */ 572 break; 573 } 574 } 575 } 576 577 return res; 578 } 579 580 /* 581 * Add the node to the probe list if matching compatible drivers are found. 582 * Follow node's compatible property list ordering to find matching driver. 583 */ 584 TEE_Result dt_driver_maybe_add_probe_node(const void *fdt, int node) 585 { 586 int idx = 0; 587 int len = 0; 588 int count = 0; 589 const char *compat = NULL; 590 TEE_Result res = TEE_ERROR_GENERIC; 591 592 if (_fdt_get_status(fdt, node) == DT_STATUS_DISABLED) 593 return TEE_SUCCESS; 594 595 count = fdt_stringlist_count(fdt, node, "compatible"); 596 if (count < 0) 597 return TEE_SUCCESS; 598 599 for (idx = 0; idx < count; idx++) { 600 compat = fdt_stringlist_get(fdt, node, "compatible", idx, &len); 601 assert(compat && len > 0); 602 603 res = add_probe_node_by_compat(fdt, node, compat); 604 605 /* Stop lookup if something was found */ 606 if (res != TEE_ERROR_ITEM_NOT_FOUND) 607 return res; 608 } 609 610 return TEE_SUCCESS; 611 } 612 613 static void parse_node(const void *fdt, int node) 614 { 615 TEE_Result __maybe_unused res = TEE_ERROR_GENERIC; 616 int subnode = 0; 617 618 fdt_for_each_subnode(subnode, fdt, node) { 619 res = dt_driver_maybe_add_probe_node(fdt, subnode); 620 if (res) { 621 EMSG("Failed on node %s with %#"PRIx32, 622 fdt_get_name(fdt, subnode, NULL), res); 623 panic(); 624 } 625 626 /* 627 * Rescursively parse the FDT, skipping disabled nodes. 628 * FDT is expected reliable and core shall have sufficient 629 * stack depth to possibly parse all DT nodes. 630 */ 631 if (IS_ENABLED(CFG_DRIVERS_DT_RECURSIVE_PROBE)) { 632 if (_fdt_get_status(fdt, subnode) == DT_STATUS_DISABLED) 633 continue; 634 635 parse_node(fdt, subnode); 636 } 637 } 638 } 639 640 /* 641 * Parse FDT for nodes and save in probe list the node for which a dt_driver 642 * matches node's compatible property. 643 */ 644 static TEE_Result probe_dt_drivers(void) 645 { 646 const void *fdt = NULL; 647 648 if (!IS_ENABLED(CFG_EMBED_DTB)) 649 return TEE_SUCCESS; 650 651 fdt = get_embedded_dt(); 652 assert(fdt); 653 654 parse_node(fdt, fdt_path_offset(fdt, "/")); 655 656 return process_probe_list(fdt); 657 } 658 659 driver_init(probe_dt_drivers); 660 661 static TEE_Result release_probe_lists(void) 662 { 663 struct dt_driver_probe *elt = NULL; 664 struct dt_driver_probe *next = NULL; 665 const void * __maybe_unused fdt = NULL; 666 667 if (!IS_ENABLED(CFG_EMBED_DTB)) 668 return TEE_SUCCESS; 669 670 fdt = get_embedded_dt(); 671 672 assert(fdt && TAILQ_EMPTY(&dt_driver_probe_list)); 673 674 TAILQ_FOREACH_SAFE(elt, &dt_driver_ready_list, link, next) { 675 DMSG("element: %s on node %s", elt->dt_drv->name, 676 fdt_get_name(fdt, elt->nodeoffset, NULL)); 677 free(elt); 678 } 679 680 return TEE_SUCCESS; 681 } 682 683 release_init_resource(release_probe_lists); 684 685 /* 686 * Simple bus support: handy to parse subnodes 687 */ 688 static TEE_Result simple_bus_probe(const void *fdt, int node, 689 const void *compat_data __unused) 690 { 691 TEE_Result res = TEE_ERROR_GENERIC; 692 int subnode = 0; 693 694 fdt_for_each_subnode(subnode, fdt, node) { 695 res = dt_driver_maybe_add_probe_node(fdt, subnode); 696 if (res) { 697 EMSG("Failed on node %s with %#"PRIx32, 698 fdt_get_name(fdt, subnode, NULL), res); 699 panic(); 700 } 701 } 702 703 return TEE_SUCCESS; 704 } 705 706 static const struct dt_device_match simple_bus_match_table[] = { 707 { .compatible = "simple-bus" }, 708 { } 709 }; 710 711 const struct dt_driver simple_bus_dt_driver __dt_driver = { 712 .name = "simple-bus", 713 .match_table = simple_bus_match_table, 714 .probe = simple_bus_probe, 715 }; 716