/** * find_acpi_cpu_cache_topology() - Determine a unique cache topology value * @cpu: Kernel logical CPU number * @level: The cache level for which we would like a unique ID * * Determine a unique ID for each unified cache in the system * * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found. * Otherwise returns a value which represents a unique topological feature. */ int find_acpi_cpu_cache_topology(unsigned int cpu, int level) { struct acpi_table_header *table; struct acpi_pptt_cache *found_cache; acpi_status status; u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu); struct acpi_pptt_processor *cpu_node = NULL; int ret = -1; status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); if (ACPI_FAILURE(status)) { acpi_pptt_warn_missing(); return -ENOENT; } found_cache = acpi_find_cache_node(table, acpi_cpu_id, CACHE_TYPE_UNIFIED, level, &cpu_node); if (found_cache) ret = ACPI_PTR_DIFF(cpu_node, table); acpi_put_table(table); return ret; }
static void cache_setup_acpi_cpu(struct acpi_table_header *table, unsigned int cpu) { struct acpi_pptt_cache *found_cache; struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu); struct cacheinfo *this_leaf; unsigned int index = 0; struct acpi_pptt_processor *cpu_node = NULL; while (index < get_cpu_cacheinfo(cpu)->num_leaves) { this_leaf = this_cpu_ci->info_list + index; found_cache = acpi_find_cache_node(table, acpi_cpu_id, this_leaf->type, this_leaf->level, &cpu_node); pr_debug("found = %p %p\n", found_cache, cpu_node); if (found_cache) update_cache_properties(this_leaf, found_cache, cpu_node); index++; } }
/** * topology_get_acpi_cpu_tag() - Find a unique topology value for a feature * @table: Pointer to the head of the PPTT table * @cpu: Kernel logical CPU number * @level: A level that terminates the search * @flag: A flag which terminates the search * * Get a unique value given a CPU, and a topology level, that can be * matched to determine which cpus share common topological features * at that level. * * Return: Unique value, or -ENOENT if unable to locate CPU */ static int topology_get_acpi_cpu_tag(struct acpi_table_header *table, unsigned int cpu, int level, int flag) { struct acpi_pptt_processor *cpu_node; u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu); cpu_node = acpi_find_processor_node(table, acpi_cpu_id); if (cpu_node) { cpu_node = acpi_find_processor_package_id(table, cpu_node, level, flag); /* * As per specification if the processor structure represents * an actual processor, then ACPI processor ID must be valid. * For processor containers ACPI_PPTT_ACPI_PROCESSOR_ID_VALID * should be set if the UID is valid */ if (level == 0 || cpu_node->flags & ACPI_PPTT_ACPI_PROCESSOR_ID_VALID) return cpu_node->acpi_processor_id; return ACPI_PTR_DIFF(cpu_node, table); } pr_warn_once("PPTT table found, but unable to locate core %d (%d)\n", cpu, acpi_cpu_id); return -ENOENT; }
static inline int get_cpu_for_acpi_id(u32 uid) { int cpu; for (cpu = 0; cpu < nr_cpu_ids; cpu++) if (uid == get_acpi_id_for_cpu(cpu)) return cpu; return -EINVAL; }
/** * acpi_find_last_cache_level() - Determines the number of cache levels for a PE * @cpu: Kernel logical CPU number * * Given a logical CPU number, returns the number of levels of cache represented * in the PPTT. Errors caused by lack of a PPTT table, or otherwise, return 0 * indicating we didn't find any cache levels. * * Return: Cache levels visible to this core. */ int acpi_find_last_cache_level(unsigned int cpu) { u32 acpi_cpu_id; struct acpi_table_header *table; int number_of_levels = 0; acpi_status status; pr_debug("Cache Setup find last level CPU=%d\n", cpu); acpi_cpu_id = get_acpi_id_for_cpu(cpu); status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); if (ACPI_FAILURE(status)) { acpi_pptt_warn_missing(); } else { number_of_levels = acpi_find_cache_levels(table, acpi_cpu_id); acpi_put_table(table); } pr_debug("Cache Setup find last level level=%d\n", number_of_levels); return number_of_levels; }