static int __init_cache_level(unsigned int cpu) { unsigned int ctype, level, leaves, of_level; struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); for (level = 1, leaves = 0; level <= MAX_CACHE_LEVEL; level++) { ctype = get_cache_type(level); if (ctype == CACHE_TYPE_NOCACHE) { level--; break; } /* Separate instruction and data caches */ leaves += (ctype == CACHE_TYPE_SEPARATE) ? 2 : 1; } of_level = of_find_last_cache_level(cpu); if (level < of_level) { /* * some external caches not specified in CLIDR_EL1 * the information may be available in the device tree * only unified external caches are considered here */ leaves += (of_level - level); level = of_level; } this_cpu_ci->num_levels = level; this_cpu_ci->num_leaves = leaves; return 0; }
bool DieHolder::get_ordinal(uint32 *ordinal) { die_cache cache; bool const found = get_cache_type(&cache); if(found) { *ordinal = cache.ordinal; } return found; }
static int __populate_cache_leaves(unsigned int cpu) { unsigned int level, idx; enum cache_type type; struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); struct cacheinfo *this_leaf = this_cpu_ci->info_list; for (idx = 0, level = 1; level <= this_cpu_ci->num_levels && idx < this_cpu_ci->num_leaves; idx++, level++) { type = get_cache_type(level); if (type == CACHE_TYPE_SEPARATE) { ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level); ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level); } else { ci_leaf_init(this_leaf++, type, level); } } return 0; }
/* * add_cpu_cache_detail() * @cache: cpu_cache_t pointer. * @index_path: full /sys path to the particular cpu cache which is to * be represented by @cache. * Populate the specified @cache based on the given cache index. * * Returns: EXIT_FAILURE or EXIT_SUCCESS. */ static int add_cpu_cache_detail(cpu_cache_t *cache, const char *index_path) { const size_t index_posn = index_path ? strlen(index_path) : 0; const size_t path_len = index_posn + 32; char path[path_len]; char *contents = NULL; int ret = EXIT_FAILURE; (void)memset(path, 0, sizeof(path)); if (!cache) { pr_dbg("%s: invalid cache specified\n", __func__); goto out; } if (!index_path) { pr_dbg("%s: invalid index specified\n", __func__); goto out; } (void)strncpy(path, index_path, index_posn + 1); mk_path(path, index_posn, "/type"); contents = get_string_from_file(path); if (!contents) goto out; cache->type = (cache_type_t)get_cache_type(contents); if (cache->type == CACHE_TYPE_UNKNOWN) goto out; free(contents); mk_path(path, index_posn, "/size"); contents = get_string_from_file(path); if (!contents) goto out; cache->size = size_to_bytes(contents); free(contents); mk_path(path, index_posn, "/level"); contents = get_string_from_file(path); if (!contents) goto out; cache->level = (uint16_t)atoi(contents); free(contents); mk_path(path, index_posn, "/coherency_line_size"); contents = get_string_from_file(path); if (!contents) goto out; cache->line_size = (uint32_t)atoi(contents); free(contents); mk_path(path, index_posn, "/ways_of_associativity"); contents = get_string_from_file(path); /* Don't error if file is not readable: cache may not be * way-based. */ cache->ways = contents ? atoi(contents) : 0; ret = EXIT_SUCCESS; out: if (contents) free(contents); return ret; }