示例#1
0
static bool __init parse_cache_info(struct device_node *np,
				    bool icache,
				    struct ppc_cache_info *info)
{
	static const char *ipropnames[] __initdata = {
		"i-cache-size",
		"i-cache-sets",
		"i-cache-block-size",
		"i-cache-line-size",
	};
	static const char *dpropnames[] __initdata = {
		"d-cache-size",
		"d-cache-sets",
		"d-cache-block-size",
		"d-cache-line-size",
	};
	const char **propnames = icache ? ipropnames : dpropnames;
	const __be32 *sizep, *lsizep, *bsizep, *setsp;
	u32 size, lsize, bsize, sets;
	bool success = true;

	size = 0;
	sets = -1u;
	lsize = bsize = cur_cpu_spec->dcache_bsize;
	sizep = of_get_property(np, propnames[0], NULL);
	if (sizep != NULL)
		size = be32_to_cpu(*sizep);
	setsp = of_get_property(np, propnames[1], NULL);
	if (setsp != NULL)
		sets = be32_to_cpu(*setsp);
	bsizep = of_get_property(np, propnames[2], NULL);
	lsizep = of_get_property(np, propnames[3], NULL);
	if (bsizep == NULL)
		bsizep = lsizep;
	if (lsizep != NULL)
		lsize = be32_to_cpu(*lsizep);
	if (bsizep != NULL)
		bsize = be32_to_cpu(*bsizep);
	if (sizep == NULL || bsizep == NULL || lsizep == NULL)
		success = false;

	/*
	 * OF is weird .. it represents fully associative caches
	 * as "1 way" which doesn't make much sense and doesn't
	 * leave room for direct mapped. We'll assume that 0
	 * in OF means direct mapped for that reason.
	 */
	if (sets == 1)
		sets = 0;
	else if (sets == 0)
		sets = 1;

	init_cache_info(info, size, lsize, bsize, sets);

	return success;
}
/**
 * refresh_cache_info
 *
 * @returns 0 on success, !0 otherwise
 */
static int
refresh_cache_info(struct dr_info *dr_info)
{
	int rc;

	/* Some systems do not have cache device nodes.  Assume
	 * that if we did not find any cache nodes during initialization,
	 * we won't find any during a refresh.
	 */
	if (dr_info->all_caches == NULL)
		return 0;

	free_cache_info(dr_info->all_caches);
	
	rc = init_cache_info(dr_info);
	if (rc) {
		say(ERROR, "failed to refresh cache information\n");
		return rc;
	}

	return 0;
}
/**
 * init_cpu_drc_info
 *
 * @returns pointer to drc_info on success, NULL otherwise
 */
int
init_cpu_drc_info(struct dr_info *dr_info)
{
	struct dr_node *cpu;
	struct thread *t;
	int rc;

	memset(dr_info, 0, sizeof(*dr_info));

	rc = init_thread_info(dr_info);
	if (rc) {
		return -1;
	}

	rc = init_cpu_info(dr_info);
	if (rc) {
		free_cpu_drc_info(dr_info);
		return -1;
	}

	rc = init_cache_info(dr_info);
	if (rc) {
		free_cpu_drc_info(dr_info);
		return -1;
	}
	
	say(DEBUG, "Start CPU List.\n");
	for (cpu = dr_info->all_cpus; cpu; cpu = cpu->next) {
		say(DEBUG, "%x : %s\n", cpu->drc_index, cpu->drc_name);
		for (t = cpu->cpu_threads; t; t = t->sibling)
			say(DEBUG, "\tthread: %d: %s\n", t->phys_id, t->path);
	}
	say(DEBUG, "Done.\n");

	return 0;
}
示例#4
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");
}