static struct device_node *cpu_to_l2cache(int cpu) { struct device_node *np; struct device_node *cache; if (!cpu_present(cpu)) return NULL; np = of_get_cpu_node(cpu, NULL); if (np == NULL) return NULL; cache = of_find_next_cache_node(np); of_node_put(np); return cache; }
static int cache_setup_of_node(unsigned int cpu) { struct device_node *np; struct cacheinfo *this_leaf; struct device *cpu_dev = get_cpu_device(cpu); struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); unsigned int index = 0; /* skip if of_node is already populated */ if (this_cpu_ci->info_list->of_node) return 0; if (!cpu_dev) { pr_err("No cpu device for CPU %d\n", cpu); return -ENODEV; } np = cpu_dev->of_node; if (!np) { pr_err("Failed to find cpu%d device node\n", cpu); return -ENOENT; } while (index < cache_leaves(cpu)) { this_leaf = this_cpu_ci->info_list + index; if (this_leaf->level != 1) np = of_find_next_cache_node(np); else np = of_node_get(np);/* cpu node itself */ if (!np) break; this_leaf->of_node = np; index++; } if (index != cache_leaves(cpu)) /* not all OF nodes populated */ return -ENOENT; return 0; }
void __init initialize_cache_info(void) { struct device_node *cpu = NULL, *l2, *l3 = NULL; u32 pvr; DBG(" -> initialize_cache_info()\n"); /* * All shipping POWER8 machines have a firmware bug that * puts incorrect information in the device-tree. This will * be (hopefully) fixed for future chips but for now hard * code the values if we are running on one of these */ pvr = PVR_VER(mfspr(SPRN_PVR)); if (pvr == PVR_POWER8 || pvr == PVR_POWER8E || pvr == PVR_POWER8NVL) { /* size lsize blk sets */ init_cache_info(&ppc64_caches.l1i, 0x8000, 128, 128, 32); init_cache_info(&ppc64_caches.l1d, 0x10000, 128, 128, 64); init_cache_info(&ppc64_caches.l2, 0x80000, 128, 0, 512); init_cache_info(&ppc64_caches.l3, 0x800000, 128, 0, 8192); } else cpu = of_find_node_by_type(NULL, "cpu"); /* * We're assuming *all* of the CPUs have the same * d-cache and i-cache sizes... -Peter */ if (cpu) { if (!parse_cache_info(cpu, false, &ppc64_caches.l1d)) DBG("Argh, can't find dcache properties !\n"); if (!parse_cache_info(cpu, true, &ppc64_caches.l1i)) DBG("Argh, can't find icache properties !\n"); /* * Try to find the L2 and L3 if any. Assume they are * unified and use the D-side properties. */ l2 = of_find_next_cache_node(cpu); of_node_put(cpu); if (l2) { parse_cache_info(l2, false, &ppc64_caches.l2); l3 = of_find_next_cache_node(l2); of_node_put(l2); } if (l3) { parse_cache_info(l3, false, &ppc64_caches.l3); of_node_put(l3); } } /* For use by binfmt_elf */ dcache_bsize = ppc64_caches.l1d.block_size; icache_bsize = ppc64_caches.l1i.block_size; cur_cpu_spec->dcache_bsize = dcache_bsize; cur_cpu_spec->icache_bsize = icache_bsize; DBG(" <- initialize_cache_info()\n"); }