| .. | .. |
|---|
| 98 | 98 | * |
|---|
| 99 | 99 | * Return: The cache structure and the level we terminated with. |
|---|
| 100 | 100 | */ |
|---|
| 101 | | -static int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr, |
|---|
| 102 | | - int local_level, |
|---|
| 103 | | - struct acpi_subtable_header *res, |
|---|
| 104 | | - struct acpi_pptt_cache **found, |
|---|
| 105 | | - int level, int type) |
|---|
| 101 | +static unsigned int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr, |
|---|
| 102 | + unsigned int local_level, |
|---|
| 103 | + struct acpi_subtable_header *res, |
|---|
| 104 | + struct acpi_pptt_cache **found, |
|---|
| 105 | + unsigned int level, int type) |
|---|
| 106 | 106 | { |
|---|
| 107 | 107 | struct acpi_pptt_cache *cache; |
|---|
| 108 | 108 | |
|---|
| .. | .. |
|---|
| 119 | 119 | if (*found != NULL && cache != *found) |
|---|
| 120 | 120 | pr_warn("Found duplicate cache level/type unable to determine uniqueness\n"); |
|---|
| 121 | 121 | |
|---|
| 122 | | - pr_debug("Found cache @ level %d\n", level); |
|---|
| 122 | + pr_debug("Found cache @ level %u\n", level); |
|---|
| 123 | 123 | *found = cache; |
|---|
| 124 | 124 | /* |
|---|
| 125 | 125 | * continue looking at this node's resource list |
|---|
| .. | .. |
|---|
| 132 | 132 | return local_level; |
|---|
| 133 | 133 | } |
|---|
| 134 | 134 | |
|---|
| 135 | | -static struct acpi_pptt_cache *acpi_find_cache_level(struct acpi_table_header *table_hdr, |
|---|
| 136 | | - struct acpi_pptt_processor *cpu_node, |
|---|
| 137 | | - int *starting_level, int level, |
|---|
| 138 | | - int type) |
|---|
| 135 | +static struct acpi_pptt_cache * |
|---|
| 136 | +acpi_find_cache_level(struct acpi_table_header *table_hdr, |
|---|
| 137 | + struct acpi_pptt_processor *cpu_node, |
|---|
| 138 | + unsigned int *starting_level, unsigned int level, |
|---|
| 139 | + int type) |
|---|
| 139 | 140 | { |
|---|
| 140 | 141 | struct acpi_subtable_header *res; |
|---|
| 141 | | - int number_of_levels = *starting_level; |
|---|
| 142 | + unsigned int number_of_levels = *starting_level; |
|---|
| 142 | 143 | int resource = 0; |
|---|
| 143 | 144 | struct acpi_pptt_cache *ret = NULL; |
|---|
| 144 | | - int local_level; |
|---|
| 145 | + unsigned int local_level; |
|---|
| 145 | 146 | |
|---|
| 146 | 147 | /* walk down from processor node */ |
|---|
| 147 | 148 | while ((res = acpi_get_pptt_resource(table_hdr, cpu_node, resource))) { |
|---|
| .. | .. |
|---|
| 164 | 165 | } |
|---|
| 165 | 166 | |
|---|
| 166 | 167 | /** |
|---|
| 167 | | - * acpi_count_levels() - Given a PPTT table, and a cpu node, count the caches |
|---|
| 168 | + * acpi_count_levels() - Given a PPTT table, and a CPU node, count the caches |
|---|
| 168 | 169 | * @table_hdr: Pointer to the head of the PPTT table |
|---|
| 169 | 170 | * @cpu_node: processor node we wish to count caches for |
|---|
| 170 | 171 | * |
|---|
| .. | .. |
|---|
| 209 | 210 | struct acpi_pptt_processor *cpu_node; |
|---|
| 210 | 211 | u32 proc_sz; |
|---|
| 211 | 212 | |
|---|
| 213 | + if (table_hdr->revision > 1) |
|---|
| 214 | + return (node->flags & ACPI_PPTT_ACPI_LEAF_NODE); |
|---|
| 215 | + |
|---|
| 212 | 216 | table_end = (unsigned long)table_hdr + table_hdr->length; |
|---|
| 213 | 217 | node_entry = ACPI_PTR_DIFF(node, table_hdr); |
|---|
| 214 | 218 | entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr, |
|---|
| .. | .. |
|---|
| 232 | 236 | /** |
|---|
| 233 | 237 | * acpi_find_processor_node() - Given a PPTT table find the requested processor |
|---|
| 234 | 238 | * @table_hdr: Pointer to the head of the PPTT table |
|---|
| 235 | | - * @acpi_cpu_id: cpu we are searching for |
|---|
| 239 | + * @acpi_cpu_id: CPU we are searching for |
|---|
| 236 | 240 | * |
|---|
| 237 | 241 | * Find the subtable entry describing the provided processor. |
|---|
| 238 | 242 | * This is done by iterating the PPTT table looking for processor nodes |
|---|
| .. | .. |
|---|
| 318 | 322 | unsigned int level, |
|---|
| 319 | 323 | struct acpi_pptt_processor **node) |
|---|
| 320 | 324 | { |
|---|
| 321 | | - int total_levels = 0; |
|---|
| 325 | + unsigned int total_levels = 0; |
|---|
| 322 | 326 | struct acpi_pptt_cache *found = NULL; |
|---|
| 323 | 327 | struct acpi_pptt_processor *cpu_node; |
|---|
| 324 | 328 | u8 acpi_type = acpi_cache_type(type); |
|---|
| 325 | 329 | |
|---|
| 326 | | - pr_debug("Looking for CPU %d's level %d cache type %d\n", |
|---|
| 330 | + pr_debug("Looking for CPU %d's level %u cache type %d\n", |
|---|
| 327 | 331 | acpi_cpu_id, level, acpi_type); |
|---|
| 328 | 332 | |
|---|
| 329 | 333 | cpu_node = acpi_find_processor_node(table_hdr, acpi_cpu_id); |
|---|
| .. | .. |
|---|
| 429 | 433 | } |
|---|
| 430 | 434 | } |
|---|
| 431 | 435 | |
|---|
| 436 | +static bool flag_identical(struct acpi_table_header *table_hdr, |
|---|
| 437 | + struct acpi_pptt_processor *cpu) |
|---|
| 438 | +{ |
|---|
| 439 | + struct acpi_pptt_processor *next; |
|---|
| 440 | + |
|---|
| 441 | + /* heterogeneous machines must use PPTT revision > 1 */ |
|---|
| 442 | + if (table_hdr->revision < 2) |
|---|
| 443 | + return false; |
|---|
| 444 | + |
|---|
| 445 | + /* Locate the last node in the tree with IDENTICAL set */ |
|---|
| 446 | + if (cpu->flags & ACPI_PPTT_ACPI_IDENTICAL) { |
|---|
| 447 | + next = fetch_pptt_node(table_hdr, cpu->parent); |
|---|
| 448 | + if (!(next && next->flags & ACPI_PPTT_ACPI_IDENTICAL)) |
|---|
| 449 | + return true; |
|---|
| 450 | + } |
|---|
| 451 | + |
|---|
| 452 | + return false; |
|---|
| 453 | +} |
|---|
| 454 | + |
|---|
| 432 | 455 | /* Passing level values greater than this will result in search termination */ |
|---|
| 433 | 456 | #define PPTT_ABORT_PACKAGE 0xFF |
|---|
| 434 | 457 | |
|---|
| 435 | | -static struct acpi_pptt_processor *acpi_find_processor_package_id(struct acpi_table_header *table_hdr, |
|---|
| 436 | | - struct acpi_pptt_processor *cpu, |
|---|
| 437 | | - int level, int flag) |
|---|
| 458 | +static struct acpi_pptt_processor *acpi_find_processor_tag(struct acpi_table_header *table_hdr, |
|---|
| 459 | + struct acpi_pptt_processor *cpu, |
|---|
| 460 | + int level, int flag) |
|---|
| 438 | 461 | { |
|---|
| 439 | 462 | struct acpi_pptt_processor *prev_node; |
|---|
| 440 | 463 | |
|---|
| 441 | 464 | while (cpu && level) { |
|---|
| 442 | | - if (cpu->flags & flag) |
|---|
| 465 | + /* special case the identical flag to find last identical */ |
|---|
| 466 | + if (flag == ACPI_PPTT_ACPI_IDENTICAL) { |
|---|
| 467 | + if (flag_identical(table_hdr, cpu)) |
|---|
| 468 | + break; |
|---|
| 469 | + } else if (cpu->flags & flag) |
|---|
| 443 | 470 | break; |
|---|
| 444 | 471 | pr_debug("level %d\n", level); |
|---|
| 445 | 472 | prev_node = fetch_pptt_node(table_hdr, cpu->parent); |
|---|
| .. | .. |
|---|
| 451 | 478 | return cpu; |
|---|
| 452 | 479 | } |
|---|
| 453 | 480 | |
|---|
| 481 | +static void acpi_pptt_warn_missing(void) |
|---|
| 482 | +{ |
|---|
| 483 | + pr_warn_once("No PPTT table found, CPU and cache topology may be inaccurate\n"); |
|---|
| 484 | +} |
|---|
| 485 | + |
|---|
| 454 | 486 | /** |
|---|
| 455 | 487 | * topology_get_acpi_cpu_tag() - Find a unique topology value for a feature |
|---|
| 456 | 488 | * @table: Pointer to the head of the PPTT table |
|---|
| 457 | | - * @cpu: Kernel logical cpu number |
|---|
| 489 | + * @cpu: Kernel logical CPU number |
|---|
| 458 | 490 | * @level: A level that terminates the search |
|---|
| 459 | 491 | * @flag: A flag which terminates the search |
|---|
| 460 | 492 | * |
|---|
| 461 | | - * Get a unique value given a cpu, and a topology level, that can be |
|---|
| 493 | + * Get a unique value given a CPU, and a topology level, that can be |
|---|
| 462 | 494 | * matched to determine which cpus share common topological features |
|---|
| 463 | 495 | * at that level. |
|---|
| 464 | 496 | * |
|---|
| 465 | | - * Return: Unique value, or -ENOENT if unable to locate cpu |
|---|
| 497 | + * Return: Unique value, or -ENOENT if unable to locate CPU |
|---|
| 466 | 498 | */ |
|---|
| 467 | 499 | static int topology_get_acpi_cpu_tag(struct acpi_table_header *table, |
|---|
| 468 | 500 | unsigned int cpu, int level, int flag) |
|---|
| .. | .. |
|---|
| 472 | 504 | |
|---|
| 473 | 505 | cpu_node = acpi_find_processor_node(table, acpi_cpu_id); |
|---|
| 474 | 506 | if (cpu_node) { |
|---|
| 475 | | - cpu_node = acpi_find_processor_package_id(table, cpu_node, |
|---|
| 476 | | - level, flag); |
|---|
| 507 | + cpu_node = acpi_find_processor_tag(table, cpu_node, |
|---|
| 508 | + level, flag); |
|---|
| 477 | 509 | /* |
|---|
| 478 | 510 | * As per specification if the processor structure represents |
|---|
| 479 | 511 | * an actual processor, then ACPI processor ID must be valid. |
|---|
| .. | .. |
|---|
| 498 | 530 | |
|---|
| 499 | 531 | status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); |
|---|
| 500 | 532 | if (ACPI_FAILURE(status)) { |
|---|
| 501 | | - pr_warn_once("No PPTT table found, cpu topology may be inaccurate\n"); |
|---|
| 533 | + acpi_pptt_warn_missing(); |
|---|
| 502 | 534 | return -ENOENT; |
|---|
| 503 | 535 | } |
|---|
| 504 | 536 | retval = topology_get_acpi_cpu_tag(table, cpu, level, flag); |
|---|
| 505 | | - pr_debug("Topology Setup ACPI cpu %d, level %d ret = %d\n", |
|---|
| 537 | + pr_debug("Topology Setup ACPI CPU %d, level %d ret = %d\n", |
|---|
| 506 | 538 | cpu, level, retval); |
|---|
| 507 | 539 | acpi_put_table(table); |
|---|
| 508 | 540 | |
|---|
| .. | .. |
|---|
| 532 | 564 | |
|---|
| 533 | 565 | status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); |
|---|
| 534 | 566 | if (ACPI_FAILURE(status)) { |
|---|
| 535 | | - pr_warn_once("No PPTT table found, cpu topology may be inaccurate\n"); |
|---|
| 567 | + acpi_pptt_warn_missing(); |
|---|
| 536 | 568 | return ret; |
|---|
| 537 | 569 | } |
|---|
| 538 | 570 | |
|---|
| .. | .. |
|---|
| 549 | 581 | |
|---|
| 550 | 582 | /** |
|---|
| 551 | 583 | * acpi_find_last_cache_level() - Determines the number of cache levels for a PE |
|---|
| 552 | | - * @cpu: Kernel logical cpu number |
|---|
| 584 | + * @cpu: Kernel logical CPU number |
|---|
| 553 | 585 | * |
|---|
| 554 | | - * Given a logical cpu number, returns the number of levels of cache represented |
|---|
| 586 | + * Given a logical CPU number, returns the number of levels of cache represented |
|---|
| 555 | 587 | * in the PPTT. Errors caused by lack of a PPTT table, or otherwise, return 0 |
|---|
| 556 | 588 | * indicating we didn't find any cache levels. |
|---|
| 557 | 589 | * |
|---|
| .. | .. |
|---|
| 564 | 596 | int number_of_levels = 0; |
|---|
| 565 | 597 | acpi_status status; |
|---|
| 566 | 598 | |
|---|
| 567 | | - pr_debug("Cache Setup find last level cpu=%d\n", cpu); |
|---|
| 599 | + pr_debug("Cache Setup find last level CPU=%d\n", cpu); |
|---|
| 568 | 600 | |
|---|
| 569 | 601 | acpi_cpu_id = get_acpi_id_for_cpu(cpu); |
|---|
| 570 | 602 | status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); |
|---|
| 571 | 603 | if (ACPI_FAILURE(status)) { |
|---|
| 572 | | - pr_warn_once("No PPTT table found, cache topology may be inaccurate\n"); |
|---|
| 604 | + acpi_pptt_warn_missing(); |
|---|
| 573 | 605 | } else { |
|---|
| 574 | 606 | number_of_levels = acpi_find_cache_levels(table, acpi_cpu_id); |
|---|
| 575 | 607 | acpi_put_table(table); |
|---|
| .. | .. |
|---|
| 581 | 613 | |
|---|
| 582 | 614 | /** |
|---|
| 583 | 615 | * cache_setup_acpi() - Override CPU cache topology with data from the PPTT |
|---|
| 584 | | - * @cpu: Kernel logical cpu number |
|---|
| 616 | + * @cpu: Kernel logical CPU number |
|---|
| 585 | 617 | * |
|---|
| 586 | 618 | * Updates the global cache info provided by cpu_get_cacheinfo() |
|---|
| 587 | 619 | * when there are valid properties in the acpi_pptt_cache nodes. A |
|---|
| 588 | 620 | * successful parse may not result in any updates if none of the |
|---|
| 589 | | - * cache levels have any valid flags set. Futher, a unique value is |
|---|
| 621 | + * cache levels have any valid flags set. Further, a unique value is |
|---|
| 590 | 622 | * associated with each known CPU cache entry. This unique value |
|---|
| 591 | | - * can be used to determine whether caches are shared between cpus. |
|---|
| 623 | + * can be used to determine whether caches are shared between CPUs. |
|---|
| 592 | 624 | * |
|---|
| 593 | 625 | * Return: -ENOENT on failure to find table, or 0 on success |
|---|
| 594 | 626 | */ |
|---|
| .. | .. |
|---|
| 597 | 629 | struct acpi_table_header *table; |
|---|
| 598 | 630 | acpi_status status; |
|---|
| 599 | 631 | |
|---|
| 600 | | - pr_debug("Cache Setup ACPI cpu %d\n", cpu); |
|---|
| 632 | + pr_debug("Cache Setup ACPI CPU %d\n", cpu); |
|---|
| 601 | 633 | |
|---|
| 602 | 634 | status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); |
|---|
| 603 | 635 | if (ACPI_FAILURE(status)) { |
|---|
| 604 | | - pr_warn_once("No PPTT table found, cache topology may be inaccurate\n"); |
|---|
| 636 | + acpi_pptt_warn_missing(); |
|---|
| 605 | 637 | return -ENOENT; |
|---|
| 606 | 638 | } |
|---|
| 607 | 639 | |
|---|
| .. | .. |
|---|
| 626 | 658 | } |
|---|
| 627 | 659 | |
|---|
| 628 | 660 | /** |
|---|
| 629 | | - * find_acpi_cpu_topology() - Determine a unique topology value for a given cpu |
|---|
| 630 | | - * @cpu: Kernel logical cpu number |
|---|
| 661 | + * find_acpi_cpu_topology() - Determine a unique topology value for a given CPU |
|---|
| 662 | + * @cpu: Kernel logical CPU number |
|---|
| 631 | 663 | * @level: The topological level for which we would like a unique ID |
|---|
| 632 | 664 | * |
|---|
| 633 | 665 | * Determine a topology unique ID for each thread/core/cluster/mc_grouping |
|---|
| .. | .. |
|---|
| 640 | 672 | * other levels beyond this use a generated value to uniquely identify |
|---|
| 641 | 673 | * a topological feature. |
|---|
| 642 | 674 | * |
|---|
| 643 | | - * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found. |
|---|
| 675 | + * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found. |
|---|
| 644 | 676 | * Otherwise returns a value which represents a unique topological feature. |
|---|
| 645 | 677 | */ |
|---|
| 646 | 678 | int find_acpi_cpu_topology(unsigned int cpu, int level) |
|---|
| .. | .. |
|---|
| 650 | 682 | |
|---|
| 651 | 683 | /** |
|---|
| 652 | 684 | * find_acpi_cpu_cache_topology() - Determine a unique cache topology value |
|---|
| 653 | | - * @cpu: Kernel logical cpu number |
|---|
| 685 | + * @cpu: Kernel logical CPU number |
|---|
| 654 | 686 | * @level: The cache level for which we would like a unique ID |
|---|
| 655 | 687 | * |
|---|
| 656 | 688 | * Determine a unique ID for each unified cache in the system |
|---|
| 657 | 689 | * |
|---|
| 658 | | - * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found. |
|---|
| 690 | + * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found. |
|---|
| 659 | 691 | * Otherwise returns a value which represents a unique topological feature. |
|---|
| 660 | 692 | */ |
|---|
| 661 | 693 | int find_acpi_cpu_cache_topology(unsigned int cpu, int level) |
|---|
| .. | .. |
|---|
| 669 | 701 | |
|---|
| 670 | 702 | status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); |
|---|
| 671 | 703 | if (ACPI_FAILURE(status)) { |
|---|
| 672 | | - pr_warn_once("No PPTT table found, topology may be inaccurate\n"); |
|---|
| 704 | + acpi_pptt_warn_missing(); |
|---|
| 673 | 705 | return -ENOENT; |
|---|
| 674 | 706 | } |
|---|
| 675 | 707 | |
|---|
| .. | .. |
|---|
| 685 | 717 | return ret; |
|---|
| 686 | 718 | } |
|---|
| 687 | 719 | |
|---|
| 688 | | - |
|---|
| 689 | 720 | /** |
|---|
| 690 | | - * find_acpi_cpu_topology_package() - Determine a unique cpu package value |
|---|
| 691 | | - * @cpu: Kernel logical cpu number |
|---|
| 721 | + * find_acpi_cpu_topology_package() - Determine a unique CPU package value |
|---|
| 722 | + * @cpu: Kernel logical CPU number |
|---|
| 692 | 723 | * |
|---|
| 693 | | - * Determine a topology unique package ID for the given cpu. |
|---|
| 724 | + * Determine a topology unique package ID for the given CPU. |
|---|
| 694 | 725 | * This ID can then be used to group peers, which will have matching ids. |
|---|
| 695 | 726 | * |
|---|
| 696 | 727 | * The search terminates when either a level is found with the PHYSICAL_PACKAGE |
|---|
| 697 | 728 | * flag set or we reach a root node. |
|---|
| 698 | 729 | * |
|---|
| 699 | | - * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found. |
|---|
| 700 | | - * Otherwise returns a value which represents the package for this cpu. |
|---|
| 730 | + * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found. |
|---|
| 731 | + * Otherwise returns a value which represents the package for this CPU. |
|---|
| 701 | 732 | */ |
|---|
| 702 | 733 | int find_acpi_cpu_topology_package(unsigned int cpu) |
|---|
| 703 | 734 | { |
|---|
| 704 | 735 | return find_acpi_cpu_topology_tag(cpu, PPTT_ABORT_PACKAGE, |
|---|
| 705 | 736 | ACPI_PPTT_PHYSICAL_PACKAGE); |
|---|
| 706 | 737 | } |
|---|
| 738 | + |
|---|
| 739 | +/** |
|---|
| 740 | + * find_acpi_cpu_topology_hetero_id() - Get a core architecture tag |
|---|
| 741 | + * @cpu: Kernel logical CPU number |
|---|
| 742 | + * |
|---|
| 743 | + * Determine a unique heterogeneous tag for the given CPU. CPUs with the same |
|---|
| 744 | + * implementation should have matching tags. |
|---|
| 745 | + * |
|---|
| 746 | + * The returned tag can be used to group peers with identical implementation. |
|---|
| 747 | + * |
|---|
| 748 | + * The search terminates when a level is found with the identical implementation |
|---|
| 749 | + * flag set or we reach a root node. |
|---|
| 750 | + * |
|---|
| 751 | + * Due to limitations in the PPTT data structure, there may be rare situations |
|---|
| 752 | + * where two cores in a heterogeneous machine may be identical, but won't have |
|---|
| 753 | + * the same tag. |
|---|
| 754 | + * |
|---|
| 755 | + * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found. |
|---|
| 756 | + * Otherwise returns a value which represents a group of identical cores |
|---|
| 757 | + * similar to this CPU. |
|---|
| 758 | + */ |
|---|
| 759 | +int find_acpi_cpu_topology_hetero_id(unsigned int cpu) |
|---|
| 760 | +{ |
|---|
| 761 | + return find_acpi_cpu_topology_tag(cpu, PPTT_ABORT_PACKAGE, |
|---|
| 762 | + ACPI_PPTT_ACPI_IDENTICAL); |
|---|
| 763 | +} |
|---|