Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * pptt.c - parsing of Processor Properties Topology Table (PPTT)
0004  *
0005  * Copyright (C) 2018, ARM
0006  *
0007  * This file implements parsing of the Processor Properties Topology Table
0008  * which is optionally used to describe the processor and cache topology.
0009  * Due to the relative pointers used throughout the table, this doesn't
0010  * leverage the existing subtable parsing in the kernel.
0011  *
0012  * The PPTT structure is an inverted tree, with each node potentially
0013  * holding one or two inverted tree data structures describing
0014  * the caches available at that level. Each cache structure optionally
0015  * contains properties describing the cache at a given level which can be
0016  * used to override hardware probed values.
0017  */
0018 #define pr_fmt(fmt) "ACPI PPTT: " fmt
0019 
0020 #include <linux/acpi.h>
0021 #include <linux/cacheinfo.h>
0022 #include <acpi/processor.h>
0023 
0024 static struct acpi_subtable_header *fetch_pptt_subtable(struct acpi_table_header *table_hdr,
0025                             u32 pptt_ref)
0026 {
0027     struct acpi_subtable_header *entry;
0028 
0029     /* there isn't a subtable at reference 0 */
0030     if (pptt_ref < sizeof(struct acpi_subtable_header))
0031         return NULL;
0032 
0033     if (pptt_ref + sizeof(struct acpi_subtable_header) > table_hdr->length)
0034         return NULL;
0035 
0036     entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr, pptt_ref);
0037 
0038     if (entry->length == 0)
0039         return NULL;
0040 
0041     if (pptt_ref + entry->length > table_hdr->length)
0042         return NULL;
0043 
0044     return entry;
0045 }
0046 
0047 static struct acpi_pptt_processor *fetch_pptt_node(struct acpi_table_header *table_hdr,
0048                            u32 pptt_ref)
0049 {
0050     return (struct acpi_pptt_processor *)fetch_pptt_subtable(table_hdr, pptt_ref);
0051 }
0052 
0053 static struct acpi_pptt_cache *fetch_pptt_cache(struct acpi_table_header *table_hdr,
0054                         u32 pptt_ref)
0055 {
0056     return (struct acpi_pptt_cache *)fetch_pptt_subtable(table_hdr, pptt_ref);
0057 }
0058 
0059 static struct acpi_subtable_header *acpi_get_pptt_resource(struct acpi_table_header *table_hdr,
0060                                struct acpi_pptt_processor *node,
0061                                int resource)
0062 {
0063     u32 *ref;
0064 
0065     if (resource >= node->number_of_priv_resources)
0066         return NULL;
0067 
0068     ref = ACPI_ADD_PTR(u32, node, sizeof(struct acpi_pptt_processor));
0069     ref += resource;
0070 
0071     return fetch_pptt_subtable(table_hdr, *ref);
0072 }
0073 
0074 static inline bool acpi_pptt_match_type(int table_type, int type)
0075 {
0076     return ((table_type & ACPI_PPTT_MASK_CACHE_TYPE) == type ||
0077         table_type & ACPI_PPTT_CACHE_TYPE_UNIFIED & type);
0078 }
0079 
0080 /**
0081  * acpi_pptt_walk_cache() - Attempt to find the requested acpi_pptt_cache
0082  * @table_hdr: Pointer to the head of the PPTT table
0083  * @local_level: passed res reflects this cache level
0084  * @res: cache resource in the PPTT we want to walk
0085  * @found: returns a pointer to the requested level if found
0086  * @level: the requested cache level
0087  * @type: the requested cache type
0088  *
0089  * Attempt to find a given cache level, while counting the max number
0090  * of cache levels for the cache node.
0091  *
0092  * Given a pptt resource, verify that it is a cache node, then walk
0093  * down each level of caches, counting how many levels are found
0094  * as well as checking the cache type (icache, dcache, unified). If a
0095  * level & type match, then we set found, and continue the search.
0096  * Once the entire cache branch has been walked return its max
0097  * depth.
0098  *
0099  * Return: The cache structure and the level we terminated with.
0100  */
0101 static unsigned int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr,
0102                      unsigned int local_level,
0103                      struct acpi_subtable_header *res,
0104                      struct acpi_pptt_cache **found,
0105                      unsigned int level, int type)
0106 {
0107     struct acpi_pptt_cache *cache;
0108 
0109     if (res->type != ACPI_PPTT_TYPE_CACHE)
0110         return 0;
0111 
0112     cache = (struct acpi_pptt_cache *) res;
0113     while (cache) {
0114         local_level++;
0115 
0116         if (local_level == level &&
0117             cache->flags & ACPI_PPTT_CACHE_TYPE_VALID &&
0118             acpi_pptt_match_type(cache->attributes, type)) {
0119             if (*found != NULL && cache != *found)
0120                 pr_warn("Found duplicate cache level/type unable to determine uniqueness\n");
0121 
0122             pr_debug("Found cache @ level %u\n", level);
0123             *found = cache;
0124             /*
0125              * continue looking at this node's resource list
0126              * to verify that we don't find a duplicate
0127              * cache node.
0128              */
0129         }
0130         cache = fetch_pptt_cache(table_hdr, cache->next_level_of_cache);
0131     }
0132     return local_level;
0133 }
0134 
0135 static struct acpi_pptt_cache *
0136 acpi_find_cache_level(struct acpi_table_header *table_hdr,
0137               struct acpi_pptt_processor *cpu_node,
0138               unsigned int *starting_level, unsigned int level,
0139               int type)
0140 {
0141     struct acpi_subtable_header *res;
0142     unsigned int number_of_levels = *starting_level;
0143     int resource = 0;
0144     struct acpi_pptt_cache *ret = NULL;
0145     unsigned int local_level;
0146 
0147     /* walk down from processor node */
0148     while ((res = acpi_get_pptt_resource(table_hdr, cpu_node, resource))) {
0149         resource++;
0150 
0151         local_level = acpi_pptt_walk_cache(table_hdr, *starting_level,
0152                            res, &ret, level, type);
0153         /*
0154          * we are looking for the max depth. Since its potentially
0155          * possible for a given node to have resources with differing
0156          * depths verify that the depth we have found is the largest.
0157          */
0158         if (number_of_levels < local_level)
0159             number_of_levels = local_level;
0160     }
0161     if (number_of_levels > *starting_level)
0162         *starting_level = number_of_levels;
0163 
0164     return ret;
0165 }
0166 
0167 /**
0168  * acpi_count_levels() - Given a PPTT table, and a CPU node, count the caches
0169  * @table_hdr: Pointer to the head of the PPTT table
0170  * @cpu_node: processor node we wish to count caches for
0171  *
0172  * Given a processor node containing a processing unit, walk into it and count
0173  * how many levels exist solely for it, and then walk up each level until we hit
0174  * the root node (ignore the package level because it may be possible to have
0175  * caches that exist across packages). Count the number of cache levels that
0176  * exist at each level on the way up.
0177  *
0178  * Return: Total number of levels found.
0179  */
0180 static int acpi_count_levels(struct acpi_table_header *table_hdr,
0181                  struct acpi_pptt_processor *cpu_node)
0182 {
0183     int total_levels = 0;
0184 
0185     do {
0186         acpi_find_cache_level(table_hdr, cpu_node, &total_levels, 0, 0);
0187         cpu_node = fetch_pptt_node(table_hdr, cpu_node->parent);
0188     } while (cpu_node);
0189 
0190     return total_levels;
0191 }
0192 
0193 /**
0194  * acpi_pptt_leaf_node() - Given a processor node, determine if its a leaf
0195  * @table_hdr: Pointer to the head of the PPTT table
0196  * @node: passed node is checked to see if its a leaf
0197  *
0198  * Determine if the *node parameter is a leaf node by iterating the
0199  * PPTT table, looking for nodes which reference it.
0200  *
0201  * Return: 0 if we find a node referencing the passed node (or table error),
0202  * or 1 if we don't.
0203  */
0204 static int acpi_pptt_leaf_node(struct acpi_table_header *table_hdr,
0205                    struct acpi_pptt_processor *node)
0206 {
0207     struct acpi_subtable_header *entry;
0208     unsigned long table_end;
0209     u32 node_entry;
0210     struct acpi_pptt_processor *cpu_node;
0211     u32 proc_sz;
0212 
0213     if (table_hdr->revision > 1)
0214         return (node->flags & ACPI_PPTT_ACPI_LEAF_NODE);
0215 
0216     table_end = (unsigned long)table_hdr + table_hdr->length;
0217     node_entry = ACPI_PTR_DIFF(node, table_hdr);
0218     entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
0219                  sizeof(struct acpi_table_pptt));
0220     proc_sz = sizeof(struct acpi_pptt_processor *);
0221 
0222     while ((unsigned long)entry + proc_sz < table_end) {
0223         cpu_node = (struct acpi_pptt_processor *)entry;
0224         if (entry->type == ACPI_PPTT_TYPE_PROCESSOR &&
0225             cpu_node->parent == node_entry)
0226             return 0;
0227         if (entry->length == 0)
0228             return 0;
0229         entry = ACPI_ADD_PTR(struct acpi_subtable_header, entry,
0230                      entry->length);
0231 
0232     }
0233     return 1;
0234 }
0235 
0236 /**
0237  * acpi_find_processor_node() - Given a PPTT table find the requested processor
0238  * @table_hdr:  Pointer to the head of the PPTT table
0239  * @acpi_cpu_id: CPU we are searching for
0240  *
0241  * Find the subtable entry describing the provided processor.
0242  * This is done by iterating the PPTT table looking for processor nodes
0243  * which have an acpi_processor_id that matches the acpi_cpu_id parameter
0244  * passed into the function. If we find a node that matches this criteria
0245  * we verify that its a leaf node in the topology rather than depending
0246  * on the valid flag, which doesn't need to be set for leaf nodes.
0247  *
0248  * Return: NULL, or the processors acpi_pptt_processor*
0249  */
0250 static struct acpi_pptt_processor *acpi_find_processor_node(struct acpi_table_header *table_hdr,
0251                                 u32 acpi_cpu_id)
0252 {
0253     struct acpi_subtable_header *entry;
0254     unsigned long table_end;
0255     struct acpi_pptt_processor *cpu_node;
0256     u32 proc_sz;
0257 
0258     table_end = (unsigned long)table_hdr + table_hdr->length;
0259     entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
0260                  sizeof(struct acpi_table_pptt));
0261     proc_sz = sizeof(struct acpi_pptt_processor *);
0262 
0263     /* find the processor structure associated with this cpuid */
0264     while ((unsigned long)entry + proc_sz < table_end) {
0265         cpu_node = (struct acpi_pptt_processor *)entry;
0266 
0267         if (entry->length == 0) {
0268             pr_warn("Invalid zero length subtable\n");
0269             break;
0270         }
0271         if (entry->type == ACPI_PPTT_TYPE_PROCESSOR &&
0272             acpi_cpu_id == cpu_node->acpi_processor_id &&
0273              acpi_pptt_leaf_node(table_hdr, cpu_node)) {
0274             return (struct acpi_pptt_processor *)entry;
0275         }
0276 
0277         entry = ACPI_ADD_PTR(struct acpi_subtable_header, entry,
0278                      entry->length);
0279     }
0280 
0281     return NULL;
0282 }
0283 
0284 static int acpi_find_cache_levels(struct acpi_table_header *table_hdr,
0285                   u32 acpi_cpu_id)
0286 {
0287     int number_of_levels = 0;
0288     struct acpi_pptt_processor *cpu;
0289 
0290     cpu = acpi_find_processor_node(table_hdr, acpi_cpu_id);
0291     if (cpu)
0292         number_of_levels = acpi_count_levels(table_hdr, cpu);
0293 
0294     return number_of_levels;
0295 }
0296 
0297 static u8 acpi_cache_type(enum cache_type type)
0298 {
0299     switch (type) {
0300     case CACHE_TYPE_DATA:
0301         pr_debug("Looking for data cache\n");
0302         return ACPI_PPTT_CACHE_TYPE_DATA;
0303     case CACHE_TYPE_INST:
0304         pr_debug("Looking for instruction cache\n");
0305         return ACPI_PPTT_CACHE_TYPE_INSTR;
0306     default:
0307     case CACHE_TYPE_UNIFIED:
0308         pr_debug("Looking for unified cache\n");
0309         /*
0310          * It is important that ACPI_PPTT_CACHE_TYPE_UNIFIED
0311          * contains the bit pattern that will match both
0312          * ACPI unified bit patterns because we use it later
0313          * to match both cases.
0314          */
0315         return ACPI_PPTT_CACHE_TYPE_UNIFIED;
0316     }
0317 }
0318 
0319 static struct acpi_pptt_cache *acpi_find_cache_node(struct acpi_table_header *table_hdr,
0320                             u32 acpi_cpu_id,
0321                             enum cache_type type,
0322                             unsigned int level,
0323                             struct acpi_pptt_processor **node)
0324 {
0325     unsigned int total_levels = 0;
0326     struct acpi_pptt_cache *found = NULL;
0327     struct acpi_pptt_processor *cpu_node;
0328     u8 acpi_type = acpi_cache_type(type);
0329 
0330     pr_debug("Looking for CPU %d's level %u cache type %d\n",
0331          acpi_cpu_id, level, acpi_type);
0332 
0333     cpu_node = acpi_find_processor_node(table_hdr, acpi_cpu_id);
0334 
0335     while (cpu_node && !found) {
0336         found = acpi_find_cache_level(table_hdr, cpu_node,
0337                           &total_levels, level, acpi_type);
0338         *node = cpu_node;
0339         cpu_node = fetch_pptt_node(table_hdr, cpu_node->parent);
0340     }
0341 
0342     return found;
0343 }
0344 
0345 /**
0346  * update_cache_properties() - Update cacheinfo for the given processor
0347  * @this_leaf: Kernel cache info structure being updated
0348  * @found_cache: The PPTT node describing this cache instance
0349  * @cpu_node: A unique reference to describe this cache instance
0350  * @revision: The revision of the PPTT table
0351  *
0352  * The ACPI spec implies that the fields in the cache structures are used to
0353  * extend and correct the information probed from the hardware. Lets only
0354  * set fields that we determine are VALID.
0355  *
0356  * Return: nothing. Side effect of updating the global cacheinfo
0357  */
0358 static void update_cache_properties(struct cacheinfo *this_leaf,
0359                     struct acpi_pptt_cache *found_cache,
0360                     struct acpi_pptt_processor *cpu_node,
0361                     u8 revision)
0362 {
0363     struct acpi_pptt_cache_v1* found_cache_v1;
0364 
0365     this_leaf->fw_token = cpu_node;
0366     if (found_cache->flags & ACPI_PPTT_SIZE_PROPERTY_VALID)
0367         this_leaf->size = found_cache->size;
0368     if (found_cache->flags & ACPI_PPTT_LINE_SIZE_VALID)
0369         this_leaf->coherency_line_size = found_cache->line_size;
0370     if (found_cache->flags & ACPI_PPTT_NUMBER_OF_SETS_VALID)
0371         this_leaf->number_of_sets = found_cache->number_of_sets;
0372     if (found_cache->flags & ACPI_PPTT_ASSOCIATIVITY_VALID)
0373         this_leaf->ways_of_associativity = found_cache->associativity;
0374     if (found_cache->flags & ACPI_PPTT_WRITE_POLICY_VALID) {
0375         switch (found_cache->attributes & ACPI_PPTT_MASK_WRITE_POLICY) {
0376         case ACPI_PPTT_CACHE_POLICY_WT:
0377             this_leaf->attributes = CACHE_WRITE_THROUGH;
0378             break;
0379         case ACPI_PPTT_CACHE_POLICY_WB:
0380             this_leaf->attributes = CACHE_WRITE_BACK;
0381             break;
0382         }
0383     }
0384     if (found_cache->flags & ACPI_PPTT_ALLOCATION_TYPE_VALID) {
0385         switch (found_cache->attributes & ACPI_PPTT_MASK_ALLOCATION_TYPE) {
0386         case ACPI_PPTT_CACHE_READ_ALLOCATE:
0387             this_leaf->attributes |= CACHE_READ_ALLOCATE;
0388             break;
0389         case ACPI_PPTT_CACHE_WRITE_ALLOCATE:
0390             this_leaf->attributes |= CACHE_WRITE_ALLOCATE;
0391             break;
0392         case ACPI_PPTT_CACHE_RW_ALLOCATE:
0393         case ACPI_PPTT_CACHE_RW_ALLOCATE_ALT:
0394             this_leaf->attributes |=
0395                 CACHE_READ_ALLOCATE | CACHE_WRITE_ALLOCATE;
0396             break;
0397         }
0398     }
0399     /*
0400      * If cache type is NOCACHE, then the cache hasn't been specified
0401      * via other mechanisms.  Update the type if a cache type has been
0402      * provided.
0403      *
0404      * Note, we assume such caches are unified based on conventional system
0405      * design and known examples.  Significant work is required elsewhere to
0406      * fully support data/instruction only type caches which are only
0407      * specified in PPTT.
0408      */
0409     if (this_leaf->type == CACHE_TYPE_NOCACHE &&
0410         found_cache->flags & ACPI_PPTT_CACHE_TYPE_VALID)
0411         this_leaf->type = CACHE_TYPE_UNIFIED;
0412 
0413     if (revision >= 3 && (found_cache->flags & ACPI_PPTT_CACHE_ID_VALID)) {
0414         found_cache_v1 = ACPI_ADD_PTR(struct acpi_pptt_cache_v1,
0415                                           found_cache, sizeof(struct acpi_pptt_cache));
0416         this_leaf->id = found_cache_v1->cache_id;
0417         this_leaf->attributes |= CACHE_ID;
0418     }
0419 }
0420 
0421 static void cache_setup_acpi_cpu(struct acpi_table_header *table,
0422                  unsigned int cpu)
0423 {
0424     struct acpi_pptt_cache *found_cache;
0425     struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
0426     u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
0427     struct cacheinfo *this_leaf;
0428     unsigned int index = 0;
0429     struct acpi_pptt_processor *cpu_node = NULL;
0430 
0431     while (index < get_cpu_cacheinfo(cpu)->num_leaves) {
0432         this_leaf = this_cpu_ci->info_list + index;
0433         found_cache = acpi_find_cache_node(table, acpi_cpu_id,
0434                            this_leaf->type,
0435                            this_leaf->level,
0436                            &cpu_node);
0437         pr_debug("found = %p %p\n", found_cache, cpu_node);
0438         if (found_cache)
0439             update_cache_properties(this_leaf, found_cache,
0440                         ACPI_TO_POINTER(ACPI_PTR_DIFF(cpu_node, table)),
0441                         table->revision);
0442 
0443         index++;
0444     }
0445 }
0446 
0447 static bool flag_identical(struct acpi_table_header *table_hdr,
0448                struct acpi_pptt_processor *cpu)
0449 {
0450     struct acpi_pptt_processor *next;
0451 
0452     /* heterogeneous machines must use PPTT revision > 1 */
0453     if (table_hdr->revision < 2)
0454         return false;
0455 
0456     /* Locate the last node in the tree with IDENTICAL set */
0457     if (cpu->flags & ACPI_PPTT_ACPI_IDENTICAL) {
0458         next = fetch_pptt_node(table_hdr, cpu->parent);
0459         if (!(next && next->flags & ACPI_PPTT_ACPI_IDENTICAL))
0460             return true;
0461     }
0462 
0463     return false;
0464 }
0465 
0466 /* Passing level values greater than this will result in search termination */
0467 #define PPTT_ABORT_PACKAGE 0xFF
0468 
0469 static struct acpi_pptt_processor *acpi_find_processor_tag(struct acpi_table_header *table_hdr,
0470                                struct acpi_pptt_processor *cpu,
0471                                int level, int flag)
0472 {
0473     struct acpi_pptt_processor *prev_node;
0474 
0475     while (cpu && level) {
0476         /* special case the identical flag to find last identical */
0477         if (flag == ACPI_PPTT_ACPI_IDENTICAL) {
0478             if (flag_identical(table_hdr, cpu))
0479                 break;
0480         } else if (cpu->flags & flag)
0481             break;
0482         pr_debug("level %d\n", level);
0483         prev_node = fetch_pptt_node(table_hdr, cpu->parent);
0484         if (prev_node == NULL)
0485             break;
0486         cpu = prev_node;
0487         level--;
0488     }
0489     return cpu;
0490 }
0491 
0492 static void acpi_pptt_warn_missing(void)
0493 {
0494     pr_warn_once("No PPTT table found, CPU and cache topology may be inaccurate\n");
0495 }
0496 
0497 /**
0498  * topology_get_acpi_cpu_tag() - Find a unique topology value for a feature
0499  * @table: Pointer to the head of the PPTT table
0500  * @cpu: Kernel logical CPU number
0501  * @level: A level that terminates the search
0502  * @flag: A flag which terminates the search
0503  *
0504  * Get a unique value given a CPU, and a topology level, that can be
0505  * matched to determine which cpus share common topological features
0506  * at that level.
0507  *
0508  * Return: Unique value, or -ENOENT if unable to locate CPU
0509  */
0510 static int topology_get_acpi_cpu_tag(struct acpi_table_header *table,
0511                      unsigned int cpu, int level, int flag)
0512 {
0513     struct acpi_pptt_processor *cpu_node;
0514     u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
0515 
0516     cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
0517     if (cpu_node) {
0518         cpu_node = acpi_find_processor_tag(table, cpu_node,
0519                            level, flag);
0520         /*
0521          * As per specification if the processor structure represents
0522          * an actual processor, then ACPI processor ID must be valid.
0523          * For processor containers ACPI_PPTT_ACPI_PROCESSOR_ID_VALID
0524          * should be set if the UID is valid
0525          */
0526         if (level == 0 ||
0527             cpu_node->flags & ACPI_PPTT_ACPI_PROCESSOR_ID_VALID)
0528             return cpu_node->acpi_processor_id;
0529         return ACPI_PTR_DIFF(cpu_node, table);
0530     }
0531     pr_warn_once("PPTT table found, but unable to locate core %d (%d)\n",
0532             cpu, acpi_cpu_id);
0533     return -ENOENT;
0534 }
0535 
0536 
0537 static struct acpi_table_header *acpi_get_pptt(void)
0538 {
0539     static struct acpi_table_header *pptt;
0540     acpi_status status;
0541 
0542     /*
0543      * PPTT will be used at runtime on every CPU hotplug in path, so we
0544      * don't need to call acpi_put_table() to release the table mapping.
0545      */
0546     if (!pptt) {
0547         status = acpi_get_table(ACPI_SIG_PPTT, 0, &pptt);
0548         if (ACPI_FAILURE(status))
0549             acpi_pptt_warn_missing();
0550     }
0551 
0552     return pptt;
0553 }
0554 
0555 static int find_acpi_cpu_topology_tag(unsigned int cpu, int level, int flag)
0556 {
0557     struct acpi_table_header *table;
0558     int retval;
0559 
0560     table = acpi_get_pptt();
0561     if (!table)
0562         return -ENOENT;
0563 
0564     retval = topology_get_acpi_cpu_tag(table, cpu, level, flag);
0565     pr_debug("Topology Setup ACPI CPU %d, level %d ret = %d\n",
0566          cpu, level, retval);
0567 
0568     return retval;
0569 }
0570 
0571 /**
0572  * check_acpi_cpu_flag() - Determine if CPU node has a flag set
0573  * @cpu: Kernel logical CPU number
0574  * @rev: The minimum PPTT revision defining the flag
0575  * @flag: The flag itself
0576  *
0577  * Check the node representing a CPU for a given flag.
0578  *
0579  * Return: -ENOENT if the PPTT doesn't exist, the CPU cannot be found or
0580  *     the table revision isn't new enough.
0581  *     1, any passed flag set
0582  *     0, flag unset
0583  */
0584 static int check_acpi_cpu_flag(unsigned int cpu, int rev, u32 flag)
0585 {
0586     struct acpi_table_header *table;
0587     u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
0588     struct acpi_pptt_processor *cpu_node = NULL;
0589     int ret = -ENOENT;
0590 
0591     table = acpi_get_pptt();
0592     if (!table)
0593         return -ENOENT;
0594 
0595     if (table->revision >= rev)
0596         cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
0597 
0598     if (cpu_node)
0599         ret = (cpu_node->flags & flag) != 0;
0600 
0601     return ret;
0602 }
0603 
0604 /**
0605  * acpi_find_last_cache_level() - Determines the number of cache levels for a PE
0606  * @cpu: Kernel logical CPU number
0607  *
0608  * Given a logical CPU number, returns the number of levels of cache represented
0609  * in the PPTT. Errors caused by lack of a PPTT table, or otherwise, return 0
0610  * indicating we didn't find any cache levels.
0611  *
0612  * Return: Cache levels visible to this core.
0613  */
0614 int acpi_find_last_cache_level(unsigned int cpu)
0615 {
0616     u32 acpi_cpu_id;
0617     struct acpi_table_header *table;
0618     int number_of_levels = 0;
0619 
0620     table = acpi_get_pptt();
0621     if (!table)
0622         return -ENOENT;
0623 
0624     pr_debug("Cache Setup find last level CPU=%d\n", cpu);
0625 
0626     acpi_cpu_id = get_acpi_id_for_cpu(cpu);
0627     number_of_levels = acpi_find_cache_levels(table, acpi_cpu_id);
0628     pr_debug("Cache Setup find last level level=%d\n", number_of_levels);
0629 
0630     return number_of_levels;
0631 }
0632 
0633 /**
0634  * cache_setup_acpi() - Override CPU cache topology with data from the PPTT
0635  * @cpu: Kernel logical CPU number
0636  *
0637  * Updates the global cache info provided by cpu_get_cacheinfo()
0638  * when there are valid properties in the acpi_pptt_cache nodes. A
0639  * successful parse may not result in any updates if none of the
0640  * cache levels have any valid flags set.  Further, a unique value is
0641  * associated with each known CPU cache entry. This unique value
0642  * can be used to determine whether caches are shared between CPUs.
0643  *
0644  * Return: -ENOENT on failure to find table, or 0 on success
0645  */
0646 int cache_setup_acpi(unsigned int cpu)
0647 {
0648     struct acpi_table_header *table;
0649 
0650     table = acpi_get_pptt();
0651     if (!table)
0652         return -ENOENT;
0653 
0654     pr_debug("Cache Setup ACPI CPU %d\n", cpu);
0655 
0656     cache_setup_acpi_cpu(table, cpu);
0657 
0658     return 0;
0659 }
0660 
0661 /**
0662  * acpi_pptt_cpu_is_thread() - Determine if CPU is a thread
0663  * @cpu: Kernel logical CPU number
0664  *
0665  * Return: 1, a thread
0666  *         0, not a thread
0667  *         -ENOENT ,if the PPTT doesn't exist, the CPU cannot be found or
0668  *         the table revision isn't new enough.
0669  */
0670 int acpi_pptt_cpu_is_thread(unsigned int cpu)
0671 {
0672     return check_acpi_cpu_flag(cpu, 2, ACPI_PPTT_ACPI_PROCESSOR_IS_THREAD);
0673 }
0674 
0675 /**
0676  * find_acpi_cpu_topology() - Determine a unique topology value for a given CPU
0677  * @cpu: Kernel logical CPU number
0678  * @level: The topological level for which we would like a unique ID
0679  *
0680  * Determine a topology unique ID for each thread/core/cluster/mc_grouping
0681  * /socket/etc. This ID can then be used to group peers, which will have
0682  * matching ids.
0683  *
0684  * The search terminates when either the requested level is found or
0685  * we reach a root node. Levels beyond the termination point will return the
0686  * same unique ID. The unique id for level 0 is the acpi processor id. All
0687  * other levels beyond this use a generated value to uniquely identify
0688  * a topological feature.
0689  *
0690  * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found.
0691  * Otherwise returns a value which represents a unique topological feature.
0692  */
0693 int find_acpi_cpu_topology(unsigned int cpu, int level)
0694 {
0695     return find_acpi_cpu_topology_tag(cpu, level, 0);
0696 }
0697 
0698 /**
0699  * find_acpi_cpu_topology_package() - Determine a unique CPU package value
0700  * @cpu: Kernel logical CPU number
0701  *
0702  * Determine a topology unique package ID for the given CPU.
0703  * This ID can then be used to group peers, which will have matching ids.
0704  *
0705  * The search terminates when either a level is found with the PHYSICAL_PACKAGE
0706  * flag set or we reach a root node.
0707  *
0708  * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found.
0709  * Otherwise returns a value which represents the package for this CPU.
0710  */
0711 int find_acpi_cpu_topology_package(unsigned int cpu)
0712 {
0713     return find_acpi_cpu_topology_tag(cpu, PPTT_ABORT_PACKAGE,
0714                       ACPI_PPTT_PHYSICAL_PACKAGE);
0715 }
0716 
0717 /**
0718  * find_acpi_cpu_topology_cluster() - Determine a unique CPU cluster value
0719  * @cpu: Kernel logical CPU number
0720  *
0721  * Determine a topology unique cluster ID for the given CPU/thread.
0722  * This ID can then be used to group peers, which will have matching ids.
0723  *
0724  * The cluster, if present is the level of topology above CPUs. In a
0725  * multi-thread CPU, it will be the level above the CPU, not the thread.
0726  * It may not exist in single CPU systems. In simple multi-CPU systems,
0727  * it may be equal to the package topology level.
0728  *
0729  * Return: -ENOENT if the PPTT doesn't exist, the CPU cannot be found
0730  * or there is no toplogy level above the CPU..
0731  * Otherwise returns a value which represents the package for this CPU.
0732  */
0733 
0734 int find_acpi_cpu_topology_cluster(unsigned int cpu)
0735 {
0736     struct acpi_table_header *table;
0737     struct acpi_pptt_processor *cpu_node, *cluster_node;
0738     u32 acpi_cpu_id;
0739     int retval;
0740     int is_thread;
0741 
0742     table = acpi_get_pptt();
0743     if (!table)
0744         return -ENOENT;
0745 
0746     acpi_cpu_id = get_acpi_id_for_cpu(cpu);
0747     cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
0748     if (!cpu_node || !cpu_node->parent)
0749         return -ENOENT;
0750 
0751     is_thread = cpu_node->flags & ACPI_PPTT_ACPI_PROCESSOR_IS_THREAD;
0752     cluster_node = fetch_pptt_node(table, cpu_node->parent);
0753     if (!cluster_node)
0754         return -ENOENT;
0755 
0756     if (is_thread) {
0757         if (!cluster_node->parent)
0758             return -ENOENT;
0759 
0760         cluster_node = fetch_pptt_node(table, cluster_node->parent);
0761         if (!cluster_node)
0762             return -ENOENT;
0763     }
0764     if (cluster_node->flags & ACPI_PPTT_ACPI_PROCESSOR_ID_VALID)
0765         retval = cluster_node->acpi_processor_id;
0766     else
0767         retval = ACPI_PTR_DIFF(cluster_node, table);
0768 
0769     return retval;
0770 }
0771 
0772 /**
0773  * find_acpi_cpu_topology_hetero_id() - Get a core architecture tag
0774  * @cpu: Kernel logical CPU number
0775  *
0776  * Determine a unique heterogeneous tag for the given CPU. CPUs with the same
0777  * implementation should have matching tags.
0778  *
0779  * The returned tag can be used to group peers with identical implementation.
0780  *
0781  * The search terminates when a level is found with the identical implementation
0782  * flag set or we reach a root node.
0783  *
0784  * Due to limitations in the PPTT data structure, there may be rare situations
0785  * where two cores in a heterogeneous machine may be identical, but won't have
0786  * the same tag.
0787  *
0788  * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found.
0789  * Otherwise returns a value which represents a group of identical cores
0790  * similar to this CPU.
0791  */
0792 int find_acpi_cpu_topology_hetero_id(unsigned int cpu)
0793 {
0794     return find_acpi_cpu_topology_tag(cpu, PPTT_ABORT_PACKAGE,
0795                       ACPI_PPTT_ACPI_IDENTICAL);
0796 }